Go語言是一門年輕、簡捷,但是強(qiáng)大、高效、充滿潛力的服務(wù)器語言。本書使用淺顯易懂的語言與大量圖片深入介紹了Go語言編譯時、類型系統(tǒng)、語法特性、函數(shù)調(diào)用規(guī)范、并發(fā)編程、內(nèi)存管理與垃圾回收、運行狀態(tài)監(jiān)控等模塊的使用方法和底層原理,并舉例說明了構(gòu)建大型軟件工程需要遵循的設(shè)計規(guī)則,讓作者系統(tǒng)并完整掌握Go語言隱藏在使用方法背后的底層細(xì)節(jié)。 本書適合有一定工作經(jīng)驗的開發(fā)工程師進(jìn)一步提升自己,以便更好地開發(fā)軟件、系統(tǒng)架構(gòu),并進(jìn)行工作面試。也可以作為高等院校計算機(jī)專業(yè)師生學(xué)習(xí)編程語言設(shè)計原理的參考教材。
鄭建勛,Golang contributor(Go語言垃圾回收模塊代碼貢獻(xiàn)者)、Go語言精度庫shopspring/decimal核心貢獻(xiàn)者。滴滴高級研發(fā)工程師。擁有豐富的分布式、高并發(fā)、大規(guī)模微服務(wù)集群的開發(fā)設(shè)計經(jīng)驗。從“雙非”院校畢業(yè)的小白跨行逆襲為“一線大廠扛把子”,這份學(xué)習(xí)的心路更加難能可貴。 微信公眾號gopher夢工廠作者,知名Go語言內(nèi)容原創(chuàng)博主。現(xiàn)任51CTO學(xué)堂高級講師、極客時間《每日一課》講師等。有豐富的教育經(jīng)驗,能夠想讀者之所想。相信這部系統(tǒng)且深入淺出的作品,會是讀者打怪升級的絕佳輔助資料。
目錄
第1章 深入Go語言編譯器 1
1.1 為什么要了解Go語言編譯器 1
1.2 Go語言編譯器的階段 1
1.3 詞法解析 3
1.4 語法解析 4
1.5 抽象語法樹構(gòu)建 6
1.6 類型檢查 8
1.7 變量捕獲 8
1.8 函數(shù)內(nèi)聯(lián) 9
1.9 逃逸分析 12
1.10 閉包重寫 14
1.11 遍歷函數(shù) 15
1.12 SSA生成 15
1.13 機(jī)器碼生成——匯編器 18
1.14 機(jī)器碼生成——鏈接 20
1.15 ELF文件解析 23
1.16 總結(jié) 26
第2章 浮點數(shù)設(shè)計原理與使用方法 27
2.1 浮點數(shù)陷阱 27
2.2 定點數(shù)與浮點數(shù) 27
2.3 IEEE-754浮點數(shù)標(biāo)準(zhǔn) 28
2.3.1 小數(shù)部分計算 29
2.3.2 顯示浮點數(shù)格式 30
2.4 最佳實踐:判斷浮點數(shù)為整數(shù) 31
2.5 常規(guī)數(shù)與非常規(guī)數(shù) 33
2.6 NaN與Inf 33
2.7 浮點數(shù)精度 34
2.8 浮點數(shù)與格式化打印 36
2.9 浮點數(shù)計算與精度損失 37
2.10 多精度浮點數(shù)與math/big庫 38
2.11 總結(jié) 41
第3章 類型推斷全解析 42
3.1 類型推斷的優(yōu)勢 42
3.2 Go語言中類型推斷的特性 43
3.3 類型推斷原理 44
3.3.1 詞法解析與語法分析階段 44
3.3.2 抽象語法樹生成與類型檢查 46
3.4 總結(jié) 48
第4章 常量與隱式類型轉(zhuǎn)換 49
4.1 常量聲明與生存周期 49
4.2 常量類型轉(zhuǎn)換 50
4.2.1 隱式整數(shù)轉(zhuǎn)換 50
4.2.2 隱式浮點數(shù)轉(zhuǎn)換 51
4.2.3 常量運算中的隱式轉(zhuǎn)換 51
4.2.4 常量與變量之間的轉(zhuǎn)換 51
4.2.5 自定義類型的轉(zhuǎn)換 52
4.3 常量與隱式類型轉(zhuǎn)換原理 53
4.4 總結(jié) 55
第5章 字符串本質(zhì)與實現(xiàn) 56
5.1 字符串的本質(zhì) 56
5.2 符文類型 57
5.3 字符串工具函數(shù) 58
5.4 字符串底層原理 59
5.4.1 字符串解析 59
5.4.2 字符串拼接 61
5.4.3 運行時字符拼接 62
5.4.4 字符串與字節(jié)數(shù)組的轉(zhuǎn)換 64
5.5 總結(jié) 66
第6章 數(shù)組 67
6.1 數(shù)組的聲明方式 67
6.2 數(shù)組值復(fù)制 68
6.3 數(shù)組底層原理 68
6.3.1 編譯時數(shù)組解析 68
6.3.2 數(shù)組字面量初始化原理 69
6.3.3 數(shù)組字面量編譯時內(nèi)存優(yōu)化 70
6.3.4 數(shù)組索引與訪問越界原理 70
6.4 總結(jié) 73
第7章 切片使用方法與底層原理 74
7.1 切片使用方法 74
7.1.1 切片的結(jié)構(gòu) 74
7.1.2 切片的初始化 75
7.1.3 切片的截取 75
7.1.4 切片值復(fù)制與數(shù)據(jù)引用 76
7.1.5 切片收縮與擴(kuò)容 77
7.2 切片底層原理 78
7.2.1 字面量初始化 78
7.2.2 make初始化 79
7.2.3 切片擴(kuò)容原理 80
7.2.4 切片截取原理 82
7.2.5 切片的完整復(fù)制 83
7.3 總結(jié) 84
第8章 哈希表與Go實現(xiàn)機(jī)制 85
8.1 哈希碰撞與解決方法 85
8.2 map基本操作 87
8.2.1 map聲明與初始化 87
8.2.2 map訪問 87
8.2.3 map賦值 88
8.2.4 key的比較性 88
8.2.5 map并發(fā)沖突 89
8.3 哈希表底層結(jié)構(gòu) 89
8.4 哈希表原理圖解 91
8.5 深入哈希表原理 94
8.5.1 make初始化原理 94
8.5.2 字面量初始化原理 96
8.5.3 map訪問原理 97
8.5.4 map賦值操作原理 99
8.5.5 map重建原理 102
8.5.6 map刪除原理 103
8.6 總結(jié) 104
第9章 函數(shù)與棧 105
9.1 函數(shù)基本使用方式 105
9.2 函數(shù)閉包與陷阱 106
9.3 函數(shù)棧 107
9.4 Go語言棧幀結(jié)構(gòu) 108
9.5 Go語言函數(shù)調(diào)用鏈結(jié)構(gòu)與特性 110
9.6 堆棧信息 111
9.7 棧擴(kuò)容與棧轉(zhuǎn)移原理 113
9.8 棧調(diào)試 118
9.9 總結(jié) 120
第10章 defer延遲調(diào)用 121
10.1 使用的defer的優(yōu)勢 122
10.1.1 資源釋放 122
10.1.2 異常捕獲 123
10.2 defer特性 125
10.2.1 延遲執(zhí)行 125
10.2.2 參數(shù)預(yù)計算 126
10.2.3 defer多次執(zhí)行與LIFO執(zhí)行順序 127
10.3 defer返回值陷阱 127
10.4 defer底層原理 129
10.4.1 defer演進(jìn) 129
10.4.2 堆分配 130
10.4.3 defer遍歷調(diào)用 134
10.4.4 Go 1.13棧分配優(yōu)化 137
10.4.5 Go 1.14內(nèi)聯(lián)優(yōu)化 138
10.5 總結(jié) 140
第11章 異常與異常捕獲 141
11.1 panic函數(shù)使用方法 141
11.2 異常捕獲與recover 142
11.3 panic與recover嵌套 144
11.4 panic函數(shù)底層原理 145
11.5 recover底層原理 149
11.6 總結(jié) 152
第12章 接口與程序設(shè)計模式 154
12.1 接口的用途 154
12.2 Go語言中的接口 155
12.3 Go接口實踐 156
12.4 Go接口的使用方法 158
12.4.1 Go接口的聲明與定義 158
12.4.2 接口實現(xiàn) 159
12.4.3 接口動態(tài)類型 160
12.4.4 接口的動態(tài)調(diào)用 161
12.4.5 多接口 162
12.4.6 接口的組合 162
12.4.7 接口類型斷言 163
12.4.8 空接口 164
12.4.9 接口的比較性 166
12.5 接口底層原理 166
12.5.1 接口實現(xiàn)算法 166
12.5.2 接口組成 168
12.5.3 接口內(nèi)存逃逸分析 171
12.5.4 接口動態(tài)調(diào)用過程 173
12.5.5 接口動態(tài)調(diào)用過程的效率評價 177
12.5.6 接口轉(zhuǎn)換 182
12.5.7 空接口組成 184
12.5.8 空接口switch 187
12.5.9 接口的陷阱 189
12.6 總結(jié) 191
第13章 反射高級編程 192
13.1 為什么需要反射 193
13.2 反射的基本使用方法 195
13.2.1 反射的兩種基本類型 195
13.2.2 反射轉(zhuǎn)換為接口 196
13.2.3 Elem()間接訪問 197
13.2.4 修改反射的值 199
13.2.5 結(jié)構(gòu)體與反射 200
13.2.6 遍歷結(jié)構(gòu)體字段 200
13.2.7 修改結(jié)構(gòu)體字段 201
13.2.8 嵌套結(jié)構(gòu)體的賦值 202
13.2.9 結(jié)構(gòu)體方法與動態(tài)調(diào)用 203
13.2.10 反射在運行時創(chuàng)建結(jié)構(gòu)體 205
13.2.11 函數(shù)與反射 206
13.2.12 反射與其他類型 206
13.3 反射底層原理 207
13.3.1 reflect.Type詳解 207
13.3.2 Interface方法原理 209
13.3.3 Int方法原理 211
13.3.4 Elem方法釋疑 211
13.3.5 動態(tài)調(diào)用剖析 213
13.4 總結(jié) 216
第14章 協(xié)程初探 217
14.1 進(jìn)程與線程 217
14.2 線程上下文切換 219
14.3 線程與協(xié)程 220
14.3.1 調(diào)度方式 220
14.3.2 上下文切換的速度 220
14.3.3 調(diào)度策略 221
14.3.4 棧的大小 221
14.4 并發(fā)與并行 221
14.5 簡單協(xié)程入門 222
14.6 main協(xié)程與子協(xié)程 223
14.7 GMP模型 225
14.8 總結(jié) 226
第15章 深入?yún)f(xié)程設(shè)計與調(diào)度原理 227
15.1 協(xié)程的生命周期與狀態(tài)轉(zhuǎn)移 227
15.2 特殊協(xié)程g0與協(xié)程切換 228
15.3 線程本地存儲與線程綁定 230
15.4 調(diào)度循環(huán) 231
15.5 調(diào)度策略 232
15.5.1 獲取本地運行隊列 234
15.5.2 獲取全局運行隊列 235
15.5.3 獲取準(zhǔn)備就緒的網(wǎng)絡(luò)協(xié)程 236
15.5.4 協(xié)程竊取 237
15.6 調(diào)度時機(jī) 238
15.6.1 主動調(diào)度 238
15.6.2 被動調(diào)度 239
15.6.3 搶占調(diào)度 241
15.6.4 執(zhí)行時間過長的搶占調(diào)度 241
15.7 總結(jié) 247
第16章 通道與協(xié)程間通信 248
16.1 CSP并發(fā)編程 248
16.2 通道基本使用方式 249
16.2.1 通道聲明與初始化 249
16.2.2 channel寫入數(shù)據(jù) 250
16.2.3 通道讀取數(shù)據(jù) 250
16.2.4 通道關(guān)閉 250
16.2.5 通道作為參數(shù)和返回值 252
16.2.6 單方向通道 253
16.2.7 通道最佳實踐 254
16.3 select多路復(fù)用 258
16.3.1 select隨機(jī)選擇機(jī)制 258
16.3.2 select堵塞與控制 259
16.3.3 循環(huán)select 260
16.3.4 select 與nil 261
16.4 通道底層原理 261
16.4.1 通道結(jié)構(gòu)與環(huán)形隊列 261
16.4.2 通道初始化 263
16.4.3 通道寫入原理 263
16.4.4 通道讀取原理 265
16.5 select底層原理 267
16.5.1 select一輪循環(huán) 269
16.5.2 select二輪循環(huán) 270
16.6 總結(jié) 271
第17章 并發(fā)控制 272
17.1 context 272
17.1.1 為什么需要Context 272
17.1.2 Context使用方式 274
17.2 context原理 277
17.3 數(shù)據(jù)爭用檢查 280
17.3.1 什么是數(shù)據(jù)爭用 280
17.3.2 數(shù)據(jù)爭用檢查詳解 282
17.3.3 race工具原理 282
17.4 鎖 286
17.4.1 原子鎖 287
17.4.2 互斥鎖 289
17.4.3 互斥鎖實現(xiàn)原理 290
17.4.4 互斥鎖的釋放 294
17.4.5 讀寫鎖 295
17.4.6 讀寫鎖原理 296
17.5 總結(jié) 298
第18章 內(nèi)存分配管理 299
18.1 Go語言內(nèi)存分配全局視野 299
18.1.1 span與元素 299
18.1.2 三級對象管理 300
18.1.3 四級內(nèi)存塊管理 301
18.2 對象分配 302
18.2.1 微小對象 302
18.2.2 mcache緩存位圖 304
18.2.3 mcentral遍歷span 305
18.2.4 mheap緩存查找 307
18.2.5 mheap基數(shù)樹查找 307
18.2.6 操作系統(tǒng)內(nèi)存申請 311
18.2.7 小對象分配 311
18.2.8 大對象分配 312
18.3 總結(jié) 312
第19章 垃圾回收初探 313
19.1 為什么需要垃圾回收 314
19.1.1 減少錯誤和復(fù)雜性 314
19.1.2 解耦 314
19.2 垃圾回收的5種經(jīng)典算法 315
19.2.1 標(biāo)記-清掃 315
19.2.2 標(biāo)記-壓縮 316
19.2.3 半空間復(fù)制 316
19.2.4 引用計數(shù) 317
19.2.5 分代GC 318
19.3 Go語言中的垃圾回收 318
19.3.1 為什么不選擇壓縮GC? 319
19.3.2 為什么不選擇分代GC? 319
19.4 Go垃圾回收演進(jìn) 319
19.5 總結(jié) 321
第20章 深入垃圾回收全流程 322
20.1 垃圾回收循環(huán) 322
20.2 標(biāo)記準(zhǔn)備階段 323
20.2.1 計算標(biāo)記協(xié)程的數(shù)量 323
20.2.2 切換到后臺標(biāo)記協(xié)程 325
20.3 并發(fā)標(biāo)記階段 325
20.3.1 根對象掃描 327
20.3.2 全局變量掃描 328
20.3.3 finalizer 330
20.3.4 棧掃描 331
20.3.5 棧對象 332
20.3.6 掃描灰色對象 333
20.4 標(biāo)記終止階段 336
20.5 輔助標(biāo)記 339
20.6 屏障技術(shù) 341
20.7 垃圾清掃 347
20.7.1 懶清掃邏輯 348
20.7.2 輔助清掃 349
20.8 系統(tǒng)駐留內(nèi)存清除 350
20.9 實戰(zhàn):垃圾回收產(chǎn)生的性能問題 352
20.10 總結(jié) 354
第21章 調(diào)試?yán)鳎禾卣鞣治雠c事件追蹤 355
21.1 pprof的使用方式 355
21.1.1 堆內(nèi)存特征分析 357
21.1.2 pprof可視化結(jié)果說明 360
21.1.3 pprof協(xié)程棧分析 361
21.1.4 base基準(zhǔn)分析 362
21.1.5 mutex堵塞分析 363
21.1.6 CPU占用分析 363
21.2 火焰圖分析 365
21.3 trace事件追蹤 366
21.3.1 trace工具的用法與說明 366
21.3.2 trace 分析場景 369
21.4 pprof底層原理 370
21.4.1 堆內(nèi)存樣本 370
21.4.2 協(xié)程棧樣本收集原理 372
21.4.3 CPU樣本收集原理 372
21.4.4 pprof分析原理 375
21.5 trace底層原理 377
21.6 總結(jié) 379