标签 编译器 下的文章

Go团队:Go是什么

本文永久链接 – https://tonybai.com/2024/05/19/what-the-go-team-think-go-is

2024年的Google I/O大会如期而至。

这届大会的核心主旨毫无疑问是坚定不移的以AI为中心:Google先是发布了上下文长度将达到惊人的200万token的Gemini 1.5 Pro,然后面对OpenAI GPT-4o的挑衅,谷歌在大会上直接甩出大杀器Project Astra,视觉识别和语音交互效果,跟OpenAI的GPT-4o不相上下;接着,谷歌又祭出文生视频模型Veo硬刚Sora,效果酷炫,时长超过1分钟,打破Sora纪录。最后Google CEO劈柴宣布:谷歌搜索将被Gemini重塑,形态从此彻底改变!用户不再需要自己点进搜索结果,而是由多步骤推理的AI Overview来代办一切。

不过,除了AI之外,Google在移动、Web和Cloud几个平台方面也为开发者带来了诸多精彩的内容,这其中就包括由Google Cloud团队带来的“Profile-guided optimization with Go”的演讲:

注:目前,Go团队已归入Google Cloud团队管理。

该演讲由Cameron Balahan、Michael Pratt和James Ma三个人共同完成。其中长相颇似电影“源代码”主角杰克·吉伦哈尔的Cameron Balahan在演讲中首先登场,阐述了Go团队眼中的Go究竟是什么

2022年,美国计算机学会通讯(Communications of the ACM)期刊2022年5月第65卷第5期将发表了一篇有关Go语言的综述类Paper:《Go编程语言与环境》,这篇文章由Russ Cox,Robert Griesemer,Rob Pike,Ian Lance Taylor和Ken Thompson等Go团队的大佬联合撰写,对10多年来Go演化发展进行了复盘,深入分析了那些对Go的成功最具决定性的设计哲学与决策,这算是Go团队第一次阐述Go究竟是什么。

而Cameron Balahan这次的演讲算是Go团队加入Google Cloud后对Go未来定位和演进上的一次说明,虽然简短,但对Gopher们也极具参考意义。在这篇文章中,我们就来看看Cameron Balahan所代表的的Go团队对Go语言的观点。

Go是构建生产系统的高效平台

Go团队认为的第一点,也可能是最重要的一点是:Go不仅仅是一种编程语言,它是一个完整的端到端构建生产系统的平台。这一直都是Go团队的愿景。Go从一开始就是为了在规模化的实际软件工程中提供便利。并且,Go团队在Google内部将该愿景简化成了下面幻灯片中的使命陈述:Go提供了构建生产系统的最高效平台。

说Go很高效(Go is productive),是因为Go易于学习和维护,并且可以在团队之间扩展(scale)。

说Go是一个平台(Go is a platform),是因为它不仅仅是一种语言,它是一种端到端的开发者体验,包括IDE集成,构建和部署工具,监控工具,运行时工具,漏洞扫描等等,这些都是开箱即用的。

说Go是生产就绪的(Go is production ready ),是因为它可靠(reliable)、高效(efficient)、稳定(stable)和安全(secure),这就是为什么大家会在企业中看到它的身影的原因,尤其是在关键业务系统和基础设施中,遍布整个云计算领域。实际上,这也是现代云计算本身建立在Go之上的原因。这并不仅仅指Google Cloud,我指的是所有主要的云服务提供商以及所有其他主要的参与者以及云工具和技术。

Go的无限双循环

无限双循环是一个很好的思考更广泛的软件开发生命周期的方式。左边的循环是内部开发循环,也就是大家编写代码的地方。你迭代地很快,寻求快速反馈和高效率。而右边的循环可以看作是外部循环,你已经部署了你的代码到生产中,你要监控和操作它。

因此,当Go团队将Go作为一个平台来考虑时,他们将考虑如何端到端地解决这整个过程,包括内部和外部循环。Cameron下面基于这个循环从developer velocity(开发人员效率)、security(安全)和performance(性能)等方面分别举一些Go如何解决这些问题的例子。

