黄勇( 博客),从事近十年的 JavaEE 应用开发工作,现任阿里巴巴公司系统架构师。对分布式服务架构与大数据技术有深入研究,具有丰富的 B/S 架构开发经验与项目实战经验,擅长敏捷开发模式。国内开源软件推动者之一,Smart Framework 开源框架创始人。热爱技术交流,乐于分享自己的工作经验。著有《架构探险——从零开始写Java Web框架》一书。

我的十年技术之路

CSDN:请和大家介绍下你和目前所从事的工作。

黄勇:大家好,我是黄勇。

我目前从事分布式服务架构的设计与开发工作,在阿里的大数据平台上进行应用程序开发。我们整个系统架构采用了“前后端分离”的思想,前端关注数据展现,后端关注数据生产,通过 REST服务将前后端整合起来,所有的应用都是无状态的,可以做到水平扩展。我们将整个系统拆分成许多“微服务”,服务之间通过统一的接口来调用,每个服务是通过容器技术进行隔离,此外服务可发布到统一的服务管理平台上,可通过该平台监控每个服务的运行状态与生命周期事件,并为服务调用者提供了服务发现的能力,可对服务进行平滑升级。

阿里有许多优秀的中间件与基础服务,可以快速帮助我们搭建应用系统,而且这些技术在阿里内部全是开源的,大家可以通过源码和文档学习到很多有价值的经验。阿里也提供了浓厚的技术氛围,每位同学都非常专注于自己的工作领域,大家对工作一丝不苟,相互配合,方向一致。

CSDN:你是如何走上技术这条路的?

黄勇:2006 年大学毕业,我离开了母校武汉理工大学,在院长薛胜军老师的推荐下,我来到了上海,这个对于我来说非常陌生的地方。我有幸加入了一家名为“动量软件”的创业公司,这家公司的老板曾经是亚信科技的 CTO,他也是普元软件的创始人兼 CTO,他的名字叫黄柳青,他也是薛老师的大学同学。于是就这样,我的老板成为了我的老师,我习惯叫他黄老师,包括公司其他资深的同事也成为了我的老师,因为我很想他们身上学到更多有价值的东西。

刚开始工作的时候我学习了什么是云计算?什么是 SaaS、PaaS、IaaS?我们花了三年时间开发了一款名为 ODE 的 PaaS 平台,让用户可以在该平台上量身定制自己的软件,最终为客户提供基于 SaaS 的产品。确实很骄傲,那时我们已经在做云了,只是没想到后来云会在中国得到这么好的市场,可能当时只有黄老师一个人想到了吧。

在 2008 年,我为公司拿回了“第一桶金”,这也是我从程序员转向项目经理的里程碑。当时我带领团队远赴深圳,为国信证券公司开发经纪人管理系统,这个项目对于我个人而言却是一笔至高无上的财富,我开始学习如何与人打交道,如何做需求分析,如何将需求转变为技术,如何带领团队小伙伴一起工作。学到了太多太多,但我依然选择在我工作第四个年头里离开了动量软件,我刚加入动量软件的时候,公司只有 5 个人(包括老板和前台),当我离开动量软件的时候,公司已经有 200 人左右了。感谢黄老师!我在他身上学到了很多,他的思想和态度直到今天都还在影响着我。

我的第二份工作还是选择了我最熟悉的证券金融行业,同样也是一家创业型公司,在这家公司里我担任了技术经理,管理了整个技术团队,从项目的售前到售后,我都亲自带领团队来完成。虽然在这家公司我只做了两年,但在这短短的时间里,我学会了如何提高开发效率、如何培养技术团队、如何选拔技术人才、如何建立企业文化。但最后我发现了一个问题,越是想做好,越是很难做好,为了做成一件事情需要做很多的尝试,做事情缺乏正确并有效的方法。

回想我工作的前六年时间里,我一直都是在创业公司里成长,虽然可以快速学到东西,但似乎很难学到更加规范的做事方法。于是我选择了新的工作机会,来到了 TCL 通讯,这是一家相当大的公司,公司的研发管理流程来源于法国阿里卡特公司。我在公司担任 Java 架构师职位,也算是整个 Java 团队的技术负责人,虽然团队并不是特别地大。我在这家公司做了三年,学到了如何整合现有资源、如何按标准流程去做事、如何设计系统架构、如何进行异地工作、如何跨团队工作、如何用英文来沟通。说实话,当时我没有任何的工作压力,可以按时上下班,从来都不会加班。虽然自己空闲的时间很多,但我并没有选择去浪费时间,而是开始写点技术博客,也正是因为这些技术文章,才改变了我后续的职业发展道路。

我清楚的记得,那是在 2013 年 9 月 1 日,我在开源中国(oschina.net)网站发表了我人生的第一篇博文 《Smart Framework:轻量级 Java Web 框架》,这篇文章影响了我后续两年。其实说句心里话,当我第一次写这篇文章时,我心里是没底的,这个框架只是根据自己的理解做出来的一个设想,当时甚至连一行代码都没写过。我的想法是先将这个思想发表出来,让大家讨论起来,我会做一个决策,然后再亲自做具体实现,最后我会将实现过程通过博文的方式展现给大家,后续大家会对我的实现进行点评,我会基于大家的建议进行改善。整个开源过程正好与敏捷的思想是一致的,有效沟通、小步快跑、拥抱变化、不断改进。

也许就是我的技术文章吸引了很多广大读者,这里面不排除想邀请我加入的其它公司。我在 2014 年离开了 TCL 通讯,加入了易传媒。为什么我要放弃如此舒适的工作环境,去加入一家还在不断拼搏的企业呢?其实我看到的是未来互联网的发展趋势,广告程序化交易以及广告与大数据的结合,未来最值钱的一定是数据。抱着这样的信心,我加入了易传媒,担任系统架构师职位。当时易传媒正处于技术转型的初期,需要将 .Net 全部迁移到 Java,这件事情对于我而言是非常有挑战的。我的做法是:第一步定义开发规范与流程,第二步培养核心技术人员,第三步分阶段进行改造。仅半年时间,我们所有的产品成功地迁移到了 Java 平台,结果出乎大家的想象。公司市场也非常不错,产品得到了业界的认可,订单数源源不断,大家每天都很忙碌,但却很开心。而易传媒的“易家人”企业文化,让我所感动,不管是核心技术部门还是其它支持性部门,大家就像一家人一样,你的事情就是我的事情。

直到 2015 年初,阿里巴巴与易传媒建立了合作关系,两家公司进行了深度合作,易传媒公司与阿里妈妈事业部进行了整合,新阿里妈妈从此诞生了,于是我也成为了阿里巴巴的一员,目前负责阿里妈妈大数据品牌营销产品的系统架构工作。就在两家公司整合的过程中,我完成了人生中的处女作《架构探险 —— 从零开始写 Java Web 框架》这本书,目前该书正在各大网上书店售卖,我真心希望这本书能对一些想成为架构师的程序员们有所帮助,由于我个人水平有限,又是第一次写书,写得不好的地方还请大家多多包涵。

