?一、HashMap實現原理與并發問題
?核心機制
1. 哈希沖突解決方案:采用數組+鏈表+紅黑樹結構(JDK1.8+),當鏈表長度超過閾值(默認8)時轉為紅黑樹,提升查詢效率
2. 擴容機制:當元素數量超過負載因子(0.75)*容量時,觸發擴容為原數組2倍,rehash過程涉及數據遷移
3. 并發隱患:多線程環境下可能導致環形鏈表(JDK1.7)或死循環(JDK1.8之前版本)
?
java
// 并發修改異常示例
Map<Integer, String> map = new HashMap<>();
new Thread(() -> map.put(1, "A")).start();
new Thread(() -> map.put(2, "B")).start(); // 可能拋出ConcurrentModificationException
?
二、線程池參數配置與拒絕策略
?核心參數解析
java
ExecutorService executor = new ThreadPoolExecutor(
? ? corePoolSize, // 核心線程數
? ? maximumPoolSize, // 最大線程數
? ? keepAliveTime, // 空閑線程存活時間
? ? TimeUnit.SECONDS,
? ? new LinkedBlockingQueue<>(queueCapacity), // 任務隊列
? ? new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略
);
?
?關鍵點
1. 隊列選擇:SynchronousQueue適合高吞吐場景,LinkedBlockingQueue適合任務執行時間差異大的場景
2. 拒絕策略:
? ?- AbortPolicy(默認):直接拋出RejectedExecutionException
? ?- CallerRunsPolicy:由提交線程執行任務
? ?- DiscardOldestPolicy:丟棄隊列頭部任務
? ?- DiscardPolicy:靜默丟棄任務
?
?三、JVM內存模型與垃圾回收
?內存分區
1. 堆內存:新生代(Eden+S0/S1)與老年代
2. 方法區:存儲類元數據(JDK8后使用元空間)
3. 本地方法棧:執行Native方法
4. 程序計數器:線程私有執行指針
?
?垃圾回收算法
- 標記-清除:基礎算法,產生內存碎片
- 復制算法:新生代常用,分From/To空間
- 標記-整理:老年代適用,解決碎片問題
- 分代收集:結合不同區域特點的混合策略
?
??四、異常處理機制與最佳實踐
?三類異常
1. Checked Exception:編譯期檢查異常(IOException)
2. RuntimeException:運行時異常(NullPointerException)
3. Error:嚴重系統錯誤(OutOfMemoryError)
?
?處理原則
1. 避免捕獲過于寬泛的Exception
2. finally塊中避免資源泄露
3. try-with-resources處理自動關閉資源
?
java
// 正確的資源管理示例
try (FileInputStream fis = new FileInputStream("test.txt")) {
? ? // 業務邏輯
} catch (IOException e) {
? ? logger.error("文件讀取失敗", e);
}
?
?五、設計模式面試題精講
?工廠模式
- 簡單工廠:通過參數決定創建對象類型
- 抽象工廠:生產產品族,符合開閉原則
?
?單例模式
1. 餓漢式:類加載時初始化
2. 雙重校驗鎖:volatile+雙重檢查保證線程安全
3. 靜態內部類:利用類加載機制保證線程安全
?
java
// 雙重校驗鎖實現
public class Singleton {
? ? private static volatile Singleton instance;
? ??
? ? public static Singleton getInstance() {
? ? ? ? if (instance == null) {
? ? ? ? ? ? synchronized (Singleton.class) {
? ? ? ? ? ? ? ? if (instance == null) {
? ? ? ? ? ? ? ? ? ? instance = new Singleton();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return instance;
? ? }
}
?
?