developer velocity(开发人员效率)

Go有一些旨在为了最大化你团队的开发人员效率的语言特性、工具和库。包括了从编写代码到将其推送到生产,再到之后可靠运维的整个过程。

Go团队提供IDE集成,包括为Visual Studio Code开发的插件,使其能够轻松利用其余工具链的特性。Go还提供了强大的并发模型,通过Goroutine实现。Go有内置的格式化工具、内置的测试框架和内置的调试器。Go编译器本身构建静态独立二进制文件,不依赖任何系统范围的依赖项或单独的运行时,这使得部署比其他语言更容易、更安全、更快。这是一种端到端的解决方案,用于获取和维护开发人员效率。

security(安全)

Go在安全性方面是领先者,这一点Go也是端到端解决的。如果你在关注最新的XZ软件供应链攻击新闻,你就会知道这是多么重要,也许比以往任何时候都更重要。这是Go团队非常重视的一个领域,因为他们已经看到在其他语言生态系统中,当一个流行的依赖项被破坏时会发生什么。

由于Go被用于云中所有这些关键基础设施,Go团队认识到安全性是Go应该提供的最重要的功能之一。从依赖管理系统开始,Go先后有了Go Module Mirror、Checksum Database和pkg.go.dev网站,它们都会警告你所依赖的库是否被篡改或遭受已知漏洞。

此外,Go的IDE集成很深入。如果你使用Go的VS Code插件,你会在IDE中就收到关于依赖项中的漏洞警告,包括你是否实际上从代码中调用了这些漏洞。这样,在真正依赖它们进入生产环境之前,你就知道了依赖项的安全态势。Go也是唯一一种将模糊测试内置并集成到其工具链中的主流语言。模糊测试就像一种自动化的测试类型,它会智能地操纵你程序的输入,以找出bug和漏洞。

最后,Go有兼容性承诺,从Go 1.0开始就确保没有破坏性更改。这意味着升级很容易,这使保持最新的安全修复变得容易,跟上增强功能也很容易。去年在Go 1.21中,Go团队在此基础上增加了向前和向后兼容性特性。Go团队确实将兼容性视为不仅仅是一种便利,更是一种关键的安全特性。

performance(性能)

Go的标准库功能丰富且健壮,并针对性能进行了优化。你可以真正构建任何东西,而无需导入一些重型库或框架。Go还有一个自我调优的垃圾收集器。如果你曾经花时间为Java调优垃圾收集器,你就会知道这简直就像是一份全职工作。它可能需要耗费的时间和你最初编写代码一样长。在Go中,垃圾收集器开箱即用,运行高效,并会自动调整以适应你的工作负载需求。 当然,还有Profile Guided Optimization(PGO),使用过PGO的开发者都很喜欢它。有些开发者甚至已经看到了令人印象深刻的性能提升。

开箱即用(out of the box)

图片中所有这些特性都符合开箱即用的端到端解决方案这一框架,正是这使Go成为构建生产系统最高效的平台。

Go团队在做所有这些的同时,也获得了来自用户的非常出色的反馈。大部分Go用户真的很喜欢Go。我们在调查中一直看到这一点,客户满意度水平(93%)实际上在业内是罕见的。

Go特性与客户价值定位

第一行可视为与生产力相关的内容。Go支持快速入门、快速迭代、快速构建真正可扩展的生产应用程序。所有这些都转化为你更快获得价值。

第二行是关于可靠性的,包括安全性、兼容性以及所有能够减少你长期维护和运维负担的内容。负担越小,你的总体拥有成本就越低,你就有更多时间和资源专注于推动业务增长的新事物。

第三行是关于云的。Go就像是为云量身定制的一样。Go启用的库、集成和架构都是为云而设计的,而不是后来才重新调整以适应云。因此,你将比使用其他语言时能更快更轻松地实现云的优势。

最后,Go用户是快乐的。他们无论在哪里都很开心。而且在Google Cloud上,他们尤其开心。每个人都喜欢开心的开发人员和运维人员。

小结

