本文為「Java 基礎面試題」系列第二部分,涵蓋日期時間 API(含 Java 8 新特性)、斷言、Error/Exception 差異、try-catch-finally 執行順序、異常處理最佳實踐、集合框架核心區別、泛型與 Comparable/Comparator、多執行緒基礎與進階(sleep/wait/yield、synchronized/Lock、執行緒池、狀態轉換)、序列化、IO 流體系、XML 解析、JDBC Statement/PreparedStatement、連接池、DAO 模式、事務 ACID 与隔離級別。內容深度適合中級開發者系統複習。
| 需求 | Java 7 (Calendar) | Java 8 (java.time) |
|---|---|---|
| 取得年月日時分秒 | cal.get(Calendar.YEAR)... | LocalDateTime.now().getYear()... |
| 毫秒數 (1970 至今) | Calendar.getInstance().getTimeInMillis()System.currentTimeMillis() | Instant.now().toEpochMilli()Clock.systemUTC().millis() |
| 某月最後一天 | cal.getActualMaximum(Calendar.DAY_OF_MONTH) | YearMonth.now().lengthOfMonth() |
| 格式化日期 | SimpleDateFormat.format(date) | DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDate.now()) |
| 昨天此刻 | cal.add(Calendar.DATE, -1) | LocalDateTime.now().minusDays(1) |
關鍵差異:Java 8 java.time 為不可變、執行緒安全,API 設計符合人類直覺,強烈建議新專案全面遷移。
-da),避免效能損耗assert expr;、assert expr : "詳細訊息";assert list.add(x))OutOfMemoryError、StackOverflowError),程式無法恢復,不應捕獲StackOverflowError 最常見原因 = 遞歸無收斂條件try { return 1; } finally { System.out.println("finally"); }
結果:先印 "finally",再返回 1。
原理:return 先將值暫存,執行 finally,最後返回暫存值。
大忌:在 finally 中修改返回值或拋出異常,會掩蓋原始返回/異常。Eclipse 可設為編譯錯誤。
try 監控區塊 → catch 捕獲特定型別 → finally 釋放資源throw 拋出具體異常物件 → throws 宣告方法可能拋出的受檢異常catch 塊)ArithmeticException、ClassCastException、IllegalArgumentException、IndexOutOfBoundsException、NullPointerException、SecurityException
| 關鍵字 | 角色 | 用途 |
|---|---|---|
| final | 修飾符 | 類不可繼承、方法不可覆寫、變數不可變(常量) |
| finally | 程式碼塊 | try-catch 後必執行區塊,釋放資源 |
| finalize | Object 方法 | GC 回收前調用,整理資源(不建議依賴,Java 9 已標記棄用) |
try { throw new ExampleB(); } // B 繼承 A 繼承 Exception
catch (ExampleA e) { ... } // 會捕獲 B,因 B is-a A
catch (Exception e) { ... } // 不會執行
原則:catch 順序必須子類在前,父類在後,否則編譯錯誤或永遠捕獲不到子類。
| 介面/類 | 特徵 | 底層結構 | 執行緒安全 |
|---|---|---|---|
| List | 有序、可重複、索引存取 | ArrayList(陣列) / LinkedList(雙向鏈表) | 否 |
| Set | 無序、不可重複 | HashSet(HashMap) / TreeSet(紅黑樹) | 否 |
| Map | 鍵值對、Key 不重複 | HashMap / TreeMap / Hashtable(舊) | Hashtable 是 |
| Vector | 舊版 List,方法 synchronized | 陣列 | 是(效能差) |
Collection 是介面;Collections 是工具類(排序、同步化、二分搜尋)TreeSet/TreeMap 要求元素實作 Comparable 或傳入 ComparatorCollections.sort() 同理,支援策略模式注入比較器| 特性 | sleep() | wait() |
|---|---|---|
| 所屬類別 | Thread (static) | Object |
| 鎖行為 | 持有鎖不釋放 | 釋放鎖,進入等待池 |
| 喚醒方式 | 時間到自動 | notify()/notifyAll() |
| 狀態轉換 | Running → Blocked → Ready | Running → Wait Pool → Lock Pool → Ready |
sleep:進入阻塞,給所有優先級機會,拋 InterruptedExceptionyield:進入就緒,僅給同/高優先級機會,不拋異常,可移植性較差執行緒進入物件的 synchronized 方法 A 後,同一物件的其他 synchronized 方法 B 無法進入(需同一把鎖)。僅能存取非同步方法。
Lock (Java 5+):lock()/unlock() 手動控制,newCondition() 實現精確通知Semaphore:控制同時存取共享資源的執行緒數(acquire/release)ThreadRunnable(推薦,支援多重實作)Callable(Java 5+,call() 有返回值,配合 Future)Executors 靜態工廠:
newSingleThreadExecutor:單執行緒序列執行newFixedThreadPool(n):固定大小newCachedThreadPool:動態伸縮,60s 空閒回收newScheduledThreadPool:定時/週期任務NEW → RUNNABLE → BLOCKED/WAITING/TIMED_WAITING → TERMINATED

Serializable(標記介面)→ ObjectOutputStream.writeObject() / ObjectInputStream.readObject()。用途:持久化、深度克隆、網路傳輸InputStream/OutputStream)與字元流(Reader/Writer)InputStreamReader)與裝飾者(BufferedInputStream)| 方式 | 原理 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|---|
| DOM | 整份文件載入記憶體建樹 | 隨機存取、可修改 | 記憶體佔用大、大檔案慢 | 小檔案、需隨機存取 |
| SAX | 事件驅動,順序讀取 | 記憶體小、速度快 | 唯讀、單向、需自行維護狀態 | 大檔案、順序處理 |
| StAX | 拉取式流處理 | 記憶體小、程式主動控制 | API 較複雜 | 大檔案、需隨機跳轉 |
實務推薦:dom4j(易用 API、XPath 支援、效能佳),Sun 官方 API 已棄用維護。
| 主題 | 關鍵點 |
|---|---|
| PreparedStatement 優勢 | 預編譯(防注入)、參數化、批次處理效能高(快取執行計畫) |
| 提升讀取效能 | ResultSet.setFetchSize(n) 減少網路往返 |
| 提升更新效能 | addBatch() + executeBatch() |
| 連接池作用 | 避免頻繁建立/關閉連線開銷(TCP 三/四次握手),空間換時間 |
| 主流連接池 | C3P0、DBCP、Druid、HikariCP、BoneCP |
| DAO 模式 | Data Access Object:抽象資料存取介面,封裝持久化細節 |
| 事務 ACID | 原子性、一致性、隔離性、持久性 |
| 並發問題 | 髒讀、不可重複讀、幻讀、第1/2類丟失更新 |
| 隔離級別 | READ_UNCOMMITTED < READ_COMMITTED < REPEATABLE_READ < SERIALIZABLE |

核心權衡:隔離級別越高,並發性能越差。無萬能最佳級別,需依業務場景選擇。
系列導航:Java 基礎面試題(一) | Java 基礎面試題(二) | Java 基礎面試題(三)