?? 1. Java跨平臺原理(字節碼文件與JVM)
- 核心機制:
- Java源程序(
.java
)編譯為與平臺無關的字節碼文件(.class
),而非直接生成機器碼。 - 字節碼由**Java虛擬機(JVM)**解釋執行,JVM將字節碼轉換為目標平臺的機器指令。
- Java源程序(
- 關鍵特點:
- 一次編譯,到處運行:只要目標平臺安裝對應的JVM,同一份
.class
文件即可運行。 - 性能權衡:解釋執行比C/C++直接編譯為機器碼效率低,但跨平臺性強。
- 一次編譯,到處運行:只要目標平臺安裝對應的JVM,同一份
- 對比C/C++:
- C/C++需針對不同平臺重新編譯生成特定機器碼,Java通過JVM屏蔽底層差異。
- C/C++需針對不同平臺重新編譯生成特定機器碼,Java通過JVM屏蔽底層差異。
🔐 2. Java的安全性
- 語言層級安全:
- 取消指針:用引用替代指針,避免內存非法訪問和越界問題。
- 垃圾回收(GC):自動管理內存,防止內存泄漏和野指針。
- 異常處理:
try/catch/finally
結構化捕獲錯誤,增強健壯性。 - 強制類型檢查:防止不安全的類型轉換。
- 底層安全機制:
- 字節碼校驗器:驗證字節碼合法性。
- 類加載器(ClassLoader):隔離不同類訪問權限。
- 運行時內存布局:防止內存沖突。
- 文件訪問限制:沙箱機制限制惡意代碼。
📦 3. Java三大版本
版本 | 全稱 | 應用場景 | 特點 |
---|---|---|---|
J2SE | Java 2 Standard Edition | 桌面應用、基礎開發 | 包含核心類庫(I/O、網絡等) |
J2EE | Java 2 Enterprise Edition | 企業級應用(電商、ERP系統) | 擴展Servlet/JSP/EJB等組件 |
J2ME | Java 2 Micro Edition | 嵌入式設備(功能機、機頂盒) | 精簡J2SE,專有API(不用于Android) |
關系:J2EE包含J2SE,J2ME包含部分J2SE核心類。
🛠? 4. JVM、JDK、JRE 核心概念
- JVM(Java虛擬機):
- 執行字節碼的虛擬計算機,實現跨平臺(不同OS有專屬JVM)。
- 核心功能:解釋字節碼、內存管理、安全控制。
- JRE(Java運行環境):
- = JVM + 核心類庫(如
rt.jar
)。 - 僅支持運行已編譯的Java程序(無編譯能力)。
- = JVM + 核心類庫(如
- JDK(Java開發工具包):
- = JRE + 開發工具(
javac
編譯器、jar
打包工具等)。 - 開發者必需,支持開發、調試、運行。
- = JRE + 開發工具(
關系總結:JDK ? JRE ? JVM 。
📝 5. Java三種注釋類型
類型 | 語法 | 用途 |
---|---|---|
單行注釋 | //注釋內容 | 臨時注釋單行代碼 |
多行注釋 | /* 注釋內容 */ | 注釋多行代碼(不可嵌套) |
文檔注釋 | /** 注釋內容 */ | 生成API文檔(通過javadoc 工具) |
示例:
/** * 動物類(文檔注釋) * @author Developer */ public class Animal { int age; // 單行注釋:年齡屬性 /* 多行注釋: void eat() { ... } */ }
🧮 6. 8種基本數據類型及字節數
數據類型 | 關鍵字 | 字節數 | 取值范圍 |
---|---|---|---|
字節型 | byte | 1 | -128 ~ 127 |
短整型 | short | 2 | -32768 ~ 32767 |
整型 | int | 4 | -231 ~ 231-1 |
長整型 | long | 8 | -2?3 ~ 2?3-1 |
單精度浮點型 | float | 4 | 科學計數法(約±3.4e3?) |
雙精度浮點型 | double | 8 | 科學計數法(約±1.8e3??) |
字符型 | char | 2 | Unicode字符(0~65535) |
布爾型 | boolean | 1位 | true /false |
布爾型大小:實際占用1位,但JVM通常以1字節處理。
🔄 7. i++
vs ++i
區別與示例
- 共同點:
- 等價于
i = i + 1
,若獨立成句(如i++;
),效果相同。
- 等價于
- 不同點:
i++
(后置自增):先取值,后自增。int a = 5; int b = a++; // b=5, a=6
++i
(前置自增):先自增,后取值。int x = 5; int y = ++x; // y=6, x=6
關鍵:在表達式中影響其他變量的計算結果。
? 8. &
vs &&
與 |
vs ||
&
和|
:&
:按位與(操作整數)或邏輯與(操作布爾值)。|
:按位或(整數)或邏輯或(布爾值)。- 特點:無論左側結果如何,右側操作數都會執行。
&&
和||
:- 短路特性:
&&
:左側為false
時,右側不執行。||
:左側為true
時,右側不執行。
- 高效場景:
if (list != null && list.size() > 0) // 避免空指針異常
- 短路特性:
優先使用:短路運算符(
&&
/||
)提升效率。
? 9. 高效計算:2乘以8的最優解法
- 答案:
2 << 3
- 原理:
- 左移運算(
<< n
)等價于乘以2的n次方。 2 << 3
= 2 × 23 = 16。
- 左移運算(
- 優勢:
- CPU直接支持位運算,效率高于乘法指令。
擴展:
a * 8
→a << 3
(適用于任意整數)。
🔄 10. 基本數據類型轉換規則
- 自動轉換(隱式):
- 小范圍 → 大范圍(如
byte
→int
)。 - 方向:
byte → short → int → long → float → double
。
- 小范圍 → 大范圍(如
- 強制轉換(顯式):
- 大范圍 → 小范圍需手動轉型,可能丟失精度或溢出。
double d = 10.24; long l = (long) d; // l=10(精度丟失)
- 特殊規則:
byte
/short
/char
參與運算時自動提升為int
。
📚 Java面試寶典:核心知識點詳解(下)
🔄 11. if多分支 vs switch多分支
特性 | if-else if-else | switch-case |
---|---|---|
適用場景 | 分支較少(≤5),條件為區間或邏輯表達式 | 分支多且為等值判斷(整型/枚舉/字符串) |
執行邏輯 | 條件從上至下判斷,匹配即停止 | 從匹配入口執行,不加break會穿透 |
條件類型 | 支持任意布爾表達式(> , != , 等) | 僅支持等值比較(不可用> , < ) |
性能 | 分支多時效率較低 | 跳轉表實現,多分支時效率更高 |
示例:
// if處理區間判斷 if (score >= 90) grade = "A"; else if (score >= 80) grade = "B"; // switch處理固定值 switch (level) { case 1: System.out.println("初級"); break; case 2: System.out.println("中級"); } // 若level=2,會輸出"中級"并穿透后續case
🔄 12. while vs do-while循環
循環類型 | 執行順序 | 首次條件=false時 | 適用場景 |
---|---|---|---|
while | 先判斷 ? 后執行 | 循環體一次都不執行 | 需要前置條件檢查 |
do-while | 先執行 ? 后判斷 | 至少執行一次循環體 | 必須執行一次的場景 |
關鍵區別:
int i = 0; while (i > 0) { // 不執行 System.out.println("while循環"); } do { // 執行一次 System.out.println("do-while循環"); } while (i > 0);
? 13. break 與 continue 作用
關鍵字 | 作用 | 示例場景 |
---|---|---|
break | 立即退出整個循環體 | 滿足條件時提前終止循環 |
continue | 跳過本次循環,進入下一次迭代 | 跳過無效數據,繼續處理后續元素 |
嵌套循環:
outer: for (int i=0; i<5; i++) { for (int j=0; j<5; j++) { if (j == 3) break outer; // 跳出外層循環 if (j == 1) continue; // 跳過j=1的本次迭代 } }
🧮 14. 遞歸算法示例:計算 n!
public static int factorial(int n) { if (n == 1) return 1; // 遞歸出口 return n * factorial(n - 1); // 遞歸調用
}
// 調用:factorial(5) = 120
?? 15. 遞歸的優缺點
優點 | 缺點 |
---|---|
代碼簡潔,描述問題自然 | 效率低(函數調用開銷大) |
解決復雜問題(如樹遍歷) | 棧溢出風險(深度過大) |
數學定義直觀映射(如斐波那契) | 難調試和維護 |
使用原則:
- 必須有明確的遞歸出口
- 深度可控(一般 ≤ 1000 層)
- 避免重復計算(可用緩存優化)
📦 16. 數組核心特性
- 類型統一:所有元素類型相同(聲明時指定)
- 長度固定:創建后不可改變(
arr.length
) - 內存連續:分配連續空間,索引訪問(
O(1)
) - 默認值:
int
→0
,double
→0.0
boolean
→false
, 引用類型 →null
- 索引從0開始:有效范圍
[0, length-1]
🔢 17~19. 三大排序算法
1. 冒泡排序(優化版)
void bubbleSort(int[] arr) { for (int i = 0; i < arr.length-1; i++) { boolean swapped = false; for (int j = 0; j < arr.length-1-i; j++) { if (arr[j] > arr[j+1]) { int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; swapped = true; } } if (!swapped) break; // 無交換時提前終止 }
}
2. 選擇排序
void selectionSort(int[] arr) { for (int i = 0; i < arr.length-1; i++) { int minIndex = i; for (int j = i+1; j < arr.length; j++) { if (arr[j] < arr[minIndex]) minIndex = j; } int temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; }
}
3. 插入排序
void insertionSort(int[] arr) { for (int i = 1; i < arr.length; i++) { int key = arr[i], j = i-1; while (j >= 0 && arr[j] > key) { arr[j+1] = arr[j]; // 后移元素 j--; } arr[j+1] = key; }
}
🔄 20. 可變參數(Varargs)特性
- 語法:
類型... 參數名
(如String... names
) - 規則:
- 必須是方法最后一個參數
- 內部按數組處理(
names.length
獲取數量) - 調用靈活:
print("A"); // 等價于 print(new String[]{"A"}) print("A", "B", "C"); // 等價于 print(new String[]{"A","B","C"})
- 禁止:不能與同類型數組方法重載(編譯沖突)
典型應用:
String.format()
、日志工具等方法
🧩 21. 類與對象關系
概念 | 定義 | 現實比喻 | 示例 |
---|---|---|---|
類 | 對象的模板(抽象) | 汽車設計圖 | class Car { ... } |
對象 | 類的實例(具體) | 根據圖紙造的實體車 | Car myCar = new Car() |
關鍵點:
- 類定義了屬性(字段)和行為(方法)
- 對象通過
new
創建,每個對象擁有獨立內存空間- 同一類的對象共享方法定義,但屬性值不同
🆚 22. 面向過程 vs 面向對象
維度 | 面向過程 | 面向對象 |
---|---|---|
核心思想 | 以步驟為中心(函數驅動) | 以對象為中心(數據封裝) |
代碼組織 | 按功能拆分成函數 | 按現實實體抽象成類 |
典型語言 | C, Pascal | Java, C#, Python |
優勢 | 簡單問題高效 | 復雜系統易擴展、維護 |
核心特性 | 無封裝、繼承、多態 | 支持三大特性 |
方法重載和方法重寫(覆蓋)的區別
開發演進:
大型系統中,面向對象通過封裝(隱藏細節)、繼承(代碼復用)、多態(接口統一)顯著降低復雜度。
🔑 23. this 與 super 關鍵字
關鍵字 | 作用 | 使用場景 |
---|---|---|
this | 1. 指代當前對象 | 解決字段/局部變量同名沖突 |
2. 調用本類構造方法(this() ) | 構造方法重載時復用代碼 | |
super | 1. 調用父類成員 | 訪問被重寫的父類方法 |
2. 調用父類構造方法(super() ) | 子類構造方法中初始化父類部分 |
約束:
this()
和super()
必須在構造方法首行- 不可在靜態方法中使用(無"當前對象"概念)
?? 24. static 關鍵字詳解
四大用途:
- 靜態變量:類級別共享(所有對象共用同一份)
class Student { static String school = "北大"; // 所有學生共享 }
- 靜態方法:無需對象即可調用(禁止訪問非靜態成員)
Math.max(10, 20); // 經典用例
- 靜態代碼塊:類加載時執行一次(初始化靜態資源)
static { System.out.println("類已加載!"); }
- 靜態內部類:不依賴外部類實例(可獨立存在)
內存特性:
- 靜態成員在方法區存儲(非堆內存)
- 類加載時初始化,程序結束時銷毀