golang快速入门[1]-go语言导论

golang快速入门[1]-go语言导论

声明

  • 这是一套帮助初学者从0到1学习go语言的开源教程,致力于打造最完整、最强悍、最有深度的Go语言学习体系html

  • 我但愿这套课程可以涵盖Go语言的全部体系、并致力于用大量的案例来诠释其用法前端

  • 鉴于做者水平有限,真诚地但愿可以集全部人的智慧,完善此项目,连接附后python

简介

  • Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具备垃圾回收功能的编程语言git

  • Go的最初目标是消除Google软件开发的缓慢性和笨拙性,从而使流程更具效率和可扩展性,更多的关注于软件工程领域程序员

  • Go致力于解决当代大型工程项目面临的多核处理,网络系统,海量计算集群、快速构建等问题,Go在语言级别考虑并发问题,提供简单高效的并发编程github

  • 罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pike)及肯·汤普逊(Ken Thompson)于2007年9月开始设计Go,稍后Ian Lance Taylor、Russ Cox加入项目golang

  • Go是基于Inferno操做系统所开发的算法

  • Go于2009年11月正式宣布推出,成为开放源代码项目,支持Linux、macOS、Windows等操做系统docker

  • 在2016年,Go被软件评价公司TIOBE 选为“TIOBE 2016 年最佳语言”数据库

  • 不少重要的开源项目都是使用Go语言开发的,其中包括 Docker、Go-Ethereum、Thrraform、Kubernetes、etcd、hyperledger、tidb

基本语言的历史

  • 1960年 Ken Thompson(肯.汤普森) 发明了B语言

  • 1972年 Dennis Ritchie(丹尼斯·里奇)发明了C语言

  • 1982年 Bjarne Stroustrup(本贾尼)发明了C++语言

  • 1989年 Guido von Rossum 发明了Python语言

  • 1995年SUN公司发明了Java语言

  • 2007年Go语言诞生

  • 2009年的11月对外正式发布

Go语言创始人

对语言进行评估时,明白设计者的动机以及语言要解决的问题很重要。Go语言出自 Ken Thompson 和 Rob Pike、Robert Griesemer 之手,他们都是计算机科学领域的重量级人物。

  • Ken Thompson
    贝尔实验室 Unix 团队成员,C语言、Unix 和 Plan 9 的创始人之一,在 20 世纪 70 年代,设计并实现了最初的 UNIX 操做系统,仅从这一点说,他对计算机科学的贡献怎么强调都不过度。他还与 Rob Pike 合做设计了 UTF-8 编码方案

  • Rob Pike
    Go语言项目总负责人,贝尔实验室 Unix 团队成员,除帮助设计 UTF-8 外,还帮助开发了分布式多用户操做系统 Plan 九、Inferno 操做系统和 Limbo 编程语言,并与人合著了《The Unix Programming Environment》,对 UNIX 的设计理念作了正统的阐述

  • Robert Griesemer
    就任于 Google,参与开发 Java HotSpot 虚拟机,对语言设计有深刻的认识,并负责 Chrome 浏览器和 Node.js 使用的 Google V8 JavaScript 引擎的代码生成部分

go语言的继承

  • Go语言有时候被描述为“C相似语言”,或者是“21世纪的C语言”

  • Go从C语言继承了类似的表达式语法、控制流结构、基础数据类型、调用参数传值、指针等思想

  • Go继承了C语言一直所看中的编译后机器码的运行效率以及和现有操做系统的无缝适配

  • Go语言的家族树中还有其它的祖先。其中一个有影响力的分支来自Niklaus Wirth所设计的Pascal语言

  • Modula-2语言激发了包的概念,而后Oberon语言摒弃了模块接口文件和模块实现文件之间的区别。第二代的Oberon-2语言直接影响了包的导入和声明的语法,还有Oberon语言的面向对象特性所提供的方法的声明语法等

  • Go语言的另外一支祖先,带来了Go语言区别其余语言的重要特性,灵感来自于贝尔实验室的Tony Hoare于1978年发表的鲜为外界所知的关于并发研究的基础文献顺序通讯进程(communicating sequential processes,缩写为CSP)

    • 在CSP中,程序是一组中间没有共享状态的平行运行的处理过程,它们之间使用管道进行通讯和控制同步。不过Tony Hoare的CSP只是一个用于描述并发性基本概念的描述语言,并非一个能够编写可执行程序的通用编程语言

    • Rob Pike和其余人开始不断尝试将CSP引入实际的编程语言中。他们第一次尝试引入CSP特性的编程语言叫Squeak,是一个提供鼠标和键盘事件处理的编程语言,它的管道是静态建立的

    • 而后是改进版的Newsqueak语言,提供了相似C语言语句和表达式的语法和相似Pascal语言的推导语法。Newsqueak是一个带垃圾回收的纯函数式语言,它再次针对键盘、鼠标和窗口事件管理。在Newsqueak语言中管道是动态建立的,属于第一等公民,能够保存到变量中

    • 在Plan9操做系统中,这些优秀的想法被吸取到了一个叫Alef的编程语言中。Alef试图将Newsqueak语言改造为系统编程语言,可是由于缺乏垃圾回收机制而致使并发编程很痛苦

    • 注:在Aelf以后还有一个叫Limbo的编程语言,Go语言从其中借鉴了不少特性。具体请参考Pike的讲稿:talks.golang.org/2012/c


  • Go语言的其余的一些特性零散地来自于其余一些编程语言;好比iota语法是从APL语言借鉴,词法做用域与嵌套函数来自于Scheme语言和其余不少语言

  • Go中也有不少创新的设计,好比Go语言的切片为动态数组提供了有效的随机存取的性能,还有Go语言新发明的defer语句

