自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

看大牛是如何閱讀JDK源碼,漲漲見(jiàn)識(shí)

開發(fā) 前端
為什么需要閱讀源碼?從實(shí)用性的角度來(lái)看,主要有三個(gè)目的:第一,解決手頭的新問(wèn)題或者新需求;第二,真正理解一部分理論的落地實(shí)現(xiàn);第三,應(yīng)對(duì)面試。

如何閱讀源碼,是每個(gè)程序員需要面臨的一項(xiàng)挑戰(zhàn)。

為什么需要閱讀源碼?從實(shí)用性的角度來(lái)看,主要有三個(gè)目的:第一,解決手頭的新問(wèn)題或者新需求;第二,真正理解一部分理論的落地實(shí)現(xiàn);第三,應(yīng)對(duì)面試。

[[273787]]

端正心態(tài)

在準(zhǔn)備投身到閱讀源碼的事業(yè)之前,首先需要端正一下心態(tài):

  1. 閱讀源碼是一場(chǎng)持久戰(zhàn),淺嘗輒止的話,頂多能寫幾篇水文,吸點(diǎn)粉糊弄下新手,對(duì)自身實(shí)力的提高沒(méi)有顯著作用。
  2. 閱讀源碼是錦上添花,不是雪中送炭。如果你進(jìn)入一個(gè)全新的領(lǐng)域,首要的任務(wù)是讀文檔而不是讀源碼。
  3. 閱讀源碼不一定會(huì)讓你成為大神。大神有兩個(gè)方向:專家型和應(yīng)用型,無(wú)論你的發(fā)展偏向哪一方,大量實(shí)操才是最根本的保障。
  4. 閱讀源碼需要理論先行。比如閱讀Socket通信的代碼卻不知道TCP/UDP協(xié)議,那就像是無(wú)頭蒼蠅在亂撞而已。

在此,我更推薦把源碼閱讀當(dāng)成是一項(xiàng)興趣愛(ài)好去做,就好比有的人通過(guò)打游戲看直播放松,有的人通過(guò)刷新聞追熱劇放松,還有的人通過(guò)找朋友吹牛逼放松...不同的人會(huì)選擇不同的勞逸結(jié)合方式,我更喜歡不寫代碼的時(shí)候,通過(guò)看別人的代碼來(lái)放松。

作為一名Javaer,朝夕相處的JDK自然是你遇到的第一處寶藏之地。從閱讀JDK代碼出發(fā),可以深入理解Java的一些新老特性,并學(xué)習(xí)部分設(shè)計(jì)模式的應(yīng)用,以及為將來(lái)閱讀更龐大的框架打下扎實(shí)的理論基礎(chǔ)與頑強(qiáng)的心理基礎(chǔ)。

選擇工具

工欲善其事必先利其器,起步之前,需要先選擇一款源碼閱讀工具。在工具的選擇上,同行的建議很多,我大致將其分為四類:

  • 文本型工具(該分類可能會(huì)有爭(zhēng)議,不過(guò)這不是重點(diǎn)...)
  • 例如Nodepad++、EditPlus、UEStudio、Sublime、VsCode、Vim等
  • 專家型工具
  • 例如Source Insight、Understand、OpenGrok(也是很多在線工具的基石)等
  • 在線工具(好幾個(gè)在線網(wǎng)站已經(jīng)掛了)
  • 例如openjdk、SearchCode等
  • IDE
  • 例如eclipse/myeclipse、IDEA等

從個(gè)人喜好講,我推薦IDEA和UEStudio(搭配UltraFinder)配合使用。

IDEA作為強(qiáng)大的Java生產(chǎn)工具,用來(lái)閱讀Java源碼顯然再合適不過(guò)。而UEStudio可以作為臨時(shí)查看Java文件或者查看JDK中部分C++代碼時(shí)的選擇,再搭配UltraFinder,實(shí)現(xiàn)跨文件的任意符號(hào)搜索,很實(shí)用。

關(guān)于閱讀環(huán)境的搭建,參見(jiàn)我在https://github.com/kangjianwei/LearningJDK中的描述即可。

閱讀順序

JDK的項(xiàng)目歷經(jīng)了十幾個(gè)大版本,算上開源社區(qū)的貢獻(xiàn),經(jīng)手的人可能也達(dá)到上千人。對(duì)于這種龐大的項(xiàng)目,一次性讀完肯定是不可能,必須先找到一個(gè)恰當(dāng)?shù)娜肟?,分模塊來(lái)一點(diǎn)點(diǎn)啃完。

