标签 RobPike 下的文章

2022年Go语言盘点:泛型落地,无趣很好,稳定为王

本文永久链接 – https://tonybai.com/2022/12/29/the-2022-review-of-go-programming-language

早早就计划好在年前写一个Go语言年度盘点,就像2020年2021年那样。但恰逢国内疫情管控放开,一波阳了之后身体十分容易疲劳,再加上工作上的事情挺多,这篇盘点也就迟迟没能下笔。

今年的盘点思路将围绕三个关键字来展开:泛型、无趣(boring)和稳定。下面我们逐一来看看。

1. “泛型”靴子落地

2022年3月中旬,Go社区尤其是那些期盼Go加入泛型特性的Gopher终于迎来了Go 1.18版本的正式发布,这意味着Go泛型这只靴子终于落地了

其实,从Go开源那一天开始,Go核心团队就没有间断过对泛型的探索,并一直尝试寻找一个理想的泛型设计方案,但始终未能如愿。直到近几年Go团队觉得Go已经逐渐成熟,是时候下决心解决Go社区主要关注的几个问题了,包括泛型、包依赖以及错误处理等。其中泛型常年在Go官方用户调查报告的“你最想要的Go语言特性”这项调查的榜单上霸榜,下图摘自2020年度Go官方用户调查结果:

之后,Go团队安排伊恩·泰勒和罗伯特·格瑞史莫花费更多精力在泛型的设计方案上,这才有了Go 1.18 版本中泛型语法特性的落地。

个人觉得:Go泛型是Go核心团队对Go社区的一次迎合与妥协,因为泛型与Go的主要设计哲学“简单”是有悖的。泛型这个语法特性会给语言带来复杂性,这种复杂性不仅体现在语法层面上引入了难于理解和使用的新的语法元素,也体现在类型系统和运行时层面上为支持泛型进行的复杂的实现。

如果从2010年6月份,伊恩·泰勒提出的Type Functions设计方案算起,到2022年3月份的泛型落地,Go加入泛型之路足足走了近12年。不过结果还是不错的,经过近12年的努力与不断地自我否定,Go团队终于找到了一个不违背Go1兼容性承诺(见下图)泛型实现方案

从这方面讲,Go对泛型的支持又是十分成功的。在如此语法巨变的情况下,依然保持向后兼容(backforward compatibility)。

不过如果你因为Go加入了对泛型的支持就打算投入Go阵营,这里先给你一些友情提示:和支持泛型的主流编程语言之间的泛型设计与实现存在差异一样,Go的泛型与其他主流编程语言的泛型也是不同的。在学习Go泛型之前,可以先了解一下Go泛型设计方案已经明确不支持的若干特性,比如:

  • 不支持泛型特化(specialization),即不支持编写一个泛型函数针对某个具体类型的特殊版本;
  • 不支持元编程(metaprogramming),即不支持编写在编译时执行的代码来生成在运行时执行的代码;
  • 不支持操作符方法(operator method),即只能用普通的方法(method)操作类型实例(比如:getIndex(k)),而不能将操作符视为方法并自定义其实现,比如一个容器类型的下标访问 c[k];
  • 不支持变长的类型参数(type parameters);
  • … …。

这些特性如今不支持,后续大概率也不会支持。所以小伙伴们,尤其是来自Java、C++等语言阵营的小伙伴,在进入Go泛型语法学习之前,你一定要先了解Go团队的这些设计决策。

此外,目前的Go泛型实现和最后一版的泛型设计方案相比还有差距,依旧不是完全版,还有一些特性没有加入,还有问题亟待解决

就目前笔者观察来看,Go泛型还处于早期阶段,远非成熟。Go module构建模式从go 1.11版本加入到go 1.16成为默认并逐渐成熟还花了3年多时间呢,何况是Go泛型。这样来看,初步预测Go泛型要到2025年才会成熟,而成熟的标志无非如下几个:

  • 泛型语法特性确定以及稳定下来;
  • 语法问题基本都解决;
  • Go标准库开始广泛使用泛型;
  • Go泛型的运行时性能问题得到基本解决。

