本篇是语言教学的“传统项目”。每个写go语言教学的人,都会介绍它的发展历程,应用领域,优缺点和特点来介绍自己的理由。当然如果你有自己的理解,那就更好了,欢迎讨论!

全景简介

go语言由google公司开源的用于提高程序员编程效率的编程语言。它是一门简单易学,静态编译,原生并发以及向后兼容性的高效快捷的轻量级语言。

发展历程

目前go语言每半年会迭代一个新版本,从2012年的go1.0开始,已经历经21个版本,目前已经到了go1.20,从2015年开始进入快速发展期,以用于大型项目的工程语言进入人们的视野。

go语言在go1.1-g1.4时还不具备工程化的条件,但在go1.5时开始具备工程化的条件,这是因为(1)在go1.5之前的版本golang采用的是c语言编译器,(2)gc的STW时间会很长,(3)第三方包没有合理的存放位置。

而在go1.5版本开始实现go语言自举,在这个版本里开始采用三色标记法,这使得golang的gc时间大幅下降,经过go1.6-go1.7的改进,使得golang的STW时间大幅缩短,另外在这个版本开始实验vender机制。

这三个特性的加入使得golang在2015年之后开始火爆的原因,在go1.7正式使用vender机制,在go1.9版本STW时间缩短至100us以内,为此golang在go1.9版本已经完全具备工程化的条件。

之后golang在go1.11版本开始实验go mod机制以替换vender机制,在go1.13正式引入go mod机制,彻底解决了第三方库的版本问题,在go1.18版本中实验golang的泛型特性,而在go1.20版本中正式引入golang的泛型特性。


应用场景

go语言用于云原生开发,命令行接口,网站开发,运维开发领域以及存储开发。注意我这里介绍go语言的应用场景来自go语言官网实际上,你会发现go语言还能应用于其他领域,如数字货币(以太坊),物联网等等(因为我不熟悉这些领域,所以我可以假装不知道吗?)

云和网络服务

随着docker和kubernetes等杀手级应用的出现和发展,golang逐渐成为云和网络服务领域中举足轻重的语言,目前由超过75%的云原生计算基金项目都是使用go语言开发的。


命令行接口

对于命令行接口应用,go语言能够将其快速地构建成二进制程序,提供跨平台工作的开发方式以及强大的社区支持。我们可以在windows或者mac上开发或者调试,在Linux上编译部署。它通过静态编译构建的二进制程序即插即用,几乎不需要任何其他依赖。


例如,hub是github推出的用于辅助git的命令行工具,它是用go语言编写的。另外如greenplum的gpbackup和gprestore也是用go语言编写的。


网站

go语言不仅天生支持高并发,能以极小的开销约4K的内存启动一个携程goroutine,而且go语言的标准库对于web开发的强大支持,能让业务人员专注于业务开发,这些使得go语言在网站开发方面占有一席之地。

注意go语言其实已经有gin以及beego这样成熟的web框架,甚至有人已经将gin,vue3结合起来gin-vue-admin这样的项目。我的建议是如果你写的web服务很简单,那么go语言标准库基本已经够用,否则请选择上述框架。


运维

go语言在运维开发编写脚本时拥有大量优秀的标准库支持。另外,go语言还提供了丰富的工具链帮助用于编写高效、健壮以及可维护性强的程序。


目前在运维开发领域,使用go语言开发优秀的项目有类似于zabbix的Prometheus,将运维数据可视化的grafana,用于容器CI/CD的Docker CI/CD等等


存储

go语言是带有gc,高性能并且高并发的特点,为此在存储领域也有比较好的发展。例如分布式数据库tidb(sql层使用go语言开发)、时序性数据库influxdb、分布式kv存储etcd以及分布式消息队列nsq都是其中的佼佼者。


优点

简单易学

sum := 0
for i := 0; i < 30; i ++ {
if i % 2 == 0 {
sum += i
}
}
fmt.Println(sum)

go语言许多语法和C语言很相似,学习难度和python类似,学习成本较低,大约1-2周初学者就能开发一些实用的小程序。当然如果你学过C语言,你将更快入门go语言


即插即用

go语言采用静态编译的方式,产生出的二进制程序即插即用,几乎无需其他依赖。

原生并发

c := make(chan int)
go func() {
for {
select {
case e, ok := <-c:
if !ok {
return
}
fmt.Println(e)
}
}
}() a := []int{5,2,4,3,1}
for _, v := range a {
c <- v
}
close(c)

go语言可以很容易地实现并发编程,通过保留字go即可实现,使用chan实现携程间通信,你可以认为chan是一个加锁的队列或者消息管道。

如上,代码通过保留字go调用匿名函数启动了一个携程,并且通过chan向这个携程传值。

注意:chan的传入并非是全局变量而是因为go语言匿名函数的闭包特性。


社区支持

go语言虽然历经时间不多,但是它的社区支持极为强大,如上go语言目前支持常用数据库的访问。

