01單一檔案最大可以到多大?
使用者可從任何裝置上傳與下載,單檔最大 50 GB。
免費完整指南
設計檔案同步系統。請涵蓋File chunking strategy and content-hash based deduplication across users, Delta sync: rsync-style block diffing instead of re-uploading whole files, Metadata service (file tree, versions)...
面試節奏保持精簡,讓頁面能把注意力花在真正的設計決策上。
不要只是陳述需求,要主動問出來。每張卡把設計限制和一句你可以在畫架構前說出口的釐清問句配成一組。
01單一檔案最大可以到多大?
使用者可從任何裝置上傳與下載,單檔最大 50 GB。
02同步是自動的嗎,離線編輯會怎樣?
檔案在所有裝置間自動同步。離線時做的編輯,會在裝置重新連線時併回來。伺服器上的那份是真相來源。
03分享是什麼意思——一份副本,還是同一個檔案?
分享給的是同一份檔案的存取權,不是一份副本。收到的人在自己的檢視裡看到它。任何更新都會傳到每個有存取權的人。
04資料夾、移動與重新命名算是檔案操作嗎?
不會。資料夾只是 metadata。移動與改名只動 metadata,永遠不碰儲存的區塊,所以不管檔案多大都是瞬間完成。
05分享帶有權限嗎——唯讀 vs 可編輯?
要。每個分享都帶一個角色(viewer/editor),由 metadata 服務強制執行。presigned URL 只限於申請它的那個角色。
06刪除會同步嗎,使用者能救回被刪的檔案嗎?
刪除跟其他編輯一樣同步,用 tombstone。區塊會在垃圾桶窗口裡待一陣子才被回收。一個同步出去的錯誤,需要一條反悔的路。
範圍外原地協同編輯(那是協同文件編輯那一題) · 不下載就預覽與渲染 · 版本歷史的 UI(資料模型保留 latest_version,但瀏覽歷史不在範圍內)
01當網路分裂時,什麼必須繼續運作?
可用性優先於一致性:檔案清單過時個幾秒沒關係;讓上傳失敗則不行。
02一個 50 GB 的上傳在 49 GB 時掛掉會怎樣?
它從最後一個已驗證的區塊續傳——絕不重來。區塊狀態在伺服器端追蹤,所以任何裝置都能接續這次上傳。
03我們如何知道一個檔案在傳輸途中沒有損毀?
每個分塊和整個檔案都帶有 SHA-256 指紋。一個分塊只有在儲存層確認位元組之後,才會被標記為已上傳。
04兩位使用者上傳同一支 2 GB 影片——我們會存兩份嗎?
不會:相同的指紋就代表相同的內容——中繼資料把兩位使用者都指向同一批已儲存的區塊。
05跨裝置同步需要多即時?
幾秒:在線的裝置會被推播變更通知,並以週期性輪詢作為安全網。
真實面試探得比一份整齊清單深得多。這些範圍問句,區分出真正拷問問題的人和只是背誦的人。
把每個估算都當成一種壓力,用來合理化一個元件:快取、佇列、分片、副本、worker pool 或退路。
大檔案的區塊數
50 GB 檔案 ÷ 5 MB 區塊50,000 MB ÷ 5 MB = 10,000 個區塊
那就是一萬個並行進行、且各自能獨立續傳的上傳。這正是為什麼一個巨大的 POST 永遠行不通。
失敗後的續傳成本
上傳在 98% 時掛掉重試 = 剩下的約 200 個區塊,而不是 10,000 個
區塊狀態追蹤把一次災難性的重來變成 2% 的補齊。
去重的效益
同一個檔案被 N 位使用者上傳,指紋相符儲存成本 = 1 份副本 + N 列中繼資料
以內容定址的儲存讓第二次以及之後的每一次上傳幾乎免費。
改一個位元組
固定大小分塊 vs 內容定義分塊(CDC)固定:插入 1 位元組會位移每一個邊界 → 幾乎所有區塊都重新上傳 · CDC:只有被動到的區塊
CDC(rolling hash)正是讓被編輯過的檔案做 delta sync 變便宜的關鍵。
presigned URL 的時間窗
URL 有效約 5 分鐘,範圍限定在單一區塊外洩窗口 = 幾分鐘 · 波及半徑 = 一個區塊
短效、窄範圍的 URL 就是用戶端直傳的安全論述。
決策範例
一個 50 GB 的檔案是一萬個 5 MB 區塊。在那個尺寸下,有意思的問題不是儲存——而是續傳、去重,以及當兩個裝置編輯同一個檔案時會發生什麼。
用戶端在本機把檔案分塊、算指紋,然後用短命的 presigned URL 把這些分塊並行、直接上傳到 blob storage。API 只處理 metadata,並在標記完成前先驗證每個分塊的 ETag。同步靠推一個通知來運作,接著每個裝置對著一個 changes-since 游標做對帳。遇到衝突時,主副本採 last-write-wins。輸掉的那筆編輯會被留成旁邊的一份衝突副本,所以使用者什麼都不會失去,由他自己去解決。
我不會做的事:把檔案位元組繞經我的 API 伺服器。它們會變成頻寬瓶頸和攻擊面,卻換不到任何好處。我也不會在衝突時無聲丟掉輸掉的那筆編輯。純 last-write-wins 用在檔案「清單」上沒問題。但用在檔案「內容」上,安靜地把某人一整個下午的工作扔掉,就是這樣流失客戶的。
如果就地協同編輯進入範圍,區塊層級的同步就是錯的工具。那會變成在文件結構上做 operational transform 或 CRDT。那是另一套設計,也是另一道面試題。
先看一張完整的圖,再把每條路徑各自畫成一張圖 —— 寫入路徑與讀取路徑承載不同流量,合理化不同的元件。
完整全貌
檔案位元組直接從 client → blob storage 流動(presigned URL)。只有 metadata 經過 API。通知服務叫其他裝置去拉 changes 游標。
路徑 1
先做去重檢查——已知的指紋不上傳一個位元組就完成。區塊平行上傳;只有在每一個區塊的 ETag 都驗證通過之後,檔案才翻成完成。
路徑 2
推播是門鈴,changes cursor 才是真相:就算漏掉一個通知,下一次輪詢也會自我修復。
在最佳化之前,先讓契約可被檢視:端點、實體、擁有權、重試與狀態。
POST/files/presigned-url
請求{ name, size, fingerprint, chunk_fingerprints[] }
回應200 { file_id, presigned_urls[] } · 200 { deduplicated: true }(當指紋已存在時)
用戶端用這些 URL 把區塊直接上傳到 blob 儲存——檔案位元組永遠不經過 API 伺服器。
PATCH/files/{file_id}/chunks
請求{ chunk_id, etag }
回應200 chunk 狀態
信任但要查證:伺服器接受用戶端的進度回報,然後在把區塊算作已上傳之前,對 blob 儲存核對 ETag。
GET/files/{file_id}/presigned-url
回應200 { url }(CDN 簽章,短效期)
下載來自 CDN edge;短效的簽章 URL 讓分享連結不會變成永久的公開 URL。
GET/files/changes?since={cursor}
回應200 [{ file_id, change, version }]
同步的骨幹:推播通知「有東西變了」;這個 endpoint 才是裝置用來協調的真相。
核心實體
FileMetadatafile_id (PK) · name · size · fingerprint (SHA-256) · latest_version · status · chunks[] {id, fingerprint, status}
file_id(身分)刻意與 fingerprint(內容)分開——重新命名既不改內容,也不動已儲存的區塊。
SharedFilesuser_id (partition key) · file_id (sort key)
每位使用者對每個分享檔案一列:「這位使用者能看到什麼」是一次單分區查詢。
Devicedevice_id (PK) · user_id · last_synced_at
同步狀態是逐裝置的——每個裝置從自己的 cursor 之後拉取變更。
在面試最後三分之一挑一條路線。每條路線給你主題、它該回答的面試官問題,以及要避免的失敗模式。
把上傳從頭到尾走一遍:分塊、平行、伺服器追蹤什麼,以及它在 98% 時掛掉會怎樣。
把檔案切塊、平行上傳,伺服器端追蹤每塊狀態;在 98% 掛掉就從最後一個驗證過的塊續傳——換任何裝置都行。
一個 multipart POST 加上從零重試——在這個尺寸下,續傳本身就是功能。
兩位使用者上傳一支一模一樣的 2 GB 影片。實際上存了什麼,系統又怎麼知道?
兩份上傳的 SHA-256 指紋相同,區塊只存一份、兩位使用者的 metadata 都指向它;第二次「上傳」其實只是一筆 metadata 寫入。
用檔名或大小去重——只有內容指紋(SHA-256)才定義身分。
筆電和手機都離線編輯了同一個檔案。兩者都上線。使用者最後拿到什麼?
先同步者乾淨勝出;後同步裝置的版本以衝突副本保留在檔案旁——由使用者裁決,系統絕不默默丟棄任何編輯。
默默只保留最後一次寫入——落敗的編輯必須以衝突副本的形式存活下來。
如果檔案位元組流經 API 伺服器會壞掉什麼,presigned URL 到底保護了什麼?
位元組走 client → blob storage 直傳,用短效、限定單塊的 presigned URL;API 只發 URL 與記 metadata,檔案流量永遠壓不垮它。
長效或涵蓋整個檔案的 presigned URL——有效期只該幾分鐘,範圍只該一個區塊。
使用者改了 50 GB 檔案中間的幾個位元組。我們要整個重傳嗎——怎麼只同步變動的部分?
內容定義分塊(content-defined chunking):塊邊界由內容本身決定,小修改只影響碰到的那幾塊,同步就只重傳那幾塊。
對編輯過的檔案用固定大小分塊——插入一個位元組會位移之後所有塊邊界,幾乎每一塊都變新的、都要重傳。
把 檔案同步系統 大聲講一遍,讓 AI 為你的說明評分。