Netty 源碼 | 我的源碼閱讀經(jīng)歷
?這篇文章主要總結(jié)我從畢業(yè)到現(xiàn)在的源碼閱讀經(jīng)歷,希望能夠助你探索一條適合自己的源碼之路。
?
1 為什么要讀源碼
關(guān)于閱讀源碼的收益網(wǎng)上有很多分享,以下是我的觀點:
「快速參與項目」。做為一線開發(fā)者,到一家新公司,進入新項目,免不了要去深入了解項目,而學會高效閱讀和調(diào)試代碼,能夠迅速熟悉新項目,更短時間內(nèi)參與到新項目的開發(fā),從而省出更多的時間來給自己充電。作為搞技術(shù)的同學,一定要終身學習,而你每天的學習時間就是在一點一滴中積累起來的。
「打磨編程技藝」。通過閱讀開源框架的源碼,可以有效地提升編程技能,學到優(yōu)秀的設(shè)計模式,形成自己的編程風格。對于一些經(jīng)典框架的設(shè)計,比如 Spring,Mybatis,如果你沒深入讀過源碼,很難去了解其設(shè)計的精髓,面試官隨便深入幾個問題立馬露餡。
「解決疑難雜癥」。掌握高效閱讀和調(diào)試源碼的思路和技巧,你可以更快地定位和解決疑難雜癥,跨語言去閱讀其他領(lǐng)域的開源框架,達到技能和語言無關(guān)的境界,感謝 JetBrains 給我們提供的 IntelliJ 系列的工具,大幅減少跨語言的遷移成本。
閱讀一款優(yōu)秀的開源框架源碼,就像閱讀一部引人入勝的偵探小說,在這個過程中,你會逐漸解開一個個謎題,環(huán)環(huán)相扣,最終水落石出。這篇文章,我會分享我從畢業(yè)到現(xiàn)在的閱讀源碼經(jīng)歷,下篇文章,我會分享一些閱讀源碼的關(guān)鍵思路和調(diào)試技巧。
2 我的源碼閱讀經(jīng)歷
回顧 2014 年畢業(yè)到現(xiàn)在,我的源碼閱讀經(jīng)歷大致可分為三個時期:探索期,成長期,成熟期。
2.1 探索期:2014年 ~ 2016年
探索期大概是 2014年 ~ 2016年,兩年左右的時間,這段時期結(jié)束的標志是快捷鍵的精通和 Tomcat 底層原理的掌握。
探索期前部分時間花在了 IDEA 快捷鍵的練習。剛畢業(yè)的半年時間里,每天都會花大量的時間去練快捷鍵,剛開始真的是死記硬背。
當時的具體做法是:
- 把每個快捷鍵都寫在便利貼上并注明 Deadline,每一行格式大概是 "抽取方法參數(shù) ALT+CMD+P 12.31" ,每個便利貼寫五行,便利貼貼在工位,抬頭就能看到。
- 每天上班前把每個便利貼都操作幾遍,一段時間之后,當便利貼上的五個快捷鍵都爛熟于心的時候,就撕下便利貼,貼在一本記事本上,前期每天新抄一張便利貼,也就是五個快捷鍵。
- 最多的時候,便利貼應(yīng)該有七八張,也就是幾十個快捷鍵,此后,每撕下一張便利貼,就抄一些新的,開始進入循環(huán)。
- 隨著記事本上的便利貼越來越多,也需要隔幾天來復習一遍,偶爾碰到幾個平時不怎么用的,若回憶不起來,就重新抄一遍在新的便利貼上貼在工位。
- 在編碼或調(diào)試過程中,如果某些快捷鍵之前已經(jīng)記憶過,就強制自己必須要用快捷鍵完成,如果回憶有卡頓,哪怕只有一秒,也要重新抄在新便利貼上,進入下一輪循環(huán)。
經(jīng)過這段時間的刻意練習,結(jié)果是我現(xiàn)在能夠記住接近 200 多個快捷鍵組合,且是肌肉記憶。
打下良好的基礎(chǔ)之后,我開始嘗試閱讀 Tomcat 的源碼,說實話,第一次干起來非常費勁,經(jīng)常陷入到細節(jié)中不能自拔,沒有捷徑,這段時間必須得你自己度過。這段過程也有驚喜,就是第一次知道如何通過 Socket 實現(xiàn)一個 Http 服務(wù)器,那種感覺非常暢快,一下子激發(fā)了我探索源碼世界的好奇心。
總的來說,這段時間只能是對著一本 Tomcat 源碼的書來閱讀源碼,看到哪算哪,還沒有形成自己閱讀源碼的思路,但是經(jīng)過這段經(jīng)歷,我了解到,其實了解開源框架源碼沒這么難,只要肯花功夫,哪怕沿著別人的思路去探索,也能了解底層原理。
這段時間做的比較有意義的輸出是,我把快捷鍵的經(jīng)驗錄成了視頻,幫助了 10w+ 的開發(fā)者:

