← 返回部落格列表 Snowflake 全流程面經:電面到 Onsite 的 Infra 側重
Snowflake

Snowflake 全流程面經:電面到 Onsite 的 Infra 側重

2026-07-16

如果說很多公司的面試是在考「你會不會寫這道題」,Snowflake 更像是在考「你能不能把一個系統從頭到尾做扎實」。這篇按 完整 loop 走一遍:從兩輪電話面試到四輪 Virtual Onsite,逐輪說清楚考什麼、面試官盯哪裡,以及一條反覆出現的主線——工程完整性(engineering completeness)。每道題只做輕量拆解,把更多篇幅留給最能拉開差距的 系統設計輪備考。Infra / 資料基礎設施方向的同學尤其值得對號入座。

一、全流程速覽

Snowflake 的軟體工程師 loop 由 兩輪電面 + 四輪 Onsite 組成,節奏緊湊、評分細緻。先用一張表建立整體印象:

階段 輪次 時長 內容 側重
電面 R1 純 coding 1h LRU Cache(Data Infra 團隊) O(1) 實作 + 指標操作細節
電面 R2 純 coding 1h Range Module(線段樹簡化版) 區間合併 + corner case
Onsite R1 coding 1h 滑動視窗眾數 高效更新,不重掃視窗
Onsite R2 coding 1h 帶頻次的區間合併 line sweep + 邊界定義
Onsite R3 BQ 1h 分歧 / 技術權衡 模糊情境下的判斷力
Onsite R4 system design 1h Log Ingestion Service Infra 落地到實作細節

一條貫穿始終的評分線:面試官不滿足於「跑得動」,他們要看你有沒有主動涵蓋邊界、能不能講清楚資料結構選型的理由。 這就是 Snowflake 的 Infra 味道。

二、電面 R1:LRU Cache(輕量拆解)

第一輪由 Data Infra 團隊的面試官出題,人很隨和,題目是經典的 LRU Cache:實作 getput,兩者都要 O(1)。

思路只有兩句話:雜湊表做 O(1) 查找,雙向鏈結串列維護存取順序。 每次存取就把節點挪到串列頭,容量滿了就刪尾節點。面試官真正盯的是 節點更新邏輯和刪除時的指標操作——先斷鏈再接鏈、別丟參照,這一段是評分點。

class Node:
    def __init__(self, key=0, val=0):
        self.key, self.val = key, val
        self.prev = self.next = None

class LRUCache:
    def __init__(self, capacity: int):
        self.cap = capacity
        self.map = {}                       # key -> Node
        # 哨兵節點:head 之後是最近使用,tail 之前是最久未用
        self.head, self.tail = Node(), Node()
        self.head.next, self.tail.prev = self.tail, self.head

    def _remove(self, node):
        node.prev.next, node.next.prev = node.next, node.prev

    def _add_front(self, node):
        node.prev, node.next = self.head, self.head.next
        self.head.next.prev = node
        self.head.next = node

    def get(self, key: int) -> int:
        if key not in self.map:
            return -1
        node = self.map[key]
        self._remove(node)                  # 先摘下
        self._add_front(node)               # 再放到最前
        return node.val

    def put(self, key: int, value: int) -> None:
        if key in self.map:
            self._remove(self.map[key])
        node = Node(key, value)
        self.map[key] = node
        self._add_front(node)
        if len(self.map) > self.cap:
            lru = self.tail.prev            # 最久未用
            self._remove(lru)
            del self.map[lru.key]

時間複雜度get / put 均 O(1);空間複雜度:O(capacity)。

三、電面 R2:Range Module(輕量拆解)

第二輪是 Range Module,可以理解成線段樹的簡化版:實作 addRangequeryRangeremoveRange 三個操作,維護一組不相交區間。

TreeMap(有序映射)存區間是最順的做法:插入時向左右探鄰區間做合併,刪除時可能把一個區間 拆成兩段。面試官會追問 TreeMap 各操作的複雜度,以及兩個高頻 corner case:插入時與既有區間重疊、刪除時正好落在區間中間。Python 沒有內建 TreeMap,用 sortedcontainers.SortedDict 表達同樣的語意即可,面試口頭講清「向左右 floor / ceiling 查找鄰居」是關鍵。

討論重點:把「合併」和「拆分」兩條路徑分別講透,主動報出重疊、包含、相鄰三種關係的處理,比悶頭寫完更能拿分。

四、Onsite R1:滑動視窗眾數(含完整程式碼)

給定整數陣列和視窗大小 k,回傳每個視窗內出現次數最多的元素。要求高效,不能每次重掃整個視窗。

思路:雜湊表記頻次 + 最大堆積取眾數,堆積裡存的是「頻次快照」,用 懶刪除 跳過過期項——這正是面試官反覆追問的點:怎麼高效處理已經不在視窗裡的元素。

import heapq
from collections import defaultdict

def sliding_window_most_frequent(nums, k):
    freq = defaultdict(int)
    heap = []                               # (-count, value) 最大堆積
    res = []
    for i, x in enumerate(nums):
        freq[x] += 1
        heapq.heappush(heap, (-freq[x], x)) # 推入當前頻次快照
        if i >= k - 1:
            # 懶刪除:堆頂快照與真實頻次不符就丟棄
            while -heap[0][0] != freq[heap[0][1]]:
                heapq.heappop(heap)
            res.append(heap[0][1])
            left = nums[i - k + 1]          # 移出視窗最左元素
            freq[left] -= 1
    return res

# 快速自測
if __name__ == "__main__":
    print(sliding_window_most_frequent([1, 3, 3, 2, 1, 1], 3))  # [3, 3, 1, 1]

