一、Java基礎知識
1. Java語言特點
題目: 請說明Java語言的主要特點?
答案:
- 面向對象:Java是純面向對象的語言,支持封裝、繼承、多態
- 平臺無關性:一次編譯,到處運行(Write Once, Run Anywhere)
- 簡單性:語法簡潔,去掉了C++中的指針、多重繼承等復雜特性
- 安全性:提供了安全管理機制,防止惡意代碼攻擊
- 多線程:內置多線程支持
- 健壯性:強類型檢查、異常處理、垃圾回收
- 分布式:支持網絡編程,便于開發分布式應用
2. JDK、JRE、JVM的關系
題目: 請解釋JDK、JRE、JVM三者的關系?
答案:
- JVM(Java虛擬機):Java程序運行的環境,負責將字節碼轉換為機器碼
- JRE(Java運行環境):包含JVM + Java核心類庫,是Java程序運行的最小環境
- JDK(Java開發工具包):包含JRE + 開發工具(javac、java、javadoc等),是Java開發環境
關系:JDK > JRE > JVM
3. 基本數據類型
題目: Java有哪些基本數據類型?各占幾個字節?
答案:
整型:
- byte:1字節,范圍 -128 到 127
- short:2字節,范圍 -32768 到 32767
- int:4字節,范圍 -2^31 到 2^31-1
- long:8字節,范圍 -2^63 到 2^63-1浮點型:
- float:4字節,單精度
- double:8字節,雙精度字符型:
- char:2字節,Unicode字符布爾型:
- boolean:1字節(JVM中實際可能占4字節)
4. 自動裝箱和拆箱
題目: 什么是自動裝箱和拆箱?
答案:
- 自動裝箱:基本類型自動轉換為對應的包裝類對象
- 自動拆箱:包裝類對象自動轉換為對應的基本類型
// 自動裝箱
Integer i = 100; // 等價于 Integer i = Integer.valueOf(100);// 自動拆箱
int j = i; // 等價于 int j = i.intValue();
注意事項:
- Integer緩存池:-128到127的Integer對象被緩存
- 可能出現NullPointerException
5. equals()和==的區別
題目: equals()和==有什么區別?
答案:
- ==:
- 對于基本類型:比較值是否相等
- 對于引用類型:比較引用地址是否相等
- equals():
- 默認實現與==相同
- 可以重寫來比較對象內容
- String類已重寫equals()方法比較字符串內容
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = "hello";
String s4 = "hello";System.out.println(s1 == s2); // false,不同對象
System.out.println(s1.equals(s2)); // true,內容相同
System.out.println(s3 == s4); // true,字符串池中同一對象
二、面向對象編程
6. 面向對象三大特性
題目: 請詳細說明面向對象的三大特性?
答案:
1. 封裝(Encapsulation)
- 將數據和方法包裝在類中
- 通過訪問修飾符控制訪問權限
- 隱藏內部實現細節
public class Person {private String name; // 私有屬性public String getName() { // 公共方法return name;}public void setName(String name) {this.name = name;}
}
2. 繼承(Inheritance)
- 子類繼承父類的屬性和方法
- 實現代碼復用
- 支持方法重寫
class Animal {protected void eat() {System.out.println("Animal is eating");}
}class Dog extends Animal {@Overrideprotected void eat() {System.out.println("Dog is eating");}
}
3. 多態(Polymorphism)
- 同一接口不同實現
- 運行時確定具體調用哪個方法
- 包括重載和重寫
Animal animal = new Dog();
animal.eat(); // 調用Dog的eat方法
7. 重載和重寫的區別
題目: 方法重載和重寫有什么區別?
答案:
特性 | 重載(Overload) | 重寫(Override) |
---|---|---|
定義 | 同一類中方法名相同,參數不同 | 子類重新實現父類方法 |
參數 | 必須不同 | 必須相同 |
返回值 | 可以不同 | 必須相同(或協變) |
訪問修飾符 | 可以不同 | 不能降低訪問權限 |
異常 | 可以不同 | 不能拋出更寬泛的檢查異常 |
發生時期 | 編譯期確定 | 運行期確定 |
8. 抽象類和接口的區別
題目: 抽象類和接口有什么區別?什么時候使用?
答案:
特性 | 抽象類 | 接口 |
---|---|---|
關鍵字 | abstract | interface |
繼承 | 單繼承 | 多實現 |
構造器 | 可以有 | 不能有 |
成員變量 | 任意類型 | public static final |
方法 | 抽象和具體方法 | 抽象方法(JDK8+支持默認方法) |
訪問修飾符 | 任意 | public |
使用場景:
- 抽象類:is-a關系,有共同的屬性和部分相同的行為
- 接口:can-do關系,定義行為規范
三、集合框架
9. Collection和Collections的區別
題目: Collection和Collections有什么區別?
答案:
- Collection:集合框架的根接口,定義了集合的基本操作
- Collections:工具類,提供了對集合操作的靜態方法
// Collection是接口
Collection<String> list = new ArrayList<>();// Collections是工具類
Collections.sort(list);
Collections.reverse(list);
10. ArrayList和LinkedList的區別
題目: ArrayList和LinkedList有什么區別?
答案:
特性 | ArrayList | LinkedList |
---|---|---|
底層結構 | 動態數組 | 雙向鏈表 |
隨機訪問 | O(1) | O(n) |
插入刪除(頭部) | O(n) | O(1) |
插入刪除(尾部) | O(1) | O(1) |
插入刪除(中間) | O(n) | O(n) |
內存占用 | 較小 | 較大(存儲指針) |
線程安全 | 不安全 | 不安全 |
11. HashMap的實現原理
題目: 請詳細說明HashMap的實現原理?
答案:
底層結構:
- JDK1.7:數組 + 鏈表
- JDK1.8+:數組 + 鏈表 + 紅黑樹
核心機制:
// 1. 計算hash值
int hash = key.hashCode();
hash = hash ^ (hash >>> 16); // 擾動函數// 2. 確定數組下標
int index = (n - 1) & hash; // n為數組長度// 3. 處理沖突
// - 鏈表長度 < 8:使用鏈表
// - 鏈表長度 >= 8:轉換為紅黑樹
// - 紅黑樹節點 <= 6:轉換為鏈表
擴容機制:
- 默認容量:16
- 負載因子:0.75
- 擴容閾值:容量 × 負載因子
- 擴容時容量翻倍
12. ConcurrentHashMap實現原理
題目: ConcurrentHashMap是如何實現線程安全的?
答案:
JDK1.7實現:
- 分段鎖(Segment)機制
- 每個Segment繼承ReentrantLock
- 降低鎖的粒度
JDK1.8實現:
- 取消分段鎖
- 使用CAS + synchronized
- 鎖住鏈表或紅黑樹的首節點
- 進一步降低鎖粒度
// JDK1.8 put方法核心邏輯
final V putVal(K key, V value, boolean onlyIfAbsent) {// 1. CAS嘗試設置空位置if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value, null)))break;// 2. synchronized鎖住首節點synchronized (f) {// 3. 插入鏈表或紅黑樹}
}
四、多線程
13. 進程和線程的區別
題目: 進程和線程有什么區別?
答案:
特性 | 進程 | 線程 |
---|---|---|
定義 | 程序的執行實例 | 進程中的執行單元 |
資源 | 擁有獨立的內存空間 | 共享進程的內存空間 |
通信 | IPC(進程間通信) | 共享內存 |
創建開銷 | 大 | 小 |
切換開銷 | 大 | 小 |
影響范圍 | 進程崩潰不影響其他進程 | 線程崩潰可能影響整個進程 |
14. 線程的狀態
題目: Java線程有哪些狀態?如何轉換?
答案:
線程狀態(Thread.State):
public enum State {NEW, // 新建RUNNABLE, // 運行(就緒+運行)BLOCKED, // 阻塞WAITING, // 等待TIMED_WAITING, // 超時等待TERMINATED // 終止
}
狀態轉換:
NEW → RUNNABLE:調用start()
RUNNABLE → BLOCKED:等待synchronized鎖
BLOCKED → RUNNABLE:獲得鎖
RUNNABLE → WAITING:調用wait()、join()
WAITING → RUNNABLE:notify()、notifyAll()
RUNNABLE → TIMED_WAITING:sleep()、wait(timeout)
TIMED_WAITING → RUNNABLE:時間到或被喚醒
RUNNABLE → TERMINATED:run()方法結束
15. synchronized關鍵字
題目: 請詳細說明synchronized的原理和使用?
答案:
使用方式:
// 1. 修飾實例方法
public synchronized void method() {}// 2. 修飾靜態方法
public static synchronized void method() {}// 3. 修飾代碼塊
synchronized(object) {// 同步代碼
}
實現原理:
- Java對象頭:包含MarkWord,存儲鎖信息
- Monitor機制:基于操作系統的互斥量
- 字節碼指令:monitorenter和monitorexit
鎖升級過程(JDK1.6+):
無鎖 → 偏向鎖 → 輕量級鎖 → 重量級鎖
16. volatile關鍵字
題目: volatile關鍵字的作用是什么?
答案:
作用:
- 保證可見性:修改后立即寫入主內存,其他線程讀取時從主內存讀取
- 禁止指令重排序:使用內存屏障
使用場景:
// 1. 狀態標記
private volatile boolean flag = true;// 2. 雙重檢查鎖單例模式
public class Singleton {private volatile static Singleton instance;public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}
注意:volatile不保證原子性
17. 線程池
題目: 請說明線程池的工作原理和參數?
答案:
核心參數:
public ThreadPoolExecutor(int corePoolSize, // 核心線程數int maximumPoolSize, // 最大線程數long keepAliveTime, // 線程存活時間TimeUnit unit, // 時間單位BlockingQueue<Runnable> workQueue, // 工作隊列ThreadFactory threadFactory, // 線程工廠RejectedExecutionHandler handler // 拒絕策略
)
工作流程:
- 提交任務到線程池
- 如果運行線程數 < corePoolSize,創建新線程
- 如果運行線程數 >= corePoolSize,任務加入隊列
- 如果隊列滿了且運行線程數 < maximumPoolSize,創建新線程
- 如果運行線程數 >= maximumPoolSize,執行拒絕策略
常用線程池:
// 固定大小線程池
ExecutorService executor = Executors.newFixedThreadPool(10);// 緩存線程池
ExecutorService executor = Executors.newCachedThreadPool();// 單線程線程池
ExecutorService executor = Executors.newSingleThreadExecutor();// 定時任務線程池
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
五、JVM虛擬機
18. JVM內存結構
題目: 請詳細說明JVM的內存結構?
答案:
運行時數據區域:
1. 程序計數器(PC Register)
- 線程私有
- 存儲當前線程執行字節碼的行號
- 唯一不會OutOfMemoryError的區域
2. Java虛擬機棧(JVM Stack)
- 線程私有
- 存儲局部變量表、操作數棧、動態鏈接、方法出口
- StackOverflowError、OutOfMemoryError
3. 本地方法棧(Native Method Stack)
- 線程私有<