当前位置:首页 > 程序设计 > Go语言pdf电子书下载
《Go语言高级编程》电子书封面

Go语言高级编程

  • 发布时间:2021年03月15日 09:06:27
  • 作者:柴树杉 曹春晖
  • 大小:23.36MB
  • 类别:Go语言电子书
  • 格式:PDF
  • 版本:超清版
  • 评分:7.3

    Go语言高级编程 PDF 超清版

      给大家带来的一篇关于Go语言相关的电子书资源,介绍了关于Go语言、Go语言编程方面的内容,我们还提供了样章在线阅读,本书是由人民邮电出版社出版,格式为PDF,资源大小23.36MB,柴树杉 曹春晖编写,目前豆瓣、亚马逊、当当、京东等电子书综合评分为:9.5分

      Tags:go语言 Go语言编程 

      内容介绍

      Go语言高级编程

      作者: 柴树杉,曹春晖 著

      出版时间: 2019

      本书从实践出发讲解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.1Go语言创世纪1
      • 1.1.1来自贝尔实验室特有基因3
      • 1.1.2你好,世界4
      • 1.2“Hello, World”的革命5
      • 1.2.1B语言——Ken Thompson, 19695
      • 1.2.2C语言——Dennis Ritchie,1972—19895
      • 1.2.3Newsqueak——Rob Pike, 19897
      • 1.2.4Alef——Phil Winterbottom, 19939
      • 1.2.5Limbo——Sean Dorward, Phil Winterbottom, Rob Pike, 199510
      • 1.2.6Go语言——2007—200911
      • 1.2.7你好,世界!——V2.013
      • 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.1Goroutine和系统线程40
      • 1.5.2原子操作40
      • 1.5.3顺序一致性内存模型44
      • 1.5.4初始化顺序45
      • 1.5.5Goroutine的创建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.8context包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.4C代码的模块化76
      • 2.1.5用Go重新实现C函数77
      • 2.1.6面向C接口的Go编程78
      • 2.2CGO基础79
      • 2.2.1import C语句79
      • 2.2.2#cgo语句81
      • 2.2.3build标志条件编译82
      • 2.3类型转换83
      • 2.3.1数值类型83
      • 2.3.2Go字符串和切片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.1Go调用C函数94
      • 2.4.2C函数的返回值94
      • 2.4.3void函数的返回值95
      • 2.4.4C调用Go导出函数96
      • 2.5内部机制97
      • 2.5.1CGO生成的中间文件97
      • 2.5.2Go调用C函数98
      • 2.5.3C调用Go函数101
      • 2.6实战:封装qsort103
      • 2.6.1认识qsort()函数103
      • 2.6.2将qsort()函数从Go包导出104
      • 2.6.3改进:闭包函数作为比较函数106
      • 2.6.4改进:消除用户对unsafe包的依赖108
      • 2.7CGO内存模型110
      • 2.7.1Go访问C内存110
      • 2.7.2C临时访问传入的Go内存111
      • 2.7.3C长期持有Go指针对象113
      • 2.7.4导出C函数不能返回Go内存115
      • 2.8C++类包装117
      • 2.8.1C++类到Go语言对象117
      • 2.8.2Go语言对象到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/CXXFLAGS133
      • 2.10.2链接参数:LDFLAGS133
      • 2.10.3pkg-config133
      • 2.10.4go 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.3X86-64体系结构145
      • 3.2.4Go汇编中的伪寄存器146
      • 3.2.5X86-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.2if/goto跳转169
      • 3.5.3for循环171
      • 3.6再论函数172
      • 3.6.1函数调用规范172
      • 3.6.2高级汇编语言173
      • 3.6.3PCDATA和FUNCDATA176
      • 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.3AVX指令185
      • 3.8例子:Goroutine ID187
      • 3.8.1故意设计没有goid187
      • 3.8.2纯Go方式获取goid187
      • 3.8.3从g结构体获取goid189
      • 3.8.4获取g结构体对应的接口对象190
      • 3.8.5goid的应用:局部存储192
      • 3.9Delve调试器194
      • 3.9.1Delve入门194
      • 3.9.2调试汇编程序198
      • 3.10补充说明201
      • 第4章RPC和Protobuf203
      • 4.1RPC入门203
      • 4.1.1RPC版“Hello, World”203
      • 4.1.2更安全的RPC接口205
      • 4.1.3跨语言的RPC207
      • 4.1.4HTTP上的RPC209
      • 4.2Protobuf210
      • 4.2.1Protobuf入门210
      • 4.2.2定制代码生成插件212
      • 4.2.3自动生成完整的RPC代码215
      • 4.3玩转RPC218
      • 4.3.1客户端RPC的实现原理218
      • 4.3.2基于RPC实现监视功能220
      • 4.3.3反向RPC222
      • 4.3.4上下文信息223
      • 4.4gRPC入门224
      • 4.4.1gRPC技术栈225
      • 4.4.2gRPC入门225
      • 4.4.3gRPC流227
      • 4.4.4发布和订阅模式229
      • 4.5gRPC进阶233
      • 4.5.1证书认证233
      • 4.5.2Token认证236
      • 4.5.3截取器238
      • 4.5.4和Web服务共存240
      • 4.6gRPC和Protobuf扩展241
      • 4.6.1验证器241
      • 4.6.2REST接口244
      • 4.6.3Nginx246
      • 4.7pbgo:基于Protobuf的框架246
      • 4.7.1Protobuf扩展语法246
      • 4.7.2插件中读取扩展信息248
      • 4.7.3生成REST代码249
      • 4.7.4启动REST服务250
      • 4.8grpcurl工具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和Web256
      • 5.1Web开发简介256
      • 5.2请求路由260
      • 5.2.1httprouter260
      • 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.5Database 和数据库打交道279
      • 5.5.1从database/sql讲起279
      • 5.5.2提高生产效率的ORM和
      • SQLBuilder281
      • 5.5.3脆弱的数据库283
      • 5.6服务流量限制285
      • 5.6.1常见的流量限制手段287
      • 5.6.2原理289
      • 5.6.3服务瓶颈和 QoS291
      • 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.1worker_id分配312
      • 6.1.2开源实例313
      • 6.2分布式锁316
      • 6.2.1进程内加锁317
      • 6.2.2尝试锁317
      • 6.2.3基于Redis的setnx319
      • 6.2.4基于ZooKeeper321
      • 6.2.5基于etcd321
      • 6.2.6如何选择合适的锁322
      • 6.3延时任务系统323
      • 6.3.1定时器的实现323
      • 6.3.2任务分发325
      • 6.3.3数据再平衡和幂等考量326
      • 6.4分布式搜索引擎327
      • 6.4.1搜索引擎328
      • 6.4.2异构数据同步336
      • 6.5负载均衡337
      • 6.5.1常见的负载均衡思路337
      • 6.5.2基于洗牌算法的负载均衡338
      • 6.5.3ZooKeeper集群的随机节点挑选问题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
         

      读书笔记

      Go语言对比 C++引用传参

      这篇文章主要介绍了Go 到底有没有引用传参(对比 C++ ),需要的朋友可以参考下

      C++ 中三种参数传递方式

      值传递:

      最常见的一种传参方式,函数的形参是实参的拷贝,函数中改变形参不会影响到函数外部的形参。一般是函数内部修改参数而又不希望影响到调用者的时候会采用值传递。

      指针传递

      形参是指向实参地址的一个指针,顾名思义,在函数中对形参指向的内容操作,实参本身会被修改。

      引用传递

      在 C++ 中,引用是变量的别名,实际上是同一个东西,在内存中也存在同一个地址。换句话说,不管在哪里对引用操作,都相当直接操作被引用的变量。

      下面看 demo:


      #include <iostream>
      //值传递
      void func1(int a) {
        std::cout << "值传递,变量地址:" << &a << ", 变量值:" << a << std::endl;
        a ++ ;
      }
      //指针传递
      void func2 (int* a) {
        std::cout << "指针传递,变量地址:" << a << ", 变量值:" << *a << std::endl;
        *a = *a + 1;
      }
      //引用传递
      void func3 (int& a) {
        std::cout << "指针传递,变量地址:" << &a << ", 变量值:" << a << std::endl;
        a ++;
      }
      int main() {
        int a = 5;
        std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl;
        func1(a);
        std::cout << "值传递操作后,变量值:" << a << std::endl;
        std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl;
        func2(&a);
        std::cout << "指针传递操作后,变量值:" << a << std::endl;
        std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl;
        func3(a);
        std::cout << "引用传递操作后,变量值:" << a << std::endl;
        return 0;
      }

      输出结果如下:

      变量实际地址:0x28feac, 变量值:5
      值传递,变量地址:0x28fe90, 变量值:5
      值传递操作后,变量值:5
      变量实际地址:0x28feac, 变量值:5
      指针传递,变量地址:0x28feac, 变量值:5
      指针传递操作后,变量值:6
      变量实际地址:0x28feac, 变量值:6
      指针传递,变量地址:0x28feac, 变量值:6
      引用传递操作后,变量值:7

      Go 中的参数传递

      上面介绍了 C++ 的三种参数传递方式,值传递和指针传递容易理解,那么 Go 是不是也有这些传参方式呢?这引起过争论,但是对比 C++ 的引用传递的概念,我们可以说,Go 没有引用传递方式。为什么这么说,因为 Go 没有变量的引用这一概念。但是 Go 有引用类型,这个稍后再解释。

      先看一个 Go 传值和传指针的例子:


      package main
      import (
        "fmt"
      )
      func main() {
        a := 1
        fmt.Println( "变量实际地址:", &a, "变量值:", a)
        func1 (a)
        fmt.Println( "值传递操作后,变量值:", a)
        fmt.Println( "变量实际地址:", &a, "变量值:", a)
        func2(&a)
        fmt.Println( "指针传递操作后,变量值:", a)
      }
      //值传递
      func func1 (a int) {
        a++
        fmt.Println( "值传递,变量地址:", &a, "变量值:", a)
      }
      //指针传递
      func func2 (a *int) {
        *a = *a + 1
        fmt.Println( "指针传递,变量地址:", a, "变量值:", *a)
      }

      输出结果如下:

      变量实际地址: 0xc04203c1d0 变量值: 1
      值传递,变量地址: 0xc04203c210 变量值: 2
      值传递操作后,变量值: 1
      变量实际地址: 0xc04203c1d0 变量值: 1
      指针传递,变量地址: 0xc04203c1d0 变量值: 2
      指针传递操作后,变量值: 2
      可以看出,Go 基本类型的值传递和指针传递和 C++ 并没有什么不同,但是它没有变量的引用这一概念。那 Go 的引用类型怎么理解呢?

      Go 的引用类型

      在 Go 中,引用类型包含切片、字典、通道等。以切片为例,传切片是传引用么?

      举个例子:


      package main
      import (
        "fmt"
      )
      func main() {
        m1 := make([]string, 1)
        m1[0] = "test"
        fmt.Println("调用 func1 前 m1 值:", m1)
        func1(m1)
        fmt.Println("调用 func1 后 m1 值:", m1)
      }
      func func1 (a []string) {
        a[0] = "val1"
        fmt.Println("func1中:", a)
      }

      输出结果如下:

      调用 func1 前 m1 值: [test]

      func1中: [val1]

      调用 func1 后 m1 值: [val1]

      函数中对切片做出的修改影响了实际参数的值。是不是说这事引用传递?

      其实并不是,要回答这个问题,首先得搞清楚调用函数切片 m1 到底有没有改变。首先我们要认清楚切片的本质。

      一个切片是一个数组片段的描述。它包含了指向数组的指针,片段的长度。

      也就是说,上面我们打印的并不是切片本身,而是切片指向的数组。再举个例子,验证一下切片到底有没有发生变化。


        package main
      import (
        "fmt"
      )
      func main() {
        m1 := make([]string, 1)
        m1[0] = "test"
        fmt.Println("调用 func1 前 m1 值:", m1, cap(m1))
        func1(m1)
        fmt.Println("调用 func1 后 m1 值:", m1, cap(m1))
      }
      func func1 (a []string) {
        a = append(a, "val1")
        fmt.Println("func1中:", a, cap(a))
      }

      输出结果如下:

      调用 func1 前 m1 值: [test] 1

      func1中: [test val1] 2

      调用 func1 后 m1 值: [test] 1

      这个结果说明,调用前后切片并没有发生变化。之前例子中所谓的“变化”其实是切片中指向数组的指针指向的数组的元素发生了变化,这句话可能比较拗口,但实际如此。再次证明,引用类型的传参不是 pass-by-reference 。

      想透彻的了解 一个切片是一个数组片段的描述。它包含了指向数组的指针,片段的长度这句话,有兴趣可以看这篇文章:http://www.jb51.net/kf/201604/499045.html。学习一下切片的内存模型。

      总结

      总结很简单,语言也需要透过现象看本质。还有本文的结论需要记住:

      There is no pass-by-reference in Go.

      以上就是Go语言对比 C++引用传参的详细内容,更多请关注码农之家其它相关文章!

      以上就是本次介绍的Go语言电子书的全部相关内容,希望我们整理的资源能够帮助到大家,感谢大家对码农之家的支持。

      上一篇:全程软件测试(第3版)

      下一篇:Python应用开发实战

      查看更多
      下载地址:百度网盘下载
      Go语言 相关电子书
      go语言入门进阶学习资料及各种应用范例
      go语言入门进阶学习资料及各种应用范例 PDF 高清版

      Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。 对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。 go语言入门进阶学习资料包:go语言入门,go语言常见问题,beego框架学习资料及项目管理,后台管理等等各种应用范例含源码及MYSQL数据库脚本,值得大家学习。特分享给大家,希望go语言越来越受

      立即下载
      Go语言高级编程
      Go语言高级编程 PDF 完整版

      本章首先简要介绍Go语言的发展历史,并较详细地分析了ldquo;Hello Worldrdquo;程序在各个 祖先语言中演化过程。 然后,对以数组、字符串和切片为代表的基础结构,对以函 数、方法和接口所体现的面向过程和鸭子对象的编程,以及Go语言特有的并发编程 模型和错误处理哲学做了简单介绍。 最后,针对macOS、Windows、Linux几个主 流的开发平台,推荐了几个较友好的Go语言编辑器和集成开发环境,因为好的工具 可以极大地提高我们的效率。 序言 第一章 语言基础

      立即下载
      机器学习:Go语言实现
      机器学习:Go语言实现 PDF 扫描版 立即下载
      Go语言从入门到进阶实战
      Go语言从入门到进阶实战 PDF 扫描版

      5位大咖力荐!资深程序员、慕课网讲师多年Go实战经验分享;详解Go编程语法、技巧与并发原理;深度剖析开源网络库设计与架构;100分钟配套视频、72个实例精讲、50个避坑技巧

      立即下载
      go语言中文教程及手册 PDF 完整版

      Go 编程语言是一个使得程序员更加有效率的开源项目。Go 是有表达力、简洁、清晰和有效率的。它的并行机制使其很容易编写多核和网络应用,而新ᓆ的类型系统允许构建有ᧄ性的模块化程序。Go编译到机器码非常快速,同时具有便利的垃圾回收和强大的运行时反射。它是快速的、静态类型编译语言,但是感觉上是动态类型的,解释型语言。 《go语言中文教程及手册》包含了语言结构、基础语法、数据类型、语言变量、语言常量以及运算符等内容的介绍

      立即下载
      读者心得
      158小时48分钟前回答

      php实现有序数组打印或排序的方法【附Python、C及Go语言实现代码】

      本文实例讲述了php实现有序数组打印或排序的方法。分享给大家供大家参考,具体如下: 有序的数组打印或排序对于php来讲非常的简单了这里整理了几个不同语言的做法的实现代码,具体的我们一起来看这篇php中有序的数组打印或排序的例子吧. 最近有个面试题挺火的——把2个有序的数组打印或排序,刚看到这个题的时候也有点蒙,最优的算法肯定要用到有序的特性. 思考了一会发现也不是很难,假如数组是正序排列的,可以同时遍历2个数组,将小的值进行排序,最后会遍历完一个数组,留下一个非空数组,而且剩下的值肯定大于等于已经排好序的最大值. PHP代码: ?php function sort_arr($a,$b) { $temp = array(); while ($a$b) {……

      90小时9分钟前回答

      go语言和python哪个难

      Python和Go都是用于编写Web应用程序的强大的高级编程语言,它们之间有什么区别吗?下面本篇文章就来带大家认识一下Python和Go语言,介绍一下Python和Go之间的区别,希望对大家有所帮助。 什么是Python? Python是一种功能强大的高级编程语言,主要用于科学和工程计算。它是一种高效的语言,优雅务实,简单而强大,适合新手和专业人士的编程。 Python支持多种编程范例,并提出了一个大型标准库,包括面向对象,命令式,功能性和程序性。 Go是什么? Go是一种通用编程语言,由Google设计;它借鉴了许多其他许多好主意语言,同时避免导致复杂性和不可靠代码的功能。 Go支持多范式,如程序,功能和并发。……

      128小时25分钟前回答

      Python和Go语言的区别总结

      什么是Python? Python是一种功能强大的高级编程语言,主要用于科学和工程计算。它是一种高效的语言,优雅务实,简单而强大,适合新手和专业人士的编程。 Python支持多种编程范例,并提出了一个大型标准库,包括面向对象,命令式,功能性和程序性。 Go是什么? Go是一种通用编程语言,由Google设计;它借鉴了许多其他许多好主意语言,同时避免导致复杂性和不可靠代码的功能。 Go支持多范式,如程序,功能和并发。它的语法传统上来自C语言,但它已经做了很多修改,以改进简单性和安全性等功能。 Python和Go之间的区别是什么? 1、范例 Python是一种基于面向对象编程的多范式,命令式和函数式编程语……

      码农之家

      曹英楠 提供上传

      资源
      49
      粉丝
      42
      喜欢
      172
      评论
      18

      Copyright 2018-2021 www.xz577.com 码农之家

      版权投诉 / 书籍推广:520161757@qq.com