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

Java 核心易混知識點大全:32 道高頻面試題深度解析與避坑指南

     編輯:Java 相關知識

前言:易混不等於難,易混是因為「似是而非」

Java 面試與日常開發中,最容易丟分、最容易埋坑的,往往不是完全陌生的知識,而是長得像、行為近、語義異的易混點。本文精選 32 組高頻易混知識,從語法、集合、並發、JVM、框架五個維度,給出標準答案、底層原理、實戰陷阱與記憶口訣。

一、基礎語法與關鍵字(1-8)

1. final / finally / finalize

關鍵字角色核心語義易混點
final修飾符類不可繼承、方法不可覆蓋、變量不可重賦值(引用不變,對象內容可變)final 引用指向的對象內容可修改
finally塊異常處理保證執行的清理代碼(return 前執行,System.exit 除外)try-with-resources 自動調用 close(),順序:catch → finally → resource close
finalize()方法GC 前調用(已棄用 JDK 9,不可靠、性能差、線程不安全)不要依賴它釋放資源,用 try-with-resources / Cleaner / PhantomReference

2. 匿名內部類能否 extends / implements?


// 只能「二選一」:
new Interface() { ... }        // 實現接口(隱式 implements)
new SuperClass() { ... }       // 繼承類(隱式 extends)
// 不能同時:new SuperClass() implements Interface { ... } // 編譯錯誤
// 但內部類可以:class Inner extends Super implements Interface {}

3. Static Nested Class vs Inner Class

特性Static Nested ClassInner Class (非靜態)
外部實例依賴無需外部實例 outer.new Inner()
訪問外部成員僅 static所有(含 private 實例字段/方法)
聲明 static 成員允許禁止(編譯時常量除外)
序列化獨立隱式序列化外部實例

口訣:static 嵌套類是「獨立租戶」,內部類是「寄生蟲」(攜帶外部引用)。

4. & vs &&

  • &:位運算 或 邏輯運算(不短路,兩邊必執行)
  • &&:邏輯運算(短路,左邊 false 右邊不執行)

if (obj != null & obj.id > 0) { } // 危險!obj 為 null 仍執行右邊 → NPE
if (obj != null && obj.id > 0) { } // 安全,短路保護

5. HashMap vs Hashtable

維度HashMapHashtable
線程安全非線程安全同步方法(性能差)
null 鍵/值允許 1 個 null key、多個 null value禁止 null
繼承體系實現 Map,繼承 AbstractMap實現 Map,繼承 Dictionary(舊)
迭代器fail-fastenumerator + iterator
推薦替代單線程:HashMap;多線程:ConcurrentHashMap已棄用,勿用

6. Collection vs Collections

  • Collection:接口,List/Set/Queue 父接口
  • Collections:工具類,靜態方法(sort、binarySearch、synchronizedList、unmodifiableList、emptyList...)

7. assert 斷言使用規範


// 兩種形式
assert condition;                    // 失敗拋 AssertionError 無消息
assert condition : "message";        // 失敗拋 AssertionError 帶消息

// 啟用:-ea / -enableassertions
// 禁用:-da / -disableassertions
// 系統類啟用:-esa / -dsa

// 正確用法:私有方法前置條件、代碼不可達處、後置條件驗證
// 錯誤用法:公共方法參數檢查(必須拋異常)、副作用代碼、業務邏輯控制流

8. GC 基礎

  • System.gc() / Runtime.getRuntime().gc():建議 JVM 執行 GC,不保證立即執行
  • 現代 GC(G1/ZGC/Shenandoah)以區域/並發為主,手動觸發通常無意義

二、對象創建與字符串(9-10)

9. String s = new String("xyz") 創建幾個對象?

  • 2 個:字符串常量池中 "xyz"(若不存在則創建)、堆中新 String 對象 s 指向
  • String s = "xyz":0 或 1 個(常量池複用)

