1. 程式人生 > >如何閱讀原始碼?(關鍵詞:閱讀/原始碼/高效)

如何閱讀原始碼?(關鍵詞:閱讀/原始碼/高效)

閱讀Java原始碼的重要性:

Java開發人員都知道,閱讀原始碼是一個非常好的學習方式,在我們日常工作中或多或少都會接觸些開原始碼, 比如說最常用的Struts,Hibernate,Spring,這些原始碼的普及與應用程度遠超過我們的想象,正因為很多人使用,也在推動著原始碼不斷地去完善。這些優秀的原始碼中有著多年積澱下來的精華,這些精華是非常值得我們學習的,不管我們當前是什麼水平,通過反覆閱讀原始碼能力能有所提升,小到對原始碼所提供的功能上的使用更加熟練,大到使我們的程式設計更加完美優秀。但是,縱觀我們身邊的人。能夠做到通讀原始碼的真的是少之又少,究其原因不外乎以下幾點。

  • 閱讀原始碼絕對算得上是一件費時費力的工作,需要讀者耗費大量的時間去完成。而作為開發人員,畢竟精力有限,實在沒辦法拿出太多的時間放在原始碼的閱讀上。
  • 原始碼的複雜性, 任何一款原始碼經歷了多年的發展與提煉,其複雜程度可想而知。當我們閱讀原始碼的時候,大家都知道需要通過工具來跟蹤程式碼的執行,進而去分析程式。但是,當代碼過於複雜,環環相扣繞來繞去的時候,跟進了幾十個甚至幾百個函式後,這時我們已經不知道自己所處的住置了,不得不再重來,但是一次又一次的,最終發現自己根本無法駕取它,不得不放棄。
  • 有些原始碼發展多年, 會遇到各種各樣的問題,並對問題進行了解決,而這些問題有的對於我們來說甚至可以用莫名其妙來修飾,有時候根本想不出會在什麼情況下會發生。我們選擇各種查閱資料,查詢無果,最終放棄。

無論基於什麼樣的原因,放棄閱讀原始碼始終不是一個明智的選擇,因為你失去了一個跟大師學習的機會。而且,當你讀過幾個原始碼之後你會發現,他們的思想以及實現方式是想通的。這就是開源的好處。隨著各種開源軟體的發展。各家都會融合別家優秀之處來不斷完善自己。這樣,到最後的結果就是所有的開源軟體從設計上或者實現上都會變得越來越相似,也就是說當你讀完某個優秀原始碼後再去讀另一個原始碼, 速度會有很大提升。

以我為例,Spring 是我閱讀的第一個原始碼,幾乎耗盡了我將近半年的時間,其中各種煎熬可想而知,但是當我讀完Spring再去讀MyBatis只用了兩週時間。當然,暫且不論它們的複雜程度不同,至少我閱讀的時候發現有很多相通的東西。當你第一次閱讀的時候,你的重點一定是在原始碼的理解上,但是,當你讀完第一個原始碼再去讀下一個的時候,你自然而然地會帶著批判或者說挑剔的眼光去閱讀:

  • 為什麼這個功能在我之前看的原始碼中是那樣實現的,而在這裡會是這樣實現的?
  • 這其中的道理在哪裡,哪種實現方式更優秀呢?

而通過這樣的對比及探索,你會發現,自己的進步快得難以想象。

閱讀Java原始碼的前提條件:

1、技術基礎

在閱讀原始碼之前,我們要有一定程度的技術基礎的支援。

假如你從來都沒有學過Java,也沒有其它程式語言的基礎,上來就啃《Core Java》,那樣是很難有收穫的,尤其是《深入Java虛擬機器》這類書,或許別人覺得好,但是未必適合現在的你。

比如設計模式,許多Java原始碼當中都會涉及到。再比如閱讀Spring原始碼的時候,勢必要先對IOC,AOP,Java動態代理等知識點有所瞭解。

2、強烈的求知慾

強烈的求知慾是閱讀原始碼的核心動力!

大多數程式設計師的學習態度分為如下幾個層次:

  1. 完成自己的專案就可以了,遇到不懂的地方就百度一下。

  2. 不僅做好專案,還會去閱讀一些和專案有關的書籍。

  3. 除了閱讀和專案相關的書籍之外,還會閱讀一些IT行業相關的書籍。

  4. 平時會經常逛逛GitHub,找一些開源專案看看。

  5. 閱讀基礎框架、J2EE規範、原始碼。

大多數程式設計師的層次都是在第一層,到第五層的人就需要有強烈的求知慾了。

3、足夠的耐心

通過閱讀原始碼我們可以學習大佬的設計思路,技巧。還可以把我們一些零碎的知識點整合起來,從而融會貫通。總之閱讀原始碼的好處多多,想必大家也清楚。

但是真的把那麼龐大複雜的程式碼放到你的眼前時,肯定會在閱讀的過程中卡住,就如同陷入了一個巨大的迷宮,如果想要在這個巨大的迷宮中找到一條出路,那就需要把整個迷宮的整體結構弄清楚,比如:API結構、框架的設計圖。而且還有理解它的核心思想,確實很不容易。 

