Gong Yong的Blog

尽可能不要学习新技术

几个朋友在讨论组里面发了一篇名为你患上开发者渐冻症了吗?的文章,歌词文章大意是讲软件界的技术日新月异,新的名词层出不穷,令人眼花缭乱。程序猿在这种形势下只能疲于奔命,发奋学习各种新技术,但由于学习速度跟不上技术更新的速度,从而变得心里没底、自信心不足,因为紧张过度而导致肌肉萎缩麻木,最终变得跟霍金一样生活无法自理(唯一的差别可能是霍金泡得到妹子,而且还劈腿,玩真爱)。

我完全认同这篇文章,我也有过类似的经历,而且我相信任何一个有点追求的程序员都会有这种经历,特别是在菜鸟阶段,碰到什么东西都想学,特别是那些名字起得很酷、包装做得很好的新技术,例如EJB、SOA、RPC这些三字经。下面列举4个我曾经觉得它们很牛逼,并且花了一定时间和精力学习的技术,但这些技术现在已经消失在时间的长河中了:

EJB

这个名字很酷,从它把J和B连在一起就可以看出。我刚毕业那会java很火,特别是用它开发企业级应用,那个时候把它叫J2EE(这个名字也很酷,我发现搞java的一帮家伙都很会取名字),而EJB就是解决java企业级开发的问题的,它提供了一些连接器、RIM之类的。我那个时候感觉在weblogic中配置EJB好神奇啊。它的具体细节我现在也不记得了,就是最开始工作的时候用了一下,后来它也被Sun自己的EJB3取代了,而且貌似现在它们都被Spring取代了。

Java的企业级web容器

当我第一次听说web容器这个词,我除了好奇就是膜拜,一个软件是提供一些容器,然后这些容器把web装在里面,真牛逼。我刚开始接触WebLogic的时候真的是花了不少时间去找这个容器在哪里,看它长什么样子。

那个时候企业级开发很火,有几家公司是当时最牛逼的:Oracle、IBM、BEA、Sun,它们都有web容器,其中以BEA的WebLogic和IBM的Websphere是最为人熟知的。而Tomcat作为一个开源项目,大家都认为它只适合开发宠物店之类的web应用,比较低级,企业级的web应用它还是不行(至少我当时是这么认为)。我当时了解到的原因就是Tomcat管理不了那么多的数据库连接池,处理不了并发请求(企业用的内部系统有个毛的并发请求啊),或者是不支持事务,再或者是不支持跨系统的事务,似乎是安全性比较差,whatever。现在这些我都不清楚,但我只知道WebLogic和Websphere基本上都已经消失了,至少没人care它们,那个年代买一个这种软件的license少说也得个十几万吧,现在大家都用tomcat,而且是真正的在上面运行高并发的应用。

Web Service

我曾在在一个国家级的事业单位做了一年的研究性的工作,研究怎么测试SOA系统,这是一个国家级的课题,有很多公司参与,有些公司负责开发中间件,有些公司负责开发SOA的应用,我们是负责测试,研究怎么测试SOA系统。实际上做的工作就只是翻译文档,说白了就是忽悠,这个就不细说了,大家都懂的。我记得当时候有个公司做了一个ESB的中间件,完全是抄袭Mule,我当时给他们测试的时候发现了他们抄袭,跟领导汇报,领导没有重视,后来课题审查的时候还曝出了一段小丑闻,不过那个时候我已经离开了那个单位,具体是怎么处置的我就不清楚。

当然我要说的重点是我在此期间了解和学习了很多Web Service方面的东西,Web Service是一套标准,包括用于信息交互的Soap标准,用于服务发现的Wstl标准,它们都是基于XML的,这些东西都是那些工业界的大佬搞出来的,他们搞这套东西是为了实现服务器的松耦合,以及解决数据孤岛和企业遗留系统问题,大概意思就是企业使用wstl来描述服务,使用soap描述数据,wstl还负责服务的管理和发现,如果完全遵从这个标准,那么所有的东西就都是服务了,这个理念很好,不过基于XML的这些标准太扯蛋了,而且要学习和实现这些标准又太复杂了。现实情况是如果你基于这些标准来开发系统,你就必须用哪些大厂商提供的中间价,以及一整套的解决方案,IBM就是通过推广这些东西赚了很多钱。

