一篇文章把本该属于你的源码天赋还给你

怎么阅读源码

 

"没有经验的技术差底子薄的初级程序员,如何阅读项目源码? "程序员

 

"有人阅读过 mybatis 的源码吗 ?就看一个初始化过程就看的已经头晕眼花了,小伙伴们支支招吧!"算法

 

"源码应该怎么阅读,我曾经尝试阅读一些源码,例如alibaba的druid中sqlparser部分,spring-mvc,可是发现很吃力,都说debug是最好的阅读方式,我在debug时常常有跟丢的现象……就是走着走着感受好像进入了一些我当前不太关注细枝末节。 "spring

。。。。。。sql

 

估计不少人都有这样的疑惑。编程

 

我很是能理解小伙伴们的痛苦,由于我也是这么痛苦着走过来的。设计模式

 

阅读优秀源码的好处想必你们都知道,学习别人优秀的设计,合理的抽象,简洁的代码...... 总之是好处多多。spring-mvc

 

可是真的把庞大的代码放到你的面前,就如同一个巨大的迷宫,要在其中东转西转寻出一条路来,把迷宫的整个结构搞清楚,理解核心思想,真心不容易。性能优化

 

在阅读由面向对象的语言如Java写的代码时,会发现接口和具体的实现常常对应不起来,不太清楚一个功能究竟是怎么在哪一个实现类中才能找到。  不像C语言,就是函数调用函数,相对还好点。服务器

 

若是是动态语言如Ruby,Python, 一个变量的类型甚至都不容易知道,阅读的难度大大增长。数据结构

 

还有一个重要的缘由,如今咱们看到的源码基本上都通过若干年发展、通过不少人不断地完善的,枝枝蔓蔓很是多,魔鬼都在细节中。  阅读的时候很容易陷进去, 看了几十层函数调用之后,就完全懵了,就放弃了: 甭管你把源码吹得天花乱坠, 老子不再看了。

 

通过不少痛苦的挣扎之后,我也算有一些成功的经历,今天用治学的三个境界来类比, 给你们分享一下:

 

昨夜西风凋碧树,独上高楼,望尽天涯路

 

想把源码搞懂,吃透,首先得登高望远,瞰察路径,明确目标与方向,了解源码的概貌。

 

因此有些准备工做必须得作。

 

1. 阅读源码以前,须要有必定的技术储备。

好比设计模式,在不少Java源码中几乎就是标配,尤为是这几个:模板方法,单例,观察者,工厂方法,代理,策略,装饰者。

 

再好比阅读Spring源码,确定得先了解IoC是怎么回事,AOP的实现方式,CGLib,Java动态代理等,本身动手,写点相关的代码,把这些知识点掌握了。

 

2. 必须得会使用这个框架/类库, 最好是精通各类各样的用法。

 

上面刚提过,魔鬼都在细节中,若是有些用法根本不知道,可能你能看明白代码是什么意思,可是不知道它为何这些写。

 

3. 先去找书,找资料,了解这个软件的总体设计。

 

都有哪些模块? 模块之间是怎么关联的?怎么关联的?

可能一会儿理解不了,可是要创建一个总体的概念,就像一个地图,防止你迷航。

 

在读源码的时候能够时不时看看本身在什么地方。

 

4. 搭建系统,把源代码跑起来!

 

相信我,Debug是很是很是重要的手段, 你想经过只看而不运行就把系统搞清楚,那是根本不可能的!

 

衣带渐宽终不悔,为伊消得人憔悴。

 

5. 根据你对系统的理解,设计几个主要的测试案例,定义好输入,输出。

 

运行系统,慢慢地debug ,一步步地走,这是个死功夫,没有办法绕过。

 

Debug一遍确定是不行的,须要Debug不少遍。

 

第一遍尽量抛弃细节,抓住主要流程, 好比有些看起来不重要的方法就不进去看了。

 

第二遍、第三遍....再去看那些细节。

 

一个很是重要的工做就是记笔记(又是写做!),画出系统的类图(不要依靠IDE给你生成的), 记录下主要的函数调用, 方便后续查看。

 

文档工做极为重要,由于代码太复杂,人的大脑容量也有限,记不住全部的细节。 文档能够帮助你记住关键点, 到时候能够回想起来,迅速地接着往下看。

 

要否则,你今天看的,可能到明天就忘个差很少了。

 

给你们看看我作的一些笔记, 格式不重要,很随意,方便本身看懂就行。

6. 主要的测试案例搞明白了,丰富测试案例,考虑一些分支流程。

继续Debug......

 

总之,静态地看代码 + 动态地debug (从业务的角度), 就会慢慢揭开这个黑暗森林的面纱。

 

这一步会很是很是地花费时间,可是你作完了,对系统的理解绝对有质的飞跃。

 

众里寻他千百度,蓦然回首,那人却在灯火阑珊处。

 

没有千百度的上下求索,不会有瞬间的顿悟和理解,衷心祝愿阅读源码的朋友们都能达到这一境界。

 

