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