題目與適用場景
假設 CSV 為 2 GB,主執行緒記憶體預算 20 MB,並要求每個分片確認後 100 毫秒內更新進度。使用者可能重新整理頁面或離線 30 分鐘。用戶端必須無需重新讀取整個檔案即可恢復,保持介面回應,且只有伺服器確認後才能宣稱分片已上傳。OPFS 屬於頁面來源私有儲存,與使用者可見的資料夾控制代碼不同。
面試官考察點
- 根據檔案大小、持久性、權限和瀏覽器支援選擇儲存原語。
- 把解析和位元組 I/O 移出主執行緒,同時保持 UI 狀態一致。
- 定義包含分片身分、校驗和、重試及伺服器對帳的恢復協定。
- 處理配額壓力、驅逐、取消、隱私和不支援的瀏覽器。
回答前需要釐清的問題
確認重新整理後是否必須保留原始檔案、伺服器是否接受亂序分片、資料列是否能增量解析,以及目標瀏覽器範圍。若伺服器能直接讀取使用者選擇的檔案,本地持久化可能不必要;若必須在重新整理後恢復,OPFS 或其他持久儲存就成為方案的一部分。
30 秒回答框架
我會在 OPFS 保存包含 upload_id、來源檔案指紋、分片大小、已確認範圍和校驗狀態的小型清單。專用 Worker 讀取有界切片,先持久化分片再標記待上傳,並使用冪等分片鍵上傳。伺服器返回已接受範圍,重試先對帳再決定。主執行緒只接收節流後的進度訊息,並負責取消與無障礙狀態。透過能力偵測、配額處理和使用者重新選擇檔案的降級流程,覆蓋不支援或被驅逐的用戶端。
分步深入解答
1. 選擇儲存與邊界
把清單和少量中繼資料放在持久瀏覽器儲存,把大型臨時分片放入 OPFS。OPFS 屬於來源私有儲存,存取通常不需要權限提示;使用者可見的檔案控制代碼採用另一套權限模型,需要明確手勢。同步存取控制代碼或其他阻塞磁碟工作放在 Worker,主執行緒不等待 I/O。
2. 讓恢復成為協定,而不是進度條
產生 uploadid 和確定性的分片編號。每次請求攜帶 uploadid、分片索引、位元組範圍、長度和校驗和。伺服器記錄已接受範圍,並在狀態介面返回這些範圍。相同分片身分的重試必須冪等,校驗不一致則拒絕。重新整理後 Worker 讀取清單,向伺服器詢問已接受範圍,只上傳缺失集合。
3. 保持 UI 回應並可恢復
讀取固定大小切片,每次只傳遞一個有界緩衝區,並節流進度事件,避免渲染和解析爭搶。網路嘗試前持久化清單,伺服器確認後再次持久化。取消時本地標記、終止活動請求並安排清理;在伺服器確認終止前不能刪除唯一的恢復中繼資料。
4. 處理配額、相容性與安全
複製檔案前檢查可用儲存,並顯示可恢復的「儲存空間已滿」狀態。OPFS 不可用或被驅逐時,降級到使用者重新選擇檔案的流程,從伺服器已知範圍繼續;此模式不能承諾離線恢復。檔案名稱和解析資料列都視為不可信,上傳需要驗證授權,不能暴露本地路徑。測試重新整理、離線、重複分片、校驗失敗、分頁崩潰、配額拒絕和 Worker 重啟。
高品質示範回答
我會先確認瀏覽器範圍、能否串流解析,以及是否必須支援重新整理恢復。用戶端在 OPFS 保存清單和有界臨時分片,由 Worker 按確定性分片身分讀取並上傳。伺服器掌握已接受範圍,重試先對帳並校驗。主執行緒只渲染節流進度並負責取消。儲存不可用時切換到重新選擇檔案的流程,明確失去離線持久化,但仍可按伺服器範圍恢復。配額、驅逐、來源私有語意和清理都應成為可觀測狀態。
常見錯誤
- 把整個檔案讀入記憶體 → 2 GB 輸入會卡死或崩潰分頁 → 在 Worker 讀取有界分片。
- 把進度百分比當作事實 → 遺失確認會造成空洞或重複 → 以伺服器已接受範圍對帳。
- 認為 OPFS 是使用者可見資料夾 → 使用者無法用相同方式查看或授權 → 說明來源私有儲存,需要匯出時使用檔案控制代碼。
- 只在上傳成功後持久化 → 崩潰會遺失下一次重試位置 → 嘗試前和確認後都保存清單。
- 忽略配額和驅逐 → 離線恢復會無提示失敗 → 檢查容量並提供明確降級。
- 信任檔案名稱或 CSV 欄位 → 本地資料可能注入內容或洩露路徑 → 驗證輸入且不暴露本地路徑。
追問及應對
伺服器已收到分片,但清單更新前分頁崩潰,怎麼辦?
重啟時向伺服器查詢已接受範圍,以伺服器結果為準。清單缺少的分片可以用相同分片身分再次上傳,伺服器應返回既有結果,而不是保存重複分片。
瀏覽器報告 OPFS 被驅逐,要讓匯入失敗嗎?
保留上傳記錄,說明離線恢復已不可用。讓使用者重新選擇來源檔案;來源指紋匹配時繼續使用伺服器範圍,否則開始新的上傳。
為什麼不對每次匯入都使用使用者可見的目錄控制代碼?
它增加權限和手勢流程,也會受到使用者外部修改目錄的影響。需要編輯或匯出原始檔案時使用目錄控制代碼;臨時私有分片使用 OPFS。
如何避免 Worker 把網路打滿?
限制並發分片數量,伺服器或瀏覽器出現背壓時暫停讀取,並優先處理重試。暴露佇列深度和重試年齡,讓 UI 能解釋進度變慢。