Google I/O 2024大会上Go团队代表对Go语言及其在软件工程领域的定位做了新的诠释:Go不仅是一种编程语言,更是一个端到端构建生产系统的高效平台

Go团队认为Go易学易维护,可扩展,同时可靠、高效、稳定和安全,适合在企业中使用,尤其是关键业务系统和基础设施领域。

文中介绍了将Go的愿景拆解为Go的”无限双循环”的理念。其中内循环侧重开发效率,外循环侧重可靠运维。Go在开发人员效率、安全性和性能等方面都有出色的解决方案。如IDE集成、并发模型、格式化工具、测试框架、调试器、静态部署等有助提高开发效率;依赖管理、漏洞扫描、模糊测试等确保安全性;垃圾回收、编译优化等提升性能。

此外,Go兼具快速入门、快速迭代、可扩展构建、安全可靠、低运维成本、云原生设计等特性,能让客户快速获得价值、降低总拥有成本、享受云优势,获得高客户满意度。Go可视为构建现代云基础设施的理想语言。


Gopher部落知识星球在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite
  • Gopher Daily归档 – https://github.com/bigwhite/gopherdaily

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

Go 1.22中值得关注的几个变化

本文永久链接 – https://tonybai.com/2024/02/18/some-changes-in-go-1-22

美国时间2024年2月6日,正当中国人民洋溢在即将迎来龙年春节的喜庆祥和的气氛中时,Eli Bendersky代表Go团队在Go官博发文“Go 1.22 is released!”,正式向世界宣告了Go 1.22版本的发布!

注:大家可以从Go官网下载Go 1.22的第一个版本go 1.22.0,也可以在Go playground上选择Go 1.22版本在线体验Go 1.22的语法。

记忆中,这似乎是Eli Bendersky首次代表Go团队撰写Go版本发布的文章,文章短小且言简意赅,会让大家误以为Go 1.22版本没有太多的功能点变更,其实不然。读过我之前写的“Go 1.22新特性前瞻”一文的童鞋都知道Go 1.22中有很多重要且影响深远的值得我们关注的变化。在这篇文章中,我们就再来介绍一下这些变化,供大家参考。

0. 插播“旧闻”:Go再次进入Top10,并刷新有史以来的最高排名

TIOBE编程语言排行榜发布2024年2月编程语言排名的时间恰逢中国人民的传统佳节春节期间,因此它的这次排名发布“淹没”在了“龙年大吉”的喜庆气氛当中了。年后开工,大家翻看这条“旧闻”时,才发现在这次排名中,Go再一次回到Top10,位列第8名,刷新了Go打榜一来的历史最好位次。

单看这一次进入top10似乎没有什么,因为2023年4月份,Go也跻身过top10,排名第10。但如果从Go打榜以来的历史曲线来看,如下图:

我们看到了“翘尾”,我们看到了Go迈过“低谷”后的爬升!这与我在《Go语言第一课专栏》的结课语《和你一起迎接Go的黄金十年》中预判:Go即将迎来自己的黄金十年 愈来愈吻合了!

不过,我在《2023年Go语言盘点:稳中求新,稳中求变》一文中提到过TIOBE index作为世界最知名的编程语言排行榜,却存在其“不靠谱”的特性,比如这一期排名中,上古时代的编程语言Fortran从去年同期的第24位上升至第11位,仅比PHP落后一位,另一门古老的COBOL语言也从去年同期的第30位上升至第19位,仅仅比大热的Rust语言落后一位。

因此,对于TIOBE的排名,大家既要了解,也无需过于看重^_^。

言归正传,我们来说说Go 1.22版本的变化。

1. 语言变化

Go 1.22对语言语法做了两处变更,一个是Go 1.21版本中的试验特性loopvar在Go 1.22中转正落地;另一个也和for循环有关,那就是for range新增了对整型表达式的支持。两者相比较,还是第一个变化loopvar带来的影响更大一些。为什么呢?因此这是Go语言发展历史上第一次真正的填语义层面的“坑”,而且修改的是一个在Go源码中最常用的控制结构的执行语义,这很大可能会带来break change。Go101教程的作者老貘将之成为Go历史上最大的向后兼容性破坏版本

