閱讀開源原始碼的正確姿勢建議
關於如何閱讀開源社群原始碼,最近陸續有同學過來問我這個問題。前段時間,在HBase技術交流群裡,大家也討論過一些零散的方法,但都不繫統。藉著這個問題,我也認真回顧了一下自己所用過的一些方法,覺的有必要整理出來,供大家參考。
先選擇合適的原始碼版本
因為不同的版本間的特性/流程方面存在較大的差異,閱讀原始碼時選擇合適的版本還是至關重要的。因此,需要先審視自己的需求:
“我閱讀原始碼,是單純的為了學習?還是希望在業務系統中更好的用好它?”
如果是前者,那完全可以選擇最新發布或待發布的穩定版本。
如果是後者,則需要選擇自己業務系統中正在使用的版本。
藉助書籍或官方資料快速瞭解技術架構和關鍵特性
如果有介紹原理的書籍,可以先快速瀏覽一遍,粗略瞭解整體架構、關鍵特性。
這些資訊也可以從官方資料中一探究竟,尤其是架構介紹相關的章節。
從快速試用開始加強自己對該專案的感性認識
先參考官方資料中的Quick Start章節,先學習如何使用,加強自己對於整體專案的感性認識。
這個過程,基本能摸清楚利用該專案"能做什麼",以及"如何做"。當然,這裡僅僅涉及了最基礎的功能。
簡單瞭解原始碼模組結構,而後從最基礎的流程入手
快速瞭解原始碼的模組組成結構,以及每一個模組的主要作用。
這樣有助於從原始碼結構上把握整體專案的輪廓,而後選擇最基礎的流程入手。
對於HBase而言,最基礎的流程無非是如何建表以及如何寫資料的流程。
學習一個特性要從瞭解配置和如何使用著手,同時建議閱讀相關特性的設計文件或網上已有的原始碼解析文章
在學習一個特性時,也應該先從如何使用這個特性開始,介面如何被呼叫,關鍵配置有哪些,都是瞭解基礎功能的基本起點。
接下來,可以先自己思考一下,這個特性如果由自己來設計,那整體思路應該是怎樣的。
部分關鍵的特性/流程,在社群的問題單中,通常會有簡潔的設計文件,這些文件能幫你理清方案的整體框架和思路。如果沒有設計文件,那問題單中的Comments也是值得參考的。
當然,網上如果已經存在一些原始碼解析文章,也可以先參考一下,但好的文章往往是可遇不可求的。
如果在閱讀原始碼之前,能夠大致瞭解方案的思路,對自己會有很大的幫助,"瞎子摸象"式的閱讀非常費時費力。
有一點需要強調一下:書籍或別人的文章中所描述的流程,在新版本中有可能已經發生了變化,因此,閱讀時一定要帶著辨證的思維。
摸清主線,避免過早陷入一些旁枝末節
剛開始閱讀原始碼時,會遇到很多"好奇點":
-
這個演算法居然實現的如此神奇?
-
這個資料結構怎麼沒有見過?
-
這個引數是幹嘛的?
我自己也時常經不起這些"誘惑",陷於對這些細節的考究中,常常"離題"半天以後,才被拉回到主線中。
在閱讀原始碼的時候,能遇到一些感興趣的細節是好事,但建議先將這些細節點記錄下來,等過完整體流程以後再回頭看這些細節,避免過早陷入。
閱讀原始碼過程中,通常需要動手做一些測試,此時,可以藉助jstack工具(針對Java專案),它能為你提供如下有價值的資訊:
-
執行緒模型
-
呼叫棧
呼叫棧資訊可以幫你理清整體呼叫流程(另外,在定位問題時,jstack打印出的資訊也時常可以發揮重要作用)。
重視閱讀日誌資訊
在程序啟動或執行過程中,一些關鍵的操作或處理,都會記錄日誌資訊,因此,閱讀日誌往往是一條有助於理清流程主線的捷徑。
閱讀原始碼過程中,同步繪製時序圖,固化對流程的理解
好不容易摸清的主線,建議及時用時序圖的方式固化下來,這樣可以幫助自己快速回顧整個流程。
當然,除了時序圖,還建議附帶簡單的文字性總結。
閱讀原始碼過程中,不斷髮現或提出疑問,並且記下來
當理清了主線流程以後,要繼續深入探索這些細節疑問點,這些點決定了你對整個特性/流程的理解深度。
掌握一個特性/流程的基本前提,就是需要自己解答自己提出的所有疑問。
對於一些"莫名其妙"或"匪夷所思"的設計,請一定要對照參考社群問題單中的描述資訊、設計文件或Comments資訊。
閱讀原始碼過程中,遇到晦澀難懂的細節,如何應對?
此時,建議開啟Debug模式,詳細跟蹤每一步的呼叫流程,Debug可以分兩種形式:
-
遠端Debug
-
本地Debug
對於HBase而言,相比於遠端Debug,本地Debug似乎更難以理解了,因為我們所熟知的HBase部署形態就是分散式的,要對執行時的HBase叢集進行Debug,自然採用遠端Debug模式了。
其實,Debug也可以針對HBase提供的測試用例,大部分用例都是基於一個本地模擬的Mini Cluster執行的,這個Mini Cluster執行在一個程序中,使用執行緒模擬HBase的關鍵程序。
這個過程中,也可以動手小改一下原始碼,驗證自己的想法,或者觀察因為改動所帶來的行為變化。
重視閱讀測試用例原始碼
很多人並不習慣於閱讀HBase的測試用例原始碼,其實,閱讀測試用例的原始碼,可以幫你理解一些正確的行為應該是怎樣的。
因為每一個被定義的正確行為,都以具體的測試用例固化下來了。
重視實際遇到的每一個Bug,每一個Bug都可以講一個完整的故事
閱讀原始碼過程中,自己提出的疑問,往往還不是最深刻的。最深刻的點,往往存在於所遇到的每一個Bug中。
對於Bug,很多人的態度往往是,能規避則規避之,叢集只要能恢復正常,就不再有任何興致去探究根因。
Bug往往是一些未考慮充足的邊界場景,如果想探究Bug的根因,必然需要先摸清與之相關的所有流程,而後結合問題現象進行相關推理。一個Bug的前因後果,通常可以講一個完整的故事。只有經過一個個Bug的歷練,才能逐步成長為核心專家。
能力進階:開始關注社群動態,或嘗試為社群貢獻Patch
關注社群動態,可以及時獲知一些重要的Bugs或社群正在開發的大的Features。關注的方式包括但不限於:
-
訂閱社群的Mail List
-
關注社群的問題單
如果感覺自己已經很好的掌握了原始碼,而且發現了部分設計不合理,或者是部分能力不完善(結合實際的業務需求),也可以主動為社群貢獻Patch,對於大部分開源專案而言,都是非常鼓勵大家貢獻Patch的。
總結
本文主要從方法論的角度探討了閱讀開源專案原始碼的一些建議,供大家參考。這是第一個版本的內容,歡迎大家在評論中貢獻自己的優秀實踐方法,我可以繼續完善它的內容,期望能夠為更多人帶來有價值的指導資訊。