Go語言高級編程

Go語言高級編程

《Go語言高級編程》是2020年4月人民郵電出版社出版的圖書,作者是柴樹杉、曹春暉。

基本介紹

  • 中文名:Go語言高級編程
  • 作者:柴樹杉、曹春暉
  • 出版時間:2020年4月
  • 出版社:人民郵電出版社
  • 頁數:365 頁
  • ISBN:9787115510365
  • 定價:89 元
  • 開本:16 開
  • 裝幀平裝
內容簡介,圖書目錄,

內容簡介

本書從實踐出發講解Go語言的進階知識。本書共6章,第1章簡單回顧Go語言的發展歷史;第2章和第3章系統地介紹CGO編程和Go彙編語言的用法;第4章對RPC和Protobuf技術進行深入介紹,並講述如何打造一個自己的RPC系統;第5章介紹工業級環境的Web系統的設計和相關技術;第6章介紹Go語言在分散式領域的一些編程技術。書中還涉及CGO和彙編方面的知識,其中CGO能夠幫助讀者繼承的軟體遺產,而在深入學習Go運行時,彙編對於理解各種語法設計的底層實現是必不可少的知識。此外,本書還包含一些緊跟潮流的內容,介紹開源界流行的gRPC及其相關套用,講述Go Web框架中的基本實現原理和大型Web項目中的技術要點,引導讀者對Go語言進行更深入的套用。
本書適合對Go語言的套用已經有一些心得,並希望能夠深入理解底層實現原理或者是希望能夠在Web開發方面結合Go語言來實現禁棄艱進階學習的技術人員學習和參考。

圖書目錄

