性能文章>【原创】我的源码阅读经历>

【原创】我的源码阅读经历原创

4月前
2509329

这篇文章主要总结我从毕业到现在的源码阅读经历,希望能够助你探索一条适合自己的源码之路。

1 为什么要读源码

关于阅读源码的收益网上有很多分享,以下是我的观点:

「快速参与项目」。做为一线开发者,到一家新公司,进入新项目,免不了要去深入了解项目,而学会高效阅读和调试代码,能够迅速熟悉新项目,更短时间内参与到新项目的开发,从而省出更多的时间来给自己充电。作为搞技术的同学,一定要终身学习,而你每天的学习时间就是在一点一滴中积累起来的。

「打磨编程技艺」。通过阅读开源框架的源码,可以有效地提升编程技能,学到优秀的设计模式,形成自己的编程风格。对于一些经典框架的设计,比如 Spring,Mybatis,如果你没深入读过源码,很难去了解其设计的精髓,面试官随便深入几个问题立马露馅。

「解决疑难杂症」。掌握高效阅读和调试源码的思路和技巧,你可以更快地定位和解决疑难杂症,跨语言去阅读其他领域的开源框架,达到技能和语言无关的境界,感谢 JetBrains 给我们提供的 IntelliJ 系列的工具,大幅减少跨语言的迁移成本。

阅读一款优秀的开源框架源码,就像阅读一部引人入胜的侦探小说,在这个过程中,你会逐渐解开一个个谜题,环环相扣,最终水落石出。这篇文章,我会分享我从毕业到现在的阅读源码经历,下篇文章,我会分享一些阅读源码的关键思路和调试技巧。

2 我的源码阅读经历

回顾 2014 年毕业到现在,我的源码阅读经历大致可分为三个时期:探索期,成长期,成熟期。

2.1 探索期:2014年 ~ 2016年

探索期大概是 2014年 ~ 2016年,两年左右的时间,这段时期结束的标志是快捷键的精通和 Tomcat 底层原理的掌握。

探索期前部分时间花在了 IDEA 快捷键的练习。刚毕业的半年时间里,每天都会花大量的时间去练快捷键,刚开始真的是死记硬背。

当时的具体做法是:

  1. 把每个快捷键都写在便利贴上并注明 Deadline,每一行格式大概是 "抽取方法参数 ALT+CMD+P 12.31" ,每个便利贴写五行,便利贴贴在工位,抬头就能看到。
  2. 每天上班前把每个便利贴都操作几遍,一段时间之后,当便利贴上的五个快捷键都烂熟于心的时候,就撕下便利贴,贴在一本记事本上,前期每天新抄一张便利贴,也就是五个快捷键。
  3. 最多的时候,便利贴应该有七八张,也就是几十个快捷键,此后,每撕下一张便利贴,就抄一些新的,开始进入循环。
  4. 随着记事本上的便利贴越来越多,也需要隔几天来复习一遍,偶尔碰到几个平时不怎么用的,若回忆不起来,就重新抄一遍在新的便利贴上贴在工位。
  5. 在编码或调试过程中,如果某些快捷键之前已经记忆过,就强制自己必须要用快捷键完成,如果回忆有卡顿,哪怕只有一秒,也要重新抄在新便利贴上,进入下一轮循环。

经过这段时间的刻意练习,结果是我现在能够记住接近 200 多个快捷键组合,且是肌肉记忆。

打下良好的基础之后,我开始尝试阅读 Tomcat 的源码,说实话,第一次干起来非常费劲,经常陷入到细节中不能自拔,没有捷径,这段时间必须得你自己度过。这段过程也有惊喜,就是第一次知道如何通过 Socket 实现一个 Http 服务器,那种感觉非常畅快,一下子激发了我探索源码世界的好奇心。

总的来说,这段时间只能是对着一本 Tomcat 源码的书来阅读源码,看到哪算哪,还没有形成自己阅读源码的思路,但是经过这段经历,我了解到,其实了解开源框架源码没这么难,只要肯花功夫,哪怕沿着别人的思路去探索,也能了解底层原理。

这段时间做的比较有意义的输出是,我把快捷键的经验录成了视频,帮助了 10w+ 的开发者:

如果你也处在第一个阶段,我的一个建议是,花点时间好好背背快捷键吧。

2.2 成长期:16年 ~ 19年

