9本醍醐灌顶的计算机好书

本文集合了鹅厂程序员们强烈推荐的9本经典计算机图书,“工作以后重新读来让我有种醍醐灌顶之感”,这是他们对这些书籍的评价。

这9本书涵盖了计算机理论科学、软件工程、分布式系统等,做到了既经典又全面。如果你在规划自己的学习计划,不妨将这几本书放进自己的书单,结合实际工作和问题场景去阅读,相信会给你带来全新的体会和认知。

01、The Art of Doing Science and Engineering

这本书是 Richard Wesley Hamming(1968 年的图灵奖得主、20 世纪最著名的应用数学家之一、编码论的奠基人)一门课程的口述稿,是 Hamming 一生关于学术、研究、智慧的结晶。本书的主题是以下几个问题:

  • 是什么激发了伟大的想法?我们能否通过训练,以期使我们的思考方式能够孕育出足以改变世界的理解和见解?
  • 在一个知识爆炸的年代,我们如何掌握和了解知识,才能做出有意义的学术研究和工程?

在书中,Hamming 根据他自己的学术生涯经验总结了计算机科学与技术的主要领域,并在书的最后给出了很多关于研究与工程的真知灼见。You and Your Research 是 Richard Hamming 最著名的演讲,收录于本书的最后一章。对我影响最大的几个观点是:

  • 应该做“好”的研究和项目。方向不对,努力无用。
  • 学习有复利效应。
  • 数学无非是清晰地思考。
  • 人是自身所有习惯的总和。

我最为赞同“学习有复利效应”这个观点。从上学到现在,我经常见到和我同龄甚至比我小的人,知识量的渊博和观点的深刻都远超于我许多倍。Richard 也有过这个纠结(他甚至在书中讲了一个完全类似的故事),而他得到的答案是,学习的复利效应很明显,所以开卷有益,而且是远超想象的收益。所以我一直不遗余力地宣传程序员也应该持续学习,多读书。学不进去的最后都转行去开宠物乐园了。

02、The Mythical Man-Month: Essays on Software Engineering 人月神话

人月神话这本书的经典之处在于,本书第一版上市于 1975 年,距今已有近 50 年的历史。在技术更新换代如此之快的今天,这本书的观点与理论仍旧具有超越时代的指导意义。

计算机领域飞速发展了近 50 年,性能更强的硬件、延迟更低速度更快的网络、更加极致弹性的计算、存储资源、更加完善的框架、更多花活的编程语言、更为先进的设计思想……软件工程领域过往存在的问题,却并没有随着底层技术的进步、基础设施的完善而得到解决,反而更加凸显:工作量仍旧无法评估、进度排期仍旧难以合理安排、万事不决叠人力、 Bug 反复出现大家都是草台班子、大量软件陷入失败……

人月神话领先于时代地指出,人力和时间并不呈现线性关系。以大量人员和较短的时间,并不能缩短软件的开发进度。一窝蜂的作业方式无助于软件生产,且会制造麻烦,产生出更差的软件。向进度落后的项目追加人力,只会使进度更加落后。

“没有银弹”,是人月神话的又一个经典。在这个微服务解决一切问题的当下,技术选型上的迷信和争论仍旧喋喋不休。越深入软件开发,读起《人月神话》你的感触和体悟会更深。

03、Probability and Computing

常读常新。概率论在计算机科学的应用的经典之作。这本书中的知识和技巧应该是做算法与系统设计的必备。

概率论近几十年在计算机科学中的应用可谓显学,在不同的领域,尤其是算法设计、数据库、网络、机器学习、大数据中有极其广泛的应用。

本书每一个章节都从概率知识开始讲起,以在计算机科学中的实际应用收尾。作者 Michael Mitzenmacher 是随机算法、网络方面的专家,特别是深耕过一系列关于 Bloom Filter 的领域。熟读这本书能够为理解概率数据结构、Sketching 等工程中常用工具提供坚实的理论基础,对读相关的论文也有帮助。

这本书编排很实用。它的出发点是为计算机科学家所写,所以主要聚集于离散过程,不需要像普通的概率论教材一样从测度论开始。测度论当然很有趣,但对工作的作用的测度为 0。

04、The Cathedral & the Bazaar 大教堂与集市

本书讨论的是两种不同的软件开发模式:

  • 大教堂模式(The Cathedral model):源代码在软件发行后公开,但在软件的每个版本开发过程中是由一个专属的团队所控管的。
  • 市集模式(The Bazaar model):源代码在开发过程中即在互联网上公开,供人查看及开发。

