如何正确的阅读源代码?


写完「你也能够像 Prisma 同样渲染图像」以后,有读者提了这样一个问题:程序员

我猜您平时应该有阅读开源项目的源码,好的开源软件或者框架,动辄数万行的源码,虽然说是宝藏,但我看源码一直不得要领,投入时间很多但收获甚微,请教下:编程

您阅读源码的关注点通常有哪些?markdown

您看源码有没有什么方法论呢,如何抓住重点下手?有时面对优秀的开源框架,想学习,我甚至都不知从哪看起。架构

关于这个问题,我说两句。框架

阅读优秀的源代码是软件工程师提升本身编程能力和学习开源框架的最佳手段之一。做为一名运动员,除了持续的刻意练习,还须要观摩大量对手的比赛视频。做为一名小说家,除了笔耕不辍,还须要阅读大量的其余做家的伟大做品。固然,观摩和阅读不是目的,是手段。路遥在创做《平凡的世界》以前读了大量的「名著」,而后,他把全部尊敬的做家都安放在远方历史为他们准备的「先圣词」中,让他们各自光芒四射,照耀大地,而后开始创做百万巨著《平凡的世界》。照耀你的世界的光芒,应该是本身发出的。分布式

程序员亦是如此。在编程的路上,有无数的大师写出了伟大的代码和软件,去学习他们的编程技巧和技术风格,取其精华,去其糟粕,最后完成本身的做品。2005年左右我有幸参与了一个相似 CORBA 的分布式应用系统的开发,我在那段时间差很少通读了这个项目的早期代码,其总体架构规划和代码设计的精巧程度让人叹为观止(代码的编写者是早期的 CORBA 规范制定者)。这个经历对我后来的编程之路产生了深远的影响。函数

与编程同样,阅读别人的源代码永远不是一件轻松的事,或者说,是一件困难的事情,须要持续的投入,阅读、研究、把玩、实践。不少人以为拿到了源代码就像买了本书同样,放到书柜上,马上就产生了一种学会了的错觉(我就是这样,微笑),但真正实践起来才会体验到强烈的挫败感。大部分状况下,读不下去,不是方法很差,而是投入度不够。工具

阅读源代码,必定要找到好的开源项目。什么是好的项目?口碑好且应用普遍的项目就是好项目,好比 Docker、Spring、OpenResty,都是很是好的阅读素材。另外,完善的文档和足够的 test case 覆盖率,都是衡量一个开源项目是否优秀的标准。不少人说,代码即文档,好的代码自己就是自解释的。可是,对于规模宏大的开源软件来讲,没有文档是不可想象的。因此在阅读源代码以前,必定要读文档。尽管读了文档以后,你可能不知道代码的技术细节,但至少能够了解项目的轮廓。结合开源项目的代码目录,差很少能够绘制出一个粗粒度的总体架构图,相似这样的:源码分析

而后为每一个目录(或模块)作记录和标识,逐一阅读,或者直接去读你最感兴趣的部分。学习

我读源代码喜欢自顶向下的方式,先把总体脉络理清楚,而后按照模块去阅读代码,把类和类、函数和函数之间的调用关系记录下来,若是能够进行逆向工程,用相似 Intelli IDEA 这样的工具把代码之间的调用关系用 Diagrams 展示出来,阅读会更加直观一些,不一样的语言有不一样的工具能够选择。

另外,阅读 test case 一样能帮助你理解做者的代码设计意图。正常状况下,测试用例都是从文档和设计衍生出来的,而不是完成了代码再写 test case。阅读测试用例,可让你更清晰的知道对应的类和函数想要作什么事情。

阅读源代码须要顺手的工具,我本身喜欢用 Vim,配合 NERDTree、CtrlP、ctags、taglist 等插件,Vim 能够成为一款优秀的代码浏览工具,并且很是轻量级。你能够在终端里用命令迅速打开、关闭、查找和索引程序,并进行有效的关联跳转(静态代码)。若是你不习惯,也能够用 Sublime Text,Atom 等工具。固然,若是你要进行调试和跟踪,那最好使用相关程序栈的 IDE 工具,好比 Eclipse、Jet Brain 系列工具,Xcode 等等,这样你能够在 debug 状态跟踪全部的函数调用和变量参数在执行时间线上的变化。

若是你喜欢 Vim,能够看下这篇「Vim 8.0,姗姗来迟」。

重复一句,工具和方法永远不是最重要的,去读,并在遇到困难的时候,看不明白的时候,咬牙坚持下去,抽丝剥茧,逐个击破。最终,你会在冰冷黑暗的二进制世界里面看到一张地图,找到一座灯塔,而后去解释和还原这个底层世界里每个细微方面的语义,重建出高层次的抽象概念和关系。

最后推荐两本书,《Docker 源码分析》和《Go 语言学习笔记》,这两本书,都是关于 Go 语言的,能够说是源代码阅读的典范,有兴趣能够找来读读。


做者:佚名

来源:51CTO