具代表性的面試主題

系統設計面試:如何設計軟體包與製品倉庫?

系統設計困難
OfferCC 編輯團隊發佈 更新

題幹

請設計一個供團隊發布和下載軟體包、容器映像或建置製品的倉庫。說明 API、儲存、版本解析、並發、權限、快取、撤回和完整性驗證。

題幹與適用場景

請設計一個供團隊發布和下載軟體包、容器映像或建置製品的倉庫。回答應涵蓋中繼資料、二進位 blob、版本標籤、權限、可用性、快取、撤回和稽核。

可以先選擇一種製品形態,再說明哪些抽象可重用。核心約束是同一內容只存一份、發布不可被部分讀取,下載方能驗證內容未被替換。

面試官考察點

中繼資料與內容分離

強回答會把套件名、版本、標籤、依賴和簽名與不可變內容 blob 分開,避免每次下載都掃描大檔案。

版本與一致性

候選人應說明語意版本、標籤移動、並發發布和刪除語義。版本解析錯誤會讓建置不可重現。

分發與成本

要解釋分塊上傳、斷點續傳、內容定址、CDN、跨區複製和垃圾回收,而不是只畫一個物件儲存。

安全與治理

權限、租戶隔離、簽名、SBOM、惡意製品掃描、稽核和撤回流程必須形成閉環。

回答前需要釐清的問題

  • 製品是 npm 類套件、OCI 映像,還是任意建置檔案?
  • 規模是每天多少發布、下載和總儲存量?
  • 版本是否允許移動標籤,例如 latest?
  • 發布後能否覆蓋版本,還是只能追加新版本?
  • 是否需要私有租戶、代理上游倉庫和跨區容災?
  • 撤回是阻止新下載、刪除內容,還是標記風險並保留稽核?

30 秒回答框架

「我先設計一個多租戶、內容定址的製品倉庫。發布端先上傳並校驗 blob,再提交不可變 manifest;標籤只是在中繼資料中指向已存在版本,移動標籤需要並發條件。下載端先讀中繼資料,再按 digest 從物件儲存或 CDN 取 blob,並校驗摘要與簽名。權限覆蓋命名空間和動作,撤回標記風險而不立即刪除稽核證據。熱門製品走 CDN,後台非同步複製、掃描和垃圾回收。」

分步驟深入解答

第一步:定義資源模型

資源包括 namespace、package、version、tag、manifest、blob、signature 和 provenance。manifest 只引用 digest、媒體類型和大小,blob 以 digest 作為不可變鍵。

第二步:設計發布流程

客戶端先申請上傳會話,分塊上傳到臨時空間;服務端校驗每塊和最終 digest,完成後原子提交 manifest。失敗會話過期清理,重複 digest 直接複用已有 blob。

第三步:處理版本與標籤

不可變版本一旦發布不能覆蓋;tag 可以移動但必須記錄操作者、前後指向和條件版本。解析依賴時優先鎖定精確版本和 digest,避免 latest 漂移。

第四步:設計下載路徑

中繼資料服務返回 manifest、依賴和簽名;blob 服務支援範圍請求、ETag 和 CDN。下載器校驗 digest,快取鍵包含 digest,標籤解析結果設定短 TTL。

第五步:擴展與容災

物件儲存承載大檔案,中繼資料儲存按 namespace 和 package 分片;跨區複製 manifest 後再複製 blob,並以複製狀態決定新區域是否可讀。

第六步:安全與營運

權限採用最小化的讀、寫、發布、改 tag 和刪除動作;掃描惡意內容、產生 SBOM、驗證簽名和來源證明。撤回把版本置為 blocked,阻止新下載但保留證據,所有動作寫稽核日誌。

高品質示範回答

「我把倉庫拆成中繼資料服務、blob 儲存和非同步治理任務。客戶端先建立分塊上傳會話,blob 完成摘要校驗後,manifest 以交易方式引用這些不可變 digest。版本不可覆蓋,tag 移動需要條件版本並記錄歷史。下載先解析精確版本,再從 CDN 或物件儲存按 digest 取內容並校驗簽名。

熱門 blob 用內容定址快取和範圍請求降低成本;後台做跨區複製、惡意掃描、SBOM 與 provenance 處理。私有 namespace 使用租戶級權限和配額。撤回標記 blocked、停止新下載並觸發建置系統告警,不刪除稽核證據。關鍵指標包括發布成功率、p95 下載延遲、快取命中率、複製滯後和未授權存取率。」

常見錯誤

  • 讓客戶端直接改物件儲存 → 繞過權限和完整性校驗 → 用短期上傳會話並由服務端提交 manifest。
  • 允許覆蓋已發布版本 → 建置不可重現 → 版本不可變,使用新版本修復。
  • 把 latest 當永久快取鍵 → 內容悄悄漂移 → 按 digest 快取,標籤只做短 TTL 解析。
  • 只存二進位不存 manifest → 無法表達依賴和簽名 → 保存結構化 manifest 與 provenance。
  • 發布後立刻同步所有區域 → 跨區半成品可讀 → 先複製 blob 與 manifest,再更新可讀狀態。
  • 刪除撤回製品 → 稽核和事故複盤丟失 → 標記 blocked,按保留策略非同步清理。
  • 只做登入鑑權 → 租戶間可能越權 → 對 namespace、動作和製品逐層授權。
  • 掃描阻塞發布請求 → 上傳高峰延遲失控 → 先存 quarantine,非同步掃描後改變可用狀態。

追問及應對

追問一:兩個發布者同時移動同一個 tag 怎麼辦?

使用條件版本或 compare-and-swap;衝突返回目前版本,讓客戶端重試並顯示歷史,禁止最後寫入靜默覆蓋。

追問二:如何保證下載到完整內容?

manifest 宣告 digest、大小和媒體類型;客戶端校驗摘要,失敗從其他副本重試,服務端記錄校驗失敗率。

追問三:跨區複製落後時能否發布?

主區域可以接受發布,但將版本標為複製中;目標區域只有 manifest、依賴 blob 和策略達到一致後才宣告可讀。

追問四:如何回收重複 blob?

從所有活躍 manifest、簽名和保留策略建立引用集合,標記無引用 blob,經過寬限期和並發檢查後刪除。

追問五:供應鏈證明如何進入下載決策?

把簽名、SBOM 和 provenance 與 manifest 關聯;策略引擎按租戶、環境和製品風險決定允許下載、隔離或只告警。

來源一:OCI Distribution Specification

OCI 規範把 manifest、descriptor 和 blob 作為分發核心,並定義 push、pull、digest 與錯誤語義,為內容定址倉庫的資源模型提供依據。

來源二:npm Registry 中繼資料

npm Registry 的中繼資料示例展示版本、dist-tags 與套件資訊分離,說明標籤解析和不可變版本需要不同的一致性與快取策略。

來源三:SLSA 供應鏈完整性

Google 對 SLSA 的介紹強調製品來源、可追溯性和防篡改證明;這些訊號可與倉庫的簽名、SBOM、掃描和下載策略組合。

公開來源

同類題目

相關面試工具

用 Solve 整理系統設計回答

從澄清需求開始,展開規模、架構、元件選擇和取捨。

查看工具