本书的核心要义是“让够多人看到源代码,错误将无所遁形”(Given enough eyeballs, all bugs are shallow)林纳斯定律。

简单摘录几句书中的经典观点,你就能 get 到本书的含金量:

优秀的程序员知道写什么,卓越的程序员知道改写(和重用)什么。

好的软件作品,往往源自于开发者的个人需要。

当你对一个程序不再感兴趣时,你最后的责任就是把它交给一个可以胜任的接棒者。

当你开始社区建设的时候,你需要能够呈现一个可行的 前景。你的程序不一定要工作的非常好。它可以是粗糙的、 问题多多的、不完整的、缺少文档记录的。它一定不能失败的是(1)能运行,(2)说服潜在的合作者它可以在可预 见的将来进化成真正漂亮的东西。

05、Staff Engineer

Will Larson 的作品,可以命名为“高阶程序员生存指南”。这本书不是关于计算机科学知识,而是关于软件工程。更确切地,这本书是“微观软件工程”,描述了作为一名高阶工程师的工作任务和职责,以及常见的陷阱需要避免。

这本书可以完美地回答“TL 到底有什么用”的问题。尤其,它解释了为什么一个高 T 一年不写几行代码并不代表他没有干活。书中的答案是:

  • 设定技术方向

需要务实、深思熟虑、关注长期趋势。不要过度关注自己感兴趣的技术,而是理解和解决组织的真正需求。

这本书严重地警告 “Stop Chasing Ghosts”:一个高级管理在空降到一家公司的时候,会完全地误判了当前的真正挑战,而立刻驱动一项重大的战略转变。他们在原本公司里面的成功或是失败的经验会极强地影响他们对新公司情况的理解,以至于他们把熟悉的当成重要的。

  • 指导、培养和支持

不要过度个人英雄主义。给初级工程师提供指导,给高级工程师提供支持。

  • 提供技术视角

没有一个技术产品是纯“技术”产品。商业产品往往是多个视角的结合体:商业、技术、产品、运营、设计……

为高层的商业策略提供“技术”层面角度,不要让技术缺席,出现“这个需求很简单,怎么实现我不管”。

每个 TL 都应该是一个好的产品经理。如果一个老板觉得 TL 只应该管技术的事情,连参与讨论产品都不应该,那这个老板是外行,而你也应该准备跑路了。

  • 写代码

是否仍然写代码应该看项目的具体情况。但是如果写太多,如同你在更低的级别,那往往是躺在舒适区、而没有把时间放在更重要的任务上的表现。

当然,不写代码不应该是因为不会,而应该是优先度不高。对大部分高阶工程师来说,Code review 仍然很常见。

衡量一个 TL 的代码水平,不应该看他的代码质量,而应该看他所管理的项目的代码质量。

不管是哪个级别的同学,这本书都值得一读,虽然可能体会不同。这也是一本常读常新的书。

06、Designing Data Intensive Applications

可能是数据密集型应用开发最好的入门书。虽然有 data-intensive 这个定语使得这本书看上去应用面比较窄,但是 data-intensive 是与 computation-intensive 对应的,现代工业界的大部分系统都是数据密集型的。这本书难得地融合了学术界理论与工业界实践。

这本书已经有太多人推荐了,在此不再赘述。在此稍微提一点读书的心得:应该把这本书作为知识体系的基础,以”修书“的方式来读这本书。

  • 本书的层次非常高,适合入门。如果之前只是对系统设计有初步了解的同学,用来建立自己的知识体系会很合适。
  • 但同样,很多可以深挖的细节也被一笔带过了。举一个简单的例子,文中提到 "ACID" 这个词由于定义不清晰,已经被滥用了,成了一个营销专用词。但实际上不同的数据库对 ACID 的不同理解和取舍是很不一样的。所以,对这本书进行扩写,会是扩展完善自己知识体系的好办法。
  • 书中的文献引用内有大量有价值的内容,非常值得一读,可以极大地扩展知识体系的深度。
  • 分布式、数据库、计算框架这几年的进展很快,所以其中的描述的一些系统和认知每年都有新的更新。可以把书中的内容按自己的理解更新认知。
  • 阅读其它的文献,扩展知识体系的广度。

07、Software Engineering at Google 谷歌软件工程

