1. 程式人生 > 實用技巧 >覃超-演算法訓練營 學習方法分享

覃超-演算法訓練營 學習方法分享

精通一個領域的三步走方式

  • Chunk it up 切碎知識點
  • Deliberate Practicing 刻意練習
  • Feedback 反饋

切碎知識點

  • 庖丁解牛的故事
  • 將演算法資料結構分解成一塊一塊相對簡單化、脈絡化的知識腦圖,脈絡相連。

任何一個知識體系都是一棵樹,如果要掌握某個領域的關鍵知識,就需要將知識變成一顆樹狀結構.有最基本的根,然後分出主幹、分出枝葉。最後每個知識點和你所熟悉的知識掛靠在一起,成為樹狀結構。
人腦不適合記憶、理解孤立的知識,腦圖有助於理解。 --- Elon Musk(引自reddit)

如何達到職業頂尖玩家的水平
如果只是停留在和寢室室友一盤盤打遊戲的話,無法達到職業水平

頂級玩家都要把每部分專門拿出來練習,不斷反覆練習、刻意練習,可以達到職業頂尖水平。

對資料結構進行分類:

  • 一維
    • 基礎:array 陣列(string) linked list 連結串列
    • 高階:stack 棧,queue 佇列,deque 雙端佇列,set 集合,map 對映
  • 二維
    • 基礎:tree 樹;graph 圖
    • 高階:binary search tree 二叉搜尋樹,red-black tree,avl,堆 heap,disjoint set 並查集,trie 字典樹,
  • 特殊
    • bitwise 位運算,BloomFilter布隆過濾
    • LRU cache

對資料結構進行分類: 一維資料結構中,高階資料結構是面試的重點 二維資料結構可以看成從一維資料結構中泛化而來

對演算法進行分點:
前三點類似於幾何公理,是演算法的基礎,是所有演算法、資料結構的基石。最樸素的運算操作。最後將演算法化繁為簡之後,可以發現它的根本就是找到它的重複單元,基於重複單元泛化成高階資料結構。所有的複雜演算法,其實就是找它的重複單元是什麼。

  • if-else,switch -> branch
  • for,while loop -> iteration
  • recursion 遞迴(divide & conquer,backtrace)

五點高階演算法: 先默識資料結構,先理解概念點,後面慢慢上手掌握,同時在學習細分知識的時候,不斷複習。(比如某一演算法的時間複雜度、空間複雜度等)

  • Search 搜尋:DFS,BFS,A*
  • Dynamic Programming 動態規劃
  • Binary Search 二分查詢
  • Greedy 貪心
  • Math 數學,Geometry 幾何

注意:在頭腦中回憶上面每種演算法思想和程式碼模板

刻意練習

練習基本功:區別職業選手和業餘選手的根本。

刷演算法題的最大誤區:做一個演算法題目的時候,只做一遍,這就是練習和切題的最大誤區。一遍是完全不夠的。就像是體育選手,一個動作不可能只做一遍就熟練,也沒法將其變成一個條件反射的動作。

  • 基本功是區別業餘和職業選手的根本
  • 基礎動作的分解訓練和反覆練習
  1. 過遍數:類似於背單詞,要多背幾遍。
  2. 五遍刷題法(五毒神掌) 練習自己的弱項,練習實力上缺陷的地方。走出舒適區。

Deliberate Practicing

  • 刻意練習-過遍數(五毒神掌)
  • 練習缺陷、弱點
  • 不舒服、不爽、枯燥
  • 例子:乒乓球、檯球、遊戲

拿CS遊戲為例: 開黑很爽,專項練習更有助於提高。可以專門開地圖練習自己不熟悉的槍(如AK),越是不熟悉而且平時常用,越要多練習。

在學習動態規劃的時候,主動刻意練習二十上百道題,逼自己練習,可以達到熟練的水平。
國家隊乒乓球練習:反覆練習一個動作,先無球,後有球,每天堅持練習,將基本功練紮實。(不要煩leetcode上的題目過於重複,這有助於練習基本功)
職業檯球選手,在練習時都是練習很工整的球陣型。就類似於在leetcode上反覆不斷的練習典型的同一個題目。不斷的過遍數。
內心不要浮躁,不要總想著用一些高大上的框架。先將基本功練好,後面在工程中coding才能事半功倍。職業選手的訓練方法如此,何況普通人。

反饋(feedback)

分為兩種:主動反饋和被動反饋

  • 即時反饋
  • 主動反饋
    • 高手程式碼(github、leetcode etc)
    • 第一視角直播
  • 被動反饋(高手指點)
    • code review
    • 教練看你打,給你反饋

刷題技巧

