1. Go语言发展历史

Golang

1.1. Go语言核心开发团队

1983年图灵奖 TuringAward 和1998年美国国家技术奖 National Medal of Technology 得主。他与Dennis Ritchie是Unix的原创者。Thompson也发明了后来衍生出 C 语言的 B 程序语言,同时也是 C 语言的主要发明人。

Go语言项目的总负责人,曾是贝尔实验室 Bell Labs 的Unix团队,和 Plan 9 操作系统计划的成员。 他与 Thompson 共事多年,并共创出广泛使用的 UTF-8 字元编码,此人兴趣广泛,包括但不限于射箭、天文学等

曾协助制作Java的 HotSpot 编译器,和 Chrome 浏览器的 JavaScript 引擎 V8

Golang 三位创作人员

1.2. Google为什么要创建Go

历史场景

谷歌有两个巨大的问题。 其中之一是编译时间:

早在 1980 年,常规项目就需要数个小时才能完成完整的构建,对此,也有专门用于重新编译的整个服务器机房。由于这种耗费时间的编译构建都在晚上进行,这也是 nightly build 这个新名词的由来。

当然,这个”优良传统”也从上世纪八十年代保持到了 2017 年,即使用高性能的 i7 服务器从头开始编译构建 chrome 也需要 5 个小时。程序的编译构建造成了巨大的时间浪费,以至于谷歌发明了区分依赖分析和编译过程的工具,只是为了让传统的编译构建提升几个百分点。

Google 的另一个问题是 字符串处理:

Google 会读取和分析大量网页,这些网页都是文本文件。他们进行了大量的字符串操作,因此这方面的功能也是非常有必要的。谷歌在 Go 中构建了一个丰富的字符串函数库,Go语言的垃圾收集机制也使得字符串处理起来更加高效,并且在某些其他字符串库所没有的方面更加高效 暗指C++ 委员会

每个公司都认为自己是编程语言设计师。微软和苹果有自己的语言(苹果现在有两种)。谷歌当然也不能缺席。Facebook 也推出了自己的语言 ,只剩下可怜的亚马逊。

作为一种语言设计,Go 也有其存在的道理。它在任何方面都不是创新的,但肯定是为非常特定的用途而精心设计的。

因此谷歌的工程师 Robert Griesemer 、 Rob Pike 和 KenThompson 为一门新语言勾画出了一些目标:

  • 快速编译

  • 不太笨重的代码

  • 自动释放未使用的内存(垃圾收集)

  • 易于编写同事执行多个操作的软件(并发)

  • 很好的支持多核处理器

经过几年的工作,谷歌创建了Go: 一种能快速编写代码并生成程序的语言,可以 快速编译 和运行。该项目在 2009 年转向了开源许可。现在任何人都可以免费使用。Go以其简单和强大的功能而迅速流行起来。

1.4. Go语言的特点

小技巧

Go语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发维护的高效率 使用一个表达式来形容Go语言: Go = C + 字符串 + 垃圾回收 + 并发

  • 从c语言中继承了很多理念

    包括表达式语法,控制结构,基础数据类型,调用参数传值,指针等等,也保留了和C语言一样的编译执行方式及弱化的指针。

// go语言的指针使用特点
func testPtr(num *int)  {
     *num = 20
}
  • 引入包的概念

    用于组织程序结构,Go语言的一个文件都要归属于一个包,而不能单独存在

  • 垃圾回收机制

    内存自动回收,不需开发人员管理

重要

稍微不注意就会出现内存泄漏

  • 天然并发

    从语言层面支持并发,实现简单goroutine,轻量级线程,可实现大并发处理,高效利用多核。基于 CPS 并发模型 Communicating Sequential Processes实现

  • 吸收了管道通信机制

    形成go语言特有的管道 channel ,通过管道 channel ,可以实现不同的 goroute 之间的相互通信

  • 函数返回多个值

    函数可以返回零到多个值

  • 新的创新

    比如切片 slice,延时执行defer

1.5. Go 还是Golang

该语言称为 Go

golang绰号的出现是因为该网站最初是golang.org。(当时还没有*.dev*域。)不过,许多人使用 golang 名称,它作为标签很方便。例如,该语言的 Twitter 标签是“#golang”。无论如何,该语言的名称只是简单的 Go。

重要

虽然官方标志有两个大写字母,但语言名称写的是 Go,而不是 GO

1.6. Hello Go

我们写一个最简单的入门代码

package main
// fmt包中提供格式化,输入和输出的函数
import "fmt"
func main() {
     fmt.Println("hello go!")
}
hello go!

1.6.1. Golang执行流程分析

每个Go文件都以 package 子句开头

  • package是一组代码,它们都做类似的事情,比如格式化字符串

  • package 子句给出包的名称,这些文件中的代码成为包的一部分

  • 在本例中,我们使用特殊的包 main ,如果要直接(通常从终端)运行此代码,这个 main 包是必需的

接下来,Go文件几乎总是有一个或多个 import 语句

  • 每个文件都需要导入其他包,然后才能使用其他包里包含的代码

  • 一次加载计算机上的所有Go代码将导致一个大的、慢速的程序,因此你可以指定只导入需要的包

img

我们可以通过以下命令来进行操作

go build hello.go -> hello.exe
go run hello.go

go build 过程

1.6.1.1. 两种执行流程分析

  • 如果我们先编译生成了可执行文件,那么我们可以将该可执行文件拷贝到没有 go 开发环境的机器上,仍然可以运行

  • 如果我们是直接 go run go源代码,那么如果要在另外一个机器上运行,也需要 go 开发环境,否则无法执行。

  • 在编译时,编译器会将程序运行依赖的库文件包含在可执行文件中,所以,可执行文件变 了很多。