注:Go 1.21版本有一个对panic(nil)的语义修正,但我估计很少会有人写出panic(nil)这样的代码。

这次语义修改用一句话表达就是:将经典三段式for循环语句以及for range语句中的用短声明形式定义的循环变量从整个循环定义和共享一个,变为每个迭代定义一个

这里借用Go官博文章中那个例子再说明一下这个语义变化:

// go1.22-examples/lang/loopvar/main.go
package main

import (
    "fmt"
    "time"
)

func main() {
    done := make(chan bool)

    values := []string{"a", "b", "c"}
    for _, v := range values {
        go func() {
            time.Sleep(time.Second)
            fmt.Println(v)
            done <- true
        }()
    }

    // wait for all goroutines to complete before exiting
    for _ = range values {
        <-done
    }
}

我们用Go 1.22.0版本之前的版本,比如Go 1.21.0,来运行该示例:

$go run main.go
c
c
c

我们看到:由于v是整个循环中各个迭代共享的一个变量,所以在每个迭代新创建的goroutine中输出的v都是循环结束后v的最终值c。

如果我们用go 1.22.0来运行上述示例,我们将得到:

// 输出的值的顺序与goroutine调度有关
$go run main.go
b
c
a

注:关于Go 1.22版本之前的for range的坑,我的极客时间专栏《Go语言第一课》专栏有图文并茂的原理讲解,欢迎订阅阅读。

那么,loopvar这一语义填“坑”究竟会对你的代码造成怎样的影响呢?在Russ Cox关于loopvar语义变更的设计文档中提到了:只有go.mod中的go version在go 1.22.0及以后的时候才会生效,这是一个渐进式过渡的过程,因此目前无论是开源项目还是商业项目,只要go.mod中的go version还没有更新为大于等于go 1.22.0,那么for循环依然会保留短声明定义的变量的原语义,这样这些项目都不会受到影响。

不过,如果是直接在脚本中通过go run xxx.go形式运行某个go源码的,且当前工作目录以及父目录下没有go.mod文件的,go 1.22.0会采用新的loopvar语义,这点大家要注意了。

此外,当你将go.mod中的go version升级到go 1.22.0或更高版本时,也要注意语义变更可能带来的问题。在升级go version之前,可以用Go 1.22版本之前的go vet对项目源码进行一次静态分析,对于go vet提示:“loop variable v captured by func literal”的地方务必注意逐个确认。

注:Go 1.22版本中的go vet已经移除了在go version >= 1.22.0时,对“loop variable v captured by func literal”情况进行警告的功能。

关于Go 1.22中for range支持后面接整型表达式的“语法糖”新特性以及函数迭代器的实验特性,这里就不细说了,大家可以看看“Go 1.22新特性前瞻”一文中的说明。

2. 编译器、运行时与工具链

在编译器、运行时和工具链这些方面,Go 1.22的正式版本与“Go 1.22新特性前瞻”一文中使用的Go 1.22rc1版本几乎没有差异,这里挑主要内容介绍一下,其他一些内容可以参考前瞻一文。

Go 1.22版本继续在编译上优化PGO(profile-guided optimization), 基于PGO的构建可以比以前版本实现更高比例的调用去虚拟化(devirtualize)。在Go 1.22中,官⽅给出的PGO带来的性能提升数字是2%~14%,这应该是基于Google内部一些典型的Go程序测算出来的。

注:如果你对PGO优化还不是很了解,可以看看“深入理解Profile Guided Optimization(PGO)”这篇文章。

Go 1.22版本编译器现在可以更多运⽤devirtualize和inline。在Go编译器中,devirtualize是一种编译优化技术,旨在消除“虚函数”调用的开销。“虚函数”是指在面向对象编程中,通过基类指针或引用调用的函数。在Go中所谓虚函数调用指的就是通过接口类型变量进行的方法调用。由于是动态调用,基于接口的方法调用需要在运行时进行查找和分派,这可能导致一定的性能损失。

