(1)本书内容丰富,技术含量高,深入浅出,竞争力强。本书的目标是让先教读者学会编写Go程序,然后帮助他们掌握Go语言的精髓,最后了解Go语言背后的设计,从而提高开发者解决复杂底层问题的能力。
(2)本书结构清晰全面。本书以普通应用开发者会涉及的知识点为纲要,深入剖析了这些知识点的底层机制,全面而透彻。
(3)内容由浅入深,便于理解。顺序阅读,会起到很好效果。当然,也可用于查询式阅读。
(4)作者资历深厚,拥有十多年的开发经验,拥有丰富的开发经验。
网站首页 软件下载 游戏下载 翻译软件 电子书下载 电影下载 电视剧下载 教程攻略
书名 | 深入浅出GO语言编程从原理解析到实战进阶 |
分类 | 教育考试-考试-计算机类 |
作者 | 阮正平 |
出版社 | 人民邮电出版社 |
下载 | |
简介 | 编辑推荐 (1)本书内容丰富,技术含量高,深入浅出,竞争力强。本书的目标是让先教读者学会编写Go程序,然后帮助他们掌握Go语言的精髓,最后了解Go语言背后的设计,从而提高开发者解决复杂底层问题的能力。 (2)本书结构清晰全面。本书以普通应用开发者会涉及的知识点为纲要,深入剖析了这些知识点的底层机制,全面而透彻。 (3)内容由浅入深,便于理解。顺序阅读,会起到很好效果。当然,也可用于查询式阅读。 (4)作者资历深厚,拥有十多年的开发经验,拥有丰富的开发经验。 内容推荐 本书是一部从核心概念、设计原理、应用场景、操作方法和实战技巧等维度全面、深入探讨 Go 语言的著 作。书中首先介绍 Go 语言的基本概念,并通过“hello world”程序引导读者熟悉 Go 的工具链。接下来逐步深 入,介绍面向包的设计、测试框架、错误与异常处理等内容。第 8 章开始探讨指针和内存逃逸分析,这对于理 解 Go 语言的内存模型至关重要。随后的章节涉及数据结构、面向对象和接口编程等核心知识。从第 15 章开始, 重点转向并发编程,从基本的并发模式到复杂的并发原理,再到内存管理和垃圾回收等高级主题。最后几 章关注实际开发中的问题,如使用标准库和第三方库、性能问题分析与追踪,以及重构“hello world”示 例代码。 本书适合想要掌握 Go 语言的基本使用方法,以及了解其底层工作原理和设计实现的初、中级读者阅读。 目录 第 1 章 Go 语言初探 1 1.1 Go 语言的发展里程碑 1 1.2 云时代 Go 语言的发展趋势 2 1.3 Go 语言优秀的语言特性 3 1.3.1 “少即是多”的设计哲学 3 1.3.2 强大的 runtime 4 1.3.3 面向接口编程 5 1.3.4 为工程服务的语言 6 1.3.5 自带标准化的测试框架 7 1.3.6 丰富的标准库和第三方库 7 1.4 强大的生态圈和成功案例 8 1.5 Go 程序是如何运行的 8 1.6 plan9 与 Go 语言 10 1.6.1 寄存器 10 1.6.2 Go 语言的反汇编方法 11 1.6.3 反汇编的查看示例 13 第 2 章 “hello world”与工具链 15 2.1 Go 语言的安装和配置 15 2.1.1 下载和安装 15 2.1.2 配置 Go 语言的环境变量 15 2.1.3 查看配置信息 16 2.2 第 一个程序“hello world” 16 2.2.1 “hello world”程序的代码说明 17 2.2.2 代码的编译与运行 21 2.2.3 “hello world”示例总结 21 2.3 Go 语言的工具链命令 22 2.3.1 与编译执行有关的工具链命令 22 2.3.2 获取与安装第三方包 22 2.3.3 工具包组合命令 go tool 23 2.3.4 跨平台交叉编译 23 2.3.5 网络代理 GOPROXY 24 第 3 章 Go 语言的基础知识 26 3.1 Go 语言的常用规范 26 3.1.1 命名与注释 26 3.1.2 声明 27 3.1.3 对变量赋值 28 3.1.4 包和文件 28 3.2 数据类型 29 3.2.1 基本类型 29 3.2.2 非引用类型和引用类型 31 3.2.3 用户自定义类型 32 3.2.4 类型别名 32 3.2.5 传参方式 33 3.3 变量的本质 33 3.3.1 类型的两个要素 33 3.3.2 变量的声明 34 3.3.3 零值机制 35 3.3.4 短变量声明与类型转换 35 3.4 常量 36 3.4.1 常量 iota 37 3.4.2 常量的类型提升机制 38 3.5 运算符 38 3.5.1 算术运算符 39 3.5.2 比较运算符 39 3.5.3 逻辑运算符 39 3.5.4 位运算符 40 3.5.5 赋值运算符 40 3.5.6 指针运算符 41 3.6 结构化语法 41 3.6.1 循环结构 41 3.6.2 条件语句 42 3.6.3 switch-case 语句 42 3.6.4 控制或跳出循环语句的关键字 43 3.7 类型转换 43 3.7.1 转换的语法 44 3.7.2 类型断言 44 3.8 Go 语言的语法糖 44 3.8.1 短变量声明和new 函数 44 3.8.2 符号“”与切片 44 3.8.3 for range 45 第 4 章 面向包的设计与依赖管理 46 4.1 包的使用 46 4.1.1 包的概述 46 4.1.2 包的查找方式 47 4.1.3 包加载的顺序 48 4.1.4 包中 init 函数的加载 49 4.1.5 包加载顺序的示例 49 4.1.6 包的使用总结 50 4.2 面向包的设计 50 4.3 包管理工具 Go Module 51 4.3.1 包管理的方式 51 4.3.2 Go Module 简介 52 4.3.3 开启 Go Module 52 4.3.4 Go Module 的优点 52 4.3.5 使用 Go Module 53 4.3.6 go.mod 文件中的命令 57 4.3.7 升级依赖包的方法 58 4.3.8 依赖包版本的选择 58 4.3.9 语义版本的导入路径语法 58 4.3.10 Go Module 的使用总结 59 第 5 章 测试框架 60 5.1 Go 语言中的测试框架 60 5.1.1 测试使用的约定 60 5.1.2 标准库 testing 的辅助功能函数 61 5.1.3 测试框架示例 61 5.1.4 使用测试命令 62 5.2 单元测试 63 5.2.1 指定测试用例 63 5.2.2 单元测试之子测试 64 5.2.3 帮助函数 64 5.3 测试代码的覆盖率 65 5.4 断言 66 5.5 基准测试 67 5.5.1 基准测试场景 67 5.5.2 基准测试的方法 67 5.5.3 基准测试之子测试 68 5.5.4 基准测试示例 68 5.6 与网络有关的模拟测试 70 5.7 与测试有关的第三方工具 71 5.7.1 gomock 71 5.7.2 BDD 71 第 6 章 错误与异常处理 73 6.1 error 的引入 73 6.1.1 预定义的错误类型 74 6.1.2 快速创建错误类型 74 6.1.3 自定义错误 75 6.1.4 接口在错误处理上的妙用 76 6.1.5 自定义错误的陷阱 77 6.1.6 获取和处理错误 78 6.1.7 Go 语言作者关于错误处理的观点 78 6.2 异常处理 79 6.2.1 panic 的使用 79 6.2.2 defer 函数的设计与使用陷阱 79 6.2.3 recover 函数的使用 81 6.3 面向错误和恢复的设计 82 6.4 带堆栈信息的 error 83 6.5 标准库 errors 的改进 84 6.6 errGroup 对象 86 6.7 日志系统的引入 87 6.7.1 日志概述 88 6.7.2 第三方日志框架 88 第 7 章 编码与字符串 89 7.1 字符编码 89 7.1.1 字符的编码方式 89 7.1.2 使用字符类型的注意事项 90 7.2 字符串 90 7.2.1 字符串的声明和初始化 90 7.2.2 字符串的数据结构 90 7.2.3 遍历字符串 91 7.2.4 字符串的长度问题 92 7.2.5 字符串的备份 92 7.2.6 字符串拼接 92 7.3 字符串与基本类型互转 94 第 8 章 指针与内存逃逸分析 96 8.1 活动帧的作用 96 8.2 值语义的本质 98 8.3 指针 99 8.3.1 指针的由来 99 8.3.2 指针和指针类型 100 8.3.3 使用指针运算符的注意事项 101 8.3.4 nil 指针 101 8.3.5 指针数组与数组指针 102 8.3.6 关于指针的补充说明 102 8.4 内存逃逸分析 103 8.4.1 内存逃逸分析的由来 103 8.4.2 内存逃逸分析的作用 103 8.4.3 两种情况会引起内存逃逸分析 103 8.4.4 内存逃逸分析示例 104 8.4.5 函数内联 106 8.4.6 手动控制内存逃逸分析 107 8.5 引用类型与深、浅拷贝 108 第 9 章 数据结构 109 9.1 面向数据的设计 109 9.1.1 编码和硬件 109 9.1.2 可预测的内存访问模式 111 9.2 数组 111 9.2.1 数组的声明及初始化 112 9.2.2 数组在内存中的形式 112 9.2.3 遍历数组 113 9.2.4 数组的截取 113 9.2.5 数组的反转 114 9.3 切片 114 9.3.1 切片的设计 114 9.3.2 切片的创建与初始化 116 9.3.3 切片的长度与容量 117 9.3.4 nil 切片和空切片 117 9.3.5 切片的共享底层数组 118 9.3.6 append 函数与切片的扩容 119 9.3.7 append 函数引发的内存泄漏 121 9.3.8 三下标切片 122 9.3.9 切片的复制 122 9.3.10 切片的比较 122 9.3.11 删除切片中的元素 123 9.3.12 特殊的切片:字符串 125 9.3.13 数组与切片的对比 125 9.4 映射 125 9.4.1 选择合适的键值类型 126 9.4.2 映射的声明和初始化 127 9.4.3 映射的使用 128 9.4.4 映射的排序 129 9.4.5 映射的扩容 130 9.4.6 映射的并发安全性 130 9.4.7 映射的删除机制 132 9.4.8 映射的设计 133 9.5 数据结构中的常见问题 138 9.5.1 make 与 new 的差异 138 9.5.2 使用引用类型前先分配空间 139 9.5.3 可能发生内存泄漏的情况 139 第 10 章 结构体与内存对齐 140 10.1 结构体 140 10.1.1 结构体的定义 140 10.1.2 结构体的初始化 142 10.1.3 结构体的类型转换 143 10.1.4 结构体比较 143 10.1.5 结构体的值 144 10.2 序列化与反序列化 145 10.2.1 序列化 145 10.2.2 反序列化 145 10.2.3 使用 tag 146 10.3 unsafe 包 147 10.3.1 unsafe.Pointer 类型 147 10.3.2 unsafe 包简介 147 10.3.3 unsafe 包中的函数 148 10.3.4 unsafe 包的使用方式 150 10.4 内存对齐 152 10.4.1 内存对齐的概念 152 10.4.2 数据类型的尺寸 153 10.4.3 内存自动对齐 153 10.4.4 内存对齐的示例 154 第 11 章 函数 155 11.1 认识函数 155 11.1.1 函数的定义 155 11.1.2 函数的种类 156 11.2 defer 函数 158 11.2.1 defer 函数的使用场景 158 11.2.2 当 panic 遇到defer 函数 159 11.2.3 defer 函数与for 循环语句 160 11.3 作为数据类型的函数 161 11.4 函数类型的使用场景 161 11.4.1 匿名函数 161 11.4.2 回调函数 162 11.4.3 闭包 163 11.5 函数的别名 165 第 12 章 面向“对象”编程 166 12.1 封装 166 12.1.1 方法 166 12.1.2 方法的声明方式 167 12.1.3 接收者类型与接收者基础类型 167 12.1.4 接收者使用的语义 168 12.1.5 两种语义本质上的区别 169 12.1.6 解耦带来的问题 170 12.1.7 更为复杂的调用方式 170 12.1.8 隐式转换 171 12.1.9 关于封装的总结 173 12.2 继承 173 12.2.1 Go 语言不支持继承 173 12.2.2 用“内嵌+组合”替代继承 174 12.2.3 扩展已有的包 175 12.3 多态 176 12.3.1 接口的定义 176 12.3.2 鸭子类型 176 12.3.3 接口与协议 178 12.3.4 接口如何实现多态 178 第 13 章 面向接口编程 180 13.1 接口编程哲学 180 13.2 接口与组合 181 13.2.1 接口的设计准则 181 13.2.2 接口与组合示例 182 13.2.3 组合的多样化 183 13.3 接口的剖析 183 13.3.1 与接口相关的说明 183 13.3.2 空接口与包裹 184 13.3.3 实现接口类型 185 13.3.4 接口包裹非接口值 185 13.3.5 接口与多态 185 13.3.6 接口类型断言 186 13.3.7 强制转换接口类型 187 13.3.8 接口类型与隐式声明 187 13.3.9 类型转换的时间复杂度 188 13.4 接口的设计原则 188 13.4.1 错误的接口设计 189 13.4.2 基于数据驱动的接口设计 189 13.4.3 类型断言在 API 设计中的应用 189 13.4.4 接口设计的建议 190 13.5 检查接口的实现 190 13.6 空接口与类型断言 193 13.7 接口值的比较 194 13.8 检查运行阶段的接口类型 195 第 14 章 反射 196 14.1 反射的概念 196 14.2 接口与反射 198 14.2.1 静态类型与动态类型 198 14.2.2 空接口 199 14.2.3 类型的底层分析 199 14.3 反射包介绍 201 14.3.1 理解反射对象的转换机制 201 14.3.2 reflect.Type 接口的转换方式 202 14.3.3 reflect.Value 结构体类型的使用方法 204 14.4 反射包的使用示例 207 14.4.1 获取变量的类型和值 208 14.4.2 获取结构体的属性和方法 209 14.4.3 动态调用方法和传值 209 14.4.4 修改接口值 210 14.4.5 判断结构体实现了哪个接口 211 14.5 反射的三个定律 212 14.6 反射的应用场景 212 14.7 反射的性能 213 第 15 章 并发编程 214 15.1 感受并发的魅力 214 15.1.1 并发和并行 214 15.1.2 并发带来的好处 215 15.1.3 “hello goroutine” 215 15.1.4 协程的执行顺序 216 15.1.5 控制协程的几种方式 216 15.2 sync.WaitGroup 217 15.2.1 sync.WaitGroup 的三个方法 217 15.2.2 使用 sync.WaitGroup 的模板 217 15.2.3 使用 sync.WaitGroup 时的注意事项 218 15.2.4 为 sync.WaitGroup 增加额外的功能 218 15.3 数据竞争问题 219 15.3.1 临界区 219 15.3.2 数据竞争的检测方法 219 15.3.3 解决临界区的数据安全问题 220 15.4 传统的锁 221 15.4.1 锁的概念 221 15.4.2 互斥锁 Mutex 222 15.4.3 Mutex 的工作模式 224 15.4.4 读写锁 RWMutex 224 15.4.5 重入与 TryLock 226 15.5 原子操作介绍 227 15.5.1 Go 语言中的原子操作 228 15.5.2 atomic 包的使用 228 第 16 章 并发与通道 230 16.1 通道的行为 230 16.2 创建通道 231 16.3 通道的特性 231 16.3.1 通道的成对性 231 16.3.2 通道的阻塞性 232 16.3.3 通道与死锁 232 16.3.4 让出当前协程的执行权 233 16.3.5 关闭通道 234 16.3.6 遍历通道 236 16.4 通道的其他特性 237 16.4.1 带缓冲的通道 237 16.4.2 缓冲区与延迟保障 238 16.4.3 通道的方向 239 16.4.4 通道的状态 239 16.5 通道的使用建议 239 16.6 select 机制 240 16.6.1 select 机制的介绍与示例 241 16.6.2 select 与超时控制 242 16.7 通道的模式 243 16.7.1 等待任务模式 243 16.7.2 等待结果模式 244 16.7.3 等待完成模式 246 16.7.4 Pooling 模式 247 16.7.5 流水线模式 248 16.7.6 FanOut/FanIn 模式 249 16.7.7 Drop 模式 251 第 17 章 其他并发技术 252 17.1 context 包 252 17.1.1 context 包的使用场景 253 17.1.2 context 包中的接口和函数 253 17.1.3 context 包的使用流程 254 17.1.4 context.Context 接口 255 17.1.5 生成 Context 的方法 255 17.1.6 Context 与请求超时 258 17.1.7 Context 的使用总结 260 17.2 sync.Cond 261 17.3 sync.Once 262 17.4 sync.Map 263 17.5 sync.Pool 265 17.5.1 sync.Pool 的介绍 265 17.5.2 缓存对象的生命周期 266 17.5.3 sync.Pool 的使用场景及存在的问题 267 17.6 实现对象池 268 17.7 常用连接池 269 17.8 并发技术选型 270 第 18 章 并发原理 271 18.1 怎样让程序跑得更快 271 18.1.1 从单进程到多线程 271 18.1.2 工作任务的种类 272 18.2 Go 语言中的协程 273 18.2.1 内核态线程与用户态线程 273 18.2.2 轻量级的协程 274 18.2.3 改造后的 Go 语言协程 275 18.2.4 简说 Go 语言协程的调度 275 18.2.5 协作式与抢占式调度器 277 18.2.6 协程与 I/O 多路复用 277 18.3 GPM 调度流程 278 18.3.1 GPM 调度模型 278 18.3.2 G 的调度 280 18.3.3 P 的调度 282 18.3.4 M 的调度 285 18.3.5 探索调度器的调度流程 286 18.3.6 循环调度 290 18.3.7 任务执行函数 execute 294 18.4 监控线程 sysmon 297 18.5 main 函数与协程的执行顺序 299 18.6 可视化分析 GPM 调度 300 18.6.1 使用 trace 分析GPM 调度 300 18.6.2 使用 GODEBUG调试 GPM 调度 302 18.7 深入探索通道 303 18.7.1 通道的底层数据结构hchan 303 18.7.2 发生阻塞的条件 304 18.7.3 select 多路复用的底层逻辑 305 第 19 章 内存管理 307 19.1 runtime 307 19.2 内存分配模型 307 19.2.1 内存模型 308 19.2.2 内存分配过程 308 19.2.3 span 与预设的内存大小和规格 309 19.3 内存管理单元 310 19.3.1 mspan 311 19.3.2 mheap 312 19.3.3 heapArena 313 19.3.4 mcentral 313 19.3.5 mcache 315 19.3.6 内存的多级分配管理 316 19.4 对象分类及分配策略 317 19.4.1 微小对象 317 19.4.2 小对象和大对象 318 19.5 堆内存分配总结 318 第 20 章 垃圾回收 319 20.1 垃圾回收算法 320 20.2 Go 语言的垃圾回收算法 321 20.2.1 标记清扫算法 322 20.2.2 三色标记法 323 20.2.3 三色标记与并发问题 325 20.2.4 三色不变式与屏障技术 326 20.2.5 插入写屏障 327 20.2.6 删除写屏障 330 20.2.7 混合写屏障 333 20.2.8 并发增量式垃圾回收 334 20.3 触发垃圾回收的时机 334 20.4 查看运行时的垃圾回收信息 335 20.5 垃圾回收优化示例 337 20.5.1 传递复杂对象时建议使用指针 337 20.5.2 自动扩容的代价 339 第 21 章 使用标准库和第三方库 341 21.1 I/O 操作 342 21.1.1 io 包 342 21.1.2 os 包 343 21.1.3 bufio 包 344 21.1.4 bytes 包 345 21.1.5 ioutil 包与替换方案 346 21.1.6 读取文件的示例 346 21.1.7 大文件读取方案 348 21.1.8 文件的复制 350 21.1.9 断点续传 351 21.2 网络操作 352 21.2.1 Socket 编程 352 21.2.2 net/http 包 355 21.2.3 与网络编程相关的其他包 359 21.3 与时间有关的标准库 359 21.3.1 时间函数 360 21.3.2 时间戳 360 21.3.3 时间的格式化与解析 361 21.4 随机数 362 21.5 正则表达式 362 21.6 flag 包的使用 363 21.6.1 简单标记的声明方式 363 21.6.2 其他使用方式 364 21.7 os 包的使用 365 21.8 crypto 包 367 21.9 base64 编码 367 21.10 fmt 包 368 21.11 使用第三方库 369 第 22 章 性能问题分析与追踪 370 22.1 性能优化概述 370 22.2 性能优化的步骤 371 22.3 硬件与软件的性能指标 373 22.4 优化工具概述 374 22.4.1 runtime.MemStats 374 22.4.2 Benchmark 374 22.4.3 go tool pprof 工具 375 22.4.4 runtime/pprof 包 375 22.4.5 net/http/pprof 包 376 22.4.6 go tool trace 工具 377 22.4.7 fgprof 包 377 22.4.8 coredump 377 22.4.9 gcflags 379 22.4.10 GODEBUG 379 22.4.11 使用场景总结 380 22.5 性能优化总结 380 22.6 使用 go tool pprof 工具进行性能分析的示例 380 22.7 pprof 包结合 HTTP 服务使用的示例 387 22.8 pprof 包和 fgprof 包的使用对比 390 22.9 go tool trace 工具的使用示例 391 22.10 持续性能分析 392 22.11 性能问题的定位及处理建议 393 22.11.1 CPU 占用率高的定位及处理建议 393 22.11.2 内存使用率高的定位及处理建议 394 22.11.3 I/O 高的定位及处理建议 395 22.11.4 阻塞问题的定位及处理建议 395 22.11.5 协程泄露的定位及处理建议 396 第 23 章 重构“hello world” 397 23.1 搭建业务处理框架 397 23.2 设计解耦的读写接口 398 23.2.1 用结构体代替读写方法 398 23.2.2 使用组合接口 399 23.3 业务实现 401 23.3.1 读日志数据 401 23.3.2 Nginx 日志数据的说明及处理 402 23.3.3 处理日志数据的关键代码 403 23.3.4 实现数据归档 404 23.4 构建 HTTP 服务发布数据 405 23.4.1 埋点处理 405 23.4.2 构建 HTTP 服务发布数据的步骤 406 23.5 整合 Prometheus 发布数据 408 23.5.1 引用第三方prometheus 包 408 23.5.2 实现自定义的exporter 409 23.6 代码细节的提升 412 23.7 总结 412 |
随便看 |
|
霍普软件下载网电子书栏目提供海量电子书在线免费阅读及下载。