如何有效的阅读开源代码

目录

零、开源项目是什么?

开源项目不仅仅是开放源代码,起码要满足四点:

一、初步了解

1、走读官网文档(至少一遍)

2、了解代码目录结构

3、在安装部署前补充新概念、新技术

二、安装部署,运行(很重要!)

2、1 成功运行并简化环境

2、2 成功运行意义何在

三、运行并研究Example例子

3、1 最简单的入门例子

3、2 逐步研究更复杂的例子

3、3 手写个人demo

四、针对部分组件,阅读其测试用例

五、阅读源代码之前必读

5、1 看代码之前认真看文档

六、阅读源代码

6、1 明确阅读代码的目的

6、2 区分主线和支线剧情

6、3 挑选感兴趣的“分支”来阅读

6、4 理清核心数据结构

6、5 添加日志 and 单步调试(情景分析)

6、6 画图梳理逻辑

6、7 解决遇到的问题

七、写笔记记录想法,促进思考和总结

八、抄写项目源代码

九、仿写项目

十、教给他人(输出知识)

更新日志:

阅读开源代码,一上来就陷入技术细节是大忌!!!

参考链接:


零、开源项目是什么?

开源项目不仅仅是开放源代码,起码要满足四点:

1、开发项目中所有源代码以及配套工具

2、完善的文档,如新手入门文档、项目整体架构设计文档、模块的详细设计文档、配置说明文档以及注意事项。

3、活跃的社区

4、持续的更新和完善

一、初步了解

1、走读官网文档(至少一遍)

有多少人愿意花时间好好看官网文档的?估计很少,大家一上来就是开始撸代码,强撸!!!

常见的几种错误:

1) 一头扎进代码细节,直到怀疑自我

我国的教育体系主张研究透底层机制后,才开始动手实践,其实并不然,俗语:“知其然,然后知其所以然”,学技术也是如此,先知道大概是什么样,然后才能逐渐的研究其原理。

人的认知过程是从观察、模仿、亲身实践、总结经验或教训,然后逐渐学会一项技能,此技能练习千百次,才慢慢窥探到其底层原理。

一个人想直接透过问题表象看到问题本质,是很难的。

2) 未阅读完操作文档,就着急动手实战,得不偿失

为赶项目进度没好好看文档就匆匆忙忙的撸代码,代码运行后有很多稀奇古怪的问题,再回过头来排查这些问题,发现是自己的使用方式有问题,而这些在文档中已明明白白的写的很清楚。

3) 多参与开源社区,闭门造车要不得

虽然网上的技术博客,专栏,公众号平台或视频课程都会针对某个技术做讲解,但是我依旧推荐

推荐你看官网的一手资料

为什么这么说呢?

时代在发展,开源软件也在不断的进化,,从时效性和内容准确性上都要比中文技术博客的内容要好的多。

重点关注下Get Started和Example之类的文档,能够帮助更快的入门。

重点看文档中什么内容:

1、开源项目背景

采用了什么技术?

提供了什么功能或特性?

解决了什么问题?

2、适用场景

优点是什么?

缺点是什么?

适用于什么场景?

不适用什么场景?

明确了适用场景,才能在架构选型时有的放矢。

3、哪些公司在生产环境中使用

有多少公司在生产环境中部署并维护过此开源项目?

一方面经历过生产环境的项目质量相对较好,即使有bug其他公司或多或少也遇到过,自己解决起来不至于孤立无援。

可以从侧面证明项目很有潜力和竞争力。

2、了解代码目录结构

在下载源代码之后,先看下代码目录的组织结构,可先从示例代码或测试代码入手。

base代表基础库

net代表网络库

demo/example代表示例代码

tests:测试代码

docs:文档目录(类图,流程图,活动图,业务知识相关资料等)

入手之初,建议从例子代码或测试代码开始看(demo,example,test)

3、在安装部署前补充新概念、新技术

