1. 程式人生 > >完全拷貝的一份,程式設計師閱讀書單

完全拷貝的一份,程式設計師閱讀書單

關於

本文把程式設計師所需掌握的關鍵知識總結為三大類19個關鍵概念,然後給出了掌握每個關鍵概念所需的入門書籍,必讀書籍,以及延伸閱讀。旨在成為最好最全面的程式設計師必讀書單。

前言

Reading makes a full man; conference a ready man; and writing an exact man.

Francis Bacon

優秀的程式設計師應該具備兩方面能力:

  • 良好的程式設計能力:
    • 掌握常用的資料結構和演算法(例如連結串列,棧,堆,佇列,排序和雜湊);
    • 理解電腦科學的核心概念(例如計算機系統結構、作業系統、編譯原理和計算機網路);
    • 熟悉至少兩門以上程式語言(例如C++,Java,C#,和Python);
  • 專業的軟體開發素養:
    • 具備良好的程式設計實踐,能夠編寫可測試(Testable),可擴充套件(Extensible),可維護(Maintainable)的程式碼;
    • 把握客戶需求,按時交付客戶所需要的軟體產品;
    • 理解現代軟體開發過程中的核心概念(例如面向物件程式設計,測試驅動開發,持續整合,和持續交付等等)。

和其它能力一樣,程式設計能力和軟體開發素養源自專案經驗和書本知識。專案經驗因人而異(來自不同領域的程式設計師,專案差異會很大);但書本知識是相通的——尤其是經典圖書,它們都能夠拓寬程式設計師的視野,提高程式設計師的成長速度。

在過去幾年的學習和工作中,我閱讀了大量的程式設計/軟體開發書籍。隨著閱讀量的增長,我意識到:

  • 經典書籍需要不斷被重讀——每一次重讀都會有新的體會;
  • 書籍並非讀的越多越好——大多數書籍只是經典書籍中的概念延伸(有時甚至是照搬);

意識到這兩點之後,我開始思考一個很功利的問題:如何從儘可能少的書中,獲取儘可能多的關鍵知識?換句話說:

  • 優秀的程式設計師應該掌握哪些關鍵概念?
  • 哪些書籍來可以幫助程式設計師掌握這些關鍵概念?

這即是這篇文章的出發點——我試圖通過程式設計師必讀書單這篇文章來回答上面兩個問題。

標準

進入必讀書單之前,我先介紹下書單裡的書籍選擇標準和領域選擇標準。當然你也

點選這裡直接跳轉到書單開始閱讀。

書籍選擇標準

  1. 必讀:什麼是必讀書籍呢?如果學習某項技術有一本書無論如何都不能錯過,那麼這本書就是必讀書籍——例如Effective Java於Java,CLR via C#於C#;
    • 注意我沒有使用“經典”這個詞,因為經典計算機書籍往往和電腦科學聯絡在一起,而且經典往往需要10年甚至更長的時間進行考驗;
  2. 注重實踐,而非理論:所以這個書單不會包含過於原理性的書籍;
  3. 入門—必讀—延伸:必讀書籍的問題在於:1. 大多不適合入門;2. 不夠全面。考慮到沒有入門閱讀和延伸閱讀的閱讀列表是不完整的——所以書單中每個關鍵概念都會由一本入門書籍,一本必讀書籍(有時入門書籍和必讀書籍是同一本),和若干延伸閱讀書籍所構成。

概念選擇標準

  1. 全面:全面覆蓋軟體開發中重要的概念;
  2. 通用:適用於每一個程式設計師,和領域特定方向無關;
  3. 注重基礎,但不過於深入:優秀的程式設計師需要良好的電腦科學基礎,但程式設計師並沒必要掌握過於深入的電腦科學知識。以演算法為例,每個程式設計師都應該掌握排序、連結串列、棧以及佇列這些基本資料結構和演算法,但計算幾何、線性規劃和網路流這些演算法可能就不是每個程式設計師都需要掌握的了;

通過這幾個標準,我把程式設計師應掌握的關鍵概念分為程式設計,軟體開發,以及個人成長三大類,每一大類均由若干關鍵概念組成。

快速通道

自從開博以來,經常會有朋友在論壇,微博,和QQ上提問學習X技術讀什麼書合適(例如:學習Java讀什麼書合適?如何學習程式設計?)所以我在這裡列出了一個“快速通道”——把常見的問題集中在一起,點選問題,即可直接進入答案。(當然,如果你把本文從頭讀到尾幫助會更大 :-))