目前Go团队对泛型的应用依旧保持谨慎,并在循序渐进地推进泛型在Go团队与Go社区的应用,最新的消息是Go团队已经提出proposal,计划在Go 1.21版本中将用泛型实现的maps包slices包加入Go标准库,这两个包原本计划在Go 1.18版本加入,但因Rob Pike的建议先放到了golang.org/x/exp下面待定。

2. 无趣(boring)很好

和其他主流编程语言如C++、Rust等在新版本中不断有新语言特性刺激程序员的神经,让大家阶段性产生兴奋感(exciting)不同,除了早期版本(比如Go 1.1和Go 1.2)以及里程碑的Go 1.5版本的完成自举和大幅降低GC延迟、Go 1.11版本的go module构建模式、Go 1.18版本的泛型落地之外,大部分版本的发布都很难让Gopher们十分兴奋,甚至业界都称“Go is boring(Go很无趣)”

在今年的线下GopherCon大会上,Go核心团队技术Leader Russ Cox发表名为“Compatibility: How Go Programs Keep Working”的主题演讲,在这个演讲中,Russ Cox借用了Go is boring的这一说法,并称That is good!

国外新冠管控放开早,经过几波疫情后,与病毒共存了,于是2022年的GopherCon大会又重新恢复线下举办。

Russ Cox的原话是:“boring is good. boring is stable. boring means to be able to focus on your work and not ours… We’ll keep doing everything we can to keep go boring for all of you”。

这几句英文不难,相信大家都能看懂。无趣的Go意味着稳定,意味着大家将注意力都集中在自己的工作上而不是Go核心团队身上(去关注新特性)。Go语言不会像其他编程语言那样堆砌新功能特性。

Russ Cox的这一观点代表了Go核心团队,也代表着Go演进未来演进的主基调。同时,Russ明确给出结论:不会有Go2了,Go 1.xy会一直持续下去。Russ甚至提出:兼容性才是Go最重要的feature

并且Russ Cox在Go项目的discussion中也给出保持Go兼容性的backward compatibilityforward compatibility的扩展方案与一个实例

关于“Go is boring”,Russ没有进一步展开说,记得之前译过一篇名为《Go语言很无聊…其实它妙不可言!》的文章,大家可以看看那篇文章进一步体会一下“Go is boring”的含义。

3. “稳定”是主旋律

Go的稳定不仅体现在Go语法特性的演化上,Go语言在各大语言排行榜上的排名也进入了相对稳定区,以TIOBE index为例,下面是2022年12月份的排名截图:

我查了一下《2021年Go语言盘点:厉兵秣马强技能,蓄势待发新征程》一文中2022年1月份Go的排名为13名,上图中2021年12月份是19名的数据应该是错误的,相对2021年12月份,Go实际排名上升1位。

我们看到2021年Go从14升到13,今年又从13升到12。按照TIOBE官方编辑说法,在新兴编程语言中,Go是唯一一个可能在未来冲入前十的后端编程语言。

Go语言在实际应用中的表现与上述排名的变化也十分契合,总体来说就是十分稳定,国内外都波澜不惊,国内大厂该用Go的也都用了,腾讯、字节依旧是这方面的领头羊,先后开源了不少Go实现的项目,最受瞩目的应该是字节将内部的Go框架逐一开源了,包括:netpollkitex(rpc框架)hertz(http框架)等。

为了更好的帮助大家回顾这一年来Go的稳定演化,这里简单整理了2022年Go大事件列表,供大家参考:

Go社区等待了多年的泛型语法特性终于加入Go中。

从调查结果中可以看到,Gopher对Go的满意度依然高达92%;81%的受访者对Go项目的长期方向充满信心。

这篇Go语言的综述文章由Russ Cox,Robert Griesemer,Rob Pike,Ian Lance Taylor和Ken Thompson联合撰写,是Go核心团队对10多年来Go演化发展的复盘,深入分析了那些对Go的成功最具决定性的设计哲学与决策,是Go诞生十多年来最重要的一篇文章。

该文介绍了ThreadSanitizer v2的工作原理,并总结了7类数据竞争模式。

相对于Go 1.18版本而言,Go 1.19是一个“小”版本,它主要针对Go 1.18版本中泛型实现的问题做了修改和优化,引入了Soft memory limit,更新了《Go内存模型》文档。

包括sync.Pool的优化、defer性能提升、基于系统信号的抢占式调度(go 1.14)、调度器性能提升、支持基于寄存器的调用规约、soft memory limit等。

软件供应链安全问题愈发受到各界关注。Go安全团队发布Go官方安全漏洞管理的工具和方案: govulncheck。govulncheck是Go安全漏洞数据库(Go vulnerability database)的一个前端,它通过Go官方维护的vuln仓库下面的vulncheck包对你仓库中的Go源码或编译 后的Go应用可执行二进制文件进行扫描,形成源码的调用图(callgraph)和调用栈(callstack)。

  • 2022年10月,GopherCon大会在芝加哥线下举行

Russ Cox发表《Compatibility: How Go Programs Keep Working》主题演讲,确定了未来Go语言演进的主基调。

  • 2022年11月,Go开源13岁生日

Go官方回顾了2022年Go团队的工作与成果,并简单说明了在新一年的工作,包括继续努力使Go成为用于大规模软件工程的最好的环境。计划特别关注供应链安全,提高兼容性和结构化日志记录(slog),当然还会有很多其他改进,包括profile-guided optimization等。

4. Go语言2023年展望

目前Go语言的演化与发展与我在2020年Go盘点中的预测基本一致。我现在依然坚持我的判断,即我在《Go语言第一课》专栏中所说的那样:

绝大多数主流编程语言将在其诞生后的第15至第20年间大步前进。按照这个编程语言的一般规律,已经迈过开源第13个年头的Go,很可能将进入自己的黄金5-10年。2022年泛型落地就是Go语言进入黄金5-10年的起点,待2025年泛型成熟后,Go将取得更快的发展速度。

前途是美好的,但道路的曲折坎坷的。目前Go更多应用于基础设施、中间件领域和基础微服务领域,在企业级业务系统方面,类似spring这样的“全家桶”框架的缺乏和无法达成一致,让开发者在开发复杂业务系统时依旧首选Java。期待Go在这方面能所有进展。

同时,Go演进道路上还存在另外一个风险,在我的《Go为什么能成功》一文中,我曾经提到过:“Go成也Google,败也Google”。Go团队目前的治理体系太过于依赖google,这是一门双刃剑。当google发展较好时,Go语言将从中受益。但当google开始走下坡路时,Go是否还能像如今这样风光呢?让我么拭目以待吧!


“Gopher部落”知识星球旨在打造一个精品Go学习和进阶社群!高品质首发Go技术文章,“三天”首发阅读权,每年两期Go语言发展现状分析,每天提前1小时阅读到新鲜的Gopher日报,网课、技术专栏、图书内容前瞻,六小时内必答保证等满足你关于Go语言生态的所有需求!2022年,Gopher部落全面改版,将持续分享Go语言与Go应用领域的知识、技巧与实践,并增加诸多互动形式。欢迎大家加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

我爱发短信:企业级短信平台定制开发专家 https://tonybai.com/。smspush : 可部署在企业内部的定制化短信平台,三网覆盖,不惧大并发接入,可定制扩展; 短信内容你来定,不再受约束, 接口丰富,支持长短信,签名可选。2020年4月8日,中国三大电信运营商联合发布《5G消息白皮书》,51短信平台也会全新升级到“51商用消息平台”,全面支持5G RCS消息。

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

Gopher Daily(Gopher每日新闻)归档仓库 – https://github.com/bigwhite/gopherdaily

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite

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

Go为什么能成功

本文永久链接 – https://tonybai.com/2022/12/07/why-go-succeed


大家在入门Go语言时,多埋头于Go语法,忙于练手或快速完成公司的项目,无暇思考。

但当大家到了要进阶,要冲刺高级阶段的时候,我建议你不能再稀里糊涂了。既然入了Go这个坑,在进入高级阶段前,我们最好在门口的“影壁墙”前驻留一下。

仔细思考一下我们投入这么多精力研究的Go为什么能成功,后续还能否持续成功下去。你要有自己的基本的判断,自我暗示也好,坚定信心也罢,我们要为继续攀登Go高峰进行蓄能

一. 头脑风暴一下Go成功的因素

相信无论针对哪个gopher群体做头脑风暴,让大家列举Go成功的因素,大家的主流答案也无外乎下图中这些:

图中的各个因素与Go的成功都不无干系,但是究竟哪个或哪几个是决定性的呢?

二. Go成功的根本因素

很显然,这个问题是没有标准答案,是见仁见智的。这里我列举一下我的观点,供大家参考。

直接上结论,我认为Go成功的根本因素就一个:Google

为什么这么说呢?下面我们展开来看(见下图)!

我将Go社区比做一支军队,而Go就是Go社区的武器,与其他编程语言搏杀,占地盘(fans)。下面我们就来解构一下这支军队的构成以及为什么这支军队目前有诸多成功案例!

1. Google为Go社区提供了统帅与武器

众所周知,2007年Google的三名员工Robert Griesemer、Rob Pike和Ken Thompson(retire很早,精神上领袖,给予Go名誉上的背书)一起发明了Go语言,2009年Go开源后,Go社区逐渐形成。统帅是一支军队的灵魂,他们做出了影响Go和Go社区的最初的也是最重要的决策和这背后的Go设计哲学!

a) 设计决策

在2022年,Go团队在美国计算机学会通讯(Communications of the ACM)期刊上发表paper:《Go编程语言与环境》,对当年做出的诸多决策做了细致说明,这里对其中两个最重要的决策做简单说明:

  • Go旨在成为一个编程环境

Go语言之父们认为语言特性仅是编程语言的一部分,而编程环境特性与语言特性同等重要,这些环境特性包括:库、工具、惯例和针对软件工程的整体做法,它们都对使用Go语言编程提供了支持,不可或缺。而这些环境特性恰恰是在传统的编程语言设计中并没有受到应有的重视的。

这样的决策让Go在开源之初就为开发者提供了使用Go进行编程所需的几乎一切:包括功能丰富、开箱即用的标准库以及全面的工具集,代码格式化、代码静态检查、依赖关系管理、构建(包括跨平台交叉编译)、测试、性能剖析、查看和生成文档等,并且这些工具集在今天都统一放在了go命令的下面。这个决策也帮助Go在开源后吸引了第一批Go社区用户。

  • Go的一致性的表现

Go的一个目标是让它在不同的实现、执行环境中,甚至在不同的时间内表现出相同的行为。所以,Go语言尽可能地规定了一致的结果。比如:Go程序生命周期内一致的性能(相对于使用JIT慢启动的语言)、一致的GC的开销等。甚至对于最常见的编程错误提供了明确定义的语义,这有助于可理解性和调试,而不是像C/C++中那样,充斥着各种未定义的行为。

而我认为最重要的一致性则是从2012年发布的Go 1.0开始,Go团队公开承诺只对语言和标准库进行向后兼容的修改,这样程序在编译到较新的Go版本时可以继续运行而不发生变化。这一承诺对业界产生了吸引力,它不仅鼓励了那些长声明周期的工程项目(比如Google内部的一些大型项目或者像Kubernetes这样的社区顶级项目),也鼓励了其他努力,如书籍、培训课程和第三方软件包的繁荣生态系统。这一一致性的决策也为Go招募了相当数量的拥趸。 Go1兼容性,同样可以避免社区分裂(像python2/python3那样),即便是10多年来变更最大的泛型语法落地,也没有违反Go1兼容性,这实属不易。

b) 设计哲学

上述的设计决策的背后蕴含着Go语言之父们的设计哲学。

  • 简单

Tony Hoare在1980年图灵奖演讲中说了这样的观点:“我的结论是,构建软件设计有两种方法:一种方法是让它变得如此简单,显然没有缺陷,另一种方法是让它变得如此复杂,以至于没有明显的缺陷。第一种方法要困难得多。它需要同样的技能,奉献,洞察力,甚至灵感,就像发现作为自然复杂现象基础的简单物理定律一样。它还要求愿意接受受物理,逻辑和技术限制的目标,并在无法实现冲突目标时接受妥协。”