可能的一種閱讀順序是:

  1. 基本類型的包裝類(Character放在最后)
  2. String、StringBuffer、StringBuilder、StringJoiner、StringTokenizer(補(bǔ)充正則表達(dá)式的知識(shí))
  3. CharacterIterator、StringCharacterIterator、CharsetProvider、CharsetEncoder、CharsetDecoder(較難)
  4. java.util.function下的函數(shù)表達(dá)式
  5. java.nio下的各種Buffer實(shí)現(xiàn)
  6. java.lang.ref和jdk.internal.ref下的各種引用:軟引用/弱引用/虛引用
  7. Unsafe的實(shí)現(xiàn)(JDK9之后有兩個(gè)同名類,一個(gè)引用了另一個(gè),建議放在一起閱讀)
  8. java.util.stream下的流式編程的實(shí)現(xiàn)(很難)
  9. Thread和ThreadLocal
  10. Math、Random、BigInteger、BigDecimal
  11. java.lang.reflect下反射的實(shí)現(xiàn)(先掌握J(rèn)DK 9之后引入的模塊系統(tǒng))
  12. ClassLoader的實(shí)現(xiàn)
  13. javax.lang.model下Java語(yǔ)言模型的實(shí)現(xiàn)(可以參考Java官方語(yǔ)法文檔)
  14. 注解(需要徹底掌握)
  15. Timer、ResourceBundle、Properties
  16. 時(shí)間日期類型(尤其是Java8新增的部分)
  17. java.lang.reflect.Proxy, JDK默認(rèn)的動(dòng)態(tài)代理
  18. java.util.concurrent并發(fā)包。先讀原子類,再讀鎖的實(shí)現(xiàn)類,最后閱讀那些并發(fā)工具的實(shí)現(xiàn)(很難)
  19. 集合框架,主要是三大類:List、Set、Map(先讀非線程安全的實(shí)現(xiàn),再讀線程安全的實(shí)現(xiàn))
  20. 網(wǎng)絡(luò)編程(主要閱讀Socket通信部分,后續(xù)可以閱讀HttpClient的實(shí)現(xiàn))
  21. IO/NIO/BIO(很難)
  22. Files、Path等文件操作工具類
  23. sql、xml處理類/接口
  24. ......

注意,這里說(shuō)的順序只是一個(gè)大致的方向,并不代表需要絕對(duì)按照這個(gè)名單來(lái)。

在閱讀某一個(gè)代碼時(shí),往往會(huì)牽涉到很多別的代碼,這個(gè)時(shí)候就會(huì)產(chǎn)生很多閱讀分支,分支的走向,并不在上述名單之內(nèi)。

善用技巧

閱讀代碼的技巧,因人而異。就像一千位讀者,就有一千部哈姆雷特,每個(gè)人對(duì)這件事的看法并不相同。在此,我只談下個(gè)人的一些經(jīng)驗(yàn)。

理論先行。閱讀某一個(gè)模塊時(shí),先搜索它的理論支撐,甚至可以先看別人的閱讀經(jīng)驗(yàn),有了一個(gè)大致的了輪廓之后,自己再去實(shí)踐。

必須試用。面對(duì)一個(gè)新的類,最好是先搜索一下它的基本用法,寫成一個(gè)小的示例,并從這個(gè)示例中用到的方法入手,去分析這個(gè)類。

巧用調(diào)試。關(guān)于IDEA中debug的使用方式,超出了本文的講述范圍。值的注意的是,除了需要學(xué)習(xí)常用的運(yùn)行時(shí)調(diào)試,還需要學(xué)習(xí)編譯時(shí)調(diào)試,這個(gè)在閱讀Java語(yǔ)言模型那塊的代碼時(shí)很有用。

分清主次。類與類之間呈網(wǎng)狀結(jié)構(gòu),在閱讀某個(gè)類的時(shí)候,不可避免地需要先去閱讀它引用的其他類。但是,如果它引用的類很復(fù)雜,則建議先放一放,做個(gè)標(biāo)記,回頭再讀。不過(guò),如果在閱讀多個(gè)類時(shí),其調(diào)用鏈最終都指向了同一個(gè)類,那么這個(gè)類就必須先拿下了。

業(yè)務(wù)為先。如果一個(gè)類太過(guò)龐大,則先將其中的方法按功能歸類,捋清大致的執(zhí)行流程,接下來(lái)再逐個(gè)功能地去攻克。

不求甚解。有些方法不需要搞清楚實(shí)現(xiàn)過(guò)程,只需要了解它的作用。比如一些特定領(lǐng)域的算法,對(duì)某些規(guī)則的解析等。

