標籤:
6 電腦科學箴言集
程式員常常要轉換時間單位; e.g. 一個程式每秒能處理100條記錄, 那處理100w條需要多久? 用除法算, 就知道要花100000秒, 按每小時3600秒算, 差不多3小時;而一年有多少秒? 如果我直接告訴你 3.155x10^7秒, 你可能很快就忘了; 事實上, 要記住這個很簡單, 在誤差不超過0.5%的約束下: π秒就是一個納世紀 ——Tom Duff 貝爾實驗室 [nano 1×10
?9 ]所以, 如果程式要運行10^7秒, 就要準備等上4個月;
1985Feb的"ACM通訊"向讀者徵集與計算有關的箴言; 讀者來稿中有些是無爭議的, e.g. Duff法則是一種很方便的記憶常數的方法; 而下面這個關於程式測試方法的法則中的數字則不那麼絕對(迴歸測試方法儲存老版本的輸入/輸出資料, 以確保新版本程式能得出同樣的輸出); 迴歸測試能將測試區間減半 ——Larry Bernstein 貝爾通訊研究院Bernstein的觀點中所說的數可能是30%也可能是70%, 然而可以確定的是, 這些測試節約了開發時間;
不怎麼定量的忠告也存在問題; 相信大家都會同意; 小別勝新婚; ——佚名 但也說 眼不見, 心不煩; ——佚名最後這句話對每個人都適用, 對這些話本身則不適用; 本章中的很多箴言也存在類似的矛盾; 儘管每句話都有真理存焉, 還是應該有所保留地看待它們; 關於箴言的出處, 不得不聲明一下; 箴言下的名字基本上都是最早把這句話發給我的人; 在一些地方我列出了更早的參考文獻以及作者的單位; 我知道這樣做對不起那些最早說出這句話的人, 只能用下面這句話表達遺憾: 剽竊即是最誠懇的恭維 ——佚名
6.1 編碼 如果還沒想清楚, 就用蠻力演算法吧 ——Ken Thompson,貝爾實驗室
不要使用反正弦和反餘弦函數——總能用優美的恒等式, 或者是計算向量點積來更好地解決這些問題 ——Jim Conyngham, Arvin/Calspan進階技術中心
在儲存日期中的年份的時候, 請使用四位元字: 千禧年快到了 ——David Martin, 賓夕法尼亞州諾裡斯敦
避免不對稱結構 ——Andy Huber, Data General公司
代碼寫得越急, 程式跑得越慢 ——Roy Carlson, 威斯康辛大學
用英語都寫不出來的東西就別指望用代碼寫了 ——Peter Halpern, 紐約州布魯克林
注意細節 ——Peter Weinberger, 貝爾實驗室
如果代碼和注釋不一致, 那很可能兩者都錯了 ——Norm Schryer,貝爾實驗室
如果發現特殊情況太多, 那你肯定是用錯方法了 ——Craig Zerouni, Computer FX公司(英國倫敦)
先把資料結構搞清楚, 程式的其餘部分自現 ——David Jones, 荷蘭阿森
6.2 使用者介面 【最小驚異原則】儘可能讓使用者介面風格一致和可預測 ——幾位讀者提出
電腦產生的輸入通常會讓一個原本設計接受手工輸入的程式不堪重負 ——Dennis Ritchie, 貝爾實驗室
手工填寫的表單中有20%都包含壞資料 ——Vic Vyssotsky, 貝爾實驗室
80%的表單會要你回答沒有必要的問題 ——Mike Garey, 貝爾實驗室
不要讓使用者提供那些系統已經知道的資訊 ——Rick Lemons, Cardinal資料系統公司
所有資料集的80%中, 有95%的資訊量都可以用清晰的圖表示 ——William S. Cleveland, 貝爾實驗室
6.3 調試 在我所有的程式錯誤中, 80%是語法錯誤; 剩下的20%裡, 80%是簡單的邏輯錯誤; 在剩下的4%裡, 80%是指標錯誤; 只有餘下的0.8%才是困難的問題 ——Marc Donner, IBM沃森研究中心
在系統測試階段找出並修正錯誤, 要比開發人員自己完成這一工作多付出2倍的努力; 而當系統已經交付使用之後找出並修正一個錯誤, 要比系統測試階段多付出9倍的努力; 因此, 請堅持讓開發人員進行單元測試 ——Larry Bernstein, 貝爾通訊研究院
不要站著偵錯工具; 那會使得你的耐心減半, 你需要的是全神貫注 ——Dave Storer, 愛荷華州錫達拉皮茲
別在注釋裡陷得太深--注釋很可能會誤導你的, 你要調試的只是代碼 ——Dave Storer,愛荷華州錫達拉皮茲
測試只能證明程式有錯誤, 而不能證明程式沒有錯誤 ——Edsger W. Dijkstra, 德克薩斯大學
新系統的每一個新使用者都可能發現一類新的錯誤 ——Brian Kernighan, 貝爾實驗室
東西沒壞, 就別亂修 ——羅納德?雷根,加州聖巴巴拉
【維護者箴言】如果我們沒能力修好它, 我們就會告訴你它根本就沒壞 ——Walt Wei, 美國陸軍中校
修正程式錯誤的第一步是要先重現這個錯誤 ——Tom Duff, 貝爾實驗室
6.4 效能 【程式最佳化第一法則】不要最佳化 【程式最佳化第二法則—僅對專家適用】還是不要最佳化 ——Michael Jackson, Michael Jackson系統公司
對於那些快速演算法, 我們總是可以拿一些速度差不多但是更容易理解的演算法來替代它們 ——Douglas W. Jones, 愛荷華大學
在一些機器上, 間接定址比基址定址要慢, 所以請把結構體或記錄中最常用的成員放在最前面 ——Mike Morton, 麻薩諸塞州波士頓
在一個非I/O密集型的程式中, 超過一半的已耗用時間是花在不足4%的代碼上的 ——Don Knuth,斯坦福大學
在最佳化一個程式之前, 請先用效能監控工具找到程式的"熱點" ——Mike Morton, 麻薩諸塞州波士頓
【代碼規模守恒定律】當你為了加速, 把一頁代碼變成幾條簡單的指令時, 請不要忘了增加註釋, 以使源碼的行數保持為一個常量 ——Mike Morton,麻薩諸塞州波士頓
如果程式員自己類比實現一個構造比編譯器本身實現那個構造還要快, 那編譯器的作者也太失敗了 ——Guy L. Steele, Jr., Tartan實驗室
要加速一個I/O密集型的程式, 請首先考慮所有的I/O; 消除那些不必要的或冗餘的I/O, 並使餘下的部分儘可能地快; ——David Martin,賓夕法尼亞州諾裡斯敦
最快的I/O就是不I/O ——Nils-Peter Nelson,貝爾實驗室
那些最便宜, 最快而且可靠性最高的電腦群組件壓根兒就不存在 ——Gordon Bell,Encore電腦公司
大多數的組合語言都有迴圈操作, 用一條機器指令進行一次比較並分支; 儘管這條指令是為迴圈設計的, 但在做普通的比較時往往也能派上用場, 而且很有效 ——Guy L. Steele, Jr.,Tartan實驗室
【編譯器作者箴言——最佳化步驟】把一個本來就錯了的程式變得更糟絕不是你的錯 ——Bill McKeeman, 王安公司
電每納秒傳播一英尺 ——Grace Murray Hopper, 美國海軍准將
Lisp程式員知道所有東西的值, 卻不知道那些東西的計算成本 ——Alan Perlis, 耶魯大學
6.5 文檔 【否定測試】如果一句話反過來就必然不成立, 那就根本沒必要把這句話放進文檔 ——Bob Martin, AT&T公司
當你試圖解釋一條命令, 一個語言特性或是一種硬體的時候, 請首先說明它要解決什麼問題 ——David Martin, 賓夕法尼亞州諾裡斯敦
【一頁原則】一個{規格說明, 設計, 過程, 測試計劃}如果不能在一頁8.5英寸×11英寸的紙<譯註1 216mm x 279mm的Letter型紙>上寫明白, 那麼這個東西別人就沒辦法理解 ——Mark Ardis, 王安公司
紙上的工作沒結束, 整個工作也就還沒結束 ——佚名
6.6 軟體管理 系統的結構反映出構建該系統的組織的結構 ——Richard E. Fairley, 王安公司
別堅持做那些沒用的事 ——佚名
【90—90法則】前90%的代碼佔用了90%的預定開發時間, 餘下的10%代碼又花費了90%的預定開發時間<譯註2 由於程式員難以事先預見到困難, 所以開發時間經常延長几乎一倍(90%+90%=180%), 很多軟體企業據此制定開發計劃, 把合理估計出來的開發時間再加倍> ——Tom Cargill, 貝爾實驗室
只有不到10%的代碼用於完成這個程式表面上的目的, 餘下的都在處理輸入輸出, 資料驗證, 資料結構維護等家務活 ——Mary Shaw, 卡內基—梅隆大學
正確的判斷來源於經驗, 然而經驗來源於錯誤的判斷 ——Fred Brooks, 北卡羅來納大學
如果有人基本上做出了你想要做的東西, 你就沒必要自己寫一個新程式; 就算你非寫不可, 也請儘可能多地利用現有的代碼 ——Richard Hill, 惠普公司(瑞士日內瓦)
代碼能借用就借用 ——Tom Duff, 貝爾實驗室
與客戶保持良好的關係可以使生產率加倍 ——Larry Bernstein, 貝爾通訊研究院
把一個現有成熟程式轉移到一種新語言或者新平台, 只需要原來開發的十分之一的時間, 人力, 成本 ——Douglas W. Jones, 愛荷華大學
那些用手做就已經很快了的事情, 就不要用電腦去做了 ——Richard Hill, 惠普公司(瑞士日內瓦)
那些能用電腦迅速解決的問題, 就別用手做了 ——Tom Duff, 貝爾實驗室
我想寫的程式不只是程式, 而且是會寫程式的程式 ——Dick Sites, DEC公司
【Brooks原型定律】計劃好拋棄一個原型, 這是遲早的事 ——Fred Brooks, 北卡羅來納大學
如果開始就打算拋棄一個原型, 那恐怕你得拋棄兩個 ——Craig Zerouni, Computer FX公司(英國倫敦)
原型方法可以將系統開發的工作量減少40% ——Larry Bernstein. 貝爾通訊研究院
【Thompson望遠鏡學徒定律】先做一個4英尺鏡片的(望遠鏡), 再做一個6英尺鏡片的, 這比直接做6英尺鏡片的更省時間 ——Bill McKeeman, 王安公司
拚命幹活無法取代理解 ——H. H. Williams, 加州奧克蘭
做事應該先做最難的部分; 如果最難的部分無法做到, ,那還在簡單的部分上浪費時間幹嘛? 一旦困難的地方搞定了, 那你就勝利在望了; 做事應該先做最簡單的部分; 你開始所預想的簡單部分, 做起來可能是很有難度的; 一旦你把簡單的部分都做好了, 你就可以全力攻克最難的部分了; ——Al Schapira,貝爾實驗室
6.7 其他 【Sturgeon定律—在科幻小說和電腦科學中同等適用】毫無疑問, 90%的軟體都沒什麼用; 這是因為對任何東西而言, 其中的90%都是沒什麼用的; ——Mary Shaw, 卡內斯—梅隆大學
對電腦撒謊是要受到懲罰的 ——Perry Farrar, 馬里蘭州
如果不要求系統可靠, 它可能做任何事情 ——H. H. Williams, 加州奧克蘭
一個人的常量是另一個人的變數 ——Susan Gerhart, Microelectronics and Computer Technology公司
一個人的資料就是另一個人的程式 ——Guy L. Steele, Jr., Tartan實驗室
【KISS法則】用最簡單, 最笨的方法做事 ——佚名
6.8 原理看到這裡, 你一定會接受下面這條不錯的箴言: 別輕信那些看似聰明的法則 ——Joe Condon, 貝爾實驗室
6.9 習題儘管每一條箴言只用了寥寥數語, 但其中大多數是可以很大程度上進行擴寫的(e.g. 可以擴寫為一篇本科生論文); 下面的問題告訴我們應該如何擴充這些箴言; 先讓程式跑起來, 再考慮怎麼讓程式跑得快 ——Bruce Whiteside, 伊利諾州伍德裡奇用類似的方式擴寫其他箴言;1.) 用更精確的語言重新表述箴言; 上面的執行個體可以擴寫為: 在確定程式的正確性之前, 請忽略程式的效率;或是 如果程式不能工作, 那運行再快也沒用; 畢竟, 一個總是給出錯誤結論的空程式是根本不花時間的;2) 舉一個小而具體的執行個體支援你的表述; Kernighan和Plauger在"Elements of Programming Style"第7章中列出了從一個程式源碼中截出的10行糾結而難以理解的代碼; 這段繞人的代碼節省了一次比較, 卻引入了一個小錯誤; 通過"浪費"時間進行一次本可以節省的比較, 他們把十行晦澀的代碼變成了兩行一目瞭然的代碼; 從這一現實教訓中, 他們總結出這個道理: 欲求快, 先求對;3) 尋找這些箴言用於大型程式設計的"實戰故事" a) 很高興這個箴言對於項目實踐有所協助; e.g. 1.2描述的幾個例子, 對系統所進行的效能監控指向了程式執行的關鍵點, 然後可以通過簡單調整這些關鍵點來提高系統效能; b) 忽略這些箴言, 可能導致災難性的結果; 20世紀60年代, Vic Vyssotsky修改一個Fortran編譯器源碼, 想讓一個原本正確的程式更加快速, 卻因而引入了一個程式錯誤; 兩年過去, 這個程式錯誤一直沒有被發現, 因為在100 000次編譯中連一次也沒有調用這個程式; Vyssotsky花在這次不成熟的最佳化上面的時間比僅僅浪費時間更加糟糕, 因為他使一個原本好好的程式出錯了;(不過, 故事教育了Vyssotsky和貝爾實驗室一代代程式員)4) 請評價這些箴言; 哪些是"不變的真理", 哪些在某些情況下會產生誤導? 有一次我曾對Tartan實驗室的Bill Wulf說"如果程式不能工作, 運行得再快也沒有用"; 他舉了一個我們都在用的文檔格式化程式的例子; 儘管這個程式比其前一版本明顯快很多, 但在有些時候會慢得難以忍受, 比如編譯一本書要花上好幾個小時; Wulf用下面這個論據贏得了這場論戰" 正如其他所有大型系統一樣, 這一程式有10個記錄在案的輕微程式錯誤, 而下個月它又將會有10個新的小錯誤被我們發現; 如果給你機會進行選擇, 是要解決現在已知的10個小錯誤, 還是讓程式快10倍呢?"-- <編程珠璣續>
---YCR---
電腦科學箴言集 -- <編程珠璣續>