如何閱讀開(kāi)源項(xiàng)目

最近這段時(shí)間一直比較忙第献,相對(duì)于之前少了很多的學(xué)習(xí)時(shí)間破加。抽空看幾篇源碼分析的文章俱恶,大多數(shù)都是大同小異的思路,把英文翻譯為中文而已范舀。鑒于關(guān)于介紹如何閱讀開(kāi)源項(xiàng)目的文章比較稀少速那,常言道授人予魚(yú)不如授人予漁。希望這篇文章能夠給準(zhǔn)備閱讀三方源碼的同學(xué)一些啟示尿背。

目的


在閱讀源碼之前最好明確一下閱讀的目的,這樣有助于閱讀的深度和時(shí)間的控制捶惜。比如如果是為了解決項(xiàng)目中的bug田藐,則可以閱讀bug所涉及的部分;如果是為了提高自己的編碼能力吱七,學(xué)習(xí)設(shè)計(jì)技巧汽久,則就需要更為深入的閱讀。

因?yàn)殚喿x源碼其實(shí)是一件非常辛苦的事情踊餐,尤其是分析一些大型開(kāi)源項(xiàng)目的源碼景醇,如果毫無(wú)目的的閱讀會(huì)浪費(fèi)大量的時(shí)間。而且閱讀源碼也是一個(gè)長(zhǎng)期的過(guò)程吝岭,不可能一天分析完Spring源碼的分析三痰,所以在分析源碼之前一定要有一個(gè)明確的認(rèn)識(shí)吧寺,不僅僅只是翻譯英文注釋?zhuān)ù罅康臅r(shí)間是在所難免的。

對(duì)筆者而言閱讀源碼的目的基本上可以分為如下幾種:

  1. 提高自己的編碼能力散劫,學(xué)習(xí)設(shè)計(jì)思想。
  2. 解決工作中所用第三方庫(kù)遇到的bug获搏。
  3. 借鑒開(kāi)源代碼赖条,私有化別人的代碼,完成工作需求常熙。

當(dāng)然不排除某些大神纬乍,讀源碼純粹是了找開(kāi)源代碼漏洞或者想改進(jìn)該項(xiàng)目。畢竟這種牛逼的人是少數(shù)裸卫。當(dāng)我們明確了閱讀的目的就可以大致確定所需要花費(fèi)的時(shí)間及精力了仿贬。

源碼獲取


獲取源碼的地方太多了,最負(fù)有盛名的就是GitHub彼城。除此之外還有sourceforge诅蝶,Google和Apple也有其開(kāi)源項(xiàng)目下載地址,分別是Google OpenSource募壕、Apple OpenSource调炬。國(guó)內(nèi)有比較出名的有開(kāi)源中國(guó)碼云(開(kāi)源中國(guó)代碼托管平臺(tái)))舱馅,Coding缰泡。

整理一下:

  1. GitHub
  2. sourceforge
  3. Google OpenSource
  4. Apple OpenSource
  5. 開(kāi)源中國(guó)
  6. 碼云(開(kāi)源中國(guó)代碼托管平臺(tái)))
  7. Coding

在進(jìn)行搜索的開(kāi)源項(xiàng)目有很多搜索技巧,就拿GitHub舉個(gè)例子代嗤。想高效的使用GitHub棘钞,一定要把 advanced searchprefixes看一下干毅。

除了上面提到的開(kāi)源項(xiàng)目下載地址宜猜,還有很多其他的地方可以獲取到源碼,這里就不多提了硝逢。

分析方法


閱讀方法才是今天的重點(diǎn)姨拥,筆者一般是按照下面的步驟開(kāi)始。

  1. 基本思想就是先對(duì)項(xiàng)目有個(gè)大致的了解渠鸽。比如關(guān)鍵的類(lèi)有哪些叫乌,各個(gè)文件夾之間的關(guān)系。
  2. 然后從最核心的API開(kāi)始徽缚,先使用UML里的類(lèi)圖建立靜態(tài)結(jié)構(gòu)憨奸,分析出類(lèi)與類(lèi)之間的關(guān)系(繼承,組合凿试,實(shí)現(xiàn)排宰,依賴(lài)似芝,關(guān)聯(lián)等等)。這一步是精讀的必經(jīng)之路额各,如果想要徹底理解国觉,畫(huà)UML圖無(wú)意識(shí)最直接的方式。
  3. 配合IDE工具分析核心流程虾啦,理解項(xiàng)目是如何工作的麻诀。
  4. 著重看項(xiàng)目中添加的注釋?zhuān)驗(yàn)橐话汩_(kāi)源項(xiàng)目中的注釋都非常重要。

