首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 面試實戰:ABC 多線程順序打印與豆瓣爬蟲項目復盤

     編輯:Java 相關知識

面試不僅考察基礎,更看重解決複雜問題的思路與工程落地能力。本文復盤兩道真實面試題:經典 ABC 線程協作與完整爬蟲項目,展示從構思到代碼的完整鏈路。

題目一:三線程順序打印 ABCABC...

需求:三線程分別打印 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);
        }
    }
}

優點:擴展性強,新增線程只需註冊節點;缺點:代碼較重,啟動協調複雜。

方案二:環形鏈表 + CAS 無鎖協調(高性能)

構建環形鏈表,利用 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 鏈式調用
  • 討論優劣:代碼簡潔度、擴展性、性能、可讀性的權衡

題目二:豆瓣圖書爬蟲(500強外企實戰題)

需求:抓取「互聯網、編程、算法」標籤圖書,篩選評價人數 > 2000,取評分 Top 100,導出 Excel,代碼上傳 GitHub。

技術棧選型

  • 網絡層:HttpClient / OkHttp(自寫 Socket 耗時太久)
  • 解析層:Jsoup(CSS 選擇器極簡)
  • 併發:線程池 + 阻塞隊列,控制並發數避免封 IP
  • 同步:ConcurrentHashMap 存儲結果,CountDownLatch 等待完成
  • 導出:Apache POI 生成 Excel

關鍵工程細節

  1. 反爬應對:隨機 User-Agent、請求間隔抖動、Cookie 維持、IP 代理池預留接口
  2. 數據清洗:評分解析容錯、缺失字段默認值、異常頁面重試機制
  3. 併發控制:固定線程池 (核心 5-10) + 有界隊列,拒絕策略 CallerRuns 緩衝
  4. 結構化日誌:請求 URL、耗時、狀態碼、解析條數,便於事後排查

面試官反饋

「架構清晰、併發控制到位、異常處理完善,但網絡/解析層未自寫略遜色。」—— 工程落地權衡在時間限制下可接受,但需表達「有能力自寫,受限於時間選擇成熟庫」的自信。

項目地址

GitHub:https://github.com/Housum/crawl.git

總結

面試題是展示工程思維的舞臺:ABC 題考察併發基礎與抽象建模,爬蟲題考察全鏈路交付能力。準備時,不僅要會寫代碼,更要能講清為什麼這樣寫、還有什麼方案、生產環境如何演進。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved