01 Go语言介绍

一 Go语言的诞生

已经有那么多编程语言了,为何还要再造一门Go???

一方面:从大的维度分析

1、近几十年来,计算机硬件飞速发展,硬件越来越廉价,并且硬件性能/抗并发能力不断攀升,超线程技术、CPU 多核化的发展和普及为并行计算提供了技术支持与编程需求,但是反观编程语言领域却没有什么大的动作,很早就诞生了C/C++在计算机领域发展的也不并好,也就是说,并没有一门专门为这个时代的硬件而生的编程语言

2、旧的编程语言无法在开发效率与执行效率之间做出很好的平衡
    要么执行效率高,开发效率低、编译速度慢,如C++;
    要么执行效率低,但拥有高效的编译,如.NET、Java;

    总之。go出现之前的语言在执行效率和开发效率上都不能做到鱼与熊掌兼得,如下所示
    - 执行效率 execution speed:        C/C++    >  Java   >  Python
    - 开发效率 developing efficiency:  Python   >  Java   >  C/C++

所以,一门同时拥有高效的执行速度、编译速度和开发速度的编程语言呼之欲出,这就是Go语言诞生的前戏与大环境

另外一方面:从具体的问题分析

面对主流编程语言,开发者不得不在其简洁性/开发效率、编译和运行的高效性、代码的可读性、类型系统的轻量性等方面纠结徘徊,或者像 Google 一样采取多语言并用的策略。但是,随着项目规模的不断扩大,开发和维护的复杂性也正在把Google公司一步一步拖入泥潭中……

时间回溯到 2007 年,那个时候,GitHub 还未问世,Intel 也才在前一年刚推出自家的第一个多核微处理器 Core 2(微处理器,简单来说,就是将 CPU 的所有元件都放入同一块芯片中的东东)。彼时的 Google 已然成长为一家全球科技巨头,与之相随的便是行数与复杂度不断增长的代码量,Google公司开发遇到了棘手的问题。。。。。。
1、系统越来越复杂:大量的代码是由C++、Java,并辅以 Python 写成
2、规模越来越庞大:成千上万的工程师每天都在围绕着数以万计行的代码及其分布式的编译系统、数百万的服务器工作着以保证各项服务的正常运行

面对如此庞大的开发规模,人才济济的谷歌虽然通过各种技术手段得以“逆风飞翔”,但是此种状态却带来了慢速、低效,甚至稍显笨拙的开发体验。随着系统进一步复杂、规模进一步庞大,下述痛点也都在进一步被放大:

  • 编译慢
  • 失控的依赖
  • 每个工程师只是用了一个语言里面的一部分
  • 程序难以维护(可读性差、文档不清晰等)
  • 更新的花费越来越长
  • 交叉编译困难

如何解决呢?

正遭遇上述问题的 Google 工程师们开始坐立不安了,他们一边对现状充满沮丧,一边回望过去,沉思良久,希望搞明白问题所在。这些在计算机语言领域已深耕多年,富有经验的工程师们意识到,不能简单地通过现有语言的单个特性,或添加某些库就能很好地解决现存问题,站在软件工程的更高角度,顺应技术的发展创造一门全新的语言才是当下亟需要做的事情。

于是,谷歌公司的三位工程师于 2007 年 9 月 20 号下午进行一次讨论,正是这次讨论才有了第二天组织在位于加利福尼亚的山景城 43 号楼的三人会议。没错,与会的三人 Robert Griesemer,Rob Pike 和 Ken Thompson 就是 Go 的创始人,他们均在 Google 任职,其中的 Ken 就是那个发明了 UNIX、B语言的神一样的男子。

  • 1、Robert Griesemer罗伯特.格利茨默(Java HotSpot虚拟机、V8引擎开发者之一)

  • 2、Rob Pike罗伯.派克(贝尔实验室UNIX团队成员,曾参与Plan9、Inferno和Limbo等项目)

  • 3、Ken Thompson肯.汤普森(贝尔实验室UNIX团队成员,C语言、UNIX和Plan 9创始人之一,与Rob Pike共同开发了UTF-8字符集规范)

    下图从左到右依次排序