CSDN:上面提到,写博客给你带来的收获颇多,能不能分享下技术人如何写博客?又应该以怎样的态度对待?

黄勇:我认为技术人员写博客需要注意以下几点:

  1. 思路要清晰,文章要有明确的大纲与标题。
  2. 对于实战类型的文章,需要分步骤来描述。
  3. 多用短句,少用长句,能一句话说明白,就不用两句话。
  4. 对于不太好理解的内容,最好能打比方来说明。
  5. 文章末尾需要有总结,用最精辟的语言归纳出这篇文章的主要内容。

写博客首先是对自己所学知识的一个总结,此外,也为其他读者提供了很好的教程,知识得到了广播与传递。

CSDN:技术一条不归路,选择了这条路是否有过放弃的想法?

黄勇:做了十年的技术,我从来都没有放弃过它,相反,我非常热爱它,因为我一直以来都很喜欢学习,希望能学到更多的东西,这样遇到了具体的技术问题,可以随时从自己积累的知识库中找到最佳的解决方案。此外,目前我在公司虽然不怎么写代码了,但我还是会利用自己工作闲暇之余写一点开源项目或者代码框架等。

CSDN:你工作过很多大大小小的公司,你认为公司最值钱的东西是什么?

黄勇:我认为是实实在在做事情的程序员们。

他们虽然工资不高,每天坐在位置上敲着代码,在很多人眼中被称为“屌丝”或“宅男”,但我认为恰恰就是这些人,他们才是公司最有价值的人。

  • 他们有自己的理想,希望能够通过自己的努力,从中得到那一点点所谓的成就感;
  • 他们需要理解产品经理真正的意图,把想法变成现实,让产品真正落地;
  • 他们更容易把握细节,而这些细节往往决定着产品的命运与成败;
  • 他们突如其来的跳槽,对我们的项目的交付有直接的影响;
  • 他们在一起工作的气氛,能体现技术公司的文化与底蕴。

由此看来,对程序员的重视是相当有必要的,我们需要关心每一位程序员的职业发展,让他们在团队里能够充分地发挥出自己的能力。

我们也需要对他们倍加关注,挖掘出有能力、肯吃苦、敢担当的人,给他们更多的机会,让他们成为技术领袖。

互联网技术公司需要大量这样的程序员:

  • 他们是一群有着技术信仰的人,他们是一群热爱编程的人,他们是一群不解决问题睡不好觉的人;
  • 他们不是打杂的,不是外包,更不是工具;
  • 他们不喜欢被忽悠,不喜欢被冷落,更不喜欢被驱动;
  • 他们需要尊重,需要培养,更需要激情!

CSDN:你能具体说说程序员需要具备哪些素质吗?

黄勇:我个人是这样理解真正的程序员的:

  1. 深爱技术,一天不写代码手就会痒,就喜欢那种成就感;
  2. 为了一个问题可以废寝忘食,有时会在梦中都能写代码;
  3. 代码洁癖症患者,喜欢优雅代码,写代码就像写诗一样;
  4. 善于分析问题,能快速看清问题的本质,并动手解决它;
  5. 喜欢研究优秀源码,学习大师的杰作,善于归纳与总结;
  6. 有自己的开源项目或技术博客,喜欢学习,更喜欢分享;
  7. 会关注技术圈子的新闻动态,时常会参加线下技术沙龙;
  8. 知道软件开发不是一个人在战斗,更需要的是团队协作;
  9. 保持良好健康的心态,用一颗积极向上的心去拥抱变化。

CSDN:十年的职场之路坚持不易,能够分享下你的「IT 职场」经验?

黄勇:时光飞逝,我事业中第一个十年已然结束了。在这十年里,让我收获了很多,跟大家分享一下我在 IT 职场方面的一些个人经验,不一定对每个人都实用,请大家仅作参考吧。

大家既然都是做技术的,那我们不妨先从技术这个话题开始说起吧。我要与大家分享的第一点经验就是:

1. 把技术当成工具

技术这东西,其实一点都不神秘,它只不过是一个工具,用这个工具可以帮助我们解决实际问题,就这么简单。

我们每天在面对技术,市面上也有很多技术,真的没有必要把这些技术都拿过来学习一遍,然后想办法找个场景去应用它。如果真的这样做了,那么只能说明技术不是工具,而是玩具,技术不是这样玩的。

我们应该从另一个角度来看待技术,不妨从自己的实际工作环境出发,现在需要什么,我们就学什么,而不要漫无目的的追求一些新技术。当然,对于新技术还是需要有所关注的,至少需要知道这个新技术是干什么用的,而且还要善于总结,将有价值的技术收集起来,以备将来使用,当需要使用的时候再来深入研究。

人的精力是有限的,人的生命也是短暂的,要善于利用自己的时间,合理地学习技术。

不要把技术看得那么重要,别把它当回事儿,把它当工具就行了,它就像我们写字的笔一样,用铅笔能写字,用钢笔一样能写字。

作为一名技术人员,除了学习与应用技术以外,还需要为自己做一个正确的职业规划,清晰认识自己究竟属于哪种技术人才,是技术专家类型的,还是技术管理类型的。路到底该怎么走?需要自己做出决定。

在我们职业路线上,最重要的人莫过于老板(我指的老板可以是公司大老板,也可以是自己的顶头上司),对待自己的老板,我也有一些经验:

2. 把老板当成情人

大家应该非常清楚,情人是需要浪漫的,浪漫是需要惊喜的。老板其实跟情人一样,也是需要惊喜的。我们做下属的,要懂得找到合适的机会给老板带来惊喜。我们跟情人谈情说爱,这是一种很好的沟通方式,可别忽略了跟老板“谈情说爱”,我们需要与老板保持良好的沟通,这种沟通并不仅仅是溜须拍马。

讲一个真实的故事吧。记得曾经我的一位同事,技术非常好,做东西非常快,质量也很高,同事们都觉得他是牛人,但他从来都不懂得在老板面前表现自己,老板也只是觉得他是可以做事的,但升职加薪的事情往往总是不会优先考虑他。

