題幹與適用場景
這道後端題考察 HTTP 部分回應、物件儲存讀取和下載狀態機。重點不是把請求標頭轉發給儲存,而是保證範圍、實體版本、壓縮編碼、權限和並行下載在失敗與重試後仍然一致。
面試官考察什麼
- 能否正確解析單一範圍請求,並構造 206、Content-Range、Content-Length 與 Accept-Ranges。
- 能否用 ETag 或 Last-Modified 配合 If-Range,避免客戶端拼接不同版本的檔案。
- 能否處理無效範圍、過期簽名、物件刪除、限流和多分段成本。
- 能否設計校驗、可觀測性和權限邊界,避免把下載介面變成任意物件讀取器。
回答前需要澄清的問題
先確認物件是否可公開存取、最大檔案大小、是否需要多範圍回應、儲存是否支援原生 Range、是否允許壓縮傳輸,以及客戶端是否保存 ETag。也要確認下載連結有效期、並行分段上限、完整性校驗演算法和資源版本變化時的產品行為。
30 秒回答框架
我會先鑑權並鎖定物件版本,讀取大小、ETag 和媒體類型。無 Range 時回傳 200;一個合法範圍回傳 206 與精確 Content-Range;越界或語法無效回傳 416 並給出目前長度。If-Range 不匹配時回傳完整目前版本,讓客戶端重新開始。每個分段都受並行和速率限制,回應與最終檔案用版本和校驗和驗證,日誌記錄範圍、命中、耗時和失敗原因。
分步驟深入解答
1. 固定表示與權限邊界
先根據使用者、租戶和物件 id 做授權,不能讓客戶端直接把任意路徑映射到儲存鍵。讀取物件元資料並固定一個版本標識、總位元組數、Content-Type、Content-Encoding 和 ETag。若物件會變更,優先使用不可變版本或版本化儲存,避免同一下載期間元資料和內容漂移。
2. 解析範圍並構造回應
支援 bytes=start-end、bytes=start- 和 bytes=-suffix 三種單一範圍形式,校驗整數、溢位和總長度。合法範圍裁剪到資源邊界後回傳 206、Content-Range 和準確長度;沒有 Range 回傳 200;沒有任何可滿足範圍回傳 416,並傳送 Content-Range: bytes */total。多範圍需求應明確拒絕、拆成多個請求或採用 multipart 方案,不要悄悄回傳錯誤片段。
3. 處理 If-Range 與編碼
If-Range 中的強 ETag 或日期只有在仍匹配目前表示時才允許傳送部分回應;不匹配則忽略 Range,回傳完整目前表示。範圍應針對實際傳輸的位元組表示定義,不能先對壓縮後位元組做範圍再讓客戶端按未壓縮檔案拼接。需要壓縮時應明確是否停用動態壓縮,或讓每種編碼擁有獨立版本和校驗。
4. 控制並行、成本和失敗恢復
限制每個使用者、租戶和物件的並行分段數、總頻寬和最小範圍大小,防止大量小範圍請求放大儲存成本。分段失敗可用相同版本和範圍重試;簽名過期時重新簽發,但不能改變物件版本。物件刪除或權限變更應停止後續分段,並讓客戶端丟棄不完整檔案而不是靜默拼接。
5. 驗證完整性與可觀測性
客戶端下載後按物件版本、總長度和校驗和驗證,必要時逐段校驗再合併。伺服器記錄正規化範圍、版本、狀態碼、位元組數、儲存延遲、快取命中和重試次數,不記錄下載憑證。測試空範圍、負後綴、超過長度、物件更新、並行重試、斷網恢復和不同 Content-Encoding,確認 206 不會回傳錯誤版本。
高品質示範回答
我會在授權後讀取一個不可變物件版本,並返回大小、ETag、類型和編碼。解析單一 bytes 範圍:合法時回傳 206、Content-Range 和 Content-Length;無範圍回傳 200;不可滿足時回傳 416 與 bytes */total。If-Range 版本不匹配就忽略 Range,回傳完整目前版本,避免客戶端把不同版本拼在一起。每個使用者和物件限制分段並行、速率和最小範圍,失敗只按相同版本重試。客戶端下載後用總長度、版本和校驗和驗證,伺服器觀測範圍、狀態、儲存延遲和重試。
常見錯誤
- 只轉發 Range,不校驗授權、物件版本和範圍整數溢位。
- 對越界範圍回傳 200 或空回應,而不是明確的 416。
- 忽略 If-Range,導致物件更新後客戶端拼出混合版本。
- 對壓縮表示按錯誤的位元組座標切片,客戶端下載後無法合併。
- 允許無限小分段和無限並行,把一次下載放大成儲存風暴。
- 只檢查 HTTP 狀態碼,不校驗總長度、ETag 和最終校驗和。
追問及應對
為什麼不能總是回傳 206?
沒有 Range 時客戶端請求的是完整表示,應回傳 200。即使有 Range,也要確認範圍可滿足;否則 416 能讓客戶端根據目前長度修正請求。
If-Range 和 If-Match 有什麼區別?
If-Range 主要決定是否繼續部分傳輸:匹配就回傳 206,不匹配就回傳完整表示。If-Match 是條件請求前置條件,失敗通常意味著不執行目標操作,語意不同。
多範圍請求應該怎麼處理?
先評估客戶端和儲存是否真的需要。可以拆成多個受限請求,也可以實作 multipart/byteranges;若成本和複雜度不值得,應明確拒絕而不是回傳第一個範圍造成誤解。
如何防止下載連結被濫用?
短時簽名綁定使用者、物件、版本和權限,伺服器再次校驗租戶邊界,並限制並行、速率、範圍數量和總位元組。撤銷權限或物件刪除後,後續範圍請求立即失效。