左程雲 程式設計師該如何學習演算法?

2021-09-11 02:57:51 字數 3315 閱讀 6181

我是《程式設計師**面試指南--it名企演算法與資料結構題目最優解》的作者 ,書籍涉及演算法與資料結構程式設計題目240道以上,並且個人實現出最優解,大部分題目為面試高頻。

這篇我想寫寫演算法的重要性、我個人是如何學習演算法以及一些如何學習演算法的建議

求職面試必考(校招+社招),且國內工資越高的面試中演算法比重就越大。

我分別說一下國內和國外的**。

· 國內的話,一般來講,工資高的公司在面試時演算法和資料結構題目的比重較大,工資一般的公司比重較小。當然同樣公司的不同崗位,要求也會不同,但總體趨勢就是 國內好公司愛考演算法和資料結構 。這是目前國內網際網路公司的情況。

先拋開演算法,我們來說說面試以及如何準備。

面試中都會考什麼呢?

面試中會考察演算法,作業系統,資料庫,計算機網路,程式語言,專案(校招涉及)/經歷(社招中涉及的更多)

如何準備?

· 作業系統,資料庫,計算機網路,程式語言這些都是平時學習,記住了,理解了,不忘記就可以了

所以,我建議大家面試或者筆試前抽出20%的時間去理解和記憶非演算法和資料結構的題目,剩下的時間就是去刷題。

今天學習演算法變得越來越重要,雖然每個公司行業不同、崗位複雜,但演算法能力強是分析能力和解決問題能力的提現。雖然計算機的處理能力越來越強,但好演算法的**執行效率相比起沒有優化的**,已經不能用快多少倍來描述了。電腦科學有自己的衡量標準,也就我們常說的複雜度標準。同時,學習演算法對理解底層實現是非常重要的,優秀的程式設計師專注細節和底層,具備演算法能力是起點更是基礎。包括今天很多的領域,比如機器學習,深度學習,還有大熱的ai領域,想要研究透徹,都離不開演算法好的大腦。還有很重要的,加薪和跳槽,演算法都起著非常重要的作用。學習演算法可不僅僅是刷題,這一過程中自己的思維和想法的提公升才是學習演算法的最大好處。

本科在華中科技大學計算機學院,這一期間能在學業上讓自己滿意的可能就是沒有掛科而已。碩士在芝加哥大學,出國之前就了解到想要在國外找工作的話,面試時幾乎只考演算法和資料結構的題目,於是開始了刷題,也就是蒐集這方面的題,並且用**實現出來,不斷看題解和與高手討論。 就這樣從2023年到今天,刷了7年演算法和資料結構的面試題。剛開始其實只是為了找工作才開始刷題,但是半年之後就變成了興趣。

剛開始刷題的過程中很不順利,因為很多演算法和資料結構,教材也不會講。而且去網上搜各種各樣的分析文章也讀不懂,感覺基礎差的很遠。當時網上的分析文章,也不會像今天這麼易懂,高手都是把最核心的點說出來,但是我沒摸到人家想說的點之前,就已經不會了。於是就把很多很厚的書拿來啃,書上也看不懂就盡可能的找到高手向人家請教。對書上的題目實現了好幾遍,才發現入了門,頭腦也開始活泛起來。遇到不會的就查,發現一大片知識不知道就練。在網上發帖被嘲笑的日子,其實非常的漲見識,我很珍視那段歲月。當時在國外,學費也貴,因為錢的刺激和好勝心,居然沒有讓我**,而是變成了一種鬥志,用了大量的時間好好刷題。剛開始**實現演算法和資料結構的題目真的非常痛苦,因為這部分的內容相比其他方面的知識絕對算高門檻,而我最開始的基礎也並不好。現在我經常在網上給同學們講題,看到同學們表達的抱怨,那簡直就是當年的我。暗暗發下心願,如果有一天講課,絕對做乙個人人都能聽懂的好老師。但不管怎麼引導,演算法學習都是乙個脫皮換骨的痛苦過程,但好在會迅速上癮,堅持半年之後就能一直堅持下去了。

演算法和資料結構問題的技術累積需要長時間的投入,因為內容又多又雜又難,很多演算法是那種你很懷疑自己再來一輩子也可能想不到的解法。當時作為乙個小白,乙個演算法的意思看懂了,實現起來是如此的難,測試用例總能指出我的幼稚;寫了很多**終於過了這一題,看到高手寫的實現,自己又幻滅了,高手寫的好棒,自己寫的……然後收拾起碎裂一地的三觀,重新出發。解了很多題目之後,類似的題目出現,自己還是會想很久。這讓我意識到,自己缺乏總結,於是開始了總結的過程,也萌生了寫書的衝動。刷完一道題其實是一件很難的事情,因為普通解法很容易,但是最優解真得去耐著性子研究好久,去查資料,去做優化,這個過程很漫長但是足夠迷人。

先跟大家聊聊演算法吧。

在網路上流行一句話:演算法分三種,競賽的演算法、面試的演算法、演算法。雖然我覺得這麼分非常讓人無語,但其實可以去這麼理解,因為競賽、面試和純理論的要求和限制是不同的,所以演算法在不同的要求中展現了不同的樣子。