大家很定会问:怎样在老板面前表现自己呢?其实方法有很多,由于篇幅有限,我先提供三招吧:

  • 第一招:在给老板做程序演示的时候,不要只是单纯的演示,不妨先用一个 PPT,简单表达一下自己的解决方案,然后再做演示,这样效果会好很多。老板会认为自己是花了心思的,是想把事情做得更好的。
  • 第二招:把自己每天的工作简单记录一下,每周汇总一次,以邮件的形式发送给老板,让老板知道自己每天在做什么。每月写一篇本月工作总结与下月工作计划,同样发邮件给老板。年底可以写一个年终工作总结,打印出来,悄悄地放在老板的桌子上。
  • 第三招:借汇报工作为理由,定期请老板出去吃饭,制造面对面单独沟通的机会。在谈话过程中,强调自己愿意帮助老板分担工作压力。

对待老板其实很简单,只要能帮他做事,又能让他开心,他基本上就搞定了。老板搞定了,自己的职业发展才会平步青云。但千万别忽略了还有一群人,他们或许是自己的团队战友,或许是自己的竞争对手,没错!他们就是同事。如何处理同事关系呢?以下便是我的经验:

3. 把同事当成小孩

处理与同事关系,其实比处理与老板关系要稍微复杂一点,因为同事有多种身份,他们可以是队友,也可以是对手。如果大家在一起做同一个项目,那么这样的同事就是队友;如果为了竞争某个项目、岗位、资源,导致同级别的同事之间发生利益上的竞争,那么这样的同事就是对手。

对于队友而言,要学会主动给他们提供帮助,让大家能够体会到团队协作的气氛,在一起学习,在一起成长,在一起分享。可以时常跟大家一起聚餐,买点零食让大家品尝。

队友关系往往比较好处理,关键在于自己能否真正懂得去分享。很多技术人员,最不愿意的就是分享,因为担心自己花了很多精力学到的知识,分分钟就被别人学会了,自己失去了优势。这种心态最好不要在团队里产生,这样只会让自己变得越来越封闭,越来越渺小,队友们也会逐渐排挤自己。

对于对手而言,要想办法让自己成为他的兄弟,告诉他,咱们是兄弟,应该相互帮助。如果有机会,可以在老板面前,当着对手的面,夸奖自己的对手。做出这样的行为,其实并不会让老板觉得自己不如对手,而会让老板认为自己在用心去容纳对手。大家在一起工作,就是一种缘分,都是跟老板打工的,真的没有必要搞得不愉快。

其实同事就是自己的小伙伴,不妨把他们当成是单纯可爱的小孩吧,用自己的心去“收买”他们。

老板与同事,他们都是公司内部的人,不管怎么说,大家都在同一条船上,大家可以关上门吵一架,只要事情能够解决就行。但对于我们的客户而言,就需要用另外一种方法来处理好关系了。我是这样认为的:

4. 把客户当成病人

客户有需求,但没有技术,而我们有技术、有经验、有产品,正好可以帮助他们实现需求,从而提高他们的工作效率,这样客户才会心甘情愿地把钱放入我们的口袋。所以,在客户面前,我们要表现出高超的专业精神,不要被客户牵着我们的鼻子走,我们在客户面前就是技术权威,就需要这样的自信。从服装、言行、邮件、文档等各个方面,都要做到专业。

我们打算把自己的产品卖给客户的时候,千万不要一上来就对自己的产品夸夸其谈,这往往会让客户感到厌烦。我们不妨先告诉客户,他们已经“生病”了,而且病得不轻,如果不及时用药的话,后果将不堪设想。也就是说,要让客户意识到自己现在所面临的困境,让客户紧张,当他们正在思考如何应对的时候,我们再告诉他们,“药”已经准备好了,可以随时服用。

要让客户有种雪中送炭的感觉,这样就对了,他们一定会主动了解我们的产品。我们要做到这一切,必须花精力来分析行业现状,揣测客户老板们每天在想什么。如果有机会进入客户所在的公司工作一段时间,相信自己的感受会更加深入。

Java 会在很长的一段时间内是主流

CSDN:能否先简答介绍下你的最新力作《架构探险——从零开始写Java Web框架》?面向的群体是怎样的?有什么特别之处?

黄勇:建议有一定 Java Web 开发经验的读者阅读这本书,当然,如果大家想通过这本书来学习 Java Web 核心技术也是非常不错的,因为书中会有大量的实例来讲解 Java 必备的基础技能。此外,建议读者们能亲自动手去实践,虽然书中所有的源代码可以自由获取,但我不建议大家只是看看代码是怎么写的,而错过了一次很好的练手机会,因为所有的开发技能都需要不断地练习,孰能生巧,巧能生辉。

CSDN:《架构探险——从零开始写Java Web框架》是你撰写的第一技术书,是什么原因促使你写这本的?

黄勇:记得那是在 2014 年 11 月底,我有幸结识了电子工业出版社博文视点编辑部的陈晓猛老师。陈老师建议我写一本书,但我当时真的不知道该写什么,我想可能在 Java Web 方面还可以尝试写点东西吧,于是在他的鼓励与帮助下,我就开始写书了。陈老师告诉我,写书其实就像写博客一样,当初我真这么觉得的,可是个人能力和经验还是非常有限,第一次写了 50 页就再也写不下去了,第二次竟然写到了 100 页,最后觉得自己的写作思路有问题,还是放弃了,直到第三次我才把结构梳理清楚,一气呵成地写完了整本书。在这个过程中,是我妻子鼓励并监督着我,那时我们的宝宝刚出生不久,每天在家里哭泣,我妻子把我一个人关在房间里,她独自一人带小孩,并操持着所有的家务,就是为了给我一个安静的环境,让我可以敞开思路,写出更加优秀的作品。在此,请允许我对我妻子说一声:辛苦了!我永远爱你!

CSDN:写书不是一件容易的事情,能不能谈谈在这段期间的辛酸和收获?

黄勇:虽然写书的过程比较艰辛,但对我个人却有很大的收获:

  1. 通过写书这件事情,让我学会了坚持,想做一件事情很简单,但想把这件事情做成却没那么容易。
  2. 通过写书我重新对轻量级 Java Web 框架做更深层次的理解,一个好的框架不是看功能有多强大,而在于它的扩展性有多好。毕竟功能是做不完的,需要有一个“微内核 + 多插件”的思想,核心是非常小的,它仅提供了整个框架的必备功能以及相关的扩展点,然后需要将不同的功能封装在不同的插件中,并为更多其他的开发者提供统一的扩展方式。
  3. 我希望这本书不再是教会读者如何去使用开源框架,而是让读者学会如何从零开始去编写开源框架,并鼓励读者发挥自己的力量,一起投身到开源社区中。

CSDN:为什么开发Java Web都要用框架?

黄勇:我个人觉得框架有以下几点作用:

  1. 让开发更加高效,屏蔽底层技术细节,让开发人员关注在具体业务上。
  2. 框架实际上也是一种规范,可以让每位开发人员保持同样的编码风格。
  3. 会使用主流框架的开发人员,在人才市场上比较好获取。

