| # | 考點 | 關鍵結論 |
|---|---|---|
| 1 | 字符串常量池與 new String | str1 == str2 → false(堆對象 vs 常量池) |
| 2 | 整數溢出 | Integer.MAX_VALUE + 1 → Integer.MIN_VALUE,滿足 (i+1)<i |
| 3 | GC 線程屬性 | GC 是 Daemon 線程,非用戶線程 |
| 4 | volatile 不保證原子性 | 100 萬循環 × 10 線程,count 遠小於 1000 萬 |
| 5 | ArrayList 擴容機制 | 初始容量 20,添加 1 元素不觸發 grow |
| 6 | BufferedReader 構造器參數 | 只接受 Reader,FileInputStream 需轉換 |
| 7 | 異常捕獲順序 | 子類異常需放前面,否則被父類捕獲 |
| 8 | 局部變量未初始化 | 編譯錯誤:variable might not have been initialized |
| 9 | 字符串拼接優先級 | "5" + 2 → "52"(字符串連接) |
| 10 | switch 穿透特性 | 無 break 導致 case 2、3 連續執行,result=10 |
| 11 | 靜態方法可通過 null 調用 | 編譯期綁定,((Null)null).hello() 正常輸出 |
| 12 | 值傳遞:String 不可變 | 方法內修改參數引用不影響外部,輸出 "good" |
| 13 | 值傳遞:數組引用可修改內容 | 方法內 ch[0]='g' 影響外部,輸出 "gbc" |
| 14 | for 循環執行順序 | 輸出:A B D C B D C B D |
| 15 | 類初始化順序 | 靜態塊 → 父非靜態塊 → 父構造器 → 子非靜態塊 → 子構造器 |
private static volatile int count = 0;
// 10 線程各自增 100 萬
// count++ 非原子:讀取-修改-寫入 三步操作
// volatile 僅保證 可見性 + 有序性,不保證 原子性
// 正確做法:AtomicInteger / LongAdder / synchronized
for (foo('A'); foo('B') && (i<2); foo('C')) {
i++;
foo('D');
}
// 執行順序:
// 1. foo('A') → true
// 2. foo('B') → true, i=0<2 → 進入循環體
// 3. i++ → 1, foo('D')
// 4. foo('C') → true
// 5. foo('B') → true, i=1<2 → 進入循環體
// 6. i++ → 2, foo('D')
// 7. foo('C') → true
// 8. foo('B') → true, i=2<2 false → 結束
// 輸出:A B D C B D C B D
「靜態優先,父先子後;塊後構造,逐層遞歸。」
static A → static B → I'm A class → HelloA → I'm B class → HelloB
// 兩次 new HelloB() 只觸發非靜態部分
LongAdder 原理、CAS、偽共享。