對於競賽來說,每道題對輸入引數和樣本量的要求都是非常明確的,同時規定的非常明確的還有空間的限制和執行時間的限制。每乙個競賽選手都非常熟練怎麼根據這些提前給好的限制,反推出自己需要實現乙個什麼樣複雜度的解法才能通過。每一行**包含著前輩和自己思考過的優化。

而對於面試來說,限制往往並不明確,造成這個現象的原因也很好理解。競賽中當然是分數最重要。在面試的過程中,與面試官的交流和體現自己想事情的方式、體現自己邏輯的嚴密更重要。所以同一道題,在競賽中必須寫清楚限制,而在面試中一道題剛開始的限制沒那麼多,目的就是縮短你理解題目的時間,讓面試者先寫出一點什麼,然後和面試官展開討論,隨著討論的深入,再逐漸的把限制聊清楚。總之在面試的場合就是想看看你想問題的習慣、軌跡以及表達能力是否符合要求。

當然,不管是什麼要求下的演算法,經常練習演算法和資料結構題目對乙個人在邏輯上的提公升都是顯而易見的,在學校參加acm並取得很好成績的同學,如果不是表達能力特別差的話,是一定會收穫很多offer的,因為思維被鍛鍊的很好。

先找到線團,然後進入線團裡學著怎麼玩。為了進入線團,需要先把基礎知識掌握好。《演算法和資料結構》(教材),你一定要看完+理解。這裡面講的都是不能再基礎的東西了,覺得講得不好,自己搜維基百科。沒辦法,如果堅持不下來,你後面就受罪去吧。

對於線上刷題平台的題目,先不找解答,先自己實現,實現的多爛,複雜度多差,都堅持寫完。然後分析出複雜度。接下來去網上找答案,看到複雜度和你一樣或比你低的,直接略過。看到比你好的,重點看,一定要理解,然後分析為什麼比你的好,如果你真的理解了,你一定能找到別人優化的點。這個過程可能是最奇妙的過程,不要給自己太大壓力,這個過程其實可以很歡樂,你有想法並創造出來,練習了自己的coding能力。別人有更好的實現,推翻了你的所有模型和幻想,你幻滅了,卻也因此找到了讓你血脈噴張方法。這個階段看似苦,實際上其樂無窮。你在學習別人解法的過程中,又了解了很多演算法和資料結構。而且你付出的每一滴汗水,都是結果導向的,可量化的,實實在在的。寫寫簡單的測試函式就可以發現自己方法的執行時間和更好的解法就是沒法比。這是乙個非常培養自驅力的階段,這是乙個只追求解法更快更強的階段。你看到很多經典的結構,你學到很多細思極妙的優化。比讀那些讓你吃力的書更加快樂,也能夠一直啟發你走下去。你苦苦尋找啊,覺得好的不能再好的方法啊,直到有一天,你突然看到乙個更優的解法,相信我,你一定會一整天都在賢者時間裡。

我不建議剛開始刷題的人就直接在網路上蒐集文章開始學習,因為太散了,而且需要花很多時間去鑑別正確與否。當這些內容都掌握之後,再開始在網上蒐集各種各樣的題,並與網友參加各種各樣的討論,會比較高效。把底子打好之後,對於專項演算法的學習就得心應手了,而且會學的很快。 對於很龐大的演算法,我個人的習慣是找例子來引導自己的思路,一點一點的接近演算法的核心。唯一需要注意的是,一定要寫**,光看沒有用的。對於經典演算法的學習,大體上分成幾個階段:

學習永無止境,不管是演算法小白,還是有一定的演算法基礎,提公升演算法永遠都是剛需,希望所有努力和上心的人都能成為大牛。

程式設計師到底該如何學習?

這篇文章只適合入門級的程式設計師。很多人都發訊息問我,有沒有推薦的學習 面試資料啊?哎,我只能說,cracking the coding interview leetcode以及leetcode論壇,topcoder等。可是,這真的適合你嗎?我真的不想做這樣不負責任的回答。因為每個人的學習方法應該是...

程式設計師該如何學習新知識

想必大家都不是張無忌,人家三十年才可以練成的乾坤大挪移,張無忌大俠兩個時辰就可以搞定,作為乙個普通的程式設計師,經常遇到很多新技術和新知識,it界就是這樣,日新月異,那麼我們如何學習一門技術和新知識呢?下面是我粗淺的幾點建議 第一 精通一兩門語言 大家都聽說過術業有專攻這個詞,作為程式設計師一定要乙...

程式設計師該如何學習新知識

想必大家都不是張無忌,人家三十年才可以練成的乾坤大挪移,張無忌大俠兩個時辰就可以搞定,作為乙個普通的程式設計師,經常遇到很多新技術和新知識,it界就是這樣,日新月異,那麼我們如何學習一門技術和新知識呢?下面是我粗淺的幾點建議 第一 精通一兩門語言 大家都聽說過術業有專攻這個詞,作為程式設計師一定要乙...