討論重點:為什麼不每視窗重建堆積(O(nk)),而用懶刪除均攤;堆積裡可能堆積過期項,但每項最多被彈出一次,整體可控。時間複雜度:O(n log n);空間複雜度:O(n)。

五、Onsite R2:帶頻次的區間合併(輕量拆解)

區間可能重疊多次,要輸出合併後的區間 以及每段的頻次

思路是 line sweep:把每個區間拆成起點(+1)和終點(−1)事件,排序後掃描,維護當前活躍計數即為該段頻次。真正的坑在 邊界定義:起點和終點落在同一時間點誰先處理、區間是否 inclusive——這兩點必須在寫之前和面試官對齊。

def merge_intervals_with_freq(intervals):
    events = []
    for s, e in intervals:
        events.append((s, 1))               # 進入:頻次 +1
        events.append((e, -1))              # 離開:頻次 -1
    events.sort()
    res, active, prev = [], 0, None
    for pos, delta in events:
        if prev is not None and pos > prev and active > 0:
            res.append((prev, pos, active)) # [prev, pos) 段的頻次
        active += delta
        prev = pos
    return res

討論重點:把 −1 與 +1 在同一座標上的排序順序講清楚(決定端點是否算重疊)。時間複雜度:O(n log n);空間複雜度:O(n)。

六、Onsite R3:BQ 輪速記

BQ 偏向 判斷力和協作,問題很典型:

我講了一個非同步資料處理系統裡權衡 批次處理延遲 vs 資源使用率 的故事:為什麼在某個資料量級下選擇放大 batch、犧牲一點時延來換吞吐。Snowflake 很看重你能否在 模糊情境下給出有理由的判斷,而不是背標準答案。

七、Onsite R4:系統設計 —— Log Ingestion Service

設計一個簡化的日誌攝取服務,支援高吞吐寫入、持久化儲存,以及查詢最近 N 筆日誌。

這一輪最能體現 Snowflake 的 Infra 底色,面試官要的不是幾個高層的框,而是 能落到實作的具體方案

選型 作用
接入 Load Balancer 分攤寫入壓力、水平擴展
緩衝 Kafka / 自建 ring buffer 削峰、解耦 ingest 與儲存
儲存 S3(落盤) + RocksDB(索引) 持久化 + 快速點查
查詢 time-based index 加速「最近 N 筆」檢索

面試官層層追問的 follow-up:日誌去重、亂序(out-of-order)處理、一致性(consistency)trade-off。整段對話考的是你對 系統瓶頸 的理解——寫入熱點在哪、索引會不會成為記憶體瓶頸、查詢延遲和一致性怎麼取捨。這一輪是全 loop 最能拉開差距的地方,下面單獨給一份備考清單。

八、如何專門備考系統設計輪

系統設計是 Snowflake(尤其 Infra)最看重、也最容易被裸考的一輪。按下面這幾條準備,方向會穩很多:

九、總結:Snowflake 到底在考什麼

一句話——工程完整性 + 系統設計的 trade-off 表達。coding 題本身不算最難,但面試官會把邊界、指標、複雜度、選型理由問到底;系統設計則要求你落到實作、講清瓶頸。把 LRU / Range Module / 滑動視窗 / line sweep 練到能講清「為什麼這麼選」,再把系統設計輪準備成「Infra 落地版」,整個 loop 就穩了。


FAQ

Q1:Snowflake 完整面試流程是怎樣的?

兩輪電話面試(各 1 小時、純 coding)+ 四輪 Virtual Onsite(兩輪 coding + 一輪 BQ + 一輪 system design)。整體偏 Infra 方向,評分核心是工程實作的完整性。

Q2:Snowflake 的 coding 到底難不難?

題目(LRU、Range Module、滑動視窗、line sweep)難度中等偏上,但真正拉分的是細節:懶刪除如何跳過過期元素、TreeMap 各操作複雜度、區間刪除時的拆分、line sweep 端點排序,面試官都會追問到底。

Q3:系統設計輪最容易踩的坑是什麼?

停在高層框圖、不下鑽到實作。以 log ingestion 為例,要能展開 buffer(Kafka / ring buffer)、儲存(S3 + RocksDB)、索引(time-based),並主動討論去重、亂序、一致性的取捨,同時點出系統瓶頸。

Q4:這篇和另一篇 Snowflake Onsite 複盤有什麼區別?

那篇聚焦幾道題的深度解法;這篇走 完整 loop(電面到 Onsite 逐輪),每題輕量拆解,把重點放在 Snowflake 的工程完整性評分標準和系統設計輪的專項備考上,適合先建立全局視角。

Q5:怎麼高效準備 Snowflake VO?

把高頻資料結構題練到能講清選型理由,BQ 準備好「技術權衡」類故事,系統設計準備 Infra 落地版。需要真題限時陪練、系統設計一對一推演,或 VO 輔助 / VO 代面 的即時對接,可以發職位 JD 先做題型預測再排練習計畫。


正在準備 Snowflake 全流程面試?

Snowflake 考的是工程完整性 + Infra 系統設計 + trade-off 表達。oavoservice 提供 Snowflake / 資料基礎設施方向的 VO 全流程陪練:電面高頻題限時模擬、log ingestion 系統設計一對一推演、BQ 權衡故事打磨,也支援 VO 輔助 / VO 代面 的即時對接。教練含前大廠 Infra 工程師,熟悉 Snowflake「摳實作細節」的評分風格。

立即加入微信 Coding0201取得 Snowflake 全流程真題與陪練

聯絡方式