面試不僅考察基礎,更看重解決複雜問題的思路與工程落地能力。本文復盤兩道真實面試題:經典 ABC 線程協作與完整爬蟲項目,展示從構思到代碼的完整鏈路。
需求:三線程分別打印 A、B、C,協作輸出有序序列。
核心思想:封裝任務節點 Node,內含打印內容、鎖競爭、索引、狀態映射。最後節點負責狀態重置實現循環。
// 關鍵結構
static class Node extends Thread {
String message; // 打印內容
Lock lock; // 共享鎖
Map<Integer, Node> map; // 所有節點引用
int index; // 執行順序索引
boolean isWorked; // 本輪是否已執行
boolean isLast; // 是否最後節點
@Override public void run() {
while (true) {
lock.lock();
try {
if (index == 0 && !isWorked) { print(); }
else if (index != 0) {
Node prev = map.get(index - 1);
if (!prev.isWorked) { prev.print(); }
else if (!isWorked) { print(); }
else if (isWorked && isLast) { refreshAll(); }
}
} finally { lock.unlock(); }
sleep(1000);
}
}
}
優點:擴展性強,新增線程只需註冊節點;缺點:代碼較重,啟動協調複雜。
構建環形鏈表,利用 Unsafe.compareAndSwapObject 原子設置頭尾節點,CountDownLatch 同步啟動,當前執行指針 currentWork 在節點間流轉。
// 節點 run() 核心邏輯
for (;;) {
if (currentWork == this) {
print(message);
currentWork = (this == tail) ? head : this.next;
}
}
優點:無鎖競爭,吞吐極高;缺點:依賴 sun.misc.Unsafe 內部 API,維護成本高,生產環境建議用 AtomicReference 替代。
wait/notify、Condition、Semaphore、Phaser、CompletableFuture 鏈式調用需求:抓取「互聯網、編程、算法」標籤圖書,篩選評價人數 > 2000,取評分 Top 100,導出 Excel,代碼上傳 GitHub。
ConcurrentHashMap 存儲結果,CountDownLatch 等待完成「架構清晰、併發控制到位、異常處理完善,但網絡/解析層未自寫略遜色。」—— 工程落地權衡在時間限制下可接受,但需表達「有能力自寫,受限於時間選擇成熟庫」的自信。
GitHub:https://github.com/Housum/crawl.git
面試題是展示工程思維的舞臺:ABC 題考察併發基礎與抽象建模,爬蟲題考察全鏈路交付能力。準備時,不僅要會寫代碼,更要能講清為什麼這樣寫、還有什麼方案、生產環境如何演進。