在已有的知识体系之上去学习新的开源项目,需要对新概念或新技术有个大致的了解,才能更好的理解项目的整体实现思路,做起事情来事半功倍。

千万不要一上来就看代码,核心概念不清楚,核心原理不懂,核心算法没吃透,看代码很难看懂。

二、安装部署,运行(很重要!)

2、1 成功运行并简化环境

好的开源项目,其文档都比较完备,安装部署文档一般会在README中或者doc目录中,甚至提供rpm安装包和docker镜像

如果官网提供qq群或微信群,也可以加下,毕竟里面有不少技术资料可供参考。

将程序运行起来!!!

将程序运行起来!!!

将程序运行起来!!!

重要的事说三遍,程序运行起来有,我们就有了直观感受。

就我的经验而言,一个项目代码,是否能顺利的搭建调试环境,效率大不一样。

跑起来之后,要尽量的精简自己的环境,减少调试过程中的干扰信息。

比如,Nginx使用多进程的方式处理请求,为了调试跟踪Nginx的行为,我经常把worker数量设置为1个,这样调试的时候就知道待跟踪的是哪个进程了。

比如有些环境是分布式的,那么我们部署个单机版本的用来学习和做实验,也算是化繁为简。

2、2 成功运行意义何在

首先,便于从视觉感官上体会项目的功能,对开源项目的功能从宏观上能了解一些。

其次,下断点-> 调试-> 修改代码 -> 观察现象 ->再调试,查看是否符合修改的预期,一点点理解程序的逻辑

最后,方便截图,截牛逼的图去吹牛逼,哈哈,2333~

玩起来,嗨起来,搭建成功后必须装逼起来,哈哈

三、运行并研究Example例子

example目录:例子目录,先通过例子上手学会如何使用此开源项目

安装部署好项目,成功运行并直观体验到项目功能后,从总体转到局部,来好好看下example例子中的代码。

3、1 最简单的入门例子

简单的入门例子,代码行数一般在50行左右,摒弃了复杂的处理细节和框架的高级特性,便于读者尽快熟悉项目的主干和核心模块。

简单例子也可能遇到问题,此时可通过邮件列表、社区、Issue来解决遇到的问题。

熟悉简单例子的过程中,对于有疑问的地方先记录下问题,后面带着问题去阅读源代码解决心中疑问

3、2 逐步研究更复杂的例子

熟悉简单例子后,也可阅读些更复杂的例子,熟悉例子代码的过程,就是熟悉开源项目api接口的过程。

中间会对照代码来查看api文档,了解接口的参数、返回值以及注意事项。

进阶:手动修改代码来验证自己心里的想法,看看例子是否能正常运行?如果运行失败报错,则查找其原因,排查问题。

3、3 手写个人demo

如果公司使用的开源项目实在没有example例子,可考虑自己根据公司需求编写一个demo例子,编写demo的过程,是检验自己是否对api接口熟悉的过程。

四、针对部分组件,阅读其测试用例

如果测试用例写的很仔细,那么很值得好好去研究一下。

原因在于:测试用例往往是针对某个单一的场景,独自构造出一些数据来对程序的流程进行验证。

test目录:测试目录,学习下单元测试是如何写的

通过看单元测试用例,可了解到某个类或某个组件是如何使用的。

先学会如何使用,然后再去从源代码角度理解实现原理,使用过程中遇到了问题或者疑惑,带着问题去阅读源代码,这个效率杠杠滴。

五、阅读源代码之前必读

5、1 看代码之前认真看文档

一个好的开源项目是有完善的文档的,比如百度开源的RPC框架brpc

docs目录:

库的开发入门指南,代码的风格文档,程序的命令操作手册,程序中采用的第三方库

类图,流程图,活动图,架构图,设计文档

业务相关基础知识介绍文档

项目技术细节详细介绍

阅读这些文档可以了解该项目的大体设计和结构,读源码的时候不会无从下手。

