內容完全排除死背的語法,聚焦於「觀念校正、架構取捨、實戰踩坑與系統邊界」,並採用資深工程師的務實口吻編寫:
第一階段:Python 與 FastAPI 核心實作
Q1:async def 與一般標準的 def 在 FastAPI 裡面有什麼差異?如果我在 async def 裡面直接呼叫會阻塞的同步套件(如 requests),會發生什麼事?
- 面試官想聽什麼: 你對 Python 異步 IO 與 Event Loop 底層機制的理解,是否具備正確的非同步意識。
- 標準解答:
- 底層運作: FastAPI 支援 ASGI 與非同步處理。如果你用標準的
def宣告 Route,FastAPI 會自動將該請求放到執行緒池(ThreadPoolExecutor)中執行,避免阻塞主執行緒。 - 踩坑風險: 如果你在
async def裡面直接呼叫會阻塞的同步套件(例如requests.get()),它不會自動轉移到執行緒池,而是直接把 Uvicorn 單一執行緒的 Event Loop 卡死。高併發時,所有後續進來的請求全部會被迫排隊癱瘓。 - 取捨: 唯有全鏈路使用 Async Native Driver(如
asyncpg、httpx)時,async def才能發揮真正的非同步高併發效能。
Q2:FastAPI 的 Depends(依賴注入)除了減少重複程式碼之外,在架構上最大的價值是什麼?
- 面試官想聽什麼: 你對程式碼解耦與系統可測試性(Testability)的設計思維。
- 標準解答:
- 除了用來管理資料庫連線生命週期(Session Scope)、JWT 身分驗證或共用查詢參數外,它最大的價值在於讓系統具備高度可測試性。
- 在撰寫單元或整合測試時,我們可以直接透過
app.dependency_overrides將真實的 Service 或 DB 依賴替換成 Mock 物件,完全不需要侵入或修改原本的商業邏輯程式碼,這是在大型專案中維持測試覆蓋率的關鍵。
Q3:在 FastAPI + SQLAlchemy 的架構下,如何處理資料庫交易(Transaction)與邊界劃分?
- 面試官想聽什麼: 資料一致性、ACID 原則與防範髒資料的實戰經驗。
- 標準解答:
- 常見錯誤: 絕對不能把
session.commit()隨意散落在各個 Repository 或單一資料操作函式中。如果一個業務流程需要寫三個 Table,第二步失敗卻沒有 Rollback,會導致資料直接髒掉。 - 正確做法: 必須把 Transaction Boundary(交易邊界) 提升並收攏在 Service Layer(或 Use Case)。透過 Context Manager(如 SQLAlchemy 的
async with session.begin():)確保一個完整的業務流程全部成功才 Commit,中間只要發生任何 Exception 就整包 Rollback。
第二階段:可靠度、任務隊列與資料庫連線管理
Q4:當系統需要處理背景任務或金流、訂單時,為什麼不能只靠 FastAPI 內建的 BackgroundTasks?何時該上 Celery 搭配訊息佇列?
- 面試官想聽什麼: 你對任務持久化、重試機制與系統可靠度的權衡能力。
- 標準解答:
- 內建
BackgroundTasks的侷限: 它跟著當前 Python 進程運行,完全沒有持久化(Persistence)。一旦 Server 重啟或發生 OOM,任務就會直接消失。它只適合用在「掉了也無所謂」的次要邏輯(如非同步 Log)。 - 金流與訂單的本質: 涉及訂單或金流時,不只是換個 Celery 工具這麼簡單,還必須考慮任務持久化、失敗重試、冪等性(Idempotency)設計、以及資料庫交易狀態的一致性(例如考慮導入 Outbox 模式),才能確保訊息絕對不漏。
Q5:在正式環境中,如何規劃與計算資料庫的連線池(Connection Pool)大小?
- 面試官想聽什麼: 你對基礎設施承載力、多服務資源分配與防止資料庫癱瘓的實戰經驗。
- 標準解答:
- 算出全站總連線預算公式:$$\text{Total DB Connections} = \text{Pod 數量} \times \text{Worker 數量} \times (\text{Pool Size} + \text{Max Overflow})$$
- 實務考量: 連線池的規劃不能只看單一 API 服務。如果環境中還有背景 Worker(如 Celery)、其他微服務、以及管理維護連線,全部必須一併納入總預算中。設定完成後,也必須透過實際負載測試來動態調整,確保不超過資料庫本身的
max_connections上限。
第三階段:跨領域與系統架構(ETL/CDC、Nginx、React 協作)
Q6:如果這份職缺的資料管線涉及 ETL 與 CDC(如 Airflow 與 MySQL Binlog),在架構設計上需要注意什麼挑戰?
- 面試官想聽什麼: 你對異動資料擷取、資料增量同步與非同步事件處理的掌握度。
- 標準解答:
- Airflow 方面: 設計 DAG 時必須確保每個 Task 的冪等性(Idempotency),讓工作流因故失敗重試時,不會重複寫入重複的資料。
- CDC 方面: 透過監控資料庫 Binlog(如 MySQL)進行增量同步時,必須妥善處理網路中斷後的斷點續傳,以及高併發下可能產生的重複事件(Duplicate Events)過濾機制。
Q7:身為後端與系統架構師,面對 Nginx 與 Docker 部署環境,你通常會把關哪些重點?
- 面試官想聽什麼: 基礎設施安全、反向代理配置與容器化排查能力。
- 標準解答:
- Nginx: 確保正確設定反向代理標頭(
X-Forwarded-For等)、處理 SSL/TLS 憑證與安全性標頭(Security Headers),並依需求配置 Rate Limiting 防止暴力破解。 - Docker: 注意容器網路隔離、環境變數的安全性管理,以及確保容器健康檢查(Liveness/Readiness Probe)能夠確實對接到應用的
/healthz路由。
Q8:在與前端(React)團隊協作開發時,你會如何規範 API 介面與處理非同步狀態?
- 面試官想聽什麼: 前後端邊界劃分、合約規範與防範非同步競態條件(Race Conditions)的經驗。
- 標準解答:
- API 契約: 透過 FastAPI 自動生成的 OpenAPI / Swagger 建立明確的合約,確保前後端對資料結構(透過 Pydantic DTO 序列化)有共識,避免憑感覺溝通。
- 前端協作: 在前端處理 API 呼叫時,建議搭配如 TanStack Query 等工具來託管 Server State,自動處理快取、重試與背景資料同步,並在架構上避免因頁面切換或快速點擊導致的資料錯亂(Race Conditions)。
沒有留言:
張貼留言