Java 多執行緒與並發基礎
執行緒安全是指多執行緒存取同一段程式碼時,不會產生不確定的結果。編寫執行緒安全的程式碼核心在於依賴執行緒同步機制。簡單來說:執行緒安全意味著在多執行緒環境下使用時,開發者無需自行進行同步處理;反之,執行緒不安全則必須顯式進行同步,否則會導致不可預期的後果。
進程與執行緒的核心差異
- 進程:執行中程式的實例,擁有獨立的記憶體地址空間和進程控制塊(PCB)。進程間切換開銷大,但隔離性好。
- 執行緒:進程內的輕量級任務,共享進程的地址空間和記憶體資源。Java 通過多執行緒機制實現並發,開銷小但增加了系統複雜度。
執行緒啟動與終止
- 啟動執行緒必須呼叫
start() 方法,而非 run()。start() 會讓執行緒進入可執行狀態,由 JVM 排程執行。
- 最有效終止執行緒的方式是在
run() 方法中設置標誌位,讓執行緒自然結束,避免使用已棄用的 stop()。
wait() vs sleep() 關鍵差異
| 特性 | sleep() | wait() |
| 所屬類別 | Thread 類別 | Object 類別 |
| 鎖行為 | 不釋放鎖 | 釋放鎖,進入等待池 |
| 喚醒方式 | 時間到期自動喚醒 | 需 notify()/notifyAll() 喚醒 |
| 使用場景 | 單純延遲執行 | 執行緒間協作/通訊 |
實現執行緒的兩種方式
- 繼承 Thread 類別:重寫
run() 方法。簡單但受限於單繼承。
- 實現 Runnable 介面:實現
run() 方法,再傳入 Thread 建構子。支援多實現,解耦任務與執行緒控制,更符合面向對象設計。
JDBC 資料庫連接核心
標準連接步驟
- 載入驅動程式(
Class.forName())
- 建立連接(
DriverManager.getConnection())
- 建立 Statement/PreparedStatement
- 執行 SQL 語句
- 處理結果集(ResultSet)
- 釋放資源(關閉連接、語句、結果集)
JDBC 四種驅動類型
- Type 1:JDBC-ODBC Bridge(橋接器,效能差)
- Type 2:Native-API 驅動(部分 Java,部分原生)
- Type 3:Network Protocol 驅動(中間件轉換)
- Type 4:Pure Java 驅動(直接通訊,最常用,如 MySQL Connector/J)
字串處理核心:String vs StringBuffer/StringBuilder
不可變的 String
String s1 = "Monday"; // 常量池中創建
String s2 = "Monday"; // 指向同一個常量池物件
String s3 = new String("Monday"); // 堆中創建新物件
s1 == s2 為 true(地址相同)
s1 == s3 為 false(地址不同)
s1.equals(s3) 為 true(內容相同)
可變字串類別
- StringBuffer:執行緒安全,同步化,效能較低
- StringBuilder:非執行緒安全,無同步,效能較高(單執行緒首選)
異常處理機制深度解析
異常體系結構
- Error:嚴重錯誤,無法恢復(如 OutOfMemoryError)
- Exception:可處理的異常
- Checked Exception:編譯期檢查(如 IOException、SQLException),必須捕獲或拋出
- Unchecked Exception (RuntimeException):執行期檢查(如 NullPointerException、ArrayIndexOutOfBoundsException),建議通過程式邏輯預防而非捕獲
finally 區塊的設計意圖
確保資源釋放(如關閉檔案、資料庫連接),無論是否發生異常都會執行。即使 try 中有 return,finally 仍會在方法返回前執行。但 System.exit(0) 會直接終止 JVM,跳過 finally。
多重 catch 區塊匹配規則
- 按照宣告順序由上往下匹配
- 只會執行第一個匹配的 catch 區塊
- 子類別異常必須放在父類別異常之前,否則編譯錯誤
Java 記憶體管理與垃圾回收
- Java 程式設計師無需手動管理記憶體,GC 自動回收無引用物件
- 可透過
System.gc() 或 Runtime.getRuntime().gc() 請求 GC,但不保證立即執行
finalize() 方法在物件被 GC 回收前調用,用於釋放非記憶體資源(如檔案控制代碼),但執行時間不確定,Java 9 起標記為棄用
集合框架核心區別
| 比較項目 | HashMap | Hashtable |
| 同步化 | 非同步,高效能 | 同步,效能較低 |
| Null 鍵/值 | 允許一個 null 鍵、多個 null 值 | 不允許 null 鍵/值 |
| 繼承關係 | 繼承 AbstractMap | 繼承 Dictionary |
| 比較項目 | Collection | Collections |
| 類型 | 介面(集合根介面) | 工具類別(靜態方法) |
| 功能 | 定義集合操作規範 | 提供排序、搜尋、同步包裝等演算法 |
物件導向核心:重載 vs 覆寫
| 特性 | Overload (重載) | Override (覆寫) |
| 發生範圍 | 同一類別內 | 父子類別之間 |
| 方法簽名 | 名稱相同,參數列表不同 | 名稱、參數、返回型別完全相同 |
| 返回型別 | 可不同 | 必須相容(共變返回型別) |
| 多型類型 | 編譯期多型(靜態) | 執行期多型(動態) |
抽象類別 vs 介面
- 抽象類別:可包含抽象方法和具體方法、建構子、成員變數。單繼承,用於「is-a」關係,提供部分實現。
- 介面:Java 8 前全為抽象方法;Java 8+ 支援 default/static 方法;Java 9+ 支援 private 方法。多實現,用於「has-a」能力定義。
- 介面變數隱含
public static final;抽象類別變數可為任意修飾符。
設計模式常見考點
- 單例模式:確保類別只有一個實例(雙重檢查鎖、靜態內部類、枚舉實現)
- 工廠模式:簡單工廠、工廠方法、抽象工廠,解耦物件創建
- 觀察者模式:定義一對多依賴,狀態變更自動通知(事件監聽器)
- 策略模式:封裝演算法族,運行時動態切換(Comparator、支付策略)
- 代理模式:為其他物件提供代理,控制存取(Spring AOP、遠程代理)
JavaBean 與 JSP 整合
<jsp:useBean id="user" class="com.example.User" scope="session"/>
<jsp:setProperty name="user" property="*"/>
<jsp:getProperty name="user" property="name"/>
JavaBean 特徵:public 類別、無參建構子、private 屬性 + public getter/setter、實現 Serializable。
XML 解析技術對比
| 解析器 | 特點 | 適用場景 |
| DOM (JAXP) | 樹狀結構,一次性載入記憶體,支援隨機存取 | 小型 XML、需頻繁修改結構 |
| SAX | 事件驅動,流式讀取,記憶體佔用低,唯讀 | 大型 XML、單向解析、效能敏感 |
| JDOM/DOM4J | Java 原生 API,支援 XPath,易用性強 | 企業級開發、複雜 XML 處理 |
GUI 技術:SWT vs Swing
- Swing:純 Java 繪製,跨平台一致性好,元件豐富,但效能依賴 JVM
- SWT:封裝原生 OS GUI 元件,效能接近原生,外觀隨平台變化,需分發平台專屬庫
關鍵字辨析:final, finally, finalize
- final:修飾符。類別不可繼承、方法不可覆寫、變數不可變更(基本型別值不變、引用型別地址不變)
- finally:異常處理區塊,保證執行清理工作
- finalize:Object 方法,GC 前調用,用於資源釋放(已棄用)
EJB 與主流框架
- EJB:企業級組件,涉及 JNDI 命名查找、RMI 遠程呼叫、容器管理事務/安全
- Struts:MVC 框架,ActionForm、Action、ActionMapping、ActionForward 核心類別
- Spring:IOC 容器、AOP 切面、事務管理、MVC 模組
- Hibernate:ORM 框架,Session、SessionFactory、HQL、延遲載入、快取策略
效能優化實戰經驗
- 使用 StringBuilder 替代字串串接
- 集合預設初始容量,避免擴容開銷
- 優化 SQL:索引、避免 SELECT *、分頁查詢
- 物件池複用(執行緒池、連線池)
- 減少同步範圍,使用並發容器替代同步容器
- JVM 調优:堆大小、GC 策略、JIT 編譯優化