以點(diǎn)帶面。如果看懂了某一個(gè)方法,就要搜索該方法的所有應(yīng)用之處,驗(yàn)證自己的想法是否正確,并在應(yīng)用之處寫下注釋。哪怕理解的有誤差也沒(méi)事,回頭有新的理解再批量修改。對(duì)于字段的閱讀與理解,也建議采取此種方式。

勇于試錯(cuò)。很多接口方法的描述很抽象,在不同的實(shí)現(xiàn)類中意義相差很大。此時(shí)先弄懂一個(gè)類的實(shí)現(xiàn),然后拿著在這個(gè)類中的理解去解讀另外的實(shí)現(xiàn)類,如果解讀有誤,再逐漸修復(fù)。不要指望一次性就能正確地理解某個(gè)方法的作用,理解錯(cuò)誤,不妨礙繼續(xù)前進(jìn)。

留意注釋。大部分公開的方法上都有相應(yīng)的注釋,這是快速理解這個(gè)方法的重要途徑。注釋建議拿到谷歌翻譯下去閱讀,當(dāng)然,如果能流利閱讀英文就更好了。不過(guò),很多時(shí)候,注釋是令人沮喪的:看完之后完全不知道他在說(shuō)啥。這個(gè)也很正常,因?yàn)橛行┳⑨屩袝?huì)涉及到很多行業(yè)術(shù)語(yǔ)或通用解決方案的描述,如果之前沒(méi)有這些理論背景,大概率是讀不懂注釋的。原生注釋不是萬(wàn)能的,有時(shí)候甚至很雞肋:你不理解這個(gè)方法之前,也不理解他的注釋,等你理解了這個(gè)方法,才會(huì)覺(jué)得這些注釋說(shuō)得對(duì)。因此,我建議留意注釋,但別依賴注釋,有時(shí)候搜索其他網(wǎng)友的理解,再結(jié)合自己的閱讀,會(huì)來(lái)的更舒服一些。

勤做筆記。有一點(diǎn)靈感,就需要記錄一下,最好是直接記錄在源碼對(duì)應(yīng)的位置,而且能詳細(xì)就別簡(jiǎn)略,好記性終究抵不過(guò)爛筆頭。

循序漸進(jìn)。在頭腦清醒的時(shí)候,打開源碼讀一讀,感覺(jué)讀不懂的時(shí)候,就不要繼續(xù)死磕了,應(yīng)該放下干點(diǎn)別的,或者改天再讀。我讀完一個(gè)類,時(shí)間跨度可能會(huì)超過(guò)一個(gè)月,這是個(gè)不斷補(bǔ)充和完善的過(guò)程,不可能一次性就搞定。有時(shí)候眼看就讀懂了,但就是差一點(diǎn)點(diǎn)關(guān)鍵性的理解,這個(gè)時(shí)候人就容易急,急就容易燥,燥就容易慌,慌就容易亂,亂就容易砸鼠標(biāo)。所以,一旦覺(jué)得遇到瓶頸,那就及時(shí)終止吧,因?yàn)槟憧赡苄枰潘纱竽X,以及補(bǔ)充一些缺失的基礎(chǔ)理論了。

責(zé)任編輯:未麗燕 來(lái)源: 安卓巴士
相關(guān)推薦

2020-12-07 11:29:24

ReactVueVue3

2010-04-01 08:46:57

CentOS系統(tǒng)

2018-11-16 16:35:19

Java源碼編程語(yǔ)言

2021-08-02 09:50:47

Vetur源碼SMART

2017-04-13 19:26:21

2021-03-13 14:08:00

Hadoop 源碼HDFS

2021-12-20 07:58:59

GitHub源碼代碼

2013-12-24 10:05:04

memcached

2020-11-25 11:48:12

比特幣加密貨幣區(qū)塊鏈

2018-07-31 14:49:45

編程語(yǔ)言Java源碼

2020-04-23 16:16:42

物聯(lián)網(wǎng)機(jī)器人技術(shù)

2009-08-25 16:12:46

Visual C#制作

2023-02-06 21:58:23

2018-06-25 11:20:18

LinuxPython大數(shù)據(jù)

2022-08-26 13:41:19

代碼PythonJava

2022-10-08 08:01:17

Spring源碼服務(wù)

2012-02-14 14:05:59

JavaSpring

2017-04-05 16:40:45

2017-03-16 11:39:33

Openstack源碼姿勢(shì)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)