Go选择的正是Tony Hoare演进中的第一种构建软件的设计方法。Rob Pike说过的一句Go流行谚语“less is exponentially more”与此异曲同工。Go的语法简单,API简单,这些为Gopher提供了极大便利,但这些简单的背后其实是Go团队长时间的复杂的思考与实现,努力将语法和API简化为最小、最有用、最接近本质的努力工作。

同时,简单意味着可读性、可维护性,意味着代码的清晰。另一句Go谚语“Clear is better than clever”告诫Gopher们编写平淡如水的Go代码才是“政治正确”的,不要炫技。

  • 并发

多核时代,Go将并发作为语言内置特性。Go内置并发原语,包括goroutine、channel、select等。

Go鼓励在较高级别使用并发性,特别是通过通信的方式。我们耳熟能详的一句Go谚语是“Don’t communicate by sharing memory. Share memory by communicating”就是并发哲学的外在体现。

  • 组合

Go拥有类型,类型可以有method,这似乎像是一种面向对象style的实现,但Go并没有OO语言那种类型层次体系(type hierarchy),在Go中,组合才是Go类型之间建立联系的最主要手段,而interface和类型嵌入恰是这种组合哲学的具体体现。

  • 面向工程

2012年, Go开源元年,Rob Pike就在SPLASH 2012大会上以“Google的Go:为软件工程服务的语言设计”为题,讲解了Go是如何围绕Google内部存在的软件工程问题进行有针对性的语言设计的。可以看出,Go从诞生伊始就将解决软件工程领域问题作为语言的目标。同时,我们看到面向工程这个哲学与上面的旨在成为一个编程环境的决策息息相关。

除了统帅之外,Go社区的治理架构也是以Google“将领”为核心的,我们继续来看。

2. Google出钱:以Google“将领”(googler and ex-googler)为核心的Go社区治理架构

Go开源10年了,Go社区形成了以Googler和ex-googler(前google员工)为核心的Go社区治理架构,这些人就是上图中的那些“将领”,他们是Go项目某个细分领域,比如:编译器、运行时goroutine调度、GC、内存管理、网络、安全等的领头人。根据Go项目一名产品经理的描述:2021年,Google Go项目的专职人员多达50多人,Google这个“亲爹”在金钱的投入上显然表现的十分大方,不得不承认:在编程语言领域里,有个有钱的“亲爹”就是好

这种以googler和Ex-googler为开源社区治理核心的架构决定了Go社区采用的是一种我称之为“民主集中制”的决策机制。在Go社区你不要幻想会有绝对的公平投票,Go项目决策向来是由少数Googler和ex-googler主导的。这样意味着很多情况下,核心治理团队的人提出的proposal以及Google内部gopher提出proposal很容易被accept,而来自外部社区的proposal要想被accept,可能难度就要大一些。怎么说呢?Google的方案不一定总是最好的,但我们也不能不承认多数情况下,Googler提的proposal还是更优的,并且通常这些proposal对应的实现都已经在google内部测试过了,甚至和Go决策组在公司内部“吹过风”,如果你是Go社区的决策人,你会怎么做呢?你是更相信Googler还是外部一个没有任何背景的gopher呢?

我觉得在Google依然引领IT前沿的今天以及未来若干年,这种机制可能还是有利于Go的蓬勃发展的。

3. Google为Go社区提供战场/试验场

就像上面所说的那样,Go是有着非常鲜明Google烙印的编程语言,除了Go语言之父都来自google,Go社区治理架构的核心都来自Google和前google员工外,Google内部为Go的设计提供了足够的一流的问题域,也为Go的真实应用提供了试验场和真实战场,即便Go至今没有成为Google内部的第一语言。面向Google的一手且一流问题域,让Go设计者和Go开发者能够获得一手的反馈,从而对Go做进一步的打磨。

