一篇文章把本該屬於你的源碼天賦還給你

怎麼閱讀源碼 "沒有經驗的技術差底子薄的初級程序員,如何閱讀項目源碼? "程序員

"有人閱讀過 mybatis 的源碼嗎 ?就看一個初始化過程就看的已經頭暈眼花了,小夥伴們支支招吧!"算法

"源碼應該怎麼閱讀,我曾經嘗試閱讀一些源碼,例如alibaba的druid中sqlparser部分,spring-mvc,可是發現很吃力,都說debug是最好的閱讀方式,我在debug時常常有跟丟的現象……就是走着走着感受好像進入了一些我當前不太關注細枝末節。 "spring

。。。。。。sql

估計不少人都有這樣的疑惑。編程

我很是能理解小夥伴們的痛苦,由於我也是這麼痛苦着走過來的。設計模式

閱讀優秀源碼的好處想必你們都知道,學習別人優秀的設計,合理的抽象,簡潔的代碼...... 總之是好處多多。spring-mvc

可是真的把龐大的代碼放到你的面前,就如同一個巨大的迷宮,要在其中東轉西轉尋出一條路來,把迷宮的整個結構搞清楚,理解核心思想,真心不容易。性能優化

在閱讀由面向對象的語言如Java寫的代碼時,會發現接口和具體的實現常常對應不起來,不太清楚一個功能究竟是怎麼在哪一個實現類中才能找到。 不像C語言,就是函數調用函數,相對還好點。服務器

若是是動態語言如Ruby,Python, 一個變量的類型甚至都不容易知道,閱讀的難度大大增長。數據結構

還有一個重要的緣由,如今咱們看到的源碼基本上都通過若干年發展、通過不少人不斷地完善的,枝枝蔓蔓很是多,魔鬼都在細節中。 閱讀的時候很容易陷進去, 看了幾十層函數調用之後,就完全懵了,就放棄了: 甭管你把源碼吹得天花亂墜, 老子不再看了。

通過不少痛苦的掙扎之後,我也算有一些成功的經歷,今天用治學的三個境界來類比, 給你們分享一下:

想把源碼搞懂,吃透,首先得登高望遠,瞰察路徑,明確目標與方向,瞭解源碼的概貌。

因此有些準備工做必須得作。

  1. 閱讀源碼以前,須要有必定的技術儲備。

好比設計模式,在不少Java源碼中幾乎就是標配,尤爲是這幾個:模板方法,單例,觀察者,工廠方法,代理,策略,裝飾者。

再好比閱讀Spring源碼,確定得先了解IoC是怎麼回事,AOP的實現方式,CGLib,Java動態代理等,本身動手,寫點相關的代碼,把這些知識點掌握了。

  1. 必須得會使用這個框架/類庫, 最好是精通各類各樣的用法。

上面剛提過,魔鬼都在細節中,若是有些用法根本不知道,可能你能看明白代碼是什麼意思,可是不知道它爲何這些寫。

  1. 先去找書,找資料,瞭解這個軟件的總體設計。

都有哪些模塊? 模塊之間是怎麼關聯的?怎麼關聯的?

可能一會兒理解不了,可是要創建一個總體的概念,就像一個地圖,防止你迷航。

在讀源碼的時候能夠時不時看看本身在什麼地方。

  1. 搭建系統,把源代碼跑起來!

相信我,Debug是很是很是重要的手段, 你想經過只看而不運行就把系統搞清楚,那是根本不可能的!

  1. 根據你對系統的理解,設計幾個主要的測試案例,定義好輸入,輸出。

運行系統,慢慢地debug ,一步步地走,這是個死功夫,沒有辦法繞過。

Debug一遍確定是不行的,須要Debug不少遍。

第一遍儘量拋棄細節,抓住主要流程, 好比有些看起來不重要的方法就不進去看了。

第二遍、第三遍....再去看那些細節。

一個很是重要的工做就是記筆記(又是寫做!),畫出系統的類圖(不要依靠IDE給你生成的), 記錄下主要的函數調用, 方便後續查看。

文檔工做極爲重要,由於代碼太複雜,人的大腦容量也有限,記不住全部的細節。 文檔能夠幫助你記住關鍵點, 到時候能夠回想起來,迅速地接着往下看。

要否則,你今天看的,可能到明天就忘個差很少了。

給你們看看我作的一些筆記, 格式不重要,很隨意,方便本身看懂就行。

6.主要的測試案例搞明白了,豐富測試案例,考慮一些分支流程。

繼續Debug......

總之,靜態地看代碼 + 動態地debug (從業務的角度), 就會慢慢揭開這個黑暗森林的面紗。

這一步會很是很是地花費時間,可是你作完了,對系統的理解絕對有質的飛躍。

沒有千百度的上下求索,不會有瞬間的頓悟和理解,衷心祝願閱讀源碼的朋友們都能達到這一境界。

最後一點,也是最關鍵的一點: 要能堅持下去。

