序言
零散地讀完《Effective Java》(中文版第二版),真心覺得這是一本經(jīng)典書籍?,F(xiàn)在想寫一下讀完這本書的整體收獲,而不是涉及到書中某一個(gè)具體的知識(shí)點(diǎn)。
收獲
在重點(diǎn)或疑問的地方,做出標(biāo)記和注釋
在讀《Effective Java》時(shí),對(duì)于前10條建議,我并沒有理解得很深刻,因?yàn)槲抑皇呛?jiǎn)單地拿筆在書上劃下重點(diǎn)的句子而已。我也感覺到了問題,后來(lái)在重點(diǎn)或疑問的地方,做出標(biāo)記和注釋,對(duì)于問題的理解提升很大。
雖然這是一個(gè)很愚蠢的問題——連小學(xué)一年級(jí)的學(xué)生都知道,但是我卻剛剛體會(huì)到這樣做的好處。比如我在看到第12條考慮實(shí)現(xiàn)Comparable接口一節(jié)時(shí),首先問了自己一個(gè)問題:如何使用Comparable接口?
后來(lái)發(fā)現(xiàn)Comparable接口采用了策略模式的設(shè)計(jì)模式,進(jìn)一步分析了策略模式。看到P54中間的一句話:依賴于比較關(guān)系的類包括有序集合類TreeSet和TreeMap,以及工具類Collection和Arrays,它們內(nèi)部包含有搜索和排序算法。我就問了自己幾個(gè)問題:這些工具類比如Arrays的sort,使用的是什么算法?Comparable接口是如何與Arrays的sort方法結(jié)合在一起,進(jìn)而通過傳入不同的Comparable接口,來(lái)實(shí)現(xiàn)Arrays的不同sort排序的?
之后我發(fā)現(xiàn)Arrays.sort會(huì)根據(jù)不同的類型,采取不同的排序方法。對(duì)于基本類型,會(huì)采用調(diào)優(yōu)的快速排序;對(duì)于對(duì)象類型,會(huì)采取改進(jìn)的歸并排序。然后我就會(huì)問自己:為什么對(duì)于基本類型和對(duì)象類型,要采取不同的排序方法呢?快速排序的調(diào)優(yōu),體現(xiàn)在哪里?歸并排序的改進(jìn),又體現(xiàn)在哪里?在查看源代碼的基礎(chǔ)上,我又發(fā)現(xiàn)JDK 7采用了一種Dual-Pivot Quicksort的快排方法,就會(huì)思考這個(gè)算法好在哪里?
在查看源代碼的過程中,我發(fā)現(xiàn)注釋中有個(gè)API的設(shè)計(jì)者是Josh Bloch,我就Google了一下。我才注意到他就是這本書的作者?。∥也胖繨ava的集合框架就是他設(shè)計(jì)的,才知道譯者序里面的介紹,都是關(guān)于他的……我看書很少注意作者,這個(gè)習(xí)慣可不好。進(jìn)一步Google,我發(fā)現(xiàn)了他的Twitter,我是不是應(yīng)該關(guān)注他?那還有哪些Java領(lǐng)域和計(jì)算機(jī)領(lǐng)域的國(guó)外、國(guó)內(nèi)牛人,我應(yīng)該關(guān)注一下?如果在使用Java的過程中,連它的開發(fā)者及演變過程都不知道……通過問自己幾個(gè)問題,我一下子就打開了一個(gè)全新的世界+_+
深入思考
忘記從哪里看見過一句話,大意是:只有了解全部的真相,才能獲得全部的自由——編程領(lǐng)域更是如此。就好比我讀《Effective Java》,如果只是簡(jiǎn)單閱讀第12條考慮實(shí)現(xiàn)Comparable接口一節(jié),想必幾分鐘就草草略過了。但是我獲得了什么?是能夠和別人吹噓說:我把《Effective Java》看了3遍,《Java編程思想》看了5遍?即使看10遍又有什么意義呢?如果我不花費(fèi)時(shí)間,問自己幾個(gè)問題,親自去研究一下Comparable接口,那么我不會(huì)知道JDK底層的實(shí)現(xiàn)細(xì)節(jié),我并沒有了解全部的真相,每次使用時(shí)都會(huì)有個(gè)疑問:咦,Arrays.sort是怎么通過對(duì)象的Comparable接口,實(shí)現(xiàn)不同的排序的?如果不去解決自己的疑惑,那么問題只會(huì)越來(lái)越多、越來(lái)越嚴(yán)重。
套用M·斯科特·派克《少有人走的路——心智成熟的旅程》中的一句話(大意):逃避問題所帶來(lái)的痛苦,甚至比問題本身所帶來(lái)的痛苦,更為嚴(yán)重;問題永遠(yuǎn)不會(huì)自動(dòng)消失,直到我們?nèi)ブ泵鎲栴}、解決問題。我可能是有些過于類比了,但是如果關(guān)于編程的疑問,我們不去自己解決并親自弄明白,那么我們就是在逃避問題。
深入思考具有許多好處(自己淺顯的總結(jié),歡迎大家留言討論):
- 不會(huì)每次遇到問題,就想一次:這個(gè)功能是怎么實(shí)現(xiàn)的?這次沒時(shí)間,還是以后再研究吧!
- 大腦的容量是有限的,這些問題只有在真正解決之后,才不會(huì)占用大腦的容量。《Head First》系列在引言部分,提出的第一條建議就是:
慢一點(diǎn),你理解的越多,需要記住的就越少。 - 在我們完全理解一個(gè)問題后,下次再遇到同樣的問題,只會(huì)更加深對(duì)于這個(gè)問題的思考,而不是那個(gè)老問題(這個(gè)功能是怎么實(shí)現(xiàn)的)。
- 增加自信,獲得自由。
深入思考并不會(huì)占用太多時(shí)間,我們離大部分真相都只有一步的距離。而且重要的是思考的深度,而且這樣思考能夠帶來(lái)很大的滿足感。至少我在讀《Effective Java》時(shí),就是這個(gè)感覺——一點(diǎn)也不覺得累,通過不斷問自己?jiǎn)栴},獲得了很多很多知識(shí),并且一直處于興奮狀態(tài)。
優(yōu)秀的框架(習(xí)慣),是指在無(wú)意識(shí)中也不會(huì)犯錯(cuò)
在第45條將局部變量的作用域最小化一節(jié)中(中文第二版P182),作者為了說明為什么將作用域最小化,for循環(huán)比while循環(huán)好時(shí),列舉出了一個(gè)代碼片段,包含一個(gè)“剪切——粘貼”錯(cuò)誤:本來(lái)是要初始化一個(gè)新的循環(huán)變量i2,卻使用了舊的循環(huán)變量i。代碼仍然能夠通過編譯,運(yùn)行的時(shí)候也不會(huì)拋出異常,但是實(shí)現(xiàn)的功能卻是錯(cuò)誤的。如果使用了for-each形式,就會(huì)從根本上避免這種無(wú)意識(shí)的錯(cuò)誤。
作者是Java API的設(shè)計(jì)者,考慮得不僅僅是如何才能夠使Java API實(shí)現(xiàn)效率更高,還包括如何讓客戶端更具靈活性、如何從架構(gòu)的設(shè)計(jì)上,減少客戶端犯錯(cuò)誤的機(jī)會(huì)。這完完全全也適合每一個(gè)開發(fā)者。進(jìn)一步思考,在現(xiàn)實(shí)中也是一樣?。∥以?jīng)看過一篇文章,討論如何通過優(yōu)秀的習(xí)慣,減少無(wú)意識(shí)中犯錯(cuò)誤的機(jī)會(huì)。
最重要的是思想,而不是實(shí)現(xiàn)細(xì)節(jié)
細(xì)節(jié)很重要,但是書籍、框架乃至Java的設(shè)計(jì)思想,才是最重要的(所以Bruce Eckel的《Thinking in Java》才會(huì)翻譯成《Java編程思想》?)。在閱讀源碼時(shí),不僅僅是語(yǔ)義上的理解,考慮一下為什么要這么實(shí)現(xiàn)這個(gè)功能?這樣實(shí)現(xiàn)有什么好處?它的適用場(chǎng)景有哪些?是否還能夠改進(jìn)?哪些思想我能夠借鑒到平時(shí)的工作和生活中?
李笑來(lái)老師的一篇文章中有這樣兩段話:
他們?cè)谧x書的時(shí)候,不僅僅是文字以及文字所闡述的道理,更多注意到的是作者的思考方式。作者的“思考方式”與自己的“思考方式”有什么不同?如果作者的“思考方式”更好,自己應(yīng)該如何調(diào)整?
一本概率論讀完,大多數(shù)人就是考個(gè)試也不一定及格,而另外的極少數(shù)人卻成了科學(xué)家——因?yàn)樗麄兏牧剂俗约旱乃伎挤绞?,從此可以“像一個(gè)科學(xué)家一樣思考”……
如果我要成為Java專家,我就應(yīng)該去閱讀JDK源碼,因?yàn)檫@是Java專家及天才思想的結(jié)晶。我更應(yīng)該去思考:他們?yōu)槭裁催@樣設(shè)計(jì)?他們的設(shè)計(jì)思想是什么?要像一個(gè)Java專家一樣思考~
抓住思想的好處:
- 提綱挈領(lǐng),能夠忽略不重要的細(xì)節(jié),將注意力集中在重要的地方(所謂的
二八法則)。 - 閱讀速度的提升??梢钥焖俾赃^不重要的細(xì)節(jié),我的閱讀效率大大提升。
- 能夠
看清全局,對(duì)整體有清晰的把握。 - 可以改良自己的思考方式,使得我們
像一個(gè)科學(xué)家一樣思考、像一個(gè)Java專家一樣思考。
總結(jié)
我在讀完《Effective Java》后,發(fā)覺《Java編程思想》這本書需要重新讀一遍了,因?yàn)橐郧爸皇呛?jiǎn)單地劃了一下重點(diǎn)句子而已。當(dāng)然,除了一個(gè)人潛心研讀之外,還需要多和他人討論和總結(jié)。
我是Yano,帝都霧霾的人肉吸塵器。
如果讀完有些收獲,記得點(diǎn)贊和關(guān)注哦O(∩_∩)O哈哈