最后一点,也是最关键的一点: 要能坚持下去。

 

我不是一个聪明人, 可是笨人自有笨办法:什么事都架不住不断的重复,一遍看不明白,再来第二遍, 两遍搞不明白,再来第三遍......

 

可能有人要问: 你怎么能这么坚持地刨根问底呢?

 

答案就是好奇心: 这玩意儿究竟是怎么实现的?!

 

阅读源码的意义与方法

 

思索了这两个问题良久,也去知乎找了一些相关话题的问答,但并无标准答案。因此,我这里也只是记录一些我对此的见解,也许会随着 RTFSC 阅历的丰富而发生变化,我会记录更新于 个人博客里面。

意义

在我看来,阅读源码的意义在于学习优秀的「套路」。

这里的「套路」所指范围很广,大到架构设计,小到可取的命名风格,还有设计模式、实现某类功能使用到的数据结构和算法等等。所谓高手,其实就是能比大部分人更早更快地掌握套路并熟练运用之人。

埋头在本身的天地里耕芸当然也能逐渐进步和成长,但总会有时候会遇到一些场景,你苦思良久也没法作出良好的设计,总会有一些时候,纠结如何为一个变量命名让你停下飞速敲击的手指。这些令你为难的场景,先贤们也许早就遇到过,而且给出了优雅的解决方案。看优秀的源码的时候,将这样的场景与对应的方案收入囊中,或者仅仅在脑中留下一个印象也好,以便在须要的时候,你的武器库里总能掏出一把称手的家伙来。

 

源码阅读三要素

 

源码分析是一种临界知识,掌握了这种临界知识,能不变应万变,源码分析对于不少人来讲很枯燥,生涩难懂。

源码阅读,我以为最核心有三点:技术基础+强烈的求知欲+耐心。

我认为是阅读源码的最核心驱动力。我见到绝大多数程序员,对学习的态度,基本上就是这几个层次(很偏激哦):

  1. 只关注项目自己,不懂就baidu一下。

  2. 除了作好项目,还会阅读和项目有关的技术书籍,看wikipedia。

  3. 除了阅读和项目相关的书外,还会阅读IT行业的书,好比学Java时,还会去了解函数语言,如LISP。

  4. 找一些开源项目看看,大量试用第三方框架,还会写写demo。

  5. 阅读基础框架、J2EE规范、Debug服务器内核。

大多数程序都是第1种,到第5种不光须要浓厚的兴趣,还须要勇气:我能读懂吗?其实,你可以读懂的。

耐心,真的很重要。由于你极少看到阅读源码的指导性文章或书籍,也没有人要求或建议你读。你读的过程当中常常会卡住,而一卡主可能就陷进了迷宫。这时,你须要作的,多是暂时中断一下,再从外围看看它:如API结构、框架的设计图。

源码知识点是程序员都绕不开的话题,说到这里,也给你们推荐一个交流平台:架构交流群650385180,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,如下的课程体系图也是在群里获取。相信对于已经工做和遇到技术瓶颈的码友,在这个群里必定有你须要的内容。

一些方法

不该该这样

不该该漫无目的地随手拿起一分源码,试图去通读。这一方面会过目即忘无所收获,另外一方面会枯燥得让你迅速从着手到放弃。学习的方式有不少种,阅读源码并不必定是最适合你当前的状况的。

应该这样

  • 精心挑选要阅读的源码项目。

这最好是与你的编程语言、你的工做内容、你的兴趣所在相关的,这样才能更切实地感觉到阅读源码给你带来的益处,更有动力继续。

  • 若是你想学习的知识点有官方文档,先看文档再看源码。

直接从源码着手,搞清楚原理当然是好,可是源码有多是难啃的,先熟悉官方提供给全部人看的文档,能较为平滑地对这方面的知识先有个大概的了解,而后再结合源码去深刻。

  • 提出具体的问题,而后带着问题到源码中找答案。

好比在使用 Toast 的过程当中,你可能会想到一些问题:Toast.makeText(...).show() 时发生了什么?Toast 能不能在非 UI 线程调用?能不能自定义 Toast 布局?诸如此类。在源码中探寻完你想要的答案,你的目的也就达到了。

  • 从一些共性层面入手。

大部分的程序里都会使用到的东西,好比线程模型、UI 组织结构、任务调度方式等等。针对某一个方面去了解,比漫无目的要有效率得多。

  • 最好可以编译运行起来。

若是一份代码你只能看不能跑,那可能读到一些地方你只能猜这个地方的数据值和跳转结构是怎么样的,而颇有可能你猜的是错的。但若是你能编译运行,那在须要的时候你能够修改,加日志等等来更好地观察和验证你的想法,获得正常的理解。

  • 作一些笔记。

一方面是将你的学习成果保留下来,方便随时查阅,毕竟只凭脑子记忆是不靠谱的;另外一方面在学习的过程当中,也能帮助理解。

相关文章
相关标签/搜索