如何阅读一个开源项目的源码
前言
这篇文章,给大家简单介绍一下很多同学都非常关心的一个问题:如何阅读一个开源项目的源码。
我相信很多同学都希望能够去阅读一些源码来提升自己的技术水平,毕竟在面试的时候,很多大厂都经常会扣到非常深入的底层源码。
1
从最简单的源码开始:别幻想一步登天
其实开源项目有很多种,比如说有Spring这种框架类的,还有比如数据库连接池、log4j等这种工具类的。
当然还有特别重型的中间件类的,比如说RocketMQ、Kafka、Redis。更有甚者也有上百万行代码的大数据类的,比如Hadoop、Spark。
所以如果很多同学想要读源码的话,面临的第一个问题:不知道从何下手。
那么是不是说只要随便挑选一个开源技术的源码,采用愚公移山的精神,直接硬着头皮去读,坚持就是胜利,铁杵一定就能磨成针吗?
不是的!其实很多同学始终都没掌握到阅读源码的顺序、技巧和方法,所以导致尝试看过一些源码,却还是看不懂。
首先你要明白一个前提,比如说Kafka的作者,Hadoop的作者,他们本身都是有很多年经验,技术功底极为扎实,都是技术大牛的人,站在一个很高的角度去设计和开发出来了这些极为出色的分布式系统。
那么如果你的技术实力达不到他们的水平,你觉得你直接去读他们写出来的源码,就能看懂吗?
那估计是很难的,因为里面蕴含的各种底层技术细节,分布式架构设计思想,还有复杂的算法和机制,都不是你能理解的。
所以建议大家第一点,想看源码,先挑一个最最简单的,适合自己技术水平的去看。
给大家举个例子,比如说你平时常用的一些源码都有什么?显而易见,每个人都会用Spring Web MVC、Spring、MyBatis、Spring Boot,等等。
其实这些开源框架的源码也不能说就简单了,他们同样蕴含了开源作者深厚的技术功底在里面。
但是你要考虑一点,这些开源项目已经相对来说是普通人可以优先触碰的了。因为他们不是分布式系统,不涉及到复杂的架构,网络通信,IO,等技术细节。
他们大多就是依赖一些底层的Java基础技术,比如说动态代理、Servlet、HTTP协议、JDBC等等。
而他们依赖的那些基础,大多数普通工程师都是掌握的,你完全可以优先尝试去阅读一些这种开源框架类的源码。
2
循序渐进:先搞定底层依赖的技术
好,现在假如说你经过了几个月的努力,把一些开源框架的源码,比如上面说的SSM三大框架的源码都看过了,现在你的技术实力有了进一步的提升。
这些提升,主要体现在对开源项目的设计思想,组件设计,组件交互,还有框架封装,等等,都有了进一步的理解。
接下来,你就可以尝试去读一些更难一点的源码。
给大家举个例子,假设你这个时候去阅读Kafka的源码。没问题。但是这里有一些是你需要注意的地方,Kafka的底层是重度依赖ZooKeeper的。
如果你不把ZooKeeper给掌握精通的话,会导致Kafka你也难以理解。
所以这个时候你得先把底层依赖的技术给搞定,那么你就得回过头去先阅读ZooKeeper的源码,把ZK这个技术先给搞精通一些。
同理,如果你在研究ZK的时候,发现他底层有一些技术是你掌握不好的,比如你发现他大量运用了Java并发包下的东西。
因此如果你对Java并发包掌握的不够好,那么建议你去把Java并发包下的源码先仔细研究一下。
通过这种方式,你可以自行追踪到自己还不熟悉的很多底层技术,然后一个一个击破,把这些底层依赖的技术的源码你可以先研究透彻一些。
然后,你再一步一步往上层的技术去研究,这样看那些复杂技术的源码就会轻松很多了。
3
一定要以Hello World作为入口来阅读
阅读源码有一个非常非常有用的技巧,那就是你别下载了源码到本地IDE里然后直接胡乱的翻看,那是不行的。
一般建议就是基于一个开源技术写一个最最基本的HelloWorld程序,就是一个入门级的程序,然后把他的核心功能给跑通。
举个例子,假如说你要阅读ZooKeeper的源码,那么你先写一个ZK的HelloWorld程序。
比如说先连接,然后创建一个znode,对znode注册一个监听。接着触发这个监听,接着再关闭连接,就这样的一个简单的程序。
然后就可以打断点,跟踪这个Hello World级别的源码一步一步调试追踪,他是如何发起和建立连接的,底层的代码流程是什么样的。
4
抓大放小,边写注释边画图
在看源码的过程中,很多人会被核心流程中混杂的一些特殊业务逻辑的处理给搞懵。
给大家举个例子,看下面的代码,是一段随手写出来演示的:
checkUser();
fetchFromPeers();
countMetrics();
大家可以看到,上面就三行代码,从方法名称就可以看出来,先是做了一个权限检查之类的操作,然后是核心业务逻辑去抓取数据,最后是做了一些metric指标统计。
那么很多同学看源码的时候,就喜欢把每一行代码都看懂,最后不停的点到很深层的地方去,把自己给绕晕了。最后淹死在源码的海洋里。。。
其实这个是不对的,这就是没有掌握源码阅读的一大典型原则:
抓大放小。
比如上面的三行代码,你应该直接跳过第一行和第三行,连看都别去看,直接进入第二行核心逻辑。
也就是说,你只需要抓最核心的代码流程就可以了,那些无关紧要的代码,千万别有强迫症点进去反复看,那样绝对会让你对源码从入门到放弃。
所以,再次强调!强调!强调!重要的事情说三遍。阅读源码,你一定要有粗大的神经,反复告诉自己,刚开始先把握代码的主流程即可。
很多细节看不懂直接跳过去,别有强迫症让自己看明白每个细节。
此外,大家一定要形成一个习惯,在看源码的过程中尽量多自己对源码写一些注释。
你应该结合自己的理解,尽可能把自己对源码阅读过程中的思考都写成注释写在源码里。
这个习惯可以促使你一边阅读一边思考,而且有自己注释的源码,是你宝贵的财富。
此外,还有一个非常重要的点,那就是一定要多画图。
你可以尝试在阅读的过程中,提取源码运行的核心流程,一边读源码,一边自己画在图上,可以用那种画图软件来作图即可。
大家记住,人脑对图片的敏感度,是远高于对文字或者代码的,这个是大脑机制决定的。
笔者公众号写的很多篇文章,里面对各种技术的讲解,无一不是通过大量的画图。相比于冗长的文字描述,图片会让人容易理解接受的多。
通过画图,能帮助你抽象和总结出源码的核心流程,以后如果你要回顾和复习,直接看图即可。
5
反复三遍:真正理解源码
另外一个要注意的点,源码这个东西,是多看几遍理解的就会越深刻。
因为你看第一遍,按照上面说的抓大放小的思路,可能很多东西就直接略过去了,因为刚开始你看不懂一些非核心代码在干什么。
但是第一遍看完以后,通过写注释,自己动手画图,对一个开源项目的核心流程、架构以及原理都有了一定的理解了。
此时再去读第二遍源码,再过一遍,你会发现之前很多看不懂的细节都能看懂了。然后再看第三遍源码,你会发现大多数的代码自己都能看懂了。
所以说任何一个源码,都是要至少反复看三遍的过程,不是看一遍就可以完成的。
6
借力打力:参考源码分析书籍及博客
其实现在有很多对热门开源项目进行源码分析的书籍以及博客,你大致可以认为就是一些技术比较牛的兄弟自己看了源码之后,写出来的一些分析和感悟。
但是那毕竟是别人的东西,如果你上来就直接看源码分析书籍或者博客,那么不一定可以看懂,因为文字的信息传递未必能很好的让你理解有些复杂的东西。
所以比较建议的方式,就是先自己尝试看几遍,有了一定的理解之后,此时可以借助源码分析书籍或者是博客,参考其他技术牛的同学对这个源码理解,结合自己之前的一些思考,综合起来进行分析,相信一定会大有裨益。
你会发现人家的一些理解可以很好的补充你没想明白的一些问题,或者是忽略的一些细节。
不过,需要提醒的一点,网上不少博客,包括一些书籍,他们写出的一些源码分析,可能是错误的。
所以,尽信书不如无书,你需要带着一定的纠错眼光。在和你的理解相悖时,不一定就是你错了。
7
最后寄语:用几年时间锻造自己的核心技术
其实上面那个过程说起来很简单,做起来非常的困难。
因为在上面任何一个步骤,阅读的过程中你都有大量的东西是不会的,而且会觉得很难,甚至经常有想放弃的冲动。
毕竟人的大脑天生就是会对困难的事情产生抗拒感,这是本能,天生就是对舒服、放松的事情有向往。
但是只有那些能克服人的动物本能,惰性本能,迎难而上,坚韧不拔的同学,才能真正攻克各种技术难题。
让自己的大脑不停的开动,不停的思考上面那个过程,也许你要持续一年才能有个小的开悟,持续三年才能有一定的心得,持续五年甚至八年,才能说真的融汇贯通,打通任督二脉,成为技术大牛。
但是坚持这个事情同样是很可怕的,一旦你坚持做到了,那么你将锻造出来自己最硬核的技术实力,远远不是普通人,或者刚毕业的年轻同学可以追上你的。技术深度、技术功底,这是每一个工程师最最硬核的技术实力。
希望各位同学可以从现在开始,尝试着用笔者分享的技巧阅读源码。跳出舒适区,去拥抱更大的舒适区。
真正体验一下读透源码之后,根据报错日志,从源码层面精确定位项目问题、精确制导线上bug,感受一下这种上帝视角解决问题的快感吧!