年愈三十,开始有身边的朋友、也有猎头开始提醒我,要注意为35岁的职业危机做准备,今天又在这里和这里读到一些相关的言论。编程是不是有前途的职业?35岁以后一定得转行?新技术层出不穷,怎么才能跟上技术发展的趋势?工具越来越牛,以后编程像组装乐高积木怎么办?人到中年家务世务缠身,怎么和年轻人竞争?我没有答案,或者我也无意于去解答这样的问题,我只是想起以前读Fred Brooks的No Silver Bullet。
No Silver Bullet的中心思想是软件开发的困难分为两类。一类是偶然困难,另一类是本质困难。偶然困难可以通过技术的进步来解决,比如说检查句法错误就是偶然困难,写出绘制窗口的代码也是偶然困难,现代IDE基本解决了这些问题。而本质困难没有工具或技术可以消除,软件的本质是一堆互相作用的抽象结构:数据,算法,关系,函数调用。这些抽象结构应该尽量独立于表现它们的具体形式。软件的本质困难在于写出这些抽象结构的规范,设计这些抽象结构,和测试这些结构的正确性。如果上述判断正确,那么世上便没有银弹。幸好,到目前为止B爷爷的判断颠扑不破。
银弹和我们的职业发展有什么关系?很简单:我们得把时间用于学习解决本质困难。新技术给高手带来方便,菜鸟们却不用指望被新技术拯救。一流的摄影师不会因为相机的更新换代而丢掉饭碗,反而可能借助先进技术留下传世佳作。因为摄影的本质困难,还是摄影师的艺术感觉。热门技术也就等于相机,不停追新,学习这个框架那个软件,好比成天钻研不同相机的说明书。而热门技术后的来龙去脉,才好比摄影技术。为什么推出这个框架?它解决了什么其它框架不能解决的问题?它在哪里适用?它在哪里不适用?它用了什么新的设计?它改进了哪些旧的设计?Why is forever。软件开发技术的半衰期20年,也就是说20年后我们现在知识里一半的东西过时。20年后IT界一半的技术过时,我们学的过时技术远远超过这个比例。
我们的行业一直在变化、一直有大量的年轻人涌入,说明我们的行业一直在创新、一直有生命力,问题在于我们能否同步维持自己的生命力,为此需要关注以下几点:
- 扎实的基础。这就好比路都走不好就别想学跳舞一样。
- 学习的能力。到底怎样快速掌握新知识和新技能?怎么样运用他们?这就是学习的能力。一些学霸们通常错误理解了学习能力的内涵,你学得好但能否应用好并解决问题呢?因为这是工程的要求;你学得好能否提出更好/新的理论/方案呢?这是研究的要求。
- 终生学习的习惯。只是把技术当吃饭的,这样的人的确没什么终生学习的热情吧。乔帮主说:Have the courage to follow your heart and intuition. They somehow already know what you truly want to become,虽然成为云风那样的铁杆编程迷有点难,但如果不能喜欢自己做的事情,人生的不完整不用等到35岁时年轻人来冲击了。
当你年过三十五,身边都是如狼似虎、加起班来永远不差鸡血的90后和00后又怎么了?只有自己才能淘汰自己,天赋是个正的常数,世俗事务是个负的——也可能是个正的——常数,而技能的增长是时间的一阶导数。有意识地注意自己的缺点,执着寻找提高自己水平的方法,不断吸取教训,并把学习成果用到自己的项目里,如此循环,不断完善培养自己的经验,一定可以成为真正的专家,而真正的专家永远不会被淘汰。
还想说一下终生学习的具体做法:
- 始终重视基础。一遍遍地重读经典。知道lamdba,知道meta-object protocol,知道动态类型,Ruby应该不难了;知道分布计算的原理,知道应用中的常见问题,知道组件开发,J2EE应该不难了;精通数据建模,精通SQL甚至关系代数,从一个DBMS转向另外一个DBMS应该不难了;通底层开发,从一个OS转到另一个OS应该不难了;精通数理统计,要学习贝叶斯网络,将其应用到机器学习应该不难了;精通yacc,转到ANTLR应该不难了;精通Python,学习JavaScript里的新功能应该不难了;精通并发计算和函数编程,从Java转到Erlang应该不难了;精通Java的类库,转到.NET应该不难了;精通ACE,转到Twisted应该不难了… Damien Katz一边学C++一边重写了Lotus Notes的公式引擎,凭的什么?鲍岳桥他们从汇编直接跳到Win32,写出联众,靠的什么?绝对不是无休止的加班吧。
- 重视理论学习。学习理论能拓展我们总结一般规律的能力,一个优美的理论总能用很少的元素涵盖广泛的现象,包括理论产生时还没有出现的情况,实际上,合格的理论必须有预见能力。比如虽然Lambda Calculus只有7条公理,但表达能力和图灵机等价。换句话说,实现了Lambda Calculus的编程语言,比如LISP,尽管句法简单,却能和基于图灵机的语言,比如C++,一样强大。而在程序设计方面,一个好的设计也应该能处理一般情况,而不是一堆特例。比如如果一个程序里有大量分散而臃肿的if..else,这个程序多半有问题。进一步说,理论学习能训练我们抽象的能力。
- 阅读前沿论文。把握未来,学术界和理论界在探索的问题,总有一天会落到工业界来…
- 关注开源社区。在一项技术开始流行起来之前就有一定的了解,了解为什么会被发明出来,解决了什么核心问题,有哪些精妙的设计…
- 学习行业知识。进而扩展到金融、法律的和其他的。了解业务逻辑,了解管理流程,了解这个世界是怎么运转的,这样能把自己的技术和商务结合起来,解决实际的问题,会更加大有作为。
一句话,不要焦虑和抱怨。而且,我们唯一可以管住的只有自己。