剛開始閱讀原始碼的時候肯定會很痛苦,所以,沒有足夠的耐心是萬萬不行的。

 

如何讀Java原始碼:

我也是經歷過閱讀原始碼種種痛苦的人,算是有一些成功的經驗吧,今天來給大家分享一下。 

如果你已經有了一年左右的Java開發經驗的話,那麼你就有閱讀Java原始碼的技術基礎了。

1、建議從JDK原始碼開始讀起,這個直接和eclipse整合,不需要任何配置。

可以從JDK的工具包開始,也就是我們學的《資料結構和演算法》Java版,如List介面和ArrayList、LinkedList實現,HashMap和TreeMap等。這些資料結構裡也涉及到排序等演算法,一舉兩得。

面試時,考官總喜歡問ArrayList和Vector的區別,你花10分鐘讀讀原始碼,估計一輩子都忘不了。

然後是core包,也就是String、StringBuffer等。 如果你有一定的Java IO基礎,那麼不妨讀讀FileReader等類。

建議大家看看《Java In A Nutshell》,裡面有整個Java IO的架構圖。Java IO類庫,如果不理解其各介面和繼承關係,則閱讀始終是一頭霧水。

Java IO 包,我認為是對繼承和介面運用得最優雅的案例。如果你將來做架構師,你一定會經常和它打交道,如專案中部署和配置相關的核心類開發。

讀這些原始碼時,只需要讀懂一些核心類即可,如和ArrayList類似的二三十個類,對於每一個類,也不一定要每個方法都讀懂。像String有些方法已經到虛擬機器層了(native方法),如hashCode方法。

當然,如果有興趣,可以對照看看JRockit的原始碼,同一套API,兩種實現,很有意思的。

如果你再想鑽的話,不妨看看針對虛擬機器的那套程式碼,如System ClassLoader的原理,它不在JDK包裡,JDK是基於它的。JDK的原始碼Zip包只有10來M,它像是有50來M,Sun公司有下載的,不過很隱祕。我曾經為自己找到、讀過它很興奮了一陣。

2、Java Web專案原始碼閱讀

步驟:表結構 → web.xml → mvc → db → spring ioc → log→ 程式碼

① 先了解專案資料庫的表結構,這個方面是最容易忘記的,有時候我們只顧著看每一個方法是怎麼進行的,卻沒有去了解資料庫之間的主外來鍵關聯。其實如果先了解資料庫表結構,再去看一個方法的實現會更加容易。

② 然後需要過一遍web.xml,知道專案中用到了什麼攔截器,監聽器,過濾器,擁有哪些配置檔案。如果是攔截器,一般負責過濾請求,進行AOP等;如果是監聽器,可能是定時任務,初始化任務;配置檔案有如 使用了spring後的讀取mvc相關,db相關,service相關,aop相關的檔案。

③ 檢視攔截器,監聽器程式碼,知道攔截了什麼請求,這個類完成了怎樣的工作。有的人就是因為缺少了這一步,自己寫了一個action,配置檔案也沒有寫錯,但是卻怎麼除錯也無法進入這個action,直到別人告訴他,請求被攔截了。

④ 接下來,看配置檔案,首先一定是mvc相關的,如springmvc中,要請求哪些請求是靜態資源,使用了哪些view策略,controller註解放在哪個包下等。然後是db相關配置檔案,看使用了什麼資料庫,使用了什麼orm框架,是否開啟了二級快取,使用哪種產品作為二級快取,事務管理的處理,需要掃描的實體類放在什麼位置。最後是spring核心的ioc功能相關的配置檔案,知道介面與具體類的注入大致是怎樣的。當然還有一些如apectj等的配置檔案,也是在這個步驟中完成。

⑤ log相關檔案,日誌的各個級別是如何處理的,在哪些地方使用了log記錄日誌。

⑥ 從上面幾點後知道了整個開源專案的整體框架,閱讀每個方法就不再那麼難了。

⑦ 當然如果有專案配套的開發文件也是要閱讀的。

3、Java框架原始碼閱讀

當然了,就是Spring、MyBatis這類框架。

在讀Spring原始碼前,一定要先看看《J2EE Design and Development》這本書,它是Spring的設計思路。注意,不是中文版,中文版完全被糟蹋了。

想要閱讀MyBatis的原始碼就要先了解它的一些概念,否則雲裡來霧裡去的什麼也不懂。有很多人會選擇去買一些書籍來幫助閱讀,當然這是可取的。那麼如果不想的話,就可以去官網檢視它的介紹(MyBatis網站:http://www.mybatis.org/mybatis-3/zh/getting-started.html),團長也是按照官網上面的介紹來進行原始碼閱讀的。團長認為MyBatis的亮點就是管理SQL語句。

總結

沒有人一開始就可以看得懂那些原始碼,我們都是從0開始的,而且沒有什麼捷徑可尋,無非就是看我們誰願意花時間去研究,誰的求知慾更強烈,誰更有耐心。閱讀原始碼的過程中我們的能力肯定會提升,可以從中學到很多東西。在我們做專案的時候就會體現出來了,的確會比