出 版 社: 機械工業出版社
出版時間: 2009-1-1 頁數: 599
印刷時間: 2009/01/01 開本: 16開
紙張: 膠版紙 I S B N : 9787111251330
包裝: 平裝 所屬分類: 圖書 >> 計算機/網路 >> 程式設計 >> 其他
編輯推薦
38位大師級的程式設計師,一步步講解他們的項目架構,開發時的種種折中考慮(tradeoffs)以及何時必須打破常規,尋求突破。全球38位頂尖高手、眾多語言之父經典之作。
本書收錄的是軟體設計領域中的一組大師級作品。每一章都是由一位或幾位著名程式設計師針對某個問題給出的完美的解決方案,並且細述了這些解決方案的巧妙之處。
本書既不是一本關於設計模式的書,也不是一本關於軟體工程的書,它告訴你的不僅僅是一些正確的方式或者錯誤的方式。它讓你站在那些優秀軟體設計師的肩膀上,從他們的角度來看待問題。
本書給出了38位大師級程式設計師在項目設計中的思路、在開發工作中的權衡,以及一些打破成規的決策。
內容簡介
本書介紹了人類在一個奮鬥領域中的創造性和靈活性:計算機系統的開發領域。在每章中的漂亮代碼都是來自獨特解決方案的發現,而這種發現是來源於作者超越既定邊界的遠見卓識,並且識別出被多數人忽視的需求以及找出令人嘆為觀止的問題解決方案。本書33章,有38位作者,每位作者貢獻一章。每位作者都將自己心目中對於“美麗的代碼”的認識濃縮在一章當中,張力十足。38位大牛,每個人對代碼之美都有自己獨特的認識,現在一覽無餘的放在一起,對於熱愛程式的每個人都不啻一場盛宴。 雖然本書的涉獵範圍很廣,但也只能代表一小部分在這個軟體開發這個最令人興奮領域所發生的事情。
作者簡介
全球38位頂尖高手、眾多語言之父經典之作目錄
第1章 正則表達式匹配器1.1 編程實踐
1.2 實現
1.3 討論
1.4 其他的方法
1.5 構建
1.6 小結
第2章 Subversion中的增量編輯器:像本體一樣的接口
2.1 版本控制與目錄樹的轉換
2.2 表達目錄樹的差異
2.3 增量編輯器接口
2.4 但這是不是藝術?
2.5 像體育比賽一樣的抽象
2.6 結論
第3章 我從未編寫過的最漂亮代碼
3.1 我編寫過的最漂亮代碼
3.2事倍功半
3.3 觀點
3.4 本章的中心思想是什麼?
3.5 結論
3.6致謝
第4章 查找
4.1 耗時
4.2 問題:部落格數據
4.3 問題:時間,人物,以及對象?
4.4 大規模尺度的搜尋
4.5 結論
第5章 正確、優美、迅速(按重要性排序):從設計XML驗證器中學到的經驗
5.1 XML驗證器的作用
5.2 問題所在
5.3 版本1:簡單的實現
5.4 版本2:模擬BNF語法——複雜度O(N)
5.5 版本3:第一個複雜度O(log N)的最佳化
5.6 版本4:第二次最佳化:避免重複驗證
5.7 版本5:第三次最佳化:複雜度 O(1)
5.8 版本 6:第四次最佳化:快取(Caching)
5.9 從故事中學到的
第6章 集成測試框架:脆弱之美
6.1 三個類搞定一個驗收測試框架
6.2 框架設計的挑戰
6.3 開放式框架
6.4 一個HTML解析器可以簡單到什麼程度?
6.5 結論
第7章 美麗測試
7.1 討厭的二分查找
7.2 JUnit簡介
7.3將二分查找進行到底
7.4 結論
第8章 圖像處理中的即時代碼生成
第9章 自頂向下的運算符優先權
9.1JavaScript
9.2 符號表
9.3 語素
9.4 優先權
9.5 表達式
9.6 中置運算符
9.7 前置操作符
9.8 賦值運算符
9.9 常數
9.10 Scope
9.11 語句
9.12 函式
9.13 數組和對象字面量
9.14 要做和要思考的事
第10章 追求加速的種群計數
10.1 基本方法
10.2 分治法
10.3 其他方法
10.4 兩個字種群計數的和與差
10.5 兩個字的種群計數比較
10.6 數組中的1位種群計數
10.7 套用
第11章 安全通信:自由的技術
11.1 項目啟動之前
11.2 剖析安全通信的複雜性
11.3 可用性是關鍵要素
11.4 基礎
11.5 測試集
11.6 功能原型
11.7 清理,插入,繼續
11.8 在喜馬拉雅山的開發工作
11.9 看不到的改動
11.10 速度確實重要
11.11 人權中的通信隱私
11.12 程式設計師與文明
第12章 在BioPerl里培育漂亮代碼
12.1 BioPerl和Bio::Graphics模組
12.2 Bio::Graphics的設計流程
12.3 擴展Bio::Graphics
12.4 結束語和教訓
第13章 基因排序器的設計
13.1 基因排序器的用戶界面
13.2 通過Web跟用戶保持對話
13.3 多態的威力
13.4 濾除無關的基因
13.5 大規模美麗代碼理論
13.6 結論
第14章 優雅代碼隨硬體發展的演化
14.1 計算機體系結構對矩陣算法的影響
14.2 一種基於分解的方法
14.3 一個簡單版本
14.4 LINPACK庫中的DGEFA子程式
14.5 lapack DGETRF
14.6 遞歸LU
14.7 ScaLAPACK PDGETRF
14.8 針對多核系統的多執行緒設計
14.9 誤差分析與操作計數淺析
14.10 未來的研究方向
14.11 進一步閱讀
第15章 漂亮的設計會給你帶來長遠的好處
15.1 對於漂亮代碼的個人看法
15.2 對於CERN庫的介紹
15.3 外在美
15.4 內在美
15.5 結論
第16章,Linux核心驅動模型:協作的好處
16.1 簡單的開始
16.2 進一步簡化
16.3 擴展到上千台設備
16.4 小對象的鬆散結合
第17章 額外的間接層
17.1 從直接代碼操作到通過函式指針操作
17.2 從函式參數到參數指針
17.3 從檔案系統到檔案系統層
17.4 從代碼到DSL9Domain-Specific Language
17.5 復用與分離
17.6.分層是永恆之道?
第18章 Python的字典類:如何打造全能戰士
18.1 字典類的內部實現
18.2 特殊調校
18.3 衝突處理
18.4 調整大小
18.5 疊代和動態變化
18.6 結論
18.7 致謝
第19章 numpy中的多維疊代器
19.1 N維數組操作中的關鍵挑戰
19.2 N維數組的記憶體模型
19.3 NumPy疊代器的起源
19.4 疊代器的設計
19.5 疊代器的接口
19.6 疊代器的使用
19.7 結束語
第20章 NASA火星漫步者任務中的高可靠企業系統
20.1 任務與CIP
20.2 任務需求
20.3 系統架構
20.4 案例分析:流服務
20.5 可靠性
20.6 穩定性
20.7 結束語
第21章 ERP5:最大可適性的設計
21.1 ERP的總體目標
21.2 ERP5
21.3 Zope基礎平台
21.4 ERP5 Project中的概念
21.5 編碼實現ERP5 Project
21.6 結束語
第22章 一匙污水
第23章 MapReduce分散式編程
23.1 激動人心的示例
23.2 MapReduce編程模型
23.3 其他MapReduce示例
23.4 分散式MapReduce的一種實現
23.5 模型擴展
23.6 結論
23.7 進階閱讀
23.8 致謝
23.9 附錄:單詞計數解決方案
第24章 美麗的並發
24.2 軟體事務記憶體
24.3 聖誕老人問題
24.4 對Haskell的一些思考
24.6 致謝
第25章 句法抽象:syntax-case 展開器
25.1 syntax-case簡介
25.2 展開算法
25.3 例子
25.4 結論
第26章 節省勞動的架構:一個面向對象的網路化軟體框架
26.1 示例程式:日誌服務
26.2 日誌伺服器框架的面向對象設計
26.3 實現串列化日誌伺服器
26.4 實現並行日誌伺服器
26.5 結論
第27章 以REST方式集成業務夥伴
27.1 項目背景
27.2 把服務開放給外部客戶
27.3 使用工廠模式轉發服務
27.4 用電子商務協定來交換數據
27.5 結束語
第28章 漂亮的調試
28.1 對調試器進行調試
28.2 系統化的過程
28.3 關於查找的問題
28.4 自動找出故障起因
28.5 增量調試
28.6 最小化輸入
28.7 查找缺陷
28.8 原型問題
28.9 結束語
28.10 致謝
28.11 進一步閱讀
第29章 把代碼當作文章
第30章 當你與世界的聯繫只有一個按鈕
30.1 基本的設計模型
30.2 輸入界面
30.3 用戶界面的效率
30.4 下載
30.5 未來的發展方向
第31章 Emacspeak:全功能音頻桌面
31.1 產生語音輸出
31.2 支持語音的Emacs
31.3 對於線上信息的簡單訪問
31.4 小結
31.5 致謝
第32章 變動的代碼
32.1 像書本一樣
32.2 功能相似的代碼在外觀上也保持相似
32.3 縮進帶來的危險
32.4 瀏覽代碼
32.5 我們使用的工具
32.6 DiffMerge的曲折歷史
32.7 結束語
32.8 致謝
32.9 進一步閱讀
第33章 為“The Book”編寫程式
33.1 沒有捷徑
33.2 給Lisp初學者的提示
33.3 三點共線
33.4 不可靠的斜率
33.5 三角不等性
33.6 河道彎曲模型
33.7 “Duh!”——我的意思是“Aha!”
33.8 結束語
33.9 進一步閱讀
後記
作者簡介
媒體評論
重新擦亮思考的火花《代碼之美》這本書已經成為經典。關於它本身的讚美之辭已經不少了,不過到底從這本書里該讀些什麼東西,我倒是有些思考。
上世紀九十年代初期,當時正在加州大學埃爾文分校攻讀博士學位的Douglas Schmidt在觀察了他所參與的軟體項目開發實踐之後,得出一個結論,即未來的軟體開發將越來越多地體現為整合(integration),而不是傳統意義上的編程(programming)。換言之,被稱為 “軟體開發者” 的這個人群,將越來越明顯地分化:一部分人開發核心構件和基礎平台,而更多地人將主要是配置和整合現有構件以滿足客戶的需求,類似現代汽車、工具機和家用電器製造業的產業格局即將到來。面對這一前景,博士生Schmidt一方面寫文章對於其進步意義大加讚揚,另一方面毫不猶豫地投入到核心構件及平台的開發陣營中去。他很清楚,在這樣一種分工體系中,由於軟體整合產業很難出現壟斷局面,因此大多數利潤總是被截留在上游,人當然要往高處走,整合是好事,但他老兄寧可讓別人來做這個好事。
事實上,軟體產業中大多數看上去挺靠譜的預測都被歷史的發展無情地拋到垃圾堆里了,然而Schmidt博士生的這個預測卻驚人的準確,其後十幾年軟體工業的發展完美地印證了他當年的判斷。因此,他本人基於這一預測所選擇的人生道路也一帆風順。如今已經是教授的Douglas Schmidt先後創造了ACE、TAO、CIAO等一系列分散式計算基礎件,先後主導了美國學界和國防領域內若干重大科研與實際開發項目,稱為世人公認的分散式計算架構領導者。
拋開他個人的輝煌不說,“整合化”趨勢實際上已經深刻地改變了世界軟體工業的面貌,從而也影響了身為晚進者的我們的命運。如今大部分的程式設計師實際上是在整合與配置現有資源以滿足需求,而不是真正意義上的“編程”。這當然是一件好事,整契約樣需要深刻的洞察力和創新精神,優秀的整合者與天才的程式設計師一樣不可多得,甚至更加罕見。然而我們也不能不承認,大多數整合性的工作是機械的,簡單的,重複的,欠缺創意的,深入的思考往往不必要。因此,在這個整合為王的時代里,思考的精神在鈍化。更有甚者,網際網路和搜尋引擎的出現大大加速了這種鈍化,幾乎所有的問題都有人解決並且張貼在網際網路上了,因此獨自思考和解決問題已經成了不必要的、降低效率的行為,不但不時髦,而且不經濟。軟體開發迅速成為一個強調搜尋和短期記憶力的技能,我想這是50年前第一代程式設計師們做夢也沒有想到的。
老實講,就整體而言,我仍然認為這是一種進步。任何一個產業的成熟,無不伴隨著分工的明晰、技能的簡化和從業門檻的降低。與少數人享受思考樂趣的需求相比,大多數人享受便宜而無處不在的軟體服務的需求顯然遠為重要。但是,對於身處軟體行業中的個體來說,思考力的削弱和喪失卻是不折不扣的悲劇。這一點不必過多解釋,正在苦苦尋找自己核心競爭力的開發者們都知道我說的是什麼意思。幾年來對中國開發者社群的近距離觀察使我確信,儘管作為一個產業,中國軟體一直享受著比較快的成長,但是總體而言,中國的軟體開發者越來越迷惘、焦躁和不自信。這一情況當然是由多種原因導致的,但開發者們每念及此,多抱怨體制、產業、市場等身外之物,實在也有失偏頗。評心而論,這幾年中國軟體技術界的生存環境還是有了很大改善,對於那些真正出類拔萃的程式設計師來說,過上一種充實自信的生活並不困難。擺在每一個個體面前的主要問題還是在於能否出類拔萃,而這就需要我們重新找回思考的能力。具備強悍思考能力的人,也就具備強悍的解決問題的能力,而這樣的開發者永遠都是產業中的稀缺資源。
我認為這正是《代碼之美》這本書的一個重要價值。合作的諸位大師級作者,給我們一個很好的機會,讓我們能夠一邊閱讀,一邊思考,找回深思熟慮的智慧火花。這本書里所講的每一個問題,可以說都是程式設計師在工作中會遇到或者至少會擦邊的問題,既沒有故弄玄虛的文字遊戲,也沒有攜帶了領域知識的私貨,只有樸實而實際的一個個問題。雖然不是以提問的方式給出,但在整個閱讀的過程中,我們還是能夠找到很多機會與大師互動,不斷地發現問題和解決問題。我在閱讀中經常感到,看上去一個很簡單的問題,卻被這些大師們一層一層挖掘的如此深入,到最後階段不由得令人感到戰慄和震撼。看著這些智慧的光芒,我們不但可以領略大師之所謂稱為大師的秘密,而且也認識到思考的真諦。因此,千萬不要想看小說一樣一帶而過,那樣會錯過本書95%的價值!我們不是要閱讀這些文字,而是要與文字背後的作者交流學習,一點一點把自己的心得記下來,對於作者提出的新問題,先自己思考,直接寫程式嘗試,爭取跟上大師的思路,甚至可能需要反覆幾遍,才能真正讀通這本書。這樣的精力不會是白費的,讀者應當認識到,當我們擁有這本書的時候,我們獲得了怎樣寶貴的機會,可以在相對比較短的時間裡有效地提升自己的思考能力。這是一個機會,也是一次考驗,我絕對相信,通過了這次考驗的讀者,會在思考和解決問題的能力上有一個大的進步。
我希望自己能夠以這樣的態度讀這本了不起的書,以此文與其他讀者朋友共勉之。
——孟岩
書摘插圖
第3章 我從未編寫過的最漂亮的代碼Jon Bentley
我曾經聽一位大師級的程式設計師這樣稱讚到,“我通過刪除代碼來實現功能的提升。”而法國著名作家兼飛行家Antoine de Saint-Exupéry的說法則更具代表性,“只有在不僅沒有任何功能可以添加,而且也沒有任何功能可以刪除的情況下,設計師才能夠認為自己的工作已臻完美。” 某些時候,在軟體中根本就不存在最漂亮的代碼,最漂亮的函式,或者最漂亮的程式。
當然,我們很難對不存在的事物進行討論。本章將對經典Quicksort(快速排序)算法的運行時間進行全面的分析,並試圖通過這個分析來說明上述觀點。在第一節中,我將首先根據我自己的觀點來回顧一下Quicksort,並為後面的內容打下基礎。第二節的內容將是本章的重點部分。我們將首先在程式中增加一個計數器,然後通過不斷地修改,從而使程式的代碼變得越來越短,但程式的功能卻會變得越來越強,最終的結果是只需要幾行代碼就可以使算法的運行時間達到平均水平。在第三節將對前面的技術進行小結,並對二分搜尋樹的運行開銷進行簡單的分析。最後的兩節將給出學完本章得到的一些啟示,這將有助於你在今後寫出更為優雅的程式。
3.1 我編寫過的最漂亮代碼
當Greg Wilson最初告訴我本書的編寫計畫時,我曾自問編寫過的最漂亮的代碼是什麼。這個有趣的問題在我腦海里盤鏇了大半天,然後我發現答案其實很簡單:Quicksort算法。但遺憾的是,根據不同的表達方式,這個問題有著三種不同的答案。
當我撰寫關於分治(divide-and-conquer)算法的論文時,我發現C.A.R. Hoare的Quicksort算法(“Quicksort”,Computer Journal 5)無疑是各種Quicksort算法的鼻祖。這是一種解決基本問題的漂亮算法,可以用優雅的代碼實現。我很喜歡這個算法,但我總是無法弄明白算法中最內層的循環。我曾經花兩天的時間來調試一個使用了這個循環的複雜程式,並且幾年以來,當我需要完成類似的任務時,我會很小心地複製這段代碼。雖然這段代碼能夠解決我所遇到的問題,但我卻並沒有真正地理解它。
我後來從Nico Lomuto那裡學到了一種優雅的劃分(partitioning)模式,並且最終編寫出了我能夠理解,甚至能夠證明的Quicksort算法。William Strunk Jr.針對英語所提出的“良好的寫作風格即為簡練”這條經驗同樣適用於代碼的編寫,因此我遵循了他的建議,“省略不必要的字詞”(來自《The Elements of Style》一書)。我最終將大約40行左右的代碼縮減為十幾行的代碼。因此,如果要回答“你曾編寫過的最漂亮代碼是什麼?”這個問題,那么我的答案就是:在我編寫的《Programming Pearls, Second Edition》(Addison-Wesley)一書中給出的Quichsort算法。在示例3-1中給出了用C語言編寫的Quicksort函式。我們在接下來的章節中將進一步地研究和改善這個函式。
【示例】 3-1 Quicksort函式
void quicksort(int l, int u)
{int i, m;
if (l >= u) return;
swap(l, randint(l, u));
m = l;
for (i = l+1; i <= u; i++)
if (x[i] < x[l])
swap(++m, i);
swap(l, m);
quicksort(l, m-1);
quicksort(m+1, u);}
如果函式的調用形式是quicksort(0, n-1),那么這段代碼將對一個全局數組x[n]進行排序。函式的兩個參數分別是將要進行排序的子數組的下標:l是較低的下標,而u是較高的下標。函式調用swap(i,j)將會交換x〔i〕與x〔j〕這兩個元素。第一次交換操作將會按照均勻分布的方式在l和u之間隨機地選擇一個劃分元素。
在《Programming Pearls》一書中包含了對Quicksort算法的詳細推導以及正確性證明。在本章的剩餘內容中,我將假設讀者熟悉在《Programming Pearls》中所給出的Quicksort算法以及在大多數初級算法教科書中所給出的Quicksort算法。
如果你把問題改為“在你編寫那些廣為套用的代碼中,哪一段代碼是最漂亮的?”我的答案還是Quicksort算法。在我和M. D. McIlroy一起編寫的一篇文章("Engineering a sort function," Software-Practice and Experience, Vol. 23, No. 11)中指出了在原來Unix qsort函式中的一個嚴重的性能問題。隨後,我們開始用C語言編寫一個新排序函式館,並且考慮了許多不同的算法,包括合併排序(Merge Sort)和堆排序(Heap Sort)等算法。在比較了Quicksort的幾種實現方案後,我們著手創建自己的Quicksort算法。在這篇文章中描述了我們如何設計出一個比這個算法的其他實現要更為清晰,速度更快以及更為健壯的新函式——部分原因是由於這個函式的代碼更為短小。Gordon Bell的名言被證明是正確的:“在計算機系統中,那些最廉價,速度最快以及最為可靠的組件是不存在的。”現在,這個函式已經被使用了10多年的時間,並且沒有出現任何故障。
考慮到通過縮減代碼量所得到的好處,我最後以第三種方式來問自己在本章之初提出的問題。“你沒有編寫過的最漂亮代碼是什麼?”。我如何使用非常少的代碼來實現大量的功能?答案還是和Quicksort有關,特別是對這個算法的性能分析。我將在下一節給出詳細介紹。
……