这么多年过去了,我除了听说有些公共的服务接口,例如雅虎的天气接口是使用webservice,我没有看到太多的web service的应用,而且现在就是使用XML的格式描述数据都很少,大家都用json,而服务的规范都使用restful,走http协议,对于一些内部的api,甚至是直接自己定义服务的调用规范,谁还管什么soap和wstl。

敏捷编程

上面说的三个技术你可能都没有接触过,但是你肯定听说过敏捷编程,如果你稍微深入研究过敏捷编程,你肯定听说过TDD、Scrum、结对之类的名词。关于敏捷,有人已经写了很多文章批判它,例如陈皓的一些博文,我最喜欢的是steve yeege的文章,它写了一本书叫做程序员的呐喊,里面收录了他的一些博文,其中就有一篇是批判敏捷编程的。

我最开始是在Uncle Bob的敏捷软件开发 原则、模式与实践这本书中接触到敏捷编程的,这本书的扉页上有一个关于敏捷编程的宣言,这个宣言的倡导者中有像Martin Flower这样的牛人,我最开始读到这些文字的时候激动不已,就像一个掉落悬崖后找到了一本武林秘籍的屌丝。虽然我是一个低调的人,但那个时候在工作中我也忍不住在内心中鄙视身边的同事,原因就是他们不知道敏捷编程。我也偶尔会在跟同事聊天的时候使用这种句式:“你们知不知道敏捷编程,****,如果我们使用敏捷编程的话什么问题都可以解决,代码的质量问题、项目延期问题,而且结对编程大家一起搞基,女朋友都不用找了,多欢乐!”。

我一直都想实践敏捷编程的这些方法论,但从来都没有机会,也许有人会说没有实践就没有发言权,但是根据我个人有限的了解很少有团队真正的实践敏捷所提倡的方法论,而且就是有团队实践,也没有谁把它们拿出来大书特书(除了咨询公司外),因为我相信他们之所以没有大力吹嘘,是因为不值得,因为问题依旧存在,而且很多问题是跟团队成员的水平直接相关的,跟敏不敏捷关系不大。所以结论就是如果某种技术,或者方法论都没有人用,而且是在很多人大力营销(那个宣言就是啊)的前提下,可想而知它所能够提供的价值。

最后想声明一点,Uncle Bob的那本书写得非常不错,特别是关于设计模式的部分,个人觉得比Gun Of Four的那本好多了。

我们为什么喜欢新技术

新技术有很好的一面:那就是有人创造了新的东西。如果市面上存在很多新技术,那说明这个行业非常繁荣,也说明有很多聪明的有才华的人把他们的创造力注入到了这个行业中,这也促进了整个行业的发展。

所以很显然,我们喜欢新技术的一个很重要的原因就是因为有这么多新技术被搞出来供我们选择,我们有义务去行使自己的选择权。还有一个重要的原因就是人类喜新厌旧本能,现在是一个消费时代,我们不断的买新的东西来满足我们的欲望。对于程序猿而言,虽然工资相对于与其他行业来说还算不错,但由于程序猿的特别基因,大多数人对买东西没那么大的兴趣,他们就通过学习和追求新技术来满足他们的欲望。而且如果学得好的话,这也是一笔不错的投资,不过事实是否如此那就另当别论了。

学习新技术还有另外一个好处:可以满足我们的虚荣心。如果你像我一样,敏捷编程刚出来的时候,你就学习了它,你会学会单元测试,然后使用TDD的方式来开发程序,测试先行,而且一切都是围绕着测试进行开发,你会坚信敏捷就是银弹,它可以解决传统的软件工业积弊已久的问题,通过结对搞基也可以提高生活乐趣。但现实是没人跟你一起玩,这不重要,你可以通过鄙视他们来显示你的优越感,而且实际上没人玩才最好,因为很多时候你知道某件事情,跟你去做了某件事情差别会很大,如果你不用去做它,那么至少你不需要承担把事情搞砸的风险。

还有一个原因就是新鲜感,新鲜感的特点就是“新鲜”,有一个保质期,但这个时期过了,我们就会放弃,所以如果我们不停的学习新技术就可以保持这种新鲜感,加上我们学习了某个东西,知道它是什么以后就会自以为掌握了它,这是一种自欺欺人的错觉,这个错觉反过来会加深我们对新技术的追求。