CSDN:现在做Java Web开发都用哪些框架呢?

黄勇:常用的比如Spring MVC、Struts2 等,国内的 JFinal、Nutz 等也不错,当然Smart 也是一个很好的选择。

CSDN:有一定Web前端开发经验的人,很多都会有这么个想法:那些写框架的人好厉害,什么时候我才能写一个自己的框架呢?有时候看看别人的框架代码,又觉得很复杂,对此你有什么建议吗?以及新人学习需要什么基础?有哪些好的方法分享?

黄勇:对于接触 Java 不太久的朋友,建议按照以下几个步骤来学习:

  1. 学习 Java 基础语法与核心技术,包括 Servlet、JSP、JDBC 等。
  2. 熟练使用流行开源框架,包括Spring、MyBatis 等。
  3. 研究开源框架源码,并吸取其中优秀的架构。

此外,在学习的过程当中,建议做学习笔记,最好能通过博客的方式来记录自己的收获。

CSDN:使用 Python、Perl、PHP、Ruby 等脚本语言开发 Web 程序,跟使用 Java 开发 Web 程序相比有什么不同或者优劣?

黄勇:前者属于动态语言,无需编译,可通过解释的方式来运行,而且 Java 需要首先通过编译,将源文件转为字节码,且载入 Java 虚拟机才能运行,相对来说,Java 对环境的要求较高,但 Java 具备更强的面向对象能力。此外,Java 还拥有较广的开源社区以及流行的开源中间件。因此,如果是做大型系统,建议使用 Java 来开发,而并非那些脚本语言。

CSDN:针对 Web,Java、PHP、Python、.NET 之中未来发展前景最好的会是什么?

黄勇:我认为 Java 在未来还会有一段很长的路,需要在语言本身上做到更加轻量级,用最少的代码来实现目标功能;PHP 相对来说会比较平稳,它的特点非常突出,上手快且易于开发 Web 项目;Python仍然不会有太大的用户群体;.NET 加入开源社区太晚,且较 Java 而言并没有太强的优势,可能会走下坡路。

CSDN:在软件开发中有很多的设计模式,也有一些很高冷,能否谈谈你对软件设计的理解,以及让一些设计原则接地气?

黄勇:了解设计模式的朋友们,想必都听说过“六大设计原则”吧。其实最经典的 23 种设计模式中或多或少地都在使用这些设计原则,也就是说,设计模式是站在设计原则的基础之上的。所以在学习设计模式之前,很有必要对这些设计原则先做一下了解。

GoF(四人帮),传说中的四位大神们,他们联手搞出了一套设计模式,堪称 OOD(面向对象设计)的经典之作!震惊了整个软件开发领域。但这四个老家伙非常怪异,总是喜欢显摆一些高深的理论,甚至有时候不说人话,十分让人费解。

除了最经典的六大设计原则以外,还有一些其他的设计原则也非常重要。我将尽可能地解释这些晦涩的理论,希望看完之后,会让您对这些设计原则稍微加深一些理解。若有不正确的地方,恳请大家指正!

  • 六大设计原则

先看一幅图吧:

这幅图清晰地表达了六大设计原则,但仅限于它们叫什么名字而已,它们具体是什么意思呢?下面我将从原文、译文、理解、应用,这四个方面分别进行阐述。

1. 单一职责原则(Single Responsibility Principle - SRP)

原文:There should never be more than one reason for a class to change.

译文:永远不应该有多于一个原因来改变某个类。

理解:对于一个类而言,应该仅有一个引起它变化的原因。说白了就是,不同的类具备不同的职责,各施其责。这就好比一个团队,大家分工协作,互不影响,各做各的事情。

应用:当我们做系统设计时,如果发现有一个类拥有了两种的职责,那就问自己一个问题:可以将这个类分成两个类吗?如果真的有必要,那就分吧。千万不要让一个类干的事情太多!

2. 开放封闭原则(Open Closed Principle - OCP)

原文:Software entities like classes, modules and functions should be open for extension but closed for modifications.

译文:软件实体,如:类、模块与函数,对于扩展应该是开放的,但对于修改应该是封闭的。

理解:简言之,对扩展开放,对修改封闭。换句话说,可以去扩展类,但不要去修改类。

应用:当需求有改动,要修改代码了,此时您要做的是,尽量用继承或组合的方式来扩展类的功能,而不是直接修改类的代码。当然,如果能够确保对整体架构不会产生任何影响,那么也没必要搞得那么复杂了,直接改这个类吧。

3. 里氏替换原则(Liskov Substitution Principle - LSP)

原文:Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

译文:使用基类的指针或引用的函数,必须是在不知情的情况下,能够使用派生类的对象。

理解:父类能够替换子类,但子类不一定能替换父类。也就是说,在代码中可以将父类全部替换为子类,程序不会报错,也不会在运行时出现任何异常,但反过来却不一定成立。

应用:在继承类时,务必重写(Override)父类中所有的方法,尤其需要注意父类的 protected 方法(它们往往是让您重写的),子类尽量不要暴露自己的 public 方法供外界调用。

该原则由麻省理工学院的 Barbara Liskov 女士提出,她是美国第一位获取计算机博士学位的女性,曾经也获得过计算机图灵奖。

4. 最少知识原则(Least Knowledge Principle - LKP)

原文:Only talk to you immediate friends.

译文:只与你最直接的朋友交流。

理解:尽量减少对象之间的交互,从而减小类之间的耦合。简言之,一定要做到:低耦合,高内聚。

应用:在做系统设计时,不要让一个类依赖于太多的其他类,需尽量减小依赖关系,否则,您死都不知道自己怎么死的。

该原则也称为“迪米特法则(Law of Demeter)”,由 Ian Holland 提出。这个人不太愿意和陌生人说话,只和他走得最近的朋友们交流。

5. 接口隔离原则(Interface Segregation Principle - ISP)

原文:The dependency of one class to another one should depend on the smallest possible interface.

译文:一个类与另一个类之间的依赖性,应该依赖于尽可能小的接口。

理解:不要对外暴露没有实际意义的接口。也就是说,接口是给别人调用的,那就不要去为难别人了,尽可能保证接口的实用性吧。她好,我也好。

应用:当需要对外暴露接口时,需要再三斟酌,如果真的没有必要对外提供的,就删了吧。一旦您提供了,就意味着,您将来要多做一件事情,何苦要给自己找事做呢。

6. 依赖倒置原则(Dependence Inversion Principle - DIP)

原文:High level modules should not depends upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.

译文:高层模块不应该依赖于低层模块,它们应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

理解:应该面向接口编程,不应该面向实现类编程。面向实现类编程,相当于就是论事,那是正向依赖(正常人思维);面向接口编程,相当于通过事物表象来看本质,那是反向依赖,即依赖倒置(程序员思维)。