入門書籍

程式設計:

軟體開發:

個人成長:

必讀書籍

程式設計:

軟體開發:

個人成長:

這個閱讀列表覆蓋了軟體開發各個關鍵領域的入門書籍和必讀書籍,我相信它可以滿足絕大多數程式設計師的需求,無論你是初學者,還是進階者,都可以從中獲益:

  • 基礎理論包括了程式設計師應該掌握的計算機基礎知識;
  • 程式語言對軟體開發至關重要,我選擇了CC++JavaC#Python,和JavaScript這六門主流程式語言進行介紹,如果想進一步理解程式語言,可以閱讀程式語言理論裡的書目;
  • 在理解程式語言的基礎上,優秀的程式設計師還應該瞭解各種程式設計技巧,熟悉基本的演算法資料結構,並且能夠高效的進行程式除錯
  • 良好的程式設計能力是成為優秀程式設計師的前提,但軟體開發知識也是必不可少的:優秀的程式設計師應具備良好的程式設計實踐,知道如何利用面向物件重構,和軟體測試編寫可複用,可擴充套件,可維護的程式碼,並具備軟體專案管理知識和專業開發素養;
  • 就像我們可以從名人傳記裡學習名人的成功經驗,程式設計師也可以通過追隨優秀程式設計師的足跡使自己少走彎路。大師之言包含一系列對大師程式設計師/電腦科學家的訪談,任何程式設計師都可以從中獲益良多;
  • 為了打造使用者滿意的軟體產品,程式設計師應當掌握一定的介面設計知識和互動設計知識(是的,這些工作應該交給UI和UX,但如果你想獨自打造一個產品呢?);
  • 專業程式設計師應當對自己進行職業規劃,並熟悉程式設計師求職面試的流程,以便在職業道路上越走越遠;
  • 軟體開發是一項需要不斷學習的技能,學習思維方式可以有效的提升學習能力和學習效率;
  • 軟體開發是一項國際化的工作,為了讓更多的人瞭解你的程式碼(工作),良好的英語寫作能力必不可少。

儘管我儘可能的去完善這個書單,但受限於我的個人經歷,這個書單難免會有所偏頗。所以如果你有不同的意見,或者認為這個書單漏掉了某些重要書籍,請在評論中指出,我會及時更新。:-)

程式設計

編碼:隱匿在計算機軟硬體背後的語言這本書其實不應該叫編碼——它更應該叫“Petzold教你造計算機”——作者Charles Petzold創造性的以編碼為主題,從電報機和手電筒講到數位電路,然後利用數位電路中的邏輯閘構造出加法器觸發器,最後構造出一個完整的儲存程式計算機。不要被這些電路概念嚇到——編碼使用大量形象貼切的類比簡化了這些概念,使其成為最精彩最通俗易懂的計算機入門讀物。

深入理解計算機系統(第2版)這本書的全名是:Computer Systems:A Programmer's Perspective(所以它又被稱為CSAPP),我個人習慣把它翻譯為程式設計師所需瞭解的計算機系統知識,儘管土了些,但更名副其實。

