代码阅读方法

基础阅读,检视阅读,分析阅读,对比阅读。
接下里我们目光需要聚焦在代码的目录结构,和每个源码的文件名。

很多语言和框架,有约定俗成的目录结构(Convention by Contract),因此,通过目录我们就可以快速知道哪些是可以略过的部分,比如 django 的 management/commands 目录,elixir 的 mix/tasks 目录,这些目录,承载着支线剧情,需要的时候,或者闲得无聊时再读也不迟;

然后我们开始从入口梳理主线。不同语言和框架的主线不太一样,比如 C 的入口是 main(),erlang/elixir otp app 的入口是 app:start,nodejs 往往是根目录下的 index.js,等等。一般而言,application 的主线比较清晰,一路下来,会走到一个 mainloop,而 framework 的主线会晦涩一些,因为 framework 往往是 application 抽象出来的部分。

我们会读根目录下的 readme,或者任何看上去撩拨着你让你戳它的文件。这就跟书本的「序」一样,能够帮你更进一步了解这份代码的意图;

场景一:为了破案而阅读代码

1.带着线索,从一堆代码中找出和问题相关的代码。nginx cache 的例子中,线索是 proxy 的 upstream,cache 总不能命中,所以出问题的代码和 cache,proxy,upstream 有关。源码目录里一翻,就能挑出需要看的文件。由于问题在 cache 上,在挑出的文件中,具体看 cache 相关的函数名,宏名,以及代码。

2.专注阅读挑出来的内容,忽略不相干的噪音。在阅读的过程中,着力寻找潜在的触发问题的路径,然后动用「我猜我猜我猜猜猜」大法,加调试信息。

3.编译运行修改过的代码,复现问题,分析调试信息,然后,bingo,恭喜你答对了!请进入第 5 步。
没答对,请回第 1 步。

4.所以关键的第 5 步是:复盘。解决问题后,趁着那坨记忆还热气腾腾,抄起 evernote(或者 xxx),把整个过程用最简洁的方式记录下来 —— 关键代码,关键路径,到达终点的整个猜测过程,以及那些日志验证了猜测是对的,哪些日志验证了猜测走不通(恭喜你 —— console 或者 terminal 在这个时候应该还没关),总之,你在不择手段的过程中用过的一切手段,都应该像记流水账一样记录下来。最后分析总结:

这个问题的 root cause 是什么?触发它的代码的流程是什么?

在读代码的过程中,哪些地方我猜对了,哪些没猜对?

有功夫的话,代码的哪个部分是值得细细品读把玩的?
下次再出现类似的问题,我该怎么更快地从源码中定位出问题?

场景二:为了明理而阅读代码

算法:bloom filter 究竟怎么实现的?怎么样把 bandit 算法在自己的系统上做简单的推荐?ossip 协议实际的生产环境的代码是什么样子的?Linux kernel 如何实现 O(1) scheduler?
基础知识:一个完整的涵盖 HTTP 1.1 协议的 REST API framework 如何实现?一个 packet 从 OS 的 driver 是如何一路送上 application 的?什么是 zero copy?Linux kernel 如何实现 zero copy?
理论:啥是 IoC / DI / Pub Sub?各种 framework 都是咋实现这些设计模式的?supervisor 这个 behavior 背后的实现是如何的?
先使用前面所述的检视阅读法把整个代码过一遍,找到值得阅读的核心代码。
粗读这部分代码,将其内容进一步 breakdown。手边准备好笔和纸(或者其他趁手的工具),随时记录。记录最好的方式是图表。这个阶段的记录不建议用软件工具(除非有用着特别舒服的,能够人件合一的)。
精读这部分代码,结合你已有的知识,理解这个代码所需要的资料
猜测和还原代码中某种事件,消息,或者某个流程发生的场景。
把猜测记录下来。
这时,如果遇到外围的代码(调用了外部的函数),只要对理解不产生障碍,可以先放一下,把整个过程完整而详细地捋一遍再说。
这个过程一定要多问问题,把「我以为我懂了但实际没懂」的情形尽可能减少。
用检视阅读法粗度剩下的代码,如果找到其他值得精读的代码,跳至 2。
使用对比阅读(或者说,主题阅读)方式,把类似功能的 repo 都扫一遍
尝试着用自己的语言消化不同作者的实现,关注其实现的差异,并试图评判这种差异。
用软件将手稿电子化,便于将来回顾。文字可以直接上笔记本工具(甚至可以尝试 gitbook),图表如果买不起 visio,omniGraffle 这样的工具,可以用 plantuml

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值