应用:并不是说,所有的类都要有一个对应的接口,而是说,如果有接口,那就尽量使用接口来编程吧。

将以上六大原则的英文首字母拼在一起就是 SOLID(稳定的),所以也称之为 SOLID 原则。

只有满足了这六大原则,才能设计出稳定的软件架构!但它们毕竟只是原则,只是四人帮给我们的建议,有些时候我们还是要学会灵活应变,千万不要生搬硬套,否则只会把简单问题复杂化,切记!

  • 补充设计原则

1. 组合/聚合复用原则(Composition/Aggregation Reuse Principle - CARP)

当要扩展类的功能时,优先考虑使用组合,而不是继承。这条原则在 23 种经典设计模式中频繁使用,如:代理模式、装饰模式、适配器模式等。可见江湖地位非常之高!

2. 无环依赖原则(Acyclic Dependencies Principle - ADP)

当 A 模块依赖于 B 模块,B 模块依赖于 C 模块,C 依赖于 A 模块,此时将出现循环依赖。在设计中应该避免这个问题,可通过引入“中介者模式”解决该问题。

3. 共同封装原则(Common Closure Principle - CCP)

应该将易变的类放在同一个包里,将变化隔离出来。该原则是“开放-封闭原则”的延生。

4. 共同重用原则(Common Reuse Principle - CRP)

如果重用了包中的一个类,那么也就相当于重用了包中的所有类,我们要尽可能减小包的大小。

5. 好莱坞原则(Hollywood Principle - HP)

好莱坞明星的经纪人一般都很忙,他们不想被打扰,往往会说:Don't call me, I'll call you. 翻译为:不要联系我,我会联系你。对应于软件设计而言,最著名的就是“控制反转”(或称为“依赖注入”),我们不需要在代码中主动的创建对象,而是由容器帮我们来创建并管理这些对象。

  • 其他设计原则

