數學和計算機 李開復

轉載地址:http://blog.csdn.net/hangxing78/article/details/3988758

老師推薦的,本人覺得很值得一看
數學和計算機      
謹以本文獻給正在學習計算機而忽視數學學習的同學們                               
同學們,希望你們在讀這篇文章的時候保持足夠的耐心,因爲這是很多人成功或者失敗的經驗。當然,是指在計算機的學習中可能會忽視的一些東西。我們以李開復先生的一篇文章開始我們的敘述。
算法的力量  
-          -  摘自李開復 
李開復 簡介:
1961年生於臺灣。 
曾就讀於卡內基梅隆大學,獲計算機學博士學位,後擔任副教授; 
在蘋果公司工作了六年,主管該公司的多媒體部門; 
曾擔任SGI公司的多媒體軟件子公司———Cosmo Software的總裁; 
1998年7月加盟微軟公司,並於11月出任微軟中國研究院(現微軟亞洲研究院)院長; 
2000年升任公司副總裁,調回總部負責自然界面部。李開復是國際知名的語音識別技術專家,原爲卡耐基梅隆大學副教授,曾獲《商業週刊》1988年“年度最重要的科學創新”稱號。 
現任Google全球副總裁、中國區總裁。
 
算法是計算機科學領域最重要的基石之一,但卻受到了國內一些程序員的冷落。許多學生看到一些公司在招聘時要求的編程語言五花八門,就產生了一種誤解,認爲學計算機就是學各種編程語言,或者認爲,學習最新的語言、技術、標準就是最好的鋪路方法。其實,大家被這些公司誤導了。編程語言雖然該學,但是學習計算機算法和理論更重要,因爲計算機語言和開發平臺日新月異,但萬變不離其宗的是那些算法和理論,例如數據結構、算法、編譯原理、計算機體系結構、關係型數據庫原理等等。在“開復學生網”上,有位同學生動地把這些基礎課程比擬爲“內功”,把新的語言、技術、標準比擬爲“外功”。整天趕時髦的人最後只懂得招式,沒有功力,是不可能成爲高手的。
當我在1980年轉入計算機科學系時,還沒有多少人的專業方向是計算機科學。有許多其他系的人嘲笑我們說:“知道爲什麼只有你們系要加一個‘科學’,而沒有‘物理科學系’或‘化學科學系’嗎?因爲人家是真的科學,不需要畫蛇添足,而你們自己心虛,生怕不‘科學’,才這樣欲蓋彌彰。” 其實,這點他們徹底弄錯了。真正學懂計算機的人(不只是“編程匠”)都對數學有相當的造詣,既能用科學家的嚴謹思維來求證,也能用工程師的務實手段來解決問題——而這種思維和手段的最佳演繹就是“算法”。
記得我讀博時寫的Othello對弈軟件獲得了世界冠軍。當時,得第二名的人認爲我是靠僥倖纔打贏他,不服氣地問我的程序平均每秒能搜索多少步棋,當他發現我的軟件在搜索效率上比他快60多倍時,才徹底服輸。爲什麼在同樣的機器上,我可以多做60倍的工作呢?這是因爲我用了一個最新的算法,能夠把一個指數函數轉換成四個近似的表,只要用常數時間就可得到近似的答案。在這個例子中,是否用對算法纔是能否贏得世界冠軍的關鍵。
有人也許會說:“今天計算機這麼快,算法還重要嗎?”其實永遠不會有太快的計算機,因爲我們總會想出新的應用。雖然在摩爾定律的作用下,計算機的計算能力每年都在飛快增長,價格也在不斷下降。可我們不要忘記,需要處理的信息量更是呈指數級的增長。現在每人每天都會創造出大量數據(照片,視頻,語音,文本等等)。日益先進的記錄和存儲手段使我們每個人的信息量都在爆炸式的增長。互聯網的信息流量和日誌容量也在飛快增長。在科學研究方面,隨着研究手段的進步,數據量更是達到了前所未有的程度。無論是三維圖形、海量數據處理、機器學習、語音識別,都需要極大的計算量。在網絡時代,越來越多的挑戰需要靠卓越的算法來解決。
並行算法:Google的核心優勢。每天Google的網站要處理十億個以上的搜索,GMail要儲存幾千萬用戶的2G郵箱,Google Earth要讓數十萬用戶同時在整個地球上遨遊,並將合適的圖片經過互聯網提交給每個用戶。如果沒有好的算法,這些應用都無法成爲現實。在這些的應用中,哪怕是最基本的問題都會給傳統的計算帶來很大的挑戰。例如,每天都有十億以上的用戶訪問Google的網站,使用Google的服務,也產生很多很多的日誌(Log)。因爲Log每分每秒都在飛速增加,我們必須有聰明的辦法來進行處理。我曾經在面試中問過關於如何對log進行一些分析處理的問題,有很多面試者的回答雖然在邏輯上正確,但在實際應用中是幾乎不可行的。按照他們的算法,即便用上幾萬臺機器,我們的處理速度都跟不上數據產生的速度。那麼Google是如何解決這些問題的呢?
首先,在網絡時代,就算有最好的算法,也要能在並行計算的環境下執行。在Google的數據中心,我們使用的是超大的並行計算機。但傳統的並行算法運行時,效率會在增加機器數量後迅速降低,也就是說,十臺機器如果有五倍的效果,增加到一千臺時也許就只有幾十倍的效果。這種事倍功半的代價是沒有哪家公司可以負擔得起的。而且,在許多並行算法中,只要一個結點犯錯誤,所有計算都會前功盡棄。
那麼Google是如何開發出既有效率又能容錯的並行計算的呢?Google最資深的計算機科學家Jeff Dean認識到, Google 所需的絕大部分數據處理都可以歸結爲一個簡單的並行算法:Map and Reduce。這個算法能夠在很多種計算中達到相當高的效率,而且是可擴展的(也就是說,一千臺機器就算不能達到一千倍的效果,至少也可以達到幾百倍的效果)。Map and Reduce的另外一大特色是它可以利用大批廉價的機器組成功能強大的server farm。最後,它的容錯性能異常出色,就算一個server farm裏面的機器down掉一半,整個farm依然能夠運行。正是因爲這個天才的認識,纔有了Map and Reduce算法。藉助該算法,Google幾乎能無限地增加計算量,與日新月異的互聯網應用一同成長。
給程序員的七個建議
(1)練內功。不要只花功夫學習各種流行的編程語言和工具,以及某些公司招聘廣告上要求的科目。要把數據結構、算法、數據庫、操作系統原理、計算機體系結構、計算機網絡,離散數學等基礎課程學好。大家不妨試試高德納所著The Art of Computer Programming裏的題目,如果你能夠解決其中的大部分題目,就說明你在算法方面有一定的功力了。
(2)多實戰。通過編程的實戰積累經驗、鞏固知識。很多中國大學畢業生缺乏編程和調試經驗;學習C語言,考試過關就算學會了;課題項目中,只要程序能夠編譯,運行,並且輸入輸出滿足要求就算了事。這些做法是不行的。寫程序的時候,大家必須多想想如何把程序寫得更加精煉、高效、高質量。建議大家爭取在大學四年中積累編寫十萬行代碼的經驗。我們必須明白的是:好程序員是寫出來的,不是學出來的。
(3)求實幹。不要輕視任何實際工作,比如一些看似簡單的編碼或測試。要不懈追求對細節一絲不苟的實幹作風與敬業精神。我發現不少程序員對於知識的掌握很膚淺,不求甚解,沒有好奇心,不會刨根問底。比如,學會了C++,是否瞭解一個對象在編譯後,在彙編代碼中是如何被初始化的?這個對象的各個成員在內存中是如何存放的?當一個成員函數被調用時,編譯器在彙編代碼中加入了哪些額外的動作?虛函數的調用是如何實現的? 這些東西恐怕在編程語言或編譯原理中都沒有詳細提到,只有通過踏實的實幹才能真正掌握。
(4)重視數學學習。數學是思維的體操,數學無處不在。學計算機至少要學習離散數學、概率論、布爾代數、集合論和數理邏輯。這些知識並不難,但是對你未來的工作幫助會很大。 尤其當你對一些“數學密集型”的領域如視頻、圖像處理等有興趣時,這些知識將成爲你手中的利器。
(5)培養團隊精神,學會與人合作。今天的軟件工程早已經不是一個人可以單獨操作的,而必須靠團隊合作才能成功。不懂得合作的人是不能成大器的。大家要多去尋找可以與人一起做項目的機會。
(6)激勵創新意識,培養好奇心,不要死記硬背。沒有掌握某種算法技術的根本原理,就不會有應變和創新的能力。想成爲一位好程序員(其實從事任何一個行業都是如此),重要的是要養成鑽研,好奇,創新,動手,合作的優秀習慣,不滿足於填鴨,不滿足於考試交差,不滿足於表象。這不是學幾門課能夠一蹴而就的。
(7)有策略地“打工”。在不影響學業的前提下,尋找真正有意義的暑期工作或兼職。去找一個重視技術的公司,在一個好的“老闆”指導下完成真正會被用戶使用的程序。不要急於去一個要你做“頭”而獨擋一面的地方,因爲向別人學習纔是你的目的。找工作也是一樣,不要只看待遇和職銜,要挑一個你能夠學習的環境,一個願意培養員工的企業,一個重視你的專業的公司。最後,還要挑一個好老闆。
希望大家都能把握機會,養成好的學習習慣,把算法學精學透;希望大家都能有一個美好的未來!
 
                         計算機與數學
在李開復先生的文章中的最後他對程序員提出了七點建議,其中有一條就是重視數學學習。計算機和數學有什麼關係呢?
計算機自從其誕生之日起,它的主要任務就是進行各種各樣的科學計算。文檔處理,數據處理,圖像處理,硬件設計,軟件設計等等,都可以抽象爲兩大類:數值計算與非數值計算。作爲研究計算機科學技術的人員,我們大都對計算數學對整個計算機科學的重要性有一些瞭解。但是數學對專業的研究和應用人員究竟有多大的用處呢?我們先來看一下下面的一個流程圖:
上圖揭示了利用計算機解決科學計算的步驟,實際問題轉換爲程序,要經過一個對問題抽象的過程,建立起完善的數學模型,只有這樣,我們才能建立一個設計良好的程序。
四川大學數學學院的曹廣福教授曾說過:“一個大學生將來的作爲與他的數學修養有很大的關係”。大學計算機專業學生都有感觸,計算機專業課程中最難的幾門課程莫過於離散數學、編譯原理、數據結構,當然像組合數學、密碼學、計算機圖形學等課程也令許多人學起來相當吃力,很多自認爲數據庫學得很好的學生在範式、函數依賴、傳遞依賴等數學性比較強的概念面前感到力不從心,這些都是因爲數學基礎或者說數學知識的缺乏所造成的。數學是計算機的基礎,這也是爲什麼考計算機專業研究生數學都採用最難試題(數學一)的原因,當然這也能促使一些新的交叉學科如數學與應用軟件、信息與計算科學專業等飛速發展。許多天才程序員本身就是數學尖子,衆所周知,Bill Gates的數學成績一直都很棒,他甚至曾經期望當一名數學教授,他的母校——湖濱中學的數學系主任弗雷福·賴特曾這樣談起過他的學生:“他能用一種最簡單的方法來解決某個代數或計算機問題,他可以用數學的方法來找到一條處理問題的捷徑,我教了這麼多年的書,沒見過像他這樣天分的數學奇才。他甚至可以和我工作過多年的那些優秀數學家媲美。當然,比爾也各方面表現得都很優秀,不僅僅是數學,他的知識面非常廣泛,數學僅是他衆多特長之一。”。影響一代中國程序人的金山軟件股份有限公司董事長求伯君當年高考數學成績滿分進一步說明了問題。很多數學基礎很好的人,一旦熟悉了某種計算機語言,他可以很快地理解一些算法的精髓,使之能夠運用自如,並可能寫出時間與空間複雜度都有明顯改善的算法。
     程序設計當中解決的相當一部分問題都會涉及各種各樣的科學計算,這需要程序員具有什麼樣的基礎呢?實際問題轉換爲程序,要經過一個對問題抽象的過程,建立起完善的數學模型,只有這樣,我們才能建立一個設計良好的程序。從中我們不難看出數學在程序設計領域的重要性。算法與計算理論是計算機程序設計領域的靈魂所在,是發揮程序設計者嚴謹,敏銳思維的有效工具,任何的程序設計語言都試圖將之發揮得淋漓盡致。程序員需要一定的數學修養,不但是編程本身的需要,同時也是培養邏輯思維以及嚴謹的編程作風的需要。數學可以鍛鍊我們的思維能力,可以幫助我們解決現實中的問題。可以幫助我們更高的學習哲學。爲什麼經常有人對一些科學計算程序一籌莫展,他可以讀懂每一行代碼,但是卻無法預測程序的預測結果,甚至對程序的結構與功能也一知半解,給他一個稍微複雜點的數學公式,他可能就不知道怎麼把它變成計算機程序。很多程序員還停留在做做簡單的MIS,設計一下MDI,寫寫簡單的Class或用SQL語句實現查詢等基礎的編程工作上,對於一些需要用到數學知識的編程工作就避而遠之,當然實現一個累加程序或者一個稅率的換算程序還是很容易的,因爲它們並不需要什麼高深的數學知識。
     一名有過10多年開發經驗的老程序員曾說過:“所有程序的本質就是邏輯。技術你已經較好地掌握了,但只有完成邏輯能力的提高,你才能成爲一名職業程序員。打一個比方吧,你會十八般武藝,刀槍棍棒都很精通,但就是力氣不夠,所以永遠都上不了戰場,這個力氣對程序員而言就是邏輯能力(其本質是一個人的數學修養,注意,不是數學知識)。”
程序員的數學修養不是一朝一夕就可以培養的。數學修養與數學知識不一樣,修養需要一個長期的過程,而知識的學習可能只是一段短暫的時間。下面是一些在業界普遍被承認的對於程序員如何提高與培養自己的數學修養的基本看法。
     首先,應該意識到數學修養的重要性。作爲一個優秀的程序員,一定的數學修養是十分重要也是必要的。數學是自然科學的基礎,計算機科學實際上是數學的一個分支。計算機理論其實是很多數學知識的融合,軟件工程需要圖論,密碼學需要數論,軟件測試需要組合數學,計算機程序的編制更需要很多的數學知識,如集合論、排隊論、離散數學、統計學,當然還有微積分。計算機科學一個最大的特徵是信息與知識更新速度很快,隨着數學知識與計算機理論的進一步結合,數據挖掘、模式識別、神經網絡等分支科學得到了迅速發展,控制論、模糊數學、耗散理論、分形科學都促進了計算機軟件理論、信息管理技術的發展。嚴格的說,一個數學基礎不紮實的程序不能算一個合格的程序員,很多介紹計算機算法的書籍本身也就是數學知識的應用與計算機實現手冊。
     其次,自身數學知識的積累,培養自己的空間思維能力和邏輯判斷能力。數學是一門分支衆多的學科,我們無法在短暫的一生中學會所有的數學知識,像泛函理論、混沌理論以及一些非線性數學問題不是三五幾天就可以掌握的。數學修養的培養並不在與數學知識的多少,但要求程序員有良好的數學學習能力,能夠很快地把一些數學知識和自己正在解決的問題聯繫起來,很多理學大師雖然不是數學出身,但是他們對數學有很強的理解能力和敏銳的觀察力,於是一系列新的學科誕生了,如計算化學、計算生物學、生物信息學、化學信息學、計算物理學,計算材料學等等。數學是自然學科的基礎,計算機技術作爲理論與實踐的結合,更需要把數學的一些精髓融入其中。從計算機的誕生來看它就是在數學的基礎上產生的,最簡單的0、1進制就是一個古老的數學問題。程序設計作爲一項創造性很強的職業,它需要程序員有一定的數學修養,也具有一定的數學知識的積累,可以更好地把一些數學原理與思想應用於實際的編程工作中去。學無止境,不斷的學習是提高修養的必經之路。
    第三,多在實踐中運用數學。有些高等學校開設了一門這樣的課程——《數學建模》。我在大學時期也曾學過,這是一門內容很豐富的課程。它把很多相關的學科與數學都聯繫在一起,通過很多數學模型來解決實際的生產生活問題,很多問題的解決需要計算機程序來實現。我在大學和研究生階段都參加過數學建模競賽,獲得了不少的經驗,同時也進一步提高了自己的數學修養。實際上,現在的程序設計從某些角度來看就是一個數學建模的過程,模型的好壞關係到系統的成敗,現在數學建模的思想已經用於計算機的許多相關學科中,不單只是計算機程序設計與算法分析。應該知道,數學是一門需要在實踐中展示其魅力的科學,而計算機程序也是爲幫助解決實際問題而編制的,因此,應該儘量使它們結合起來,在這個方面,計算機密碼學是我認爲運用數學知識最深最廣泛的,每一個好的加密算法後面都有一個數學理論的支持,如橢圓曲線、揹包問題、素數理論等。作爲一名優秀的程序員,應該在實際工作中根據需要靈活運用數學知識,培養一定的數學建模能力,善於歸納總結,慢慢使自己的數學知識更加全面,數學修養得到進一步提高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章