[GO专栏-1]Go语言的前生今世
博主介绍
Go 语言的诞生
Go 语言的早期团队和演化历程
Go 语言正式公布并开源
Go 语言的版本
结尾
💫点击直接资料领取💫
博主介绍
💂 个人社区:CSDN全国各地程序猿
🤟作者介绍:中国DBA联盟(ACDU)成员,CSDN全国各地程序猿(媛)聚集地管理员。目前从事工业自动化软件开发工作。擅长C#、Java、机器视觉、底层算法等语言。2019年成立柒月软件工作室,2021年注册苏州凯捷智能科技有限公司
💬如果文章对你有帮助,欢迎关注、点赞、收藏(一键三连)和C#、Halcon、python+opencv、VUE、各大公司面试等一些订阅专栏哦
💅 有任何问题欢迎私信,看到会及时回复
👤 微信号:stbsl6,微信公众号:苏州程序大白
Go 语言的诞生
字节跳动为什么全面使用Go语言?
2007年9月20日的下午,在谷歌山景城总部的一间办公室里,谷歌的大佬级程序员 Rob Pike1在等待一个 C++ 项目构建的过程中和谷歌的另外两个大佬级程序员 Robert Griesemer2和 Ken Thompson3进行了一次有关设计一门新编程语言的讨论。
图1-1-1 Go语言之父(从左到右分别是Robert Griesemer、Rob Pike和Ken Thompson)
当时的谷歌内部主要使用 C++ 语言构建各种系统,但 C++ 的巨大复杂性、编译构建速度慢以及在编写服务端程序时对并发支持的不便等让三位大佬产生了重新设计一门新编程语言的想法。在他们的初步构想中,这门新语言应该是能够给程序员带来快乐、匹配未来硬件发展趋势并适合用来开发谷歌内部大规模程序的。
趁热打铁!在第一天的简短讨论后,第二天这三位大佬又在总部的一间名为 Yaounde 的会议室里进行了一场有关这门新语言具体设计的会议。会后的第二天,Robert Griesemer 发出了一封题为“prog lang discussion”的电邮,这封电邮便成为了这门新语言的第一版设计稿,三位大佬在这门语言的一些基础语法特性上达成了初步一致。
9月25日,Rob Pike在一封回复电邮中把这门新编程语言命名为 Go:
Subject: Re: prog lang discussion From: Rob 'Commander' Pike Date: Tue, Sep 25, 2007 at 3:12 PM To: Robert Griesemer, Ken Thompson i had a couple of thoughts on the drive home. 1. name 'go'. you can invent reasons for this name but it has nice properties. it's short, easy to type. tools: goc, gol, goa. if there's an interactive debugger/interpreter it could just be called 'go'. the suffix is .go ...
Go 语言的早期团队和演化历程
经过早期讨论,三位 Go 作者在语言设计上达成初步一致后,便开启了 Go 语言迭代设计和实现的过程。
2008 年初,Unix 之父 Ken Thompson实现了第一版 Go 编译器,用于验证之前的设计。这个编译器先将 Go 代码转换为 C 代码,再由 C 编译器编译成二进制文件。
到 2008 年中旬,Go 的第一版设计基本结束了。这时,同样在谷歌工作的 Ian Lance Taylor给 Go 语言的三位作者发了一封电子邮件。他宣称为 Go 语言实现了一个 gcc 的前端,这也是 Go 语言的第二个编译器。
Subject: A gcc frontend for Go From: Ian Lance Taylor Date: Sat, Jun 7, 2008 at 7:06 PM To: Robert Griesemer, Rob Pike, Ken Thompson One of my office-mates pointed me at http://.../go_lang.html . It seems like an interesting language, and I threw together a gcc frontend for it. It's missing a lot of features, of course, but it does compile the prime sieve code on the web page.
随后,Ian Lance Taylor 正式加入 Go 语言开发团队,并在后面的 Go 语言发展演进进程中成为了 Go 语言及工具设计和实现的核心人物之一。Russ Cox 也是在 2008 年加入到刚成立不久的 Go 语言开发团队的。随着他的加入,他的一些天赋也随即在语言设计和实现中展现出来,比如io.Reader和io.Writer接口,奠定了所有 I/O 库的整体结构。
Go 语言正式公布并开源
2009 年 10 月 30 日,Rob Pike在 Google Techtalk 上做了一次有关Go 语言的演讲《The Go Programming Language》,这也是 Go 语言第一次公之于众。
Go 语言项目在 2009 年 11 月 10 日正式开源,之后这一天被官方定位 Go 语言的诞辰。最初 Go 语言项目托管在 code.google.com 上,几年后迁移至 GitHub。
随着 Go 语言的开源,Go 语言吸引了全世界开发者的目光。再加上 Go 三位作者在业界的影响力以及谷歌这座大树的加持,更多有才华的程序员加入到 Go 开发团队中,更多贡献者开始为 Go 语言项目添砖加瓦。于是,Go 在发布的当年(2009 年)就成为了著名编程语言排行榜 TIOBE 的年度最佳编程语言。
Go 发布后就吸引了一些公司,尤其是云计算领域的初创公司成为了 Go 语言的早期接纳者。在经过若干年的磨合后,在这些公司中诞生了不乏像 Docker、Kubernetes这样的“杀手级”或示范性项目,这些项目也让Go 被誉为“云计算基础设施新兴语言”或直接称为云计算语言。
在发布后,Go 语言也拥有了自己的“吉祥物” - 一只由Rob Pike 夫人``Renee French设计的地鼠,从此地鼠称为了世界各地 Go 程序员的象征。Go 程序员也被称为 Gopher,Go 语言官方技术大会也被称为 GopherCon。
Go 语言的版本
和绝大多数编程语言相似,Go 语言也是“站在巨人的肩膀上的”,正如下图所示,Go 继承了诸多编程语言的特性。
Go 的基本语法参考了 C 语言,是“C 家族语言”的一个分支;而 Go 的声明语法、包概念则受到了Pascal/Modula/Oberon的启发;一些并发的思想则来自于受到了 Tony Hoare 教授 CSP 理论影响的语言,比如:Newsqueak和Limbo。
2009 年 11 月 10 日,Go 语言正式对外发布并开源。之后,Go 语言在一段时间内采用了“Weekly Release”的模式,即每周发布一个版本。目前我们在 github.com 上 golang 的官方仓库中仍能找到的早期的 Weekly Release 版本,比如:“weekly.2009-11-06”。
从 2011 年 3 月 7 日开始,除了 Weekly Release,Go 项目还会每月发布一个 Release,即 Monthly Release,比如:release.r56,这种情况一直延续到 Go 1.0 版本发布之前;
2012 年 3 月 28 日,Go 1.0 正式发布。同时 Go 官方发布 Go1 兼容性承诺:只要符合 Go1 语言规范的源代码,Go 编译器将保证向后兼容;
2013 年 5 月 13 日,Go 1.1 版本发布。主要的变动点包括:
1、新增"method value"语法:允许将方法绑定到一个特定的 receiver 实例上,从而形成一个 function;
2、引入"terminating statement"的概念;
3、将 64 位平台上的 int 类型的字节数升为 8 个字节,即 64 bits;
4、更为精确的 Heap GC,尤其是针对 32 位平台。
2013 年 12 月 1 日,Go 1.2 版本发布。从 Go 1.2 开始,Go 开发组启动了“以每 6 个月为一个发布周期”的发布计划。Go 1.2 版本主要的变动点包括:
1、增加 Full slice expression: a[low : high : max];
2、实现抢占式 Goroutine 调度器;
3、go test新增-cover标志用于计算测试覆盖率。
2014 年 6 月 18 日,Go 1.3 版本发布。主要的变动点包括:
1、支持更多平台:solaris,dragonfly,plan9,nacl 等;
2、goroutine 的 stack 模型从”segmented“ model 改为了“contiguous” model,改善“Hot stack split”问题;
3、更为精确的 Stack GC。
2014 年 12 月 10 日,Go 1.4 版本发布。Go 1.4 也是最后一个编译器和 runtime 由 C 语言实现的版本。其主要的变动点包括:
1、新增 for range x {…}形式的 for-range 语法;
2、使用 Go 语言替换 runtime 的部分 C 语言实现,这使得 GC 变得全面精确;
3、由于 contiguous stack 的应用,goroutine 的默认栈大小从 8k 减小为 2k;
4、增加 internal package 机制;
5、增加"canonical import path"机制;
6、新增 go generate 子命令;
7、删除 Go source 树中的 src/pkg/xxx 中 pkg 这一级别,直接使用 src/xxx。
2015 年 8 月 19 日,Go 1.5 版本发布,Go 1.5 版本是一个里程碑式的重要版本。因为从这个版本开始,Go 实现了自举,即无需再依赖 C 编译器。但 Go 编译器的性能照比 Go 1.4 的 C 实现有了较大幅度的下降。其主要的变动点包括:
1、Go 编译器和 runtime 使用 Go 全部重写,原先的 C 实现被彻底移除;
2、跨平台编译 Go 程序更为简洁,只需设置两个环境变量即可:GOARCH 和 GOOS;
3、支持 map literal;
4、GOMAXPROCS 的初始默认值由 1 改为了运行环境的 CPU 核数;
5、大幅度优化 GC 延迟,多数情况 GC "Stop The World"的时间低于 10ms;
6、增加 vendor 机制,改善 Go 包依赖管理;
7、增加 go tool trace 子命令;
8、go build 增加-buildmode 命令选项,支持将 Go 代码编译为 shared library 形式。
2016 年 2 月 17 日,Go 1.6 版本发布。主要的变动点包括:
1、进一步优化 GC 延迟,实现 Go 程序在占用大内存的情况下,GC 延迟仍低于 10ms;
2、自动支持 HTTP/2;
3、定义了在 C 代码中共享 Go 指针的规则。
2016 年 8 月 15 日,Go 1.7 版本发布。主要的变动点包括:
1、针对 x86-64,实现了 SSA 后端,使得编译出的 binary file size 减少 20%~30%;运行效率提升 5%~35%;
2、Go 编译器的性能比 Go 1.6 版本提升近一倍;
3、go test 支持 subtests 和 sub-benchmarks;
4、标准库新增 context 包。
2017 年 2 月 16 日,Go 1.8 版本发布。主要的变动点包括:
1、支持仅 tags 不同的两个 struct 可以相互做显式类型转换;
2、标准库增加 sort.Slice 函数;
3、支持 HTTP/2 Push 机制;
4、支持支持 HTTP Server 优雅退出;
5、增加了对 Mutex 和 RWMutex 的 profiling(剖析)支持;
6、支持 Go plugins,增加 plugin 包;
7、支持默认的 GOPATH 路径,无需再显式设置;
8、进一步优化 SSA 后端代码,程序平均性能提升 10%左右;
9、Go 编译器性能进一步提升,平均编译链接的性能提升幅度在 15%左右;
10、GC 的延迟进一步降低,STW(Stop The World)的时间通常将低于 100 微秒,甚至经常低于 10 微秒。
11、优化 defer 的实现,使得其性能损耗降低了一半。
2017 年 8 月 25 日,Go 1.9 版本发布。主要的变动点包括:
1、新增了 type alias 语法;
2、在原先的支持包级别的并发编译的基础上又实现了包函数级别的并发编译,使得 Go 编译性能有 10%左右的提升;
3、大内存对象分配性能得到显著提升;
4、增加了对 monotonic clock 的支持;
5、提供了一个支持并发的 Map 类型:sync.Map;
6、增加 math/bits 包,将高性能位操作实现收入标准库。
2018 年 2 月 17 日,Go 1.10 版本发布。主要的变动点包括:
1、支持默认 GOROOT,开发者无需显式设置 GOROOT 环境变量;
2、增加 GOTMPDIR 环境变量;
3、通过 cache 大幅提升构建和 go test 执行的性能,并基于源文件内容是否变化判定是否使用 cache 结果;
4、支持 Unicode 10.0 版本。
2018 年 8 月 25 日,Go 1.11 版本发布。Go 1.11是Russ Cox在GopherCon 2017 大会上发表 "Toward Go2"之后的第一个 Go 版本,新的 Go 包管理机制 go modules 在 Go 1.11 中的落地为后续“Go2”的提议渐进落地奠定了良好的基础。该版本主要的变动点包括:
1、引入 Go module,为 Go 包管理提供了创新性的解决方案;
2、引入对 WebAssembly 的支持,让 Gopher 可以使用 Go 语言来开发前端 Web 应用;
3、为调试器增加了一个新的实验功能:允许在调试过程中动态调用 Go 函数。
2019 年 2 月 25 日,Go 1.12 版本发布。主要的变动点包括:
1、对 Go 1.11 中增加的 go modules 机制做了进一步优化;
2、增加对 TLS 1.3 的支持;
3、优化了大量 heap 依然存在时 GC 清理环节的性能,使得一次 GC 后的内存分配延迟得以改善;
4、运行时更加积极地将释放的内存归还给操作系统,以应对大块内存分配无法重用已存在的堆空间的问题;
5、该版本中 Build cache 成为必需。
2019 年 9 月 4 日,Go 1.13 版本发布。主要的变动点包括:
1、增加以 0b 或 0B 开头的二进制数字字面量形式,如:0b111;
2、增加以"0o"或"0O"开头的八进制数字字面量形式,如:0o700;
3、增加以 0x 或 0X 开头的十六进制形式的浮点数字面量,如:0x123.86p+2;
4、支持在数字字面量中通过数字分隔符"_"提高可读性,如:a := 5_3_7等;
5、取消了移位操作(>>和<<)的右操作数仅能是无符号数的限制;
6、继续对 Go module 机制进行优化,包括:当GO111MODULE=auto时,无论是在$GOPATH/src 下还是 GOPATH 之外的仓库中>,只要目录下有 go.mod,Go 编译器都会使用 go module 来管理依赖;GOPROXY 支持配置多个代理,默认值为https://proxy.golang.org,direct;提供了 GOPRIVATE 变量,用于指示哪些仓库下的 module 是私有的,即不需要通过 GOPROXY 下载,也不需要通过 GOSUMDB 去验证其校验和;
7、Go 错误处理改善:在标准库中增加 errors.Is 和 As 函数来解决 error value 的比较判定问题;增加 errors.Unwrap 函数来解决 error 的展开(unwrap)问题;
8、defer 性能提升 30%;
9、支持的 unicode 标准从 10.0 版本升级到Unicode 11.0 版本。
2020 年 2 月 26 日,Go 1.14 版本发布。主要的变动点包括:
1、支持嵌入接口的方法集可重叠;
2、支持 goroutine 的异步抢占式调度;
3、defer 性能得到大幅优化,理论上可实现 30%的提升;
4、重新实现了运行时(runtime)层的 timer;
5、go module 可应用于生产环境;
6、标准库 testing 包增加Cleanup方法用于实现测试执行后的清理工作
结尾
了解一门编程语言的诞生历史和早期演化史,有助于程序员在学习这门语言的同时产生或加深对语言的认同感。程序员能感同身受,从而能更加有热情的投入到这门语言的学习和使用当中。同时这种认同感也能积极推动程序员在后续的实践中形成语言的原生思维(比如:Go 语言思维),从而更加高效地利用这门语言进行编程,解决实际问题。
同时,了解 Go 版本的发布历史以及不同版本的主要变动点,将有助于程序员根据自身的实际情况选择最为适合的 Go 版本。
Rob Pike(罗伯·派克),早期贝尔实验室成员,参与了 Plan9 操作系统、C 编译器以及多种语言编译器的设计和实现,UTF-8 发明人之一。
Robert Griesemer(罗伯特·格瑞史莫),Java 的 HotSpot 虚拟机和 Chrome 浏览器的 JavaScript V8 引擎的设计者之一。
Ken Thompson(肯·汤普逊),图灵奖得主、Unix 之父以及 C 语言的发明人之一。