深入理解計算機系統是我讀過的最優秀的計算機系統導論型作品,它創造性的把作業系統,計算機組成結構,數位電路,以及編譯原理這些計算機基礎學科中的核心概念彙集在一起,從而覆蓋了指令集體系架構,組合語言,程式碼優化,計算機儲存體系架構,連結,裝載,程序,以及虛擬記憶體這些程式設計師所需瞭解的關鍵計算機系統知識。如果想打下紮實的計算機基礎又不想把作業系統計算機結構編譯原理這些書統統讀一遍,閱讀深入理解計算機系統是最有效率的方式。

延伸閱讀:

  • 世界是數字的K&R中的K(Brian Kernighan)的近作,這本書源自Brian在普林斯頓大學所教授的計算機基礎課程,以通俗易懂的方式講述了現代人所應瞭解的計算機知識和網路知識;
  • 計算機系統概論(第2版):另一部優秀的計算機系統導論型作品,和深入理解計算機系統不同,這本書採用自下而上的方式,從二進位制,和數字邏輯這些底層知識一步步過渡到高階程式語言(C),從而以另一種方式理解計算機系統。

程式語言是程式設計師必不可少的日常工具。工欲善其事,必先利其器。我在這裡給出了C,C++,Java,C#,JavaScript,和Python這六種常用程式語言的書單(我個人不熟悉Objective-C和PHP,因此它們不在其中)。

需要注意的是:我在這裡給出的是程式語言(Programming Language)書籍,而非程式設計平臺(Programming Platform)書籍。以Java為例,Effective Java屬於程式語言書籍,而Android程式設計權威指南就屬於程式設計平臺書籍。

C

忘記譚浩強那本糟糕不堪的C程式設計,C和指標才是C語言的最佳入門書籍。它詳細但又不失簡練的介紹了C語言以及C標準庫的方方面面。

對於C語言初學者,最難的概念不僅僅是指標和陣列,還有指向陣列的指標和指向指標的指標。C和指標花了大量的篇幅和圖示來把這些難懂但重要的概念講的清清楚楚,這也是我推薦它作為C語言入門讀物的原因。

儘管C程式設計語言是二十多年前的書籍,但它仍然是C語言——以及電腦科學中最重要的書籍之一,它的重要性不僅僅在於它用清晰的語言和簡練的程式碼描述了C語言全貌,而且在於它為之後的計算機書籍——尤其是程式語言書籍樹立了新的標杆。以至於在很多計算機書籍的扉頁,都會有“感謝Kernighan教會我寫作”這樣的字樣。

延伸閱讀:

  • C專家程式設計:不要被標題中的“專家”嚇到,這實際是一本很輕鬆的書籍,它既包含了大量C語言技術細節和程式設計技巧,也包含了很多有趣的程式設計軼事;
  • C陷阱與缺陷:書如其名,這本書介紹了C語言中常見的坑和一些稀奇古怪的程式設計“技巧”,不少刁鑽的C語言面試題都源自這本小冊子;
  • C語言參考手冊:全面且權威的C語言參考手冊,而且覆蓋C99,如果你打算成為C語言專家,那麼這本書不可錯過;
  • C標準庫:給出了15個C標準庫的設計思路,實現程式碼,以及測試程式碼,配合C程式設計語言閱讀效果更佳;
  • C語言介面與實現:這本書展示瞭如何使用C語言實現可複用的資料結構,其中包含大量C語言高階技巧,以至於Amazon上排行第一的評論是“Probably the best advanced C book in existance”,而排行第二的評論則是“By far the most advanced C book I read”。

C++

作為C++的發明者,沒有人能比Bjarne Stroustrup更理解C++。Bjarne在Texas A&M大學任教時使用C++為大學新生講授程式設計,從而就有了C++程式設計原理與實踐這本書——它面向程式設計初學者,既包含C++教程,也包含大量程式設計原則。它不但是我讀過最好的C++入門書,也是我讀過最好的程式設計入門書。

比較有趣的是,C++程式設計原理與實踐直到全書過半都沒有出現指標,我想這可能是Bjarne為了證明不學C也可以學好C++吧。

