小白也能玩轉(zhuǎn)開源項(xiàng)目,你與大神只差這幾步!
原創(chuàng)【51CTO.com原創(chuàng)稿件】作為開發(fā)者,如果能充分利用好開源項(xiàng)目中的資源,不僅能提高實(shí)踐能力,專業(yè)知識(shí)水平,還能從中學(xué)到優(yōu)秀的架構(gòu)思想。
本文將提供一些學(xué)習(xí)開源項(xiàng)目的思路,相信看了這篇文章,小白也可學(xué)習(xí)讀懂開源項(xiàng)目,不必再對(duì)著高大上的開源項(xiàng)目望而生畏,淺嘗輒止。
學(xué)習(xí)的價(jià)值
總結(jié)起來(lái),學(xué)習(xí)開源項(xiàng)目的價(jià)值主要包括以下幾點(diǎn):
專業(yè)水平的提升
很多通用的專業(yè)知識(shí),在專業(yè)領(lǐng)域內(nèi)去到哪個(gè)公司都能通用,特別是底層方面的知識(shí),可以在開源項(xiàng)目中學(xué)到,比如多線程處理、網(wǎng)絡(luò)通信、操作系統(tǒng)處理等。
舉個(gè)例子,通過學(xué)習(xí) Redis 的 RDB 持久化模式的“會(huì)將當(dāng)前內(nèi)存中的數(shù)據(jù)庫(kù)快照保存到磁盤文件中”,可以學(xué)習(xí)到在操作系統(tǒng) fork 一個(gè)子進(jìn)程來(lái)實(shí)現(xiàn),再繼續(xù)深入的話,就涉及到父子進(jìn)程機(jī)制,copy-on-write 技術(shù)。
這些專業(yè)知識(shí)之間是可以聯(lián)系起來(lái)的并且像一顆大樹一樣自我生長(zhǎng),但是當(dāng)沒理解透徹,自然沒法產(chǎn)生聯(lián)系,也就不能夠自我生長(zhǎng)了。
當(dāng)我們對(duì)開源項(xiàng)目的關(guān)鍵的點(diǎn)理解清晰,知識(shí)也隨著自我生長(zhǎng),也就如滾雪球一樣可以滾起來(lái)了。
解決問題能力的提升
通過學(xué)習(xí)開源項(xiàng)目的實(shí)現(xiàn),出現(xiàn)線上問題時(shí),可以快速定位問題癥結(jié)所在,通過修改配置或者修改源代碼來(lái)解決;或者當(dāng)業(yè)務(wù)需求沒有合適的開源項(xiàng)目能滿足時(shí),可以改造現(xiàn)有的開源項(xiàng)目來(lái)滿足業(yè)務(wù)。
作為要優(yōu)秀開發(fā),避免陷入“API 操作工”的被動(dòng)局面,學(xué)習(xí)開源項(xiàng)目的一個(gè)很重要目的就是知道其功能點(diǎn)是如何實(shí)現(xiàn)且優(yōu)化的。
學(xué)習(xí)其中的知識(shí)好比公式的推導(dǎo)過程,掌握基本 API 使用好比會(huì)數(shù)學(xué)公式可以應(yīng)付考試。
但是理解好的推導(dǎo)過程根據(jù)有助于記憶和理解,知其然也要知其所以然,當(dāng)遇那些沒法套公式的情況下,我們也知道如何解決。
思維的提升
通過學(xué)習(xí)成熟的開源項(xiàng)目的優(yōu)秀架構(gòu),可以總結(jié)和理解一些軟件設(shè)計(jì)常用的架構(gòu)思路。
例如實(shí)現(xiàn)高可用,主要是通過集群的數(shù)據(jù)冗余;例如 Kafka 集群,HDSF 集群,實(shí)現(xiàn)可擴(kuò)展可以考慮把變化層和不變層隔離,把業(yè)務(wù)實(shí)現(xiàn)抽象化;例如 Spring 的預(yù)留的一些可擴(kuò)展接口。
常見錯(cuò)誤觀點(diǎn)
學(xué)習(xí)開源項(xiàng)目有一些常見的錯(cuò)誤觀點(diǎn),導(dǎo)致新手容易望而生畏而輕易放棄,或者浪費(fèi)大量時(shí)間而收獲不大。
“學(xué)習(xí)開源項(xiàng)目是架構(gòu)師,技術(shù)大牛的事,我作為新手根本難以學(xué)會(huì),就算學(xué)了也用不到”
學(xué)習(xí)是一個(gè)過程,不是一朝一夕就可以成為大牛的,但是只要踏出第一步,總會(huì)有可能實(shí)現(xiàn)大牛夢(mèng)想的。
另一方面,通過不斷復(fù)盤不斷總結(jié),加以合適的方法論指導(dǎo),相信是可以有所收獲,能力得到提升的。
學(xué)習(xí)之后對(duì)于邏輯思維,知識(shí)體系的構(gòu)建相信會(huì)有很大提升,即使項(xiàng)目沒用到具體的開源項(xiàng)目,以后遇到相關(guān)問題可以觸類旁通,舉一反三,也是一種進(jìn)步。
“數(shù)據(jù)結(jié)構(gòu)和算法很重要,我只要學(xué)習(xí)這項(xiàng)目中的兩方面就可以了”
不要只盯著數(shù)據(jù)結(jié)構(gòu)和算法,這兩點(diǎn)在開源項(xiàng)目中并沒有那么重要。
例如 Netty 中的超時(shí)隊(duì)列是基于紅黑樹來(lái)實(shí)現(xiàn)的,我們其實(shí)只需要知道這一點(diǎn)就夠了,除非需要改造這方面的功能。更重要的是理解系統(tǒng)的設(shè)計(jì),功能的實(shí)現(xiàn)方案。
“一頭扎進(jìn)源碼進(jìn)行學(xué)習(xí)”
很多新手篤信社區(qū)論壇流行的一句話:“Talk is cheap,show me the code”,一頭扎進(jìn)源碼閱讀,卻最后陷入源碼的泥潭中,在層層代碼函數(shù)跳轉(zhuǎn)中迷失了方向。
其實(shí)學(xué)習(xí)開源項(xiàng)目應(yīng)該是自頂而下的,最底層的源碼應(yīng)該是最后才開始學(xué)習(xí),在此之前,需要學(xué)習(xí)項(xiàng)目相關(guān)架構(gòu)設(shè)計(jì)方面的知識(shí)。
有了這些知識(shí),就仿佛數(shù)據(jù)庫(kù)有了索引,按照知識(shí)索引來(lái)進(jìn)行源碼針對(duì)性突破,如巡航導(dǎo)彈精準(zhǔn)爆破,自然比地毯式轟炸更起到事半功倍的作用。
學(xué)習(xí)的四個(gè)層次
根據(jù)學(xué)習(xí)理解的深入程度不同,可以把學(xué)習(xí)分為 4 個(gè)層次,如上圖所示。
基礎(chǔ)學(xué)習(xí)
對(duì)項(xiàng)目有一個(gè)大概性、基礎(chǔ)性的了解,比如項(xiàng)目是什么,有什么作用,大概怎么用,解決了什么問題。
在面試中,不少初入職場(chǎng)的人的簡(jiǎn)歷寫到用到眾多的技術(shù)框架,實(shí)際上往往僅僅只到了這個(gè)層次,再深入往下問,便支支吾吾答不上來(lái)了。
檢視學(xué)習(xí)
對(duì)項(xiàng)目有一個(gè)系統(tǒng)性的了解,系統(tǒng)的各方面功能,基本原理,優(yōu)缺點(diǎn),使用場(chǎng)景,各配置項(xiàng)、API 使用。
在實(shí)際工作中,如果作為一個(gè)團(tuán)隊(duì)的普通成員,達(dá)到這個(gè)級(jí)別已經(jīng)可以滿足基本業(yè)務(wù)開發(fā)需求,但是如果想有更高的技術(shù)追求,僅僅到此是不夠的。
分析學(xué)習(xí)
在檢視學(xué)習(xí)的基礎(chǔ)上,對(duì)開源項(xiàng)目的各項(xiàng)性能參數(shù),各自場(chǎng)景性能調(diào)優(yōu)有比較全面的了解和實(shí)踐經(jīng)驗(yàn)。
到達(dá)這個(gè)層次,在項(xiàng)目生產(chǎn)中,已經(jīng)有獨(dú)當(dāng)一面的能力,有一定能力承擔(dān)核心主力開發(fā)的角色。
主題學(xué)習(xí)
在分析學(xué)習(xí)的基礎(chǔ)上,對(duì)開源項(xiàng)目的關(guān)鍵功能模塊的源碼有所了解,能夠根據(jù)實(shí)際需要封裝、修改源碼,或者借鑒項(xiàng)目造出新的輪子。
到達(dá)這個(gè)層次,往往有一定能力承擔(dān)技術(shù)負(fù)責(zé)人、技術(shù)帶頭人的角色。
學(xué)習(xí)的四個(gè)步驟
針對(duì)上面提到的學(xué)習(xí)的層次,下面介紹如何“自頂而下”學(xué)習(xí),來(lái)達(dá)到這 4 個(gè)層次。
步驟 1:基礎(chǔ)性了解學(xué)習(xí)
目標(biāo)是達(dá)到基礎(chǔ)學(xué)習(xí)的層次,對(duì)項(xiàng)目有大概性的了解,包括項(xiàng)目背景,解決的問題場(chǎng)景,項(xiàng)目功能,使用場(chǎng)景,基本的 API 使用。通過查找官方文檔、相關(guān)博客、視頻資料學(xué)習(xí)即可。
通過對(duì)系統(tǒng)有大概性了解之后,會(huì)自然而然有一些疑問,例如實(shí)現(xiàn)的原理,優(yōu)缺點(diǎn)等,后續(xù)學(xué)習(xí)帶著這些疑問進(jìn)行學(xué)習(xí)會(huì)更高效。
步驟 2:系統(tǒng)性學(xué)習(xí)與實(shí)踐
目標(biāo)是達(dá)到檢視學(xué)習(xí)的層次,對(duì)項(xiàng)目有系統(tǒng)性、全面性的了解,包括項(xiàng)目的功能、組成模塊、基本原理、使用場(chǎng)景、配置項(xiàng)、API 使用、與其他類似項(xiàng)目的優(yōu)缺點(diǎn)比較等。方法步驟如下:
安裝運(yùn)行
按照相關(guān)文檔,安裝運(yùn)行項(xiàng)目。在這個(gè)過程中,需要關(guān)注:
- 系統(tǒng)的依賴組件,因?yàn)橐蕾嚱M件是系統(tǒng)設(shè)計(jì)和實(shí)現(xiàn)的基礎(chǔ),可以了解系統(tǒng)一下關(guān)鍵信息。
例如 Memcached 最重要的依賴是高性能的網(wǎng)絡(luò)庫(kù) libevent,我們就能大概推測(cè) Memcached 的網(wǎng)絡(luò)實(shí)現(xiàn)應(yīng)該是 Reactor 模型的。
- 安裝目錄,常見的安裝目錄是 conf 存放配置文件,logs 存放日志文件,bin 存放日志文件。
而不同項(xiàng)目有些特殊目錄,比如 Nginx 有 HTML 目錄,這種目錄能促使我們帶著相關(guān)疑問繼續(xù)去研究學(xué)習(xí),帶著問題去學(xué)習(xí)效率是最高的。
- 系統(tǒng)提供的工具,需要特別“關(guān)注命令行和配置文件”,它們提供 2 個(gè)非常重要的關(guān)鍵信息,系統(tǒng)具備哪些能力和系統(tǒng)將會(huì)如何運(yùn)行。這些信息是我們學(xué)習(xí)系統(tǒng)內(nèi)部機(jī)制和原理的一個(gè)觀察窗口。
通常情況下,如果對(duì)每個(gè)命令行參數(shù)和配置項(xiàng)的作用和原理基本掌握了解的話,基本上對(duì)系統(tǒng)已經(jīng)很熟悉了。實(shí)踐中,可以不斷嘗試去修改配置項(xiàng),然后觀察系統(tǒng)有什么變化。
系統(tǒng)性研究原理與特性
這點(diǎn)相當(dāng)重要,因?yàn)橹挥星宄莆占夹g(shù)的原理特性,才能算真正掌握這門技術(shù),才能做架構(gòu)設(shè)計(jì)的時(shí)候做出合理的選擇。
在這個(gè)過程中,需要重點(diǎn)關(guān)注:
- 關(guān)鍵特性的基本實(shí)現(xiàn)原理,關(guān)鍵特性是該開源項(xiàng)目流行的重要賣點(diǎn),常見的有高性能、高可用、可擴(kuò)展等特性,項(xiàng)目是如何做到的,這是我們需要重點(diǎn)關(guān)注的地方。
- 優(yōu)缺點(diǎn)比對(duì)分析,優(yōu)缺點(diǎn)主要通過對(duì)比來(lái)分析,即:我們將兩個(gè)類似的系統(tǒng)進(jìn)行對(duì)比,看看它們的實(shí)現(xiàn)差異,以及不同的實(shí)現(xiàn)優(yōu)缺點(diǎn)都是什么。
典型的對(duì)比有 Memcached 和 Redis、Kafka 和 ActiveMQ、RocketMQ的比較。
- 使用場(chǎng)景,項(xiàng)目在哪些場(chǎng)景適用,哪些場(chǎng)景不適用,業(yè)界適用的常見案例等。
在此階段可以通過學(xué)習(xí)官方技術(shù)設(shè)計(jì)文檔,架構(gòu)圖,原理圖,或者相關(guān)技術(shù)博客,通常比較熱門的開源項(xiàng)目都有很多分析文檔,我們可以站在前人的基礎(chǔ)上避免重復(fù)投入。
但需要注意的是,由于經(jīng)驗(yàn)、水平、關(guān)注點(diǎn)、使用的版本不同等差異,不同的人分析的結(jié)論可能有差異,甚至有的是錯(cuò)誤的,因此不能完全參照。
一個(gè)比較好的方式就是多方對(duì)照,也就是說(shuō)看很多篇分析文檔,比較它們的內(nèi)容共同點(diǎn)和差異點(diǎn)。
同時(shí),如果有些技術(shù)點(diǎn)難以查到資料,自己又不確定,可以通過寫 Example 進(jìn)行驗(yàn)證,通過日志打印、調(diào)試、監(jiān)測(cè)工具觀察理解具體的細(xì)節(jié)。
例如可以寫一個(gè)簡(jiǎn)單程序使用 Netty,通過抓包工具觀察網(wǎng)絡(luò)包來(lái)理解其中的實(shí)現(xiàn)。
步驟 3:系統(tǒng)測(cè)試
如果只是自己學(xué)習(xí)和研究,可以參考網(wǎng)上測(cè)試和分析的文檔,但是如果要在生產(chǎn)環(huán)境投入使用必須進(jìn)行測(cè)試。
因?yàn)榫W(wǎng)上搜的測(cè)試結(jié)果,不一定與自己的業(yè)務(wù)場(chǎng)景很契合,如果簡(jiǎn)單參考別人的測(cè)試結(jié)果,很可能會(huì)得出錯(cuò)誤的結(jié)論,或者使用的版本不同,測(cè)試結(jié)果差異也比較大。
要特別注意的是,測(cè)試必須建立在對(duì)這個(gè)開源項(xiàng)目有“系統(tǒng)性”了解的基礎(chǔ)上,不能安裝完就立馬測(cè)試。
否則可能會(huì)因?yàn)榕渲庙?xiàng)不對(duì),使用方法不當(dāng),導(dǎo)致沒有根據(jù)業(yè)務(wù)的特點(diǎn)搭建正確的環(huán)境、沒有設(shè)計(jì)合理的測(cè)試用例,從而使得最終的測(cè)試結(jié)果得出了錯(cuò)誤結(jié)論,誤導(dǎo)了設(shè)計(jì)決策。
下面提供測(cè)試常見的思路參考,需要根據(jù)具體項(xiàng)目具體業(yè)務(wù)進(jìn)行測(cè)試用例的設(shè)計(jì):
核對(duì)每個(gè)配置項(xiàng)的作用和影響,識(shí)別出關(guān)鍵配置項(xiàng)。
進(jìn)行多種場(chǎng)景的性能測(cè)試。
進(jìn)行壓力測(cè)試,連續(xù)跑幾天,觀察 CPU、內(nèi)存、磁盤 IO 等指標(biāo)波動(dòng)。
進(jìn)行故障測(cè)試:Kill,斷電、拔網(wǎng)線、重啟 100 次以上、倒換等。
步驟 4:關(guān)鍵源碼學(xué)習(xí)
鉆研、領(lǐng)悟該項(xiàng)目的各種設(shè)計(jì)思想與代碼實(shí)現(xiàn)細(xì)節(jié),基本定位是“精通”,精益求精,學(xué)無(wú)止境。這是大神們追求的境界。
如果希望成為團(tuán)隊(duì)技術(shù)擔(dān)當(dāng)、項(xiàng)目社區(qū)的重要貢獻(xiàn)者,則應(yīng)當(dāng)以這個(gè)層次作為努力的目標(biāo)。
代碼不僅是讀,還要理和試,有的人連 API 都沒有調(diào)用過,上來(lái)就看代碼,以為省了時(shí)間,實(shí)際是邁向自我摧殘。
對(duì)源碼進(jìn)行理和試的關(guān)鍵如下:
在 IDE 拿到調(diào)用棧
在 IDE 里讀。IDE 里可以方便跳轉(zhuǎn),查看定義,比起網(wǎng)頁(yè)上看效率高得多。
通過 IDE 工具,運(yùn)行 Example 程序進(jìn)行跟蹤調(diào)試,通過打斷點(diǎn)可以得到程序運(yùn)行的調(diào)用棧。盡可能編譯調(diào)試。能調(diào)試的代碼,幾乎沒有看不懂的。
把調(diào)用棧畫下來(lái)
把代碼的調(diào)用邏輯梳理出來(lái)之后,再通過畫圖工具,把代碼的圖畫出來(lái),可以畫:流程圖、類圖、調(diào)用圖、時(shí)序圖,根據(jù)實(shí)際情況選擇最有表現(xiàn)力的圖。
此外,平時(shí)多了解一些設(shè)計(jì)模式。這樣看到名字里有 Proxy、Builder、Factory 之類的,就心領(lǐng)神會(huì)了。
橫向分層,縱向分塊。代碼都是分模塊的,有的是 core,有的是 util,parser 之類的,要知道看的是哪一層,那一塊。
有的小項(xiàng)目分層不明顯,也不必強(qiáng)求。要看的不只是語(yǔ)法上的技巧,更重要的是設(shè)計(jì)上的思路和原理。
讀沒讀懂,最簡(jiǎn)單的標(biāo)準(zhǔn)是,假如給充足的時(shí)間,有沒有信心寫出一個(gè)差不多的東西來(lái)。
步驟總結(jié)
實(shí)際實(shí)踐操作中,完整執(zhí)行上面 5 個(gè)步驟花費(fèi)時(shí)間就長(zhǎng),通常情況下,前面 2 個(gè)步驟,在研究開源項(xiàng)目的時(shí)候都必不可少。
第 3 個(gè)步驟可以在工作中打算采用開源項(xiàng)目才實(shí)施,第 4 個(gè)步驟在有一定的時(shí)間和精力下靈活安排時(shí)間做。
與其每個(gè)項(xiàng)目走馬觀花去簡(jiǎn)單了解,不如集中火力把一個(gè)項(xiàng)目研究吃透,即使半年才吃透一個(gè),積累幾年之后數(shù)量還是很可觀的。
而且很多項(xiàng)目的思想是共同的,例如高可用方案、分布式協(xié)議等,研究透一個(gè),再研究類似項(xiàng)目,你會(huì)發(fā)現(xiàn)學(xué)習(xí)速度非???,因?yàn)橐呀?jīng)把共性的部分掌握了,只需要再研究新項(xiàng)目差異的部分。
同時(shí),在學(xué)習(xí)的過程中,需要不斷總結(jié),復(fù)盤,輸出學(xué)習(xí)筆記,一方面鍛煉邏輯思維能力;一方面有利于建立知識(shí)索引,過一段時(shí)間回顧的時(shí)候通過索引可以快速重新掌握知識(shí),不容易遺忘。
參考資料:
- 從0開始學(xué)架構(gòu) —— Alibaba 李運(yùn)華
- 如何高效的學(xué)習(xí)掌握新技術(shù)
- 學(xué)習(xí)開源項(xiàng)目的若干建議
- 我是如何閱讀開源項(xiàng)目的源代碼的
【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文作者和出處為51CTO.com】