第1章 語言基礎 1
1.1 Go語言創世紀 1
1.1.1 來自貝爾實驗室特有基因 3
1.1.2 邀姜頁你好,世界 4
1.2 “Hello, World”的革命 5
1.2.1 B語言——Ken Thompson, 1969 5
1.2.2 C語言——Dennis Ritchie,1972—1989 5
1.2.3 Newsqueak——Rob Pike, 1989 7
1.2.4 Alef——Phil Winterbottom, 1993 9
1.2.5 Limbo——Sean Dorward, Phil Winterbottom, Rob Pike, 1995 10
1.2.6 Go語言——2007—2009 11
1.2.7 你好,世界!——V2.0 13
1.3 數組、字元串和切片 13
1.3.1 數組 14
1.3.2 字元串 17
1.3.3 切片 21
1.4 函式、方法和接口 27
1.4.1 函式 27
1.4.2 方法 31
1.4.3 接口 35
1.5 面向並發的記憶體模型 39
1.5.1 Goroutine和系統線懂嘗程 40
1.5.2 原子操作 40
1.5.3 順序一致性記憶體模型 44
1.5.4 初始化順序 45
1.5.5 Goroutine的創建 46
1.5.6 基於通道的通信 46
1.5.7 不靠譜的同步 48
1.6 常見的併發模式 49
1.6.1 並發版本的“Hello, World” 50
1.6.2 生產者/消費者模型 52
1.6.3 習項促囑發布/訂閱模型 53
1.6.4 控制並發數 56
1.6.5 贏者為王 57
1.6.6 素數篩 58
1.6.7 並發的安全退出 59
1.6.8 context包 62
1.7 錯誤和異常 64
1.7.1 錯誤處理策略 65
1.7.2 獲取錯誤的上下文 67
1.7.3 錯誤的錯誤返回 69
1.7.4 剖析異常 70
1.8 補充說明 73
第 2章 CGO編程 74
2.1 快速入門 74
2.1.1 最簡CGO程式 74
2.1.2 基於C標準庫函式輸出字元串 75
2.1.3 使用自己的C函式 75
2.1.4 C代碼的頁歡白模組化 76
2.1.5 用Go重新實現C函式 77
2.1.6 面向C接口的Go編程 78
2.2 CGO基礎 79
2.2.1 import ""C""語句 79
2.2.2 #cgo語句 81
2.2.3 build標誌條件編譯 82
2.3 類型轉換 83
2.3.1 數值類型寒頁茅 83
2.3.2 Go字元串和切片 85
2.3.3 結構體、聯合和枚舉類型 86
2.3.4 數組、字元串和切片 89
2.3.5 指針間的轉換 91
2.3.6 數值和指針的轉換 92
2.3.7 切片間的轉換 93
2.4 函式調用 94
2.4.1 Go調用C函式 94
2.4.2 C函式的返回值 94
2.4.3 void函式的返回值 95
2.4.4 C調用Go導出函式 96
2.5 戀踏詢寒內部機制 97
2.5.1 CGO生成的中間檔案 97
2.5.2 Go調用C函式 98
2.5.3 C調用Go函式 101
2.6 實戰:封裝qsort 103
2.6.1 認識qsort()函式 103
2.6.2 將qsort()函式從Go包導出 104
2.6.3 改進:閉包函式作為比較函式 106
2.6.4 改進:消除用戶對unsafe包的依賴 108
2.7 CGO記憶體模型 110
2.7.1 Go訪問C記憶體 110
2.7.2 C臨時訪問傳入的Go記憶體 111
2.7.3 C長期持有Go指針對象 113
2.7.4 導出C函式不能返回Go記憶體 115
2.8 C++類包裝 117
2.8.1 C++類到Go語言對象 117
2.8.2 Go語言對象到C++類 121
2.8.3 徹底解放C++的this指針 125
2.9 靜態庫和動態庫 126
2.9.1 使用C靜態庫 126
2.9.2 使用C動態庫 128
2.9.3 導出C靜態庫 129
2.9.4 導出C動態庫 131
2.9.5 導出非main包的函式 131
2.10 編譯和連結參數 133
2.10.1 編譯參數:CFLAGS/CPPFLAGS/CXXFLAGS 133
2.10.2 連結參數:LDFLAGS 133
2.10.3 pkg-config 133
2.10.4 go get鏈 134
2.10.5 多個非main包中導出C函式 135
2.11 補充說明 135
第3章 Go彙編語言 136
3.1 快速入門 136
3.1.1 實現和聲明 136
3.1.2 定義整數變數 137
3.1.3 定義字元串變數 138
3.1.4 定義main()函式 141
3.1.5 特殊字元 141
3.1.6 沒有分號 142
3.2 計算機結構 142
3.2.1 圖靈機和BrainFuck語言 143
3.2.2 《人力資源機器》遊戲 144
3.2.3 X86-64體系結構 145
3.2.4 Go彙編中的偽暫存器 146
3.2.5 X86-64指令集 147
3.3 常量和全局變數 150
3.3.1 常量 150
3.3.2 全局變數 150
3.3.3 變數的記憶體布局 156
3.3.4 標識符規則和特殊標誌 157
3.3.5 小結 158
3.4 函式 158
3.4.1 基本語法 158
3.4.2 函式參數和返回值 160
3.4.3 參數和返回值的記憶體布局 161
3.4.4 函式中的局部變數 163
3.4.5 調用其他函式 165
3.4.6 宏函式 166
3.5 控制流 167
3.5.1 順序執行 167
3.5.2 if/goto跳轉 169
3.5.3 for循環 171
3.6 再論函式 172
3.6.1 函式調用規範 172
3.6.2 高級彙編語言 173
3.6.3 PCDATA和FUNCDATA 176
3.6.4 方法函式 177
3.6.5 遞歸函式: 1到n求和 178
3.6.6 閉包函式 180
3.7 彙編語言的威力 182
3.7.1 系統調用 182
3.7.2 直接調用C函式 184
3.7.3 AVX指令 185
3.8 例子:Goroutine ID 187
3.8.1 故意設計沒有goid 187
3.8.2 純Go方式獲取goid 187
3.8.3 從g結構體獲取goid 189
3.8.4 獲取g結構體對應的接口對象 190
3.8.5 goid的套用:局部存儲 192
3.9 Delve調試器 194
3.9.1 Delve入門 194
3.9.2 調試彙編程式 198
3.10 補充說明 201
第4章 RPC和Protobuf 203
4.1 RPC入門 203
4.1.1 RPC版“Hello, World” 203
4.1.2 更安全的RPC接口 205
4.1.3 跨語言的RPC 207
4.1.4 HTTP上的RPC 209
4.2 Protobuf 210
4.2.1 Protobuf入門 210
4.2.2 定製代碼生成外掛程式 212
4.2.3 自動生成完整的RPC代碼 215
4.3 玩轉RPC 218
4.3.1 客戶端RPC的實現原理 218
4.3.2 基於RPC實現監視功能 220
4.3.3 反向RPC 222
4.3.4 上下文信息 223
4.4 gRPC入門 224
4.4.1 gRPC技術棧 225
4.4.2 gRPC入門 225
4.4.3 gRPC流 227
4.4.4 發布和訂閱模式 229
4.5 gRPC進階 233
4.5.1 證書認證 233
4.5.2 Token認證 236
4.5.3 截取器 238
4.5.4 和Web服務共存 240
4.6 gRPC和Protobuf擴展 241
4.6.1 驗證器 241
4.6.2 REST接口 244
4.6.3 Nginx 246
4.7 pbgo:基於Protobuf的框架 246
4.7.1 Protobuf擴展語法 246
4.7.2 外掛程式中讀取擴展信息 248
4.7.3 生成REST代碼 249
4.7.4 啟動REST服務 250
4.8 grpcurl工具 251
4.8.1 啟動反射服務 251
4.8.2 查看服務列表 252
4.8.3 服務的方法列表 253
4.8.4 獲取類型信息 253
4.8.5 調用方法 254
4.9 補充說明 255
第5章 Go和Web 256
5.1 Web開發簡介 256
5.2 請求路由 260
5.2.1 httprouter 260
5.2.2 原理 262
5.2.3 壓縮檢索樹創建過程 263
5.3 中間件 267
5.3.1 代碼泥潭 267
5.3.2 使用中間件剝離非業務邏輯 269
5.3.3 更優雅的中間件寫法 272
5.3.4 哪些事情適合在中間件中做 273
5.4 請求校驗 274
5.4.1 重構請求校驗函式 275
5.4.2 用請求校驗器解放體力勞動 276
5.4.3 原理 277
5.5 Database 和資料庫打交道 279
5.5.1 從database/sql講起 279
5.5.2 提高生產效率的ORM和
SQL Builder 281
5.5.3 脆弱的資料庫 283
5.6 服務流量限制 285
5.6.1 常見的流量限制手段 287
5.6.2 原理 289
5.6.3 服務瓶頸和 QoS 291
5.7 常見大型Web項目分層 291
5.8 接口和表驅動開發 297
5.8.1 業務系統的發展過程 297
5.8.2 使用函式封裝業務流程 298
5.8.3 使用接口來做抽象 298
5.8.4 接口的優缺點 301
5.8.5 表驅動開發 303
5.9 灰度發布和A/B測試 303
5.9.1 通過分批次部署實現灰度發布 304
5.9.2 通過業務規則進行灰度發布 305
5.9.3 如何實現一套灰度發布系統 306
5.10 補充說明 310
第6章 分散式系統 311
6.1 分散式ID生成器 311
6.1.1 worker_id分配 312
6.1.2 開源實例 313
6.2 分散式鎖 316
6.2.1 進程內加鎖 317
6.2.2 嘗試鎖 317
6.2.3 基於Redis的setnx 319
6.2.4 基於ZooKeeper 321
6.2.5 基於etcd 321
6.2.6 如何選擇合適的鎖 322
6.3 延時任務系統 323
6.3.1 定時器的實現 323
6.3.2 任務分發 325
6.3.3 數據再平衡和冪等考量 326
6.4.1 搜尋引擎 328
6.4.2 異構數據同步 336
6.5 負載均衡 337
6.5.1 常見的負載均衡思路 337
6.5.2 基於洗牌算法的負載均衡 338
6.5.3 ZooKeeper集群的隨機節點挑選問題 340
6.5.4 負載均衡算法效果驗證 340
6.6 分散式配置管理 341
6.6.1 場景舉例 341
6.6.2 使用etcd實現配置更新 342
6.6.3 配置膨脹 345
6.6.4 配置版本管理 345
6.6.5 客戶端容錯 345
6.7 分散式爬蟲 346
6.7.1 基於colly的單機爬蟲 346
6.7.2 分散式爬蟲 347
6.7.3 結合nats和colly的訊息生產 350
6.7.4 結合colly的訊息消費 352
6.8 補充說明 353
附錄A 使用Go語言常遇到的問題 354
附錄B 有趣的代碼片段 363
1.6.3 發布/訂閱模型 53
1.6.4 控制並發數 56
1.6.5 贏者為王 57
1.6.6 素數篩 58
1.6.7 並發的安全退出 59
1.6.8 context包 62
1.7 錯誤和異常 64
1.7.1 錯誤處理策略 65
1.7.2 獲取錯誤的上下文 67
1.7.3 錯誤的錯誤返回 69
1.7.4 剖析異常 70
1.8 補充說明 73
第 2章 CGO編程 74
2.1 快速入門 74
2.1.1 最簡CGO程式 74
2.1.2 基於C標準庫函式輸出字元串 75
2.1.3 使用自己的C函式 75
2.1.4 C代碼的模組化 76
2.1.5 用Go重新實現C函式 77
2.1.6 面向C接口的Go編程 78
2.2 CGO基礎 79
2.2.1 import ""C""語句 79
2.2.2 #cgo語句 81
2.2.3 build標誌條件編譯 82
2.3 類型轉換 83
2.3.1 數值類型 83
2.3.2 Go字元串和切片 85
2.3.3 結構體、聯合和枚舉類型 86
2.3.4 數組、字元串和切片 89
2.3.5 指針間的轉換 91
2.3.6 數值和指針的轉換 92
2.3.7 切片間的轉換 93
2.4 函式調用 94
2.4.1 Go調用C函式 94
2.4.2 C函式的返回值 94
2.4.3 void函式的返回值 95
2.4.4 C調用Go導出函式 96
2.5 內部機制 97
2.5.1 CGO生成的中間檔案 97
2.5.2 Go調用C函式 98
2.5.3 C調用Go函式 101
2.6 實戰:封裝qsort 103
2.6.1 認識qsort()函式 103
2.6.2 將qsort()函式從Go包導出 104
2.6.3 改進:閉包函式作為比較函式 106
2.6.4 改進:消除用戶對unsafe包的依賴 108
2.7 CGO記憶體模型 110
2.7.1 Go訪問C記憶體 110
2.7.2 C臨時訪問傳入的Go記憶體 111
2.7.3 C長期持有Go指針對象 113
2.7.4 導出C函式不能返回Go記憶體 115
2.8 C++類包裝 117
2.8.1 C++類到Go語言對象 117
2.8.2 Go語言對象到C++類 121
2.8.3 徹底解放C++的this指針 125
2.9 靜態庫和動態庫 126
2.9.1 使用C靜態庫 126
2.9.2 使用C動態庫 128
2.9.3 導出C靜態庫 129
2.9.4 導出C動態庫 131
2.9.5 導出非main包的函式 131
2.10 編譯和連結參數 133
2.10.1 編譯參數:CFLAGS/CPPFLAGS/CXXFLAGS 133
2.10.2 連結參數:LDFLAGS 133
2.10.3 pkg-config 133
2.10.4 go get鏈 134
2.10.5 多個非main包中導出C函式 135
2.11 補充說明 135
第3章 Go彙編語言 136
3.1 快速入門 136
3.1.1 實現和聲明 136
3.1.2 定義整數變數 137
3.1.3 定義字元串變數 138
3.1.4 定義main()函式 141
3.1.5 特殊字元 141
3.1.6 沒有分號 142
3.2 計算機結構 142
3.2.1 圖靈機和BrainFuck語言 143
3.2.2 《人力資源機器》遊戲 144
3.2.3 X86-64體系結構 145
3.2.4 Go彙編中的偽暫存器 146
3.2.5 X86-64指令集 147
3.3 常量和全局變數 150
3.3.1 常量 150
3.3.2 全局變數 150
3.3.3 變數的記憶體布局 156
3.3.4 標識符規則和特殊標誌 157
3.3.5 小結 158
3.4 函式 158
3.4.1 基本語法 158
3.4.2 函式參數和返回值 160
3.4.3 參數和返回值的記憶體布局 161
3.4.4 函式中的局部變數 163
3.4.5 調用其他函式 165
3.4.6 宏函式 166
3.5 控制流 167
3.5.1 順序執行 167
3.5.2 if/goto跳轉 169
3.5.3 for循環 171
3.6 再論函式 172
3.6.1 函式調用規範 172
3.6.2 高級彙編語言 173
3.6.3 PCDATA和FUNCDATA 176
3.6.4 方法函式 177
3.6.5 遞歸函式: 1到n求和 178
3.6.6 閉包函式 180
3.7 彙編語言的威力 182
3.7.1 系統調用 182
3.7.2 直接調用C函式 184
3.7.3 AVX指令 185
3.8 例子:Goroutine ID 187
3.8.1 故意設計沒有goid 187
3.8.2 純Go方式獲取goid 187
3.8.3 從g結構體獲取goid 189
3.8.4 獲取g結構體對應的接口對象 190
3.8.5 goid的套用:局部存儲 192
3.9 Delve調試器 194
3.9.1 Delve入門 194
3.9.2 調試彙編程式 198
3.10 補充說明 201
第4章 RPC和Protobuf 203
4.1 RPC入門 203
4.1.1 RPC版“Hello, World” 203
4.1.2 更安全的RPC接口 205
4.1.3 跨語言的RPC 207
4.1.4 HTTP上的RPC 209
4.2 Protobuf 210
4.2.1 Protobuf入門 210
4.2.2 定製代碼生成外掛程式 212
4.2.3 自動生成完整的RPC代碼 215
4.3 玩轉RPC 218
4.3.1 客戶端RPC的實現原理 218
4.3.2 基於RPC實現監視功能 220
4.3.3 反向RPC 222
4.3.4 上下文信息 223
4.4 gRPC入門 224
4.4.1 gRPC技術棧 225
4.4.2 gRPC入門 225
4.4.3 gRPC流 227
4.4.4 發布和訂閱模式 229
4.5 gRPC進階 233
4.5.1 證書認證 233
4.5.2 Token認證 236
4.5.3 截取器 238
4.5.4 和Web服務共存 240
4.6 gRPC和Protobuf擴展 241
4.6.1 驗證器 241
4.6.2 REST接口 244
4.6.3 Nginx 246
4.7 pbgo:基於Protobuf的框架 246
4.7.1 Protobuf擴展語法 246
4.7.2 外掛程式中讀取擴展信息 248
4.7.3 生成REST代碼 249
4.7.4 啟動REST服務 250
4.8 grpcurl工具 251
4.8.1 啟動反射服務 251
4.8.2 查看服務列表 252
4.8.3 服務的方法列表 253
4.8.4 獲取類型信息 253
4.8.5 調用方法 254
4.9 補充說明 255
第5章 Go和Web 256
5.1 Web開發簡介 256
5.2 請求路由 260
5.2.1 httprouter 260
5.2.2 原理 262
5.2.3 壓縮檢索樹創建過程 263
5.3 中間件 267
5.3.1 代碼泥潭 267
5.3.2 使用中間件剝離非業務邏輯 269
5.3.3 更優雅的中間件寫法 272
5.3.4 哪些事情適合在中間件中做 273
5.4 請求校驗 274
5.4.1 重構請求校驗函式 275
5.4.2 用請求校驗器解放體力勞動 276
5.4.3 原理 277
5.5 Database 和資料庫打交道 279
5.5.1 從database/sql講起 279
5.5.2 提高生產效率的ORM和
SQL Builder 281
5.5.3 脆弱的資料庫 283
5.6 服務流量限制 285
5.6.1 常見的流量限制手段 287
5.6.2 原理 289
5.6.3 服務瓶頸和 QoS 291
5.7 常見大型Web項目分層 291
5.8 接口和表驅動開發 297
5.8.1 業務系統的發展過程 297
5.8.2 使用函式封裝業務流程 298
5.8.3 使用接口來做抽象 298
5.8.4 接口的優缺點 301
5.8.5 表驅動開發 303
5.9 灰度發布和A/B測試 303
5.9.1 通過分批次部署實現灰度發布 304
5.9.2 通過業務規則進行灰度發布 305
5.9.3 如何實現一套灰度發布系統 306
5.10 補充說明 310
第6章 分散式系統 311
6.1 分散式ID生成器 311
6.1.1 worker_id分配 312
6.1.2 開源實例 313
6.2 分散式鎖 316
6.2.1 進程內加鎖 317
6.2.2 嘗試鎖 317
6.2.3 基於Redis的setnx 319
6.2.4 基於ZooKeeper 321
6.2.5 基於etcd 321
6.2.6 如何選擇合適的鎖 322
6.3 延時任務系統 323
6.3.1 定時器的實現 323
6.3.2 任務分發 325
6.3.3 數據再平衡和冪等考量 326
6.4.1 搜尋引擎 328
6.4.2 異構數據同步 336
6.5 負載均衡 337
6.5.1 常見的負載均衡思路 337
6.5.2 基於洗牌算法的負載均衡 338
6.5.3 ZooKeeper集群的隨機節點挑選問題 340
6.5.4 負載均衡算法效果驗證 340
6.6 分散式配置管理 341
6.6.1 場景舉例 341
6.6.2 使用etcd實現配置更新 342
6.6.3 配置膨脹 345
6.6.4 配置版本管理 345
6.6.5 客戶端容錯 345
6.7 分散式爬蟲 346
6.7.1 基於colly的單機爬蟲 346
6.7.2 分散式爬蟲 347
6.7.3 結合nats和colly的訊息生產 350
6.7.4 結合colly的訊息消費 352
6.8 補充說明 353
附錄A 使用Go語言常遇到的問題 354
附錄B 有趣的代碼片段 363

相關詞條

熱門詞條

聯絡我們