举几个例子:

  • Google内部的单一代码仓库让Go最初设计了不带版本的go get(后在社区的强烈要求下引入了go module,go get才支持版本号);
  • googler反馈,google内部工具超好用,这一定程度让Go团队认识到向Gopher提供完善的go工具链的重要性;
  • Google内部的多核与网络服务让Go设计者决定内置原生goroutine以应对多核时代的应用开发;
  • Google内性能与开发效率并重让Go设计者决定设计一门带gc的静态编程语言,将内存管理、并发管理下沉到runtime,这与近两年出现的服务网格, dapr等概念的思路一致;

  • Google内部大规模人员协作让Go决定面向软件工程,不仅要设计好语言特性,还要提供体验良好的编程环境(工具链、标准库等);
  • Google超大规模的系统构建慢让Go决定提供快速的构建能力,为此对包格式与包依赖做了精心的设计;
  • Google内部长期维护的系统(生命周期长) 让Go团队决定支持Go1兼容性并提供支持重构的语法,比如type alias等;
  • Google认为安全十分重要,促使Go提供了go sumdb和对sbom的良好支持;

同时Google内部系统为了支持Go的内部试验也是不遗余力,比如:每当Go发布大版本的RC版本,甚至是Beta版本时,Google App Engine都会首当其冲的充当“小白鼠”,在生产环境支持尚未发布正式版的Go。

另外Google在业内的领先性也让“近水楼台”的Go受益,比如像容器调度编排这样的平台,Google十年前就有了(borg),后续Googler以另起开源项目的方式将其中经验外溢输出,让Kubernetes最终选择了Go作为开发语言,从而成为Go的最大的也是最典型的成功战例。

综上,我们看到Google对Go成功的决定性作用,这种作用可决不能被理解为简单的金钱上的支撑。

三. Go语言演进历史

进入Go高级阶段后,对Go语言的演化历史要知道,当然能做到如数家珍更佳,即便不能,也要能记住Go语言的主要演化历史:

  • 2007年9月,Go语言诞生;
  • 2009年11月,Go正式开源;
  • 2012年3月,Go 1.0发布,同时Go1兼容性承诺官宣;
  • 2014年12月,Go 1.4版本发布,这是最后一个编译器和runtime由C语言实现的版本;
  • 2015年8月,Go 1.5版本发布,这个版本Go实现了自举(用go编译go),同时编译器和runtime中的绝大部分c代码都换成了go,新版gc让延迟大幅降低;
  • 2018年8月,Go 1.11版本发布,go module被正式引入;
  • 2022年3月,Go 1.18版本发布,Go泛型语法正式落地。

四. 小结

C++之父说过:“世上只有两种编程语言:一种是总是被人抱怨的,一种是从来没人用的”。

Go属于前者。世界上没有完美的编程语言,Go经过十年的打磨已经有了长足的进步,并且取得了不错的战绩,尤其是在云基础设施和云原生因公领域,就连Rob Pike也承认Go确实已成为云基础架构的语言。而这个Go走向成功的过程中,Google起着根本性的作用。

不过中国古语有云:成也萧何,败也萧何!目前Google仍然引领IT技术前沿,这对Go的发展来说是一个利好,也会不断推动Go向着好的方向发展。

但我大胆预测一下:“成也Google,败也Google”,一旦Google开始走下坡路的那天,Go语言成功的根基就不在了,Go还能像今天这样顺风顺水么?如果Go社区治理结构不重构,很可能不会再有今天这样的良好状态。大家觉得呢?

五. 参考资料

-《Go编程语言与环境:万字长文复盘导致Go语言成功的那些设计决策
-《Go内存模型》- https://research.swtch.com/gomm
-《Go语言真正的问题》 – https://vanitynotes.com/posts/20221101-the-real-problem-with-go


“Gopher部落”知识星球旨在打造一个精品Go学习和进阶社群!高品质首发Go技术文
章,“三天”首发阅读权,每年两期Go语言发展现状分析,每天提前1小时阅读到新鲜的Gopher日报,网课、技术专栏、图书内容前瞻,六小时内必>答保证等满足你关于Go语言生态的所有需求!2022年,Gopher部落全面改版,将持续分享Go语言与Go应用领域的知识、技巧与实践,并增加诸多互
动形式。欢迎大家加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

Gopher Daily(Gopher每日新闻)归档仓库 – https://github.com/bigwhite/gopherdaily

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite

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

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 AI原生开发工作流实战 Go语言精进之路1 Go语言精进之路2 Go语言第一课 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