10. Math.round(11.5) / Math.round(-11.5)

  • Math.round(11.5) == 12:floor(x + 0.5)
  • Math.round(-11.5) == -11:負數向零方向取整(-11.5 + 0.5 = -11.0 → -11)

三、類型轉換與運算(11-12)

11. short s1 = 1; s1 = s1 + 1 vs s1 += 1

  • s1 = s1 + 1:編譯錯誤。s1 + 1 提升為 int 運算,結果 int 不能隱式賦值給 short
  • s1 += 1:正確。復合賦值隱式包含強轉:s1 = (short)(s1 + 1)

12. sleep() vs wait()

方法所屬鎖行為喚醒方式典型場景
sleep()Thread不釋放鎖時間到 / 中斷定時任務、延遲重試
wait()Object釋放鎖notify/notifyAll / 時間到 / 中斷生產消費者、線程協作

鐵律:wait/notify 必須在 synchronized 塊中調用,否則拋 IllegalMonitorStateException。

四、語言特性(13-16)

13. Java 有 goto 嗎?

  • goto 是保留字,不支持使用
  • 替代:標籤配合 break/continue label(極少用)

14. 數組 length vs String length()

  • 數組:length 屬性(JVM 內部字段)
  • String:length() 方法(返回 char[] 長度,即 UTF-16 代碼單元數)
  • 集合:size() 方法

15. Overload vs Override

維度Overload (重載)Override (重寫)
發生位置同一類內父子類之間
方法簽名名稱相同,參數列表不同(類型/個數/順序)名稱、參數、返回類型(協變)完全相同
返回類型可不同兼容(子類型)
拋出異常無限制子類異常 ⊆ 父類異常
多態性編譯時靜態綁定運行時動態綁定

16. Set 判重:== 還是 equals()?

  • equals():HashSet 先比 hashCode(),再 equals();TreeSet 用 compareTo() / Comparator 判等(返回 0 視為相等)
  • ==:比較引用地址,不用於 Set 判重
  • 契約:a.equals(b) → a.hashCode() == b.hashCode()(反向不必然)

五、異常與錯誤(17-18)

17. 常見 RuntimeException

  • NullPointerException、IndexOutOfBoundsException、IllegalArgumentException、ClassCastException、IllegalStateException、UnsupportedOperationException、ConcurrentModificationException、ArithmeticException

18. Error vs Exception

類別代表可恢復性處理策略
ErrorOOM、StackOverflow、NoClassDefFoundError極難/不可恢復通常不捕獲,記錄日誌、快速失敗、重啟
Exception受檢/非受檢業務異常可恢復捕獲處理、轉換、重試、降級

六、集合框架(19-20)

19. List/Set/Map 與 Collection 關係

  • List、Set 繼承 Collection
  • Map 不繼承 Collection(鍵值對 ≠ 單一元素集合)

20. Abstract Class vs Interface

特性Abstract ClassInterface
方法實現可有實例方法、構造函數、字段JDK 8 前全抽象;JDK 8+ default/static 私有方法
繼承/實現單繼承 extends多實現 implements
訪問修飾符任意默認 public(JDK 9+ 私有方法)
設計意圖「是一種」關係、共享代碼、模板方法「能做什麼」契約、能力標識、多實現

七、修飾符組合限制(21-22)

21. abstract 方法不能與哪些修飾符共存?

  • static:靜態屬於類,抽象要求子類實現,矛盾
  • native:本地方法由外部實現,抽象無實現,矛盾
  • synchronized:同步是實現細節,抽象不關心實現,矛盾
  • final:最終不可覆蓋,抽象必須覆蓋,矛盾
  • private:私有不可繼承,抽象要求繼承實現,矛盾

22. 接口繼承/實現規則

  • 接口 可繼承多個接口:interface A extends B, C {}
  • 抽象類 可實現接口:abstract class A implements B {}(可不實現方法)
  • 抽象類 可繼承具體類:前提是父類有可見構造函數(非 private)

