程式設計珠璣,字字珠璣
文章來源:http://www.infoq.com/cn/news/2011/11/programming-pearls
作者:丁雪豐
無論你自稱是“程式猿”還是“攻城師”,只要在寫程式,都免不了要和演算法打交道。說起演算法,第一本從你的記憶中檢索出的圖書是什麼呢?是經典的大部頭《演算法導論》?還是之前大紅大紫的《程式設計之美》?以前它們幾乎是同時映入我腦海的,分不清誰先誰後,這兩本書我都讀過,前者是在學校的演算法課上,而後者則是在畢業求職前。
最近,我終於有了一個明確的答案,在這些演算法相關的書籍中,最讓我愛不釋手的是《程式設計珠璣》這本薄薄的小冊子,因為它真正激發起了我對學習演算法的熱情。不愧是培養了James Gosling(Java之父)、Charles Leiserson(《演算法導論》作者)等眾多大師的“超級大師”的傳世之作。與學校裡接觸的“教材式”的書不同,《程式設計珠璣》更像是“問答式”的,丟擲一個由實際問題簡化而來的問題,然後一步步進行分析解答,作者將想要傳達給讀者的知識與技巧貫穿其中,期間還經常讓人發自內心地感嘆一下,原來還能這麼做。
以書中第8章為例,我把問題簡單描述為“輸入一個長度為n的陣列x,求其中任意連續子元素相加的最大和”。最常規的思路就是寫一個三層巢狀的迴圈,演算法的執行時間為O(n3),時間似乎有點長,做點優化,充分利用之前的計算結果,可以節省一層迴圈,於是得出了一個O(n2)的演算法。如果引入“分治”的思路,將陣列拆開,分別求解,然後再合併起來,這樣只需O(nlogn)的時間。別以為這樣就結束了,終極方案總是出現在最後的,直接從頭開始掃描陣列,一次掃描得出結果(具體演算法請允許我賣個關子),O(n)時間內就能解決問題,神奇吧。千萬不要以為這是專門用來教授演算法知識的假想的“教學問題”,這可是源自布朗大學的Ulf Grenander曾經遇到過的真實問題,可見設計一個好的演算法是多麼重要。
在日常工作中,估計大多數人都不太有機會遇到太複雜的演算法,就算遇到了,也可以僥倖依靠強大的計算和儲存能力來解決問題。誠然現在的伺服器計算能力越來越強,1個核心可以抵得上從前的幾個龐然大物,更何況CPU還是多核的,記憶體都按GB計算,但不能因為這樣就認為現在演算法和資料結構的重要性不如從前了。假設上文提到的問題中不是計算陣列元素,而是每次迴圈需要運算元據庫或者呼叫遠端服務,一次操作就要耗時幾毫秒,甚至是幾百毫秒,那麼O(n3)和O(n)的區別就顯而易見了。加伺服器不是唯一的解決方案,有時簡單地調整演算法能讓你省下大把的金錢和時間。
再來說說空間的問題,節省空間似乎已經不再重要了,對某些人來說是這樣,但不可否認還是存在很多場景,需要錙銖必較,仔細地設計演算法和資料結構。嵌入式裝置就不說了,來說說眼下流行的Redis,為了能最大限度地使用好伺服器的記憶體空間,減少浪費,antirez在編寫Redis時就煞費苦心地改良資料結構,真的是能省1位元組算1位元組。HDFS和BigTable面向海量儲存,照理說它們都是不缺空間的主,可是其中還是提供了LZO、Snappy等眾多壓縮演算法,用“閒置”的CPU運算時間來換取更多的空間……類似的例子還有很多,所以在編寫程式碼時,如果條件允許,請再多考慮一下自己的實現。
多數Java程式設計師應該都有GC調優的經歷,遇到GC過於頻繁,耗時太長的情況,通常會對JVM的堆配置做調整,如果調整的效果都不明顯呢?來看看程式碼吧,也許對程式碼稍作修改,優化下演算法,就能把陡峭的記憶體增長曲線將下來了。啊哈,演算法!
書中還時不時地回顧下歷史,比如二分搜尋,相信大多數人都知道是怎麼回事,可是你知道麼,第一篇二分搜尋的論文1946年就發表了,可是直到1962年才有人寫出了第一個完全正確的二分搜尋程式,太讓人驚訝了,這個可是如今演算法教材上的標配啊。還有那些在編碼規範中經常出現的最長不要超過80個字元,其中80的由來原來和早期的打孔卡有關(如果對這個話題感興趣,可以閱讀阮一峰的這篇文章)。
薄薄的《程式設計珠璣》,兩百多頁捧在手上完全沒有板磚的壓力,可以將其作為教材以外的輔助讀物,工具書以外的休閒讀物,亦或者是和我一樣,將其作為睡前讀物,每晚睡前讀上幾頁,和演算法聊上幾句,和資料結構打個招呼。
相關文章
- 程式設計珠璣:續(程式設計珠璣.Ⅱ修訂版)程式設計
- 程式設計珠璣程式設計
- 把《程式設計珠璣》讀薄程式設計
- iOS面試珠璣iOS面試
- 《程式設計珠璣》第二章-迴圈移位程式設計
- 《程式設計珠璣》第2章三個問題程式設計
- [心得] Linux使用技巧珠璣Linux
- 《程式設計珠璣》第一章-點陣圖排序程式設計排序
- 《程式設計珠璣》程式碼之路15:節省空間的常見姿勢程式設計
- 一本書到底有幾個版本?——《程式設計珠璣》和《重構》程式設計
- 《程式設計珠璣》程式碼之路11:最大子陣列和問題,花式七種解法程式設計陣列
- 《程式設計珠璣》程式碼之路13:陣列如何線上性時間內實現多次區間修改程式設計陣列
- 《程式設計珠璣》程式碼之路14:兩個不會演算法也能把效率提升4倍的小套路程式設計演算法
- 《程式設計珠璣》程式碼之路12:如何用C/C++實現array[-1]並利用它寫出優美的程式碼程式設計C++
- 面試中如何剔除“魚目混珠”程式設計師?面試程式設計師
- 彈珠 題解
- 五彩珠遊戲遊戲
- Fever Time! 彈珠與少女——核心戰鬥節奏設計淺析
- Zen Pinball Party Mac(彈珠遊戲)Mac遊戲
- 珠聯跳棋2.27之註冊分析
- 龍珠:超宇宙遊戲 中文移植版遊戲
- 高效產生一組不重複的隨機數(受程式設計珠磯啟示)java實現隨機程式設計Java
- CSS3五連珠載入等待效果CSSS3
- 小遊戲五子連珠消除解決方案遊戲
- 譯海拾珠 | 美國律所能採用公司形式嗎?
- 數字天空簽下《龍珠》《仙劍》等多個IP
- 歷史的遺珠:圖靈測試與人工智慧圖靈人工智慧
- 智慧電話如何迭代?杜絕被魚龍混珠給迫害
- 《怪物彈珠》國服:遊戲性再強,終敗在水土不服?遊戲
- 磁珠和電感在解決EMI和EMC的不同應用
- 畫素、彈珠、勇者鬥魔王,這款小眾遊戲如何吸引玩家?遊戲
- PlayCoin與Qbao Network珠聯璧合---共同開啟全新遊戲平臺遊戲
- Cocos2d-x 小試牛刀五子連珠遊戲遊戲
- 快手團購小程式先鋒者張哥:哪有一夜暴富,不過慧眼識珠,負重前行
- 數字孿生港珠澳大橋,大灣區綜合管理資訊系統
- 數字孿生港珠澳大橋:大灣區綜合管理資訊系統
- 讓港珠澳大橋如此長壽的祕訣:先進的防腐蝕技術
- 廣州珠源資訊科技有限公司 招聘JAVA 專案經理和開發人員Java