1.6.1.2. 什么是编译

  • 有了.go源文件,通过编译器将其编译成机器可以识别的二进制码文件。

  • 在该源文件目录下,通过go buildhello.go文件进行编译。可以指定生成的可执行文件名,在windows下必须是.exe后缀。

  • 如果程序没有错误,没有任何提示,会在当前目录下会出现一个可执行文件(windows下是.exe Linux下是一个可执行文件),该文件是二进制码文件,也是可以执行的程序。

  • 如果程序有错误,编译时,会在错误的那行报错。

1.7. Go语言开发注意事项

  • Go源文件以go为扩展名

  • Go应用程序的执行入口是main()方法

  • Go语言严格区分大小写。

  • Go方法由一条条语句构成,每个语句后不需要分号;(Go语言会在每行后自动加分号),这也体现出Golang的简洁性。

  • Go编译器是一行行进行编译的,因此我们一行就写一条语句,不能把多条语句写在同一个,否则报错

  • Go语言定义的变量或者import的包如果没有使用到,代码不能编译通过

  • 大括号都是成对出现的,缺一不可。

1.8. Go语言中的转义字符

GoLang常用的转义字符(escape char)

  • \t:一个制表位,实现对齐的功能

  • \n:换行符

  • \:一个\

  • \r:一个回车

1.9. Go语言的优势

部署简单

编译生成的是一个静态可执行文件,除了glibc外没有其他外部依赖。这让部署变得异常方便:目标机器上只需要一个基础的系统和必要的管理、监控工具,完全不需要操心应用所需的各种包、库的依赖关系,大大减轻了维护的负担。

编译快速

Go编译器非常惊人,它从一开始就被设计得非常快。

静态链接

Go编译器支持静态链接。 整个Go项目可以静态地链接到一个庞大的二进制文件中,它可以很容易地部署在云服务器中,而不用担心依赖关系。

并发性好

Goroutine和channel使得编写高并发的服务端软件变得相当容易,很多情况下完全不需要考虑锁机制以及由此带来的各种问题。单个Go应用也能有效的利用多个CPU核,并行执行的性能好。

良好的语言设计

从学术的角度讲Go语言其实非常平庸,不支持许多高级的语言特性;但从工程的角度讲,Go的设计是非常优秀的:规范足够简单灵活,有其他语言基础的程序员都能迅速上手。更重要的是Go 自带完善的工具链,大大提高了团队协作的一致性。

格式统一

Gofmt是用来自动格式化go的源代码。 它使用制表符进行缩进,使用空格进行对齐。 无需额外的编码规范,你写的就是源码规范。

执行性能好

虽然不如 C 和 Java,但相比于其他编程语言,其执行性能还是很好的,适合编写一些瓶颈业务,内存占用也非常省。

开源

最后但同样重要的是,Go是一个开源项目。 你可以参与和贡献到Go项目中。

1.9.1. 缺陷

package大部分都在 github上

  • 作者修改项目名称

  • 作者删库跑路

  • vendormod 迁移麻烦,很多遗留依赖问题

无泛型

  • 2.0 有计划加上 (传言)

  • interface{}可以解决该问题, 但是不易于代码阅读

没有Exception

  • 使用Error来处理异常

  • error处理不太优雅, 很多重复代码

  • 不支持动态加载代码库

1.10. Go语言的应用场景

小技巧

前面的介绍你可能知道了Go语言的优势在哪,却不知道Go语言适合用于哪些地方?Go能干什么

Go语言主要应用在以下领域

Go语言目前在云计算容器虚拟化分布式存储网络爬虫运维开发Web开发服务端开发区块链IoT等领域都有所应用

1.10.1. 几个典型的应用场景

服务端开发

以前你使用 C 或者 C++ 做的那些事情,用 Go 来做很合适,例如日志处理、文件系统、监控系统等;

爬虫及大数据

Go语言天生支持并发,所以十分适合编写分布式爬虫及大数据处理;

网络编程

大量优秀的Web框架如EchoGinIrisbeego等,而且 Go 内置的 net/http 包十分的优秀;

Paas云平台领域

KubernetesDocker Swarm等;

分布式存储领域

etcdGroupcacheTiDBCockroachdbInfluxdb等;

区块链领域

区块链里面有两个明星项目以太坊和fabric都使用Go语言;

容器虚拟化

大名鼎鼎的Docker就是使用Go语言实现的。

1.10.1.1. Go微服务开发

  • 零依赖,让我们可以更小化我们的Images,节省存储与拉取镜像的带宽

  • Runtime使用更小的内存,相对于JavaJVM而言

  • 更好的并行能力,当年需要更多的CPU的时候

  • High Performance,对比解释性语言,在处理数据方面有着巨大的优势

  • 简单,学习成本低,内部人员可以很快的转入Go阵营

  • 使用Go能更接近云原生生态,比如DockerKubernetesHarbor等都是用GoLang开发的

1.10.2. Go语言项目

1.10.2.1. Go Project

使用 Go 开发的项目列表:https://github.com/golang/go/wiki/Projects

  • Go

  • docker

  • kubernetes

  • lantern

  • etcd

  • Prometheus

  • Influxdb

  • Consul

  • nsq

  • nats

  • beego

  • ……

1.10.2.2. Go Org

使用 Go 开发的组织:http://go-lang.cat-v.org/organizations-using-go

  • 国外:Google、CloudFlare……

  • 国内:阿里、腾讯、百度、京东、爱奇艺、小米、今日头条、滴滴、美团、饿了么、360、七牛、B 站、盛大、搜狗……

1.11. 学习Golang的一些方法

img