学习各类开源项目,已经成为不少朋友不可回避的工做内容了。笔者本人也是如此。在接触并学习了若干个开源项目以后,笔者试图对本身工做过程当中的若干体会加以总结,以期对一些但愿借鉴的朋友有所裨益。编程
须要说明的是,笔者本人接触的开源项目大多属于计算机系统领域,例如Linux kernel,KVM,QEMU,OpenStack等。所以,此处介绍的经验一定也有些局限。请读者们自行分辨,区别对待。数据结构
对于一个开源项目,能够将与之相关的各类知识和技能的学习大体划分为以下五个层次: 架构
第一层次:了解项目的基本概念、基本用途、逻辑结构、基本原理、产生背景、应用场景等基本知识。 框架
这个层次的基本定位其实就是“科普”。若是对于一个项目只须要有些基本了解,且短时间内并不须要上手进行实际技术工做,则学习到这个层次也就能够先应付一下了。 编程语言
第二层次:掌握项目的基本安装流程和使用方法。 函数
这个层次的基本定位是“入门”,以便对这个项目得到直观认识,对其安装和使用得到亲身体验。若是只是须要以as-is方式使用这个项目,则初步学习到这个层次便可。 工具
第三层次:了解代码的组织,找到各个主要逻辑/功能模块与代码文件之间的对应关系,经过代码分析走通几个关键的、有表明性的执行流程。 学习
这个层次的基本定位是“深刻”,开始理解这个项目的实际实现,可以真正将项目的功能、工做原理和代码实现对应起来,得到对这个项目工做过程的直观认识。这个层次是学习开源项目代码的真正开始。若是但愿基于这一项目进行应用开发,或者针对与这一项目密切相关的其余项目进行工做时,则对项目自己的代码进行这一层次的理解,会颇有帮助。 google
第四层次:了解该项目全部代码模块、程序文件的做用,走通全部主要执行流程。 云计算
这个层次的基本定位是“掌握”,可以比较全面、系统地理解这个项目的设计和实现,而且熟悉项目各个部分的代码。若是但愿对项目进行深度定制修改,或者对社区有所贡献,则应当以达到这个层次做为目标。
第五层次:钻研、领悟该项目的各类设计思想与代码实现细节。
这个层次的基本定位是“精通”,精益求精,学无止境。这是大神们追求的境界。若是但愿成为项目社区的重要贡献者乃至核心贡献者,则应当以这个层次做为努力的目标。
综上,对于一个开源项目的学习过程能够大体分为五个层次。至于到底要学习到什么阶段,投入多少相关精力,则彻底取决于学习的目的。
学习一个开源项目须要的知识基础主要包括:
1)该项目涉及的技术领域的背景知识
举例而言,分析Linux Kenrel,则应该了解操做系统原理;学习OpenStack,则应该知道什么是云计算。若是没有这些背景知识做为基础,上来就死磕源代码,只能是事倍功半。
2) 该项目开发使用的语言及其各类开发调试工具
这个就无需多言了。
3) 英语
很遗憾,目前为止真正流行的开源项目大部分不是起源于国内。所以,除了学习个别极其流行、文档完备的项目以外,你们仍是须要自行搜集阅读英文资料参考。学好英语很重要。
固然,到底须要准备多少知识基础,彻底取决于学习的目的和层次。若是只是想科普一下,也就没必要太过麻烦了。
学习一个项目的过程,其实就是由表及里了解分析它的过程。上述说起的五个学习层次便组成了这样一个逐渐深刻的过程。在此基础之上,学习、分析代码的过程,也能够尝试作到由表及里、逐渐深刻。
在刚开始接触一个项目的时候,咱们看到的其实就是一个黑盒子。根据文档,咱们必定会发现盒子上具备若干对外接口。一般而言,这些接口能够被分为三类:
所以,在分析一个开源项目的代码时,能够围绕重要的配置、控制、数据接口展开分析工做,特别应该注意理解一个关键的接口背后隐藏的操做流程。例如,针对数据接口,至少应当走通一条完整的数据输入输出流程,也即在代码中找到数据从输入接口进入盒子后,通过各类处理、转发步骤,最终从输出接口被传输出去的整个执行过程。一旦走通了这样一条流程,则能够将与数据处理相关的各个主要模块、主要步骤贯穿起来,并将逻辑模块图上和文档中的抽象概念对应到代码实现之中,能够有效推动对于项目的深刻理解。
在实践这一思路的过程当中,笔者建议能够优先从控制接口和数据接口中各自选择一二重要者进行背后的执行流程详细分析,力争找到其中每一步的函数调用及数据传递关系(对于一些系统、应用库提供的底层函数能够先行跳过以节省时间)。这一工做完成以后,则第1节中第三层次的学习目标便可初步达成。
配置接口在不一样的项目中的重要程度不一样。对于一些架构极为灵活、配置空间甚大的项目(如OpenStack的Ceilometer),则能够适当多花些时间加以研究,不然简单了解便可。
对于这个学习思路,下文中还将结合实例进行进一步的说明。
如下是笔者的一些零散建议,供你们参考。
1)作好记录
在刚刚入手开始学习某个项目的源代码时,其实颇有点破译密码的感受。大量的数据结构和函数方法散落在代码的各个角落里,等待着学习者将它们贯穿到一个个重要的执行流程中。所以,在分析学习的过程当中,不管有什么零散收获,都值得认真记录下来。珍珠天然会串成项链的。
2)不要过度纠缠于细节
立志搞懂一个项目的每行源代码是值得尊敬的,但至少在刚刚入手的时候是没有必要的。若是过于纠缠于代码的实现细节,则可能很快就被搞得头晕眼花不胜其烦了(看英文资料的时候,每遇到一个不认识的词都要马上查词典么?)。不妨避免细节上的过分纠缠,仍是先尽快走通关键的执行流程,将项目的骨干框架搭起来,而后再以此为参照,就能够清晰判断什么代码值得深刻分析,什么地方能够简单略过了。
3)想像和联想很重要
如前所述,从零开始搞懂一个项目的代码,就像破译密码。所以,不妨展开合理的想象和联想,将各个零散的发现和理解联系起来,并加以分析印证。在这个过程当中,对项目所在领域的背景知识、对项目自己的逻辑框架和工做原理等方面的理解,都是想像和联想的参照与指导。此外,一些关键的函数名、变量名等等都是联想的hint。本质上,编程语言也是语言,而程序代码就是说明文。在分析代码时,必定要超越语言和代码的细节去理解被说明的事物自己。
4)该搜就搜
分析代码的时候,很容易出现的状况就是,一个执行流程走到半截找不到下一步了。。。在这种状况下,固然首先仍是推荐采用各类调试工具的单步执行功能加以跟踪。若是暂时不会,或者种种缘由只能进行静态代码分析,那么该搜就搜吧。各类IDE工具的文本搜索都能用,哪怕是grep也行。至于到底以什么为搜索关键词,就须要琢磨琢磨了。
5)外事不决问google,内事不决问百度
如题,不解释。
转自CSDN 做者资料
章宇于2002年及2007年分别于清华大学电子工程系得到学士及博士学位,其后一直从事计算机系统领域的研究与开发工做,目前供职于华为技术有限公司云操做系统部门,从事OpenStack相关工做。出于工做缘由和我的兴趣,做者陆续关注了一些开源项目,主要包括:KVM/QEMU,libvirt,virt-mamager,OpenStack,Open vSwitch,Ceph,Zabbix等。