如何學習源碼?阿里架構師教你一招攻破源碼難關

最新互聯網大廠面試真題、Java程序員面試策略(面試前的準備、面試中的技巧)請移步GitHub

對於很多開源軟件來說,如果我們把它作爲我們業務系統的重要組成部分之一,真正地用於生產,僅僅知道如何使用是遠遠不夠的,你必須掌握它的實現原理和很多細節,這樣才能找到最佳的使用姿勢,當你的系統出現問題時,你纔有可能基於它的實現原理,再根據一些現象來排查問題原因。

掌握這些開源軟件的最佳方式就是去學習它的源代碼。很多同學跟我說:“我也很想去看一些開源軟件的代碼,也嘗試去看過,但是面對上千個源碼文件,幾十萬行代碼,完全不知道從哪兒入手啊。”

今天我們就針對這個情況來聊一聊,學習開源軟件的代碼該如何入手。

有一點我提前說明一下,對於這節課裏面涉及到的一些名詞,我會直接使用英文,主要目的是方便你直接對應到那些開源軟件英文官網上的標題。

一、通過文檔來了解開源項目

學習源代碼應該從哪兒入手呢?最佳的方式就是先看它的文檔

通過看文檔,你可以快速地掌握這個軟件整體的結構,它有哪些功能特性,它涉及到的關鍵技術、實現原理和它的生態系統等等。在掌握了這些之後,你對它有個整體的瞭解,然後再去看它的源代碼,就不會再有那種盲人摸象找不到頭緒的感覺了。

首先強調一點是,你必須去看這些開源軟件官方網站上的文檔,儘量不要去網上搜一些翻譯的中文文檔。爲什麼呢?

因爲這些開源軟件,特別是一些社區活躍的軟件,它的迭代是很快的,即使是自帶官方中文翻譯的項目,它的中文文檔很多都會落後於英文版,你能看到的中文版本很多時候都已經過時了。那非官方的翻譯,問題可能就不止是過時的問題了,可能還會出現一些錯漏的地方。所以,最好還是直接來看官方的英文文檔。

如果說你的英文閱讀水平確實有限,直接閱讀英文文檔有困難或者看得非常慢,怎麼辦?你還是要按照我接下來告訴你的方法去看它的英文官網,即使閱讀大段的技術文章有困難,網站的標題你總能看懂吧?找到你需要閱讀的文章後,你可以在網上搜一下對應的中文版本,先看一遍中文版,然後再對着英文原版過一遍,彌補中文版可能過時或翻譯不準確的問題。

開源社區經過這麼多年的發展,它已經形成一個相對比較成熟的文化。每個開源軟件,代碼如何管理、社區成員如何溝通、如何協作這些都已經形成了一個比較固定的套路。大多數開源軟件,它的官網和技術文檔也是有一個相對比較固定的結構的。

接下來我們以Kafka 的官網爲例子,來說下怎麼來看它的文檔。

如果說你對這個項目完全不瞭解,沒用過這個軟件,你首先需要看的文檔是Quick Start,按照 Quick Start 中的指導快速把它的環境搭起來,把它運行起來,這樣你會對這個項目有個感性認識,也便於你在後續深入學習的時候“跑”一些例子。

然後你需要找一下它的Introduction,一般裏面會有項目的基本介紹。這裏面很重要的一點是,你需要找到這個項目用到的一些基本概念或者名詞的介紹文檔,在 Kafka 的文檔中,

這些內容就在 Introduction 裏面,比如 Topic、Producer、 Consumer、Partition 這些概念在 Kafka 中代表的含義。

有些開源項目會單獨有一個 Basic Concepts 文檔來講這些基礎概念。這個文檔非常重要,因爲這些開源社區的開發者都有個很不好的愛好:發明概念。很多開源項目都會自己創造一些名詞或者概念,瞭解這些基本概念纔有可能看懂它項目的其他文檔。

對項目有個基本的瞭解之後呢,接下來你可以看一下它的使用場景、功能特性以及相關的生態系統的介紹。在 Kafka 中功能相關的內容在Use cases和EcoSystem兩篇文章中,有些項目中會有類似名爲 Features 的文檔介紹功能和特性。

其中項目的生態系統,也就是 EcoSystem,一般會介紹它這個項目適用的一些典型的使用場景,在某個場景下適合與哪些其他的系統一起來配合使用等。如果說你的系統不是特別特殊或者說冷門的話,你大概率可以在 EcoSystem 裏面找到和你類似的場景,可以少走很多的彎路。

你在讀完上面這些文檔之後,對這個項目的整體應該會有一個比較全面的瞭解了,比如說:

  • 這個項目是幹什麼的?
  • 能解決哪些問題?
  • 適合在哪些場景使用?
  • 有哪些功能?
  • 如何使用?