向后兼容性承诺

使用go语言编写的代码会被其之后版本的go语言兼容,例如你用go语言1.8写了代码,那么几乎不用做出任何更改在go语言1.17中直接编译使用。这就意味着通过这个承诺,你几乎无需修改代码就能让go语言代码享受新版本带来的性能提升。

强大的标准库以及丰富的工具链

优秀的编译运行速度

go语言不仅有着c/c++,java等传统编译语言无法企及的编译速度,又有类似于c/c++的运行速度,这些让程序员有更好的编程体验。当然据说这是Google公司的阴谋,让程序员有“更多时间工作”。


缺点

  • go语言对GUI用户界面支持不够完善,需要额外的qt库支持或者采用wasm技术。
  • go语言对机器学习方面支持不够完善,存在神经网络和go语言对应库对接成本。
  • go语言不支持aix7.2以下的aix操作系统,这是由于go语言底层有少量通过汇编写成,对硬件有部分要求。
  • go语言对移动端app开发支持不够完善,在api使用上存在限制。
  • gol语言缺乏对传统异常捕获机制的支持,需要通过大量的if语句去判定其是否有有异常。

特点

这是相较于c/c++ ,java,javascript以及python等主流语言不一样的地方,不算是优点也不算是缺点的语言特性


多返回值

由于基本上目前的主流语言的函数都是单返回值,而golang为了使错误能够被返回,采用了含有多返回值的函数,如下:

func Write(data []byte) (n int, err error)

还有表达式中也可以使用多返回值,例如交换a,b可以写成

a:= 1
b:= 2
a,b = b,a

还有前面提到的

for _, v := range a {
c <- v
}

以及

select {
case e, ok := <-c:
if !ok {
return
}
fmt.Println(e)
}

公有私有

golang并非通过指定关键字private和public去实现面向对象的封装特性,而是通过大小写去指定成员是否公有和私有,在下述代码中,writer包外的只能访问公有的成员变量,函数,或者方法。

package writer
import (
"os"
) var (
OsType = "Linux" //公有变量
osType = "linux" //私有变量
) type FileWriter struct {
Filename string //共有成员变量
f * os.file //私有成员变量
} //公有函数
func NewFileWriter(filename string) (*FileWriter, error){
return newFileWriter(filename)
}
//私有函数
func newFileWriter(filename string) (fw *FileWriter, err error){
fw = &FileWriter{
Filename:filename,
}
err = fw.createFile()
return
} //公有方法
func (w *FileWriter) Write(data []byte) (n int, err error){
return w.f.Write(data)
} //公有方法
func (w *FileWriter) Close() (err error){
return w.f.Close()
} //私有方法
func (w *FileWriter) createFile() (err error){
w.f, err = os.Create(w.Filename)
if err != nil{
return err
}
return
}

面向接口

golang由于采用了静态编译的方式,使得golang无法在运行时加载,为此它使用组合而没有继承,使用面向接口来实现面向对象的多态特性,这样更容易写出高内聚低耦合的代码。

例如我们定义一个接口

type Writer interface {
Write(data []byte) (n int, err error)
}

然后上述代码中的FileWriter已经实现该接口

type FileWriter struct {
filename string
f * os.file
} func (w *FileWriter) Write(data []byte) (n int, err error){
return w.f.Write(data)
}

网络同步编程

网络编程往往如下图采用异步回调的方式去完成事件处理。

但是在golang中网络编程可以使用同步模式去完成,这可能不是一个很好的例子。


func HandleConn(conn net.Conn) {
defer conn.Close()
for {
buf := make([]byte, 1024)
cnt, err := conn.Read(buf)
if err != nil {
//请处理错误
}
//处理信息
}
} func main() {
listen, err := net.Listen("tcp", ":8888")
if err != nil {
//处理错误
return
} for {
conn, err := listen.Accept()
if err != nil {
//处理错误
return
} go HandleConn(conn)
}
}