成长期大概是 16年 ~ 19年,三年左右的时间,这段时间结束的标志是 Netty 源码分析视频课程的上线。

大概毕业一两年之后吧,我开始阅读 Spring 的源码,第一次读就被 Spring 优美的设计和代码风格给吸引到,直到现在,我还是认为 Spring 是开源世界中最美的代码。

当时读 Spring 源码也是参考了一本源码指导的书(所以大家没事一定要多读读书呀)。和探索期不一样的是,在这个时期,调试技能有一定的提升,尤其是一些场景下的组合调试技能,逐渐开始形成自己的方**。接下来开始做源码分析的分享,记得有一次分享 Spring 的核心流程,连续讲了两三个小时都不带停顿的。

由于对 Spring 源码的熟悉,当时组内同学还给起了个奇怪的外号,叫做 "Spring fairy",翻译成中文是 "春仙",这个组内昵称保留到了现在,"闪电侠" 也干不过。

成长期的中间那段时间,接到一个长连相关的项目(感谢勇哥的信任),核心技术用到了 Netty,当时了解到这个框架是几乎所有中间件最底层的技术,于是在完成项目目标的同时,开始研究 Netty 底层的实现。

和 Tomcat、Spring 不一样的是,那个时候 Netty 相关的原理分析相关的文章几乎为零,只能自己尝试去啃。

有了前面几年的基础,自己阅读源码的关键思路和调试技巧逐渐稳定,尝试在不参考任何原理分析资料的情况下自己去探索,确实花了非常多的时间,在这个过程中有煎熬,有兴奋,有停滞不前,也有豁然开朗,但是,终究这只硬骨头还是被我啃下了。

啃的过程对于别人来说可能相对枯燥,但是对我来说其乐无穷:几乎每天下班,每个周末都会打开源码,一调试就是几个小时,不断地 "CMD F2,Shift F9,F7...",调试技能因此得到了打磨,积累了很多调试技巧。

同时,那段时间,周末花了大量的时间去写 Netty 底层原理的相关的文章,通过文章结识了不少同行,部分甚至成为现在的同事。

成长期写的那些文章

后来慕课的编辑通过我的文章找到我,想合作出一门课,再三考虑之下,我决定出一门 Netty 源码分析相关的视频课程来拓荒,更好地帮助在这条路上探索的同行。视频课程要比写文章要难,因为出错的成本比较高,无法反复修改。

当时没有办法,只能硬着头皮,再次深入到 Netty 的底层世界中,不断地啃,反复地啃,每次录制一个新的章节之前,都会再花大量的时间去啃细节,抓脉络,直到这个章节涉及到所有的部分烂熟于心才开始录制。

最终,《Java 读源码之 Netty 深入剖析》这门视频课程在 18 年中在慕课上线,前后大概花了大半年的时间,每个周末要么在录视频,要么在录视频的路上。

Netty慕课

总结这段时期的转变:通过阅读 Spring 和 Netty 源码,及文章博客、视频课的分享,基本形成了阅读源码的关键思路和调试的方**,后续在解决 Spring 和 Netty 相关的问题,即使之前没有研究过相关模块,也能够很快定位并解决问题,接下来就进入了成熟期。

2.3 成熟期:19年 ~ 今

从 2019 年到现在,处在成熟期,这段时间开始大量阅读其他开源框架源码,排查各类疑难杂症,并逐渐开始探索计算机底层原理的实现。

这段时间周末没事就在家研究一些开源框架的实现,比如 Dubbo、Mybatis 及工作中涉及到的一些核心框架。我的研究方式是,每次研究之前,都给自己抛出一个问题,比如:Dubbo 的服务发现是怎么做的,然后花一个下午或一个晚上的时间通过源码找到完整的答案。

经过成长期的磨练,到这个时期,快捷键已形成了肌肉记忆。可能我无法快速说出某操作的快捷键,但是能用手指本能地按出来。快捷键的肌肉记忆给我阅读和调试源码带来了巨大的帮助,当手速跟上了思维的速度之后,思维的连续性得到保障,每一次阅读源码都能够进入心流状态。

在探索 Dubbo,Mybatis 等其他开源框架的源码过程中,凭借过去的经验和调试技能,给我带来一个非常直观的心理感受就是:每次分析源码的过程就像是一次推理破案的过程,又犹如阅读一篇悬疑小说,在纷繁复杂的世界中抓住核心环节,厘清思路,最终水落石出。源码面前无秘密,一切都是公开的。