如果你也處在第一個階段,我的一個建議是,花點時間好好背背快捷鍵吧。
2.2 成長期:16年 ~ 19年
成長期大概是 16年 ~ 19年,三年左右的時間,這段時間結(jié)束的標志是 Netty 源碼分析視頻課程的上線。
大概畢業(yè)一兩年之后吧,我開始閱讀 Spring 的源碼,第一次讀就被 Spring 優(yōu)美的設(shè)計和代碼風格給吸引到,直到現(xiàn)在,我還是認為 Spring 是開源世界中最美的代碼。
當時讀 Spring 源碼也是參考了一本源碼指導的書(所以大家沒事一定要多讀讀書呀)。和探索期不一樣的是,在這個時期,調(diào)試技能有一定的提升,尤其是一些場景下的組合調(diào)試技能,逐漸開始形成自己的方法論。接下來開始做源碼分析的分享,記得有一次分享 Spring 的核心流程,連續(xù)講了兩三個小時都不帶停頓的。
由于對 Spring 源碼的熟悉,當時組內(nèi)同學還給起了個奇怪的外號,叫做 "Spring fairy",翻譯成中文是 "春仙",這個組內(nèi)昵稱保留到了現(xiàn)在,"閃電俠" 也干不過。
成長期的中間那段時間,接到一個長連相關(guān)的項目(感謝勇哥的信任),核心技術(shù)用到了 Netty,當時了解到這個框架是幾乎所有中間件最底層的技術(shù),于是在完成項目目標的同時,開始研究 Netty 底層的實現(xiàn)。
和 Tomcat、Spring 不一樣的是,那個時候 Netty 相關(guān)的原理分析相關(guān)的文章幾乎為零,只能自己嘗試去啃。
有了前面幾年的基礎(chǔ),自己閱讀源碼的關(guān)鍵思路和調(diào)試技巧逐漸穩(wěn)定,嘗試在不參考任何原理分析資料的情況下自己去探索,確實花了非常多的時間,在這個過程中有煎熬,有興奮,有停滯不前,也有豁然開朗,但是,終究這只硬骨頭還是被我啃下了。
啃的過程對于別人來說可能相對枯燥,但是對我來說其樂無窮:幾乎每天下班,每個周末都會打開源碼,一調(diào)試就是幾個小時,不斷地 "CMD F2,Shift F9,F(xiàn)7...",調(diào)試技能因此得到了打磨,積累了很多調(diào)試技巧。
同時,那段時間,周末花了大量的時間去寫 Netty 底層原理的相關(guān)的文章,通過文章結(jié)識了不少同行,部分甚至成為現(xiàn)在的同事。
成長期寫的那些文章后來慕課的編輯通過我的文章找到我,想合作出一門課,再三考慮之下,我決定出一門 Netty 源碼分析相關(guān)的視頻課程來拓荒,更好地幫助在這條路上探索的同行。視頻課程要比寫文章要難,因為出錯的成本比較高,無法反復修改。
當時沒有辦法,只能硬著頭皮,再次深入到 Netty 的底層世界中,不斷地啃,反復地啃,每次錄制一個新的章節(jié)之前,都會再花大量的時間去啃細節(jié),抓脈絡(luò),直到這個章節(jié)涉及到所有的部分爛熟于心才開始錄制。
最終,《Java 讀源碼之 Netty 深入剖析》這門視頻課程在 18 年中在慕課上線,前后大概花了大半年的時間,每個周末要么在錄視頻,要么在錄視頻的路上。
Netty慕課總結(jié)這段時期的轉(zhuǎn)變:通過閱讀 Spring 和 Netty 源碼,及文章博客、視頻課的分享,基本形成了閱讀源碼的關(guān)鍵思路和調(diào)試的方法論,后續(xù)在解決 Spring 和 Netty 相關(guān)的問題,即使之前沒有研究過相關(guān)模塊,也能夠很快定位并解決問題,接下來就進入了成熟期。
2.3 成熟期:19年 ~ 今
從 2019 年到現(xiàn)在,處在成熟期,這段時間開始大量閱讀其他開源框架源碼,排查各類疑難雜癥,并逐漸開始探索計算機底層原理的實現(xiàn)。
這段時間周末沒事就在家研究一些開源框架的實現(xiàn),比如 Dubbo、Mybatis 及工作中涉及到的一些核心框架。我的研究方式是,每次研究之前,都給自己拋出一個問題,比如:Dubbo 的服務(wù)發(fā)現(xiàn)是怎么做的,然后花一個下午或一個晚上的時間通過源碼找到完整的答案。
經(jīng)過成長期的磨練,到這個時期,快捷鍵已形成了肌肉記憶。可能我無法快速說出某操作的快捷鍵,但是能用手指本能地按出來。快捷鍵的肌肉記憶給我閱讀和調(diào)試源碼帶來了巨大的幫助,當手速跟上了思維的速度之后,思維的連續(xù)性得到保障,每一次閱讀源碼都能夠進入心流狀態(tài)。
在探索 Dubbo,Mybatis 等其他開源框架的源碼過程中,憑借過去的經(jīng)驗和調(diào)試技能,給我?guī)硪粋€非常直觀的心理感受就是:每次分析源碼的過程就像是一次推理破案的過程,又猶如閱讀一篇懸疑小說,在紛繁復雜的世界中抓住核心環(huán)節(jié),厘清思路,最終水落石出。源碼面前無秘密,一切都是公開的。
研究了一些開源框架之后,我發(fā)現(xiàn)很多框架最底層的原理其實大同小異(比如 redis、nginx、netty 的應(yīng)用層的內(nèi)存分配機制和線程模型的設(shè)計幾乎是一致的),框架每過幾年就會翻新一遍,沒這么多時間去把所有的框架都去研究一遍。
這個時候需要問自己一個問題:每當遇到一個新的技術(shù),如何很快掌握?
2021 年春節(jié)前開始思考這個問題,春節(jié)那段時間,得出結(jié)論:后續(xù)的技術(shù)生涯中,我需要去探索在未來幾年甚至十幾年那些不變的東西。
于是我將研究方向轉(zhuǎn)向了計算機底層原理。其中一部分就是 Linux 內(nèi)核,內(nèi)核中有非常多的寶藏值得深挖,很多應(yīng)用層的一些設(shè)計與內(nèi)核設(shè)計同構(gòu),且有很多技術(shù)直接依賴于內(nèi)核的實現(xiàn),如 Docker。
雖然內(nèi)核是 C 語言和匯編寫的,而我是搞 Java 的,但是源碼分析的思路和調(diào)試的技能是相通的,經(jīng)過了一段時間的嘗試,21年年底開始寫 Linux 內(nèi)核分析相關(guān)的文章(【原創(chuàng)】Linux 內(nèi)核源碼分析之進程概要及調(diào)度時機、【原創(chuàng)】Linux 內(nèi)核源碼分析之進程調(diào)度的邏輯),算是開始入門了吧。
內(nèi)核遠比我想象的要復雜得多,但是越復雜,探索的過程就越刺激。
今天是 2022 年元旦,給自己訂個內(nèi)核小目標:2025 年元旦前入門,2027 年元旦前熟悉,2032 年元旦前精通,10 年后來看,希望不要被打臉呀!
3 結(jié)語
本來這篇文章想重點寫寫閱讀源碼的關(guān)鍵思路和調(diào)試技能的,沒想到寫到最后成了源碼回憶錄,索性把干貨部分放到下一篇文章中吧,歡迎大家關(guān)注公眾號。
最后順便說一句,元旦之后,我的新書 《跟閃電俠學 Netty》要出版了。書的前半部分是掘金小冊中的內(nèi)容:通過一個完整的 IM 項目入門 Netty;后半部分用了較大的篇幅來介紹 Netty 的底層原理,也會穿插講一些源碼閱讀的思路,希望能夠幫助到你。

全文完,大家元旦快樂!
喜歡本文的朋友們,歡迎長按下圖關(guān)注訂閱號閃電俠的博客,收看更多精彩內(nèi)容
期
精
彩
《跟閃電俠學Netty》01:?服務(wù)端啟動流程介紹[圖文+視頻]
海量連接服務(wù)端jvm參數(shù)調(diào)優(yōu)雜記
深夜對話:NIO中SelectionKey.OP_WRITE你了解多少
天池中間件大賽dubboMesh優(yōu)化總結(jié)(qps從1000到6850)
支持點贊↓↓