同樣是Bjarne Stroustrup的作品,C++程式設計語言是C++最權威且最全面的書籍。第4版相對於之前的版本進行了全面的更新,覆蓋了第二新的C++ 11標準,並砍掉了部分過時的內容。

延伸閱讀:

  • A Tour of C++:如果你覺得C++程式設計語言過於龐大,但你又想快速的瀏覽一遍新版C++的語言特色,那麼可以試試這本小紅書;
  • C++語言的設計與演化:C++的“歷史書”,講述了C++是如何一步一步從C with Classes走到如今這一步,以及C++語言特性背後的故事;
  • C++標準庫(第2版):相對於其它語言的標準庫,C++標準庫雖然強大,但學習曲線十分陡峭,這本書是學習C++標準庫有力的補充;
  • 深度探索C++物件模型:這本書系統的講解了C++是如何以最小的效能代價實現物件模型,很多C++面試題(包括被問爛的虛擬函式指標)都可以在這本書裡找到答案;
  • Effective C++More Effective C++:由於C++的特性實在繁雜,因此很容易就掉到坑裡。Effective系列既講述了C++的良好程式設計實踐,也包含C++的使用誤區,從而幫你繞過這些坑。

Java

平心而論Java核心技術(即Core Java)並不算是一本特別出色的書籍:示例程式碼不夠嚴謹,充斥著很多與C/C++的比較,語言也不夠簡潔——問題在於Java並沒有一本很出色的入門書籍,與同類型的Java程式設計思想相比,Java核心技術至少做到了廢話不多,與時俱進(Java程式設計思想還停留在Java 6之前),矮子裡面選將軍,Java核心技術算不錯了。

儘管Java沒有什麼出色的入門書籍,但這不代表Java沒有出色的必讀書籍。Effective Java是我讀過的最好的程式設計書籍之一,它包含大量的優秀Java程式設計實踐,並對泛型和併發這兩個充滿陷阱的Java特性給出了充滿洞察力的建議,以至於Java之父James Gosling為這本書作序:“我很希望10年前就擁有這本書。可能有人認為我不需要任何Java方面的書籍,但是我需要這本書。”

延伸閱讀:

  • 深入理解Java虛擬機器(第2版):非常優秀且難得的國產佳作,系統的介紹了Java虛擬機器和相關工具,並給出了一些調優建議;
  • Java程式設計師修煉之道:在這本書之前,並沒有一本Java書籍系統詳細的介紹Java 7的新特性(例如新的垃圾收集器,try using結構和invokedynamic指令),這本書填補了這個空白;
  • Java併發程式設計實踐:系統全面的介紹了Java的併發,如何設計支援併發的資料結構,以及如何編寫正確的併發程式;
  • Java Puzzlers:包含了大量的Java陷阱——以至於讀這本書時我說的最多的一個詞就是WTF,這本書的意義在於它是一個反模式大全,Effective Java告訴你如何寫好的Java程式,而Java Puzzlers則告訴你糟糕的Java程式是什麼樣子。更有意思的是,這兩本書的作者都是Joshua Bloch

C#

可能你會疑問我為什麼會推薦這本接近1200頁的“鉅著”用作C#入門,這是我的答案:

  1. C#的語言特性非常豐富,很難用簡短的篇幅概括這些特性;
  2. 精通C#之所以有近1200頁的篇幅,是因為它不但全面介紹了C#語言,而且還覆蓋了ADO.NET,WCF,WF,WPF,以及ASP.NET這些.Net框架。你可以把這本書視為兩本書——一本500多頁的C#語言教程和一本600多頁的.Net平臺框架快速上手手冊。
  3. 儘管標題帶有“精通”兩字,精通C#實際上是一本面向初學者的C#書籍,你甚至不需要太多程式設計知識,就可以讀懂它。