1. 不要重复你自己(Don't repeat yourself - DRY)

不要让重复的代码到处都是,要让它们足够的重用,所以要尽可能地封装。

2. 保持它简单与傻瓜(Keep it simple and stupid - KISS)

不要让系统变得复杂,界面简洁,功能实用,操作方便,要让它足够的简单,足够的傻瓜。

3. 高内聚与低耦合(High Cohesion and Low Coupling - HCLC)

模块内部需要做到内聚度高,模块之间需要做到耦合度低。

4. 惯例优于配置(Convention over Configuration - COC)

尽量让惯例来减少配置,这样才能提高开发效率,尽量做到“零配置”。很多开发框架都是这样做的。

5. 命令查询分离(Command Query Separation - CQS)

在定义接口时,要做到哪些是命令,哪些是查询,要将它们分离,而不要揉到一起。

6. 关注点分离(Separation of Concerns - SOC)

将一个复杂的问题分离为多个简单的问题,然后逐个解决这些简单的问题,那么这个复杂的问题就解决了。难就难在如何进行分离。

7. 契约式设计(Design by Contract - DBC)

模块或系统之间的交互,都是基于契约(接口或抽象)的,而不要依赖于具体实现。该原则建议我们要面向契约编程。

8. 你不需要它(You aren't gonna need it - YAGNI)

不要一开始就把系统设计得非常复杂,不要陷入“过度设计”的深渊。应该让系统足够的简单,而却又不失扩展性,这是其中的难点。

敏捷开发模式的修炼之道

CSDN:请问你是如何接触到敏捷开发的?你如何理解敏捷开发?

黄勇:曾经我们开发项目都是采用传统的“瀑布式”流程进行开发,即需求、设计、开发、测试、上线等阶段,其中每个阶段都有明确的交付时间点,且每个阶段都依赖于它的上个阶段,一旦需求有变化,就会影响后续的每个阶段,项目管理存在一定的风险。为了避免这个风险,做到更好地拥抱变化,我们尝试使用了敏捷开发方法,最为典型的是 Scrum。我们参考Scrum 的流程结合自身的特点,总结了一套更容易落地的Scrum,后面我会跟大家讲到一些相关细节。

我理解的敏捷开发实际上是一个轻量级的项目管理规范,因为我们可以将整个大的需求范围拆分成若干迭代周期,我们为这些迭代周期设置明确的里程碑,且评估完成这些功能需要花费的成本,更重要的是,每次迭代完成以后,我们会对本次迭代进行一个回顾,取其精华,去其糟粕,不断完善,持续改进。

CSDN:你认为国内的敏捷开发何时能成为主流?敏捷开发的未来走向是什么?

黄勇:我认为敏捷开发现在已经成为了主流,传统开发模式已经出现了明显的缺陷,随着互联网的发展,软件开发的节奏会越来越快,变化也会越来越频繁,需要我们能够快速地发现变化,并进行及时地调整。

我认为敏捷开发的未来会变得更好,不仅仅在软件开发行业,而且可能会在其它行业里也会得到应用,因为从客户的角度来看,他们想要的是能通过最短的时间看到自己想要的东西,很多时候不做出一点东西出来,客户是没有任何想法的,所以需要将事情分解成多阶段,迭代完成每个阶段的里程碑,让客户满意,才是企业最大的收获。

CSDN:在你的工作生涯中,前期是在创业公司,后来是大公司,有着一套自己的敏捷开发模式,能够谈谈在你现在使用的敏捷开发工具或方法?

黄勇:敏捷这个话题大家一直都在谈论,也有很多关于敏捷的工具或方法,我个人比较倾向于 Scrum。我理解的敏捷其实是一种思想,Scrum 是对让这个思想落地的一个参考。也就是说,我们大可不必完全拘泥于 Scrum 定义的规范,只需要参考它并结合自身的条件做适当调整即可。比如说,每日站会这个环节就非常重要,不管是放在每天上午,还是放在每天下午,总之最好要有固定的周期。此外,每次 Sprint(迭代)结束后除了有评审会以外,Scrum Master 不要忘记对本次 Sprint 做一个回顾与总结,哪些是本次迭代中做的好的地方,哪些是做的不好的,再对比上次迭代的的结论,哪些是有改进的,哪些是新的问题。

Scrum 提供了三类角色,分别是:Product Owner(一般由产品经理担任)、Scrum Master(一般由开发经理担任)、Scrum Team(包括开发与测试人员),其中,Scrum Master 的角色至关重要,对项目的成败起决定性作用。

阿里巴巴也在广泛使用 Scrum 敏捷开发模式,而且整个项目几十人都可以用 Scrum,只是首先需要将整个团队拆分成若干小团队,保证每个小团队按照 Scrum 进行操作,此外,再将每个小团队的 Scrum Master 召集在一起,再做一轮 Scrum,这就是所谓的 Scrum of Scrum。过程稍微复杂一点,但可以将敏捷用于更大的团队规模,并能保证敏捷的效果。

CSDN:你认为Scrum Master 的角色至关重要,对项目的成败起决定性作用。那敏捷开发中由产品经理担任Scrum Master会有什么问题?

黄勇:我个人不太建议由产品经理来担当Scrum Master,原因如下:

  1. Scrum Master 关注的是项目开发视角,而产品经理关注的是产品功能视角,两者关注的视角是不一样的。
  2. Scrum Master 需要有一定的技术开发功底,需要对开发工作量进行评估,也需要对技术实现进行评审,可能还会有一定的编码工作,而具有技术功底的产品经理毕竟太少了,即便有的话,可能对技术方面也不会太深入。
  3. 需要有一个人,他来对整个产品负责,这个人就是Product Owner,该角色最好由产品经理来担任。

CSDN:敏捷开发过程中测试团队的职责和产出是什么?

黄勇:在敏捷开发过程中,我认为测试团队的职责有以下几点:

  1. 根据产品需求,定义测试用例。
  2. 针对测试用例进行功能测试,并将测试的结果反馈给开发人员。
  3. 负责搭建系统运行所需的环境,包括软件安装、数据初始化等。

CSDN:除了Scrum,还有XP、CM、FDD、ASD、DSDM等敏捷开发方法,如何去选择一个合适的敏捷开发工具或者方法呢?

黄勇:敏捷开发方法有很多,不仅仅只有Scrum 一种,其实不妨相互借鉴,再结合自身的特点,定义一套适合自己的敏捷开发方法。例如XP 中所提倡的结对编程、持续集成、测试驱动等,这些都是很好的方法,值得借鉴。包括看板也是一个很不错的工具,可以结合Scrum 来工作。

CSDN:从博客上,你也研究过「使用看板进行敏捷开发」,能不能分享你的研究成果?

黄勇:敏捷开发工具“看板”,该词汇来自于岛国,当我看到看板的英文时,我真的惊呆了,看板竟然就是 Kanban?!

我们可以结合 Scrum 与 Kanban,让项目管理更加有效,让资源分配更加合理,让绩效考核更加公平!

  • 对于项目经理而言,最担心的就是项目进度不可控,不知道每位开发人员具体的工作进度,有了 Kanban 一切都是那么地清晰。
  • 对于开发经理而言,最担心的就是资源分配不合理,忙的人忙死,闲的人闲死,有了 Kanban 一切都是那么地自然。
  • 对于开发人员而言,最担心的就是绩效考核不公平,“凭什么我做的比他多,拿的工资却比他少?不公平啊!”有了 Kanban 一切都是那么地公平。

可见,项目经理、开发经理、开发人员拥有了 Kanban,也就拥有了和谐与快乐!

那么 Kanban 到底是什么呢?我们先来看看这张表格吧:

下面我们来理解一下这个表格吧!

  • 这个表格有 5 列:Backlog(原始需求)、Selected(被选中的需求)、Develop(开发阶段)、Deploy(部署阶段)、Live(上线阶段)
  • 其中 Develop 阶段包括 2 个子阶段:Ongoing(进行中)、Done(已完成)
  • 包括 3 中角色:产品经理(红色小人)、开发人员(蓝色小人)、部署人员(绿色小人),其实还有项目经理,只是他/她贯穿于始终,所有就没有画出来了。

在 Backlog 中放置了许多小卡片,它们在 Kanban 中被称为 WIP(Work In Process,在制品)。对于产品经理而言,WIP 是需求,而对于开发人员与部署人员而言,WIP 却是任务。

实际这些 WIP 卡片上都带有一些文字描述,包括:标题、描述、优先级等信息。

需要注意的是,Selected、Develop、Deploy 下方有一个数字,该数字表示此阶段中最多可以放置的 WIP 数量。例如,在 Selected 中最多只能放 2 个 WIP;在 Develop 中(包括它的子阶段)最多只能放置 2 个 WIP。这里的数字只是一个示例,具体多少可根据团队实际情况而定。有一个经验公式可以参考“WIP 上限 = 团队规模 * 2 - 1”,减 1 表示大家需要协作,例如:4 人的团队,WIP 上限是 7。

也许有人会提出,为什么没有 Test 阶段?—— 这个可以有,这里只是一个示例而已,你不妨自行加上去。

对于多个项目而言,可以在这张表格中添加更多的泳道(行),每一行相当于一个项目,所有的项目进度清晰明了。

好!继续我们的 Kanban,有意思的事情即将发生!

产品经理挑选了 2 个 WIP 到 Selected 中,此时,由开发经理决定该任务的技术难度,并由项目经理将任务分配到指定的开发人员,也可将同一个任务分配给两个人,让他们去结对编程。

开发人员(架构师与程序员)可对 Selected 中的需求进行工作量评估,可采用投票的方式进行,最终给出一个合理的评估值,整个估算过程,项目经理无需参与,主要是开发人员共同完成。

开发经理可以对任务设置一个“分值”,这个分值可直接影响到后续的绩效考核,所以对大家来说,这个分值是公开可见的,谁做的多,谁做得少,一目了 然。当然,开发人员也可以主动承担具有更具挑战的任务(为了锻炼自己,也为了多拿点钱),但任务分配的决定权始终在项目经理手中。

现在假设 A、B 两个任务已经分别被不同的开发人员处理了,那么这些任务就应该移动到 Ongoing 中,同时,产品经理可以从 Backlog 中挑选出 2 个优先级较高的需求到 Selected 中。这样就保证 Selected 与 Develop 都达到了 WIP 的上限。

有人已经把 A 做完了,那么 A 就可以移动到 Done 中了。随后,部署人员就可以开始干活了。

部署人员就可以将 A 从 Done 中移动到 Deploy 中,表示部署人员正在做这件事情。同时,做完了 A 任务的开发人员可以再做其它新任务,只需从 Selected 中移动到 Ongoing 中,移动这件事情不是开发人员随意操作的,而是有项目经理负责的。产品经理发现 Selected 中只有一个 D,就可以考虑放入一些新的需求了。

此时,部署人员遇到了问题,发现 A 部署的时候总是报错,跑不起来了。同时,其他开发人员也完成了 B 任务。

完成了 B 任务的开发人员本来是可以做新需求的,但项目经理发现 Develop 中只能放 2 个任务,所以肯定是后面的阶段出现了问题,导致整个流程受阻了。项目经理可以灵活调度人力资源,集中火力解决现在所遇到的问题。

所以项目经理不得不放弃新的任务,去让开发人员去帮助部署人员来解决问题。此时,其他的开发人员还在进行 C 任务。

部署的问题还没来得及解决,此时 C 任务也完成了,同时,产品经理也放入了新的 K 需求,确保 Selected 这个水池是装满水的。

整个部署问题看起来比较搞人,所有的开发人员全都上阵了,集中更多人的智慧,解决这个棘手的问题。此时,产品经理不能放入更多的需求,由于此时 Selected 已经满额了。其实,开发人员面对太多的需求时,往往都会倍感压力,身心憔悴。

看来这个部署问题,确实够折腾的,连产品经理都过来了凑热闹了。但他或许不懂技术,但多个人多个头脑吧,正所谓“当局者迷,旁观者清”,最终经过大家的努力,肯定会攻克这座碉堡!

几天之后,Kanban 流程依旧是稳定的,大家分工协作,人力资源合理利用。大家是一个团队,目标就是把项目做好,不会因为自己的事情做完了就闲置了。

我们不妨将这张表格贴到墙上去吧!让每个员工都可以看到,让过路的老板们也可以看到我们的辛苦努力,这确实是一种非常好的项目管理方法!

CSDN:一个成功的项目,离不开每个人的努力,能够分享下你曾经的项目管理经验?

黄勇:给大家提出以下 10 点建议及其目标:

  1. Sprint 第一天,需要将目标定义清楚,并让团队所有人都知道「确保建立一致的目标并使之明确」;
  2. 若出现需求变更,则优先排到下次迭代,特殊情况需特殊处理「确保本次迭代可以按时完工」;
  3. Scrum Master 将迭代中的需求分解为任务,每个任务只能有一个任务负责人,且不超过一个人天「确保每日任务可评估」;
  4. 让 Product Owner 直接与相关开发人员确定需求,Scrum Master 需一同参与「确保需求与实现不会发生偏差」;
  5. 每日定时站会,时长不超过 15 分钟,规模不要太大「确保任务完成情况与计划保持一致」;
  6. 每日进行一次代码评审,由 Scrum Master 负责,并在次日将评审结果通知给相关开发人员「确保代码质量不要下降」;
  7. 各个团队的 Scrum Master 保持每日沟通一次,时间不要超过 15 分钟「确保项目管理不会出现风险」;
  8. 每次迭代结束,让大家稍微放松一下,可提供一些团队活动,比如聚餐「确保团队能够更加凝聚」;
  9. Scrum Master 需要给团队一些承诺,比如项目奖金或特殊福利等「确保团队更加有激情」;
  10. 对于情绪异常的员工,Scrum Master 需及时与其沟通「确保不要让一个人的情绪影响整个团队」;

此外,作为项目管理者,需要不断在团队中加强以下 6 点文化:

  1. 方向一致
  2. 当面沟通
  3. 全情投入
  4. 充分信任
  5. 说到做到

真正的开源并非只是代码的开源,而是思想的开源

CSDN:你在开源方面有着诸多的建树,例如,你是Smart Framework开源框架创始人,你对「开源」怎么看?国内的开源的现在如何,对比国外呢?

黄勇:我个人认为,真正的开源并非只是代码的开源,而是思想的开源。在做开源项目之前,建议能将自己的想法共享出来,而不是 埋头闭门造车。我不反对“重造轮子”,因为我们需要更好的轮子,轮子好了车子才能跑得快。凡是有利也有弊,我们也不能盲目地选择开源技术,因为并不是适合 别人的技术就适合自己,而是需要根据自身的需求,选择最适合的开源技术,搭建恰如其分的架构。

有大量的新技术,我首先会去关注它,了解它是做什么的,可以解决什么问题,但我一开始绝不会去深入研究它,更不会去看它的源码,因为一旦遇到这方面的需求场景,我就会从这个“知识库”中去寻找最好的解决方案,如果仍然寻找不到最合适的开源技术,我才会尝试自己去实现。

CSDN:能够介绍下你写的Smart Framework的轻量级 Java Web 开发框架?

黄勇:基于对开源的热爱,以及上述中我的开源态度。我写了一款名为 Smart Framework 的轻量 级 Java Web 开发框架,它基于“微内核 + 多插件”的体系架构,基于 Servlet 3.0 规范,不依赖于 Spring、 Hibernate 等开源框架,提供 IOC、AOP、ORM 等轻量级解决方案,并具备良好的可扩展性,前端直接使 用 HTML + CSS + JS 开发模式,同时也兼容 JSP、JSTL、Tag 等技术,后端提供 REST 服务接口(基于 JSON 格 式),没有任何的 XML 配置文件,真正的零配置。我认为这些特性足以开发一些简单的 Web 应用程序,至于复杂的功能,就留给插件去完善吧。

当初写 Smart 的时候并没有想到大家会对这个框架会如此感兴趣,抱着分享的态度,并不想去推广这个产品,仅仅只是想找到能够理解自己开源思想 的同道中人。世事总难料,已经有一些企业和个人开始使用这款框架了,并提供了大量的改造与扩展。我很欣慰,因为我基本上实现了自己的愿望,并希望将来会出 现有更好的 Java Web 框架,丢掉重量级的帽子,披上轻量级的外衣。

技术人的归途

编者注:在采访期间,小编和一位同是十年工作经验的coder聊天,发现他正陷于转型做管理、深耕技术的泥潭,为此向黄勇老师请教,得出了一个非常不错的中肯建议,也整理在这里,希望对你有所帮助。

CSDN:走技术这条路,归途是什么?是否转型又该如何抉择呢?

黄勇:至少有好几条路线是可以走的,比如:深入技术、转型做产品、转型做管理等,需要根据自己的特长和性格来选择,做自己喜欢的事情。

从技术转管理,对自身的要求比较高,说具体点,需要看自己的情商,为人处世的经验,与人沟通的技巧,自己也需要有足够的胸怀,去包容一些事情,还需要自己有足够的人格魅力去吸引别人,让别人愿意跟着你一起做事。管理有些东西是很难从书本上学到的,但一些经典的管理理论是必须要去学的。

相比较而言,继续深入技术或者从技术转产品会容易一些了,因为很多时候都不太需要与人打交道

CSDN:关于机遇,是可遇不可求的。比如,当管理,那也是有一定的环境造就,你得有这个机会去试一下,才知道自己是否感兴趣做管理,以及是否适合等。

黄勇:没错,机遇太重要了,而且有些时候,机遇是可以考自己的努力去得到的,说到底还是与人沟通,让自己的老板给自己机会,如果现在的公司给不了自己足够的机遇,那么不妨考虑一下外面的机遇。总之,自己需要灵活处理,伴随公司共同成长才是最好的。

CSDN:程序员相对比较「直」,也就是有啥说啥,事后或许才发现说了不该说的话,情商不高,如果改善这一情况呢?

黄勇:性格比较直,说话容易得罪人,这个很正常了,只不过首先需要向对方阐明自己的观点,是为了把这件事情做好,和对方的目标是一致的,也就是说,首先与对方共同的价值观,然后再说自己的想法,并多听取对方的意见,尽量多和对方保持相同的看法,最后需要注意的是,自己不擅长的方面,尽量多听少说,听也是在学习。

在听的过程中,可以表达自己的认识,并询问对方是否这样理解的。

CSDN:最后,你是怎么分配一天的时间的?闲暇时,喜欢做些什么来放松自己?

黄勇:平时工作我一般都比较忙,会议占据了我大部分时间,在自己仅有的工作时间里我会花更多的时间与团队主管们进行沟通,让大家保持一致的方向,这样每个技术主管也会带出更适合公司文化的团队。总之,技术氛围不是一两天就能形成的,需要长时间的沟通,这个时间对于技术管理人员是必须要付出的。

在闲暇之余,我喜欢听音乐,也喜欢和朋友聊天,朋友是自己的一面镜子,可以通过这面镜子来看清自己,其实人这一辈子都是在不断地看清自己,认识自己。

写给读者的话:

非常感谢读者们能够花自己宝贵的时间来阅读本文,其实我自己也和大家一样,我们都在不断地学习,不断地提高自己,真心希望本文能够帮助大家。此外,我也很期待大家能与我进一步互动,我平时也会在线下组织一些小规模的技术交流活动,希望大家能够相互认识,相互分享,相互帮助。

转:一位10年Java工作经验的架构师聊Java和工作经验的更多相关文章

  1. 一位10年Java工作经验的架构师聊Java和工作经验

    从事近十年的 JavaEE 应用开发工作,现任阿里巴巴公司系统架构师.对分布式服务架构与大数据技术有深入研究,具有丰富的 B/S 架构开发经验与项目实战经验,擅长敏捷开发模式.国内开源软件推动者之一, ...

  2. Java程序员到架构师的推荐阅读书籍

    作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.我想就我自己读过的技术书籍中挑选出来一些,按照学习的先后顺序,推荐给大家,特别是那些想不断提高自己技术水 ...

  3. 问题集录--从初级java程序员到架构师,从小工到专家

    怎样学习才能从一名Java初级程序员成长为一名合格的架构师,或者说一名合格的架构师应该有怎样的技术知识体系,这是不仅一个刚刚踏入职场的初级程序员也是工作三五年之后开始迷茫的老程序员经常会问到的问题.希 ...

  4. Java程序员进阶架构师推荐阅读书籍

    [IT168 技术]作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.我想就我自己读过的技术书籍中挑选出来一些,按照学习的先后顺序,推荐给大家,特别是那些 ...

  5. 阿里P8架构师总结Java并发面试题(精选)

    一.什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速.比如,如果一个线程完成一 ...

  6. 一名资深架构师规划Java程序员五年职业生涯指南

    每个程序员.或者说每个工作者都应该有自己的职业规划,如果你不是富二代,不是官二代,也没有职业规划,希望你可以思考一下自己的将来.今天我给大家分享的是一篇来自阿里大牛对五年工作经验程序员的职业建议,希望 ...

  7. 个人总结的一个中高级Java开发工程师或架构师需要掌握哪几点!

    今天,我来唠叨几句~~ 知识改变命运,对于Java程序员来说,技术不断更新,只有及时充电,才能不被市场淘汰.今天为大家分享Java程序员学习的6个小技巧. 1.一定要看书 现在学习Java变得比以前容 ...

  8. ()IT 职场经验)一位10年Java工作经验的架构师的经验分享,感觉很受用。

    阿里巴巴技术大牛黄勇的经验分享,感觉很受用. 关于IT 职场经验 1. 把技术当成工具 技术这东西,其实一点都不神秘,它只不过是一个工具,用这个工具可以帮助我们解决实际问题,就这么简单. 我们每天在面 ...

  9. 【饿了么】招聘Java开发工程师、架构师

    3年以上实际工作经验,本科及以上学历. 具有良好的编程基础( 比如熟悉HTTP.多线程.Socket.JVM.基本的数据结构和算法等). 熟悉Java语言以及相关的服务器(比如Tomcat).工具(M ...

随机推荐

  1. 【hdoj_2079】选课时间(母函数)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2079 此题采用母函数的知识求解,套用母函数模板即可: http://blog.csdn.net/ten_s ...

  2. 《The art of software testing》的一个例子

    这几天一直在看一本书,<The art of software testing>,里面有一个例子挺有感触地,写出来和大家分享一下: [问题] 从输入对话框中读取三个整数值,这三个整数值代表 ...

  3. JS作用域和ASP(vbs)作用域比较

    一.js作用域,先上图: 以上代码执行的效果是,依次弹出 undefined, undefined, a, a,为什么是这样的结果啦?因为JS的作用域为链式作用域. 作用域链: 用VAR声明一个变量时 ...

  4. C++ cin.ignore()用法

    cin.ignore(int a,char b); a为一行中最大读取字符长度,b为某一个字符.在缓冲区中寻找b,找到后忽略b以前的所有字符(包括b).如果在a的范围内还没有找到b,则忽略b以前的所有 ...

  5. JavaWeb中常见的乱码处理(亲测)

    常见编码方式: ISO-8859-1  西欧码 GB2312  简体中文码 GBK   大五码 UTF-8 全球码(推荐) 1.页面(HTML,JSP,Servlet) <%@ page lan ...

  6. 洛谷——P1862 输油管道问题

    P1862 输油管道问题 题目背景 听说最近石油危机 所以想到了这题 题目描述 某石油公司计划建造一条由东向西的主要输油管道.该管道要穿过一个有n口油井的油田.从每口油井都要有一条输油管道沿最短路径( ...

  7. 洛谷——P2799 国王的魔镜

    P2799 国王的魔镜 题目描述 国王有一个魔镜,可以把任何接触镜面的东西变成原来的两倍——只是,因为是镜子嘛,增加的那部分是反的.比如一条项链,我们用AB来表示,不同的字母表示不同颜色的珍珠.如果把 ...

  8. 【线性筛】【质因数分解】【约数个数定理】hdu6069 Counting Divisors

    d(x)表示x的约数个数,让你求(l,r<=10^12,r-l<=10^6,k<=10^7) #include<cstdio> using namespace std; ...

  9. 【FFT】OpenJ_POJ - C17H - Reverse K-th Problem

    对每个位置i处理出以其为结尾,且比a(i)大的数有j个的前缀个数,记成一个数组l:同理,处理出以其为开头,且比a(i)大的数有j个的后缀的个数,记成一个数组r. 整个序列中比a(i)大的数的个数的数组 ...

  10. es进行聚合操作时提示Fielddata is disabled on text fields by default

    在进行派粗前,先执行以下操作 { "properties": { "updatedate": { "type": "text&qu ...