学习笔记287—为什么要开发 Go 这门新语言?有什么优势?
编程语言已经非常多,偏性能敏感的编译型语言有 C、C++、Java、C#、Delphi和Objective-C等,偏快速业务开发的动态解析型语言有 PHP、Python、Perl、Ruby、JavaScript和Lua等,面向特定领域的语言有 Erlang、R和MATLAB等,那么我们为什么需要 Go这样一门新语言呢? 在2000年前的单机时代, C语言是编程之王。随着机器性能的提升、软件规模与复杂度的提高,Java逐步取代了C的位置。尽管看起来 Java已经深获人心,但 Java编程的体验并未尽如人意。Google 的大佬们为什么还要再开发一门新的语言呢?
Go适合用来做什么
-
服务器编程,以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。
-
分布式系统,数据库代理器等
-
网络编程,这一块目前应用最广,包括Web应用、API应用、下载应用、
-
内存数据库,前一段时间google开发的groupcache,couchbase的部分组建
-
云平台,目前国外很多云平台在采用Go开发,CloudFoundy的部分组建,前VMare的技术总监自己出来搞的apcera云平台。
背景
Go 编程语言构思于 2007 年底,构思的目的是:为了解决在 Google 开发软件基础设施时遇到的一些问题。
Go 语言之父
图上三位是 Go 语言最初的设计者,功力都非常的深厚,按序从左起分别是:
-
Robert Griesemer:参与过 Google V8 JavaScript 引擎和 Java HotSpot 虚拟机的研发。
-
Rob Pike:Unix 操作系统早期开发者之一,UTF-8 创始人之一,Go 语言吉祥物设计者是 Rob Pike 的媳妇。
-
Ken Thompson:图灵奖得主,Unix 操作系统早期开发者之一,UTF-8 创始人之一,C 语言(前身 B 语言)的设计者。
遇到的问题
曾经在早期的采访中,Google 大佬们反馈感觉 "编程" 太麻烦了,他们很不喜欢 C++,对于现在工作所用的语言和环境感觉比较沮丧,充满着许多不怎么好用的特性。
具体遭遇到的问题。如下:
-
软件复杂:多核处理器、网络系统、大规模计算集群和网络编程模型所带来的问题只能暂时绕开,没法正面解决。
-
软件规模:软件规模也发生了变化,今天的服务器程序由数千万行代码组成,由数百甚至数千名程序员进行工作,而且每天都在更新(据闻 Go 就是在等编译的 45 分钟中想出来的)。
-
编译耗时:在大型编译集群中,构建时间也延长到了几分钟,甚至几小时。
设计目的
为了实现上述目标,在既有语言上改造的话,需要解决许多根本性的问题,因此需要一种新的语言。
这门新语言需要符合以下需求:
-
目的: 设计和开发 Go 是为了使在这种环境下能够提高工作效率 。
-
设计:在 Go 的设计上,除了比较知名的方面:如内置并发和垃圾收集。还考虑到:严格的依赖性管理,随着系统的发展,软件架构的适应性,以及跨越组件之间边界的健壮性。
这门新语言就是现在的 Go。
Go 在 Google
Go 是 Google 设计的一种编程语言,用于帮助解决谷歌的问题,而 Google 的问题很大。
Google 整体的应用软件很庞大,硬件也很庞大,有数百万行的软件,服务器主要是 C++ 语言,其他部分则是大量的 Java 和 Python。
数以千计的工程师在代码上工作,在一个由所有软件组成的单一树的 "头 " 上工作,所以每天都会对该树的所有层次进行重大改变。
一个大型的定制设计的分布式构建系统使得这种规模的开发是可行的,但它仍然很大。
当然,所有这些软件都在几十亿台机器上运行,这些机器被视为数量不多的独立、联网的计算集群。
简而言之,Google 的开发规模很大,速度可能是缓慢的,而且往往是笨拙的。但它是有效的。
Go 项目的目标是:消除 Google 软件开发的缓慢和笨拙,从而使这个过程更富有成效和可扩展。 这门语言是由编写、阅读、调试和维护大型软件系统的人设计的,也是为他们设计的 。
因此 Go 的目的不是为了研究编程语言的设计,而是为了改善其设计者及其同事的工作环境。
Go 更多的是关于软件工程而不是编程语言研究。或者换个说法,它是为软件工程服务的语言设计。
痛点
当 Go 发布时,有些人声称它缺少被认为是现代语言的必要条件的特定功能或方法。在缺乏这些设施的情况下,Go怎么可能有价值?
我们的答案是:Go 所拥有的特性可以解决那些使大规模软件开发变得困难的问题。
这些问题包括:
-
构建速度缓慢。
-
不受控制的依赖关系。
-
每个程序员使用不同的语言子集。
-
对程序的理解不透彻(代码可读性差,文档不全等)。
-
工作的重复性。
-
更新的成本。
-
版本偏移(version skew)。
-
编写自动工具的难度。
-
跨语言的构建。
纯粹一门语言的单个功能并不能解决这些问题,我们需要对软件工程有一个更大的看法。因此在 Go 的设计中,我们试图把重点放在这些问题的解决方案上。
Go成功的项目
nsq:bitly开源的消息队列系统,性能非常高,目前他们每天处理数十亿条的消息
docker:基于lxc的一个虚拟打包工具,能够实现PAAS平台的组建。
packer:用来生成不同平台的镜像文件,例如VM、vbox、AWS等,作者是vagrant的作者
skynet:分布式调度框架
Doozer:分布式同步工具,类似ZooKeeper
Heka:mazila开源的日志处理系统
cbfs:couchbase开源的分布式文件系统
tsuru:开源的PAAS平台,和SAE实现的功能一模一样
groupcache:memcahe作者写的用于Google下载系统的缓存系统
god:类似redis的缓存系统,但是支持分布式和扩展性
gor:网络流量抓包和重放工具
Go有什么优势
-
可直接编译成机器码,不依赖其他库,glibc的版本有一定要求,部署就是扔一个文件上去就完成了。
-
静态类型语言,但是有动态语言的感觉,静态类型的语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉就是有很多的包可以使用,写起来的效率很高。
-
语言层面支持并发,这个就是Go最大的特色,天生的支持并发,我曾经说过一句话,天生的基因和整容是有区别的,大家一样美丽,但是你喜欢整容的还是天生基因的美丽呢?Go就是基因里面支持的并发,可以充分的利用多核,很容易的使用并发。
-
内置runtime,支持垃圾回收,这属于动态语言的特性之一吧,虽然目前来说GC不算完美,但是足以应付我们所能遇到的大多数情况,特别是Go1.1之后的GC。
-
简单易学,Go语言的作者都有C的基因,那么Go自然而然就有了C的基因,那么Go关键字是25个,但是表达能力很强大,几乎支持大多数你在其他语言见过的特性:继承、重载、对象等。
-
丰富的标准库,Go目前已经内置了大量的库,特别是网络库非常强大,我最爱的也是这部分。
-
内置强大的工具,Go语言里面内置了很多工具链,最好的应该是gofmt工具,自动化格式化代码,能够让团队review变得如此的简单,代码格式一模一样,想不一样都很困难。
-
跨平台编译,如果你写的Go代码不包含cgo,那么就可以做到window系统编译linux的应用,如何做到的呢?Go引用了plan9的代码,这就是不依赖系统的信息。
-
内嵌C支持,前面说了作者是C的作者,所以Go里面也可以直接包含c代码,利用现有的丰富的C库。
总结
软件工程指导了 Go 的设计。
与大多数通用编程语言相比, Go 的设计是为了解决我们在构建大型服务器软件时接触到的一系列软件工程问题 。这可能会使 Go 听起来相当沉闷和工业化。但事实上,整个设计过程中对清晰、简单和可组合性的关注反而导致了一种高效、有趣的语言,许多程序员发现它的表现力和力量。
为此产生的 Go 特性包括:
-
清晰的依赖关系。
-
清晰的语法。
-
清晰的语义。
-
相对于继承的组合。
-
编程模型提供的简单性(垃圾收集、并发)。
-
简单的工具(Go工具、gofmt、godoc、gofix)。
这就是为什么要开发 Go 的由来,以及为什么会产生如此的设计和特性的原因。
参考
-
翻译、修整《Go at Google: Language Design in the Service of Software Engineering》
参考链接:https://baijiahao.baidu.com/s?id=1722260361892643204&wfr=spider&for=pc