而Go编译器在进行devirtualize优化时,会尝试根据程序的上下文信息和类型信息,确定方法调用的具体对象实例。如果编译器能够确定调用的具体实例,则会将通过接口的方法调用替换为直接调用具体对象实例的方法,从而消除运行时的开销,使得通过接口类型变量进行方法调用的性能得到优化提升。

Go 1.22版本中的运行时可以使基于类型的垃圾收集的元数据更接近每个堆对象,从而将Go程序的CPU性能(延迟或吞吐量)提高了1-3%。这一变化还支持通过重复数据删除冗余元数据,进而将大多数Go程序的内存开销减少了大约1%。

在工具链方面,有三个主要改变这里提一下:

  • go work支持vendor

在Go 1.22版本中,通过go work vendor可以将workspace中的依赖放到vendor⽬录下,同时在构建时,如果workspace下有vendor⽬录,那么默认的构建是go build -mod=vendor,即基于vendor的构建。

  • go mod init不再care其他vendor工具的配置文件

go mod init不再尝试将其他vendor工具(例如Gopkg.lock )的配置文件导入到go module依赖文件(go.mod)中了,也就是说从Go 1.22版本开始,go module出现之前的那些gopath时代的依赖管理工具正式退出并成为历史了。

  • 改进go test -cover的输出

对于没有自己的测试文件的包,go test -cover在go 1.22版本之前会输出:

? mymod/mypack [no test files]

但在Go 1.22版本之后,会报告覆盖率为0.0%:

mymod/mypack coverage: 0.0% of statements

3. 标准库

这里列举一下标准库值得关注的重大变化,大家可以与前瞻一文相互参考着阅读。

3.1 math/rand/v2:标准库的第一个v2版本包

Go 1.22中新增了math/rand/v2包,这里之所以将它列为Go 1.22版本标准库的⼀次重要变化,是因为这是标准库第一次为某个包建⽴v2版本,按照Russ Cox的说法,这次math/rand/v2包的创建,算是为标准库中的其他可能的v2包“探探路”,找找落地路径。关于math/rand/v2包相对于原math/rand包的变化有很多,具体可以参考issue 61716中的设计与讨论。

3.2 增强http.ServeMux表达能力

在Go 1.22版本中,http.ServeMux的表达能力得到了大幅提升,从原先只支持静态路由,到新版本中支持如下一些特性:

  • “/index.html”路由将匹配任何主机和方法的路径”/index.html”;
  • “GET /static/”将匹配路径以”/static/”开头的GET请求;
  • “example.com/”可以与任何指向主机为”example.com”的请求匹配;
  • “example.com/{$}”会匹配主机为”example.com”、路径为”/”的请求,即”example.com/”;
  • “/b/{bucket}/o/{objectname…}”匹配第一段为”b”、第三段为”o”的路径。名称”bucket”表示第二段,”objectname”表示路径的其余部分。

并且新版ServeMux在路由匹配性能方面也不输众多开源http路由框架太多,后续建立Go web或api类新项目时,可以考虑首选新版ServeMux来进行路由匹配了,减少对外部的一个依赖。

关于新版http.ServeMux的具体使用方法,其作者Jonathan Amsterdam(也是log/slog的作者)在官博发表了一篇名为“Routing Enhancements for Go 1.22”的文章,大家可以详细参考。

关于标准库的其他一些变化,大家可以参考前瞻一文以及更详细的Go 1.22的发布说明文档

4. 小结

综上,Go 1.22版本对语言、编译器、工具链、运行时和标准库都有一定程度的改进和创新,遗留代码通过Go 1.22版本的重新编译便可以得到一定程度的性能上的自然提升,这也体现了Go语言在稳中求新、稳中求变的特点。

不过这里还要提醒各位Go开发者,在升级Go 1.22版本时务必注意潜在的向后兼容性问题,尤其是loopvar语义带来的变化影响。

本文涉及的源码可以在这里下载。


Gopher部落知识星球在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite
  • Gopher Daily归档 – https://github.com/bigwhite/gopherdaily

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats