首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 核心高級特性面試必考點:集合、並發、字符串、隨機數與線程安全

     編輯:Java 相關知識

本文匯總 Java 核心高級特性中的高頻面試考點與實戰易錯點,涵蓋集合框架差異、隨機數陷阱、字符串拼接行為、線程安全類特征與字符長度計算,助力面試突擊與代碼質量提升。

1. HashMap vs Hashtable 核心差異

維度HashMapHashtable
線程安全非線程安全同步方法 (synchronized),線程安全
Null 鍵/值允許 1 個 null key、多個 null value不允許 null key/value,拋 NPE
繼承體系AbstractMapDictionary (舊 API)
迭代器fail-fast (快速失敗)Enumerator (非 fail-fast)
性能高 (無同步開銷)低 (全鎖同步)
初始容量/擴容16 → 2倍11 → 2n+1
JDK 1.8 優化鏈表轉紅黑樹 (閾值 8)無

生產環境選型建議

  • 單線程/非併發:HashMap
  • 多線程高併發讀寫:ConcurrentHashMap (JDK 1.8 CAS + synchronized + 紅黑樹)
  • 舊代碼維護/強一致性需求:Collections.synchronizedMap(new HashMap()) 或 Hashtable

2. Random.nextInt(n) 邊界陷阱

// 常見錯誤認知
Random r = new Random();
int num = r.nextInt(10) + 1;  // 實際範圍:[1, 10]
// nextInt(10) 返回 [0, 9] → +1 後 [1, 10]

// 正確理解
// nextInt(bound) 返回 [0, bound-1]
// 如需 [min, max] 閉區間:
int randomInRange = r.nextInt(max - min + 1) + min;

ThreadLocalRandom (JDK 7+ 推薦)

// 多線程環境下性能優於 Random
int num = ThreadLocalRandom.current().nextInt(1, 11); // [1, 10] 左閉右開

3. 字符串 + 操作符重載行為

編譯期優化:字面量常量折疊

String s1 = "a" + "b" + "c";  // 編譯期直接優化為 "abc"
String s2 = "a" + 1 + 2;      // "a12" (左到右:("a"+1)="a1" → "a1"+2="a12")
String s3 = 1 + 2 + "a";      // "3a" (左到右:(1+2)=3 → 3+"a"="3a")

運行期:StringBuilder 自動優化

String a = "a";
String b = "b";
String s = a + b;  // 反編譯等價:
// new StringBuilder().append(a).append(b).toString()

循環中拼接性能殺手

// 反模式:每次循環創建 StringBuilder
String result = "";
for (int i = 0; i < 10000; i++) {
    result += i;  // 極慢,O(n²)
}

// 正確:複用 StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.append(i);
}
String result = sb.toString();

4. 線程安全類特征與選型

JDK 內建線程安全類 (舊 API)

  • Vector - 同步方法的動態數組 (推薦 ArrayList + 外部同步/並發包)
  • Hashtable - 同步方法的哈希表 (推薦 ConcurrentHashMap)
  • Stack - 繼承 Vector (推薦 ArrayDeque)
  • Enumeration - 疊代器 (推薦 Iterator)
  • StringBuffer - 同步字符串構建器 (推薦 StringBuilder 單線程)

現代並發包替代方案 (java.util.concurrent)

舊類現代替代優勢
VectorCopyOnWriteArrayList / List + ReentrantLock讀多寫少 / 精細控制
HashtableConcurrentHashMap分段鎖/CAS,高併發吞吐
StackArrayDeque / ConcurrentLinkedDeque非同步雙端隊列 / 線程安全棧
StringBufferStringBuilder (單線程) / StringJoiner無鎖開銷 / 格式化拼接

核心原則

線程安全類方法級同步 ≠ 復合操作線程安全
例:if (!hashtable.containsKey(key)) hashtable.put(key, value); 仍需外部同步

5. 字符長度計算規則

// Java char 為 UTF-16 代碼單元 (2 字節)
String s = "a中😀";  // 英文、中文、Emoji

s.length();        // 4 (UTF-16 代碼單元數:a=1, 中=1, 😀=2 個 surrogate pair)
s.codePointCount(0, s.length()); // 3 (實際 Unicode 碼點數)
s.getBytes(StandardCharsets.UTF_8).length; // 7 (UTF-8 字節數:a=1, 中=3, 😀=4)

常見長度單位對照

字符類型char/length()codePointCount()UTF-8 bytesUTF-16 bytes
ASCII (a-Z, 0-9, 符號)1112
中日韓統一表意文字 (CJK)1132
Emoji / 輔助平面字符2 (surrogate pair)144

6. 綜合實戰題:找出代碼問題

// 題目 1:Map 併發
Map<String, Integer> map = new HashMap<>();
// 多線程 put/get → 可能導致死循環 (JDK 7 擴容鏈表成環) 或數據丟失
// 修正:ConcurrentHashMap

// 題目 2:隨機數
int prize = new Random().nextInt(100) + 1; // [1, 100] ✓
// 但若作為安全令牌 → 不安全,用 SecureRandom

// 題目 3:字符串拼接
String sql = "SELECT * FROM user WHERE id = " + id + " AND name = '" + name + "'";
// 風險:SQL 注入 + 拼接性能
// 修正:PreparedStatement / StringBuilder

// 題目 4:線程安全復合操作
Vector<String> v = new Vector<>();
if (v.isEmpty()) v.add("first"); // 非原子!兩線程同時進入 → 重複添加
// 修正:synchronized(v) { if (v.isEmpty()) v.add("first"); }

// 題目 5:字符長度截取
String sub = s.substring(0, 10); // 可能截斷 Emoji surrogate pair → 亂碼
// 修正:按 codePoint 截取或用 StringBuilder + codePoint 判斷

總結

Java 高級特性考點往往隱藏在「看似簡單的 API 行為差異」中:HashMap 非線程安全與擴容機制、Random 邊界與安全性、字符串拼編譯期/運行期雙重語義、線程安全類「方法安全 ≠ 復合安全」、字符長度的多重度量標準。掌握本質、避開陷阱、選對工具,是從「會用」到「精通」的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved