• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 297,  comments - 15,  trackbacks - 0

            轉自:http://kaifu163tech.blog.163.com/blog/static/54381270200812041447221/

            算法是計算機科學領域最重要的基石之一,但卻受到了國內一些程序員的冷落。許多學生看到一些公司在招聘時要求的編程語言五花八門,就產生了一種誤解,認為學計算機就是學各種編程語言,或者認為,學習最新的語言、技術、標準就是最好的鋪路方法。其實,大家被這些公司誤導了。編程語言雖然該學,但是學習計算機算法和理論更重要,因為計算機語言和開發平臺日新月異,但萬變不離其宗的是那些算法和理論,例如數據結構、算法、編譯原理、計算機體系結構、關系型數據庫原理等等。在“開復學生網”上,有位同學生動地把這些基礎課程比擬為“內功”,把新的語言、技術、標準比擬為“外功”。整天趕時髦的人最后只懂得招式,沒有功力,是不可能成為高手的。

            算法與我

            當我在1980年轉入計算機科學系時,還沒有多少人的專業方向是計算機科學。有許多其他系的人嘲笑我們說:“知道為什么只有你們系要加一個‘科學’,而沒有‘物理科學系’或‘化學科學系’嗎?因為人家是真的科學,不需要畫蛇添足,而你們自己心虛,生怕不‘科學’,才這樣欲蓋彌彰。” 其實,這點他們徹底弄錯了。真正學懂計算機的人(不只是“編程匠”)都對數學有相當的造詣,既能用科學家的嚴謹思維來求證,也能用工程師的務實手段來解決問題——而這種思維和手段的最佳演繹就是“算法”。

            記得我讀博時寫的Othello對弈軟件獲得了世界冠軍。當時,得第二名的人認為我是靠僥幸才打贏他,不服氣地問我的程序平均每秒能搜索多少步棋,當他發現我的軟件在搜索效率上比他快60多倍時,才徹底服輸。為什么在同樣的機器上,我可以多做 60倍的工作呢?這是因為我用了一個最新的算法,能夠把一個指數函數轉換成四個近似的表,只要用常數時間就可得到近似的答案。在這個例子中,是否用對算法才是能否贏得世界冠軍的關鍵。

            還記得1988年貝爾實驗室副總裁親自來訪問我的學校,目的就是為了想了解為什么他們的語音識別系統比我開發的慢幾十倍,而且,在擴大至大詞匯系統后,速度差異更有幾百倍之多。他們雖然買了幾臺超級計算機,勉強讓系統跑了起來,但這么貴的計算資源讓他們的產品部門很反感,因為“昂貴”的技術是沒有應用前景的。在與他們探討的過程中,我驚訝地發現一個O(n*m)的動態規劃(dynamic programming)居然被他們做成了O(n*n*m)。更驚訝的是,他們還為此發表了不少文章,甚至為自己的算法起了一個很特別的名字,并將算法提名到一個科學會議里,希望能得到大獎。當時,貝爾實驗室的研究員當然絕頂聰明,但他們全都是學數學、物理或電機出身,從未學過計算機科學或算法,才犯了這么基本的錯誤。我想那些人以后再也不會嘲笑學計算機科學的人了吧!

            網絡時代的算法

            有人也許會說:“今天計算機這么快,算法還重要嗎?”其實永遠不會有太快的計算機,因為我們總會想出新的應用。雖然在摩爾定律的作用下,計算機的計算能力每年都在飛快增長,價格也在不斷下降。可我們不要忘記,需要處理的信息量更是呈指數級的增長。現在每人每天都會創造出大量數據(照片,視頻,語音,文本等等)。日益先進的記錄和存儲手段使我們每個人的信息量都在爆炸式的增長?;ヂ摼W的信息流量和日志容量也在飛快增長。在科學研究方面,隨著研究手段的進步,數據量更是達到了前所未有的程度。無論是三維圖形、海量數據處理、機器學習、語音識別,都需要極大的計算量。在網絡時代,越來越多的挑戰需要靠卓越的算法來解決。

            再舉另一個網絡時代的例子。在互聯網和手機搜索上,如果要找附近的咖啡店,那么搜索引擎該怎么處理這個請求呢?

            最簡單的辦法就是把整個城市的咖啡館都找出來,然后計算出它們的所在位置與你之間的距離,再進行排序,然后返回最近的結果。但該如何計算距離呢?圖論里有不少算法可以解決這個問題。

            這么做也許是最直觀的,但絕對不是最迅速的。如果一個城市只有為數不多的咖啡館,那這么做應該沒什么問題,反正計算量不大。但如果一個城市里有很多咖啡館,又有很多用戶都需要類似的搜索,那么服務器所承受的壓力就大多了。在這種情況下,我們該怎樣優化算法呢?

            首先,我們可以把整個城市的咖啡館做一次“預處理”。比如,把一個城市分成若干個“格子(grid)”,然后根據用戶所在的位置把他放到某一個格子里,只對格子里的咖啡館進行距離排序。

            問題又來了,如果格子大小一樣,那么絕大多數結果都可能出現在市中心的一個格子里,而郊區的格子里只有極少的結果。在這種情況下,我們應該把市中心多分出幾個格子。更進一步,格子應該是一個“樹結構”,最頂層是一個大格——整個城市,然后逐層下降,格子越來越小,這樣有利于用戶進行精確搜索——如果在最底層的格子里搜索結果不多,用戶可以逐級上升,放大搜索范圍。

            上述算法對咖啡館的例子很實用,但是它具有通用性嗎?答案是否定的。把咖啡館抽象一下,它是一個“點”,如果要搜索一個“面”該怎么辦呢?比如,用戶想去一個水庫玩,而一個水庫有好幾個入口,那么哪一個離用戶最近呢?這個時候,上述“樹結構”就要改成“r-tree”,因為樹中間的每一個節點都是一個范圍,一個有邊界的范圍(參考:http://www.cs.umd.edu/~hjs/rtrees/index.html)。

            通過這個小例子,我們看到,應用程序的要求千變萬化,很多時候需要把一個復雜的問題分解成若干簡單的小問題,然后再選用合適的算法和數據結構。

            并行算法:Google的核心優勢

            上面的例子在Google里就要算是小case了!每天Google的網站要處理十億個以上的搜索,GMail要儲存幾千萬用戶的2G郵箱,Google Earth要讓數十萬用戶同時在整個地球上遨游,并將合適的圖片經過互聯網提交給每個用戶。如果沒有好的算法,這些應用都無法成為現實。

            在這些的應用中,哪怕是最基本的問題都會給傳統的計算帶來很大的挑戰。例如,每天都有十億以上的用戶訪問Google的網站,使用Google的服務,也產生很多很多的日志(Log)。因為Log每分每秒都在飛速增加,我們必須有聰明的辦法來進行處理。我曾經在面試中問過關于如何對log進行一些分析處理的問題,有很多面試者的回答雖然在邏輯上正確,但在實際應用中是幾乎不可行的。按照他們的算法,即便用上幾萬臺機器,我們的處理速度都跟不上數據產生的速度。

            那么Google是如何解決這些問題的呢?

            首先,在網絡時代,就算有最好的算法,也要能在并行計算的環境下執行。在Google的數據中心,我們使用的是超大的并行計算機。但傳統的并行算法運行時,效率會在增加機器數量后迅速降低,也就是說,十臺機器如果有五倍的效果,增加到一千臺時也許就只有幾十倍的效果。這種事倍功半的代價是沒有哪家公司可以負擔得起的。而且,在許多并行算法中,只要一個結點犯錯誤,所有計算都會前功盡棄。

            那么Google是如何開發出既有效率又能容錯的并行計算的呢?

            Google最資深的計算機科學家Jeff Dean認識到, Google 所需的絕大部分數據處理都可以歸結為一個簡單的并行算法:Map and Reduce(http://labs.google.com/papers/mapreduce.html)。這個算法能夠在很多種計算中達到相當高的效率,而且是可擴展的(也就是說,一千臺機器就算不能達到一千倍的效果,至少也可以達到幾百倍的效果)。Map and Reduce的另外一大特色是它可以利用大批廉價的機器組成功能強大的server farm。最后,它的容錯性能異常出色,就算一個server farm里面的機器down掉一半,整個farm依然能夠運行。正是因為這個天才的認識,才有了Map and Reduce算法。借助該算法,Google幾乎能無限地增加計算量,與日新月異的互聯網應用一同成長。

            算法并不局限于計算機和網絡

            舉一個計算機領域外的例子:在高能物理研究方面,很多實驗每秒鐘都產生幾個TB的數據量。但因為處理能力和存儲能力的不足,科學家不得不把絕大部分未經處理的數據丟棄掉??纱蠹乙溃略氐男畔⒑苡锌赡芫筒卦谖覀儊聿患疤幚淼臄祿锩?。同樣的,在其他任何領域里,算法都可以改變人類的生活。例如人類基因的研究,就可能因為算法而發明新的醫療方式。在國家安全領域,有效的算法可能避免下一個 911的發生。在氣象方面,算法可以更好地預測未來天災的發生,以拯救生命。

            所以,如果你把計算機的發展放到應用和數據飛速增長的大環境下,你一定會發現,算法的重要性不是在日益減小,而是在日益加強。

            給程序員的七個建議

            (1)練內功。不要只花功夫學習各種流行的編程語言和工具,以及某些公司招聘廣告上要求的科目。要把數據結構、算法、數據庫、操作系統原理、計算機體系結構、計算機網絡,離散數學等基礎課程學好。大家不妨試試高德納所著The Art of Computer Programming里的題目,如果你能夠解決其中的大部分題目,就說明你在算法方面有一定的功力了。

            (2)多實戰。通過編程的實戰積累經驗、鞏固知識。很多中國大學畢業生缺乏編程和調試經驗;學習C語言,考試過關就算學會了;課題項目中,只要程序能夠編譯,運行,并且輸入輸出滿足要求就算了事。這些做法是不行的。寫程序的時候,大家必須多想想如何把程序寫得更加精煉、高效、高質量。建議大家爭取在大學四年中積累編寫十萬行代碼的經驗。我們必須明白的是:好程序員是寫出來的,不是學出來的。

            (3)求實干。不要輕視任何實際工作,比如一些看似簡單的編碼或測試。要不懈追求對細節一絲不茍的實干作風與敬業精神。我發現不少程序員對于知識的掌握很膚淺,不求甚解,沒有好奇心,不會刨根問底。比如,學會了C++,是否了解一個對象在編譯后,在匯編代碼中是如何被初始化的?這個對象的各個成員在內存中是如何存放的?當一個成員函數被調用時,編譯器在匯編代碼中加入了哪些額外的動作?虛函數的調用是如何實現的? 這些東西恐怕在編程語言或編譯原理中都沒有詳細提到,只有通過踏實的實干才能真正掌握。

            (4)重視數學學習。數學是思維的體操,數學無處不在。學計算機至少要學習離散數學、概率論、布爾代數、集合論和數理邏輯。這些知識并不難,但是對你未來的工作幫助會很大。 尤其當你對一些“數學密集型”的領域如視頻、圖像處理等有興趣時,這些知識將成為你手中的利器。

            (5)培養團隊精神,學會與人合作。今天的軟件工程早已經不是一個人可以單獨操作的,而必須靠團隊合作才能成功。不懂得合作的人是不能成大器的。大家要多去尋找可以與人一起做項目的機會。

            (6)激勵創新意識,培養好奇心,不要死記硬背。沒有掌握某種算法技術的根本原理,就不會有應變和創新的能力。想成為一位好程序員(其實從事任何一個行業都是如此),重要的是要養成鉆研,好奇,創新,動手,合作的優秀習慣,不滿足于填鴨,不滿足于考試交差,不滿足于表象。這不是學幾門課能夠一蹴而就的。

            (7)有策略地“打工”。在不影響學業的前提下,尋找真正有意義的暑期工作或兼職。去找一個重視技術的公司,在一個好的“老板”指導下完成真正會被用戶使用的程序。不要急于去一個要你做“頭”而獨擋一面的地方,因為向別人學習才是你的目的。找工作也是一樣,不要只看待遇和職銜,要挑一個你能夠學習的環境,一個愿意培養員工的企業,一個重視你的專業的公司。最后,還要挑一個好老板。

            希望大家都能把握機會,養成好的學習習慣,把算法學精學透;希望大家都能有一個美好的未來!

            posted on 2009-05-30 22:21 chatler 閱讀(208) 評論(0)  編輯 收藏 引用 所屬分類: Gossips
            <2010年9月>
            2930311234
            567891011
            12131415161718
            19202122232425
            262728293012
            3456789

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            精品久久久久久无码中文字幕一区| 亚洲AV日韩精品久久久久久久 | A级毛片无码久久精品免费| 香蕉久久夜色精品国产尤物| 亚洲综合熟女久久久30p| 少妇人妻88久久中文字幕| 91精品国产综合久久精品| 精品久久久久久无码国产| 亚洲狠狠婷婷综合久久久久| 日本精品久久久久中文字幕| 中文精品99久久国产 | 久久久国产精品网站| 久久精品综合网| 2020最新久久久视精品爱| 伊人热热久久原色播放www| 99久久精品国产高清一区二区| 久久99精品久久久久久野外| 亚洲va久久久噜噜噜久久狠狠| 精品熟女少妇aⅴ免费久久| 久久国产精品一国产精品金尊| 久久久久这里只有精品| 情人伊人久久综合亚洲| 99久久超碰中文字幕伊人| 亚洲午夜久久久久久噜噜噜| 久久综合五月丁香久久激情| 成人a毛片久久免费播放| 久久久久久久久久久久中文字幕| 亚洲另类欧美综合久久图片区| 国产精品va久久久久久久| 久久青草国产精品一区| 久久99精品久久久久久久不卡 | 亚洲成色999久久网站| 日韩精品久久无码人妻中文字幕| 亚洲欧美一级久久精品| 久久青青色综合| 2021国产精品久久精品| 中文成人无码精品久久久不卡 | 久久影视国产亚洲| 亚洲精品无码久久不卡| 亚洲午夜无码久久久久小说| 伊人伊成久久人综合网777|