优秀程序员思考、学习新技术的原则和方式
最近了解了几个 MVC 的框架,其中有两个是公司内部的。发现这些东西都是类似的,从处理逻辑到页面渲染;从 service 到 layout;配置的实现无非就是 XML,或者 annotation……我有种感觉,兴许已经跳不出这个思维圈子了?
如今的时代,是一个概念翻飞的时代,oschina 里的开源软件数量就已经超过了两万,五花八门的技术层出不穷,到底什么技术才是值得学习的?
有位朋友说,他想学习一些关于 Android 上的开发技术,兴趣驱使。几个月过去了,他说他已经能做出许多小程序了,可是他现在回想起来,掌握一门技术是好,可兴趣之外还有什么呢?他说,“如果我的工作中不使用 Android 平台,我学它还有何用?”。
学习技术到底是一件有意思的事,还是一件痛苦的事?读书的时候,我曾经买过侯捷翻译的《深入浅出 MFC》,对那时的我来说,似乎太困难了一点,我强迫自己看完了三分之一,实在是没有毅力继续往下读了。我在其中察觉不到快乐,这本书在当时似乎充满了生涩。
如上这样的故事太多了,很多时候,程序员们(包括我在内)辛苦地学习,有的没有好的效果,有的过程充满痛苦,有的更是不知道我学它的目的是什么。
国内的教育体制,培养了这样一批人:
他们努力、奋进,热爱技术,愿意投身软件行业,愿意写出高质量的代码,他们对业界的东西很感兴趣,他们愿意学习扎实的基础知识,他们渴求火热的新技术……
几年以后,他们拥有广泛的视野,阅历宽阔、经验老到、言辞犀利,对行业动态了如指掌,显然,他们是行业的博学者。
然而……
他们却缺乏这样一种能力——思考。
欠缺思考容易导致这样的现象:
不会做设计
遇到了问题,拿见到过的、学到了的熟悉的框架、方案、模式往上套,而不仔细分析其中的利弊,只是尽可能地寻找最接近当前问题的解决途径。
有的是不会做系统设计。和少数所谓的“架构师”接触过,他们“只懂业务,不懂技术”,这样设计出来的系统只能满足功能性需求;而论坛上的一些具 体问题的讨论话题,则暴露出一些跟帖讨论者“只谈技术,不提业务”,譬如“XXX 大容量的解决方案”、“秒杀系统的终极架构”,企图对某一类宽泛的问题,设计出一套放之四海皆准的通用解决方案。
还有的则是不会做面向对象设计,缺少抽象和解耦的能力,这样的例子就更多了。朋友告诉我,他的单位有一位写 Ruby 的老员工,一个庞大的工程,代码里面居然只有一个上帝类,就搞定了所有的问题。
不能坚持自己的观点
这一点在面试中最容易观察到。应聘者有刚毕业的学生,也有工作超过 10 年的有丰富经验的从业者。他给出一个粗略的方案以后,在方案没有细化到一定程度以前,很难给出优劣的评论,但是,如果你轻轻地 challenge 一下,他就迅速放弃本来的构思,跑到你的思路上来。
例如,SNS 系统中,服务端有消息要怎样通知到客户端,这样的一个问题,解决方案有很多种,比如客户端轮询、服务端 hold 住连接推送等,各有利弊。应聘者应当有自己的观点。
不能细化一个问题解决方案
怎样区分一个空谈家和一个实干家?给他一个具体的问题是最好的办法。在我刚工作的时候,我曾经很钦佩那些在活动中、讨论中高谈阔论的人,我觉得 他们很能说。可是后来我逐渐发现,能说的人实在是太多太多了。细化设计、甚至落到编码,才是对一个程序员真实的检验。当然,如果你觉得做软件设计的人可以 不熟悉编码、架构师可以不首先是一名高级程序员,那我们也没有什么可谈了:)。
如果你会学习,你可以成长得很快;如果你不会思考,你永远只能跟在别人后面。
在新技术的学习上我认为也应当多思考,不同的人有不同的学习动机。在非外界所迫的情况下,对于新技术的学习,我的观点可以概括为:
它要解决什么问题,就是所谓的问题域,是我关心的吗?
我没有去研究操作系统底层的实现,并非这没有价值,而是我没有兴趣,这就是问题域的影响(不过现在我有兴趣了,我想做一些这方面的事情)。
和过往解决方案它的优势在哪里,是否显著?
这是 competition,重复的技术是没有生存空间的(当然,你是微软的话除外:)),就像互联网同一个类型的网站,竞争到最后就那么两三家。就像 Groovy,我很喜欢它,但是有了 Scala 以后,我觉得兴许有一个要死掉(Groovy 创始人说,如果他早些知道 Scala 的话,就没有 Groovy 什么事了。具体的报道请去 Google 上搜他的 blog)。
它的实现和带来的效果上看,有没有很有意思的思路,是值得借鉴和思考的?
这是最难讲的一个问题。以去年初开始接触的 Node.js 为例,它可以做到把后端的聚合(譬如 portlet 之流)放到前端来,后端只保留一种类型的页面服务——页面模板,以及若干易于管理的 API 接口,大大简化了后端体系的复杂度,而且还能把压力分散到前端来,这是我早些年不曾见到的。
这三个问题想过之后,觉得有价值,我才去学习。要不然,对我而言就是不想深入的东西,了解了解也就罢了。
新技术学习的方式呢,我想说这么几点:
寻找切入点
我很喜欢 BlueDavy 的 blog 上的一句话:“理论不懂就实践,实践不会就学理论!”。
最后最好是要落到动手实践上去的,但是倘若习惯从那些原理介绍的文字入手,未尝不是一种不好的选择。而且,现实情况会有一些约束,例如在了解几 家互联网公司的云平台的时候(Amazon 的 EC2,M$的 Azure 等等),除非你是这几家公司的员工,否则是很难深入其中的。
寻找自己的兴趣点
学习应当是一件有意思的事情,当你的大脑排斥它的时候,我不相信可以很容易地掌握这门新技术。如果你找不到兴趣点,那么,不妨回到我前文对于新技术是否值得你学习的观点上去,既然你没有什么兴趣,你学它干嘛?西安软件培训
善于比较
比较是一种非常容易上手的思考方式,和什么比较?和相似技术比较,和操作系统、网络这些基础设施上面的例子比较,最后,和生活中的例子比较(譬如,JAVANIO 的实现是一个很好的例子)。
不断获得回馈
回馈是什么?做出一个 HelloWorld 的例子,就是一个极好的回馈;理解某一项实现原理,联想到其它类似的实现,产生一种恍然大悟的感觉,也是一种回馈。在学习的过程中,不断产生回馈,意味着你不断地收获成就感,这是继续下去的动力之一。