go语言的特色

全部的编程语言都反映了语言设计者对编程哲学的反思,一般包括以前的语言所暴露的一些不足地方的改进。

  • 简洁

    • Go项目是在Google公司维护超级复杂的几个软件系统遇到的一些问题的反思(可是这类问题毫不是Google公司所特有的)

    • 正如Rob Pike所说,“软件的复杂性是乘法级相关的”,经过增长一个部分的复杂性来修复问题一般将慢慢地增长其余部分的复杂性

    • 经过增长功能、选项、配置是修复问题的最快的途径,可是这很容易让人忘记简洁的内涵,卽使从长远来看,简洁依然是好软件的关键因素

    • 简洁的设计须要在工做开始的时候舍弃没必要要的想法,而且在软件的生命周期内严格区别好的改变或坏的改变。经过足够的努力,一个好的改变能够在不破坏原有完整概念的前提下保持自适应

    • 而一个坏的改变则不能达到这个效果,它们仅仅是经过肤浅的和简单的妥协来破坏原有设计的一致性。只有经过简洁的设计,才能让一个系统保持稳定、安全和持续的进化

    • 附带了相关的工具和标准库

    • 没有隐式的数值转换

    • 没有构造函数和析构函数

    • 没有运算符重载

    • 没有默认参数

    • 没有继承

    • 没有泛型(go2中考虑加入)

    • 没有异常,即没有与错误处理相关的控制结构

    • 没有宏

    • 没有函数修饰

    • 没有线程局部存储。

    • 没有指针运算

    • 没有类型别名

    • 数组边界老是受到检查


  • 基本特性

    • 自动垃圾回收

    • 包管理

    • 函数做为一等公民

    • 系统调用接口

    • 只读的UTF8字符串

    • 函数多返回值

    • 匿名函数和闭包

    • 反射

    • 静态连接

    • 严格的依赖规范

    • CSP并发编程

    • Goroutine协程

    • 接口类型


  • 向后兼容

    • Go语言自己是成熟和稳定的,并且承诺保证向后兼容:用以前的Go语言编写程序能够用新版本的Go语言编译器和标准库直接构建而不须要修改代码


  • 类型系统

    • 相比较于js、python,Go语言的类型系统避免动态语言中那些粗心的类型错误。可是Go语言的类型系统相比传统的强类型语言又要简洁不少,虽然有时候这会致使一个“无类型”的抽象类型的概念

    • Go语言程序员并不须要像C++或Haskell程序员那样纠结于具体类型的安全属性。在实践中Go语言简洁的类型系统给了程序员带来了更多的安全性和更好的运行时性能

    • Go语言遵循当代计算机系统设计的原则,特别是局部的重要性。Go的内置数据类型和大多数的标准数据结构都通过精心设计而避免显式的初始化或隐式的构造函数,所以内存分配和内存初始化代码被隐藏在库代码中了

    • Go语言的聚合类型(结构体和数组)能够直接操做它们的元素,只须要更少的存储空间、更少的内存分配,并且指针操做比其余间接操做的语言也更有效率


  • 并发支持

    • 因为现代计算机是一个并行的机器,Go语言提供了基于CSP的并发特性支持。Go语言的动态栈使得轻量级线程goroutine的初始栈能够很小,所以建立一个goroutine的代价很小,建立百万级的goroutine彻底是可行的。

    • Go并发的座右铭:不要经过共享内存进行通讯,而要经过通讯共享内存(Don't communicate by sharing memory, share memory by communicating)


  • 自动垃圾回收机制

    • 对于系统语言,垃圾回收多是一个有争议的功能

    • Go没有显式的内存释放操做:分配的内存返回池的惟一方法是经过垃圾回收器。

    • 内存管理对语言在实践中的工做方式具备深远的影响。在C和C++中,太多的编程工做花费在内存分配和释放上

    • 因为垃圾回收机制,语言更易于使用。

    • 垃圾回收会带来巨大的成本:常规开销,延迟和实现的复杂性

    • 知识渊博的程序员能够限制收集器所承受的压力,从而提升性能。(此外,Go安装附带了用于研究正在运行的程序的动态内存性能的良好工具)

    • 自动垃圾回收算法是一个持续跟新的过程、活跃的开发领域


  • 强大的标准库与规范

    • Go语言的标准库,提供了清晰的构建模块和公共接口,包含I/O操做、文本处理、图像、密码学、网络和分布式应用程序等,并支持许多标准化的文件格式和编解码协议

    • 库和工具使用了大量的约定来减小额外的配置和解释,从而最终简化程序的逻辑,并且每一个Go程序结构都是如此的类似,所以Go程序也很容易学习

    • Go语言自带工具构建Go语言项目只须要使用文件名、标识符名称以及少许的注释肯定全部的库、可执行文件、测试、基准测试、案例、以及特定于平台的变量、项目的文档等;Go语言源代码自己就包含了构建规范


  • 开源,活跃的社区

  • 组成而不是继承

    • Go采用一种不寻常的方法来进行面向对象的编程(接口),它容许有相同方法的任何类型继承,而不只是类

    • Go没有任何形式的基于类型的继承,这意味着没有类型层次结构

    • 这是一个故意的设计选择,尽管类型层次结构已用于构建许多成功的软件,但Go认为该模型已被过分使用


Go语言的优点

  • 学习曲线容易,语法简单清晰

    • 单就类型和规则而言,Go 与 C9九、C11 类似之处颇多,这也是Go语言被冠以“NextC”名号的重要缘由。

    • Go语言的语法规则严谨,没有歧义,更没什么黑魔法变异用法。

    • 任何人写出的代码都基本一致,这使得Go语言简单易学。放弃部分“灵活”和“自由”,换来更好的维护性


  • 强大的标准库和工具链

    • 完整的工具链对于平常开发极为重要。Go 在此作得至关不错,不管是编译、格式化、错误检查、帮助文档,仍是第三方包下载、更新都有对应的工具

    • 内置完整测试框架,其中包括单元测试、性能测试、代码覆盖率、数据竞争,以及用来调优的 pprof,这些都是保障代码能正确而稳定运行的必备利器

    • 可经过环境变量输出运行时监控信息,尤为是垃圾回收和并发调度跟踪,可进一步帮助咱们改进算法,得到更佳的运行期表现


  • 自动垃圾回收机制

    • 垃圾回收一直是个难题。早年间,Java 就因垃圾回收低效被嘲笑了许久,后来 Sun 连续收纳了好多人和技术才发展到今天。可即使如此,在 Hadoop 等大内存应用场景下,垃圾回收依旧捉襟见肘、寸步难行

    • 相比 Java,Go 面临的困难要更多。因指针的存在,因此回收内存不能作收缩处理。幸亏,指针运算被阻止,不然要作到精确回收都难

    • 每次升级,垃圾回收器必然是核心组件里修改最多的部分。从并发清理,到下降 STW 时间,直到 Go 的 1.5 版本实现并发标记,逐步引入三色标记和写屏障等等,都是为了能让垃圾回收在不影响用户逻辑的状况下更好地工做


  • 静态连接
    运行时、依赖库直接打包到可执行文件内部,简化了部署和发布操做,无须事先安装运行环境和下载诸多第三方库

  • 编译迅速

  • 清晰的依赖关系

  • 并发编程

    • 在早期 CPU 都是以单核的形式顺序执行机器指令。Go语言的祖先C语言正是这种顺序编程语言的表明

    • 随着处理器技术的发展,单核时代以提高处理器频率来提升运行效率的方式遇到了瓶颈,单核 CPU 发展的停滞,给多核 CPU 的发展带来了机遇

    • 现代计算机都拥有多个核,可是大部分编程语言都没有有效的工具让程序能够轻易利用这些资源。编程时须要写大量的线程同步代码来利用多个核,很容易致使错误

    • Go语言正是在多核和网络化的时代背景下诞生的原生支持并发的编程语言。Go语言从底层原生支持并发,无须第三方库,开发人员能够很轻松地在编写程序时决定怎么使用 CPU 资源

    • Goroutine 是 Go 最显著的特征

    • Go语言的并发是基于 goroutine 的,goroutine 相似于线程,但并不是线程。能够将 goroutine 理解为一种虚拟线程。Go语言运行时会参与调度 goroutine,并将 goroutine 合理地分配到每一个 CPU 中,最大限度地使用 CPU 性能

    • Go用类协程的方式来处理并发单元,却又在运行时层面作了更深度的优化处理。这使得语法上的并发编程变得极为容易

    • 无须处理回调,无须关注线程切换,仅一个关键字,简单而天然

    • 搭配 channel,实现 CSP 模型。将并发单元间的数据耦合拆解开来,各司其职,这对全部纠结于内存共享、锁粒度的开发人员都是一个可期盼的解脱


  • 内存分配

    • Go 选择了 tcmalloc,它本就是为并发而设计的高性能内存分配组件

    • 刨去因配合垃圾回收器而修改的内容,内存分配器完整保留了 tcmalloc 的原始架构。使用 cache 为当前执行线程提供无锁分配,多个 central 在不一样线程间平衡内存单元复用

    • heap 则管理着大块内存,用以切分红不一样等级的复用内存块。快速分配和二级内存平衡机制,让内存分配器能优秀地完成高压力下的内存管理任务


Go语言擅长的领域

  • Go语言主要用做服务器端开发,适合于多人周期较长的大型软件和支持云计算的网络服务

  • 在服务器编程方面,Go语言适合处理日志、中间件、数据打包、虚拟机处理、文件系统、分布式系统、数据库代理等

  • 网络编程方面,Go语言普遍应用于 Web 应用、API 应用、下载应用等

  • 此外,Go语言还可用于内存数据库和云平台领域,目前国外不少云平台都是采用 Go 开发

  • 因为Go垃圾回收牺牲了一些性能,所以其不适合作操做系统编程以及对速度要求极致的程序,不适合直接处理数据分析与计算

使用Go语言的公司

参见世界上使用Go语言的企业

  • Google

    • 做为创造了Go语言的 google 公司,固然会力挺Go语言了。Google 有不少基于 Go 开发的开源项目,好比 kubernets,docker,你们能够参考《哪些项目使用Go语言开发》一节了解更多的Go语言开源项目


  • Facebook

    • Facebook 也在使用Go语言,为此他们还专门在 Github 上创建了一个开源组织 facebookgo。你们能够经过 github.com/facebookgo 访问查看 facebook 开源的项目,其中最具表明性的就是著名平滑重启工具 grace


  • 腾讯

    • 腾讯在 15 年就已经作了 Docker 万台规模的实践。由于腾讯主要的开发语言是 C/C++ ,因此在使用Go语言方面会方便不少,也有不少优点,不过日积月累的 C/C++ 代码很难改造,也不敢动,因此主要在新业务上尝试使用 Go


  • 百度

    • 百度主要在运维方面使用到了Go语言,好比百度运维的一个 BFE 项目,主要负责前端流量的接入,其次就是百度消息通信系统的服务器端也使用到了Go语言


  • 七牛云

    • 七牛云算是国内第一家选Go语言作服务端的公司。早在 2011 年,当Go语言的语法还没彻底稳定下来的状况下,七牛云就已经选择将 Go 做为存储服务端的主体语言


  • 京东

    • 京东云消息推送系统、云存储,以及京东商城的列表页等都是使用Go语言开发的


  • 小米

    • 小米对Go语言的支持,在于运维监控系统的开源,它的官方网址是 open-falcon.org/。此外,小米互娱、小米商城、小米视频、小米生态链等团队都在使用Go语言


  • 360

    • 360 对Go语言的使用也很多,好比开源的日志搜索系统 Poseidon,你们能够经过 github.com/Qihoo360/pos 查看,还有 360 的推送团队也在使用Go语言
      除了上面提到的,还有不少公司开始尝试使用Go语言,好比美团、滴滴、新浪等。


Go语言吉祥物

Go语言有一个吉祥物,在会议、文档页面和博文中,大多会包含下图所示的 Go Gopher,这是才华横溢的插画家 Renee French 设计的,她也是 Go 设计者之一 Rob Pike 的妻子。

v2-b47ef94e67ff0c63e00a7dabe13a3970_hd.jpeg

参考资料

相关文章
相关标签/搜索