务必要耐心好好的看,多看多实践多思考,少BB

六、阅读源代码

6、1 明确阅读代码的目的

在开始阅读代码之前,首先要明确自己的阅读目的:

是需要了解其中一个模块的实现?比如基础模块还是业务模块?基础模块中有内存池、线程池、网络数据收发epoll模型等

还是需要了解这个框架的大体结构,

还是需要具体熟悉其中的一个算法的实现,等等。

心里很清楚自己想要什么,才能更有动力去朝着目标努力奋斗。

6、2 区分主线和支线剧情

阅读源代码时,分清主线和支线

先看主线:

想了解一个业务逻辑的实现流程,中间调用了第三方库函数、utils函数、定制的数据结构和算法等,其实不需要了解其内部实现;

只需要了解其对外接口,了解这些接口的入口、出口参数以及作用,把这部分当成一个“黑盒”即可。

再看支线:

在对主线有充分了解前提下,可以考虑打开“黑盒”研究下其内部实现,比如看看内存池的实现代码,调度器的代码,dpdk中对于海量数据包是如何处理的等。

具体做法:

从main函数进入,使用gdb单步跟踪理清一次完整流程(如程序初始化)的代码调用路径,这可以通过debug来观察运行时的变量和行为。

6、3 挑选感兴趣的“分支”来阅读

这里的分支指的是功能或版本:

从功能上说:

比如你对网络通讯感兴趣,就阅读网络层的代码,深入到实现细节:

如它用了什么库,

采用了什么设计模式,

为什么这样做等。

如果可以,debug细节代码。

从源代码版本上说:

不一定选择最新版本的开源代码进行阅读,如果感觉有点吃力,可选用同一个开源项目的老版本(如1.0版本),

此时的项目代码,不管是代码量还是复杂度上都要小很多,看起来要容易的多。

6、4 理清核心数据结构

程序设计 = 数据结构 + 算法

因为结构定义了一个程序的架构,结构定下来了才有具体的实现。好比盖房子,数据结构就是房子的框架结构,如果一间房子很大,而你并不清楚这个房子的结构,会在这里面迷路。

而对于算法,如果属于暂时不需要深究的细节部分,可以参考前面“区分主线和支线剧情”部分,先了解其入口、出口参数以及作用即可。

Linus说: “烂程序员关心的是代码。好程序员关心的是数据结构和它们之间的关系。”

因此,在阅读一份代码时,厘清核心的数据结构之间的关系尤其重要。

6、5 添加日志 and 单步调试(情景分析)

看文档或看代码的过程中,对一些技术点,是需要验证的。

所谓的“情景分析”,就是自己构造一些情景,然后通过加断点、调试语句等分析在这些场景下的行为。

我惯用的做法,是在某个重要的入口函数上面加上断点,然后构造触发场景的调试代码,当代码在断点处停下,通过查看堆栈、变量值等等来观察代码的行为。

情景分析的好处在于:不会在一个项目中大海捞针似的查找,而是能够把问题缩小到一个范围内展开来理解。

从而把个人的时间和精力聚焦到一个小的范围内不断的研究,一直研究到自己满意为止。

修改源码加入日志和打印可以帮助你更好的理解源码。

gdb单步调试,一步步跟踪,是了解源代码最好的途径,没有之一。

6、6 画图梳理逻辑

适当画图来帮助你理解源码,在理清主干后,可以将整个流程画成一张流程图或者标准的UML图,帮助记忆和下一步的阅读。

画图虽然很浪费时间,但是对帮助理解架构和流程很有帮助。

6、7 解决遇到的问题

相信经过前面三个阶段,你已经是各种玩,各种瞎折腾,心里还是有很多疑问吧?

这个功能真牛逼,是如何实现的呢?

我的配置文件为什么没有生效呢?

程序为什么被我搞挂了呢?

我添加的打印为什么没有被执行?

打印的值为什么不符合我的预期?