为什么尽可能不要学习新技术

日常工作中,绝大多数的新技术都是难以实践的,除非你跳槽到一个使用新技术的公司。通常情况下,切换技术的成本很高。当redis或者mongodb刚出来的时候,你可能还在使用mysql+memcache。如果你看了一些文章介绍redis或者mongodb的特点,并且你自己也做了一些benchmark的对比测试,发现redis和mongodb的性能确实不错,也许此时你会觉得mysql+memcache又老又丑,但是你真的可以在现实工作中抛弃mysql,而转到redis或者mongodb么?也许你唯一能做的就是在新项目中使用它们,哪怕就是这样,当你的新项目上线后,你会发现系统的维护成本增加了,而且团队的学习成本也增加了,最可悲的是,你实际只是使用了它们的皮毛,离真正掌握它们还有相当的距离。

繁荣也许是好事,但也并非完美无缺,新技术的繁荣必然会导致的技术的同质化。这一点我们可以轻易发现,ruby、python、php都主要用于开发web应用,所以如果我要开发web应用,显然我只需要掌握一种就可以。jQuery可以操作dom、发送ajax请求,angularjs也可以做这些事情,如果我只是想实现这些简单的工作,我有必要学习angularjs么?除了同质化外,大多数技术之间都存在壁垒,当你熟悉掌握了某个技术之后,如果想转到其他的技术上去,这不是一时半会就可以完成的。假如你之前是一个Java程序员,你想使用Go语言开发,虽然你用Java做的事情和用Go做的事情是一样的。你想使用Go语言的最关键的理由就是它是新技术,而且现在很火,很显然这不是一下子可以搞定的,你需要学习Go语言基础,需要学习Go语言是怎么打包封装的,程序开发完了,你还需要搞定Go语言程序的发布和部署,虽然这些工作Java都可以做,并且你已经很熟悉。

也许你看到这里会喷我:“既然不学习不使用新技术,那还要新技术干嘛,大家都回到远古时代用汇编写代码!”。稍安勿躁,我的意思是学习新技术要考虑现实的情况,而且学习方法也很重要。其实无论是什么技术,只有不断的实践才能掌握它,而且只有掌握了才能说是学会了某个技术,才能最大的发挥它的作用。谈到实践,大家都知道如果只是看书是学不好什么东西的,必须找机会使用它,无论是参加开源项目,还是在工作中使用,这里不讨论开源项目(我们实际上没有开源生态圈)。我想表达的就是,在工作中,我们必须得谨慎地考虑要不要使用新技术,我比较反对的就是不顾现实的需求而强行推行新技术,就像上面的说的那个redis/mongodb的例子,redis/mongodb也许很好,但如果我们使用mysql+memcache就可以解决问题,并且实践也证明了它们的可靠,这个时候强行在项目中使用只会把事情搞得更负责,这是一种不负责任的表现。

不过另一方面我承认采用新技术是一种进化,大多数采用新技术的创业公司都更有活力。所以新技术的发展有时候也是一个机遇的问题,如果某个公司采用了某个新的技术做出了一个牛逼的产品,这个技术可能就会火。对于开发人员而言,如果可以在项目初期就使用新技术,或者是去一个完全使用新技术的公司,这虽然有一些冒险,但也不失为一个不错的使用新技术的方式。

不过对我而言,也许我会去学习了解某个新技术,但我只会使用哪些经过了时间检验的技术。因为新技术是否能够存活下来,并且成为主流、占领市场只有通过时间来检验。而且我一直认为仅仅只是学习了某个技术离真正掌握它还有很远的距离。所以如果今后有人跟你吹嘘某个新技术多么牛逼、比起老的技术有多么的好,如果你觉得不爽的话,可以问问它是否用过那个技术做过什么东西,如果回答是否定,那你完全可以不用在意它说的,如果回答是肯定的,你可以问它在使用过程中有没有什么问题,通过问题你就可以了解他对这个技术的掌握程度,而且你也可以通过问题真正学到有价值的东西。而且我相信如果你可以掌握某个旧技术,成为了它的专家,那么你也可以轻易的掌握某个新的技术。

既然我们应该尽可能不要学习新技术,那么现在问题就来了,作为一个程序猿,应该学习什么呢?