在寫任何一個題目、面試答一個題目之前,先養成四步系統化的思考題目的方式(切題四件套

  1. clarification(多看幾次題目,和麵試官多溝通,確保理解題目準確)

  2. Possible Solutions(非常重要!看到題目之後,想 所有可能的解法 來解題,先過一遍。
    不要只用想到的第一種寫法去解題),比較不同的方法時間、空間複雜度的區別,從中找出最優解法

    • Compare(space/time)
    • optimal(加強)
  3. Coding 寫程式碼。

  4. Test cases 列舉測試樣例。

五毒神掌(五遍刷題法,任何題目都至少刷5遍)

  • 第1遍:(適合初次練習)

    • 5分鐘:讀題+思考(如果基礎薄弱,可以給自己10分鐘到15分鐘時間)。
      如果在思考時間內沒有任何思路,不知道怎麼做的話也很正常。
    • 直接看解法
      適用於上一點中沒有任何思路的情況下,有思路的話直接Coding就行了。
      同時注意比較多解法,比較解法優劣。
      演算法的本身是要理解、運用的,而不是自己發明創造
    • 背誦、默寫好的解法。
      背誦和默寫很重要,在背誦和默寫的基礎上,可以慢慢做到理解。
  • 第2遍:(在第1遍的基礎之上,這時候沒必要看他人的解法了)

    • 馬上自己寫 -- > leetcode上提交,不斷Debug修改
    • 多種解法比較、體會-->優化。
      比較不同解法的時間、記憶體消耗。
    • 對於執行時間長的Code,多想優化策略。
    • 直到所有不同解法都是優的(領先90%以上,80%也不錯)。
  • 第3遍:(在第2遍的基礎之上,過了24小時之後,做前一天做過的題目)

    • 對於不同解法熟練程度不一樣,針對性的對自己不是特別熟的題目進行專項練習。
  • 第4遍:(第3遍過了一週之後,反覆回來練習相同的題目,同時對於不熟練的題目進行專項練習)

    • 完成了第4遍,基本上對於相關知識點掌握的比較牢固了
  • 第5遍 :(針對面試,面試前一個星期、兩個星期進行恢復性訓練。)

    • 將之前做過的題目再做一遍
    • 時間視面試準備程度而定,按照自己的時間計劃安排

預期達到的效果:看到一道演算法題,馬上就能產生肌肉式記憶,並馬上能得到相關的系列解法(解法1、解法2、解法3…,同時清楚知道所有解法的優劣程度)

經驗-如何應對演算法面試?

  • 不要死磕。不要對於寫的又臭又長又充滿bug的程式碼,不停的打補丁。就算最後花費大力氣通過了,也沒什麼進步。因為這時候已經耗幹了精力,沒有力氣再去看優秀的題解了。這樣刷題的效率是最低。

  • 遇到自己搞不定的,直接放棄,去看優秀題解。

  • 提升英文打字速度,做職業的程式設計師。

  • 消遣和娛樂方式,不要去刷抖音,而是去刷easy的題目。

語言基礎的鞏固

  • Java記憶體?全域性、區域性、棧變數、堆變數
  • 工具翻新(vscode/idea/google/iterm)
  • 打字練習 typing.io,speedcoder.net
  • 其他:cs-notes,labuladuo演算法fucking-algorithm(谷歌搜尋),cheatsheet(快捷鍵)
  • 科學做題、科學看資料

高效學習

  • 分清優先順序,時間是擠出來的
  • 費曼學習法:以教為學
  • 腦圖+五毒神掌
  • 做能夠帶來長期複利的事。

早日完成300題,拿下理想公司offer。

每週四:模擬面試。

挑選,考試和完成度很高的學員參加模擬面試。

FAQ

  1. 為什麼在過去,似乎資料結構與演算法不是很好的人,也可以找到很好的工作?
    答:在過去,中國經濟發展比較快,程式設計師崗位大量空缺,而在大學裡的知識又太水,很多人還沒準好,就已經上崗了。而現在中國經濟放緩,接下來將是存量程式設計師之間的競爭,基本功會越來越重要。
  2. 現在學的演算法,在以後工作中用的到麼?
    答:絕對絕對能用的到。相信超哥,演算法很重要。這種內功心法的鍛鍊,是經久不衰的。從10年前,20年前,從谷歌到facebook、Amazon,再到國內的BAT、TMD,為什麼都考這個?把這個練好了,程式碼速度、程式碼邏輯和其他方面都要比一般的程式設計師好。
  3. 年齡太大學習演算法,晚不晚?
    答:腦子的細胞是有大量冗餘的,不同年齡只是體現在學習的速度上,而在邏輯思維上沒有損耗。短期記憶會慢,但是長期記憶沒有影響。可參見Growth mindset(谷歌搜尋)
  4. 35歲失業的原因:公司養你的成本高於你對公司的貢獻。
    答:第一性原理可解釋(埃隆 馬斯克)

參考連結