本文匯總 Java 基礎、集合、併發、JVM、類加載、GC 等核心領域 50 道高頻面試題,每題附帶「標準答案 + 底層原理 + 實戰避坑」,助你構建完整知識網絡,從容應對初中高級崗位面試。
JDK = JRE + 編譯/診斷工具 + 源碼;JRE = JVM + 核心類庫;JVM = 執行引擎。開發用 JDK,運行用 JRE,JVM 是跨平台基石。
告訴類加載器去哪裡找 .class/jar。動態指定:java -cp /path/to/jar:./classes MainClass 或 -classpath。
jar cvfe app.jar com.MainClass -C out/ .,Manifest 中指定 Main-Class,雙擊即可運行。
屬於類而非實例,編譯期靜態綁定。static 不能 override(可隱藏),private 不可見不可 override。
不能。static 階段實例尚未創建,非 static 成員不存在。
byte/short/int/long/float/double/boolean/char。編譯器自動在基本類型與包裝類轉換(Integer.valueOf/intValue),緩存 -128~127。
Override:子類重寫父類方法,簽名相同,運行期動態綁定。Overload:同類中方法名同參數表不同,編譯期靜態綁定。
新對象創建時調用。Java 無 C++ 式復制構造器,需自行實現 clone() 或複製構造器。
類單繼承,介面多實現。默認方法讓介面擁有行為復用能力。
介面:全隱式 public static final 字段、default/static 方法、多實現。抽象類:可有構造器、非 final 字段、任意訪問權限、單繼承。
Java 唯有值傳遞。傳對象時傳「引用的副本」,可修改對象內部狀態,不可替換引用本身。
進程=資源分配單位,線程=調度單位。繼承 Thread、實現 Runnable、Executor 線程池(推薦)。
NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。
方法級=粗粒度鎖(this/class),代碼塊=細粒度鎖(任意對象),後者併發度更高。
每個對象關聯一把 Monitor,synchronized 獲取鎖進入臨界區,wait/notify 依賴 Monitor。
互斥、持有等待、不可搶佔、循環等待。預防:統一鎖獲取順序、嘗試性獲取 (tryLock)、超時釋放。
Collection → Set/List/Queue;Map(非 Collection 子介面)。
具體實現決定存儲方式(有序/無序、可重複/不可重複),介面不應強制序列化/克隆策略。
前者單向遍歷 Collection,後者雙向遍歷 List 且支援增刪改、索引獲取。
Fail-fast:直接讀取原集合,檢測 modCount 變化拋 CME(java.util)。Fail-safe:遍歷副本,無 CME(java.util.concurrent)。
hashCode()、equals()、鏈表/紅黑樹解決碰撞。JDK 8 引入樹化閾值 8。
違反契約導致「邏輯相同 key 進不同桶」或「不同 key 進同桶且誤判相等」,破壞 Map 語義。
前者非同步、允許 null、Iterator fail-fast;後者同步、不允許 null、Enumeration、遺留類。
基本類型固定長 → Array;對象、動態擴容、豐富 API → ArrayList。
隨機訪問 O(1) vs O(n);插刪尾部同速,中間 LinkedList 快(無擴容/移位);LinkedList 佔更多內存(雙向指針)。
前者內部比較 (compareTo),自然順序;後者外部策略 (compare),多種排序邏輯共存。
最小堆(數組實現),O(log n) 入隊/出隊,非線程安全,不允許 null,可傳 Comparator 定制順序。
描述最壞情況增長率。ArrayList 查找 O(1) 擴容 O(n);LinkedList 查找 O(n) 插刪 O(1);HashMap 增刪查 O(1) 平均。
有序:二分查找 O(log n),插入 O(n);無序:查找 O(n),插入 O(1)。按查找/寫入比例選擇。
預估大小指定初始容量、全程泛型、優先介面編程(List<> list = new ArrayList<>())、空集合返回空實例而非 null。
Enumeration 速度快、內存少、只讀;Iterator 安全(fail-fast)、支援 remove、標準化。
HashSet:HashMap 鍵,無序,O(1);TreeSet:紅黑樹,有序,O(log n)。
回收不可達對象釋放內存。觸發:新生代滿、老年代滿、Metaspace 滿、System.gc() 建議。
同義,僅建議 JVM 執行 GC,不保證立即執行。
GC 前調用一次,不可靠(可能不執行、拋異常阻塞、性能差),Java 9 棄用,改用 Cleaner/try-with-resources。
不會。下一 GC 週期可達性分析發現不可達才回收。
新生代 (Eden+S0+S1) + 老年代。JDK 8 移除永久代,類元數據移至本地內存 Metaspace,避免 OOM。
Serial:單線程、小應用、Client 模式;Throughput:並行新生代、大吞吐、Server 模式默認。
GC Roots 可達性分析不可達。強/軟/弱/虛引用影響判定時機。
會。類卸載條件嚴格(類加載器不可達、實例無引用、Class 對象無引用),Full GC 時觸發。
禁止指令重排、強制刷新主內存,不保證原子性(複合操作仍需鎖/CAS)。
Compare-And-Swap 原子指令。ABA:值 A→B→A 檢測失敗。解決:AtomicStampedReference 加版本號。
基於雙向隊列的狀態同步器,state 代表鎖狀態,tryAcquire/tryRelease 由子類實現,支援獨享/共享模式。
前者可中斷、可超時、公平鎖、多 Condition、非阻塞獲取;後者語法簡單、JVM 優化好、死鎖自動釋放。
Key 弱引用被 GC → Entry.key=null → Value 強引用殘留 → 線程池長壽命導致洩漏。static final + remove() 破解。
加載→驗證→準備→解析→初始化。雙親委派模型打破需重寫 loadClass。
類不可繼承、方法不可覆蓋、變量不可修改(引用不變,對象內容可變)。
String 不可變;StringBuilder 非線程安全、高效;StringBuffer 同步、線程安全。拼接優先 Builder。
這 50 道題覆蓋 Java 後端開發 90% 核心考點。建議按模塊專項攻克,配合源碼閱讀與手寫代碼,將知識內化為肌肉記憶。祝你面試順利,Offer 滿懷!