學習演算法的真正目的#

學習資料結構和演算法,並不是為了死記硬背幾個知識點,而是為了:

  • 建立時間複雜度、空間複雜度意識
  • 寫出高品質的程式碼
  • 能夠設計基礎架構
  • 訓練邏輯思維

我們學任何知識都是為了「用」的,是為了解決實際工作問題的。

高手與普通人的差距,往往是「數量級」的#

物理學界曾把物理學家分成五個等級,每一級之間的貢獻相差大約一個數量級——也就是十倍。工程師之間也是如此:一流工程師的產出,常常不是比二流好 20%、30%,而是好上十倍。賈伯斯就說過,一個頂尖工程師可以頂得上五十個平庸工程師。

這種「數量級差距」從哪裡來?很大一部分,就藏在演算法的選擇裡。

人類天生對「大數」沒有概念,因為我們活在小數的世界裡;也對計算機的高速無感,因為我們活在一個很慢的世界裡。正因如此,我們的直覺會嚴重低估當資料規模變大時,複雜度差異帶來的後果——這正是必須刻意訓練 Big-O 思維的理由。

舉個讓人脊背發涼的例子:圍棋的變化數約為 3³⁶¹ ≈ 2×10¹⁷²,而整個可觀測宇宙的基本粒子數量只有約 10⁸⁰。換句話說,即使把宇宙中每一個粒子都變成一個宇宙、再把所有粒子數一遍,總數仍遠少於圍棋的變化數。指數爆炸的威力,遠超任何人的直覺。

一個真實的故事:某位工程師實習時負責對帳模組,用了一個笨演算法。當資料量增大十倍,執行時間卻多出了幾十倍;最後一位同學只改了十幾行程式碼就解決了。演算法的差異,是實打實的真金白銀。

不同角色的學習必要性#

業務開發工程師#

你可能會說:「我整天就是做資料庫 CRUD,哪裡用得到演算法?」

確實,大部分業務開發利用封裝好的介面、類別庫來堆砌業務邏輯,很少需要自己實作資料結構和演算法。但是:

  • 不需要自己實作,不代表不需要了解
  • 不懂原理,如何選擇 ArrayList 還是 LinkedList?
  • 不懂複雜度分析,如何評估程式碼的效能?

常用的框架如 Spring、RPC、Redis 等,都揉合了大量資料結構和演算法的設計思想。掌握這些知識,能更好地使用它們,出問題時也更容易定位。

基礎架構研發工程師#

不同的人做出的框架,架構設計思路都差不多,但品質差異巨大。高手之間的競爭在於細節

  • 演算法是否夠最佳化
  • 資料存取效率是否夠高
  • 記憶體是否夠節省

這些累積起來,決定了一個框架是否優秀。

資深工程師#

有的人寫程式從來不考慮非功能性需求,只完成功能、湊合能用就好。十年的積累可能跟一年沒有任何區別。

在大公司面對千萬級甚至億級使用者時,效能幾乎是開發過程中時刻都要考慮的問題。一個簡單的 ArrayList、LinkedList 的選擇,就可能產生成千上萬倍的效能差別。

面試的角度#

大公司面試為什麼喜歡考演算法?

  • 校園徵才:學生沒有實際專案經驗,只能考察基礎知識是否牢固
  • 有經驗者徵才:越厲害的公司,越注重基礎知識,因為他們更看重長期潛力而非短期能力

小結#

角色學習必要性重點
業務開發選型判斷、效能評估
基礎架構極高細節最佳化、框架設計
資深工程師極高大規模系統效能

資料結構和演算法如果不去學,可能真的這輩子都用不到。但一旦掌握,你就會常常被它的強大威力所折服。之前需要費很大勁最佳化的程式碼,用了資料結構和演算法之後,很容易就可以解決。