Java程序員修煉之道(第2版) The Well-Grounded Java Developer, Second Edition
[英] 本傑明 · J. 埃文斯(Benjamin J. Evans) [美] 傑森 · 克拉克(Jason Clark) [荷] 馬丁 · 韋爾伯格(Martijn Verburg)
- 出版商: 人民郵電
- 出版日期: 2025-06-01
- 售價: $959
- 語言: 簡體中文
- 頁數: 571
- ISBN: 7115662320
- ISBN-13: 9787115662323
- 此書翻譯自: The Well-Grounded Java Developer, Second Edition
下單後立即進貨 (約4週~6週)
相關主題
商品描述
《Java 程序員修煉之道(第2 版)》是為有誌成為卓越 Java 開發者的人編寫的實用指南。相比於第 1 版,第 2 版擴展了內容,深入探討了 Java 8、11 及更高版本的特性。本書不僅覆蓋了 Java 語言本身的新特性,還引入了與現代開發實踐息息相關的主題,包括函數式編程、並發、多語言編程及容器化部署等。本書的核心目標是幫助開發者建立紮實的基礎,掌握 Java 語言和 JVM 平臺的深層知識,同時引導讀者了解 Java 生態中的非 Java 語言,如 Kotlin 和 Clojure。通過對 Java 語言核心原理的學習,讀者將掌握如何高效地使用 Java,如何應對日益復雜的開發環境,並理解平臺的未來演化方向。
作者簡介
本傑明·J. 埃文斯(Benjamin J. Evans)
全球 Java 領域最具影響力的技術專家之一。作為 Java Champion,他在 Java 社區享有崇高聲譽,參與制定Java標準,直接影響 Java 生態的發展方向。目前擔任紅帽公司首席軟件工程師,致力於企業級 Java 解決方案的創新與優化。
傑森·克拉克(Jason Clark)
New Relic 公司首席工程師和架構師,專註於高性能分布式系統、雲計算和 Java 生態的優化。他在企業級軟件開發、微服務架構和 JVM 深度優化方面有豐富的經驗。
馬丁·韋爾伯格(Martijn Verburg)
Java 生態領域的頂尖技術領袖之一,AdoptOpenJDK(現為 Eclipse Adoptium) 聯合創始人,現任微軟首席工程組經理(Java & Golang)。同時,馬丁是倫敦 Java 社區(LJC)的聯合領導者,致力於推動 Java 技術在全球開發者社區中的普及與創新。他在多個 Java 規範組織中擔任重要角色,直接參與 Java 標準的制定與演進。
目錄大綱
第 一部分 從 Java 8 到 Java 17 及更高版本
第 1章 現代 Java 介紹 2
1.1 Java 語言和 Java 平臺 2
1.2 Java 的新發布模型 4
1.3 類型推斷增強(var 關鍵字) 7
1.4 語言和平臺的更改 10
1.4.1 撒點兒糖 11
1.4.2 語言更改 11
1.4.3 JSR 和 JEP 12
1.4.4 孵化特性和預覽特性 12
1.5 Java 11 中的小變更 13
1.5.1 集合工廠(JEP 213) 13
1.5.2 移除企業版模塊(JEP 320) 14
1.5.3 HTTP/2(Java 11) 15
1.5.4 單文件源代碼程序(JEP 330) 19
小結 21
第 2章 Java 模塊 22
2.1 場景設置 22
2.1.1 Jigsaw 項目 23
2.1.2 模塊圖 26
2.1.3 保護內部 27
2.1.4 新的訪問控制語義 28
2.2 模塊的基本語法 29
2.2.1 導出和依賴 30
2.2.2 傳遞性 31
2.3 模塊加載 32
2.3.1 平臺模塊 32
2.3.2 應用模塊 33
2.3.3 自動模塊 33
2.3.4 未命名模塊 34
2.4 構建模塊化應用程序 34
2.4.1 模塊的命令行開關 35
2.4.2 運行模塊化應用 37
2.4.3 模塊與反射 38
2.5 模塊架構 39
2.5.1 拆分包 40
2.5.2 Java 8 運行時精簡模式 40
2.5.3 多版本 JAR 42
2.6 超越模塊 45
小結 46
第3章 Java 17 47
3.1 文本塊 47
3.2 switch 表達式 48
3.3 record 51
3.3.1 名義類型 56
3.3.2 緊湊記錄構造器 58
3.4 sealed 59
3.5 instanceof 的新用法 63
3.6 模式匹配和預覽特性 65
小結 67
第二部分 內部原理
第4章 類文件和字節碼 70
4.1 類加載和類對象 71
4.1.1 加載和鏈接 72
4.1.2 類對象 73
4.2 類加載器 74
4.2.1 自定義類加載器 76
4.2.2 模塊和類加載 82
4.3 檢查類文件 82
4.3.1 javap 簡介 83
4.3.2 方法簽名的內部表示形式 83
4.3.3 常量池 84
4.4 字節碼 87
4.4.1 分解類文件 87
4.4.2 運行時環境 89
4.4.3 操作碼介紹 91
4.4.4 加載和存儲操作碼 92
4.4.5 數學運算操作碼 93
4.4.6 流程控制操作碼 93
4.4.7 調用操作碼 94
4.4.8 平臺操作碼 97
4.4.9 操作碼的快捷形式 97
4.5 反射 98
4.5.1 反射概述 98
4.5.2 類加載與反射 100
4.5.3 反射的局限性 101
小結 102
第5章 Java 並發基礎 103
5.1 並發理論 104
5.1.1 我已經了解線程了 104
5.1.2 硬件 104
5.1.3 Amdahl 定律 105
5.1.4 Java 的線程模型 106
5.1.5 經驗教訓 107
5.2 設計原則 107
5.2.1 安全性 107
5.2.2 活躍度 108
5.2.3 性能 109
5.2.4 重用性 109
5.2.5 這些設計原則為何以及如何
相互沖突 109
5.2.6 系統開銷之源 110
5.3 塊結構並發 110
5.3.1 同步與鎖 111
5.3.2 線程的狀態模型 112
5.3.3 完全同步對象 113
5.3.4 死鎖 114
5.3.5 為什麼要同步 117
5.3.6 volatile 關鍵字 118
5.3.7 Thread 類的狀態和方法 119
5.3.8 不變性 124
5.4 Java 內存模型 128
5.5 通過字節碼理解並發 129
5.5.1 更新丟失 131
5.5.2 同步的字節碼表示 133
5.5.3 同步方法 136
5.5.4 非同步讀取 137
5.5.5 重溫死鎖 139
5.5.6 重溫死鎖解決方案 141
5.5.7 易失性訪問 145
小結 147
第6章 JDK 並發庫 148
6.1 現代並發程序的構建塊 148
6.2 原子類 149
6.3 鎖 150
6.4 CountDownLatch 152
6.5 ConcurrentHashMap 154
6.5.1 簡化版 HashMap 154
6.5.2 Dictionary 的局限性 157
6.5.3 並發 Dictionary 158
6.5.4 使用 ConcurrentHashMap 160
6.6 CopyOnWriteArrayList 162
6.7 阻塞隊列 165
6.7.1 使用 BlockingQueue API 170
6.7.2 使用工作單元 171
6.8 Future 172
6.9 任務與執行 175
6.9.1 任務建模 176
6.9.2 執行器 177
6.9.3 單線程執行器 178
6.9.4 大小固定的線程池 178
6.9.5 緩存線程池 179
6.9.6 ScheduledThreadPool-Executor 180
小結 181
第7章 理解 Java 性能 182
7.1 性能術語:基本定義 184
7.1.1 時延 184
7.1.2 吞吐量 185
7.1.3 利用率 185
7.1.4 效率 185
7.1.5 容量 185
7.1.6 可擴展性 185
7.1.7 退化 185
7.2 性能分析的實用方法 186
7.2.1 知道自己在測量什麼 186
7.2.2 了解如何進行測量 187
7.2.3 知道性能目標是什麼 188
7.2.4 知道什麼時候停止 188
7.2.5 了解實現更高性能的成本 189
7.2.6 了解過早優化的危險 189
7.3 出了什麼問題,我們為什麼要關心 190
7.3.1 摩爾定律 190
7.3.2 理解內存延遲層級 192
7.4 Java 性能調優為什麼這麼難 193
7.4.1 時間在性能調優中的作用 194
7.4.2 理解緩存未命中 195
7.5 垃圾收集 196
7.5.1 基礎知識 197
7.5.2 標記-清除 197
7.5.3 內存區域 199
7.5.4 新生代垃圾收集 199
7.5.5 老年代垃圾收集 200
7.5.6 安全點 200
7.5.7 G1:Java 的默認垃圾收集器 200
7.5.8 並行收集器 202
7.5.9 GC 配置參數 203
7.6 使用 HotSpot 進行 JIT 編譯 204
7.6.1 為什麼要動態編譯 205
7.6.2 HotSpot 簡介 205
7.6.3 內聯方法 206
7.6.4 動態編譯和單態分派 207
7.6.5 理解編譯日誌 207
7.6.6 逆優化 208
7.7 JDK 飛行記錄器 209
7.7.1 JFR 209
7.7.2 JMC 210
小結 215
第三部分 JVM 上的多語言編程
第8章 JVM 語言 218
8.1 語言生態學 218
8.1.1 解釋型語言與編譯型語言 219
8.1.2 動態類型語言與靜態類型語言 219
8.1.3 命令式語言與函數式語言 220
8.1.4 對現有語言的重新實現與原始 JVM 語言 221
8.2 JVM 上的多語言編程 222
8.2.1 為什麼使用非 Java 語言 223
8.2.2 新興語言 225
8.2.3 那些我們沒有選擇的語言 226
8.3 如何為項目選擇非 Java 語言 227
8.3.1 項目域的風險承受能力是高還是低 228
8.3.2 該語言與 Java 的互操作性如何 228
8.3.3 這門語言是否有良好的工具和測試支持 229
8.3.4 這門語言有多難學 229
8.3.5 使用這門語言的開發者多嗎 229
8.4 JVM 對其他語言的支持 230
8.4.1 性能 230
8.4.2 非 Java 語言的運行時環境 231
8.4.3 編譯器虛構 231
小結 233
第9章 Kotlin 234
9.1 為什麼使用 Kotlin 234
9.2 便利和簡潔 235
9.2.1 從少開始 235
9.2.2 變量 236
9.2.3 相等性 236
9.2.4 函數 237
9.2.5 集合 240
9.2.6 表達自己 242
9.3 對類和對象的不同看法 244
9.4 安全 250
9.4.1 空安全 250
9.4.2 智能轉型 251
9.5 並發 253
9.6 與 Java 的互操作性 256
小結 259
第 10章 Clojure:編程新視角 260
10.1 介紹 Clojure 261
10.1.1 在 Clojure 中實現 Hello
World 262
10.1.2 REPL 入門 264
10.1.3 犯錯 265
10.1.4 學著去愛括號 268
10.2 尋找 Clojure:語法和語義 269
10.2.1 特殊形式訓練營 269
10.2.2 列表、向量、映射和集合 271
10.2.3 算術、相等和其他操作 274
10.2.4 使用函數 275
10.2.5 Clojure 中的循環 278
10.2.6 讀取器宏和派發器 279
10.3 函數式編程和閉包 281
10.4 Clojure 序列 282
10.5 Clojure 和 Java 的互操作 287
10.5.1 從 Clojure 中調用 Java 288
10.5.2 Clojure 調用的本質 288
10.5.3 Clojure 值的 Java 類型 289
10.5.4 使用 Clojure 代理 290
10.5.5 使用 REPL 進行探索式編程 290
10.5.6 在 Java 中使用 Clojure 291
10.6 宏 292
小結 296
第四部分 構建和運行 Java 應用
第 11章 構建工具 Gradle 和 Maven 298
11.1 為什麼構建工具對優秀的程序員至關重要 298
11.1.1 自動化煩瑣的操作 298
11.1.2 管理依賴 299
11.1.3 確保開發者間的一致性 302
11.2 Maven 303
11.2.1 構建生命周期 303
11.2.2 命令 /POM 概述 304
11.2.3 構建 305
11.2.4 控制清單文件 306
11.2.5 添加多語言支持 307
11.2.6 測試 310
11.2.7 依賴管理 313
11.2.8 評估 316
11.2.9 超越 Java 8 317
11.2.10 如何在 Maven 中使用不同版本的 JAR 318
11.2.11 Maven 與模塊 321
11.2.12 編寫 Maven 插件 324
11.3 Gradle 327
11.3.1 安裝 Gradle 327
11.3.2 任務 328
11.3.3 腳本 329
11.3.4 使用插件 330
11.3.5 構建 331
11.3.6 避免工作 333
11.3.7 Gradle 中的依賴 334
11.3.8 增加對 Kotlin 的支持 338
11.3.9 測試 339
11.3.10 自動化靜態分析 340
11.3.11 超越 Java 8 341
11.3.12 通過 Gradle 使用模塊 341
11.3.13 定制化 347
小結 350
第 12章 在容器中運行 Java 351
12.1 為什麼容器對優秀的 Java 程序員至關重要 351
12.1.1 操作系統、虛擬機、容器的區別與聯系 351
12.1.2 容器的優勢 353
12.1.3 容器的缺點 354
12.2 容器基礎 355
12.2.1 構建容器鏡像 355
12.2.2 運行 Docker 容器 358
12.3 使用 Docker 開發 Java 應用程序 360
12.3.1 選擇基礎鏡像 360
12.3.2 使用 Gradle 構建鏡像 361
12.3.3 在容器中執行構建 362
12.3.4 端口與主機 364
12.3.5 使用 Docker Compose 進行本地開發 366
12.3.6 在容器中調試 369
12.3.7 容器中的日誌 371
12.4 Kubernetes 372
12.5 可觀測性與性能 379
12.5.1 可觀測性 379
12.5.2 容器中的性能 381
小結 382
第 13章 測試基礎 383
13.1 為什麼要測試 383
13.2 如何開展測試 384
13.3 測試驅動開發 386
13.3.1 TDD 概述 387
13.3.2 一個單一用例的 TDD 示例 388
13.4 測試替身 393
13.4.1 Dummy 對象 394
13.4.2 Stub 對象 396
13.4.3 Fake 對象 398
13.4.4 Mock 對象 400
13.4.5 Mock 的問題 401
13.5 從 JUnit 4 到 JUnit 5 402
小結 408
第 14章 測試不止 JUnit 409
14.1 使用 Testcontainers 進行集成測試 409
14.1.1 安裝 testcontainers 庫 409
14.1.2 Redis 示例 410
14.1.3 收集容器的日誌 413
14.1.4 Postgres 示例 414
14.1.5 使用 Selenium 進行端到端測試的示例 416
14.2 利用 Spek 和 Kotlin 規範測試風格 418
14.3 使用 Clojure 進行基於屬性的測試 423
14.3.1 clojure.test 423
14.3.2 closure.spec 425
14.3.3 test.check 428
14.3.4 clojure.spec 和test.check 433
小結 434
第五部分 Java世界的前沿展望
第 15章 高級函數式編程 436
15.1 函數式編程的概念 436
15.1.1 純函數 437
15.1.2 不可變性 437
15.1.3 高階函數 437
15.1.4 遞歸 438
15.1.5 閉包 438
15.1.6 惰性求值 439
15.1.7 柯裏化與部分執行 439
15.2 Java 作為一門函數式語言的局限性 440
15.2.1 純函數 440
15.2.2 可變性 441
15.2.3 高階函數 443
15.2.4 遞歸 444
15.2.5 閉包 447
15.2.6 惰性求值 448
15.2.7 柯裏化與部分執行 450
15.2.8 Java 的類型系統與集合類型 450
15.3 Kotlin 中的函數式編程 452
15.3.1 純函數及高階函數 452
15.3.2 閉包 453
15.3.3 柯裏化與部分執行 454
15.3.4 不可變性 455
15.3.5 尾遞歸 458
15.3.6 惰性求值 461
15.3.7 序列 462
15.4 Clojure 的函數式編程 466
15.4.1 推導式 466
15.4.2 惰性序列 467
15.4.3 Clojure 中的柯裏化 469
小結 470
第 16章 高級並發程序設計 471
16.1 Fork/Join 框架 471
16.1.1 一個簡單的 Fork/Join應用示例 472
16.1.2 通過 Fork/Join 框架將問題處理並行化 475
16.1.3 工作竊取算法 476
16.2 並發與函數式編程 477
16.2.1 回顧 CompletableFuture 477
16.2.2 並行流 481
16.3 深入了解 Kotlin 協程的實現原理 482
16.3.1 協程的工作原理 482
16.3.2 協程的作用域及調度 487
16.4 Clojure 中的並發實踐 489
16.4.1 持久化數據結構 490
16.4.2 Future 和 pcall 495
16.4.3 軟件事務內存 497
16.4.4 代理 500
小結 501
第 17章 現代內核 503
17.1 JVM 內核概述 503
17.1.1 調用虛方法 504
17.1.2 調用接口方法 507
17.1.3 調用“特殊”方法 508
17.1.4 final 方法 509
17.2 反射的內部機制 510
17.3 方法句柄 514
17.3.1 MethodHandle 514
17.3.2 MethodType 516
17.3.3 查找方法句柄 516
17.3.4 反射、代理和方法句柄 517
17.4 動態調用 519
17.5 JVM 內核的最新變化 523
17.5.1 字符串連接 523
17.5.2 壓縮字符串 525
17.5.3 Nestmates 527
17.6 Unsafe 類 529
17.7 用支持的 API 替換 Unsafe 533
17.7.1 VarHandles 534
17.7.2 隱藏類 535
小結 537
第 18章 Java 的未來 538
18.1 項目 Amber 538
18.2 項目 Panama 540
18.3 項目 Loom 546
18.3.1 虛擬線程 549
18.3.2 線程構建器 550
18.3.3 使用虛擬線程編程 551
18.3.4 項目 Loom 什麼時候發布 552
18.4 項目 Valhalla 553
18.4.1 改變語言模型 556
18.4.2 值對象帶來的影響 557
18.4.3 回顧泛型 559
18.5 Java 18 559
小結 560
附錄A 選擇 Java 版本 561
附錄B 回顧 Java 8 中的流 564