開源項目學習方法

學習各類開源項目,已經成爲不少朋友不可迴避的工做內容了。筆者本人也是如此。在接觸並學習了若干個開源項目以後,筆者試圖對本身工做過程當中的若干體會加以總結,以期對一些但願借鑑的朋友有所裨益。編程

須要說明的是,筆者本人接觸的開源項目大多屬於計算機系統領域,例如Linux kernel,KVM,QEMU,OpenStack等。所以,此處介紹的經驗一定也有些侷限。請讀者們自行分辨,區別對待。數據結構

1. 學習分層和目標管理 

對於一個開源項目,能夠將與之相關的各類知識和技能的學習大體劃分爲以下五個層次: 架構

第一層次:瞭解項目的基本概念、基本用途、邏輯結構、基本原理、產生背景、應用場景等基本知識。 框架

這個層次的基本定位其實就是「科普」。若是對於一個項目只須要有些基本瞭解,且短時間內並不須要上手進行實際技術工做,則學習到這個層次也就能夠先應付一下了。 編程語言

第二層次:掌握項目的基本安裝流程和使用方法。 函數

這個層次的基本定位是「入門」,以便對這個項目得到直觀認識,對其安裝和使用得到親身體驗。若是隻是須要以as-is方式使用這個項目,則初步學習到這個層次便可。 工具

第三層次:瞭解代碼的組織,找到各個主要邏輯/功能模塊與代碼文件之間的對應關係,經過代碼分析走通幾個關鍵的、有表明性的執行流程。 學習

這個層次的基本定位是「深刻」,開始理解這個項目的實際實現,可以真正將項目的功能、工做原理和代碼實現對應起來,得到對這個項目工做過程的直觀認識。這個層次是學習開源項目代碼的真正開始。若是但願基於這一項目進行應用開發,或者針對與這一項目密切相關的其餘項目進行工做時,則對項目自己的代碼進行這一層次的理解,會頗有幫助。 google

第四層次:瞭解該項目全部代碼模塊、程序文件的做用,走通全部主要執行流程。 雲計算

這個層次的基本定位是「掌握」,可以比較全面、系統地理解這個項目的設計和實現,而且熟悉項目各個部分的代碼。若是但願對項目進行深度定製修改,或者對社區有所貢獻,則應當以達到這個層次做爲目標。 

第五層次:鑽研、領悟該項目的各類設計思想與代碼實現細節。 

這個層次的基本定位是「精通」,精益求精,學無止境。這是大神們追求的境界。若是但願成爲項目社區的重要貢獻者乃至核心貢獻者,則應當以這個層次做爲努力的目標。 

綜上,對於一個開源項目的學習過程能夠大體分爲五個層次。至於到底要學習到什麼階段,投入多少相關精力,則徹底取決於學習的目的。 

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等。

相關文章
相關標籤/搜索