第一篇:如何用两年的时间面试一个人-刘未鹏
Joel Spolsky曾经感叹:招聘难,难于上青天(此处笔者稍加演绎:))。他有两个辛辣但不乏洞察力的断言:真正的牛人也许一辈子就投大概4次简历,这些家伙一毕业就被好公司抢走了,并且他们的雇主会给他们不赖的待遇,所以他们也不想挪窝。(刚刚去世的Dennis Ritchie就是这样一个人)而“人才”市场上能找到的大多都不是什么人才。招到这帮人轻则费钱重则把你公司搞挂。
诚然,也许没有哪个行业像IT行业这样,无形资产占据公司的绝大多数资产。拒坊间传言比尔·盖茨就曾经说过类似这样的话:只要允许我带走100个人我可以再造一个微软。这话没搜到原版出处,但是从一个侧面反映了IT公司当中智力资产所占的比例之重。
所以一个自然的推论就是,招聘也许是一个公司决策当中最最重要的一个环节。Joel Spolsky把他在这方面的观察,体会和洞见集结成了一本小册子《Smart and Gets Things Done》,开篇就挑战“产品是公司成败的关键”这个传统观念,他认为创造最适合工程师生活的环境,留下最优秀的人才才是最先最重要的一步,接下来好的产品是水到渠成的事情。国内iapp4me.com创始人郝培强正是这个理念,所以他在微博上说:
我们是小公司,工资开的不高,也不招太多的人,但是电脑都是iMac27,iMac21,Macbook pro15,基本上比很多大公司都好多了。软件没盗版,刚才photoshop的正版我也收了。中午管饭,公司备伞。哈哈。节日假正常放,从不加班,早晨11点上班,下午6点下班。我是有资格说某些大公司的员工苦逼的。
事实上,米国找个人尚且难成这样,搞得Joel还费心费力写本书语重心长地劝企业们要善待好工程师,国内找个人更是难上加难,国内高质量问答社区知乎创始人周源就曾经在知乎上分享他呕心沥血的招人历程,看完真是让人慨叹这年头找个靠谱的人多不容易(这条知乎问答还有很多精彩的跟帖):
其实从 08 年到现在,我一直想这事能不能有点窍门,或者是实用的方法,结论是几乎没有。我用过的大家都用的方法:
在水木上发贴子(有点效果)
在蓝色理想上发贴子(无效)
在技术邮件组里发贴子(无效)
买 51job/智联 最便宜的服务(有点效果)
给所有可以想到的人打电话,请他们推荐(无效)
给所有和你讨论过创业,喝过点小酒的人打电话(无效)
约前同事私下谈(有效)
我用过的大家可能没有用的方法:
上 twitter,看 XXX 的 follower,一个一个看,看他们的 twitter,博客,Google Reader 分享,想办法搞到邮件,联系,半夜电话骚扰。
上豆瓣,前端后端挑几本重量级的书,去找想看,看过,正在看这本书的人,一个一个看,看他们的活动,博客,Google Reader 分享,想办法搞到邮件,联系,半夜电话骚扰。
找同事,问他们都看什么技术博客,想办法搞到邮件,联系,半夜电话骚扰。
正是这样的不容易,才有不少公司走内部培养的办法,这里的逻辑是:一上来就招到靠谱的人太难了,但找一块靠谱的璞玉然后雕琢雕琢相对就简单很多。这倒是个办法,但这样做的人难免就陷入了纠结:培养好了,人跑了怎么办。这也不能怪招聘的公司,的确是人之常情。其实解决的办法也很简单,培养的时候进行适当引导,让员工发挥自己的主动学习能力,这样不但人得到更多成长,公司也不会觉得投入太多患得患失。所谓师傅领进门修行在个人。
但是,这仍然还是没有解决根本的问题,就是招聘真的很困难。应聘者固然觉得自己是在“海投”,大海捞针一般。而招聘者何尝不也是这种大海捞针的感觉。这就好比两个人谈恋爱,都想和对方好上,但是偏偏就聊不到一块去。
招聘真的很困难。以至于招聘者每年需要绞尽脑汁出新笔试题,以免往年的笔试题早就被人背熟了。出题很费脑子,要出的不太简单也不太难,能够滤掉绝大多数滥竽充数的但又要保证不因题目不公平而滤掉真正有能力的,要考虑审题人的时间成本就只能大多数用选择题,而选择题又是可以猜答案的(极少有人会在选了答案之后还敢在空白的地方写为什么选某答案的原因的)。更悲催的是,有些题目出的连公司的员工们自己都会做错(真的是员工们做错了吗?还是题目本身就出错了?)
笔试完了之后如果还没有被鄙视就要进入面试环节,姑且不说笔试题的种种弊端,就说面试环节,短短几个小时的面试(大多数公司也许连几个小时的面试时间都没有),既需要全面考察基本知识,又要考察编程素养,还要考察(也许最重要的)性格心态。再然后还有一项根本没法考察但却占据程序员相当一部分工作时间的:debug能力。面试官不但得找准问题,不因对方一题答对而妄下结论,也不因一题打错而就扼杀机会,还要以管窥豹,从一朵花看到整个世界,从面试人的举止言谈,分析问题的方式,甚至写程序的笔迹来观察这个人的性格,做事的方式和心态,简直是要面试官具备心理分析师的水准才行。
这厢要招人的雇主苦不堪言,那边找工作的人也是一团乱麻。绝大多数应届生直到毕业也不清楚他们想要去的公司到底需要什么样的能力,或者说,他们到底需要具备什么样的能力才能在应聘季节拥有自己的选择权。中国虽然本科教育环境差,但是同样有很多的人在本科希望整点东西出来,他们有一腔的激情和抱负,有强大的动力,但就是不知道自己需要掌握哪些技能才能满足雇主的要求,求告无门,整年整年苦闷的像没头苍蝇一样乱撞(我就收到过很多次这样的来信,他们往往很想学点东西,但又不知道哪些重要哪些不重要,到底该学到什么程度,不知道导致不确定,不确定导致决策瘫痪,干脆嘛也不动,荒废时间)。
什么叫熟练?什么又叫精通?那么扎实呢?两年的YY经验又意味着什么?能这么简单的量化吗?同样是两年的“实践”有的人能真的学到点东西,有的人也许近似一无所得。那么实习呢?很多人都一定要在简历上弄个实习经验,这个又能说明多少问题呢?大作业呢?得奖呢?有一次我面试一位同学,据简历说编译原理课的大作业得了一等奖,可我一问什么是递归下降,就傻眼了。
这个现实的结果就是,现在绝大多数应届简历而言,也许最具信息量的部分不是“精通XXX,熟悉YYY,掌握ZZZ”,不是“在UUU实习过”,也不是这个项目那个作业,反倒是越来越被认为不重要的一项:毕业学校。毕业学校本不应该是最具信息量的,它之所以最具信息量只是源于一个悲剧的事实:简历上其他条目实在信息量太少了。所以靠谱的面试者往往学会了无视简历上华而不实的内容,只相信面试的时候亲眼所见,扫两眼简历也就罢了,最后还得自己捋起袖子慢慢面。而应聘者也许也知道招聘的也不会细细纠简历上的条目,所以什么词也都敢往上捅,反正先过了HR筛简历这关再说。从经济学角度来讲,应聘者的这种策略是正确的,没有代价(因为目前似乎没有公司会去给已经申请过的人做一个诚信数据库),但至少有可能会带来巨大的收益。应聘成了博彩。而博彩式的应聘给招聘公司带来了巨大的筛选压力。简历成了摆设。
那么招聘这个关系里面的第三者——学校——所处的位置呢?学校更关心的是毕业率和就业率,这似乎是件好事,有这个为目标,那么老师们似乎应该努力让自己的学生多学点东西。可惜就业的质量似乎不是最重要的指标,此其一。其二老师本身大多数没有丰富的业界经验,根本不知道企业整整需要的人才是什么样的,可能花了精力,但却培养不出雇主真正需要的人。另一方面,老师所起的作用很多时候甚至是一个负面的作用,例如布置大作业表面上看上去是培养学生的能力,我们姑且不说抄袭,假设每个人都做了,那么大作业本身能够衡量多少东西呢?能否衡量代码质量,能否衡量团队协作能力?能否衡量交流能力?考虑到大作业用到的东西往往都是书里面现成的,大作业甚至不能衡量学习能力。而学习能力简直算是这个行业最重要的能力没有之一了。
所以,简而言之,如果把人才培养/招聘这件事情本身类比做一个项目,那么这整个项目迄今为止就是一个巨大的失败。为什么这么说呢:
和需求严重脱节:作为人才需求方的雇主的需求到底是什么?绝大多数应聘者都没搞清。更严重的是,这却一点都不是应聘者的错。因为雇主是stakeholder,是雇主自己的责任得去说清楚需求是什么。结果应聘者实现的不是雇主想要的,雇主想要的应聘者没有实现。
应聘者雇来培训自己的人根本不管事:学生交了学费,就相当于雇老师来培训自己,可培训者根本也不了解(或不关心)他的客户们的需求。这里,学生是需求方,老师则是实现方。弄清需求的职责在后者,可后者也弄不清。学生自己也弄不清:学生自己既是需求方(需要特定技能),也是实现方。可他们自己也弄不清需求到底是什么。
以上三点还不是最严重的,最严重的在下面:
明白需求是什么的也不知道怎么实现:怎么去培养现代IT企业真正需要的人才?特别地,实战能力怎么培养?代码素养怎么培养?协作沟通能力怎么培养?学习能力怎么培养?就算这些都知道怎么培养,又怎么给在象牙塔里头,离催命之日还遥遥无期的学生提供足够的动力呢?而学生自己就算知道该学哪些技能,又怎么知道具体怎么着手?什么是最有效率的学习方法?又如何让自己保持学习的热情?
以上这些问题,就是当下人才培养/招聘的惨淡现状。简而言之,在雇主和学生之间,横梗着一条巨大的鸿沟,两头都很着急,两头都有动力,但就是没有方法,君住长江头妾住长江尾。像微软谷歌这样的,干脆和高校合作,直接插手本科或硕士的教育,从而保证到时有足够强的候选,某种程度上,这的确是根本解决之道,可一来这代价太大了,非一般企业承受得起,二来这影响面也太小了。
这一切,也许将在未来的5年发生根本的变化。
《Switch: How to Change Things When Change Is Hard》(中译《瞬变》)里面指出,表面上看来非常困难的改变,也许是因为根本就没有抓住要害。在书中作者通过大量案例分析和心理学研究,雄辩地指出以下几点促成改变的关键之处: 触动内心的大象:要改变的人必须要有情感层面的动力。有一些特定的方法能够比另一些方法更能对人的情感产生触动。
给出清晰、明确的目标:目标一定不能含糊,模棱两口的目标让人无所适从,导致决策瘫痪。例如最近我们组在招实习生,我在微博上发了一条招聘信息,其中提到“扎实”的系统底层知识,有同学就写信来问,怎么叫“扎实”。我傻眼了。比尔·盖茨就以目标清晰明确著称,不仅在战略制定上,“每个人桌面上都有一台PC”,而且居然还体现在招聘上——“如果你读完了TAOCP,那么就给我投简历吧”。多么清晰,明确的目标啊——虽然高了点,也许这就是比尔·盖茨至今还没被应聘邮件淹没的原因:)
给前进的道路扫清障碍:人是懒惰的,只要有借口就会不想往前。如果既有明确的目标,同时道路又直直指向目标,一览无余,只等你开始往前走,那么便没有借口,一往无前。
那么让我们对照上面看看,可以做什么?
首先,内心的大象不需要触动,中国有足够多的人足够早就开始焦虑就业的事情,只是不知道往哪使劲,这部分人如果把劲头用到正确的事情上面也许足以满足现在的IT企业人才饥渴了。至于其他人,好吧,也许身边的人开始动起来他们也会被触动。
然后是清晰、明确的目标。这一点上目前雇主们的做法可谓好坏参半,好的一点是大家都强调要有实践经验,要有团队协作精神,坏的一点就在基础知识和技能的要求方面,可谓再含糊不过了:“精通XX语言”,“扎实的XX功底”,“熟悉XX技术”,甚至看上去最具量化感的描述“X年YY经验”其实都根本说明不了多少东西,在信息量方面还不如我家门口菜市场上一家卖酥油饼的店门口挂的横幅——“三天不硬、至少六层!”。
很多朋友也许注意到一个现象,现在企业对招聘者简历的要求也在变得越来越灵活变通,例如ThoughtWorks在招聘的时候就希望招聘者能给出自己的博客地址,博客对IT行业的意义也许胜过其他所有行业,一个积累多年的技术博客比任何简历都更能说明问题。台湾的郭安定也说“为什么写技术博客对新人如此重要”。可惜这个做法也有一个弊端:并不是所有技术牛人都写博客,有人就是只干不说型的,而就算写博客,乃至动手写过一阵子的,写一个常年的博客,也远比你想象的更为困难,因为很多时候,写(说)得靠谱比做得靠谱更难。所以这个过滤器很多时候用不上。
但是这的确表明了一个思考的方向,就是寻找更具鉴别力的过滤器,Stackoverflow Careers 2.0之所以强大,是因为Joel Spolsky和Jeff Atwood这两位常年混社区的资深博主创造性地将一个人在社区的活动历史浓缩成为一系列的量化数值,由于这个历史很长期,所以鉴别力非常高。但它同样也有问题,就是对于应聘者来讲相当花费时间,而且并不是花时间(在Stackoverflow上回答问题)就一定能花到点子上。
到底什么特征才是既通用,又能够有效地鉴别高低应聘者的特征呢?这个特征必须不像博客那样难以实现,同时又必须有足够的区分度。
有的地方在要求填写简历的时候必须填上平时都访问哪些技术网站。恩,很不错的尝试,可区分度仍然还是不够,因为上网站上查东西毕竟只占现阶段大多数应届生的少数信息来源,特别是当我们看重得更多的是应届应聘者的系统性的知识基础的时候,网上的东西虽然丰富,但属于提高班,也更为琐碎,什么是更系统的知识来源呢?答案其实大家都知道—— 书。
我一向认为,很多时候,是否好好看完一本好书,对一个人的提升往往能达到质的区别。就算不好好看完一本好书,马马虎虎看完,只要书是真的好书,也肯定会有很大的提高。我在面试的时候就经常询问对方看过哪些技术书籍,经常上哪些网站,订哪些博客。这里头尤其数书籍这一项的区分度最高。此外,好书和坏书的差别,从本质上,就是学习效率和大方向的差别。一本烂书可以浪费你半年的时间,但一本好书却可以为你带来真正扎实的基础和开阔的视野。人们常常用“内功”来形容扎实的基础,认为学好了内功以后学什么都快,其实一点没错,好的“内功”书不仅讲清楚深刻的原理,而且指明技术的本质,刻画领域的地图。好的书抓住不变量,让人能够触类旁通。好的书不仅介绍知识,而且阐释原则,介绍那些万变不离其宗的东西。读烂书浪费时间,但读好书却节省时间。
象牙塔内的学生受到视野的限制,往往择书不慎,事倍功半,烂书不仅浪费时间,还会打击人的积极性,让人对知识心生恐惧,认为很难掌握,殊不知只是作者没有讲好(或者没有翻译好)。因此,为招聘头疼的公司完全可以给出“应聘俺们公司前必读的十本书”,也不一定要每个公司都不一样,在某个技术子领域有影响力的人,或者创始人们,可以来定义具有代表性的书单。
我们姑且把这个计划叫做“书单计划”,容易看到“书单计划”具备以下几个卓越的优点:
清晰、明确。完全可度量。防伪:读没读过,随便一问便知。而正因为应聘者也知道这事不像实习经验可以忽悠,所以也不敢乱往简历上捅词。
不在乎是否“泄题”:书单完全公开的,无所谓,本来就是要你去读的。想背题?背书吧。真能背下来说明认真看了。
管你用心不用心读,只要读了,读完了,就有区别。真正的好书,你想不被吸引都难。据我观察很多人就是不知道该去读什么书。
不存在“怎么做”的障碍:所有人都知道怎么读书——一页一页读。
不需要招聘者投入精力:书单在此,就这么简单,您看着办。
评估的负担很大程度转移到了应聘者的身上:是不是认真看完了,有没有心得体会,您自己掂量。没看完别来找我们。
“书单计划”能很大程度上起到强鉴别器的作用,看了就是看了,必然能学到东西,没看就是没看。知道和不知道,区别是本质的。其实很多企业内部培训,根本上其实还不就是叫员工去看之前没看过的书或者资料嘛。最后,除了鉴别作用之外,它还是一个清晰促进的目标,是完全不花精力的培养。
当然,“书单计划”的背后是另一个悲剧的现实,如果不是因为这个现实,这个计划也完全没有必要,那就是,中国IT大学教育当中要求要学的书,和企业真正需要你去读的书相比,不是完全不够用,就是写的不够好,或者更悲剧的就是根本用不上,所以在这个大背景下出来的牛人都是自己淘书自己学的。微软高级开发测试工程师,《Windows用户态程序高效排错》作者熊力就在微博上说过:“我当年毕业的时候总结了一个公式:第一份工作的月薪=大学四年买过的技术书籍价格的总和。” 但是光有“书单计划”还不够,因为书籍只能管基础知识这一块,一些更难以量化衡量的实战“能力”又怎么办呢?至少目前为止,除了“练”之外好像还没有特别好的办法。可是在象牙塔里面做的项目,或大作业,真的能起到练的作用吗?前面说了,学生会知道自己最终要交差的不是雇主,而是老师,于是就以老师能够评判的标准来默认要求自己了,老师能够评判编码素养?代码风格?文档?设计?协作?甚至连著名的Joel 12条的第一条“是否用源代码管理系统”都没法通过。所以大多数时候,大作业能起到的作用近乎0。
但是如果这一切是由雇主来评判的,这个“作业”是由雇主来给出的,就完全不一样了。一想到作业是要作为简历的一部分的,能不紧张嘛。能不好好做嘛。能不学到点东西嘛?
可是这事儿能实现吗?雇主能给学生出大作业吗?也许一两个关系好的高校可以,可是中国那么多学生呢?
为什么不能呢?如果像书单那样,列出各个技术领域“推荐在学校期间尝试的项目”,至于动不动手做,那是学生自己的问题。做的,自然能够得到锻炼,面试的时候自然能得到更大的优势。
可问题是,面试的人又怎么来评估呢?这不又回到了没法有效评估的怪圈了吗?答案很简单,但这个答案,直到最近几年,才真正成为现实——
GitHub GitHub诞生于08年春天,第一年便产生了4万6千个公共项目,大约一年半之后用户就已经达到10万用户之巨。而到今年九月份,GitHub已经迎来了百万级用户。Host超过两百万个项目。
增长的太快了!就像Twitter一样。这样疯了一般的增长只能说明一个事实——人们等待这个产品太久了。
Social Coding。
真实的项目,真实的流程,真实的人名,一切代码review, check-in, test, build, document, 甚至讨论,计划,brianstorming,流程,一切的一切,都是项目历史的一部分,都可以像棋局那样复盘。有经验的面试者只要稍稍扫两眼一个人的GitHub历史,挑出几个check-in历史看一看,便完全能够迅速判断这个人是否满足他的要求。不再需要费劲心机地去想题目,去观察,去揣测,去花费大量的时间的同时还只能采样到几个极为有限的点。
不像象牙塔里面大作业,这里有源代码管理系统,自动化build,有check-in,有review,有分工,有合作,最重要的是——这是一个集市,一个超出象牙塔的集市,牛人相互吸引,你可以在互联网上找到和自己拥有共同兴趣的一帮人,真正做起一点事情,而不是交差,不需要受限于几十个人的一个小班级。Here Comes Everybody。
为什么我这么有信心?因为这事儿已经发生了。这个想法也完全不是我原创的。正如很多事情一样,现在在国内发生的事情,往往是美国那头的历史。今年7月中旬,纽约一家公司的工程师老大发了一篇博客文章:Github is Your New Resume。指出一个惊人但再合理不过的事实:越来越多的IT公司在招聘的时候要求应聘者给出GitHub账号。甚至已经有人为GitHub写了根据GitHub上的历史自动生成简历的工具。
仔细想想,这是必然的趋势,没有比这个再合理的事情了,既然StackOverflow的历史能够作为简历,GitHub的历史不本该就是更好的简历吗:你想要具有实战经验,懂check-in懂review懂test和代码质量的重要性,懂交流和沟通的重要性,你本就应该在一个真实的项目当中去锻炼这些东西,而这些在目前已经完全可以办到。正如邹欣老师所说,你的工作就是最好的面试。
这件事情放在早几年,是完全没法做到的,因为我们那时候还没有GitHub。正如没有Twitter,没有微博之前,很多事情都不会成为可能一样,你有千钧之力,缺乏一个合适的支点,也没法撬动一整个社群。无组织中的组织,具有强大的杠杆效应。
这个事情里面,我唯一提出的东西就是:在目前国内这个现状下,苦闷的招聘者应该主动行动,给出一些建议项目,正如前面提到的书单计划一样,招聘者需要给出的只是引导和清晰明确的目标,剩下的事情,应聘者自然会去完成,这些项目可以是实验项目,也可以是完全能做出点卖钱的东西的项目(如果好好做的话),唯一的不可或缺的前提是,项目不能太小,单人就能完成的项目不理想,一两个月就能完成的项目不理想,最好足够大到能够锻炼到方方面面,偏大一点倒是无所谓的,因为一个尚未完成的项目完全可以作为简历。当然,可以想见的是,真到了那个时候,学生们肯定又是不会满足于仅去做那些已经有许多人做过的项目了。所以这里企业们一开始所建议的项目只是一个《Nudge》,是滚雪球之前需要的一点初始动能。后面的事情,他们自己会完成。
“GitHub计划”同样有一些明显的、甚至不可替代的优点:
清晰、明确,完全可度量。
防伪:同样不担心“泄题”。你伪造不了GitHub历史,伪造不了check-in历史,review comments,文档,交流记录…
它不但是招聘,也是不花精力的培养。善哉善哉。
评估的责任很大程度上交给了应聘者自己。
从你的GitHub旅程开始,你就已经一脚踏进了真正的企业,而企业的面试也已经开始。
书单+GitHub,就相当于一个两年左右的面试。
没有什么面试比持续两年的面试更具有信息量。
书单,加上项目,已经基本上覆盖了所需的全部技能。最妙的是,有太多的人在焦急的等待着他们未来的雇主给出明确的信号,他们想投入精力,去学习和实践,去成为企业需要的人,但是他们就是不知道往什么方向走,所谓有动力没方向。所以,雇主给出了清晰明确的要求,相信对于很多人来说反倒是一个解脱:“终于知道该干什么了”。《编程之美》为什么常居畅销榜?因为它透露了雇主眼中的需求,明确、清晰的需求,可以实现,并且知道怎么去实现的需求。
你提前两年就开始面试和培养未来的候选者,而且还不需要你花出一分精力,而且人家还很乐意,没有比这更完美的面试了。
想一想,以后那些没见过世面的公司看见你拿出GitHub账号给他看,该是多么惊讶同时又觉得多么合理。
而这一切,只是因为两个小小的改变:
由需求方(雇主)给出了清晰、明确的目标。
GitHub这样的平台。
那么,学校/老师在这个事情当中的位置呢?说实话我不知道。没有哪个行业像IT行业这样特殊:没有什么东西不能够(应该)在互联网上学到的。自组织的力量完全大过传统的教育方式。而且,既然雇主都当了领路人了,我不知道还有中间开发商什么事儿。(注:这里说的是软件开发,并非计算机科学研究,后者另当别论)
那么,这个改变会发生吗?多久会发生呢?当然,它在国外已经发生了,所以问这个问题多少有点无趣。但我还是预计很快就会在国内发生,毕竟,不是已经有人要求出示博客,和经常浏览的网站了吗?也许5年左右(4年本科和6年硕士的中间值?))就会深刻改变整个人才培养/招聘的格局。当然,我并不是预言家,所以不要把我的时间估计当真,我能肯定的是,这种方式是必然的大势所趋。刚才我就收到一位同学邀请我上知乎回答一个问题“找工作的首要原则是什么?”,当然,这个问题的答案是:“弄清雇主的需求到底是什么”。
------------------
列一下我所认为的,你面试微软前必须要读的十本书:
Code: The Hidden Language of Computer Hardware and Software(《编码的奥秘》)
Computer System: A Programmer’s Approach(《深入理解计算机系统》)/ Windows via C/C++(《Windows核心编程》 / 《程序员的自我修养》
Code Complete 2(《代码大全》)/ The Pragmatic Programmer(《程序员修炼之道》,我也把这本书称为《代码小全》)
Programming Pearls(《编程珠玑》)/ Algorithms / Algorithm Design / 《编程之美》
The C Programming Language
The C++ Programming Language / Programming: Principles and Practice Using C++ / Accelerated C++
The Structure and Interpretation of Computer Programs(《计算机程序的构造和解释》)
Clean Code / Implementation Patterns Design Patterns(《设计模式》)/ Agile Software Development, Principles, Patterns, and Practices Refactoring(《重构》)
(注:1.以上同一条目下用“/”隔开的表示任选,当然你也可以都读了,相信我,时间是足够的。2.读这些书并不意味着逐字逐句从第一页读到最后一页——当然你也可以这么做。怎么是聪明高效的读法,可以参考我之前写的关于如何阅读和查找/鉴别书籍/资料的博文)
注意:以上是我个人认为你面试微软开发职位前必须要读的10本书,它不代表我的雇主的观点。它也只是一个初步的书单,肯定会受到我个人经验和眼界的限制。欢迎大家提意见。
此外,IT不同子领域的必读书单可能千差万别,所以在发布之前我把这篇文章发给了一些朋友,他们给出了自己的书单(你是不是能看到一些有趣的共同点呢):
云风(中国游戏编程先行者,前网易游戏部门资深程序员,简悦创始人):
如果面试,我会挑以下的我自己读过的书,让人选择他也读过的部分,再了解他对这些书的理解。这些书其实本质上就是两类,对所面对的东西(程序语言也好,操作系统也好,底层设施也好)本身的理解程度。以及另一类:对设计思想和原则的理解:
C++编程思想 Effective C++
深度探索C++对象模型
C++语言的设计和演化
C专家编程
C陷阱与缺陷
C语言接口与实现
Lua程序设计
Linkers and Loaders COM本质论
Windows核心编程
深入解析Windows操作系统
程序员修炼之道
代码大全
UNIX编程艺术
设计模式
代码优化:有效使用内存
深入理解计算机系统
深入理解LINUX内核
TCP/IP 详解
冯大辉(丁香园CTO,贝塔咖啡创始人): 软件随想录
黑客与画家
重来
UNIX编程艺术
编程人生
洪强宁(豆瓣技术总监):
StackOverflow上有一个程序员必读书单帖子,这里仅列出top10,更多参考这里。
Code Complete 2
The Mythical Man-Month(《人月神话》)
Code: The Hidden Language of Computer Hardware and Software(《编码的奥秘》)
TAOCP(不解释)
The Pragmatic Programmer(《程序员修炼之道》)
Design Patterns(《设计模式》)
The Structure and Interpretation of Computer Programs(《计算机程序的构造和解释》)
Refactoring(《重构》)
The C Programming Language
Introduction to Algorithms(《算法导论》)张峥(微软亚洲研究院副院长):
Algorithms(by Sanjoy Dasgupta, Christos Papadimitriou and Umesh Vazirani)Data Structure and Algorithms The C Programming Language
The Design of the UNIX Operating System Compilers(龙书)
Computer Architecture: A Quantitative Approach Flow
Outliers(why hard work and luck are both important)
读好书是如此的重要,因为好书往往带领你去到更好的书,更大的世界。
第二篇:一直以来伴随我的一些学习习惯(By 刘未鹏)
一直以来伴随我的一些学习习惯(By 刘未鹏)
Part 1 1.Google&Wiki(遇到问题做的第一件事情,也是学习某个东西做功课(homework)最先用到的东西。
2.看书挑剔,只看经典。如何选择经典,可以到网上做做功课,看看评价,综合分析一下。
3.做读书笔记。一是将自己阅读的时候的思考(包括闪念)总结下来,二是将书中的好例子摘抄下来。(这个习惯是一年前才养成的,发现受益极大。)有了 google note,笔记可以加上tag,非常便于回顾,加深理解。我觉得,人与人学习的差距不在资质上,而在花在思考的时间和思考的深度上(后两者常常也是相关 的)。
4.提到思考,我有一个小习惯。利用走路和吃饭的时候思考,还有睡觉前必然要弄一个问题放在脑子里面,在思考中迷糊入睡。发现这样一来往往在不知不觉中多出来大量的思考时间。
4a.将思考成为习惯还有一个很大的好处——避免焦虑。卡耐基用一整本书讲 了一个有效的做法来避免焦虑——底线思考。然而实际上还有另一个有效的做法,就是投入地做另一件事情。不去想“喜马拉雅山上的猴子”的方法并不是使劲的告诉自己不去想“喜马拉雅山上的猴子”,因为那样等于就是脑袋里想了那只猴子,正确的做法是真的不去想那猴子,而是想别的。用别的东西充满工作记忆,其他的 神经活动自然会被抑制(神经科学基本事实)。所以,感到焦虑的时候不妨思考吧,甚至完全可以去理性分析和思考导致焦虑的问题本身,将其拆解,分析来源,在不知不觉中,大脑的工作重心就从情绪模块转向了推理模块了,而且这思考也可能顺带更有效地解决了导致焦虑的问题呢:)5.重要的事情优先(详见史蒂芬〃柯维的《高效能人士的七个习惯》或《要事优先》)。尽量避免琐事骚扰,不重要的事情能不做就不做。有时候,紧急的事情往往只是当事人觉得必须马上做完才显得紧急或者干脆就是紧他人之急,最糟糕的就是纯属性 格上原因觉得每件事情都得第一时间完成,很多看上去紧急的事情实际上并不是真的“不能再拖了”,有的干脆就并不需要或值得去做。有很多事情都是可以先放一 放甚至完全let go的,否则的话就整天被所谓“紧急”的事情牵着鼻子走了。
6.重要的事情营造比较大的时间块来完成。比如一本好书,或者一个重要的知识点,最好不要切得太琐碎了看,否则看了后面忘了前面。不利于知识的组织&联系。
7.多看心理学与思维的书,因为它们是跨学科的。知识分两种,一是我们通常所谓的知识,即领域知识。二是关于我们的大脑吸收知识的机制的知识,后者不妨称为元知识。虽说这也是领域知识,但跟其它的领域知识不同的是,它指导着我们学习其它所有的领域知识。
8.学习一项知识,必须问自己三个重要问题:1.它的本质是什么。2.它的第一原则是什么。3.它的知识结构是怎样的。
9.获得的多少并不取决于读了多少,而取决于思考了多少、多深。10.善于利用小块时间,也就是《奇特的一生》中所说的“时间下脚料”,如何利用前面有几个方法。同时,也善于创造整块时间(如通过要事优先)。
11.关于习惯的养成,必须要说明的:经常看到有些人评论说,说说容易,做 起来哪有那么容易啊(另一个无关习惯的“说起来容易做起来难”则是因为纸上谈兵不可能 算计到所有现实中的因素,但那是另一个问题)。对此我要说的是,做起来当然不容易,所谓江山易改,本性难移。人的性格和认识事物的框架是长期积累养成的,并且人们非常珍视自己的信念(英语里面表达不相信某个东西叫做“I don't buy it”)。从进化心理学上这是有依据的,一个经过时间检验的信念往往是更靠谱的。只不过可惜的是靠谱不代表最佳,一个信念能让你活下来并不代表能让你活得 最好(详见 《 Mene Genes 》,更多的例子参见 《 How we know what isn't so 》)。我们评判一个信念的标准是satisficing 原则(即足够,能行就好,这个术语不是我提的,是大牛Herbert Simon 提的),并不是optimizing原则。话说回来,为什么说起来容易做起来难,是因为“说”只是理性上承认正确,并没有考虑到我们每个人大脑中居住的那个非理性自我。这个自我以强大的情绪力量为动机,以习惯为己任,每时每刻都驱使着我 们的行为。因为它掌握了“情绪”这个武器,所以我们只能时时拿它当大爷。不记得是哪位哲学家说的了,理性是感性的奴隶。那么,是不是就是说无法克服既有习惯了?以我的经验(以及观察到的别人的经验),还是可以的。第一条就是认识到习惯的改变绝不是一天两天的事情,承认它的难度。第二条就是如果你真想改掉习惯,就需要在过程中常常注意观察自己的行为,否则习惯会以一种你根本觉察不到的方式左右你的行为让你功亏一篑。有一个认知技巧也许可以缓解更改习惯过程中的不适:即把居住在内心的那个非理性自我当成你自己的孩子(你要去培养他),或者你的对手(你要去打败他)也行。总之不能当成自己,因为每个人都不想改变自己。这里转一个认知技巧的例子:李笑来老师在《把时间当作朋友》(顺便也推荐这本开放电子书)中提到他一个朋友用另一个认知技巧来克服背单词的枯燥的:因为,一共要搞定20,000个单词,而因此可能获得的奖学金是每年40,000美元左右——并且连续四年没有失业 可能(后来的事实是,他直到五年之后才获得了博士学位)。当时的美元兑换人民币的汇率差不多是8:1,所以,大约应该相当于320,000元人民币。而如 果一年的税后收入是320,000元人民币的话,那么税前就要赚取差不多400,000元人民币。那么,每个单词应该大约值20元人民币——这还只不过是 这算了一年的收入而已。所以,他终于明白背单词是非常快乐的。他每天都强迫自己背下200个单词。而到了晚上验收效果的时候,每在确定记住了的单词前面画上一个勾的时候,他就要想象一下刚刚数过一张20元人民币的钞票。每天睡觉的时候总感觉心满意足,因为今天又赚了4000块!注意,这跟自我欺骗不同。一来,我们的情绪系统只能这般对付(《 Synaptic Self 》中提到,大脑中的新皮层(neocortex,所谓“理性”居住的地方,尤其是前额叶)在进化历史上是较为新近的年代才进化出来的,跟底层较原始的模块(如主管情绪的杏仁核)之间的神经网络沟通并不是合作无间,这就解释了为什么有些事情我们明明知道是对的,但就是不能说服自己,情绪还是在那里不依不挠的驱使 你去做另一样事情)。二来,我们知道在干什么,所以不能算欺骗:P 总之,对于习惯的更改,除了最重要的一日三省,加上一些认知技巧(其实每个人都是自己的心理学家,你可以自己看看能不能想出什么法子)。其实是没有什么速效银弹的。但是,知难而不退嘛,值得做的事情几乎总是如此:)
Part 2 一.学习和思考的过程中常问自己的几个问题: 1.你的问题到底是什么?(提醒自己思考不要偏离问题。)
2.OK,到现在为止,我到底有了什么收获呢?(提醒自己时不时去总结,整理学习的东西)。
3.设想自己正在将东西讲给别人听(有声思考;能否讲出来是判断是否真正理解的最佳办法)。
3.1 设想需要讲给一个不懂的人听。(迫使自己去挖掘知识背后最本质、往往也是最简单的解释)。
4.时常反省和注意自己的思维过程。尤其是当遇到无法理解或解决的问题之后,最需要将原先的思维过程回顾一 遍,看看到底哪个环节被阻塞住了妨碍了理解。问题到底出在哪里。并分析以后需要加强哪方面的思维习惯,才能够不在同样或类似的时候被绊住。对此,将思维的 大致脉络写下来是一个很好的习惯。
5.养成反驳自己的想法的习惯:在有一个想法的时候,习惯性地去反驳它,问自己“这个难道就一定成立吗?”、“有没有反例或例外?”、“果真如此吗?”之类的问题。(参见Critical Thinking)
6.人的思维天生就是极易流于表面来理解事物的(参见 《 Psychology of Problem Solving 》 第11章)。觉得自己理解了一个问题了么?条件反射性地问自己:你真的理解了吗?你真的理解了问题的本质了?问题的本质到底是什么?目前我的理解是什么?我对这个理解感到满意吗?这样的理解到底有什么建设性呢?等等。
二.重视知识的本质:对于程序员来说这一点尤其重要,程序员行业的知识芜杂海量,而且总是在增长变化。很多人感叹跟不上新技术。应对这个问题的办法只能是:抓住不变量。大量的新技术其实只是一层皮,背后的支撑技术其实都是十来年不变的东西。底层知识永远都不过时。算法数据结构永远都不过时。基本的程序设计理论永远都不过时。良好的编码习惯永远都不过时。分析问题和解决问题的能力永 远都不过时。强大的学习能力和旺盛的求知欲永远都不过时。你大脑的思维方式永远都不过时。
三.重视积累的强大力量,万事提前准备: 计划订长一点,自然就可以多获得准备的时间。设想你若干年后会在做什么事情,需要哪些技能,现在就开始准备。一个5年计划便可以让你获得从现在开始的5年准备时间。5年中每天腾出半个到一个小时专心于某一件事情,认准一个方向,每次走一点,其实不要说5年,两年就会发现会起到宏大的效应。长期订阅我的Blog的朋友们也一定注意到我基本上不写东西,一般一个月写上2篇就算多的了。但总结一段时间的学习和思考的习惯却一直都没有停止(博客文章对我来说是 学习和思考的副产品,我并不为写文章而写文章),所以5年下来竟也写了不少东西。所以这就是一个简单的例子。你大致还可以从我的Blog看出来我一段时间 关注的东西,一般来说,一段比较长的时间(少则半年至一年——譬如对心理学与思维的关注;多则几年——譬如对编程技术的关注),在这段时间内,我的业余时 间会被一个主题所充斥。反之,如果不知道目的是什么,就不知道往哪个方向上使劲,就容易产生无用功。
四.抬起头来:人的思维是非常容易只见树木不见森林的(否则这个成语 从哪来的呢?)。时不时抬起头来审视一下自己正在做的事情,问一问它(对现在或未来)有什么价值,是不是你真正希望做的。你学到的东西到底是什么?它们重 要吗?你 需要在这个时候学习这些吗?(见第2条)。你的时间就是你的资源,你投入这些资源来掌握知识,所以到底用来掌握哪些知识是一个很重要的问题。仅仅遵循兴趣是不够的,人会对很多次要的东西产生兴趣,并一头钻进去浪费好多时间。所以判断一个东西值不值得学习是很重要的。
五.杂项
1.退订RSS:RSS Reader是个时间黑洞。就算mark all as read,在有大量feed的情况下,也会无形中消耗掉大量的时间。我们一旦订阅了某个RSS之后就会倾向于不肯退订它,心想也许某天有个重要的信息会从那里得到。这其实是源于人不肯“关上一扇门(即便门内的收益概率极小)”的心理(参见《 Predictably Irrationa l 》); 而实际上,关上一扇门,有时能够增大收益期望。仔细观察一下reader里面的feeds,有哪些是真正有价值的,把那些没价值的或者价值很小乃至于不值 得每天被它骚扰的,全都退订掉。不要舍不得,那些一个星期都没出现让你眼睛一亮的内容的feed,很大的可能是永远也不会出现。就算可能,也别担心你会漏掉什么宝贵信息,真正宝贵的信息,在其他来源你也会接触到的。一开始我的Greader里面每天都有大量的新内容,每天都是1000+,但一段时间之后发现除了信息焦虑,实际上有价值的内容不多,现在,我很高兴地发现自己摆脱了这种状况,我持续不断地退订feeds,留下的内容越来越少,也越来越精,带来的阅读焦虑也越来越少。(顺便推荐一个东西,aideRSS,初步使用,感觉对订阅reddit这样的每天更新大量内容的feed很有用)。
2.有时间吗?总结总结最近得到的新知识吧。一般来说,我在一段时间 内学习的一些东西总是会在这段时间内一直在脑子里打转,一有时间空隙(譬如走路,吃饭)它们就会自己蹦出来,促使我去进一步思考和总结。永远不要认为对一 个知识的把握足够深刻,“理解”的感觉很多时候只是假象。学会反问自己对知识到底把握了多少,是很有价值的。(如何反问,前面的总结中有提到)。
3.有时间吗?看本书吧。(传统的)阅读和思考永远优于所谓的在互联网上汲取新知识,后者往往浅表、不系统、乃至根本没价值。
4.制定简要的阅读计划:选出最近认为对你最有价值的书,先总览一下,决定阅读的顺序(哪些章节可以优先阅读)。然后每天看一点。并利用走路、吃饭、乘车或其他不适合带着书和笔的时间来总结看过的内容,建立知识结构,抽取知识本质,与以往的大脑中的知识建立联系。(参见《奇特的一生》)
Part 3 这篇主要写一些学习(尤其是阅读)的基本方法。
1.趁着对一件事情有热情的时候,一股脑儿把万事开头那个最难的阶段熬过去。万事开头难,因为从不了解到了解基本的一些事实,是一个新知识暴涨的阶段,这个时候的困难是最大的。有人熬不过去,觉得困难太大就放弃了。不过,狂热的兴趣可以抵消对困难的感觉,所以趁着对一件事情有热情的时候,开一个好头是很重要的。(当然,这并不是说持之以恒就不重要了)。当然,也许这个是因人而异的,对我来说我会在对一件事情有浓厚兴趣的时候非常专注地学习,把很多 groundworks 做掉。后面就会顺利一些了。
2.根据主题来查阅资料,而不是根据资料来查阅主题。以前读书的时候是一本一本的读,眼里看到的是一本一本的书,现在则是一章、甚至一节一节的读,眼中 看到的不是一本一本的书,而是一堆一堆的章节,一个一个的知识主题,按照主题来 阅读,你会发现读的时候不再是老老实实地一本书看完看另一本,而是非常频繁地从一本书跳到另一本书,从一处资料跳到另一处资料,从而来获得多个不同的人对 同一个主题是如何讲解的。比如最近我发现在看蒙特卡罗算法时就查了十来处资料,其中有三四篇 paper 和六七本书;这是因为即便是经典的书,你也不能指望它对其中每一个主题的介绍都是尽善尽美的,有些书对某个主题(知识点)的介绍比较到位,有些书则对另一 些知识点介绍得比较到位。而有时候一篇紧凑的 paper 比一本书上讲得还要好。我硬盘里面的书按主题分类,每个主题下面都有一堆书,当我需__________要学习某个主题的知识时(譬如贝叶斯学习或者神经网络),我会把里面涉 及这个主题的书都翻开来,索引到相关章节,然后挑讲得好的看。那么,如何判断一个资料是好资料还是坏资料呢?
3.好资料,坏资料。好资料的特点:从问题出发;重点介绍方法背后的理念(rationale),注重直观解释,而不是方法的技术细节;按照方法被发明的时间流程来介绍(先是遇到了什么什么问题,然后怎样分析,推理,最后发现目前所使用的方法)。坏资料的特点是好资料的反面:上来就讲方法细节,仿佛某方法是从天上掉下来的,他们往往这样写“我们定义...我们称...我们进行以下几个步骤...”。根本不讲为什么要用这个方法,人们最初是因为面对什么问题才想到这个方法的,其间又是怎样才想出了这么个方法的,方法背后的直观思想又是什么。实际上 一个方法如果将其最终最简洁的形式直接表达出来往往丢失掉了绝大多数信息,这个丢掉的信息就是问题解决背后的思维过程。至于为什么大多数书做不到这一点,我在这里试着分析过。
4.学习一个东西之前,首先在大脑中积累充分的“疑惑感”。即弄清面临的问题到底是什么,在浏览方法本身之前,最好先使劲问问自己能想到什么方法。一个公认的事实是,你对问题的疑惑越大,在之前做的自己的思考越多,当看到解答之后 印象就越深刻。记得大学里面的课本总是瀑布式地把整个知识结构一览无余地放在面前,读的过程倒是挺爽,连连点头,读完了很快又忘掉了,为什么?因为没有带 着疑问去学习。
5.有选择地阅读。很多人觉得我读书速度很快,其实我只是有选择地阅读。这里 的选择体现在两个地方,一是选择一本书中感兴趣的章节优先阅读。二是对一本书中技术性较弱或信息密度较低的部分快速地略读。一般来说,除了技术性非常强的 书之外,大多数书的信息密度很低,有很多废话。一般来说在阅读的时候应该这样来切分内容:1.问题是什么?2.方案是什么?3.例子是什么?如果是需要解释一个现象的(譬如《黑天鹅》),那么1.现象是什么?2.解释是什么?3.支撑这个解释的理由是什么?4.例子是什么?一般来说,这一二三四用不了多少字就可以写完了(如果假设只举一到两个精到的例子的话),这样的无废话著作的典型是《合作的进化》;那为什么 有些书,明明核心观点就那点东西(顶多加上几个精要的例子罢了)却写得长得要命呢?因为人的思维都有一个“联想”的特点,写着写着就容易旁逸斜出,而且作者自己也往往觉得引申出去挺牛逼,有时候很多与主题无关的废话就掺和进来了;那么,阅读的时候就应该有选择性地滤掉这些不相干的废话;此外还有一种可能性 就是大量冗余的例子。一般来说组织得比较好的书会有详细且一目了然的目录和索引,根据目录首先就可以滤掉一部分(比如某个子章节的内容 你以前是看过的),然后有时候作者还会举很多冗余的例子,如果你已经觉得印象够深刻了这些例子完全可以不看(一些书就非常厚道地对每个观点只辅以一两个最最经典的例子,譬如 《与众不同的心理学——如何正视心理学》,这样的书我最是喜欢)。
6.为什么看不懂?如果看不懂一个知识,一般有如下几个可能的原因:1.你看得不够使劲。对此古人总结过——书读百遍其义自现。虽然这个规律不是任何时候都成立的,但是从认知科学的角度看是完全可以解释的,我们在阅读的时候,注意力往往会有选择性地关注其中的某一些“点”,而忽略了另一些“点”,于是一遍看下来可能因为某一些忽略导致无法理解整体。或者干脆看的时候就没注意其 中一些细节但重要的东西。此外,大脑理解一个东西需要一定的处理时间,人脑的处理速度很慢,神经冲动每秒传输速度不过百米,所以不能指望看到哪懂到哪。最后,我们可能因为思维定势的原因会从某个特定的角度去看一句话而忽略了从不同角度去理解的可能性。对于这类情况,仔仔细细地再多读两遍,多试着去理解两 遍,往往会“哦!原来这样。”地恍然大悟。2.其中涉及到了你不懂的概念。这是技术性的不理解。这种情况就需要 Cross Reference。如果一句话中用到了你不懂的概念,那就去查,现在很多书都是电子书,直接搜索一下,或者对于纸书,看一下书后面的索引就行了。奇怪的是很多人看不懂也 不分析一下为什么不懂,就直接放弃了。正如解决问题一样,问题卡住解决不了,第一时间要做的就是分析到底为什么解决不了,而不是直接求救。3.作者讲述的顺序不对,你接着往下看,也许看到后面就明白了前面的了。
杂项
7.如何在阅读之前就能获得对一本书质量的大致评估。在深入阅读之前能够迅速评估一本书的质量可以节省很多时间。基本上有几个线索:1.看作者。牛作者写的书一般都不错。2.看目录和简介。一份好的目录和简介能够透露这本书质量的相当一部分信息。目录结构是否清晰,是否直白(而不是装神弄鬼),都是衡量的线索。3.看 Amazon 上的评价,这里要注意的是,除了看整体打分之外,更要看打分最低的人是怎么说的,因为小众意见往往有可能来自那些真正懂行的人(除了来踢馆的),如果在打 分最低的意见里面看不到真正有价值的反驳意见的话就相当肯定书是不错的了。4.看样章。Amazon 上一般都可以随机浏览一些章节的,表达是否清晰,论证是否严谨,内容是否深刻,基本是几页纸就能看出来的。
8.如何搜寻到好书。几个线索:1.同作者的著作。2.Amazon 相关推荐和主题相关的书列(类似豆瓣的豆列)。3.一本好的著作(或一份好的资料——不管是书还是网页)在参考资料里面重点提到的其他著作。4.有时对于一个主题,可以搜索到好心人总结的参考资源导引,那是最好不过的。
Part 4 程序员的知识结构
自从建立了 TopLanguage 以来,发现在上面待的时间越来越多,与高手讨论问题是个粘性十足的事情,一方面,分享自己的认识是整理不成熟的想法的极好途径,另一方面,互相之间视角不同,所以往往自己忽视的地方会被别人发现。在讨论中不断精化既有的知识体系。以下这段基本上摘抄自(略有整理和添加)在 TopLanguage 上的发言:抓住不变量我喜欢把知识分为essential的和 non-essential的。对于前者采取提前深入掌握牢靠的办法,对于后者采取待用到的时刻RTM(Read the manual)方法(用本)。如何区分essential和non-essential的知识想必绝大多数时候大家心里都有数,我举几个例子:对 程序员来说,硬件体系结构是essential的,操作系统的一些重要的实现机制是essential的,主流编程范式(OO、FP)是为了满足什么需求 出现的(出现是为了解决什么问题),是怎么解决的,自身又引入了哪些新的问题,从而适用哪些场景)。这些我认为都是essential的。我想补充一点的是,并不是说硬件体系结构就要了解到逻辑门、晶体管层面才行(其实要了解到这个层面代价也很小,一两 本好书就行了),也并不是说就要通读《Computer Architecture: Quantitative Approach》才行。而是关键要了解那些重要的思想(很长时间不变的东西),而不是很细的技术细节(易变的东西)。《Computer Systems: A Programmer’s Perspective》就是为此目的,针对程序员的需求总结出那些essential knowledge的好书。
再来说一下为什么需要预先牢靠掌握这些essential的知识: 1.根据Joel Spolsky同学的说法(原文),编程语言技术是对底层设备的封装,然而封装总是会出现漏洞的,于是程序员被迫下到“下水道”当中去解决问题,一旦往下走,漂亮的OO、N层抽象就不复存在 了,这时候不具备坚硬的底层知识就会无法解决问题。简而言之就是这些底层知识会无可避免的需要用到,既然肯定会被用到那还是预先掌握的好,否则一来用到的 时候再查是来不及的,因为essential的知识也往往正是那些需要较长时间消化掌握的东西,不像Ruby的mixin或closure这种翻一下 manual就能掌握的东西。(英语也是这样的essential knowledge——上次在PyCN上看到一个招Python开发人员的帖子将英语列为必备技能,却并不将自然语言处理列为必备技能,正是因为英语不是 可以临阵磨枪的东西,而且作为知识的主要载体,任何时候都少不了它,如果不具备英语能力,这个就会成为个人知识结构的短板或瓶颈,而且由于需要长时间才能 获得这项能力,所以这个瓶颈将持续很长时间存在。我们曾经在 TopLanguage 上讨论过如何花最少的时间掌握英语)另一方面,在问题解决当中,如果不具备必要的知识,是根本无从思考的,再好的分析能力也并不是每个问题都能分析出该用哪些知识然后再去查手册的,很多时候 是在工具和问题之间比较,联想,试探性的拼凑来解决问题;这就使得一个好的既有知识基变得至关重要。(实际上以上这个是一个较大的话题,希望有一天我能够 把它详细展开说清:))
2.如果你不知道某个工具的存在,遇到问题的时候是很难想到需要使用这么样一个工具的,essential knowldge就是使用最为广泛的工具,编程当中遇到某些问题之后,如果缺乏底层知识,你甚至都不知道需要去补充哪些底层知识才能解决这个问题。
3.你必须首先熟悉你的工具,才能有效地使用它(须知工具的强是无敌的,但这一切得以“了解你的工具”为前提,甚至得以“了解目前可能有哪些工具适合你的问题”为前提)。一门语言,你必须了解它的适用场景,不适用场景(比如继 承能解决你的问题不代表继承就是解决你的问题的最适合的方案,须知问题是一个复杂系统,解决方案总是常常引入新的问题)。你必须了解它支持的主要编程范 式,此外你还必须了解它的traps和pitfalls(缺陷和陷阱,如果不知道陷阱的存在,掉进去也不知道怎么掉的。)这些都是essential knowledge,如果不事先掌握,指 望用的时候查manual,是很浪费时间的,而且正如第2点所说,正因为你不知道这些知识(如适用场景),从而用 sub-optimal的方式使用了一门语言自己可能还不知道(最小白的例子是,如果你不知道语言支持foreach,那么可能每次都要写一个冗长的循 环,较常见的例子是不知道有很方便的库设施可以解决手头的问题所以傻乎乎的自己写了一堆代码),因为人的评价标准常常是:只要解决了最醒目的问题并且引入 的新问题尚能忍受,就行。注意,熟悉并非指熟悉所有细节,而是那些重要的,或者无法在需要用到的时候按需查找的知识。比如上面提到的:适用场景不适用场 景,编程范式,主要语言特性,缺陷和陷阱。
当然,以上作为程序员的essential knowledge列表并不完备,关键是自己在学习新知识的时候带着第三只眼来敏锐地判断这个知识是否是不变量,或不易变的量,是否完全可以在用的时候查 手册即可,还是需要提前掌握(一些判断方法在上文也有所提及)。并且学会在纷繁的知识中抽象出那些重要的,本质的,不变的东西。我在之前的part 里面也 提到我在学习新知识的时候常常问自己三个问题:该知识的(体系或层次)结构是什么、本质是什么、第一原则是什么。
另外还有一些我认为是essential knowledge的例子:分析问题解决问题的思维方法(这个东西很难读一两本书就掌握,需要很长时间的锻炼和反思)、判断与决策的方法(生活中需要进行判断与决策的地方远远多于我们的想象),波普尔曾经说过:All Life is Problem-Solving。而判断与决策又是其中最常见的一类Problem Solving。尽管生活中面临重大决策的时候并不多,但另一方面我们时时刻刻都在进行最重大的决策:如:决定自己的日常时间到底投入到什么地方去。如:你能想象有人宁可天天花时间剪报纸上的优惠券,却对于房价的1%的优惠无动于衷吗?(《别做正常的傻瓜》、《Predictably Irrational》)如:你知道为什么当手头股票的股价不可抑止地滑向深渊时我们却一边揪着头发一边愣是不肯撤出吗?(是的,我们适应远古时代的心理 机制根本不适应金融市场。)糟糕的判断与决策令我们的生活变得糟糕,这还不是最关键的,最关键的是我们从来不会去质疑自己的判断,而是总是能“找到”其他 为自己辩护的理由(《错不在我(Mistakes were made, but not by me)》)又,现在是一个信息泛滥的时代,于是另一个问题也出现:如何在海洋中有效筛选好的信息,以及避免被不好的信息左右我们的大脑(Critical Thinking)关于以上提到的几点我在豆瓣上有一个专门的豆列(“学会思考”),希望有一天我能够积累出足够多的认识对这个主题展开一些详细介绍。
最后分享一个学习小Tip:
学习一个小领域的时候,时时把“最终能够写出一篇漂亮的Survey”放在大脑中提醒自己,就能有助于在阅读和实践的时候有意无意地整理知识的结构、本质和重点,经过整理之后的
知识理解更深刻,更不容易忘记,更容易被提取。
杨军在 TopLanguage 上也曾分享了三篇非常棒的学习心得的文章,字字珠玑: [1] 有些事情做起来比想象中容易 [2] 有关读书方法的一点想法
[3] 一件事情如果你没有说清楚,十有八九不能做好