[TOC]
<!-- Appendix: Becoming a Programmer -->
# 附錄:成為一名程序員
>我分別于2003,2006,2007和2009年撰寫的博客文章混搭
<!-- How I Got Started in Programming -->
## 如何開始
這是一條相當漫長和曲折的道路。我在高一學代數時(1971年),有個非常古怪的老師有一臺計算機,還弄到了一臺配有一個300波特的音頻電話耦合器的ASR-33電傳打字機,我學會了如何執行命令并得到響應,以及一個可以在高中區使用的HP-1000計算機上的帳戶。我們能夠創建和運行BASIC程序并將它們保存在打孔磁帶上。我對此非常著迷,所以盡可能地把它帶回家后在晚上寫程序。我寫了一個賽馬模擬游戲--HOSRAC.BAS,用星號來代表馬的移動,由于是在紙上打印輸出,所以需要一點想象力。
我的朋友丹尼爾(就是設計我的書封面的人)有一個兄弟,他有段時間通過向酒吧和餐館提供彈球機來賺錢。他有一臺投幣式街機(老虎機),最早的《乓》游戲之一,我對此全然不知,到現在我還忍受不了這東西(現在我幾乎不玩電腦游戲,這樣看來我可能是個沒有幽默的人,但似乎編程比玩電腦游戲更有趣、更具挑戰性。)
后來我在高中參與了攝影和新聞工作,在大學的第一年就主修新聞學。我覺得自己已經從學校學到了足夠多的東西,又轉修了物理學。后來我在加州大學歐文分校完成了物理學位,如果我當時選擇了一個特定的工程領域,修了足夠的工程課就能拿到雙專業,但我試圖走得更遠一些,所以最后我獲得的本科學位是 "應用物理"。作為一名本科生,我多多少少學習了一些可以自娛自樂,但又沒有任何深度的計算機編程課程。我個人認為在這些課程細細熏陶下,幫我打下了一定的基礎,但事實我理解的這些東西沒有任何深度。我不知道計算機、編譯器或解釋器有什么區別(只是對編譯器和解釋器一點點的理解)。對我來說計算機是絕對可靠的,而且我從來沒有想過在程序語言和操作系統中會有出現錯誤的可能。
后來我去了在加州州立理工大學攻讀研究生,主要有三點原因
1. 我真的非常喜歡物理學這個領域
2. 他們接受了我,甚至給了我一份教學工作和獎學金
3. 出乎意料的是他們給我的工作時間不止一個夏天
而我完全沒做好上班的準備。
作為一名物理專業的學生,我學習的是太陽能發電系統,當時太陽能發電系統很大 (如果你的房子上裝了太陽能或生意上是關于太陽能系統,加州就會給予稅收抵免,因此也興起很多生意),加州理工大學也承諾會在工程系開設相應的課程。然而因為學校沒有提供必要的課程,要想獲得在太陽能工程的學位得花好幾年時間。所以我學習了研究生其他的工程課,包括介紹機械,太陽能,電氣和電子工程。我上的課是非電氣工程專業的電氣工程導論。最常見的研究生工程課程是計算機工程專業,所以最后我拿了那個學位。我還上了藝術課,幾門舞蹈課,還有一些計算機科學課程 (Pascal和數據結構),在計算機工程中,我終于弄清楚了處理器的工作流程,從那以后我一直帶著一個處理器在身上。這些就是我學的計算機基礎知識。
剛開始工作的時候,憑借著一堆硬件和相對簡單低水平的編程,做了一名計算機工程師。因為C語言似乎是理想的嵌入式系統語言,于是我開始自學,并慢慢開始了解更多關于編程語言的東西。我們在這家公司從源代碼構建編譯器,這讓我大開眼界。 (想象一下一個編譯器只是另一個軟件的一部分!)
當我去華盛頓大學海洋學院為Tom Keffer后來創建了“瘋狗浪”)工作時,我們決定使用C++。我只有一本Stroustrup寫的非初學者書可以參考,最終不得不通過檢查C++預處理器生成的中間C代碼來了解語言的功能。這個過程非常痛苦,但學習的效果很好。從那以后我就用相同的方式學習,因為它讓我學習了如何剖析一種語言,并看到它本質的能力,與此同時開始有了批判性思維。
我并沒有理解清楚所有的概念。只是在之后的日子里不斷反復,我所知道的一切需要時間才能消化吸收。如果我現在能很容易地理解一個新概念,那只是因為它是我已經知道的積累概念的一個變種。在加州理工大學招收非計算機本科學歷的計算機科學研究生項目中,學生們曾經說他們花了一年的時間才弄清楚他們對計算機的困惑(他們正在沉浸程序之中)。當人們學習計算機時,他們往往會對自己抱有不切實際的期望,通常是他們聽說學計算機編程的好處,就希望在幾周內找到一份高薪的工作。但是,最好的學習過程是先對計算機感興趣,隨著時間的推移,學習的越來越多,自然的就開始自學。
這些就是我主要做的事,盡管我通過學計算機工程有還算扎實的基礎,但我沒上過編程課,而是通過自學。在此期間我也在不斷地學習新事物,在這個行業里,不斷學習是非常重要的一部分。
<!-- A Career in Computing -->
## 碼農生涯
我會定期收到有關職業建議的請求,所以我嘗試在這里回答一下這個問題。
人們提出的問題通常是錯誤的問題:“我應該學習 C++ 還是 Java ?”在本文中,我將嘗試闡述我對選擇計算機職業所涉及的真正問題的看法。
請注意,我在這里并不是和那些已經知道自己使命的人聊(譯者注:指計劃成為程序員或者已經從業的程序員,暗指這里是講給外行的小白的)。因為無論別人怎么說,你都要去做,因為它已經滲入你的血液,并且你將無法擺脫它。你已經知道答案了:你當然會學到 C++ ,Java ,shell 腳本,Python 和許多其他語言和技術。即使你只有14歲,你也已經知道其中幾種語言。
問我這個問題的人可能來自另一職業。也許他們來自 Web 開發等領域,他們已經發現 HTML 只是一種類似編程,他們想嘗試構建更實質的內容。但是,我特別希望,如果你提出這個問題,你就已經意識到,要在計算機領域取得成功,你必須教自己如何學習,并且永不停止學習。
隨著我做的越來越多,在我看來,軟件越發比其他任何東西都更像寫作。而且我們還沒有弄清怎樣成為一個好的作家,我們只知道何時我們喜歡別人寫的東西。這不是像一些工程那樣,我們要做的只是將某些東西放到一端,然后轉動曲柄。誘人的是將軟件視為確定性的,這就是我們想要的,這就是我們不斷推出工具來幫助我們實現所需行為的原因。但是我的經驗不斷表明事實是相反的:它更多地是關于人而不是過程,并且它在確定性機器上運行的事實變得越來越沒有影響力(指運行環境受機器影響,與機器相關這個事實),就像海森堡原理(不確定性原理:不可能同時知道一個粒子的位置和它的速度)不會在人類規模上影響事物一樣。
在我青年時期,父親是建造民居的,我偶爾會為他工作,大部分時間都從事艱苦的工作,有時還得懸掛石膏板。他和他的木匠會告訴我說,他們是為了我才把這些工作交給了我 —— 為了不讓我從事這項工作。這確實是有效的。
因此,我也可以用比喻說,建造軟件就像蓋房子一樣。我們并不是指每個在房屋上工作的人都一樣。有混凝土泥瓦匠,屋頂工,水管工,電工,石膏板工人,抹灰工,瓷磚鋪砌工,普通勞工,粗木匠,精整木匠,當然還有總承包商。這些中的每一個都需要一套不同的技能,這需要花費不同的時間和精力 房屋建造也受制于繁榮和蕭條的周期,例如編程。為了快速起步,你可能需要當普通勞工或石膏板工人工作,在那里你可以在沒有太多學習曲線的情況下開始獲得報酬。只要需求旺盛,你就可以穩定工作,而且如果沒有足夠的人來工作,你的薪水甚至可能會上漲。但是一旦經濟低迷,木匠甚至總承包商就可以自己將石膏板掛起來。
當 Internet 剛興起時,你所要做的就是花一些時間學習 HTML ,就可以找到一份工作并賺到很多錢。但是,當情況惡化時,你很快就會發現需要的技能層次結構很深,HTML 程序員(例如勞工和石膏板工)排在第一位,而高技能的碼農和木匠則被保留。
我想在這里說的是:除非你準備致力于終身學習,否則請不要從事這項業務。有時,編程似乎是一份報酬豐厚,值得信賴的工作,但確保這一點的唯一方法是,始終使自己變得更有價值。
當然,也可以找到例外。總會有一些人只學習一種語言,并且足夠精通,甚至足夠聰明,那么可以在不用多學很多其他知識的情況下繼續工作。但是他們靠運氣生存,最終很脆弱。為了減少自身的脆弱性,必須通過閱讀,參加用戶組,會議和研討會來不斷提高自己的能力。你在該領域的走得越深,你的價值就越大,這意味著你的工作前景更穩定,并且可以獲得更高的薪水。
另一種方法是從總體上看待該領域,并找到一個你能成為專家的點。例如,我的兄弟對軟件感興趣,并且涉足軟件,但是他的業務是安裝計算機,維修計算機和升級計算機。他一直都很細致,因此,當他安裝或修理計算機時,你會知道計算機狀態良好。不僅是軟件,而且一直到電纜,電纜都整齊地捆扎在一起,并且不成束。他的工作多到做不完,而且他從不關心網絡泡沫破滅。毋庸置疑,他是不可能失業的。
我在大學待了很長時間,并以各種方式設法度過了難關。我甚至開始在加州大學洛杉磯分校攻讀博士學位。這里的課程很短,我欣慰地說是因為我不再愛上大學了,而我在大學待了這么長時間的原因是因為我非常喜歡。但是我喜歡的通常是跑偏的東西。例如藝術,舞蹈課程,在大學報社工作,以及我參加的少數計算機編程課程(由于我是物理本科生和計算機工程專業的研究生,所以也算跑偏)。盡管我在學業上還算是出色的(具有諷刺意味的是,當時許多不接受我作為學生的大學現在都在課程中使用我的書),但我確實很享受大學生的生活,并且完成了博士學位。我可能會走上簡單的道路,最終成為一名教授。
但是事實證明,我從大學獲得的最大價值一部分來自那些跑偏的課程,這些課程使我的思維超出了“我們已經知道的東西”。我認為在計算機領域尤其如此,因為你總是通過編程來實現其他目標,而你對該目標越了解,你的表現就會越好(我學習了一些歐洲研究生課程,這些課程要求結合其他一些專業研究計算,通過解決這個領域相關的問題,你就會形成一種新的理論體系并可以將它用在別處)。
我還認為,不僅編程,多了解一些其它的知識,還可以大大提高你的解決問題的能力(就像了解一種以上的編程語言可以極大地提高你的編程能力一樣)。在很多情況下,我遇到過僅接受過計算機科學訓練的人,他們的思維似乎比其他背景(例如數學或物理學)的人更受限制,但其實這些人(數學或物理學領域的人)才更需要嚴格的思維。
在我組織的一次會議上,主題之一是為理想的求職者提供一系列功能:
- 將學習作為一種生活方式。例如,學習一種以上的語言;沒有什么比學習另一種語言更能吸引你的眼球。
- 知道在哪里以及如何獲得新知識。
- 研究現有技術。
- 我們是工具使用者,即要善于利用工具。
- 學習做最簡單的事情。
- 了解業務(閱讀雜志。從 *fast company*(國外一家商業雜志)開始,該公司的文章非常簡短有趣。然后你就會知道是否要閱讀其他的)
- 應對錯誤負責。 “我用著沒事”是不可接受的策略。查找自己的錯誤。
- 成為領導者:那些溝通和鼓舞別人的人。
- 你在為誰服務?
- 沒有正確的答案……但總是更好的方法。展示和討論你的代碼,不要有情感上的依戀。你不是你的代碼。
- 這是通往完美的漸進旅程。
承擔一切可能的風險,最好的風險是那些可怕的風險,但是在嘗試時你會比想象中的更加活躍。最好不要刻意去預測某個特定的結果,因為如果你過于重視某個結果,就會經常錯過真正的可能性。應該“讓我們做一點實驗,看看會把我們帶到哪里”。這些實驗是我最好的冒險。
有些人對這個答案感到失望,然后回答“是的,這都是非常有趣和有用的。但是實際上,我應該學習什么? C++ 還是 Java ?”,以防這些問題,我將在這里重復一遍:我知道似乎所有的 1 和 0 都應該使一切具有確定性因此此類問題應該有一個簡單的答案,但事實并非如此。這與做出選擇并完成選擇無關,這是有關持續學習和有時需要大膽的選擇。相信我,這樣你的生活會更加令人興奮。
### 延伸閱讀
* [Teach Yourself Programming In Ten Years](http://norvig.com/21-days.html), by Peter Norvig.
* [How To Be A Programmer](http://samizdat.mines.edu/howto/HowToBeAProgrammer.html), by Robert Read.
* A [speech by Steve Jobs](http://news.stanford.edu/news/2005/june15/jobs-061505.html) to inspire a group of graduating college students.
* Kathy Sierra: [Does College Matter](https://headrush.typepad.com/creating_passionate_users/2005/07/does_college_ma.html)?
* Paul Graham [on College](http://www.paulgraham.com/college.html).
* Joel Spolsky: [Advice for Computer Science College Students](https://www.joelonsoftware.com/2005/01/02/advice-for-computer-science-college-students/).
* James Shore: [Five Design Skills Every Programmer Should Have](https://www.jamesshore.com/Blog/Five-Design-Skills.html).
* Steve Yegge: [The Truth About Interviewing](http://steve-yegge.blogspot.com/2006/03/truth-about-interviewing.html).
<!-- The Mythical 5% -->
## 百分之五的神話
<!-- Writing Software Is Like … Writing -->
## 重在動手
<!-- Programming as Typing -->
## 像打字般編程
<!-- Do What You Love -->
## 做你喜歡的事
*“1960年,一位研究人員對1500名商學院學生進行了訪談,并將他們分為兩類:那些為了錢財來這里上學的人,1245人,以及那些打算利用學位做他們非常關心的事情的人,255人。二十年后,研究人員再次訪談了這些畢業生,發現其中有101位百萬富翁,除了其中一位,所有百萬富翁都來自追求他們喜歡做的事的那255人!”*
“現在你可能覺得你對巴洛克時期的冰島詩歌,或者蝴蝶收集,或者高爾夫,抑或是對社會正義的熱情,會因為要養家糊口而讓你和你喜歡做的事分道揚鑣,并非一定要如此。弗拉基米爾·納博科夫(Vladimir Nabokov)是本世紀最偉大的小說家之一,他對蝴蝶收藏的熱情遠遠超過寫作。事實上,他的第一個大學教學工作是關于鱗翅類昆蟲。在過去40年里,對40萬美國群眾的研究表明,即使是部分的、零散的追求培養你的激情,也可以幫助你充分利用你目前的能力,激勵你培養新的能力。”--摘自《The Other 90%》 Robert K.Cooper
當然你可以看Po Bronson寫的《 What Should I Do With My Life?》這本書,對這些想法進行更多的探索。
<!-- 分頁 -->
<div style="page-break-after: always;"></div>
- 譯者的話
- 前言
- 簡介
- 第一章 對象的概念
- 抽象
- 接口
- 服務提供
- 封裝
- 復用
- 繼承
- "是一個"與"像是一個"的關系
- 多態
- 單繼承結構
- 集合
- 對象創建與生命周期
- 異常處理
- 本章小結
- 第二章 安裝Java和本書用例
- 編輯器
- Shell
- Java安裝
- 校驗安裝
- 安裝和運行代碼示例
- 第三章 萬物皆對象
- 對象操縱
- 對象創建
- 數據存儲
- 基本類型的存儲
- 高精度數值
- 數組的存儲
- 代碼注釋
- 對象清理
- 作用域
- 對象作用域
- 類的創建
- 類型
- 字段
- 基本類型默認值
- 方法使用
- 返回類型
- 參數列表
- 程序編寫
- 命名可見性
- 使用其他組件
- static關鍵字
- 小試牛刀
- 編譯和運行
- 編碼風格
- 本章小結
- 第四章 運算符
- 開始使用
- 優先級
- 賦值
- 方法調用中的別名現象
- 算術運算符
- 一元加減運算符
- 遞增和遞減
- 關系運算符
- 測試對象等價
- 邏輯運算符
- 短路
- 字面值常量
- 下劃線
- 指數計數法
- 位運算符
- 移位運算符
- 三元運算符
- 字符串運算符
- 常見陷阱
- 類型轉換
- 截斷和舍入
- 類型提升
- Java沒有sizeof
- 運算符總結
- 本章小結
- 第五章 控制流
- true和false
- if-else
- 迭代語句
- while
- do-while
- for
- 逗號操作符
- for-in 語法
- return
- break 和 continue
- 臭名昭著的 goto
- switch
- switch 字符串
- 本章小結
- 第六章 初始化和清理
- 利用構造器保證初始化
- 方法重載
- 區分重載方法
- 重載與基本類型
- 返回值的重載
- 無參構造器
- this關鍵字
- 在構造器中調用構造器
- static 的含義
- 垃圾回收器
- finalize()的用途
- 你必須實施清理
- 終結條件
- 垃圾回收器如何工作
- 成員初始化
- 指定初始化
- 構造器初始化
- 初始化的順序
- 靜態數據的初始化
- 顯式的靜態初始化
- 非靜態實例初始化
- 數組初始化
- 動態數組創建
- 可變參數列表
- 枚舉類型
- 本章小結
- 第七章 封裝
- 包的概念
- 代碼組織
- 創建獨一無二的包名
- 沖突
- 定制工具庫
- 使用 import 改變行為
- 使用包的忠告
- 訪問權限修飾符
- 包訪問權限
- public: 接口訪問權限
- 默認包
- private: 你無法訪問
- protected: 繼承訪問權限
- 包訪問權限 Vs Public 構造器
- 接口和實現
- 類訪問權限
- 本章小結
- 第八章 復用
- 組合語法
- 繼承語法
- 初始化基類
- 帶參數的構造函數
- 委托
- 結合組合與繼承
- 保證適當的清理
- 名稱隱藏
- 組合與繼承的選擇
- protected
- 向上轉型
- 再論組合和繼承
- final關鍵字
- final 數據
- 空白 final
- final 參數
- final 方法
- final 和 private
- final 類
- final 忠告
- 類初始化和加載
- 繼承和初始化
- 本章小結
- 第九章 多態
- 向上轉型回顧
- 忘掉對象類型
- 轉機
- 方法調用綁定
- 產生正確的行為
- 可擴展性
- 陷阱:“重寫”私有方法
- 陷阱:屬性與靜態方法
- 構造器和多態
- 構造器調用順序
- 繼承和清理
- 構造器內部多態方法的行為
- 協變返回類型
- 使用繼承設計
- 替代 vs 擴展
- 向下轉型與運行時類型信息
- 本章小結
- 第十章 接口
- 抽象類和方法
- 接口創建
- 默認方法
- 多繼承
- 接口中的靜態方法
- Instrument 作為接口
- 抽象類和接口
- 完全解耦
- 多接口結合
- 使用繼承擴展接口
- 結合接口時的命名沖突
- 接口適配
- 接口字段
- 初始化接口中的字段
- 接口嵌套
- 接口和工廠方法模式
- 本章小結
- 第十一章 內部類
- 創建內部類
- 鏈接外部類
- 使用 .this 和 .new
- 內部類與向上轉型
- 內部類方法和作用域
- 匿名內部類
- 嵌套類
- 接口內部的類
- 從多層嵌套類中訪問外部類的成員
- 為什么需要內部類
- 閉包與回調
- 內部類與控制框架
- 繼承內部類
- 內部類可以被覆蓋么?
- 局部內部類
- 內部類標識符
- 本章小結
- 第十二章 集合
- 泛型和類型安全的集合
- 基本概念
- 添加元素組
- 集合的打印
- 迭代器Iterators
- ListIterator
- 鏈表LinkedList
- 堆棧Stack
- 集合Set
- 映射Map
- 隊列Queue
- 優先級隊列PriorityQueue
- 集合與迭代器
- for-in和迭代器
- 適配器方法慣用法
- 本章小結
- 簡單集合分類
- 第十三章 函數式編程
- 新舊對比
- Lambda表達式
- 遞歸
- 方法引用
- Runnable接口
- 未綁定的方法引用
- 構造函數引用
- 函數式接口
- 多參數函數式接口
- 缺少基本類型的函數
- 高階函數
- 閉包
- 作為閉包的內部類
- 函數組合
- 柯里化和部分求值
- 純函數式編程
- 本章小結
- 第十四章 流式編程
- 流支持
- 流創建
- 隨機數流
- int 類型的范圍
- generate()
- iterate()
- 流的建造者模式
- Arrays
- 正則表達式
- 中間操作
- 跟蹤和調試
- 流元素排序
- 移除元素
- 應用函數到元素
- 在map()中組合流
- Optional類
- 便利函數
- 創建 Optional
- Optional 對象操作
- Optional 流
- 終端操作
- 數組
- 集合
- 組合
- 匹配
- 查找
- 信息
- 數字流信息
- 本章小結
- 第十五章 異常
- 異常概念
- 基本異常
- 異常參數
- 異常捕獲
- try 語句塊
- 異常處理程序
- 終止與恢復
- 自定義異常
- 異常與記錄日志
- 異常聲明
- 捕獲所有異常
- 多重捕獲
- 棧軌跡
- 重新拋出異常
- 精準的重新拋出異常
- 異常鏈
- Java 標準異常
- 特例:RuntimeException
- 使用 finally 進行清理
- finally 用來做什么?
- 在 return 中使用 finally
- 缺憾:異常丟失
- 異常限制
- 構造器
- Try-With-Resources 用法
- 揭示細節
- 異常匹配
- 其他可選方式
- 歷史
- 觀點
- 把異常傳遞給控制臺
- 把“被檢查的異常”轉換為“不檢查的異常”
- 異常指南
- 本章小結
- 后記:Exception Bizarro World
- 第十六章 代碼校驗
- 測試
- 如果沒有測試過,它就是不能工作的
- 單元測試
- JUnit
- 測試覆蓋率的幻覺
- 前置條件
- 斷言(Assertions)
- Java 斷言語法
- Guava斷言
- 使用斷言進行契約式設計
- 檢查指令
- 前置條件
- 后置條件
- 不變性
- 放松 DbC 檢查或非嚴格的 DbC
- DbC + 單元測試
- 使用Guava前置條件
- 測試驅動開發
- 測試驅動 vs. 測試優先
- 日志
- 日志會給出正在運行的程序的各種信息
- 日志等級
- 調試
- 使用 JDB 調試
- 圖形化調試器
- 基準測試
- 微基準測試
- JMH 的引入
- 剖析和優化
- 優化準則
- 風格檢測
- 靜態錯誤分析
- 代碼重審
- 結對編程
- 重構
- 重構基石
- 持續集成
- 本章小結
- 第十七章 文件
- 文件和目錄路徑
- 選取路徑部分片段
- 路徑分析
- Paths的增減修改
- 目錄
- 文件系統
- 路徑監聽
- 文件查找
- 文件讀寫
- 本章小結
- 第十八章 字符串
- 字符串的不可變
- +的重載與StringBuilder
- 意外遞歸
- 字符串操作
- 格式化輸出
- printf()
- System.out.format()
- Formatter類
- 格式化修飾符
- Formatter轉換
- String.format()
- 一個十六進制轉儲(dump)工具
- 正則表達式
- 基礎
- 創建正則表達式
- 量詞
- CharSequence
- Pattern和Matcher
- find()
- 組(Groups)
- start()和end()
- Pattern標記
- split()
- 替換操作
- 正則表達式與 Java I/O
- 掃描輸入
- Scanner分隔符
- 用正則表達式掃描
- StringTokenizer類
- 本章小結
- 第十九章 類型信息
- 為什么需要 RTTI
- Class對象
- 類字面常量
- 泛化的Class引用
- cast()方法
- 類型轉換檢測
- 使用類字面量
- 遞歸計數
- 一個動態instanceof函數
- 注冊工廠
- 類的等價比較
- 反射:運行時類信息
- 類方法提取器
- 動態代理
- Optional類
- 標記接口
- Mock 對象和樁
- 接口和類型
- 本章小結
- 第二十章 泛型
- 簡單泛型
- 泛型接口
- 泛型方法
- 復雜模型構建
- 泛型擦除
- 補償擦除
- 邊界
- 通配符
- 問題
- 自限定的類型
- 動態類型安全
- 泛型異常
- 混型
- 潛在類型機制
- 對缺乏潛在類型機制的補償
- Java8 中的輔助潛在類型
- 總結:類型轉換真的如此之糟嗎?
- 進階閱讀
- 第二十一章 數組
- 數組特性
- 一等對象
- 返回數組
- 多維數組
- 泛型數組
- Arrays的fill方法
- Arrays的setAll方法
- 增量生成
- 隨機生成
- 泛型和基本數組
- 數組元素修改
- 數組并行
- Arrays工具類
- 數組比較
- 數組拷貝
- 流和數組
- 數組排序
- Arrays.sort()的使用
- 并行排序
- binarySearch二分查找
- parallelPrefix并行前綴
- 本章小結
- 第二十二章 枚舉
- 基本 enum 特性
- 將靜態類型導入用于 enum
- 方法添加
- 覆蓋 enum 的方法
- switch 語句中的 enum
- values 方法的神秘之處
- 實現而非繼承
- 隨機選擇
- 使用接口組織枚舉
- 使用 EnumSet 替代 Flags
- 使用 EnumMap
- 常量特定方法
- 使用 enum 的職責鏈
- 使用 enum 的狀態機
- 多路分發
- 使用 enum 分發
- 使用常量相關的方法
- 使用 EnumMap 進行分發
- 使用二維數組
- 本章小結
- 第二十三章 注解
- 基本語法
- 定義注解
- 元注解
- 編寫注解處理器
- 注解元素
- 默認值限制
- 替代方案
- 注解不支持繼承
- 實現處理器
- 使用javac處理注解
- 最簡單的處理器
- 更復雜的處理器
- 基于注解的單元測試
- 在 @Unit 中使用泛型
- 實現 @Unit
- 本章小結
- 第二十四章 并發編程
- 術語問題
- 并發的新定義
- 并發的超能力
- 并發為速度而生
- 四句格言
- 1.不要這樣做
- 2.沒有什么是真的,一切可能都有問題
- 3.它起作用,并不意味著它沒有問題
- 4.你必須仍然理解
- 殘酷的真相
- 本章其余部分
- 并行流
- 創建和運行任務
- 終止耗時任務
- CompletableFuture類
- 基本用法
- 結合 CompletableFuture
- 模擬
- 異常
- 流異常(Stream Exception)
- 檢查性異常
- 死鎖
- 構造方法非線程安全
- 復雜性和代價
- 本章小結
- 缺點
- 共享內存陷阱
- This Albatross is Big
- 其他類庫
- 考慮為并發設計的語言
- 拓展閱讀
- 第二十五章 設計模式
- 概念
- 單例模式
- 模式分類
- 構建應用程序框架
- 面向實現
- 工廠模式
- 動態工廠
- 多態工廠
- 抽象工廠
- 函數對象
- 命令模式
- 策略模式
- 責任鏈模式
- 改變接口
- 適配器模式(Adapter)
- 外觀模式(Fa?ade)
- 包(Package)作為外觀模式的變體
- 解釋器:運行時的彈性
- 回調
- 多次調度
- 模式重構
- 抽象用法
- 多次派遣
- 訪問者模式
- RTTI的優劣
- 本章小結
- 附錄:補充
- 附錄:編程指南
- 附錄:文檔注釋
- 附錄:對象傳遞和返回
- 附錄:流式IO
- 輸入流類型
- 輸出流類型
- 添加屬性和有用的接口
- 通過FilterInputStream 從 InputStream 讀取
- 通過 FilterOutputStream 向 OutputStream 寫入
- Reader和Writer
- 數據的來源和去處
- 更改流的行為
- 未發生改變的類
- RandomAccessFile類
- IO流典型用途
- 緩沖輸入文件
- 從內存輸入
- 格式化內存輸入
- 基本文件的輸出
- 文本文件輸出快捷方式
- 存儲和恢復數據
- 讀寫隨機訪問文件
- 本章小結
- 附錄:標準IO
- 附錄:新IO
- ByteBuffer
- 數據轉換
- 基本類型獲取
- 視圖緩沖區
- 字節存儲次序
- 緩沖區數據操作
- 緩沖區細節
- 內存映射文件
- 性能
- 文件鎖定
- 映射文件的部分鎖定
- 附錄:理解equals和hashCode方法
- 附錄:集合主題
- 附錄:并發底層原理
- 附錄:數據壓縮
- 附錄:對象序列化
- 附錄:靜態語言類型檢查
- 附錄:C++和Java的優良傳統
- 附錄:成為一名程序員