如何阅读源码¶
前言¶
读了很多资料
源码是最后一步
整体阅读¶
代码量级:
几十 k 体量的代码:
顶多半年,可以精读
既不算太过吃力
也不至于读完意犹未尽
linux kernel级别代码:
总代码量15406.9k
分而治之,每次读一部分
scheduler(20k)
memory management(80k)
阅读类别:
* 基础阅读
* 检视阅读
* 分析阅读
* 对比阅读
检视阅读方法:
1. 读 readme
类似书本的「序」
帮你更进一步了解这份代码的意图
2. 目录结构
像书本的目录页
目录下有 readme,快速阅读
约定俗成的目录结构(Convention by Contract)
快速知道哪些是可以略过的部分
场景一: 为了破案而阅读¶
适用情形:
* 遇到奇葩问题
* 查各种资料无果
方法论:
* 顺着一点蛛丝马迹,开始剖析代码
* 抛开一切纷扰和杂音,集中精力,带着线索,循着问题
* 读且只读和解决问题直接相关的代码
* 「猎手模式」
* 专注,集中力量攻击且仅攻击一点
方法之「猜」:
* 「猜」起到了很大的作用
* 连蒙带猜也是解题的一种思路
* 猜文件名,函数名,变量名,某分支,某段代码的意图
* 结合运行的结果,打印调试信息来印证猜测
* 形成有效 feedback loop(read - guess - verify)
操作步骤:
1. 带着线索,从一堆代码中找出和问题相关的代码
2. 专注阅读挑出来的内容,忽略不相干的噪音
3. 编译运行修改过的代码,复现问题,分析调试信息
4. 没答对,请回第 1 步
复盘:
1. 整理过程:
把整个过程用最简洁的方式记录流水账
关键代码,关键路径,到达终点的整个猜测过程
哪些日志验证了猜测是对的,哪些日志验证了猜测走不通
2. 总结:
这个问题的 root cause 是什么?触发它的代码的流程是什么?
在读代码的过程中,哪些地方我猜对了,哪些没猜对?
有功夫的话,代码的哪个部分是值得细细品读把玩的?
下次再出现类似的问题,我该怎么更快地从源码中定位出问题?
3. 复盘的意义:
帮你把这样的信息沉淀下来,让你有机会回顾
进而组织和固化成上篇文章中所说的知识
这样累积多了,才能形成一个光环,成为砖家
场景二: 为了明理而阅读¶
阅读对象:
* 算法
* 基础知识
* 理论
正反馈:
* 马太效应
* 读的书多,知道的知识点就多,疑问也多
* 疑问促使你读相关的代码去印证和解惑
* 代码读多了,又感觉理论知识欠缺
* 周而复始
完成后还要做的事:
* 这代码有可以优化的地方么?
* 有潜在的安全漏洞么?
* 是否有未处理的状态或者异常?
总结:
1. 使用「检视阅读」把整个代码过一遍,找到值得阅读的核心代码
2. 粗读这部分代码,将其内容进一步 breakdown
手边准备好笔和纸,随时记录
记录最好的方式是图表
3. 精读这部分代码
结合你已有的知识,理解这个代码所需要的资料
猜测和还原代码中事件,消息,或者某个流程发生的场景
把猜测记录下来
遇到外围的代码调用,可先放一下
整个过程完整而详细地捋一遍
这过程要多问问题,减少「我以为我懂了但实际没懂」
4. 用检视阅读法粗读剩下的代码
如果找到其他值得精读的代码
跳至 2
5. 对比阅读
主题阅读
把类似功能的 repo 都扫一遍
尝试着用自己的语言消化不同作者的实现
关注其实现的差异,并试图评判这种差异
6. 用软件将手稿电子化,便于将来回顾
是个非常耗时的过程
好为人师,要把你的心得分享出去
场景三: 为了能级跃迁而阅读¶
目标:
* 打破平台期,成就越级跃迁
* 读代码积蓄能量为跃迁准备
* 读那些基础地不能再基础
* 自己一辈子都不会去写的代码
* 比如 linux kernel,比如 OTP
方法:
* 要有足够的耐心和时间
* 检视阅读 + 主题阅读 + 思维导图
困难:
* 这种阅读有时会让人非常沮丧
* 遇见非常非常之多的 knowledge gap
* 查资料弥补这些你缺失的知识点
* 拉慢了整个阅读理解的步伐
收获:
* 这些 knowledge gap 是上天馈赠的礼物
* 弥补 you don't know what you don't know 的机会
* 享受获取额外知识的喜悦
参考¶
[微信 程序人生 陈天]如何阅读一份代码: https://mp.weixin.qq.com/s/e15zfnHYKpZv3TFrksEzfg
如何阅读一份代码: https://zhuanlan.zhihu.com/p/26222486