CLR via C#是C#/.Net最重要的書籍,沒有之一。它全面介紹了.Net的基石——CLR的執行原理,以及構建於CLR之上的C#型別系統,執行時關係,泛型,以及執行緒/並行等高階內容。任何一個以C#為工作內容的程式設計師都應該閱讀此書。

延伸閱讀:

  • 深入理解C#(第3版):C#進階必讀,這本書偏重於C#的語言特性,它系統的介紹了C#從1.0到C# 4.0的語言特性演化,並展示瞭如何利用C#的語言特性編寫優雅的程式;
  • .NET設計規範(第2版):C#專業程式設計師必讀,從變數命名規範講到型別系統設計原則,這本書提供了一套完整的.Net程式設計規範,使得程式設計師可以編寫出一致,嚴謹的程式碼,
  • C# 5.0權威指南:來自O'Reilly的C#參考手冊,嚴謹的介紹了C#語法,使用,以及核心類庫,C#程式設計師案頭必備;
  • LINQ to Objects Using C# 4.0Async in C# 5.0:LINQ和async分別是.Net 3.5和.Net 4.5中所引入的最重要的語言特性,所以我認為有必要在它們上面花點功夫——這兩本書是介紹LINQ和async程式設計的最佳讀物。

儘管JavaScript現在可以做到客戶端伺服器端通吃,儘管JQuery之類的前端框架使得一些人可以不懂JavaScript也可以程式設計,但我還是認為學習JavaScript從HTML DOM開始最為適合,因為這是JavaScript設計的初衷。JavaScript DOM程式設計藝術系統的介紹瞭如何使用JavaScript,HTML,以及CSS建立可用的Web頁面,是一本前端入門佳作。

JavaScript語言包含大量的陷阱和誤區,但它卻又有一些相當不錯的特性,這也是為什麼Douglas Crockford稱JavaScript為世界上最被誤解的語言,並編寫了JavaScript語言精粹一書來幫助前端開發者繞開JavaScript中的陷阱。和同類書籍不同,JavaScript語言精粹用精煉的語言講解了JavaScript語言中好的那部分(例如閉包,函式是頭等物件,以及物件字面量),並建議讀者不要使用其它不好的部分(例如混亂的型別轉換,預設全域性名稱空間,以及奇葩的相等判斷符),畢竟,用糟糕的特性編寫出來的程式往往也是糟糕的。

