雜湊表:為什麼它找東西快到不講理
還記得第一課埋下的那條伏筆嗎?「查會員名單」的版本 B 用了一行 set.has(user),名單從 100 人漲到 1000 萬人,耗時紋絲不動。當時說好第五課揭底——今天就把這個「直達」的魔術拆給你看:它根本不翻,它是算出來的。
回到收納的比喻:大抽屜找東西要挨個翻,是因為你不知道東西在哪。雜湊表的思路徹底反過來——放進去的那一刻,就用一條固定的公式算出它該放在幾號桶;要找的時候,用同一條公式再算一遍,直接開那個桶。這條公式就叫雜湊函式,它是一張「定位公式」:不用翻,一步算出在哪。
下面是 8 個編號 0 到 7 的桶,和 6 個等著入住的名字。點一個名字,看它怎麼三步進桶:先把每個字變成電腦裡的編碼數字並求和,再對 8 求餘(因為只有 8 個桶),最後飛進算出來的那個桶。留意:全程沒有「挨個對比」這個動作,位置完全是算出來的。
你可能已經發現了:阿芳和麗麗算出來都是 2 號桶!這叫雜湊碰撞——桶就 8 個,名字千千萬,撞桶遲早發生。那該怎麼辦?最常用的辦法樸素得可愛:在桶裡掛一條小鏈,後來的排在鏈上(術語叫「鏈地址法」)。按順序點下面三個按鈕,留意查詢時翻了幾次。
現在把資料量拉大,讓兩種找法正面賽跑。選一個資料量,點開跑。留意右邊的計數器:不管左邊翻到天荒地老,它永遠停在 1-2 次。
🗄 翻一遍(線性查詢)
翻找 0 次🗃 直達(雜湊查詢)
翻找 0 次雜湊表可能是你每天被服務次數最多的結構——只是它總躲在幕後。下面四個場景,背後全是同一招「算出位置,一步直達」。
Set 與字典
第一課版本 B 的 Set、Python 的 dict、JS 的 Map——語言裡所有「按 key 取值」的容器,肚子裡都是雜湊表。
快取的鍵
快取要在毫秒內回答「這個問題算過嗎」,靠的就是把問題雜湊成 key 直達查詢——下一課的主角。
去重
訓練語料去重、爬蟲判斷「這個網頁抓過沒」,都是把內容雜湊後進 Set 一查——不然億級資料兩兩對比要算到宇宙熱寂。
session 查詢
你每次開啟 ChatGPT,伺服器拿著 session id 在千萬線上使用者裡瞬間找到你的會話——靠的不是翻名單。
✅ 這一課想和你分享的
- 雜湊函式 = 定位公式:放和找用同一條公式,位置是算出來的,不是翻出來的
- 耗時和資料量無關:6 個人算一次,600 萬人還是算一次——這就是版本 B「直達」的真相
- 碰撞不可怕:撞桶就在桶裡掛條小鏈;鏈太長就加桶重排(擴容)
- 空間換時間:多備一套「定位公式 + 桶」,換來查詢自由——AI 世界裡 Set、字典、快取鍵、去重、session 全是它
- 驗收視角:看到「在大名單裡挨個找」的程式碼,就該問一句「這裡為什麼不用雜湊表?」