谈“技术含量”的问题
最近又从离职同事那里听到这样的抱怨(原因),说做的事没有技术含量。想一想,从事车载软件开发这个行业快8年了,这个话题似乎从来没有停过。我自己曾经也为自己做的事是否有技术含量而苦恼过,今天就专门花点时间聊一聊。
为什么会觉得没有技术含量?
真正思考过这个问题的人很少。简单粗暴地概括,大部分人(我所遇到的全部)都只是觉得,“这个事我会做了,所以没有技术含量”。也就是说,他们只是不愿意用已经会的方法,做曾经做过的类似的事。这可以理解,人们都不喜欢做重复的事。但现实确实是,大部分的工程师的工作,都是用已经掌握的技术,去做相对熟悉的事。因为
我们是在做工程,而不是做研究
虽然我一直觉得“软件工程”相比起其它的工程而言,是愧对“工程”两个字的,但是毕竟我们是在做产品,而不是在做科研。做科研中失败是常态,做产品如果也经常失败,那公司就完蛋了。那么怎么算“成功”?就是在规定的工期内用可接受的成本完成了满足质量要求的产品。要达到这个目标,就要求
一、尽量采用成熟的技术
工程师们(程序员们)要对软件所涉及的技术比较熟悉(知道什么地方有些什么坑),并对要开发的产品相对比较熟悉(有行业经验)。只有这样,产品才相对有可能在要求的工期内完成。(说话,很多的加班其实是由于技能和经验不足造成的)。如果一个产品涉及到的技术有20%是这个团队的成员所没有掌握的,那么会有80%的概率出问题(工期要超,或是成本要超)。
二、细划分工,提高效率降低风险
5个人干半年的活,只要有可能,就会安排10个人做3个月。问题域被细分了。这样每个人做的事相对比较窄,很多程序员只做一小部分,没有对整个软件的把握,不知道自己做的这一块是做什么的。所以也往往觉得“没有什么成长”。另外,细分的结果是使用工作简单了。举个例子,举个例子,做SSL的通信协议是比较难的(粗暴地说,比较有“技术含量”),但在工程中往往不是安排一个人把SSL通信协议做一遍,而是安排多个人去做,某个人完成RAS算法,某个人完成ASN.1编码,某个人做X.590的支持,某个人做DES等等等……问题细分下去之后,每一个小部分会比原来要容易很多,于是参与的人就觉得,没有什么“技术含量”了。(是的,细分下去看,所有程序不都是if else for嘛?)
这就是“工程”的特质。不同的公司会因为各种原因情况稍有变化,本质上是类似的。
难道工作就没有什么乐趣和挑战性了吗?
当然不是!
正如前文所说,软件工程虽然号称“工程”,与传统工程相比却还有很多差别。一是因为软件的边际成本很低,一旦完成,就可以无限地复制,所以不会有真正意义上的“重复”地生产,软件开发本身是一个创造性和实验性并存的过程,它本来就需要试错(测不准的程序员)。也因为如此软件工程师能力的“度量”是个很大的问题(创造性是很难度量的)。因为很难知道,某个功能,一个“合格的”工程师应该花多少时间写完,写出来的代码量应该是多少,这样的代码在质量上,可维护性上,扩展性上表现如何。遵守流程以及使用熟悉的技术能只在一定程度上保证项目能做到及格。虽然如何精确定义优秀的工程师是很难的,但项目要想做到出色,优秀的开发工程师确实起决定性作用。这种工程师对新的技术和手法感兴趣。他们尽量在能控制住风险的情况下,采取一些新的方法和工具来提高效率,尝试新的设计来提高代码的维护性和扩展性。这是让软件开发工作充满乐趣和挑战的部分。
软件技术发展日新月异,而且学习的来源非常广泛,所以,有上进心的程序员们可以用很多办法学到很多新东西(开源项目,博客,书,等等),然后在工作中去尝试自己学到的东西用来提高效率,掌握不同技能的程序员之间的效率差别可以成十上百倍(所以有高手和菜鸟)。在软件开发的领域,高手几乎都是靠自学、实践最终领悟得道的。在这部分程序员看来,手头上的事总是有新办法可以做,新工具可以尝试。并且在这个过程中,工作也越做越好。同样的事,有非常多的方法做,他们从不觉得不会再有进步了,因为有无数的东西可以学,学会之后实践到工作中去。
真正对技术感兴趣的人,反而很少会为“没有技术含量”这个问题而烦恼。因为他知道所有的问题都存在着更好的解决,只是看你有没有兴趣去找这样的解法。觉得工作没有技术含量的人往往是这样的:期待别人来教自己,从不主动学习和思考。所以在我看来,在软件开发中,“技术含量”的问题大多数时候只是个伪问题,只是一个借口而已(有的人意识到了,有的人没有)。真正热爱技术的人在离职时也很少用“没有技术含量”这种笼统的方式来表达,更多的是已经非常清楚自己下一步想做的是什么,他觉得在哪里才能得到更好的环境去做他想做的事。
不是“技术含量”的问题,那是什么问题?
从上面我们知道,“是否有技术含量”的问题其实和他们是否真心想做技术没有多大关系。深一层地追究,其实他们有意或无意中,真实想的是:“这个事我已经会做,我要掌握点其它的知识,用来提升自己的价值(也就是,让自己在市场上保值或是升值)”。不信?试着想一下这个问题:“给你一份工作,月薪2万,每年涨薪15%,保证终身雇佣,工作内容是每天把各大网站的IT新闻收集起来发给经理”,你是否愿意接受这份工作?如果愿意,那么你根本就不在意“技术含量”这个事儿。你是在乎“钱”。
这没有什么不好意思承认的,追求好的生活天经地义。那么大家自然会关心
什么能力是值钱的?
市场上稀缺的才可能是值钱的。
这点大家都很清楚。十年前非常流行“程序员是吃青春饭”的这种说法,现在要少一些了。那时所谓程序员们所做的事都处在行业链下游,需要的技能大多数没有多少门槛。新人也很容易就能掌握,谈不上稀缺。随着行业的发展,这个状况逐渐在发生变化。也就越来越需要一些高端的人才了。这些人才大概会有下面这些特点:
1. 在某些领域有比较丰富的经验(业务和技术方向)
新人一般学了一段时间之后都会觉得“这也不过如此”,但有经验的人都知道,“其实水很深”。这种过来人的阅历在项目中是非常重要的。有这种经验的人比较不容易犯错,也不会轻视可能出现的困难。另外,他们的抗压能力也比较好,遇到之前没出现过的问题不会慌了手脚或是束手无策。他们大概会知道还有什么办法可以尝试,有什么人可以求助。每个领域,都有一些很特殊的问题,至少要经历好几个项目才会有所把握的经验。拥有这些经验的人在对风险的控制能力要强得多(最直接的结果就是加班会少)。在设计的前期也能预见性地解决大部分可能出现的问题,而避免在项目后期疲于解决bug的情况。而且每个项目都会有几个很难解决的bug,需要相当的技术和经验才能搞定。
要做到这一点,需要长时间在某个领域的积累,不通过遇到和解决大量的问题,是很难得到提高的。
2. 有较强的学习能力
前面说过,程序员们几乎不会做真正重复的东西。学习能力对于软件开发来说无比重要。这一点大家都很清楚。学习能力来自哪里?一是独立和积极地思考。这一点其实非常重要,这直接影响到学习的效果。二是基础好。现在想来,大学学的那些课程,都是非常重要的。因为快速地学习能力绝对是基于这些基础的。三是经验,旧有的经验往往能加快新领域的学习。会C#再学Java,就不再需要花同样多的时间了。
3. 带团队的能力
这一点几乎不需要展开说。但确又是不少人心里不太愿意承认的。特别是不善沟通的技术人,往往在心里看不起那些技术并不是最好,但沟通能力、计划能力方面很平衡而当上Leader的同事。但现实就是,一个团队除了极少一两个人能在技术上给团队带来很大价值之外(他们能解决99%的程序员不能解决的问题),其它程序员的水平差别并不会显著到不同的量级上。能带一个团队(几个到几十人)做好一件事,反而是比较稀有的能力。
所以,其实那些以所谓没有技术含量而离职的人,很多人后续发展并不好,因为他们总是归咎于环境,不主动实践和思考,并且因为不够稳定而在从事过的事方面都没有深入的积累,反而使得自己没有多少“特别的价值”可言。
很是可惜。
时间比较仓促,很多点没有能展开写。以后有机会再谈。