淺談程式設計師的數學修養
可能有很多朋友在網上看過Google公司早幾年的招聘廣告,它的第一題如下了:{first 10-digit prime found in consecutive digits e}.com,e中出現的連續的第一個10個數字組成的質數。據說當時這個試題在美國很多地鐵的出站口都有大幅廣告,只要正確解答了這道題,在瀏覽器的位址列中輸入這個答案,就可以進入下一輪的測試,整個測試過程如同一個數學迷宮,直到你成為Google的一員。又如Intel某年的一道面試題目:巴拿赫病故於1945年8月31日。他的出生年份恰好是他在世時某年年齡的平方,問:他是哪年出生的?這道看似很簡單的數學問題,你能不能能快地解答呢?下面則是一道世界第一大軟體公司微軟的招聘測試題:中間只隔一個數字的兩個素數被稱為素數對,比如5和7,17和19,證明素數對之間的數字總能被6整除(假設這兩個素數都大於6),現在證明沒有由三個素陣列成的素數對。這樣的試題還有很多很多,這些題目乍初看上去都是一些數學問題。但是世界上一些著名的公司都把它們用於招聘測試,可見它們對新員工數學基礎的重視。數學試題與應用程式試題是許多大型軟體公司面試中指向性最明顯的一類試題,這些試題就是考察應聘者的數學能力與計算機能力。某諮詢公司的一名高階顧問曾說:微軟是一家電腦軟體公司,當然要求其員工有一定的計算機和數學能力,面試中自然就會考察這類能力。微軟的面試題目就考察了應聘人員對基礎知識的掌握程度、對基礎知識的應用能力,甚至暗含了對計算機基本原理的考察。所以,這樣的面試題目的確很“毒辣”,足以篩選到合適的人。
四川大學數學學院的曹廣福教授曾說過:“一個大學生將來的作為與他的數學修養有很大的關係”。大學計算機專業學生都有感觸,計算機專業課程中最難的幾門課程莫過於離散數學、編譯原理、資料結構,當然像組合數學、密碼學、計算機圖形學等課程也令許多人學起來相當吃力,很多自認為資料庫學得很好的學生在正規化、函式依賴、傳遞依賴等數學性比較強的概念面前感到力不從心,這些都是因為數學基礎或者說數學知識的缺乏所造成的。數學是計算機的基礎,這也是為什麼考計算機專業研究生數學都採用最難試題(數學一)的原因,當然這也能促使一些新的交叉學科如數學與應用軟體、資訊與計算科學專業等飛速發展。許多天才程式設計師本身就是數學尖子,眾所周知,Bill Gates的數學成績一直都很棒,他甚至曾經期望當一名數學教授,他的母校——湖濱中學的數學系主任弗雷福·賴特曾這樣談起過他的學生:“他能用一種最簡單的方法來解決某個代數或計算機問題,他可以用數學的方法來找到一條處理問題的捷徑,我教了這麼多年的書,沒見過像他這樣天分的數學奇才。他甚至可以和我工作過多年的那些優秀數學家媲美。當然,比爾也各方面表現得都很優秀,不僅僅是數學,他的知識面非常廣泛,數學僅是他眾多特長之一。”。影響一代中國程式人的金山軟體股份有限公司董事長求伯君當年高考數學成績滿分進一步說明了問題。很多數學基礎很好的人,一旦熟悉了某種計算機語言,他可以很快地理解一些演算法的精髓,使之能夠運用自如,並可能寫出時間與空間複雜度都有明顯改善的演算法。
程式設計當中解決的相當一部分問題都會涉及各種各樣的科學計算,這需要程式設計師具有什麼樣的基礎呢?實際問題轉換為程式,要經過一個對問題抽象的過程,建立起完善的數學模型,只有這樣,我們才能建立一個設計良好的程式。從中我們不難看出數學在程式設計領域的重要性。演算法與計算理論是計算機程式設計領域的靈魂所在,是發揮程式設計者嚴謹,敏銳思維的有效工具,任何的程式設計語言都試圖將之發揮得淋漓盡致。程式設計師需要一定的數學修養,不但是程式設計本身的需要,同時也是培養邏輯思維以及嚴謹的程式設計作風的需要。數學可以鍛鍊我們的思維能力,可以幫助我們解決現實中的問題。可以幫助我們更高的學習哲學。為什麼經常有人對一些科學計算程式一籌莫展,他可以讀懂每一行程式碼,但是卻無法預測程式的預測結果,甚至對程式的結構與功能也一知半解,給他一個稍微複雜點的數學公式,他可能就不知道怎麼把它變成計算機程式。很多程式設計師還停留在做做簡單的MIS,設計一下MDI,寫寫簡單的Class或用SQL語句實現查詢等基礎的程式設計工作上,對於一些需要用到數學知識的程式設計工作就避而遠之,當然實現一個累加程式或者一個稅率的換算程式還是很容易的,因為它們並不需要什麼高深的數學知識。
一名有過10多年開發經驗的老程式設計師曾說過:“所有程式的本質就是邏輯。技術你已經較好地掌握了,但只有完成邏輯能力的提高,你才能成為一名職業程式設計師。打一個比方吧,你會十八般武藝,刀槍棍棒都很精通,但就是力氣不夠,所以永遠都上不了戰場,這個力氣對程式設計師而言就是邏輯能力(其本質是一個人的數學修養,注意,不是數學知識)。”
程式設計師的數學修養不是一朝一夕就可以培養的。數學修養與數學知識不一樣,修養需要一個長期的過程,而知識的學習可能只是一段短暫的時間。下面是一些我個人對於程式設計師如何提高與培養自己的數學修養的基本看法。
首先,應該意識到數學修養的重要性。作為一個優秀的程式設計師,一定的數學修養是十分重要也是必要的。數學是自然科學的基礎,電腦科學實際上是數學的一個分支。計算機理論其實是很多數學知識的融合,軟體工程需要圖論,密碼學需要數論,軟體測試需要組合數學,計算機程式的編制更需要很多的數學知識,如集合論、排隊論、離散數學、統計學,當然還有微積分。電腦科學一個最大的特徵是資訊與知識更新速度很快,隨著數學知識與計算機理論的進一步結合,資料探勘、模式識別、神經網路等分支科學得到了迅速發展,控制論、模糊數學、耗散理論、分形科學都促進了計算機軟體理論、資訊管理技術的發展。嚴格的說,一個數學基礎不紮實的程式不能算一個合格的程式設計師,很多介紹計算機演算法的書籍本身也就是數學知識的應用與計算機實現手冊。
其次,自身數學知識的積累,培養自己的空間思維能力和邏輯判斷能力。數學是一門分支眾多的學科,我們無法在短暫的一生中學會所有的數學知識,像泛函理論、混沌理論以及一些非線性數學問題不是三五幾天就可以掌握的。數學修養的培養並不在與數學知識的多少,但要求程式設計師有良好的數學學習能力,能夠很快地把一些數學知識和自己正在解決的問題聯絡起來,很多理學大師雖然不是數學出身,但是他們對數學有很強的理解能力和敏銳的觀察力,於是一系列新的學科誕生了,如計算化學、計算生物學、生物資訊學、化學資訊學、計算物理學,計算材料學等等。數學是自然學科的基礎,計算機技術作為理論與實踐的結合,更需要把數學的一些精髓融入其中。從計算機的誕生來看它就是在數學的基礎上產生的,最簡單的0、1進位制就是一個古老的數學問題。程式設計作為一項創造性很強的職業,它需要程式設計師有一定的數學修養,也具有一定的數學知識的積累,可以更好地把一些數學原理與思想應用於實際的程式設計工作中去。學無止境,不斷的學習是提高修養的必經之路。
第三,多在實踐中運用數學。有些高等學校開設了一門這樣的課程——《數學建模》。我在大學時期也曾學過,這是一門內容很豐富的課程。它把很多相關的學科與數學都聯絡在一起,通過很多數學模型來解決實際的生產生活問題,很多問題的解決需要計算機程式來實現。我在大學和研究生階段都參加過數學建模競賽,獲得了不少的經驗,同時也進一步提高了自己的數學修養。實際上,現在的程式設計從某些角度來看就是一個數學建模的過程,模型的好壞關係到系統的成敗,現在數學建模的思想已經用於計算機的許多相關學科中,不單只是計算機程式設計與演算法分析。應該知道,數學是一門需要在實踐中展示其魅力的科學,而計算機程式也是為幫助解決實際問題而編制的,因此,應該儘量使它們結合起來,在這個方面,計算機密碼學是我認為運用數學知識最深最廣泛的,每一個好的加密演算法後面都有一個數學理論的支援,如橢圓曲線、揹包問題、素數理論等。作為一名優秀的程式設計師,應該在實際工作中根據需要靈活運用數學知識,培養一定的數學建模能力,善於歸納總結,慢慢使自己的數學知識更加全面,數學修養得到進一步提高。
第四,程式設計師培養制度與教學的改革。許多程式設計師培養體制存在很多缺陷,一開始就要求學員能夠快速精通某種語言,以語言為中心,對演算法的核心思想與相關的數學知識都一筆帶過,講得很少,這造成很多程式設計師成為背程式的機器,這樣不利於程式設計師自身的快速成長,也不利於程式設計師解決新問題。我在長期的程式設計師培訓與計算機教學工作採用了一些與傳統方式不一致的方法,收到了一定的效果。很多初學程式的人往往寫程式時有時候會有思維中斷,或者對一些稍難的程式覺得無法下手,我採用了一些課前解決數學小問題的方法來激勵大家的學習興趣,這些小問題不單單是腦筋急轉彎,其中不少是很有代表意義的數學思考題。通過數學問題來做程式設計的熱身運動,讓學員在數學試題中激發自己的思維能力,記得有位專家曾經說過,經常做做數學題目會使自己變聰明,很長時間不去接觸數學問題會使自己思維遲鈍。通過一些經典的數學問題來培養學員的思維的嚴謹性和跳躍性。很多人可能不以為然,其實有些看似簡單的問題並不一定能夠快速給出答案,大腦也是在不斷的運用中變更加靈活的。不信嗎?大家有興趣可以做做下面這道題目,看看能不能在1分鐘之內想到答案,這只是一道小學數學課後習題。很多人認為自己的數學基礎很好,但是據說這道題目90%以上的人不能在一個小時內給出正確答案。試試,如果你覺得我說的是錯的。
證明:AB+AC>DB+DC(D為三角形ABC的一個內點)。
最後,多學多問,多看好書,看經典。我在這裡向大家推薦兩部可能大家已經很熟悉的經典的計算機演算法教材,它們中間很多內容其實就是數學知識的介紹。第一部是《演算法導論》,英文名稱:Introduction to Algorithms,作者:Thomas H. Cormen,Charles E. Leiserson,Ronald L. Rivest,Clifford Stein。本書的主要作者來自麻省理工大學計算機,作者之一Ronald L.Rivest由於其在公開祕鑰密碼演算法RSA上的貢獻獲得了圖靈獎。這本書目前是演算法的標準教材,美國許多名校的計算機系都使用它,國內有些院校也將本書作為演算法課程的教材。另外許多專業人員也經常引用它。本書基本包含了所有的經典演算法,程式全部由虛擬碼實現,這更增添了本書的通用性,使得利用各種程式設計語言進行程式開發的程式設計師都可以作為參考。語言方面通俗,很適合作為演算法教材和自學演算法之用。另一部是很多人都應該知道的Donald.E.Knuth所著《計算機程式設計藝術》,英文名稱:The Art of Computer Programming。 Donald.E.Knuth人生最輝煌的時刻在史丹佛大學計算機系渡過,美國計算機協會圖靈獎的獲得者,是本領域內當之無愧的泰斗。有戲言稱搞計算機程式設計的不認識Knuth就等於搞物理的不知道愛因斯坦,搞數學的不知道尤拉,搞化學的不知道道爾頓。被簡稱為TAOCP的這本鉅著內容博大精深,幾乎涵蓋了計算機程式設計演算法與理論最重要的內容。現在發行的只有三卷,分別為基礎運演算法則,半數值演算法,以及排序和搜尋(在寫本文之際,第四卷已經出來了,我也在第一時間搶購了一本)。本書結合大量數學知識,分析不同應用領域中的各種演算法,研究演算法的複雜性,即演算法的時間、空間效率,探討各種適用演算法等,其理論和實踐價值得到了全世界計算機工作者的公認。書中引入的許多術語、得到的許多結論都變成了計算機領域的標準術語和被廣泛引用的結果。另外,作者對有關領域的科學發展史也有深入研究,因此本書介紹眾多研究成果的同時,也對其歷史淵源和發展過程做了很好的介紹,這種特色在全球科學著作中是不多見的。至於本書的價值我覺得Bill Gates先生的話足以說明問題:“如果你認為你是一名真正優秀的程式設計師讀Knuth的《計算機程式設計藝術》,如果你能讀懂整套書的話,請給我發一份你的簡歷”。作者數學方面的功底造就了本書嚴謹的風格,雖然本書不是用當今流行的程式設計語言描述的,但這絲毫不損傷它“程式設計史詩”的地位。道理很簡單,它內涵的設計思想是永遠不會過時的。除非英語實在有困難,否則建議讀者選用英文版。我個人就是閱讀的該書的英文版,雖然花了不少money和時間,但是收穫頗豐,值得。
總之,要想成為一名有潛力有發展前途的程式設計師,或者想成為程式設計師中的佼佼者,你一定要培養良好的數學修養。切記:對於一個能夠靈活自如編寫各種程式的人,數學是程式的靈魂。
參考文獻
[1]林慶忠.修煉一名程式設計師的職業水準. http://blog.csdn.net/imwj/archive/2005/02/02/27723.
[2]劉汝佳,黃亮.演算法藝術與資訊學競賽.清華大學出版社: 2004.
[3] Thomas H.Cormen Charles E.Leiserson Ronald L.Rivest Clifford Stein. Introduction to Algorithms (Second Edition). The MIT Press: 2002.
[4] Donald.E.Knuth. The Art of Computer Programming.清華大學出版社: 2002.
[5]姜啟源.數學模型.清華大學出版社: 1993.
[6] Zbigniew Michalewicz, David B. Fogel.如何求解問題:現代啟發式方法.中國水利水電出版社: 2003.
作者簡介:
劉偉,國家認證系統分析員,國家認證資料庫系統工程師,中南大學計算機應用技術博士,有超過十年計算機軟體開發與計算機教學經驗,在多個學校與培訓機構承擔教學工作,參與組織與開發各類資訊系統30多個。學生期間曾獲得全國研究生數學建模競賽全國一等獎和二等獎各一次。參與翻譯外文專著一部,發表論文十餘篇。相關文章
- 很認真的談一談程式設計師的自我修養程式設計師
- 程式設計師的自我修養程式設計師
- 談談對程式設計師的培養程式設計師
- 程式設計師的自我修養之全棧程式設計師程式設計師全棧
- iOS 程式設計師的自我修養 — 讀《程式設計師的自我修養 連結、裝載與庫》iOS程式設計師
- 程式設計師修煉之道—程式設計師如何提高自我修養(2)程式設計師
- 程式設計師修煉之道——程式設計師如何提高自我修養(1)程式設計師
- 淺談程式設計師的英語學習程式設計師
- 一個野生程式設計師的自我修養程式設計師
- 程式設計師的科技道德修養 - idlewords程式設計師
- 程式設計師如何提高自我修養(4)程式設計師
- 《程式設計師的自我修養》-讀書筆記程式設計師筆記
- 程式設計師的自我修養-編譯連結程式設計師編譯
- 讀書筆記 - 《程式設計師的自我修養》筆記程式設計師
- 《程式設計師的自我修養》讀書總結程式設計師
- 程式設計師的自我修養:溫故而知新程式設計師
- 程式設計師自我修養之IT人學習方法論—學習方向程式設計師
- 程式設計師自我修養之程式設計經驗總結程式設計師
- 淺談軟體工程師的程式碼素養軟體工程工程師
- 《程式設計師自我修養》讀書筆記程式設計師筆記
- 淺談程式設計師創業程式設計師創業
- 程式設計師的自我修養筆記之裝載程式設計師筆記
- 【程式設計師的自我修養①】iOS記憶體管理程式設計師iOS記憶體
- 給每個菜鳥程式設計師的修養之道程式設計師
- 產品經理看程式設計師的自我修養程式設計師
- 淺談程式設計師的“內卷化”程式設計師
- 程式設計師自我修養之IT人學習方法論——學習誤區程式設計師
- 淺談前端/軟體工程師的程式碼素養前端軟體工程工程師
- 程式設計修養(一) (轉)程式設計
- 程式設計修養(二) (轉)程式設計
- 程式設計修養(三) (轉)程式設計
- 程式設計修養(五) (轉)程式設計
- 程式設計修養(六) (轉)程式設計
- 程式設計修養(四) (轉)程式設計
- 程式設計修養(七) (轉)程式設計
- 《程式設計師的自我修養》(三)——庫與執行庫程式設計師
- 很認真地聊一聊程式設計師的自我修養程式設計師
- 很認真的聊一聊程式設計師的自我修養程式設計師