刚开始,三位神仙只是一些有一些想法和愿望,但隶属行动派的三人数日之内就敲定了目标和接下来要做的事情,

- 1、Go希望成为互联网时代的C语言。多数系统级语言(包括Java和C#)的根本编程哲学来源于C++,并将C++的面向对象进一步发扬光大。但是Go语言的设计者却有不同的看法,他们认为值得学习的是C语言。C语言经久不衰的根源是它足够简单。因此,Go语言也是足够简单。
- 2、所以,他们当时设计Go的目标是为了消除各种缓慢和笨重、改进各种低效和扩展性。Go是由那些开发大型系统的人设计的,同时也是为了这些人服务的;它是为了解决工程上的问题,不是为了研究语言设计;它还是为了让我们的编程变得更舒适和方便。
- 3、但是结合Google当时内部的一些现实情况,如很多工程师都是C系的,所以新设计的语言一定要易学习,最好是类似C的语言;20年没有出新的语言了,所以新设计的语言必须是现代化的(例如内置GC)等情况。

最后根据实战经验,他们向着既定的目标开始设计Go语言。。。

在他们的第 1 封有关语言设计的邮件列表中,这门语言的名称 “Go” 就已初漏端倪:

Go VS Golang
由于 Google 在注册 Go 的官网域名时,go.org 已被迪士尼抢注,golang.org 才得以“上位”,这也就产生了很多人误以为 Golang 就是其正式名称的误会,而事实却恰恰相反,我们可以认为 Golang 只是 Go 的绰号。

得益于Google公司良好的企业文化,允许工程师拿出20%的时间来研究自己喜欢的项目。语音服务Google Now、谷歌新闻Google News、谷歌地图Google Map上的交通信息等,全都是20%时间的产物,Go语言最开始也是20%时间的产物。在接下来的日子里,Go 的设计等相关工作始终以兼职的形式进行着。直到 2008 年年中,Go 项目才正式“转正”,成为一个全职项目。

此间,第一件令人惊喜的事就来自那三位创始人收到的这份邮件:

邮件中 Ian (全名Ian Lance Taylor,GCC核心开发人员)讲到自己为 Go 实现了一个能进行语法分析、词法分析和语义分析的 gcc 前端编译组件。后来,Ian 也成为了 Go 的核心开发人员。

2008 年末,另一位技术大神 Russ Cox(曾参与Plan 9 操作系统的开发) 也加入到了 Go 开发团队。在他的助攻下,Go 语言和标准库从原型变成了现实。

后来还加入了Brand Fitzpatrick(memcached的作者)

Go创始团队的神仙阵容,标志着Go语言的创始团队对操作系统和系统编程有着非常深刻的理解,这对一门语言的开发起到至关重要的作用。

2009 年 11 月 10 号,Go 宣布开源,这一天也被选定为 Go 的生日🎂。

2012 年 3 月,Go version 1 正式发布,这标志着 Go 作为一门全新的编程设计语言已可投身生产,根据 Go 的 兼容性原则,我们可以放心地使用它编写简单、高效、稳定可靠的应用了。

二 Go语言的发展

Go 语言起源 2007 年

Go 从 2009 年 9 月 21 日开始正式作为谷歌公司 20% 兼职项目

2009年11月10日Google公司才正式发布Go语言,并以BSD协议完全开源,支持Linux和Mac OS平台,同年11月支持Windows平台。

下面我们以时间轴的方式梳理了在这个迭代过程中,发生了哪些里程碑式的大事件。

go历史大事

若想详细了解Go历史版本更迭请看: https://golang.google.cn/doc/devel/release.html

- 2007年9月,雏形设计 ,Rob Pike(罗伯.派克) 正式命名为Go;
- 2008年5月,Google全力支持该项目;
// 2009年11月10日,首次公开发布,Go将代码全部开源,它获得了当年的年度语言;
- 2011年3月16日,Go语言的第一个稳定(stable)版本r56发布。
// 2012年3月28日,Go语言的第一个正式版本Go1发布。
- 2013年4月04日,Go语言的第一个Go 1.1beta1测试版发布。
- 2013年4月08日,Go语言的第二个Go 1.1beta2测试版发布。
- 2013年5月02日,Go语言Go 1.1RC1版发布。
                RC=Release Candidate,含义是”发布候选版”,
                它不是最终的版本,而是最终版(RTM=Release To Manufacture)之前的最后一个版本。
- 2013年5月07日,Go语言Go 1.1RC2版发布。
- 2013年5月09日,Go语言Go 1.1RC3版发布。
- 2013年5月13日,Go语言Go 1.1正式版发布。
- 2013年9月20日,Go语言Go 1.2RC1版发布。
- 2013年12月1日,Go语言Go 1.2正式版发布。
- 2014年6月18日,Go语言Go 1.3版发布。
- 2014年12月10日,Go语言Go 1.4版发布。
// 2015年8月19日,Go语言Go 1.5版发布,本次更新中移除了”最后残余的C代码”。
go1.5的发布被认为是历史性的。完全移除C语言部分,使用GO编译GO(ps:少量代码使用汇编实现),GO编译GO称之为Go的自举,是一门编程语言走向成熟的表现。另外,他们请来了内存管理方面的权威专家Rick Hudson,对GC进行了重新设计,支持并发GC,解决了一直以来广为诟病的GC时延(STW)问题。并且在此后的版本中,又对GC做了更进一步的优化。到go1.8时,相同业务场景下的GC时延已经可以从go1.1的数秒,控制在1ms以内。GC问题的解决,可以说GO语言在服务端开发方面,几乎抹平了所有的弱点。

- 2016年2月17日,Go语言Go 1.6版发布。
- 2016年8月15日,Go语言Go 1.7版发布。
- 2017年2月17日,Go语言Go 1.8版发布。
- 2017年8月24日,Go语言Go 1.9版发布。
- 2018年2月16日,Go语言Go 1.10版发布。
- 2018年8月24日,Go语言Go 1.11版发布。
- 2019年2月25日,GO语言Go1.12版发布。

ps:
在GO语言的版本迭代过程中,语言特性基本上没有太大的变化,基本上维持在GO1.1的基准上,并且官方承诺,新版本对老版本下开发的代码完全兼容。事实上,GO开发团队在新增语言特性上显得非常谨慎,Go语言的版本更迭主要集中在稳定性、编译速度、执行效率以及GC性能等底层性能方面,所以说Go语言使用者不必担心快速的版本更迭带来的兼容性问题

Go语言这两年在语言排行榜(https://www.tiobe.com/tiobe-index/)增长曲线如下,总体还是处于上涨趋势的

大量基于GO语言开发的杀手级应用:Docker、Kubernetes、Go-Ethereum、Thrraform、Moby、Gogs、Grafana、Etcd等。于2009、2016两次夺得TIOBE年度编程语言的称号,2020年世界排名处于第12位

发展中的 Go :最有前途的编程语言

Go 从诞生之初,就有一个明确的目标,那就是解决 Google 内部正面临的软件开发问题,这些问题并非 Google 独自的遭遇,业界普遍存在。所以,GO 不仅是一门通用编程设计语言(general-purpose language),更是一门着眼解决现实问题的实用编程语言。历经多年,核心开发者与社区众多优秀成员不断地完善改进这门语言,Go 已经发展成为了一门成熟的现代编程语言,在 web、移动应用、图形处理、以及云计算、机器学习、区块链等领域都能见到它的身影,其语言本身的简洁性、内置的并发编程支持、垃圾回收机制等特性深受开发者青睐。

JetBrains 近期发布的一份分析报告——2019 开发人员生态系统现状 在对比了主流开发语言后,得出一个结论:Go 是最有前途的编程语言。

核心开发者的持续支持,活跃的社区,日益增长的开发者众,越来越多的企业开始转投 Go 阵营,Russ Cox 在 GopherCon 2017 上做了对 Go 2 畅想的 演讲……

Go,未来可期!

三 GO语言归类

编程语言通常按照下述三点进行分类

// 1、编译型or解释型
1.1 编译型:程序运行前先用编译器将程序源代码进行编译,以后拿着编译的结果直接运行 golang/C/C++
1.2 解释型:每次运行程序时,都需要拿来源代码、由解释器"当场"解释执行 python/shell

// 2、静态类型or动态类型
2.1 静态类型:写程序时需要事先给变量声明类型,因为编译时就会确定类型 java/C/C++/golang
// golang静态类型示例
var age1 int = 18 // 为变量age1指定类型为int

2.2 动态类型:写程序时需要无需给变量声明类型,因为运行时才确定类型   python/PHP
// python静态类型示例:
age3=18 // 一直到解释执行的时候才会确定变量age3的类型

补充:
数据是程序的基石,因此数据类型的设计牵扯到程序的整体质量,无论是采用静态类型设计还是动态类型设计都会衍生出无数的优缺点。
对于习惯使用动态类型的程序员来说,可能会觉得Go的静态类型略显笨重,确实如此,但静态类型也有其好处,特别是配合编译操作的时候可以大幅度提升编译速度。
总之一句话:世界上只有两种语言,没人用的和挨人骂的,技术只是服务于商业的工具,能用就用,该扔就扔,不要跟个村头老大妈一样天天叨叨东家长李家短的,没意义而且很猥琐。

// 3、强类型or弱类型
3.1 强类型:类型是定义好的,无法改变它的类型(python/golang)
python提供了一系列内置功能用来转换,转换之后都是产生了新的值,并非修改了原值的类型
Go语言也是一门强类型语言,如interface{}任意类型不能随意的转换为其他类型

3.2 弱类型:类型之间可以自由转换
比如linux中的shell中定义一个变量,是随着调用方式的不同,数据类型可随意切换的那种。

综上

1、Python是一门开源的解释型、动态、强类型语言

2、Golang是一门开源的编译型、静态、强类型语言

四 Go语言的设计思想

1、围绕 简单 这一核心的设计

- 隐式接口,切片
- 类的弱化,强制用组合
- 简洁高效的并发
- 弱化的指针
- err 判定,先判错的习俗.

2、有自己的坚持,不盲目攀比

比优点比不过很多语言,没C快,没java灵活,赶不上python实现简单,但是也没有大的缺点.
优点多,上手快,多线程方便,slice,channel 方便,格式严谨,从而简单实用. 这就奠定了其流行的基础.

3、keep it simple

追求简单实用的哲学,从语言的层面上减少代码的复杂度 ------------- 直指程序管理的终极目标,以及管理的复杂度

五 Go语言的特点

5.1 Go的优势

简明扼要地说:

1、Go 语言是一个开源项目

2、简化问题,易于学习

3、内存管理,简洁语法,易于使用

4、快速编译,高效开发

5、高效执行

6、并发支持,轻松驾驭

Go 语言最最吸引人的地方可能是其原生支持并发编程(语言层面原生支持和通过第三方库支持是有很大区别的)。Go 语言的对网络通信、并发和并行编程的支持度极高,从而可以更好地利用大量的分布式和多核的计算机。开发者可以通过 goroutine 这种轻量级线程的概念来实现这个目标,然后通过 channel 来实现各个 goroutine 之间的通信。他们实现了分段栈增长和 goroutine 在线程基础上多路复用技术的自动化。

7、静态类型

Go语言新颖的类型系统使程序结构变得灵活而模块化。
Go语言虽然是静态编译型语言,但是它却拥有脚本化的语法,它简洁、清晰而高效,并且支持多种编程范式(函数式和面向对象)。

8、标准类库,规范统一

9、易于部署

Go 代码编译成机器码非常迅速

10、文档全面

11、免费开源

其余详细见附录:Go语言特性

一句话总结:它是一个快速的、静态类型的编译型语言,感觉却像动态类型的解释型语言。

5.2 关于特性缺失

许多能够在大多数面向对象语言中使用的特性 Go 语言都没有支持,但其中的一部分可能会在未来被支持。

  • 为了简化设计,不支持函数重载和操作符重载
  • 为了避免在 C/C++ 开发中的一些 Bug 和混乱,不支持隐式转换
  • Go 语言通过另一种途径实现面向对象设计(第 10-11 章)来放弃类和类型的继承
  • 尽管在接口的使用方面(第 11 章)可以实现类似变体类型的功能,但本身不支持变体类型
  • 不支持动态加载代码
  • 不支持动态链接库
  • 不支持泛型
  • 通过 recoverpanic 来替代异常机制(第 13.2-3 节)
  • 不支持断言
  • 不支持静态变量

关于 Go 语言开发团队对于这些方面的讨论,你可以通过 Go 常见问题 页面查看。

5.3 GO的性能说明及与其他语言对比

根据 Go 开发团队和基本的算法测试,于 2013 年 3 月 28 日之前统计结果得出,Go 语言与 C 语言的性能差距大概在 10%~20% 之间。虽然没有官方的性能标准,但是与其它各个语言相比已经拥有非常出色的表现。

如果说 Go 语言的执行效率大约比 C++ 慢 20% 也许更有实际意义。保守估计在相同的环境和执行目标的情况下,Go 程序比 Java 或 Scala 应用程序要快上 2 倍,并比这两门语言使用少占用 70% 的内存。在很多情况下这种比较是没有意义的,因为像谷歌这样拥有成千上万台服务器的公司都抛弃 C++ 而开始将 Go 用于生产环境已经足够说明它本身所具有的优势。

时下流行的语言大都是运行在虚拟机上,如:Java 和 Scala 使用的 JVM,C# 和 VB.NET 使用的 .NET CLR。尽管虚拟机的性能已经有了很大的提升,但任何使用 JIT 编译器和脚本语言解释器的编程语言(Ruby、Python、Perl 和 JavaScript)在 C 和 C++ 的绝对优势下甚至都无法在性能上望其项背。

如果说 Go 比 C++ 要慢 20%,那么 Go 就要比任何非静态和编译型语言快 2 到 10 倍,并且能够更加高效地使用内存。

其实比较多门语言之间的性能是一种非常猥琐的行为,因为任何一种语言都有其所擅长和薄弱的方面。例如在处理文本方面,那些只处理纯字节的语言显然要比处理 Unicode 这种更为复杂编码的语言要出色的多。有些人可能认为使用两种不同的语言实现同一个目标能够得出正确的结论,但是很多时候测试者可能对一门语言非常了解而对另一门语言只是大概明白,测试者对程序编写的手法在一定程度也会影响结果的公平性,因此测试程序应该分别由各自语言的擅长者来编写,这样才能得到具有可比性的结果。另外,像在统计学方面,人们很难避免人为因素对结果的影响,所以这在严格意义上并不是科学。还要注意的是,测试结果的可比性还要根据测试目标来区别,例如很多发展十多年的语言已经针对各类问题拥有非常成熟的类库,而作为一门新生语言的 Go 语言,并没有足够的时间来推导各类问题的最佳解决方案。如果你想获取更多有关性能的资料,请访问 Computer Language Benchmark Game

这里有一些评测结果:

  • 比较 Go 和 Python 在简单的 web 服务器方面的性能,单位为传输量每秒:

    原生的 Go http 包要比 web.py 快 7 至 8 倍,如果使用 web.go 框架则稍微差点,比 web.py 快 6 至 7 倍。如果是使用Python 中的 tornado 异步服务器和框架开发出的Web应用,那么要比传统的 web.py 快很多,此时,Go 大概只比它快 1.2 至 1.5 倍,Go在Web开发的领域比Python要快,但目前来看,并非碾压态势。

  • Go 和 Python 在一般开发的平均水平测试中,Go 要比 Python 3 快 25 倍左右,少占用三分之二的内存,但比 Python 大概多写一倍的代码,毫无疑问,开发效率上,python是要技高一筹的。

  • 根据 Robert Hundt(2011 年 6 月)的文章对 C++、Java、Go 和 Scala,以及 Go 开发团队的反应(),可以得出以下结论:

    • Go 和 Scala 之间具有更多的可比性(都使用更少的代码),而 C++ 和 Java 都使用非常冗长的代码。
    • Go 的编译速度要比绝大多数语言都要快,比 Java 和 C++ 快 5 至 6 倍,比 Scala 快 10 倍。
    • Go 的二进制文件体积是最大的(每个可执行文件都包含 runtime)。
    • 在最理想的情况下,Go 能够和 C++ 一样快,比 Scala 快 2 至 3 倍,比 Java 快 5 至 10 倍。
    • Go 在内存管理方面也可以和 C++ 相媲美,几乎只需要 Scala 所使用的一半,比 Java 少 4 倍左右。

四 Go语言的应用场景

编程语言说到底只是一种工具,不选最好的,只选最合适的

// Go语言适用的场景为:
    - 1、服务器编程,以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。
    - 2、凭借其出色的并发能力,Go在分布式系统领域,如集群系统、游戏服务器、数据库代理器、中间件等场景同样极具威力
    - 3、网络编程,这一块目前应用最广,包括Web应用、API应用、下载应用,而且Go内置的net/http包基本上把我们平常用到的网络功能都实现了。
    - 4、数据库操作
    - 5、开发云平台,目前国外很多云平台在采用Go开发

// Go语言不适合的场景为:
    1、强实时性软件:话音通信、无人驾驶
        垃圾回收、自动内存分配等因素都让Go在实时性上力不从心

其他

Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。

Go 语言一个非常好的目标就是实现所谓的复杂事件处理(CEP),这项技术要求海量并行支持,高度的抽象化和高性能。当我们进入到物联网时代,CEP 必然会成为人们关注的焦点。

但是 Go 语言同时也是一门可以用于实现一般目标的语言,例如对于文本的处理,前端展现,甚至像使用脚本一样使用它。

值得注意的是,因为垃圾回收和自动内存分配的原因,Go 语言不适合用来开发对实时性要求很高的软件。

越来越多的谷歌内部的大型分布式应用程序都开始使用 Go 语言来开发,例如谷歌地球的一部分代码就是由 Go 语言完成的。

如果你想知道一些其它组织使用Go语言开发的实际应用项目,你可以到 使用 Go 的组织 页面进行查看。出于隐私保护的考虑,许多公司的项目都没有展示在这个页面。

在 Chrome 浏览器中内置了一款 Go 语言的编译器用于本地客户端(NaCl),这很可能会被用于在 Chrome OS 中执行 Go 语言开发的应用程序。

Go 语言可以在 Intel 或 ARM 处理器上运行,因此它也可以在安卓系统下运行,例如 Nexus 系列的产品。

在 Google App Engine 中使用 Go 语言:2011 年 5 月 5 日,官方发布了用于开发运行在 Google App Engine 上的 Web 应用的 Go SDK,在此之前,开发者们只能选择使用 Python 或者 Java。这主要是 David Symonds 和 Nigel Tao 努力的成果。目前最新的稳定版是基于 Go 1.4 的 SDK 1.9.18,于 2015 年 2 月 18 日发布。

四 国内外那些公司在用Go语言

详见:“附录:哪些公司在用Go语言”

五 Go语言Logo

六 Go语言吉祥物

gopher是一种生活在加拿大的小动物,它的中文名叫做囊地鼠,是go语言的吉祥物,在会议、文档页面和博文中,大多会包含这个小吉祥物,下图是才华横溢的插画家 Renee French 设计的,她也是 Go 设计者之一 Rob Pike 的妻子,gopher最大的特点就是挖洞速度特别快,这也正好吻合Go语言追求更快的运行速度、开发速度、学习速度(develop)的思想。

吉祥物

上一篇
下一篇
Copyright © 2022 Egon的技术星球 egonlin.com 版权所有 帮助IT小伙伴学到真正的技术