研究了一些开源框架之后,我发现很多框架最底层的原理其实大同小异(比如 redis、nginx、netty 的应用层的内存分配机制和线程模型的设计几乎是一致的),框架每过几年就会翻新一遍,没这么多时间去把所有的框架都去研究一遍。

这个时候需要问自己一个问题:每当遇到一个新的技术,如何很快掌握?

2021 年春节前开始思考这个问题,春节那段时间,得出结论:后续的技术生涯中,我需要去探索在未来几年甚至十几年那些不变的东西。

于是我将研究方向转向了计算机底层原理。其中一部分就是 Linux 内核,内核中有非常多的宝藏值得深挖,很多应用层的一些设计与内核设计同构,且有很多技术直接依赖于内核的实现,如 Docker。

虽然内核是 C 语言和汇编写的,而我是搞 Java 的,但是源码分析的思路和调试的技能是相通的,经过了一段时间的尝试,21年年底开始写 Linux 内核分析相关的文章(【原创】Linux 内核源码分析之进程概要及调度时机【原创】Linux 内核源码分析之进程调度的逻辑),算是开始入门了吧。

内核远比我想象的要复杂得多,但是越复杂,探索的过程就越**。

今天是 2022 年元旦,给自己订个内核小目标:2025 年元旦前入门,2027 年元旦前熟悉,2032 年元旦前精通,10 年后来看,希望不要被打脸呀!

3 结语

本来这篇文章想重点写写阅读源码的关键思路和调试技能的,没想到写到最后成了源码回忆录,索性把干货部分放到下一篇文章中吧,欢迎大家关注公众号。

最后顺便说一句,元旦之后,我的新书 《跟闪电侠学 Netty》要出版了。书的前半部分是掘金小册中的内容:通过一个完整的 IM 项目入门 Netty;后半部分用了较大的篇幅来介绍 Netty 的底层原理,也会穿插讲一些源码阅读的思路,希望能够帮助到你。

全文完,大家元旦快乐!

喜欢

 

 

 

netty [!]

 

IntelliJ IDEA 2018.1

netty

NettyNetty

Netty01: [+]

netty

nettyreactor线

nettyreactor线

nettyreactor线

jvm

NIOSelectionKey.OP_WRITE

dubboMeshqps10006850

 

请先登录,再评论

👍好文章

4月前

3年入门,10年精通,突然有点害怕😨

4月前

跟着大佬足迹学习!

4月前

为你推荐

关于内存溢出,咱再聊点有意思的?
概述 上篇文章讲了JVM在GC上的一个设计缺陷,揪出一个导致GC慢慢变长的JVM设计缺陷,可能有不少人还是没怎么看明白的,今天准备讲的大家应该都很容易看明白 本文其实很犹豫写不写,因为感觉没有
又发现一个导致JVM物理内存消耗大的Bug(已提交Patch)
概述 最近我们公司在帮一个客户查一个JVM的问题(JDK1.8.0_191-b12),发现一个系统老是被OS Kill掉,是内存泄露导致的。在查的过程中,阴差阳错地发现了JVM另外的一个Bug。这个B
LONG究竟有多长,从皇帝的新衣到海康SDK
转眼之间初中毕业30年了,但我仍清楚的记得初中英语的一篇课文,题目叫《皇帝的新装》(“The king’s new clothes”)。这篇课文的前两句话是:”Long long ago, there
谨防JDK8重复类定义造成的内存泄漏
概述 如今JDK8成了主流,大家都紧锣密鼓地进行着升级,享受着JDK8带来的各种便利,然而有时候升级并没有那么顺利?比如说今天要说的这个问题。我们都知道JDK8在内存模型上最大的改变是,放弃了Perm
JVM菜鸟进阶高手之路九(解惑)
关于MAT工具相关知识解惑MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如 Sun, HP, SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的
JVM垃圾回收与一次线上内存泄露问题分析和解决过程
本文转载自:花椒技术微信公众号 前言内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。Ja
小闪对话:阅读源码的关键思路
本次对话帮助大家快速理清阅读源码的关键思路,下篇会对话阅读源码的实战技巧,目录在文末。
【原创】我的源码阅读经历
谈谈我从毕业到现在的源码阅读经历,应该会对你有帮助