接下來(lái)分下面幾個(gè)部分詳細(xì)介紹傲醉。

  • 看:靜態(tài)對(duì)代碼進(jìn)行分析蝇闭,看相關(guān)資料,代碼邏輯
  • 跑:將項(xiàng)目在IDE里面跑起來(lái)硬毕,通過(guò)IDE調(diào)試參數(shù)呻引,加Log等。
  • 查:閱讀過(guò)程中肯定會(huì)遇到不懂的吐咳,這時(shí)候需要通過(guò)搜索引擎來(lái)解決你的疑惑逻悠。

這個(gè)部分是非常基礎(chǔ)但是重要的部分韭脊,主要完成對(duì)代碼的基本感知童谒。從靜態(tài)的角度理解代碼。

現(xiàn)有資料

在我們準(zhǔn)備閱讀某個(gè)開(kāi)源項(xiàng)目之前沪羔,如果搜集了相關(guān)的資料的話饥伊,對(duì)我理解起來(lái)非常有幫助。也就是常說(shuō)的站在巨人的肩膀上蔫饰。

主要分為兩種:

  1. 項(xiàng)目官方文檔比如Wiki
  2. 使用者分析的文檔比如項(xiàng)目源碼分析琅豆。

GitHub上的開(kāi)源項(xiàng)目大部分都有文檔介紹,好一點(diǎn)的項(xiàng)目都會(huì)有對(duì)應(yīng)的Wiki篓吁。除此之外開(kāi)源項(xiàng)目的Issue也是我們需要關(guān)心的茫因。往往這些Isuue對(duì)應(yīng)到項(xiàng)目中都是核心部分,也就是我們非常值得關(guān)注的地方杖剪。如下圖所示节腐,一定要善用這些選項(xiàng)。因?yàn)檫@些都是前人踩過(guò)的坑摘盆,對(duì)于項(xiàng)目理解非常有用。

除了項(xiàng)目本身的文檔外饱苟,還有一種形式的文檔也需要我們注意孩擂。這類(lèi)文檔就是別人對(duì)這個(gè)項(xiàng)目寫(xiě)過(guò)的一些源碼分析文章。這類(lèi)文章已經(jīng)對(duì)項(xiàng)目分析過(guò)一次了箱熬,先閱讀完之后类垦,會(huì)對(duì)我們自己去閱讀源碼起到一個(gè)理清思路狈邑,引路的作用。

但是有些大型的開(kāi)源項(xiàng)目文檔太多了米苹,就官方說(shuō)明文檔就不可能一次看完砰琢,比如java中的Spring,看完文檔也是不現(xiàn)實(shí)的陪汽。這個(gè)時(shí)候就應(yīng)該把文檔與代碼調(diào)試結(jié)合在一起训唱。效率會(huì)高不少。而且這類(lèi)型的大型項(xiàng)目至少也得花一年半載才能弄清楚况增。

代碼內(nèi)注釋

對(duì)于開(kāi)源項(xiàng)目?jī)?nèi)注釋一定训挡,一定要仔細(xì)看看澳骤。在使用第三方庫(kù)的時(shí)候澜薄,往往因?yàn)闆](méi)有仔細(xì)閱讀代碼內(nèi)注釋而導(dǎo)致濫用方法。

如下圖是iOS開(kāi)源項(xiàng)目CocoaAsyncSocket一段代碼內(nèi)注釋


如果沒(méi)有仔細(xì)看代碼內(nèi)注釋?zhuān)瑳](méi)有注意到必須設(shè)置代理和代理隊(duì)列表悬,遇到報(bào)錯(cuò)了根本不知道怎么發(fā)生的。

