> For the complete documentation index, see [llms.txt](https://shniu.gitbook.io/cs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shniu.gitbook.io/cs/other/yue-du-yuan-ma.md).

# 阅读源码

如何阅读别人的代码，如何阅读一些开源软件的代码

**阅读别人的代码需要一定的目的性**，完整的把一个软件的源码都读完，急需要精力耐心，也需要大量的时间，而这样做的结果 ROI 也比较低。所以说，阅读源码前，搞清楚你的目的：

1. 在做技术方案时需要评估某个第三方库/框架，这个时候需要做技术 Spike，也可以去读一些它的核心流程的代码和设计，来看它的代码质量如何
2. 为了解决项目中的一个 Bug，这个 Bug 比较棘手而且资料较少，参考较少，我们可以通过读源码的方式来探索底层机制、实现原理，从而找出一些对策
3. 需要长期接手一个项目，并维护它，这个时候需要完整阅读这些代码
4. 某个开源的项目比较好，代码质量高，设计优秀，学习这个项目作为榜样，探索它的设计精髓和代码实现
5. 应付面试，探索更多的源码级别的知识
6. ...

阅读源码除了需要有目的性，还需要树立正确的心态，读源码是非常艰难的，因为它是架构的反向过程，需要根据代码来反推更高纬的思想。

1. 读源码是很难的，要有心里准备，它是架构的反向过程
2. 读源码是持久站，不可能会一下子就看懂
3. 读源码前最好有一些相关的理论知识，最好先从它的文档下手，先去简单的使用，搞清楚是什么
4. 阅读源码也是有方法的，在阅读源码的过程中需要有产出，比如画流程图、画类图、画时序图、写总结文章等

理解架构的核心脉络

1. 有文档的先读文档，从文档中了解架构的设计思想，通过文档和代码可以互相印证
2. 理解系统的概要设计，概要设计的关注点是各个软件实体的业务范畴，以及它们之间的关系

怎么做？

1. 把公开的软件实体（模块、类、函数、常量、全局变量等）的规格整理出来
2. 看 example、unit test 等，这些属于我们研究对象的客户，也就是使用方。它们能够辅助我们理解各个软件实体的语义。
3. 印证结论，我们在读代码前可能会有很多疑惑和猜想，读源码时就可以印证；如果有更懂的人，最好带着问题列表去寻求别人的解答
4. 确保我们正确理解了系统，将结论写下来，形成文档
5. 制定**阅读计划**，一步一步来，积少成多
6. 运用一些技巧：理论先行 -> 自己使用并构造一些场景 -> 调试 -> 分清主次（先后顺序的优先级，有可能有的分支会很多，要懂得取舍）-> 业务为先不求甚解 -> 勇于试错 -> 留意注释 -> 勤做笔记 -> 循序渐进

所以，对于一个项目（无论是开源的还是公司的业务系统）最终需要的是：

* 搞清楚项目解决的问题，以及应用领域，应用场景
* 搞清楚系统的概要设计
* 搞清楚系统的关键业务流程
* 理清楚系统的接口（包括开放的API接口，还有内部设计细节的类和接口）
* 在阅读代码的过程中，我们可以做很多事情：比如发现代码的坏味道，就小范围的修改（修改时需要保证修改前后的语义一致，需要注意边界Case等）；学习别人的架构设计、系统设计、类和接口设计、运用的设计思想、设计原则与模式、针对特殊场景的处理思路等（学到之后尽可能的用到自己写的代码中）

制定自己的源码阅读计划，脚踏实地。

带着问题去读开源源码，具体要怎么做呢？

1. 通过看文档来了解架构设计、系统设计、功能设计等
2. 找到一个很小的问题来读源码，验证这个小问题，以点带面

使用这种以问题为阅读单元的方式来读源代码，你每次只要花很短的时间，阅读很少的一部分源码，就能解决一个问题，得到一些收获。这种方式其实是通过一个一个的问题，在网状的源代码中，每次去读几个点组成的那一两条线。随着你通过阅读源码了解的问题越来越多，你对项目源码的理解也会越来越全面和深入。

参考

* [如何阅读别人的代码](https://time.geekbang.org/column/article/186399)
* [大牛是如何阅读源码的？](http://blog.itpub.net/31545684/viewspace-2653724/)
* [学习开源代码该如何入手？](https://time.geekbang.org/column/article/115519)
* [高效学习：如何学习和阅读代码](https://time.geekbang.org/column/article/14380)
