擁有一套清晰的 OOD 面試框架,比許多人想像中更為重要。沒有結構的面試容易顯得雜亂,無論對你或面試官而言都難以跟上節奏。
本章介紹一套四步驟框架,幫助你自信地引導開放式的 OOD 討論。它能協助你將抽象需求轉化為具體的架構或程式碼,並在真實世界的限制下展現深思熟慮的取捨能力。
OOD 面試形式多元,本框架並非萬靈丹。實際結構與期待會因面試官偏好而異,請保持靈活並適時調整。
在進入框架本身之前,先來認識常見的 OOD 面試類型。
OOD 面試的三種類型#
OOD 面試通常聚焦於下列三個面向之一,每種對應不同的交付產物(Deliverable)。建議在面試初期便詢問面試官的期待:
「我們應該專注於高階類別圖(class diagram)、程式碼骨架,還是完整實作?」
這能協助你在有限時間(通常 45 ~ 60 分鐘)內精準交付。
三種主要交付形式#
- UML 圖(UML Diagrams):曾是業界標準,至今仍常被用來視覺化系統設計。UML 類別圖呈現類別之間的關係,包括屬性、方法與互動
- 程式碼骨架(Code Skeleton):在現代面試中越來越普遍,更貼近真實開發。你以類別與方法宣告定義設計結構,但暫不實作方法主體
- 可運作的程式碼(Working Code):隨著 OOD 面試重要性提升,部分面試官會要求完整、無錯誤的實作,甚至要求測試案例
若被要求寫出可運作的程式碼,不必驚慌。面試官通常會簡化問題範圍,確保時間內可完成。
在 OOD 面試中,過程與最終成果同等重要。沉默地寫程式無法留下深刻印象。請在過程中分享你的見解,展現設計思維與溝通能力。
OOD 面試框架:四個步驟#
我們建議的四個步驟如下:
Step 1:需求蒐集(5 ~ 10 分鐘)#
從仔細分析題目開始,識別關鍵的功能性與非功能性需求。透過有針對性的提問釐清模糊之處、建立合理限制並確認假設,確保你與面試官對範圍與優先順序有共識。
Step 2:辨識核心物件(3 ~ 7 分鐘)#
需求釐清後,挑選一個主要使用案例(Use Case),逐步走過流程以識別核心物件與其互動。實務做法是:
- 將需求中的名詞對應到物件(例如 parking lot、vehicle、ticket)
- 將動詞對應到方法(例如 assign spot、calculate fee)
這能形成一個雖然粗略但相關的初步設計,作為後續精煉的基礎。
使用案例圖(Use Case Diagram)有助於視覺化工作流程與物件互動,但在多數 OOD 面試中並非必要。
Step 3:設計類別圖與程式碼(20 ~ 25 分鐘)#
當核心物件與職責明確後,開始發展類別圖並展示如何轉換為程式碼。
兩種設計途徑#
- 由上而下(Top-down):先識別高階元件或父類別,再細化其屬性與方法
- 由下而上(Bottom-up):先定義具體類別(屬性、方法),再從中建立關係
接著定義物件之間的互動,並依據**低耦合、高內聚(Low Coupling, High Cohesion)**等設計原則分配職責。這是確立物件模型並具體化屬性與方法的階段。
實作核心類別#
設計完成後,實作核心類別以展示結構如何轉化為程式碼。某些情況下不需要完整實作,只要聚焦於關鍵部分即可,除非面試官另有要求。
OOD 面試的主軸是設計與程式碼品質,但時間與空間複雜度也不能忽略。良好的類別與關係建模包含選擇合適的資料結構,例如:
- 根據存取模式與效能需求,謹慎選擇
List或SetHashSet與TreeSet並非可互換- 熟悉更複雜的集合與巢狀結構
在面試中提及你的考量並做出正確選擇,但不要過度分析或自行發明優化。
Step 4:深度討論(10 ~ 15 分鐘,可選)#
驗證設計能滿足主要使用案例後,進一步處理邊界情境並解決不一致之處。這通常是深入討論的起點。面試官可能會追問細節以評估你的理解、挑戰你的設計決策,或探討更進階的面向。
端到端範例:停車場設計#
為了更清楚理解 OOD 面試的進行方式,以下走一個從頭到尾的真實範例。
Step 1:需求蒐集#
Anne 是一位應徵後端職位的軟體工程師。面試官 Beth 請她設計一個停車場系統,並給她 45 分鐘呈現設計。
Anne 先消化問題,提出幾個澄清問題以建立共識。她很快了解到停車場需要支援不同車種、預約位置以及精確的計費。
對話範例#
Anne:停車場應該支援哪些車種?我們要考慮汽車與機車嗎?
Beth:是的,還有公車。每輛公車佔三個車位。
Anne:我們需要為不同車種設計不同類型的停車位嗎?
Beth:是的,這部分由你決定。
Anne 持續以深思熟慮的問題清楚定義範圍與限制,並避免下列常見錯誤:
- 提出顯而易見或過度瑣碎的問題
- 重複已被回答過的問題(會顯得心不在焉)
- 帶出與主題無關或過度複雜的話題
有效需求蒐集的技巧#
OOD 面試的前幾分鐘至關重要,以下提供幾個建議。
聚焦最關鍵的需求
從最關鍵的需求開始,確認對問題範圍的共識。Anne 在理解後重述並列出核心功能以驗證她的詮釋:
Anne:系統將支援車輛進出、追蹤車位狀態、依車種與停留時間計費,並支援三種車種。
用範例釐清範圍
Anne 不只是陳述需求,更透過具體範例來釐清討論並暴露邊界情境。
同時準備一個簡單情境與一個複雜情境,能更有效地暴露隱藏的需求。
簡單情境:
Anne:基本場景:一輛汽車進入停車場,找到空位停車,兩小時後離開。系統應分配車位、追蹤時長並計算費用。
複雜情境:
Anne:現在想像一輛有預約的公車進入停車場。部分車位太小或被預約給其他車種。系統需要找到最合適的可用車位,同時兼顧未來的可用性。
藉由對比情境,Anne 釐清了模糊處,並確保雙方對問題有一致理解。
Step 2:辨識核心物件#
Anne 從一個關鍵使用案例著手:停車。她在走流程時,從需求中的名詞與動詞識別出相關物件。
Anne:當一輛車進入時,系統會找到合適大小的可用車位、分配車位、產生票券並標記車位為已佔用。
保持設計聚焦#
Anne 透過聚焦於兩三個代表性使用案例,讓需求自然引導設計,避免一開始就試圖建模所有細節,優先重視清晰與相關性而非完整性。
當邊界情境被提出時:
Beth:你會如何處理停車場滿位等邊界情境?
Anne:好問題。如果沒有可用車位,系統應回傳適當訊息。我會在完成主要設計後再回來精煉這部分邏輯。
當更複雜的議題冒出時,Anne 會先承認再回頭:
Anne:讓我們先完成核心使用案例。如果時間允許,我會再擴充設計以支援可調整的計費策略,可能用 strategy pattern。
若有助於溝通,Anne 可以畫一個簡單的使用案例圖來視覺化流程。雖然多數面試不要求,但她可以詢問面試官是否需要。
Step 3:類別設計與程式碼#
定義類別#
Anne 從構成系統骨幹的基礎元件開始,聚焦於:ParkingLot、ParkingSpot、Vehicle、Ticket。
Anne:核心實體是 ParkingLot、ParkingSpot、Vehicle 與 Ticket。每個車位有 size 與 availability 屬性,每輛車有類型,Ticket 則追蹤入場時間並計算費用。
她接著畫出 UML 圖表示關係:
ParkingLot包含多個ParkingSpot實例- 每個
ParkingSpot可容納一輛Vehicle - 一個
Ticket連結Vehicle與ParkingSpot,並追蹤時間
Anne 確保每個類別都符合 OOP 原則:封裝、單一職責與繼承。
Anne:ParkingLot 管理整體結構,包括追蹤車位與處理車輛流動;每個 ParkingSpot 負責自身狀態與停在其中的車輛。
Anne:我們可以定義一個基底 Vehicle 類別,再衍生 Car、Motorcycle、Bus 等子類別,因為它們的停車需求與計費方式不同。
她避免過度複雜化模型,只聚焦於具有實質行為的物件。
程式碼實作#
設計就緒後,Anne 寫出類別定義並加入相關屬性與方法簽章:
- ParkingLot:管理車位集合並處理分配
- ParkingSpot:追蹤大小、可用性與所停車輛
- Ticket:儲存入場時間並計算費用
撰寫過程中,Anne 持續向面試官解釋她的理由,並驗證設計:
Anne:這個結構涵蓋了我們討論過的主要使用案例。我接著確認它能否支撐邊界情境。
Step 4:深度討論#
此時 Anne 的設計已接近完成,無論是詳細的 UML 圖或連貫的程式碼骨架。最後一步是精煉——退一步從高層次審視設計、處理邊界情境並考慮改進。
補上缺漏#
Anne 重新檢視邊界情境並精煉設計:
Anne:對於邊界情境,我會加上處理滿位的邏輯與公車佔多格的群組邏輯,並在退場時驗證票券有效性。
總結設計#
Anne:這個設計支援關鍵使用案例、可擴展到不同車種,並涵蓋核心邊界情境。如果時間允許,我會再探討依時段動態定價的延伸設計。
做出深思熟慮的取捨#
精煉常涉及繼承 vs 組合、資料模型或設計模式等取捨。重點不在於選出「正確答案」,而在於清楚說明為什麼這個決定合理。
也要懂得適時說「夠好了」並繼續前進。如果設計已涵蓋主要使用案例,避免陷入假設情境或過度優化。
當面試不如預期時怎麼辦?#
無論準備多充分,真實面試很少完全照著腳本走。你可能會遇到需求變動、突然被拉入細節、或面試官冷淡等狀況。關鍵是保持靈活、清楚溝通,並專注於交付有思維深度的設計。
1. 需求變動或範圍擴大#
範圍擴大常常是面試官刻意安排的,目的在測試彈性與可擴展性。
應對方式:
- 承認新需求並簡短評估其影響
- 說明既有設計如何因應變化,或需要哪些取捨
- 保持彈性但有策略,避免不必要的大幅重構
- 若面試官持續擴張某個面向,他們很可能在測試彈性與可擴展性
- 範圍變動有時是暗示你的設計存在盲點,請花點時間重新評估
2. 過早被拉入細節#
有時面試官想在你尚未勾勒整體結構前就深入細節。過早深入容易失去全局視野並耗盡時間。
應對方式:
- 先設下期待:「我先做高層次概覽,再針對需要的部分深入。」
- 定期確認時間與結構
- 若卡住,可以說:「目前我會這樣處理。完成系統其餘部分後,我會有更完整脈絡來精煉這裡。」
- 別忘了稍後回頭——這展現了完整性
- 避免一開始就過早優化或過度具體化
3. 難以表達思路#
清晰溝通與穩固的設計同等重要。
應對方式:
- 從高層次摘要切入:「系統有三個主要元件:A、B、C。它們的互動方式如下…」
- 善用視覺化工具,類別圖或程式碼骨架能錨定討論
- 強調設計為什麼這樣做,而非僅描述做了什麼
- 為類別與方法選擇直觀的名稱,好的命名能省去冗長解釋
4. 面試官冷淡#
並非每位面試官都會主動回饋。若對方顯得不感興趣或沉默,別被影響。
應對方式:
- 禮貌性提問以重新拉回對話:「需要我釐清什麼或聚焦在某個部分嗎?」
- 若無效,讓作品自己說話。專注於畫出乾淨的圖表或寫出可執行的程式
- 在以程式碼為主的面試中,執行可運作的程式比口頭討論更能展現實力
5. 設計決策被質疑#
被挑戰並非壞事,這是展示推理能力與彈性的機會。
應對方式:
- 保持冷靜並闡述思路
- 用具體範例或真實世界類比佐證
- 適時引用時間複雜度、可擴展性或可維護性等概念
- 提出替代方案:「我同時考慮過繼承與組合,這裡選繼承的原因是…」
- 不確定時可暫停或請求澄清:「能否舉一個你認為這個方法不足的具體案例?」
6. 遇到陌生術語#
若遇到不熟悉的術語,澄清比猜測來得明智。
應對方式:
- 禮貌詢問:「能否說明你所指的術語?」
- 或表達部分理解並校準:「我對這個概念的理解是 X,請告訴我在你的脈絡下有何不同。」
- 這展現謙遜與專業,不會損及你的可信度
7. 抽象層次的拿捏#
太廣會讓方案顯得空泛,太深又會浪費時間。
應對方式:
- 從整體結構開始,再逐層加入細節
- 詢問面試官偏好的深度:「你希望先看高階架構,還是更詳細的類別拆解?」
- 保持彈性,依面試官的線索調整縮放層級
- 每道 OOD 題都有其自然的複雜度,經驗會培養出適當的判斷
8. 並行(Concurrency)議題#
並行是進階主題,面試官可能會詢問你的系統如何處理多人或多進程同時存取共享資源。
經典例子是訂票系統,核心關切是防止多位使用者同時選同一個座位導致重複預訂。這是展現以下技巧的好機會:
- 加鎖(Locking)
- 樂觀鎖(Optimistic Locking)
- 語言內建的同步機制與並行資料結構(Concurrent Data Structures)
解釋簡潔、實作簡單。多數面試中,高層次描述加上一段防止 race condition 的程式片段就已足夠。
若使用 Java 寫程式,熟悉 Thread、Runnable、Callable、ExecutorService 等類別會很有幫助,能避免你從低階原語重新發明並行機制。
最後的提醒#
OOD 面試不只考技術能力,更考驗在壓力下清晰思考、有效溝通,並運用 OOP 原則建構可維護、可擴展方案的能力。
將過程拆解為可掌握的步驟,並學會應對各種突發狀況,你就能從容處理最不可預測的面試。透過練習與正確心態,你能將意外變成機會,留下深刻印象。