對這些問題有一個初步的答案之後,接下來你就可以去深入學習它的實現原理了。這是不是意味着,你可以立即去看它的源碼呢?這樣做或許可行,但並不是最好的方法。

你知道大部分開源項目都是怎麼誕生的嗎?一般來說是這樣的:某個大學或者大廠的科學家,某天腦海裏突然出現了一個改變世界的想法,科學家們會基於這個想法做一些深入的研究,然後寫了一篇論文在某個學術期刊或者會議上發表。論文發表後在業內獲得很多的贊,這時候就輪到像 Google、Facebook 這樣的大廠出手了:這個論文很有價值,不如我們把它實現出來吧?一個開源項目就這樣誕生了。

所以,對於這樣的開源項目,它背後的這篇論文就是整個項目的靈魂,你如果能把這篇論文看完並且理解透了,這個項目的實現原理也就清楚了。

學習完項目靈魂,就可以開始閱讀源碼了。

二、用以點帶面的方式來閱讀源碼

需要注意的是,你在讀源碼的時候,千萬不要上來就找 main 方法這樣泛泛地去看,爲什麼?你可以想一下,一篇文章,它是一個線性結構,你從前往後讀就行了。一本書呢?如果我們看目錄的話,可以認爲是個樹狀結構,但大多數的書的內容還是按照線性結構來組織的,你可以從前往後讀,也可以通過目錄跳着讀。

那程序的源代碼是什麼結構?那是一個網狀結構,關係錯綜複雜,所以這種結構是非常不適合人類去閱讀的。你如果是泛泛去讀源代碼,很容易迷失在這個代碼織成的網裏面。那怎麼辦?
我推薦大家閱讀源碼的方式是,帶着問題去讀源碼,最好是帶着問題的答案去讀源碼。你每次讀源碼之前,確定一個具體的問題,比如:

  • RocketMQ 的消息是怎麼寫到文件裏的?
  • Kafka 的 Coordinator 是怎麼維護消費位置的?

類似這種非常細粒度的問題,粒度細到每個問題的答案就是一兩個流程就可以回答,這樣就可以了。如果說你就想學習一下源代碼,或者說提不出這些問題怎麼辦呢?答案還是,看文檔

確定問題後,先不要着急看源代碼,而是應該先找一下是否有對應的實現文檔,一般來說,核心功能都會有專門的文檔來說明它的實現原理,比如在 Kafka 的文檔中,DESIGN和IMPLEMENTATION兩個章節中,介紹了 Kafka 很多功能的實現原理和細節。一些更細節的非核心的功能不一定有專門的文檔來說明,但是我們可以去找一找是否有對應的Improvement Proposal。(Kafka 的所有 Improvement Proposals 在這裏。)

這個 Improvement Proposal 是什麼呢?你可以認爲它是描述一個新功能的文檔,一般開源項目需要增加一個新的功能或者特性的時候,都會創建一個 Improvement Proposal,一般標題都是"xIP- 新功能名稱",其中 IP 就是 Improvement Proposal 的縮寫,x 一般就是這個開源項目的名稱的首字母,比如 Kafka 中 Improvement Proposal 的標題就都是以KIP 來開頭。

每個 Improvement Proposal 都是有固定格式的,一般要說明爲什麼需要增加這個功能,會對系統產生那些影響和改變,還有我們最關心的設計和實現原理的簡述。

你讀完講解實現的文檔再去看源代碼,也就是我剛剛說的,不只是帶着問題去讀,而是帶着答案去讀源碼。這樣你在讀源碼的時候,不僅僅是更容易理解源代碼,還可以把更多的精力放在一些實現細節上,這樣閱讀源碼的效果會更好。

使用這種以問題爲閱讀單元的方式來讀源代碼,你每次只要花很短的時間,閱讀很少的一部分源碼,就能解決一個問題,得到一些收穫。這種方式其實是通過一個一個的問題,在網狀的源代碼中,每次去讀幾個點組成的那一兩條線。隨着你通過閱讀源碼瞭解的問題越來越多,你對項目源碼的理解也會越來越全面和深入。

三、總結

如果你想了解一個開源項目,學習它的代碼,最佳的切入點就是去讀它的官方文檔,這些文檔裏面,最重要的靈魂就是項目背後的那篇論文,它一般是這個開源項目的理論基礎。

在閱讀源碼的時候呢,最佳的方式是帶着問題去閱讀,最好是帶着問題的答案去讀,這樣難度低、週期短、收穫快。不要想着一定要從總體上去全面掌握一個項目的所有源代碼,也沒有必要。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章