好!很好!带着这些你心里的问题,去源代码中找答案吧

1.先总体后局部,把握好主体逻辑代码,然后再逐层深入下去

一上来就陷入太多的实现细节是大忌!!!

熟悉主体逻辑后,你大概能知道你感兴趣的代码处于整个项目中的什么模块,什么文件,什么类中

是个什么样的处理流程,定位到具体代码,一行行的分析它,这个过程会持续一段时间。

2.带着问题去看代码

一个系统实现了什么功能,为什么要实现这些功能,是基于什么业务场景?

3.思考自己如何实现类似系统(功能)

如果要我来实现一套类似的系统,我会如何来考虑问题,如何来实现这套系统?

然后再看看别人是如何实现的,找到两者之间的差距,并不断缩小之间的差距。

七、写笔记记录想法,促进思考和总结

1.记录解开问题谜团的过程

2.记录下开源代码中好的设计思想,好的代码技巧,以及任何你觉得好的东西

3.画整个程序的流程图,有利于理解程序的整个流程,而不被代码的细节所干扰。

4.坚持记录源代码学习笔记,记笔记能够有助于更深入的思考,以前很多问题只是浅层思考,不够深入

八、抄写项目源代码

以groupcache来举例,它包括lru,singleflight,protobuf,一致性hash这四个技术

步骤一:抄写前,可以大致了解下这些技术,比如lru是什么?lru解决什么问题?简单了解下lru的实现原理(后续深入具体实现)

步骤二:抄写过程中,会发现和之前了解的实现原理有不同的地方,比如有优化,或者有疑惑点,记录下来,继续抄写。

步骤三:抄写后,针对有疑惑的点,找资料,找人交流,必须搞清楚前面记录的不动的地方。

九、仿写项目

如果感觉自己对于项目理解的还不到位,我推荐一个笨方法,抄项目代码,抄着抄着你就懂了。

如果想进一步深刻的学习到源代码的精髓,可以仿写一个相近的程序进行操练。

理解了这个程序并不表明掌握了这个程序,只有在操练一个相近的程序时,才知道你到底理解了多少,掌握了多少

最近一直在仿写,或者说叫抄写开源项目,所以有点心得,整理一下:

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

自己写的东西,必须要合理的制作文档

仿写开源项目,按照如下思路来:

首先,熟悉开源项目,并熟练使用

其次,阅读开源项目源代码,梳理其流程和核心数据结构

再次,取主干,抛细节

以开源项目用一棵大树比喻,核心思想是剥离出开源项目的主干,去除掉繁杂的枝叶,以求能否更好的理解其设计理念和编码技巧。

最后,开始仿写开源项目代码。

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

十、教给他人(输出知识)

检验是否掌握一门技术,就是将知识输出,看他人能否听懂

当自己对项目的方方面面都很熟悉后,可以在B站上开直播,将自己所学的知识传授给他人。

输出形式:

1、csdn博客、知乎、头条、微信公众号等平台发文章

2、组内技术讨论或者微信群讨论

3、公司内技术分享会(正式)

3、在B站上直播
 

//以下是2021年更新的

更新日志:

2020-12-25 添加ch兄的学习方法论截图

2021-01-27 添加杨波老师的开源项目学习经验

阅读开源代码,一上来就陷入技术细节是大忌!!!

上图是ch总结的学习方法论,

核心概念:

总体架构

核心概念和术语

逻辑关系如何

从使用者的角度来看:

1、提供什么功能?

2、解决什么问题?

3、使用场景和限制是什么

4、如何来使用

横向对比:

功能上相似之处和差异

技术实现原理上相似之处和差异

从设计者角度:

1、为什么这么设计?

2、背后的思想和理论

3、如果我来设计,会从哪些方面来考虑?

参考链接:

优秀架构师是如何学习开源项目的?_架构师波波的博客-CSDN博客

如何阅读一份源代码?(2020年版) - codedump的网络日志

  • 14
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值