作者简介
郑建勋,Golang contributor(Go语言垃圾回收模块代码贡献者)、Go语言精度库shopspring/decimal核心贡献者。滴滴研发。拥有丰富的分布式、高并发、大规模微服务集群的开发设计经验。
公众号“gopher梦工厂”作者,知名Go语言内容原创博主。现任51CTO学堂讲师、极客时间“每日一课”讲师等。有丰富的教育经验,能够想读者之所想。相信这部系统且深入浅出的作品,会是读者打怪升级的辅助资料。
目录
目录
第1章 深入Go语言编译器1
1.1 为什么要了解Go语言编译器1
1.2 Go语言编译器的阶段1
1.3 词法解析3
1.4 语法解析4
1.5 抽象语法树构建6
1.6 类型检查8
1.7 变量捕获8
1.8 函数内联9
1.9 逃逸分析12
1.10 闭包重写14
1.11 遍历函数15
1.12 SSA生成15
1.13 机器码生成――汇编器18
1.14 机器码生成――链接20
1.15 ELF文件解析23
1.16 总结26
第2章 浮点数设计原理与使用方法27
2.1 浮点数陷阱27
2.2 定点数与浮点数27
2.3 IEEE-754浮点数标准28
2.3.1 小数部分计算29
2.3.2 显示浮点数格式30
2.4 最佳实践:判断浮点数为整数31
2.5 常规数与非常规数33
2.6 NaN与Inf33
2.7 浮点数精度34
2.8 浮点数与格式化打印36
2.9 浮点数计算与精度损失37
2.10 多精度浮点数与math/big库38
2.11 总结41
第3章 类型推断全解析42
3.1 类型推断的优势42
3.2 Go语言中类型推断的特性43
3.3 类型推断原理44
3.3.1 词法解析与语法分析阶段44
3.3.2 抽象语法树生成与类型检查46
3.4 总结48
第4章 常量与隐式类型转换49
4.1 常量声明与生存周期49
4.2 常量类型转换50
4.2.1 隐式整数转换50
4.2.2 隐式浮点数转换51
4.2.3 常量运算中的隐式转换51
4.2.4 常量与变量之间的转换51
4.2.5 自定义类型的转换52
4.3 常量与隐式类型转换原理53
4.4 总结55
第5章 字符串本质与实现56
5.1 字符串的本质56
5.2 符文类型57
5.3 字符串工具函数58
5.4 字符串底层原理59
5.4.1 字符串解析59
5.4.2 字符串拼接61
5.4.3 运行时字符拼接62
5.4.4 字符串与字节数组的转换64
5.5 总结66
第6章 数组67
6.1 数组的声明方式67
6.2 数组值复制68
6.3 数组底层原理68
6.3.1 编译时数组解析68
6.3.2 数组字面量初始化原理69
6.3.3 数组字面量编译时内存优化70
6.3.4 数组索引与访问越界原理70
6.4 总结73
第7章 切片使用方法与底层原理74
7.1 切片使用方法74
7.1.1 切片的结构74
7.1.2 切片的初始化75
7.1.3 切片的截取75
7.1.4 切片值复制与数据引用76
7.1.5 切片收缩与扩容77
7.2 切片底层原理78
7.2.1 字面量初始化78
7.2.2 make初始化79
7.2.3 切片扩容原理80
7.2.4 切片截取原理82
7.2.5 切片的完整复制83
7.3 总结84
第8章 哈希表与Go实现机制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并发冲突89
8.3 哈希表底层结构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 总结104
第9章 函数与栈105
9.1 函数基本使用方式105
9.2 函数闭包与陷阱106
9.3 函数栈107
9.4 Go语言栈帧结构108
9.5 Go语言函数调用链结构与特性110
9.6 堆栈信息111
9.7 栈扩容与栈转移原理113
9.8 栈调试118
9.9 总结120
第10章 defer延迟调用121
10.1 使用的defer的优势122
10.1.1 资源释放122
10.1.2 异常捕获123
10.2 defer特性125
10.2.1 延迟执行125
10.2.2 参数预计算126
10.2.3 defer多次执行与LIFO执行顺序127
10.3 defer返回值陷阱127
10.4 defer底层原理129
10.4.1 defer演进129
10.4.2 堆分配130
10.4.3 defer遍历调用134
10.4.4 Go 1.13栈分配优化137
10.4.5 Go 1.14内联优化138
10.5 总结140
第11章 异常与异常捕获141
11.1 panic函数使用方法141
11.2 异常捕获与recover142
11.3 panic与recover嵌套144
11.4 panic函数底层原理145
11.5 recover底层原理149
11.6 总结152
第12章 接口与程序设计模式154
12.1 接口的用途154
12.2 Go语言中的接口155
12.3 Go接口实践156
12.4 Go接口的使用方法158
12.4.1 Go接口的声明与定义158
12.4.2 接口实现159
12.4.3 接口动态类型160
12.4.4 接口的动态调用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 接口实现算法166
12.5.2 接口组成168
12.5.3 接口内存逃逸分析171
12.5.4 接口动态调用过程173
12.5.5 接口动态调用过程的效率评价177
12.5.6 接口转换182
12.5.7 空接口组成184
12.5.8 空接口switch187
12.5.9 接口的陷阱189
12.6 总结191
第13章 反射高级编程192
13.1 为什么需要反射193
13.2 反射的基本使用方法195
13.2.1 反射的两种基本类型195
13.2.2 反射转换为接口196
13.2.3 Elem()间接访问197
13.2.4 修改反射的值199
13.2.5 结构体与反射200
13.2.6 遍历结构体字段200
13.2.7 修改结构体字段201
13.2.8 嵌套结构体的赋值202
13.2.9 结构体方法与动态调用203
13.2.10 反射在运行时创建结构体205
13.2.11 函数与反射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 动态调用剖析213
13.4 总结216
第14章 协程初探217
14.1 进程与线程217
14.2 线程上下文切换219
14.3 线程与协程220
14.3.1 调度方式220
14.3.2 上下文切换的速度220
14.3.3 调度策略221
14.3.4 栈的大小221
14.4 并发与并行221
14.5 简单协程入门222
14.6 main协程与子协程223
14.7 GMP模型225
14.8 总结226
第15章 深入协程设计与调度原理227
15.1 协程的生命周期与状态转移227
15.2 特殊协程g0与协程切换228
15.3 线程本地存储与线程绑定230
15.4 调度循环231
15.5 调度策略232
15.5.1 获取本地运行队列234
15.5.2 获取全局运行队列235
15.5.3 获取准备就绪的网络协程236
15.5.4 协程窃取237
15.6 调度时机238
15.6.1 主动调度238
15.6.2 被动调度239
15.6.3 抢占调度241
15.6.4 执行时间过长的抢占调度241
15.7 总结247
第16章 通道与协程间通信248
16.1 CSP并发编程248
16.2 通道基本使用方式249
16.2.1 通道声明与初始化249
16.2.2 channel写入数据250
16.2.3 通道读取数据250
16.2.4 通道关闭250
16.2.5 通道作为参数和返回值252
16.2.6 单方向通道253
16.2.7 通道最佳实践254
16.3 select多路复用258
16.3.1 select随机选择机制258
16.3.2 select堵塞与控制259
16.3.3 循环select260
16.3.4 select 与nil261
16.4 通道底层原理261
16.4.1 通道结构与环形队列261
16.4.2 通道初始化263
16.4.3 通道写入原理263
16.4.4 通道读取原理265
16.5 select底层原理267
16.5.1 select一轮循环269
16.5.2 select二轮循环270
16.6 总结271
第17章 并发控制272
17.1 context272
17.1.1 为什么需要Context272
17.1.2 Context使用方式274
17.2 context原理277
17.3 数据争用检查280
17.3.1 什么是数据争用280
17.3.2 数据争用检查详解282
17.3.3 race工具原理282
17.4 锁286
17.4.1 原子锁287
17.4.2 互斥锁289
17.4.3 互斥锁实现原理290
17.4.4 互斥锁的释放294
17.4.5 读写锁295
17.4.6 读写锁原理296
17.5 总结298
第18章 内存分配管理299
18.1 Go语言内存分配全局视野299
18.1.1 span与元素299
18.1.2 三级对象管理300
18.1.3 四级内存块管理301
18.2 对象分配302
18.2.1 微小对象302
18.2.2 mcache缓存位图304
18.2.3 mcentral遍历span305
18.2.4 mheap缓存查找307
18.2.5 mheap基数树查找307
18.2.6 操作系统内存申请311
18.2.7 小对象分配311
18.2.8 大对象分配312
18.3 总结312
第19章 垃圾回收初探313
19.1 为什么需要垃圾回收314
19.1.1 减少错误和复杂性314
19.1.2 解耦314
19.2 垃圾回收的5种经典算法315
19.2.1 标记-清扫315
19.2.2 标记-压缩316
19.2.3 半空间复制316
19.2.4 引用计数317
19.2.5 分代GC318
19.3 Go语言中的垃圾回收318
19.3.1 为什么不选择压缩GC?319
19.3.2 为什么不选择分代GC?319
19.4 Go垃圾回收演进319
19.5 总结321
第20章 深入垃圾回收全流程322
20.1 垃圾回收循环322
20.2 标记准备阶段323
20.2.1 计算标记协程的数量323
20.2.2 切换到后台标记协程325
20.3 并发标记阶段325
20.3.1 根对象扫描327
20.3.2 全局变量扫描328
20.3.3 finalizer330
20.3.4 栈扫描331
20.3.5 栈对象332
20.3.6 扫描灰色对象333
20.4 标记终止阶段336
20.5 辅助标记339
20.6 屏障技术341
20.7 垃圾清扫347
20.7.1 懒清扫逻辑348
20.7.2 辅助清扫349
20.8 系统驻留内存清除350
20.9 实战:垃圾回收产生的性能问题352
20.10 总结354
第21章 调试利器:特征分析与事件追踪355
21.1 pprof的使用方式355
21.1.1 堆内存特征分析357
21.1.2 pprof可视化结果说明360
21.1.3 pprof协程栈分析361
21.1.4 base基准分析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 堆内存样本370
21.4.2 协程栈样本收集原理372
21.4.3 CPU样本收集原理372
21.4.4 pprof分析原理375
21.5 trace底层原理377
21.6 总结379
内容摘要
Go语言是一门年轻、简捷,但是强大、高效、充满潜力的服务器语言。本书使用浅显易懂的语言与大量图片深入介绍了Go语言编译时、类型系统、语法特性、函数调用规范、并发编程、内存管理与垃圾回收、运行状态监控等模块的使用方法和底层原理,并举例说明了构建大型软件工程需要遵循的设计规则,让作者系统并完整掌握Go语言隐藏在使用方法背后的底层细节。 本书适合有一定工作经验的开发工程师进一步提升自己,以便更好地开发软件、系统架构,并进行工作面试。也可以作为高等院校计算机专业师生学习编程语言设计原理的参考教材。
主编推荐
"深入浅出,层层递进,讲解Go语言背后的逻辑
对源码进行逐行解析,系统说明底层原理
上百张精美的说明图,让理论学习不再枯燥晦涩
大量特性实现方法与防坑秘籍,构建优雅高效的工业级代码
深度剖析调试与可视化方法,全面提升对复杂程序的掌控力"
媒体评论
"这是一本Go语言的初学者和进阶学者都可以受益的书。它不仅仅介绍了Go的语言特性,还深入这些特性背后的设计考量、编译器及语言实现的细节。授人以鱼和授人以渔在本书里面一起得到了体现。更难得的是,本书并没有粘贴大段的代码,而是以图文的形式将复杂的概念解释清楚,降低了阅读和理解的难度,使得读者不会望“底层”和“深入”二词而却步。
——Shopee技术委员会主席、顺丰速运前CTO、Google前主任工程师 叶绍志博士"
以下为对购买帮助不大的评价