go语言全景俯瞰的更多相关文章

  1. 漫谈C语言及如何学习C语言

    抄自:http://my.oschina.net/apeng/blog/137911 目录:[ - ] 为什么要学习C语言? C语言学习方法 1,参考书籍 2,动手实验环境搭建 3,网络资源 附录 一 ...

  2. [转贴]漫谈C语言及如何学习C语言

    抄自http://my.oschina.net/apeng/blog/137911,觉得很有用,收藏它 目录:[ - ] 为什么要学习C语言? C语言学习方法 1,参考书籍 2,动手实验环境搭建 3, ...

  3. 打造H5里的“3D全景漫游”秘籍

    近来风生水起的VR虚拟现实技术,抽空想起年初完成的“星球计划”项目,总结篇文章与各位分享一下制作基于Html5的3D全景漫游秘籍. QQ物联与深圳市天文台合作,在手Q“发现新设备”-“公共设备”里,连 ...

  4. 译文 [ROM][多国语言][2015.06.11] Lenovo S750 (MTK6589) - andrea_d86-lenovos750-4.2.2

    ************************************************** andrea_d86-lenovos750-4.2.2-150530 ************** ...

  5. 俯瞰 Java 服务端开发

    原文首发于 github ,欢迎 star . Java 服务端开发是一个非常宽广的领域,要概括其全貌,即使是几本书也讲不完,该文将会提到许多的技术及工具,但不会深入去讲解,旨在以一个俯瞰的视角去探寻 ...

  6. 轩辕展览-VR虚拟展厅设计如何实现全景漫游功能

    什么是在线3d漫游?如何在VR虚拟展厅设计之中实现3d漫游功能?让我们来分享3dVR虚拟展厅的在线漫游. 实际上,在线3d漫游就是通过3d仿真场景,使用鼠标和键盘在虚拟空间之中自由漫游,它可以从高空俯 ...

  7. C语言 · 高精度加法

    问题描述 输入两个整数a和b,输出这两个整数的和.a和b都不超过100位. 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储.对于这种问题,一般使用数组来处理. 定义一个数组A ...

  8. Windows server 2012 添加中文语言包(英文转为中文)(离线)

    Windows server 2012 添加中文语言包(英文转为中文)(离线) 相关资料: 公司环境:亚马孙aws虚拟机 英文版Windows2012 中文SQL Server2012安装包,需要安装 ...

  9. iOS开发系列--Swift语言

    概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...

  10. C语言 · Anagrams问题

    问题描述 Anagrams指的是具有如下特性的两个单词:在这两个单词当中,每一个英文字母(不区分大小写)所出现的次数都是相同的.例如,"Unclear"和"Nuclear ...

随机推荐

  1. 解决VM虚拟机中IP或域名不能ping通

    c4548abb-da65-4f7d-827f-e95dca25a13d 问题 无法ping通域名, 检查事项 确定在同一个子网,能访问DNS服务器. DNS服务器正确设置了正反向解析,且DNS服务器 ...

  2. SPSS计算极值、平均值、中位数、方差、偏度、峰度、变异系数

      本文介绍基于SPSS软件的经典统计学分析与偏度.峰度等常用统计学指标的计算方法.   首先需要说明,本文所述数据的经典统计学分析,包括计算数据的极值.平均值.中位数.标准差.方差.变异系数.偏度与 ...

  3. 「微服务」这10道Consul面试题值得一看

    前言 Consul 是一种非常强大的分布式服务发现和配置管理工具,它可以帮助开发人员和运维人员更好地管理和维护分布式系统. 但是,使用 Consul 也需要投入一定的人力和物力,需要根据实际情况进行选 ...

  4. 2023-03-28:有一根长度为 n 个单位的木棍,棍上从 0 到 n 标记了若干位置。 给你一个整数数组 cuts ,其中 cuts[i] 表示你需要将棍子切开的位置, 你可以按顺序完成切割,也可

    2023-03-28:有一根长度为 n 个单位的木棍,棍上从 0 到 n 标记了若干位置. 给你一个整数数组 cuts ,其中 cuts[i] 表示你需要将棍子切开的位置, 你可以按顺序完成切割,也可 ...

  5. 2022-10-15:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。 你可以按 任意顺序 返回答案。 要求时间复杂度O(N)。 输入: nums = [1,1,1

    2022-10-15:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素. 你可以按 任意顺序 返回答案. 要求时间复杂度O(N). 输入: nums = [1,1,1 ...

  6. Windows服务程序管理器 - 开源研究系列文章

    这些天弄了一个Windows服务程序管理器,主要是对需要的Windows服务程序进行管理.这个也能够将自己开发的服务程序注册到操作系统里去运行. 1.        项目目录: 目录见下图,对代码进行 ...

  7. odoo开发教程五:高级视图

    树视图 tree视图表现出来是列表视图,列表中一行一纪录.可以根据每行纪录的某字段值不同而把每行以不同样式显示. decoration-{样式}="条件" 样式主要有: bf(fo ...

  8. 如何用ReadWriteLock实现一个通用的缓存中心?

    摘要:在并发场景中,Java SDK中提供了ReadWriteLock来满足读多写少的场景. 本文分享自华为云社区<[高并发]基于ReadWriteLock开了个一款高性能缓存>,作者:冰 ...

  9. java匿名内部类的初解

    java原生态中的匿名内部类 1.匿名内部类的定义 使用匿名内部类的两种的方法 建立父类,重写父类的方法 实现接口的方法 2.普通类的实现 1. 普通类实现 实现普通类需要先声明对一个类的对象,再调用 ...

  10. vivo 帐号服务稳定性建设之路-平台产品系列06

    作者:vivo 互联网平台产品研发团队- Shi Jianhua.Sun Song 帐号是一个核心的基础服务,对于基础服务而言稳定性就是生命线.在这篇文章中,将与大家分享我们在帐号稳定性建设方面的经验 ...