八、線程與同步(23-26)

23. 啟動線程:start() 還是 run()?

  • start():創建新線程,JVM 調度執行 run()
  • run():當前線程直接調用,無新線程創建

24. 構造器能否 override?

  • 不能。構造器不參與繼承,子類構造器隱式/顯式調用 super()
  • 可 overload(同類多構造器)

25. String 能否繼承?

  • 不能。final class String

26. synchronized 方法鎖對象

  • 實例方法:鎖 this
  • 靜態方法:鎖 Class對象
  • 同一對象同一時間只能有一個線程執行其 所有 synchronized 實例方法(或塊鎖 this)

九、finally 與 return(27)

27. try 有 return,finally 會執行嗎?何時執行?

  • 會執行,在 return 指令執行前(返回值已壓棧)
  • 陷阱:finally 中 修改返回值 / 拋出異常 會覆蓋原返回值/異常

public int test() {
    try { return 1; }
    finally { return 2; } // 返回 2,原 return 1 被吃掉
}

十、位運算與算法(28-30)

28. 最高效計算 2 * 8


2 << 3 // 左移 3 位 = 乘 2^3 = 16
// 現代 JVM JIT 會自動優化乘法為移位,可讀性優先用 2 * 8

29. equals(true) 但 hashCode 不同?

  • 違反契約。a.equals(b) → a.hashCode() == b.hashCode() 必須成立
  • 若發生,HashMap/HashSet 會出現「找不到已存入對象」等異常行為

30. 參數傳遞:值傳遞還是引用傳遞?

  • 只有值傳遞。對象傳遞的是「引用的值(副本)」
  • 方法內可修改對象內容(通過副本引用),但無法讓外部引用指向新對象

十一、Switch 支持類型(31)

31. switch 作用於 byte/long/String?

  • 支持:int、short、char、byte、enum、String(JDK 7+)、Character/Byte/Short/Integer(自動拆箱)
  • 不支持:long、float、double、boolean

十二、單例模式寫法(32)

32. 線程安全單例演進


// 1. 餓漢式(類加載初始化,天然線程安全)
public class Singleton {
    private static final Singleton INSTANCE = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() { return INSTANCE; }
}

// 2. 懶漢式雙重檢查鎖(JDK 5+ volatile 保證可見性)
public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) instance = new Singleton();
            }
        }
        return instance;
    }
}

// 3. 靜態內部類(推薦:延遲加載、線程安全、代碼簡潔)
public class Singleton {
    private Singleton() {}
    private static class Holder { static final Singleton INSTANCE = new Singleton(); }
    public static Singleton getInstance() { return Holder.INSTANCE; }
}

// 4. 枚舉單例(最強:防反射、防序列化破壞、天然線程安全)
public enum Singleton { INSTANCE; }

附錄:Hashtable vs HashMap 補充

  • Hashtable 繼承 Dictionary,HashMap 實現 Map
  • contains(key) 歧義大(鍵還是值?),HashMap 拆分為 containsKey/containsValue
  • 最大不同:Hashtable 方法同步,HashMap 非同步,多線程需外部同步或用 ConcurrentHashMap
  • Hash/rehash 算法相似,單線程性能差異微小

總結:易混點背後的核心原理

  1. 語義邊界:final 修飾引用 vs 對象、Override vs Overload 綁定時機
  2. 契約與規範:equals/hashCode 契約、Cloneable 協議、Comparable 一致性
  3. 底層實現:String 常量池、數組 length 屬性、synchronized 鎖對象
  4. 演進歷史:Hashtable→HashMap→ConcurrentHashMap、Vector→ArrayList、StringBuffer→StringBuilder

掌握這些易混點,不僅為了面試,更是為了在代碼中寫對、寫快、寫穩。每一次「易混」的釐清,都是對 Java 語言本質理解的深化。

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