大部分软件工程的教材会很详细地描述软件工程的整个生命周期,设计、需求、建模、开发、测试、发布、维护,但是对具体的工程实践所涉甚少。

归根结底,一方面软件工程还处于发展的初期,还没有系统的方法论;另一方面,软件工程的主体不是软件,而是人,而人是极其复杂的,很难有简化的模型。所以,业界的共识是,对软件工程,尤其是工程师的产出,进行量化,至少在现在是不可能的。但是,软件开发的复杂性是切实的,又需要对项目进行管理。

SE@Google 这本书非常诚实地描述了 G 家对软件开发的核心复杂度的认识:复杂度来自于时间,所谓 软件工程=代码*时间。他们的软件工程都是在与时间导致的复杂度做斗争,主要分为文化、流程和工具三种。我尤其关注了工具部分,因为与本职工作更相关。

这本书好就好在它不光讲了怎么做,还讲了为什么要这么做:每一样大规模推广的工程实践都详细地阐述了动机,甚至对其中的子决定的取舍都做了叙述。其中书中的大部分实践,也正是我们在日常工作中都需要的:

  • 版本控制
  • 构建系统
  • 持续集成
  • 持续部署
  • 代码评审
  • 文档编写
  • 测试

不过,学习别人的实践要做到三层境界:“怎么做/WHAT”,“为什么这么做/WHY”,“为什么不用别的办法做/WHY NOT”。选择某些实践可能看上去理由充分,但是为什么不选择同样合理的其它实践呢?这可能只是由于公司的惯性和历史等很多因素,而这并不为外人所知。那么,如果只是单纯地复制别人的实践,很容易东施效颦。一定要结合组织的实际情况(正如 Staff Engineer 中所说,stop chasing the ghost)。在做大型的软件工程治理时,应该治大国如烹小鲜,谋定而后动;而一动下定决心,就应该不再回头。

08、Economics Rules 经济学规则

解决了我长久以来的困惑:如果抽象的模型是简化的,那么它在映射到现实世界时不会失灵吗?如果会的话,那么抽象模型的意义是什么呢?

果然,这个困惑不只是我专有:著名的经济学家 Ariel Rubinstein 说,“‘模型’一词听起来比‘寓言’或‘童话’更科学,(但)我看不出它们有多大的区别。”。这本书并不是计算机书籍,而是一本经济学家的反思之作:“部分由于经济学家把自然科学当作榜样,他们有误用模型的倾向。他们常常会把具体模型误解为无论何时皆适用的普适模型。经济学家必须克服这种倾向。他们必须根据条件变化、根据关注对象的变化而谨慎选择模型。他们需要学习如何更自如地在不同模型之间转换”。

这本书给我的启示是,软件工程并不是自然科学,而更像经济学/社会学/管理学。如果没有模型,软件工程也很难进行知识创造,但是,滥用模型,把所有的问题诉诸于使用某些大银弹,会极大地增加模型失灵的风险。

不应该在软件工程中过度使用数学方法。不应该建立关于软件工程的基本假设,然后在此建立复杂的数学推理进行模型推演以得到一些自己都说不定不信的结论。

这本书同时回答了我另一个困惑:为什么知道这么多道理,但还是过不好这一生。因为所有的道理都是简化的模型。这个世界上只有这个世界才是真实的模型,在此之外,不过是你的,还是别人的,还是畅销书的道理、真理、方法论,都是简化的模型。拉普拉斯之妖并不存在,计算的极限也说明决定论是不存在的,而心智的成熟就是我们内心中那个模型逐渐完善的过程。

09、Computer Systems: A Programmer's Perspective

本书的中文译名叫《深入理解计算机系统》,但实际上原意更符合“系统开发者的视角”看计算机系统,这是本操作系统入门书,不是所谓读一本就精通 os 的万灵药。无论是北大上交还是 CMU,这本书都是作为大一大二的 ICS 计算机系统导论课进行教学。

这本书在国内计算机领域的地位非常稳健,无论是本科阶段的教学还是考研阶段的进阶,都会大量运用到本书作为学习工具。对国内的计算机专业学生而言,这本书更像是一种启蒙,而非30天精通的毕业之作。

然而现实情况是,大多数计算机专业毕业生直到参加工作,都未必对本书有多深入的了解。尽管如此,它仍旧值得每个没有接触过类似书籍的人去认真阅读。

-End-

原创作者|鹅厂推书官