哈希表:為什麼它找東西快到不講理
仲記唔記得第一課嗰條伏筆?「查會員名單」的版本 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 全是它
- 驗收視角:看到「在大名單裏挨個找」的程式碼,就該問一句「呢度點解唔用哈希?」