TL;DR
目标导向,带着问题读源码;自顶向下,先理解 what,再去代码中找 how;最后擅用图形化工具,抓大放小,有的放矢。
目标导向
为什么要阅读源码,这个问题将贯穿阅读源码的始终。
这段源码解决了什么问题,你是为了弄懂这个问题而阅读源码的吗?如果你是为了学习优秀的代码,你要学习的是代码的风格,代码的模块划分,还是具体的算法实现?
不带着目标去阅读源码,只能像无头苍蝇一样到处乱撞,收获甚微。
目标回答的是 why 的问题。
自顶向下
即便明确了目标,也不应打开 IDE 开始阅读源码。
首先理解相关概念,然后再深入其中的数据结构及其关联,最后才是阅读源码。
采取自底向上的策略,会迷失在细节的相互引用之中。只见点,不见面。
以 Python Threading 这篇为例,一定是理解了 Thread/Event/Condition 等概念、理解它们之间的关联之后,再去看数据结构的实现。
优秀的源码,肯定是按照几个主要概念组织代码的。从概念入手,就将复杂的代码做了第一步拆分。
这里的概念不仅是名词,更多时候是动词。比如 Redisson 的布隆过滤器实现,布隆过滤器解决了什么问题,如何解决的。这些问题在看代码之前已经有了答案。
代码回答的只是 how 的问题。从代码中寻求 what 的解答,不是不能,而是不够高效。
抓大放小
在阅读源代码的阶段,要将注意力集中在更重要的部份,不要调入细节的黑洞。
比如每个函数调用都会对返回值进行检查,这是非常重要的。总有异常情况可能导致程序崩溃,代码必须能够正确处理各种情形。但此类细节会妨碍我们察看真正重要之处。
这时候,流程图就有用武之地了。流程图来说明函数执行的实质工作,同时省略一些东西。
以 Redis 创建 event loop 为例,下图就足以捕捉实质性的操作,而不会被次要的工作干扰。
一个忠于源码的流程图,既不清楚,也难于理解。