本文精選高頻 Java 面試基礎題,**按知識點分類、附標準答案、核心原理、易錯點、追問延伸**,適合校招、社招系統複習、面試前速查。每題包含:結論、代碼證據、JLS/JVM 規範依據、實戰避坑。
結論:可以包含多個類,**但最多只能有一個 `public` 類**,且 `public` 類名**必須與文件名完全一致** (大小写敏感)。
// File: Main.java
public class Main { } // ✅ 唯一 public,同名
class Helper { } // ✅ package-private
// public class Another { } // ❌ 編譯錯誤
追問:為什麼? → JVM 類加載器按文件名查找 `public` 類,保證類名唯一映射。
結論:`goto` 是**保留關鍵字**,**未使用**、**編譯錯誤**。但字節碼有 `goto` 指令 (編譯器生成)。
結論:
- `&`:邏輯與 (雙方均求值) + 位運算 (整數操作數)。
- `&&`:短路邏輯與,**左側為 false 則右側不求值**。
String s = null;
if (s != null & s.length() > 0) // NPE! 右側仍執行
if (s != null && s.length() > 0) // 安全,短路
int a = 5 & 3; // 1 (位運算)
int b = 5 && 3; // 編譯錯誤:&& 需 boolean 操作數
結論:`switch(expr)` 中 `expr` 僅支援:**`byte/short/char/int` 及其包裝類、`enum`、JDK 7+ `String`**。不支援 `long`、`float`、`double`、`boolean`。
結論:`s+1` 觸發**整數提升**為 `int`,賦值回 `short` 需強轉。`+=` 是**複合賦值運算符**,JLS 規定**隱含強轉**:`s += 1` 等價 `s = (short)(s + 1)`。
結論:能。`char` 是 **UTF-16 代碼單元 (2 bytes)**,BMP 字符 (含常用漢字) 佔 1 `char`;補充字符 (Emoji、生僻字) 佔 2 `char` (代理對)。
結論:引用不可變**,對象內容可變**。
final StringBuilder sb = new StringBuilder();
// sb = new StringBuilder(); // ❌ 編譯錯誤
sb.append("hello"); // ✅ 合法,修改對象內容
結論:
- `==`:比較**引用地址** (基本型比值、引用型比地址)。
- `equals()`:比較**邏輯內容** (需類覆寫)。`Object.equals()` 默認同 `==`。
String a = new String("foo");
String b = new String("foo");
a == b // false (不同對象)
a.equals(b) // true (內容相同)
結論:
- 靜態變量:屬於**類**,類加載時分配,**全局唯一**,`ClassName.staticVar` 訪問。
- 實例變量:屬於**對象**,`new` 時分配,**每個實例一份**,`obj.instanceVar` 訪問。
結論:不能直接調用**。非靜態方法需綁定實例 (`this`),靜態方法無 `this`。可 `new Obj().nonStatic()` 或傳入實例參數。
結論:
維度 int Integer 類型 基本型 包裝類 (對象) 默認值 0 null 記憶體 4 bytes (棧/物件內) 對象頭 + 4 bytes (堆) 泛型 ❌ ✅ 快取 無 [-128,127] `IntegerCache` Web 表單 顯示 0 顯示空 (null 安全)
結論:
修飾符 同類 同包 子類(異包) 非子類(異包) `private` ✅ ❌ ❌ ❌ `default` (package) ✅ ✅ ❌ ❌ `protected` ✅ ✅ ✅ ❌ `public` ✅ ✅ ✅ ✅ 注意:`protected` 對**同包非子類也可見** (不同於 C++)。
結論:
- **Overload (重載)**:同類中,**方法名相同、參數列表不同** (類型/個數/順序)。—— **返回類型、異常、修飾符可不同**。
- **Override (覆寫)**:子類覆寫父類,**簽名完全相同** (名、參數、返回類型协变)。—— **權限 ≥ 父類、拋出異常 ≤ 父類**。
返回類型 alone 不能重載:調用時不看返回值,編譯器無法區分。
結論:`is-a` = **繼承** (子類是父類一種);`has-a` = **組合/聚合** (類包含另一類實例)。
結論:**雙親委派模型**:
- Bootstrap ClassLoader → `jre/lib/rt.jar` (核心庫)
- Extension ClassLoader → `jre/lib/ext/*.jar`
- Application ClassLoader → `classpath`
- 自定義 ClassLoader → 繼承 `ClassLoader` 重寫 `findClass`
流程:`loadClass` → 檢查已加載 → 委派父加載器 → 父加載失敗 → 自己 `findClass` → `defineClass`。
結論:解耦、分工、維護、復用、替換 (如 Hibernate→MyBatis)、擴展、適應變化。典型三層:Controller (Web) → Service (Biz) → DAO (Data)。
結論:用於**哈希容器** (`HashMap`、`HashSet`) 定位桶位。契約:
1. 同一對象多次調用返回一致。
2. `a.equals(b) → a.hashCode()==b.hashCode()` (反向不要求)。
3. **覆寫 `equals` 必須覆寫 `hashCode`**。
結論:面向切面編程。**切面** = 橫切關注點 (日志、事務、權限)。**切點** = 具體連接點 (方法執行、異常拋出) 的匹配規則。**通知** = 切面在切點執行的動作 (前/後/環繞/異常/最終)。**織入** = 將通知應用到目標對象 (編譯期/類加載期/運行期代理)。
結論:Model (數據/業務邏輯) ↔ View (展示/交互) ↔ Controller (請求分發/協調)。流程:請求 → Controller → Service/Model → Controller 選 View → View 渲染 Model → 響應。核心:**關注點分離、單一職責、可測試、可替換 View**。
💡 複習策略:背誦結論 → 手寫代碼驗證 → 畫圖講原理 → 模擬面試追問**。重點掌握:**HashMap/JMM/GC/Spring事務/MySQL索引鎖** 五大核心專題。