問題與範圍
平台每天接收 1000 萬張原始圖片,客戶請求不同尺寸、裁切區域和輸出格式。請設計從原圖儲存、轉換工作、衍生圖快取到 CDN 回應的系統。原圖必須可重新處理;圖片編輯器圖層協作、內容審核模型和專業色彩校準不在範圍內。
面試官在考察什麼
重點是區分原圖、轉換請求和衍生資產的身分,並說明非同步處理與低延遲讀取如何共存。高品質回答會處理穩定快取鍵、重複工作合併、佇列背壓、像素和解壓炸彈、物件權限、格式協商以及原圖刪除後的衍生清理。
回答前要釐清的問題
- 是否允許任意寬高、裁切和濾鏡?最大像素、檔案大小和處理時間是多少?
- 輸出需要哪些格式、品質等級、色彩空間和動畫支援?
- 首次請求必須同步回傳,還是可回傳
202與工作狀態? - 原圖和衍生圖的保留期、租戶隔離和跨區域要求是什麼?
- 處理結果公開可讀,還是每個 URL 都需要簽名授權?
30 秒回答框架
「我會把原圖內容定址儲存,把正規化轉換參數編碼成衍生鍵。讀取先查 CDN 和衍生物件;未命中時以冪等鍵提交工作,按原圖和租戶分片進入佇列。工作程序在隔離環境限制像素、記憶體、CPU、解壓和輸出大小,寫入暫存物件後原子發佈。失敗工作帶版本和重試預算,重複請求共用同一工作。存取層執行簽名 URL、格式協商和快取控制,刪除原圖時非同步清理衍生資產。」
分步深入設計
上傳 API 只負責授權、校驗摘要和寫入原圖物件儲存。中繼資料記錄 asset_id、租戶、內容雜湊、媒體類型、寬高、影格數、色彩資訊、掃描狀態和保留策略。以內容雜湊去重時仍要獨立檢查租戶授權,並用檔案魔數和解碼驗證,不可只信任副檔名。
轉換請求先正規化參數:寬高上限、裁切座標、縮放演算法、品質、旋轉、背景色和輸出格式都轉成穩定序列。衍生鍵可表示為 hash(originalbytes, normalizedtransform, processor_version);處理器升級時版本變更,避免新舊演算法覆寫同一物件。拒絕負數、NaN、極大比例和遞迴濾鏡。
讀取路徑依序檢查 CDN、衍生物件索引和工作去重表。命中可用衍生圖就回傳帶 Cache-Control、ETag 和內容類型的回應。未命中時,若產品允許延遲,建立 PENDING 工作並回傳狀態 URL。唯一約束保護 (tenantid, derivedkey),多個相同請求共用工作。
佇列按租戶和原圖雜湊分區,工作程序按像素成本而非請求數計量。租戶配額、全域並發上限和優先佇列共同提供背壓;超大圖片不能占滿所有程序。工作帶租約和處理器版本,程序崩潰後可重試。退避只針對可恢復錯誤,參數錯誤和不支援格式直接失敗並記錄原因。
處理沙箱限制 CPU、記憶體、暫存磁碟、解壓比、影格數和輸出尺寸,禁止存取內網。解碼後重新計算實際像素和影格數,防止壓縮炸彈。先寫暫存物件並校驗摘要、尺寸和格式,再以條件寫入或版本化物件原子發佈,客戶永遠看不到半成品。對 SVG、ICC 設定和中繼資料採明確策略。
快取策略按衍生鍵長期快取,原圖刪除或權限變更透過資產事件觸發衍生索引和 CDN 失效。私有資產使用短期簽名 URL,簽名涵蓋租戶、衍生鍵、到期時間和允許回應標頭。Vary 只包含確實影響輸出的協商維度,避免任意查詢參數造成快取爆炸。
監控原圖寫入成功率、轉換佇列年齡、按像素成本的吞吐、快取命中率、重複工作合併率、p95 轉換延遲、失敗分類、沙箱資源峰值、衍生物件增長和 CDN 5xx。對帳任務比較原圖中繼資料、工作終態、衍生索引和物件清單,清理孤兒物件。故障注入涵蓋程序被殺、物件儲存逾時、重複訊息、處理器升級和 CDN 失效失敗。
高品質示範回答
「我會把原圖作為不可變、可定址資產,把正規化轉換參數和處理器版本組成衍生鍵。請求先查 CDN 和衍生物件;未命中時透過唯一約束建立共用工作,回傳既有工作或狀態 URL。佇列按租戶和像素成本調度,程序在隔離沙箱限制解壓比、記憶體、CPU、影格數和輸出大小,暫存寫入後校驗並原子發佈。
私有存取使用涵蓋租戶、衍生鍵和到期時間的簽名 URL,公開回應設定正確的 ETag、Cache-Control 和內容類型。原圖刪除事件清理衍生索引和 CDN。指標涵蓋命中率、佇列年齡、p95 延遲、資源峰值和失敗分類;對帳發現孤兒物件。這樣相同請求不會重複計算,惡意圖片不能耗盡容量,處理器升級也不會污染舊衍生結果。」
常見錯誤
- 使用檔名作身分 → 改名或同名上傳會覆蓋資產 → 使用內容雜湊和資產 ID。
- 直接拼接所有參數 → 參數順序不同造成快取碎片 → 先正規化再生成衍生鍵。
- 每次未命中都新建工作 → 熱門圖片形成計算風暴 → 按租戶和衍生鍵冪等合併。
- 只限制檔案位元組 → 壓縮炸彈仍可展開成巨量像素 → 限制解碼後像素、影格和解壓比。
- 全部同步處理 → 慢工作阻塞讀取鏈路 → 非同步佇列與受控同步快徑並存。
- 直接覆蓋最終物件 → 客戶可能讀到半成品 → 暫存校驗後原子發佈。
- 簽名只涵蓋 URL → 參數或標頭可被竄改 → 簽名租戶、衍生鍵、到期時間和策略。
- 刪除原圖不清理衍生圖 → 私有資料繼續可存取 → 由資產事件驅動清理。
追問與回答
追問一:為什麼快取鍵要包含處理器版本?
不同演算法或函式庫可能產生不同位元組。版本納入衍生鍵可讓新處理器並行產生結果,再按策略淘汰舊版本。
追問二:如何處理動畫圖片?
把影格數、總時長和輸出策略納入參數與成本模型,限制最大影格和總像素;首幀縮圖使用獨立衍生鍵。
追問三:何時回傳 202?
轉換成本不可預測、輸出較大或佇列積壓時回傳 202、工作 ID 和重試建議。小尺寸常見格式可在預算內同步完成。
追問四:如何防止快取投毒?
衍生鍵只由服務端正規化參數生成,不接受客戶指定物件鍵。回應類型、長度和摘要發佈前校驗;私有快取綁定租戶和簽名。
追問五:原圖替換後舊 URL 怎麼辦?
原圖使用不可變版本 ID。替換產生新資產或版本事件,舊衍生圖依保留策略續讀或失效。
追問六:如何保證費用公平?
按解碼像素、輸出像素和濾鏡複雜度計費,而非只按請求數。租戶令牌桶、並發上限和每日預算控制昂貴工作。