延伸閱讀:

  • JavaScript高階程式設計(第3版):詳盡且深入的介紹了Javascript語言,DOM,以及Ajax,並針對HTML5做了對應更新;
  • 編寫可維護的JavaScript:書如其名,這本書給出了大量的優秀JavaScript程式設計實踐,使得程式設計師編寫出健壯且易於維護的JavaScript程式碼;
  • JavaScript非同步程式設計:和常見的支援併發的程式語言(例如Java和C#)不同,JavaScript本身是單執行緒的,因此不能把其它語言處理併發的方式照搬到JavaScript。JavaScript非同步程式設計系統的介紹了JavaScript中的併發原理,並闡述瞭如何使用PromiseDeferred以及Async.js編寫出簡潔高效的非同步程式。

Python的入門書籍很多,而且據說質量大多不錯,我推薦Python基礎教程的原因是因為它是我的Python入門讀物——簡潔,全面,程式碼質量很不錯,而且有幾個很有趣的課後作業,使得我可以快速上手。

這裡順便多說一句,不要用Python學習手冊作為Python入門——它的廢話實在太多,你能想象它用了15頁的篇幅去講解if語句嗎?儘管O'Reilly出了很多經典程式設計書,但這本Python學習手冊絕對不在其中。

權威且實用的Python書籍,覆蓋Python 2和Python 3。儘管它名為參考手冊,但Python參考手冊在Python語法和標準庫基礎之上對其實現機制也給出了深入的講解,不容錯過。

延伸閱讀:

  • Python袖珍指南(第5版):實用且便攜的Python參考手冊,我會說我在飛機上寫程式時用的就是它麼 -_-#;
  • Python Cookbook(第3版):非常好的Python進階讀物,包含各種常用場景下的Python程式碼,使得讀者可以寫出更加Pythonic的程式碼;
  • Python原始碼剖析:少見的國產精品,這本書以Python 2.5為例,從原始碼出發,一步步分析了CPython是如何實現型別,控制流,函式/方法的宣告與呼叫,型別以及裝飾器等Python核心概念,讀過之後會大大加深對Python的理解。儘管這本書有些過時,但我們仍然可以按照它分析原始碼的方式來分析新版Python。

大多數程式設計師並不需要從頭編寫一個編譯器或直譯器,因此龍書(編譯原理)就顯得過於重量級;然而多數程式設計師還是需要解析文字,處理配置檔案,或者寫一個小語言,程式語言實現模式很好的滿足了這個需求。它把常用的文字解析/程式碼生成方法組織成一個個模式,併為每個模式給出了例項和應用場景。這本書既會提高你的動手能力,也會加深你對程式語言的理解。Python發明者Guido van Rossum甚至為這本書給出了“Throw away your compiler theory book!”這樣的超高評價。

程式設計師每天都要和程式語言打交道,但是思考程式語言為什麼會被設計成這個樣子的程式設計師並不多,程式設計語言——實踐之路完美的回答了這個問題。這本書從程式語言的解析和執行開始講起,系統了介紹了名稱空間,作用域,控制流,資料型別以及方法(控制抽象)這些程式設計語言的核心概念,然後展示了這些概念是如何被應用到過程式語言,面嚮物件語言,函式式語言,指令碼式,邏輯程式語言以及併發程式語言這些具有不同程式設計正規化的程式語言之上。這本書或極大的拓寬你的視野——無論你使用什麼程式語言,都會從這本書中獲益良多。理解這一本書,勝過學習十門新的程式語言。

延伸閱讀:

  • 七週七語言:理解多種程式設計範型:儘管我們在日常工作中可能只使用兩三門程式語言,但是瞭解其它程式語言正規化是很重要的。七週七語言一書用精簡的篇幅介紹了Ruby,Io,Prolog,Scala,Erlang,Clojure,和Haskell這七種具有不同程式設計正規化的語言——是的,你沒法通過這本書變成這七種語言的專家,但你的視野會得到極大的拓寬;
  • 自制程式語言:另一本優秀的編譯原理作品,自制程式語言通過從零開始製作一門無型別語言Crowbar和一門靜態型別語言Diksam,把型別系統,垃圾回收,和程式碼生成等程式語言的關鍵概念講的清清楚楚;
  • 計算的本質:深入剖析程式和計算機:披著Ruby外衣的計算理論入門書籍,使你對程式語言的理解更上一層樓。

現代程式語言的語法大多很繁雜,初學者使用這些語言學習程式設計會導致花大量的時間在程式語言語法(諸如指標,引用和型別定義)而不是程式設計方法(諸如資料抽象和過程抽象)之上。程式設計方法解決了這個問題——它專注於程式設計方法,使得讀者無需把大量時間花在程式語言上。這本書還有一個與之配套的教學開發環境DrScheme,這個環境會根據讀者的程度變換程式語言的深度,使得讀者可以始終把注意力集中在程式設計方法上。

我個人很奇怪程式設計方法這樣的佳作為什麼會絕版,而譚浩強C語言這樣的垃圾卻大行其道——好在是程式設計方法第二版已經被免費釋出在網上。

計算機程式的構造與解釋是另一本被國內大學忽視(至少在我本科時很少有人知道這本書)的教材,這本書和程式設計方法有很多共同點——都使用Scheme作為教學語言;都專注於程式設計方法而非程式語言本身;都擁有相當出色的課後題。相對於程式設計