如何有效閱讀Github上開源項目代碼?
問題背景:
對於普通程序員,可能已經習慣了在IDE(myeclipse,eclipse)中閱讀源代碼,但是從GitHub上fork然後clone下來的項目源碼往往無法import到eclipse中,那麼問題來了,有什麼好的工具或者方法來閱讀這些源碼?
本人正好最近用github較多,聊聊自己讀開源項目的一些體會吧。
1.首先要能運行起來
本人一般都是先想辦法讓代碼運行起來,只有這樣,當我對代碼做更改的時候,才能通過程序的變化直觀的看到我更改的這部分代碼究竟是負責哪一部分的。個人經驗表示,github上只要是靠譜點的開源項目都會在README裡面寫上如何部署的。我一般發現README寫的不太好的,都是先去找找別的,實在找不到了才會回來看這個。
-----------------------------------比如碰到某個輸出函數你不知道到底執行在哪個部分,可以直接改掉裡面的輸出,再運行程序,發現你設置的輸出在哪裡粗線了(就是這就是這~),就找到了這句話的執行區間了。比如你還可以注釋掉一些代碼,看看程序有什麼反應,是崩潰了還是哪些地方消失了。如果你注釋掉一部分代碼,發現程序數據不更新了,那就可以判斷出這部分代碼是跟數據更新有關的,如果程序崩潰了,那看看在哪down掉了,那你注釋的那部分代碼就在這個地方被使用了。等等。2.要有一個全局搜索的工具我一般用的是sublime,感覺蠻好用的。它的作用是只要你有一絲線索,就可以迅速定位到你想要的地方。你自己還可以折騰下安裝sublime的tag插件,就可以很方便的從函數調用的地方跳到函數定義的地方。------------------------------------這個方法還是滿通用的。比如android,我clone下來一個網路非同步的庫volley,但是我覺得他這個庫對json支持的達不到我的要求。我想自己更改,那第一步肯定是用sublime打開源碼,搜索Json。就可以把範圍縮小到局部了。比如node.js,我想研究下hexo的git push,那我直接用sublime打開源碼,搜索git就可以直接把範圍縮小很多了。比如前端我用到了DataTable,但是我覺得他的排序不滿足我的需求。那我可以直接用「sort"關鍵詞搜索他的源代碼,定位出排序演算法,接下來就可以慢慢改了。不然2W多行的源代碼,豈不是瘋了-_-!
再進一步,可能我不太清楚某個函數的用法與用處,我直接用sublime搜索這個函數名,所有調用到這個函數的代碼就在我眼前了,接下來我就可以研究這個函數到底在程序中如何使用了。3.學會注釋與修改這個其實就是第一步說的。程序跑不起來很多東西都不能確定,你甚至不知道是對是錯。4.多用搜索引擎與官網文檔其實不光是github開源代碼,讀別人的代碼都需要多用搜索。因為很多時候如果源代碼的注釋不到位,你讀起來是很費勁的。這個時候搜索引擎就很重要了。-------------------------------------比如我前一陣嘗試iOS的時候,第一次看到block這個東西,根本就不懂這是什麼代碼怎麼能讀明白,於是直接粘到谷歌里看了。比如有時候別人對代碼做封裝了,你看到的函數根本就不是原生的,但是你剛讀可能不知道,完了你又看不太懂,這個時候你可以直接去搜谷歌或者developer center,比如我前一陣看別人源碼看到了這個:[self performDelay:0.5 block:^{}];谷歌后發現丫根本找不到這個函數是啥。那請不要慌,多半是因為這個函數根本就是項目作者自己封裝的。(有iOS大神可能會文你為毛不command直接進去看,求大神們不噴,我就是舉個例子。)
5.不建議通讀源碼本人作為一個開發沒多久的程序猿,水平一般,所以讀開源項目的時候很多代碼根本通讀不能,所以我一般都是用上面的這些方法,從功能入手,一點點研究,慢慢吃透整個項目。希望能對樓主有所幫助。
以上為什麼收藏比贊還多。。如果覺得有乾貨就給個贊吧,么么噠~代碼光是看沒太大用。你得讓他跑起來。eclips不行,就換ide。總之讓它跑起來。
編譯-&>運行-&>了解過程-&>找bug-&>fix bug-&> submit patch-&> submit feature request
|(有問題) |
+-&> 解決問題-&>運行閱讀代碼要做的第一件事情是收集所有和項目相關的資料。比如你要做一個項目的售後服務,那麼你首先要搞明白項目做什麼用的,那麼調研文檔、概要設計文檔、詳細設計文檔、測試文檔、使用手冊都是你要最先搞到手的。如果你是為了學習那麼盡量收集和你的學習有關的資料,比如你想學習linux的文件系統的代碼,那最好要找到linux的使用手冊、以及文件系統設計的方法、數據結構的說明。(這些資料在書店裡都可以找到)。
材料的種類分為幾種類型
1.基礎資料。
比如你閱讀turbo c2的源代碼你要有turbo c2的函數手冊,使用手冊等專業書籍,msc 6.0或者java 的話不但要有函數手冊,還要有類庫函數手冊。這些資料都是你的基礎資料。另外你要有一些關於uml的資料可以作為查詢手冊也是一個不錯的選擇
2.和程序相關的專業資料。
每一個程序都是和相關行業相關的。比如我閱讀過一個關於氣象分析方面的代碼,因為裡邊用到了一個複雜的數據轉換公式,所以不得不把自己的大學時候課本 找出來來複習一下高等數學的內容。如果你想閱讀linux的文件管理的代碼,那麼找一本講解linux文件系統的書對你的幫助會很大。
3.相關項目的文檔資料
這一部分的資料分為兩種,一個相關行業的資料,比如你要閱讀一個稅務系統的代碼那麼有一些財務/稅務系統的專業資料和國家的相關的法律、法規的資料是 必不可少的。此外就是關於這個項目的需求分析報告、概要設計報告、詳細設計報告,使用手冊、測試報告等,盡量多收集對你以後的代碼閱讀是很重要的
知識準備
了解基礎知識,不要上來就閱讀代碼,打好基礎可以做到事半功倍的效果
留備份,構造可運行的環境
代碼拿到手之後的第一件事情是先做備份,最好是刻在一個光碟上,在代碼閱讀的時候一點不動代碼是很困難的一件事情,特別是你要做一些修改性或增強性維護的時候。而一旦做修改就可能發生問題,到時候要恢復是經常發生的事情,如果你不能很好的使用版本控制軟體那麼先留一個備份是一個最起碼的要求了。
在做完備份之後最好給自己構造一個可運行的環境,當然可能會很麻煩,但可運行代碼和不可運行的代碼閱讀起來難度會差很多的。所以多用一點時間搭建一個環境是很值得的,而且我們閱讀代碼主要是為了修改其中的問題或做移植操作。不能運行的代碼除了可以學到一些技術以外,用處有限。
找開始的地方
做什麼事情都要知道從那裡開始,讀程序也不例外。在c語言里,首先要找到main()函數,然後逐層去閱讀,其他的程序無論是vb、delphi都要首先找到程序頭,否則你是很難分析清楚程序的層次關係。
分層次閱讀
在閱讀代碼的時候不要一頭就紮下去,這樣往往容易只見樹木不見森林,閱讀代碼比較好的方法有一點象二叉樹的廣度優先的遍歷。在程序主體一般會比較簡 單,調用的函數會比較少,根據函數的名字以及層次關係一般可以確定每一個函數的大致用途,將你的理解作為註解寫在這些函數的邊上。當然很難一次就將全部注 解都寫正確,有時候甚至可能是你猜測的結果,不過沒有關係這些註解在閱讀過程是不斷修正的,直到你全部理解了代碼為止。一般來說採用逐層閱讀的方法可以是 你系統的理解保持在一個正確的方向上。避免一下子扎入到細節的問題上。在分層次閱讀的時候要注意一個問題,就是將系統的函數和開發人員編寫代碼區分開。在 c, c++,java ,delphi中都有自己的系統函數,不要去閱讀這些系統函數,除非你要學習他們的編程方法,否則只會浪費你的時間。將系統函數表示出來,註明它們的作用 即可,區分系統函數和自編函數有幾個方法,一個是系統函數的編程風格一般會比較好,而自編的函數的編程風格一般比較會比較差。從變數名、行之間的縮進、注 解等方面一般可以分辨出來,另外一個是象ms c6++會在你編程的時候給你生成一大堆文件出來,其中有很多文件是你用不到了,可以根據文件名來區分一下時候是系統函數,最後如果你實在確定不了,那就 用開發系統的幫助系統去查一下函數名,對一下參數等來確定即可。
寫註解
寫註解是在閱讀代碼中最重要的一個步驟,在我們閱讀的源代碼一般來說是我們不熟悉的系統,閱讀別人的代碼一般會有幾個問題,1搞明白別人的編程思想不 是一件很容易的事情,即使你知道這段程序的思路的時候也是一樣。2閱讀代碼的時候代碼量一般會比較大,如果不及時寫註解往往會造成讀明白了後邊忘了前邊的 現象。3閱讀代碼的時候難免會出現理解錯誤,如果沒有及時的寫註解很難及時的發現這些錯誤。4不寫註解有時候你發生你很難確定一個函數你時候閱讀過,它的功能是什麼,經常會發生重複閱讀、理解的現象。
好了,說一些寫註解的基本方法:
1.猜測的去寫,剛開始閱讀一個代碼的時候,你很難一下子就確定所有的函數的功能,不妨採用採用猜測的方法去寫註解,根 據函數的名字、位置寫一個大致的註解,當然一般會有錯誤,但你的註解實際是不但調整的,直到最後你理解了全部代碼。
2.按功能去寫,別把註解寫成語法說明 書,千萬別看到fopen就寫打開文件,看到fread就寫讀數據,這樣的註解一點用處都沒有,而應該寫在此處開發參數配置文件(****。dat)讀出 系統初始化參數。。。。。,這樣才是有用的註解。
3.在寫註解的使用另外要注意的一個問題是分清楚系統自動生成的代碼和用戶自 己開發的代碼,一般來說沒有必要寫系統自動生成的代碼。象delphi的代碼,我們往往要自己編寫一些自己的代碼段,還要對一些系統自動生成的代碼段進行 修改,這些代碼在閱讀過程是要寫註解的,但有一些沒有修改過的自動生成的代碼就沒有必要寫註解了。
4.在主要代碼段要寫較為詳細的註解。有一些函數或類在程序中起關鍵的作用,那麼要寫比較詳細的註解。這樣對你理解代碼有很大的幫助。
5.對你理解起來比較困難的地方要寫詳細的註解,在這些地方往往會有一些編程的技巧。不理解這些編程技巧對你以後的理解或移植會有問題。
6.寫中文註解。如果你的英文足夠的好,不用看這條了,但很多的人英文實在不怎麼樣,那就寫中文註解吧,我們寫註解是為了加快自己的理解速度。中文在大多數的時候比英文更適應中國人。與其寫一些誰也看不懂的英文註解還不如不寫。
重複閱讀
一次就可以將所有的代碼都閱讀明白的人是沒有的。至少我還沒有遇到過。反覆的去閱讀同一段代碼有助於得代碼的理解。一般來說,在第一次閱讀代碼的時候 你可以跳過很多一時不明白的代碼段,只寫一些簡單的註解,在以後的重複閱讀過程用,你對代碼的理解會比上一次理解的更深刻,這樣你可以修改那些註解錯誤的 地方和上一次沒有理解的對方。一般來說,對代碼閱讀3,4次基本可以理解代碼的含義和作用。
運行並修改代碼
如果你的代碼是可運行的,那麼先讓它運行起來,用單步跟蹤的方法來閱讀代碼,會提高你的代碼速度。代碼通過看中間變數了解代碼的含義,而且對 以後的修改會提供很大的幫助
用自己的代碼代替原有代碼,看效果,但在之前要保留源代碼
600行的一個函數,閱讀起來很困難,編程的人不是一個好的習慣。在閱讀這個代碼的時候將代碼進行修改,變成了14個函數。每一個大約是40-50 行左右.
題主感謝樓上各位的熱心解答,以此想到,是否可以在Github上創建一個入門repo,介紹一些比較基礎的Github技巧,題主搭了一個框架jerrycave/introduce-github · GitHub,資深github玩家請繞道
覺得題主應該了解一下構建工具,比如cmake, ant, maven之類的。
非常同意「讓代碼跑起來」在github上,稍微完整些的項目,都有自動化構建的工具。題主應該花點時間學習這些工具怎麼使用。同時,這些工具會用了,也對自己開發項目很有幫助。idea 完美支持git
chrome插件:octotree,值得你擁有
Atom
推薦閱讀:
※學習Rust適合寫什麼練手項目?
※C++ 是不是最博大精深的編程語言?
※C++里,typeid里的type_info是怎麼構造出來的,或是type_info從來沒有被構造?
※程序員在面試時是否會被要求手寫代碼?
※你見過哪些很贊的宏定義?