代碼內(nèi)注釋是作者著重想傳達(dá)給使用者的信息籽暇,所以切記切記戒悠,一定要仔細(xì)看代碼內(nèi)注釋绸狐。但是好多人都誤以為把注釋看懂就是源碼分析了累盗,而且好多源碼分析文章也是這樣寫(xiě)的,把注釋翻譯一下符相,說(shuō)明一下用途。

這個(gè)過(guò)程是對(duì)代碼的深入理解部分镜豹,通過(guò)改變函數(shù)參數(shù)蓝牲,運(yùn)行環(huán)境等。不同的語(yǔ)言用了不同的IDE例衍,大部分IDE的作用都相差不多肄渗,都可以追溯堆棧,查看變量信息等翎嫡。所以思路都是相同的。

IDE調(diào)試

項(xiàng)目編譯出來(lái)惑申,運(yùn)行加log,試著修改一些數(shù)據(jù)和代碼人芽,看看有什么變化绩脆。這是最為常用的方法。靈活使用IDE的debugger惕味,而debugger最重要的功能是獲取call stack玉锌。查看變量的變化情況,在你不知道有什么用的函數(shù)里加個(gè)斷點(diǎn)禀倔,顯示出來(lái)的call stack都能讓你對(duì)系統(tǒng)有更清晰的認(rèn)識(shí)参淫。

關(guān)于IDE的調(diào)試使用常用的斷點(diǎn)調(diào)試,變量跟中這些鞋既,這里就不多講了。

調(diào)試技巧

很多時(shí)候我們不知道某個(gè)變量或者某個(gè)變量具體的作用,那么這個(gè)時(shí)候就可以用到對(duì)CUD(Create,Update,Delete)思想检吆。

調(diào)試中的CUD具體來(lái)講就是對(duì)源代碼的類(lèi)程储、函數(shù)、變量進(jìn)行增加摊灭、修改败徊、刪除。如果一直停留在源碼的基礎(chǔ)上很有可能不能透徹的理解煤杀,當(dāng)我們掌握了代碼設(shè)計(jì)規(guī)則沪哺,使用CUD方式可以加深理解辜妓,以及驗(yàn)證我們的猜想是否正確。

特別注意籍滴,在實(shí)現(xiàn)項(xiàng)目中一定不要去修改第三方的源碼异逐,有時(shí)候可以通過(guò)修改第三方源碼來(lái)達(dá)到暫時(shí)的目的,但是往往在后期維護(hù)腥例,升級(jí)方面必將付出慘重的代價(jià)酝润。這里指的CUD只適合在分析源碼的時(shí)候。


在分析源碼的過(guò)程中构回,肯定會(huì)遇到自己不懂的地方纤掸,對(duì)于這種問(wèn)題,大部分靠自己現(xiàn)有的知識(shí)很有可能無(wú)法理解借跪,這個(gè)時(shí)候就需要實(shí)在不懂就問(wèn)了掏愁。Google、相關(guān)社區(qū)沦泌、GitHub Issue辛掠、Stackoverflow多搜多問(wèn)。

查這個(gè)步驟應(yīng)該是貫穿整個(gè)過(guò)程的他宛,但是也得注意不是一遇到問(wèn)題就上網(wǎng)查欠气,而是應(yīng)該在自己思考之后,得不到解答才去查队塘。很多同學(xué)養(yǎng)成了一遇到問(wèn)題就Google宜鸯,百度淋袖,其實(shí)從長(zhǎng)遠(yuǎn)來(lái)看不利于自己的提升。

分析總結(jié)

走完上面的步驟之后焰情,基本上對(duì)一個(gè)項(xiàng)目源碼掌握了剥懒。但是這個(gè)層次還是有點(diǎn)low。僅僅停留在理解的階段验游,如果想做得更好就需要對(duì)項(xiàng)目的設(shè)計(jì)進(jìn)行分析,看看有沒(méi)有可以改進(jìn)的地方崔梗,甚至完全試一試自己能不能針對(duì)某個(gè)模塊改進(jìn)一下垒在。

