写在前面
每个人都有自己的学习方法,选择最合适自己的,才能事半功倍。了解一份别人的代码,也是如此。
很多人觉得代码读得越多水平越高,本人并不完全赞同。
代码的第一作用,是写给计算机执行的,并不只是给人阅读,掌握正确的代码学习方法,才能从优秀工程师的作品中汲取自己所需的。
每个人阅读代码都可能带有不同的目的,或为了了解一个软件的体系结构、或为了了解一种语言的经典使用方法、或为了二次开发做技术准备。这里,描述的是我们在了解一个开源项目的过程中,惯常采用的步骤,希望对您有所启发。在实际的代码学习过程中,您还需要根据自己的需求,做不同的调整。
主要步骤
了解架构
在开始阅读一个项目之前,首先对其整体架构进行了解是非常必要的。否则,一股脑扎进代码细节中,最后看代码的结果必定是晕头转向不知所云。这个阶段我们需要了解的主要内容包括:
- 项目的主要功能是什么?
- 分成多少个子模块(子系统),它们完成主要功能是什么?
- 不同某块(子系统)之间是如何交互的?
- 代码的组织方式是如何的?有怎样的目录结构,从哪里能快速获得项目的README等说明文档。
Hello World
这应该是每个程序员都不陌生的过程。一般项目中都会提供Example或者Hello World样例,尝试按照说明文档搭建执行环境,并编译、使用第一个样例程序,从程序使用者的角度初步了解项目的使用方法以及最基本的接口调用方式。同时,摸清楚项目日志的输出方式、基本的问题排查方法。
编译内核
在这个阶段,尝试依照说明文档搭建编译环境,对项目源码进行重新编译,在IDE中载入工程源码,为代码阅读及修改准备好条件。
修改实现
按照我们的学习(使用)需求,在项目的代码中开始做些简单的修改。可以从最感兴趣的模块开始动手,了解其基本类、函数实现,通过代码注释寻找作用明确的地方,在其中加上一些简单的打印以验证自己对代码的理解。比如,在了解Hadoop的NameNode模块时,找到NameNode的实现类,在其format方法中加入日志,打印诸如“Hi, this is my first log from namenode format!”这样的语句,然后执行NameNode的format操作,查看日志文件中是否出现了自己打印的东西,来验证自己所找的位置是否正确。
复杂结构
对于代码结构有一定了解之后便可以着手了解一个模块更复杂的实现方法。依据不同人的习惯,这里可以借助更多的工具来完成对模块乃至系统的了解。我们可以采用的方法包括但不限于:
- 阅读类代码,通过UML绘制不同类之间的关系。类关系在一些项目的文档中本身就带有,如果有的话,这里可以直接变成对照类关系图,了解代码实现细节。
- 进行一个典型操作,在操作必定会触发的代码中,加上打印代码栈的逻辑,将操作过程中的所触发的逻辑栈打印出来以辅助理解一个典型操作发生时,不同类之间是如何相互调用和完成这个功能的。比如,在Java代码中,通过(new Exception()).printStackTrace(),就可以打印当前代码被触发时,前面一共经历了什么样的调用过程。
- 在Linux中,熟悉strace、tcpdump等工具,当希望了解特殊的系统操作流程或者网络操作等信息时,可以适时的用上这些工具。
看代码的方法,跟学习方法一样,千人千面,每人都应有最适合自己的。这里仅抛砖引玉,欢迎交流。