我不是一個聰明人, 可是笨人自有笨辦法:什麼事都架不住不斷的重複,一遍看不明白,再來第二遍, 兩遍搞不明白,再來第三遍......

可能有人要問: 你怎麼能這麼堅持地刨根問底呢?

答案就是好奇心: 這玩意兒究竟是怎麼實現的?!

閱讀源碼的意義與方法 思索了這兩個問題良久,也去知乎找了一些相關話題的問答,但並無標準答案。因此,我這裏也只是記錄一些我對此的見解,也許會隨着 RTFSC 閱歷的豐富而發生變化,我會記錄更新於個人博客裏面

意義

在我看來,閱讀源碼的意義在於學習優秀的「套路」。

這裏的「套路」所指範圍很廣,大到架構設計,小到可取的命名風格,還有設計模式、實現某類功能使用到的數據結構和算法等等。所謂高手,其實就是能比大部分人更早更快地掌握套路並熟練運用之人。

埋頭在本身的天地裏耕芸當然也能逐漸進步和成長,但總會有時候會遇到一些場景,你苦思良久也沒法作出良好的設計,總會有一些時候,糾結如何爲一個變量命名讓你停下飛速敲擊的手指。這些令你爲難的場景,先賢們也許早就遇到過,而且給出了優雅的解決方案。看優秀的源碼的時候,將這樣的場景與對應的方案收入囊中,或者僅僅在腦中留下一個印象也好,以便在須要的時候,你的武器庫裏總能掏出一把稱手的傢伙來。

源碼閱讀三要素

源碼分析是一種臨界知識,掌握了這種臨界知識,能不變應萬變,源碼分析對於不少人來講很枯燥,生澀難懂。

源碼閱讀,我以爲最核心有三點:技術基礎+強烈的求知慾+耐心。

我認爲是閱讀源碼的最核心驅動力。我見到絕大多數程序員,對學習的態度,基本上就是這幾個層次(很偏激哦):

只關注項目自己,不懂就baidu一下。

除了作好項目,還會閱讀和項目有關的技術書籍,看wikipedia。

除了閱讀和項目相關的書外,還會閱讀IT行業的書,好比學Java時,還會去了解函數語言,如LISP。

找一些開源項目看看,大量試用第三方框架,還會寫寫demo。

閱讀基礎框架、J2EE規範、Debug服務器內核。

大多數程序都是第1種,到第5種不光須要濃厚的興趣,還須要勇氣:我能讀懂嗎?其實,你可以讀懂的。

耐心,真的很重要。由於你極少看到閱讀源碼的指導性文章或書籍,也沒有人要求或建議你讀。你讀的過程當中常常會卡住,而一卡主可能就陷進了迷宮。這時,你須要作的,多是暫時中斷一下,再從外圍看看它:如API結構、框架的設計圖。

源碼問題是程序員都繞不開的話題,說到這裏,也給你們推薦一個交流平臺:架構交流羣180705916,裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化這些成爲架構師必備的知識體系。還能領取免費的學習資源,如下的知識體系圖也是在羣裏獲取。相信對於已經工做和遇到技術瓶頸的碼友,在這個羣裏必定有你須要的內容。

一些方法

不該該這樣

不該該漫無目的地隨手拿起一分源碼,試圖去通讀。這一方面會過目即忘無所收穫,另外一方面會枯燥得讓你迅速從着手到放棄。學習的方式有不少種,閱讀源碼並不必定是最適合你當前的狀況的。

應該這樣

精心挑選要閱讀的源碼項目。

這最好是與你的編程語言、你的工做內容、你的興趣所在相關的,這樣才能更切實地感覺到閱讀源碼給你帶來的益處,更有動力繼續。

若是你想學習的知識點有官方文檔,先看文檔再看源碼。

直接從源碼着手,搞清楚原理當然是好,可是源碼有多是難啃的,先熟悉官方提供給全部人看的文檔,能較爲平滑地對這方面的知識先有個大概的瞭解,而後再結合源碼去深刻。

提出具體的問題,而後帶着問題到源碼中找答案。

好比在使用 Toast 的過程當中,你可能會想到一些問題:Toast.makeText(...).show() 時發生了什麼?Toast 能不能在非 UI 線程調用?能不能自定義 Toast 佈局?諸如此類。在源碼中探尋完你想要的答案,你的目的也就達到了。

從一些共性層面入手。

大部分的程序裏都會使用到的東西,好比線程模型、UI 組織結構、任務調度方式等等。針對某一個方面去了解,比漫無目的要有效率得多。

最好可以編譯運行起來。

若是一份代碼你只能看不能跑,那可能讀到一些地方你只能猜這個地方的數據值和跳轉結構是怎麼樣的,而頗有可能你猜的是錯的。但若是你能編譯運行,那在須要的時候你能夠修改,加日誌等等來更好地觀察和驗證你的想法,獲得正常的理解。

作一些筆記。

一方面是將你的學習成果保留下來,方便隨時查閱,畢竟只憑腦子記憶是不靠譜的;另外一方面在學習的過程當中,也能幫助理解

相關文章
相關標籤/搜索