這個(gè)階段類(lèi)似于提升爪膊、創(chuàng)新的程度砸王,建立在見(jiàn)多識(shí)廣的基礎(chǔ)之上,對(duì)于閱讀開(kāi)源項(xiàng)目不多的同學(xué)還是非常有難度的耘成。

整理成文

最后的階段就是把自己分析的內(nèi)容整理成為文檔驹闰,分享出來(lái)师妙。這也是提升自己能力的一個(gè)重要渠道默穴,在寫(xiě)文章的時(shí)候蓄诽,會(huì)強(qiáng)迫自己對(duì)那些不清楚的知識(shí)點(diǎn)加深理解。

文章內(nèi)容應(yīng)包括自己整理的UML圖闸英,核心類(lèi)的實(shí)現(xiàn)嚎莉,代碼設(shè)計(jì)技巧趋箩,以及告知讀者使用該第三方的時(shí)候需要注意的問(wèn)題叫确。

在寫(xiě)文章的時(shí)候需要注意竹勉,不要過(guò)多的延伸吓歇。畢竟一個(gè)點(diǎn)所涉及的知識(shí)網(wǎng)太大了,選擇其中比較核心的幾點(diǎn)闡述即可测柠。

EOF

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市朝扼,隨后出現(xiàn)的幾起案子凹耙,更是在濱河造成了極大的恐慌肖抱,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異潮针,居然都是意外死亡瓣戚,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)舱权,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宴倍,“玉大人脖捻,你說(shuō)我怎么就攤上這事郭变∷弑簦” “怎么了未荒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵速侈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我冶共,道長(zhǎng)捅僵,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任馒闷,我火速辦了婚禮沛善,結(jié)果婚禮上金刁,老公的妹妹穿的比我還像新娘尤蛮。我一直安慰自己,他們只是感情好坯临,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著挟炬,像睡著了一般谤祖。 火紅的嫁衣襯著肌膚如雪粥喜。 梳的紋絲不亂的頭發(fā)上容客,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音供置,去河邊找鬼芥丧。 笑死续担,一個(gè)胖子當(dāng)著我的面吹牛物遇,可吹牛的內(nèi)容都是我干的询兴。 我是一名探鬼主播警儒,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼记劝!你這毒婦竟也來(lái)了钳恕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎类茂,沒(méi)想到半個(gè)月后巩检,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體示启,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冲秽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了民轴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杉武。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轻抱,死狀恐怖祈搜,靈堂內(nèi)的尸體忽然破棺而出容燕,到底是詐尸還是另有隱情,我是刑警寧澤蝗茁,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布颈嚼,位于F島的核電站阻课,受9級(jí)特大地震影響限煞,放射性物質(zhì)發(fā)生泄漏晰骑。R本人自食惡果不足惜硕舆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一抚官、第九天 我趴在偏房一處隱蔽的房頂上張望钦听。 院中可真熱鬧朴上,春花似錦痪宰、人聲如沸衣撬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)畔乙。三九已至,卻和暖如春钥庇,著一層夾襖步出監(jiān)牢的瞬間评姨,已是汗流浹背吐句。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工攀芯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侣诺,地道東北人氧秘。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像妥箕,于是被迫代替她去往敵國(guó)和親更舞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,839評(píng)論 25 707
  • 當(dāng)天邊那顆行出現(xiàn)刊头,你可知我又開(kāi)始想念。偶爾瘋魔原杂,會(huì)回憶會(huì)哭泣會(huì)想你卻不會(huì)露痕跡,感情濃烈也只“沉默”便掩埋了...
    燦然笑步閱讀 287評(píng)論 2 1
  • 今天有點(diǎn)忙穿肄!主要是全力籌備慶六一文藝匯演,這不上午基本都在剪輯音樂(lè)課了咸产,下午全程參與了第一次彩排,下午放學(xué)后急急地...
    甲午之印閱讀 198評(píng)論 0 0
  • 「東京不是實(shí)現(xiàn)夢(mèng)想的地方脑溢。東京是讓人忘記自己沒(méi)有實(shí)現(xiàn)夢(mèng)想的地方。」 鎮(zhèn)樓圖是富士臺(tái)月九連續(xù)劇验庙。直譯:“某天想起這段...
    少女冉閱讀 1,674評(píng)論 12 13