學習各種開源項目,已經成為很多朋友不可回避的工作內容了。筆者本人也是如此。在接觸并學習了若干個開源項目之后,筆者試圖對自己工作過程中的若干體會加以總結,以期對一些希望借鑒的朋友有所裨益。
需要說明的是,筆者本人接觸的開源項目大多屬于計算機系統領域,例如Linux kernel,KVM,QEMU,OpenStack等。因此,此處介紹的經驗必定也有些局限。請讀者們自行分辨,區別對待。
1. 學習分層和目標管理?
對于一個開源項目,可以將與之相關的各種知識和技能的學習大致劃分為如下五個層次:?
第一層次: 了解項目的基本概念、基本用途、邏輯結構、基本原理、產生背景、應用場景等基本知識。?
這個層次的基本定位其實就是“科普”。如果對于一個項目只需要有些基本了解,且短期內并不需要上手進行實際技術工作,則學習到這個層次也就可以先應付一下了。?
第二層次: 掌握項目的基本安裝流程和使用方法。?
這個層次的基本定位是“入門”,以便對這個項目獲得直觀認識,對其安裝和使用獲得親身體驗。如果只是需要以as-is方式使用這個項目,則初步學習到這個層次即可。?
第三層次: 了解代碼的組織,找到各個主要邏輯/功能模塊與代碼文件之間的對應關系,通過代碼分析走通幾個關鍵的、有代表性的執行流程。?
這個層次的基本定位是“深入”,開始理解這個項目的實際實現,能夠真正將項目的功能、工作原理和代碼實現對應起來,獲得對這個項目工作過程的直觀認識。這個層次是學習開源項目代碼的真正開始。如果希望基于這一項目進行應用開發,或者針對與這一項目密切相關的其他項目進行工作時,則對項目本身的代碼進行這一層次的理解,會很有幫助。?
第四層次: 了解該項目所有代碼模塊、程序文件的作用,走通所有主要執行流程。?
這個層次的基本定位是“掌握”,能夠比較全面、系統地理解這個項目的設計和實現,并且熟悉項目各個部分的代碼。如果希望對項目進行深度定制修改,或者對社區有所貢獻,則應當以達到這個層次作為目標。?
第五層次: 鉆研、領悟該項目的各種設計思想與代碼實現細節。?
這個層次的基本定位是“精通”,精益求精,學無止境。這是大神們追求的境界。如果希望成為項目社區的重要貢獻者乃至核心貢獻者,則應當以這個層次作為努力的目標。?
綜上,對于一個開源項目的學習過程可以大致分為五個層次。至于到底要學習到什么階段,投入多少相關精力,則完全取決于學習的目的。?
2. 知識基礎?
學習一個開源項目需要的知識基礎主要包括:?
1)該項目涉及的技術領域的背景知識 ?
舉例而言,分析Linux Kenrel,則應該了解操作系統原理;學習OpenStack,則應該知道什么是云計算。如果沒有這些背景知識作為基礎,上來就死磕源代碼,只能是事倍功半。?
2) 該項目開發使用的語言及其各種開發調試工具 ?
這個就無需多言了。?
3) 英語?
很遺憾,目前為止真正流行的開源項目大部分不是起源于國內。因此,除了學習個別極其流行、文檔完備的項目之外,大家還是需要自行搜集閱讀英文資料參考。學好英語很重要。?
當然,到底需要準備多少知識基礎,完全取決于學習的目的和層次。如果只是想科普一下,也就不必太過麻煩了。?
3. 學習思路?
學習一個項目的過程,其實就是由表及里了解分析它的過程。上述提及的五個學習層次便組成了這樣一個逐漸深入的過程。在此基礎之上,學習、分析代碼的過程,也可以嘗試做到由表及里、逐漸深入。?
在剛開始接觸一個項目的時候,我們看到的其實就是一個黑盒子。根據文檔,我們一定會發現盒子上具有若干對外接口。通常而言,這些接口可以被分為三類:?
- 配置接口: 用于對盒子的工作模式、基本參數、擴展插件等等重要特性進行配置。這些配置往往是在盒子啟動前一次性配好。在盒子的工作過程中,這些配置或者不變,或者只在少數的情況下發生改變。?
- 控制接口: 用于在盒子的工作過程中,對于一些重要的行為進行操縱。這是盒子的管理員對盒子進行控制命令注入和狀態信息讀取的通路。?
- 數據接口: 用于盒子在工作過程中讀取外部數據,并在內部處理完成后向外輸出數據。這是盒子的用戶真正關心的數據通路。?
因此,在分析一個開源項目的代碼時,可以圍繞重要的配置、控制、數據接口展開分析工作,特別應該注意理解一個關鍵的接口背后隱藏的操作流程。例如,針對數據接口,至少應當走通一條完整的數據輸入輸出流程,也即在代碼中找到數據從輸入接口進入盒子后,經過各種處理、轉發步驟,最終從輸出接口被傳輸出去的整個執行過程。一旦走通了這樣一條流程,則可以將與數據處理相關的各個主要模塊、主要步驟貫穿起來,并將邏輯模塊圖上和文檔中的抽象概念對應到代碼實現之中,可以有效推進對于項目的深入理解。?
在實踐這一思路的過程中,筆者建議可以優先從控制接口和數據接口中各自選擇一二重要者進行背后的執行流程詳細分析,力爭找到其中每一步的函數調用及數據傳遞關系(對于一些系統、應用庫提供的底層函數可以先行跳過以節省時間)。這一工作完成之后,則第1節中第三層次的學習目標即可初步達成。?
配置接口在不同的項目中的重要程度不同。對于一些架構極為靈活、配置空間甚大的項目(如OpenStack的Ceilometer),則可以適當多花些時間加以研究,否則簡單了解即可。?
對于這個學習思路,下文中還將結合實例進行進一步的說明。?
4. 若干小建議?
以下是筆者的一些零散建議,供大家參考。?
1)做好記錄?
在剛剛入手開始學習某個項目的源代碼時,其實很有點破譯密碼的感覺。大量的數據結構和函數方法散落在代碼的各個角落里,等待著學習者將它們貫穿到一個個重要的執行流程中。因此,在分析學習的過程中,無論有什么零散收獲,都值得認真記錄下來。珍珠自然會串成項鏈的。?
2)不要過分糾纏于細節?
立志搞懂一個項目的每行源代碼是值得尊敬的,但至少在剛剛入手的時候是沒有必要的。如果過于糾纏于代碼的實現細節,則可能很快就被搞得頭暈眼花不勝其煩了(看英文資料的時候,每遇到一個不認識的詞都要立刻查詞典么?)。不妨避免細節上的過度糾纏,還是先盡快走通關鍵的執行流程,將項目的骨干框架搭起來,然后再以此為參照,就可以清晰判斷什么代碼值得深入分析,什么地方可以簡單略過了。?
3)想像和聯想很重要?
如前所述,從零開始搞懂一個項目的代碼,就像破譯密碼。因此,不妨展開合理的想象和聯想,將各個零散的發現和理解聯系起來,并加以分析印證。在這個過程中,對項目所在領域的背景知識、對項目本身的邏輯框架和工作原理等方面的理解,都是想像和聯想的參照與指導。此外,一些關鍵的函數名、變量名等等都是聯想的hint。本質上,編程語言也是語言,而程序代碼就是說明文。在分析代碼時,一定要超越語言和代碼的細節去理解被說明的事物本身。?
4)該搜就搜?
分析代碼的時候,很容易出現的情況就是,一個執行流程走到半截找不到下一步了。。。在這種情況下,當然首先還是推薦采用各種調試工具的單步執行功能加以跟蹤。如果暫時不會,或者種種原因只能進行靜態代碼分析,那么該搜就搜吧。各種IDE工具的文本搜索都能用,哪怕是grep也行。至于到底以什么為搜索關鍵詞,就需要琢磨琢磨了。?
5)外事不決問google,內事不決問百度?
如題,不解釋。?
?
?
轉自CSDN 作者資料
? ? ?章宇于2002年及2007年分別于清華大學電子工程系獲得學士及博士學位,其后一直從事計算機系統領域的研究與開發工作,目前供職于華為技術有限公司云操作系統部門,從事OpenStack相關工作。出于工作原因和個人興趣,作者陸續關注了一些開源項目,主要包括:KVM/QEMU,libvirt,virt-mamager,OpenStack,Open vSwitch,Ceph,Zabbix等。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
