Tony Bai 说
分享经验交流心得,学习前沿流行技术
-
【讲师分享】2022年Go语言盘点:泛型落地,无趣很好,稳定为王
早早就计划好在年前写一个Go语言年度盘点,就像2020年和2021年那样。但恰逢国内疫情管控放开,一波阳了之后身体十分容易疲劳,再加上工作上的事情挺多,这篇盘点也就迟迟没能下笔。 今年的盘点思路将围绕三个关键字来展开:泛型、无趣(boring)和稳定。下面我们逐一来看看。 1. “泛型”靴子落地 2022年3月中旬,Go社区尤其是那些期盼Go加入泛型特性的Gopher终于迎来了Go 1.18版本的正式发布,这意味着Go泛型这只靴子终于落地了。 其实,从Go开源那一天开始,Go核心团队就没有间断过对泛型
3083浏览
0推荐
0评论
-
【讲师分享】Go为什么能成功
大家在入门Go语言时,多埋头于Go语法,忙于练手或快速完成公司的项目,无暇思考。 但当大家到了要进阶,要冲刺高级阶段的时候,我建议你不能再稀里糊涂了。既然入了Go这个坑,在进入高级阶段前,我们最好在门口的“影壁墙”前驻留一下。 仔细思考一下我们投入这么多精力研究的Go为什么能成功,后续还能否持续成功下去。你要有自己的基本的判断,自我暗示也好,坚定信心也罢,我们要为继续攀登Go高峰进行蓄能。 一. 头脑风暴一下Go成功的因素 相信无论针对哪个gopher群体做头脑风暴,让大家
3356浏览
0推荐
0评论
-
【讲师分享】Go 1.20新特性前瞻
在近期Russ Cox代表Go核心团队发表的“Go, 13周年”一文中,他提到了“在Go的第14个年头,Go团队将继续努力使Go成为用于大规模软件工程的最好的环境,将特别关注供应链安全,提高兼容性和结构化日志记录,当然还会有很多其他改进,包括profile-guided optimization等”。 当前正在开发的版本是Go 1.20,预计2023年2月正式发布,这个版本也将是Go在其第14个年头发布的第一个版本。很多人没想到Go真的会进入到Go 1.2x版本,而不是Go 2.x。记得Russ Cox曾说过可能永远也不会有Go2了,毕竟Go
1857浏览
0推荐
0评论
-
【讲师分享】万字长文详解Go context包
自从context包在Go 1.7版本加入Go标准库,它就成为了Go标准库中较难理解和易误用的包之一。在我的博客中目前尚未有一篇系统介绍context包的文章,很多来自“改善Go语言编程质量的50个有效实践”专栏的读者都希望我能写一篇介绍context包的文章,今天我就来尝试一下^_^。 1. context包入标准库历程 2014年,Go团队核心成员Sameer Ajmani在Go官博上发表了一篇文章“Go Concurrency Patterns: Context”,介绍了Google内部设计和实现的一个名为context的包以及该包在Google内部实践后得出的
5389浏览
2推荐
0评论
-
【讲师分享】slog:Go官方版结构化日志包
Go自诞生以来就在其标准库内置了log包作为Go源码输出日志的标准组件,该包被广泛应用于Go标准库自身以及Go社区项目中。 不过,针对Go标准库log包,Go社区要求改进的声音始终不断,主流声音聚焦在以下几点: log包是为了方便人类可读而设计的,不支持便于机器解析的结构化日志(比如像zap那样输出json格式的日志); 不支持日志级别(log level); log包采用专有日志输出格式,又没有提供可供Go社区共同遵循的Logger接口类型,导致Go社区项目使用的log输出格式五花八门,相互之间又难以兼容。
1854浏览
0推荐
0评论
-
【讲师分享】当函数设计遇到切片
切片(slice)是Go语言中的一种重要的也是最常用的同构数据类型。在Go语言编码过程中,我们多数情况下会使用slice替代数组,一来是因为其动态可扩展,二来在多数场合传递slice的开销要比传递数组要小(这里有一些例外)。 切片算是“半个”零值可用的类型,为什么这么说呢? 当我们声明一个切片类型实例但在未显式初始化的情况下,我们不能直接对其做下标操作,比如: var sl []int sl[0] = 5 // 错误:引发panic 但是我们可以通过Go内置的append函数对其进行追加操作,即便sl目前的值为n
1492浏览
0推荐
0评论
-
【讲师分享】一文搞懂Go内联优化
移动互联网时代,直面C端用户的业务系统规模一般都很庞大,系统消耗的机器资源也很可观,系统使用的CPU核数、内存都是在消耗公司的真金白银。在服务水平不下降的前提下尽量降低单服务实例的资源消耗,即我们俗称的“少吃草多产奶”,一直是各个公司经营人员的目标,有些公司每降低1%的CPU核数使用,每年都能节省几十万的开销。 在编程语言选择不变的情况下,要想持续降低服务资源消耗,一方面要靠开发人员对代码性能持续地打磨,另一方面依靠编程语言编译器在编译优化方面提升带来的效果则更为
5120浏览
2推荐
0评论
-
【讲师分享】Go语言之道
近期阅读了John Arundel的文章《The Tao of Go》,看完后我都有心去阅读一遍《道德经》了:)。作者将Go语言设计哲学与惯例与“道”学三宝有机的联系到一起,给了我不小的启发。这里译成中文,供大家参考。 你可以让水牛去任何地方,只要它们想去 - 杰拉尔德・温伯格 《咨询的奥秘》(译注:原文似乎将Gerald M. Weinberg 写成了Jerry Weinberg,应该是笔误) “道”是指事物的内在本质或自然趋势。例如,水向低处流:这就是水的“道”。你可以筑坝、疏导、抽水,或以其他方式干扰它,
3199浏览
3推荐
0评论
-
Go软件安全漏洞扫描终于出官方方案了!
2022年9月7日,Go安全团队在Go官博发表文章《Vulnerability Management for Go》,正式向所有Gopher介绍Go对安全漏洞管理的工具和方案。 在这篇文章中,Go安全团队引入了一个名为govulncheck的命令行工具。这个工具本质上只是Go安全漏洞数据库(Go vulnerability database)的一个前端,它通过Go官方维护的vuln仓库下面的vulncheck包对你仓库中的Go源码或编译后的Go应用可执行二进制文件进行扫描,形成源码的调用图(callgraph)和调用栈(callstack)。 vuln仓库下面的client包则提供了访问漏
2903浏览
0推荐
0评论
-
【讲师分享】Go字符串比较,终于有人讲清楚了
西娅(Thea)是一个刚刚入门Go语言的妹子程序员,今天她遇到了一个让她“surprise”的问题。下面就是那段让妹子西娅困惑的Go代码: func main() { s1 := "12345" s2 := "2" fmt.Println(`"12345" > "2":`, s1 > s2) // false s3 := "零" s4 := "一" s5 := "二" fmt.Println(`"一" > "零":`, s4 > s3) // false fmt.Println(`"二" > "零":`, s5 > s3) // false fmt.Println(`"二" > "一":`, s5 > s4) // true } 在这段关于Go字符串比较的代码
3441浏览
0推荐
0评论
-
万字长文告诉你Go 1.19中值得关注的几个变化
我们知道Go团队在2015年重新规定了团队发布版本的节奏,将Go大版本的发布频率确定为每年两次,发布窗口定为每年的2月与8月。而实现自举的Go 1.5版本是这一个节奏下发布的第一个版本。一般来说,Go团队都会在这两个窗口的中间位置发布版本,不过这几年也有意外,比如承载着泛型落地责任的Go 1.18版本就延迟了一个月发布。 就在我们以为Go 1.19版本不会很快发布的时候,美国时间2022年8月2日,Go核心团队正式发布了Go 1.19版本,这个时间不仅在发布窗口内而且相对于惯例还提前了。为什么呢?
4100浏览
0推荐
0评论
-
【讲师分享】一文告诉你Go 1.19都有哪些新特性
美国时间2022年5月7日,Go 1.19版本开发分支进入新特性冻结(freeze)阶段,即只能修Bug,不能再向Go 1.19版本中增加新特性了。由于上一个版本Go 1.18因引入泛型改动较大,推迟了一个月发布,这直接导致了Go 1.19版本的开发周期被缩短。 虽然开发周期少了近一个月,但Go 1.19版本仍然会按计划在2022年8月份发布。而Go 1.19的第一个beta版也于今天凌晨发布了。Go 1.19版本都有哪些重要变化呢,我通过这篇文章带大家先睹为快。 注1:版本特性变化以最终发布为准! 注2:本文仅是前瞻,不会
5289浏览
1推荐
2评论
-
使用ANTLR和Go实现DSL入门
一. 引子 设计与实现一门像Go这样的通用编程语言的确很难!那是世界上少数程序员从事的事业,但是实现一门领域特定语言(Domain Specific Language, DSL)似乎是可行的。 就像著名的语言解析器生成工具ANTLR作者Terence Parr在《编程语言实现模式》一书中说的那样: Yes, building a compiler for a general-purpose programming language requires a strong computer science background. But, most of us don’t build compilers. So, this book focuses on
3738浏览
1推荐
3评论
-
使用具名返回值巧妙解决泛型函数返回零值的问题
Go语言泛型语法特性在Go 1.18版本落地后,不出所料,在github上看到大量的基础容器类型数据结构被用泛型重写。这种重写我觉得是很正常、很自然的,并且实现良好的通用数据结构改为泛型其实也不难,有些简单的结构可能分分钟就能搞定。 Go 1.18发布后,我一直没机会写泛型,今天在做DSL语义模型提取时,多处用到Stack结构,于是想到使用泛型简单实现了一个通用的Stack结构。 在Go中,我们可以用一个切片来定义Stack。泛型Stack类型的定义如下: type Stack[T any] []T 这里的Stack类型就
4306浏览
1推荐
0评论
-
绞尽脑汁,帮你理解方法本质并选择正确的receiver类型
Go语言虽然不支持经典的面向对象语法元素,比如:类、对象、继承等,但Go语言也有方法(method)。和函数相比,Go语言中的方法在声明形式上仅仅多了一个参数,Go称之为receiver参数,而receiver参数正是方法与类型之间的纽带。 那么Go语言的方法究竟是什么?它与函数究竟是什么关系?我们又该如何选择receiver参数的类型呢? 是选择值类型还是指针类型? 本文将通过《改善Go语言编程质量的50个有效实践》这门专栏的内容来帮助大家深入理解Go方法的本质,并给出receiver参数类型选择的原则,让
2501浏览
0推荐
0评论
-
Go 1.19新特性前瞻: 第一部分
由于Go 1.18推迟一个月发布,这导致Go 1.19版本的开发周期缩短,Go 1.19的新特性冻结(freeze)时间定在了美国时间5月7日。尽管开发周期短,但Go 1.19版本中依然有一些新特性值得我们关注,下面我们就来看第一部分。 Go 1.19的里程碑在这里,所有feature大家可以在该里程碑中看到。 泛型问题的fix 尽管Go核心团队在Go 1.18泛型上投入了很多精力,但Go 1.18发布后泛型这块依然有已知的天生局限,以及后续逐渐发现的一些问题,而Go 1.19版本将继续打磨Go泛型,并重点fix Go 1.18中发现
3551浏览
1推荐
1评论
-
我来告诉你Go项目标准结构如何布局
每当我们编写一个非hello world的实用Go程序或库时,我们都会在项目结构、代码风格以及标识符命名这三个“门槛”前面踯躅徘徊许久,甚至始终得不到满意答案。 本文将通过《改善Go语言编程质量的50个有效实践》这门专栏的内容来详细看一看Go项目结构这道“门槛”应该如何迈过,以帮助大家能更快地深入Go语言的核心腹地,提高学习效率。 除非是像hello world这样的简单程序,但凡我们编写一些实用程序或库,我们都会遇到采用什么样的项目结构(project structure)的问题(通常一个Go项目对应
2207浏览
0推荐
0评论
-
带你走近Go语言编程思维
经过十几年的演化和发展,Go语言在全世界范围内已经拥有了百万级别的拥趸,在这些开发者当中,除了一部分新入行的编程语言初学者之外,更多的是从其他编程语言阵营转过来的开发者。由于Go语言上手容易,在转Go的初期大家很快就掌握了Go的语法。 但在编写更多Go代码之后,很多人发现自己写的Go代码总是感觉很别扭,并且总是尝试在Go语言中寻找自己上一门语言中熟悉的语法元素。自己的Go代码风格似乎和Go标准库、主流Go开源项目的代码在思考角度和使用方式上存在不小差异,并且每每看到Go核心开发
1896浏览
0推荐
0评论
-
万字长文告诉你Go 1.18中都有哪些值得关注的变化
2022年3月15日,Go团队在官方博客上官宣了Go 1.18正式版的发布。Go 1.18这个网红版本终于落地了。泛型的加入让Go 1.18成为继Go 1.0(首个正式版)、Go 1.5(实现自举、去C代码、新版GC)、Go 1.11(引入Go module)版本之后的又一里程碑版本。 泛型是Go语言开源以来最大的语法特性变化,其改动和影响都很大,Go核心团队尽管很努力了,但Go 1.18正式版本的发布时间还是延迟了一个月。不过好消息是加入泛型语法的Go 1.18继续保持了Go1兼容性,这本身就是Go团队的胜利,同样也是Go社区的幸运。
6219浏览
1推荐
1评论
-
Go是否支持增量构建?我来告诉你!
Go语言以编译速度快闻名于码农界。这缘于Go在设计之初就选择抛弃其祖辈C语言的头文件包含机制,选择了以包(package)作为基本编译单元。Go语言的这种以包为基本构建单元的构建模型使得依赖分析变得十分简单,避免了C语言那种通过头文件分析依赖的巨大开销。在我的专栏《改善Go语言编程质量的50个有效实践》中,我也给出了Go编译速度快的三点具体原因,包括: Go要求每个源文件在开头处显式地列出所有依赖的包导入,这样Go编译器不必读取和处理整个文件就可以确定其依赖的包列表; Go要求包之间
1068浏览
0推荐
0评论
-
Go 1.18版本正式发布了
美国时间2022年3月15日,Go核心团队官宣了Go 1.18版本正式版的发布!这是一个万众期待的版本,因为在这个版本中,Go核心团队做了Go语言开源以来的最大一次语法特性变更 - 增加了对泛型(generics)的支持下面是对Go官博文章的全文翻译,供大家参考! 今天,Go团队很高兴地发布了Go 1.18,你可以通过访问下载页面获得该版本。 Go 1.18是一个真正的大版本,包括新功能特性、性能改进和我们对语言的最大改变。可以说Go 1.18的部分设计始于十年前我们首次发布Go语言的那个时候也并不夸张。 泛
2584浏览
2推荐
0评论
-
为什么有了Go module后“依赖地狱”问题依然存在
如果所有Gopher都抛弃GOPATH构建模式,拥抱Go module构建模式;如果所有legacy Go package作者都能为自己的legacy package加上go.mod;如果所有Go module作者都严格遵守语义版本(semver)规范,那么Go将彻底解决“依赖地狱”问题。 但现实却没那么乐观!Go中的“依赖地狱问题”依然存在。这一篇我们就来聊聊Go中依赖地狱的“发作场景”、原因以及解决方法。 1. 什么是“依赖地狱(dependency hell)”? “依赖地狱”问题不是某种编程语言独有的问题,而是一个在软件开发和发布领域广泛存
967浏览
1推荐
0评论
-
聊聊Go应用输出日志的工程实践
Go隶属于后端语言,以开发各类服务、中间件和系统平台见长。日常学习Go语言时,日志不是不可或缺的,甚至是无需考虑的,但是一旦到真正的Go的工程实践中,输出日志便是我们绕不过去的、必须面对的问题。 Go开发的服务大多具有连续和自主运行的属性,通常都是7x24小时运行的,开发运维人员不可能一直盯着服务的运行状态,这就需要记录服务的运行日志。而日志的本质正是留档待查。通过日志,我们可以: 查看系统运行状态 发现异常 审计行为 辅助问题的诊断 在如今云原生时代,可观测性(Obser
837浏览
0推荐
1评论
-
Go GC如何检测内存对象中是否包含指针
众所周知,Go是带垃圾回收(GC)的编程语言,开发者通常不需要考虑对内存的管理,降低了心智负担。Go程序运行的时候,GC在背后默默辛劳地为开发者“擦屁股”:把无法reach到的内存对象定期地释放掉以备后续重用。 GC只关心指针,只要被扫描到的内存对象中有指针,它就会“顺藤摸瓜”,把该内存对象所在的“关系网”摸个门儿清,而那些被孤立在这张“网”之外的内存对象就是要被“清扫”的对象。 那么GC在扫描时如何判断某个内存对象中是否有指针呢?这篇文章我们就来说说这事儿! 内存对象中有
3773浏览
1推荐
0评论
-
Go究竟是否为空切片分配了底层数组
这周在看到一位同学的这样一个问题: 切片是Go语言中的一个重要的语法元素,也是日常Go开发中使用最为频繁的语法元素。有过Go语言开发经验的童鞋估计大多都知道空切片(empty slice)与nil切片(nil slice)比较的梗,这也是Go面试中的一道高频题。 var sl1 = []int{} // sl1是空切片 var sl2 []int // sl2是nil切片 要真正理解切片,离不开运行时的切片表示。在我的专栏中有对切片在运行时表示的细致讲解。 切片在运行时由三个字段构成,reflect包中有切片在类型系统中表示的对应的
873浏览
0推荐
0评论
-
Go 1.18 Beta1版本发布,支持泛型
北京时间今天凌晨,美国时间12月14日,Go核心团队技术负责人Russ Cox在Go官博发表文章《Go 1.18 Beta 1 is available, with generics》,正式宣布Go 1.18的第一个预览版Go 1.18 beta1发布!Go团队这次少见的通过官博来发布一个beta版本,足以证明Go团队对Go 1.18版本的重视,毕竟Go 1.18是Go自诞生以来最大的一次语法变动,Go团队希望Go社区的gopher们广泛参与公测,在Go 1.18版本发布之前尽可能多地找出版本中存在的bug。 这里简单翻译一下这篇官博,正文如下。 我们刚刚发布了
5479浏览
9推荐
1评论
-
使用Docker容器突破客户端6w可用端口的误区
近期的一个项目刚刚完成了第一个版本的开发,经过一段时间的自测与集成测试,功能问题已经不是重点了。项目在初期设定了性能目标,压测与性能优化势在必行,因此这一阶段我们都在做压测前的准备,包括压测方案、环境部署、各种工具的开发等。在互联网大厂的一波接着一波的熏陶与教育下,但凡一个有点用户量的系统,交付前不压测与优化一下,似乎都不好意思上线^_^。 压测准备阶段逃不过“模拟并发连接数量”这一环节,我们第一次压测设定的系统运行背景是100w的并发长连接。那么怎么构造出这么
833浏览
0推荐
0评论
-
Go 1.18新特性前瞻:原生支持Fuzzing测试
今年6月初,Go官博发表了一篇名为《Fuzzing is Beta Ready》的文章,文中称gotip版本已经原生支持Fuzzing并开始了公测。这意味着Fuzzing将以一等公民(first-class citizen)的身份正式加入到即将于2022年2月发布的[Go 1.18版本]中: <center>图:关于add fuzz test的issue已经关闭并放入Go1.18里程碑</center> 有了对Fuzzing技术的原生支持后,我相信会有更多代码经过Fuzzing测试,未来不久Go社区的Go代码的安全水平将会得到整体提升。本文我们就来简单聊聊Fuzzing这个Go 1.18版本的新
8955浏览
4推荐
1评论
-
Go 1.18新特性前瞻:Go工作区模式
Go 1.18版本如无意外,将于2022年2月发布。 在这个版本中,除了包含万众期待的[Go泛型]之外,还包含很多实用的功能特性,Go工作区模式(Go workspace mode)就是其中之一,它弥补了当前go module构建模式的一些不足,堪称是go module构建模式的最后一块拼图。这篇文章我们就来看看什么是Go工作区模式,它究竟能解决什么问题。 一. 引子 1. replace带来的烦恼 近期在研究raft算法,参考的是etcd的raft实现。etcd还提供了一个raftexample的样例来说明如何实现基于raft的分布式应用。 要
2022浏览
0推荐
0评论
-
gRPC服务的响应设计
1. 服务端响应的现状 做后端服务的开发人员对错误处理总是很敏感的,因此在做服务的响应(response/reply)设计时总是会很慎重。 如果后端服务选择的是HTTP API(rest api),比如json over http,API响应(Response)中大多会包含如下信息: { "code": 0, "msg": "ok", "payload" : { ... ... } } 在这个http api的响应设计中,前两个状态标识这个请求的响应状态。这个状态由一个状态代码(code)与状态信息(msg)组成。状态信息是对状态代码所对应错误原因的详细诠释。只有当状态
1183浏览
0推荐
0评论
-
Go 1.17新特性详解:使用基于寄存器的调用惯例
除了Go语言特性与go module有重要变化之外,Go编译器与Go运行时也都有着优化与改进,这两方面的变化对Go程序的构建与运行影响巨大。在这个系列的最后一篇中,我们来看看编译器与运行时中那些值得关注的变化。 1. 使用基于寄存器的调用惯例替代基于堆栈的调用惯例 所谓“调用惯例(calling convention)”是调用方和被调用方对于函数调用的一个明确的约定,包括:函数参数与返回值的传递方式、传递顺序。只有双方都遵守同样的约定,函数才能被正确地调用和执行。如果不遵守这个约定,函数将无
9805浏览
0推荐
0评论
-
Go 1.17新特性详解:module依赖图修剪与延迟module加载
Go module的引入终于让Go语言有了自己的包依赖管理标准机制与工具,虽说它的引入与推广过程略显坎坷,但不得不承认Go 1.11及之后的每一次Go版本发布,Go module都在进步!在Go 1.17版本中亦是如此,本篇我们就来详细聊聊在Go 1.17版本中Go module都有哪些重要的变化。 1. module依赖图修剪 本文的标题暗示了Go 1.17中go module的两个主要变化。module依赖图修剪(module graph pruning)是延迟module加载(lazy module loading)的基础。 我们以下图中的例子来解释一下什么是module
4098浏览
1推荐
0评论
-
Go 1.17新特性详解:支持将切片转换为数组指针
Go属于那种极简的语言,从诞生到现在语言自身特性变化很小,不会像其他主流语言那样走“你有的我也要有”的特性融合路线。因此新语言特性对于Gopher来说属于“稀缺品”,属于“供不应求”那类事物^_^。这也直接导致了每次Go新版本发布,我们都要首先看看语言特性是否有变更,每个新加入语言的特性都值得我们去投入更多关注,去深入研究。下面我们就来深入[Go 1.17版本]中语言规范的一些变化! 1. 支持将切片转换为数组指针 在Go 1.17版本之前,我们可以将数组转换为切片,数组将成为转换后
1975浏览
0推荐
0评论
-
Go 1.17中值得关注的几个变化
Go核心开发团队在[去年GopherCon大会上给Go泛型的定调是在2022年2月份的Go 1.18版本中发布],那可是自[Go诞生]以来语法规范变动最大的一次,这让包括笔者在内的全世界的Gopher们都满怀期待。 不过别忘了,在Go 1.18这个“网红版本”发布前,还有一个“实力派”版本Go 1.17呢!美国当地时间2021年8月16日,[Go 1.17版本在经过两个RC版本之后正式发布]!并且值得庆幸的是Go 1.17版本并没有过多受到Go 1.18版本这个“网红”的影响,Go 1.17默默地加入和优化了着实不少的特性。在这一篇文章
3185浏览
0推荐
0评论
-
Go经典阻塞式TCP协议流解析的实践
1. Go经典阻塞I/O的TCP网络编程模型 [Go语言诞生十多年]来取得了飞速发展,并得到了全世界开发者的广泛接纳和应用,其应用领域广泛,包括:Web服务、数据库、网络编程、系统编程、DevOps、安全检测与管控、数据科学以及人工智能等。下面是2020年Go官方开发者调查的部分结果: <center>图:2020年Go官方开发者调查之Go语言的应用领域(对比2019)</center> 我们看到“Web编程”和“网络编程”分别位列第一名和第四名,这个应用领域数据分布与Go语言最初的面向大规模分布式网络服务的设计目标十
863浏览
0推荐
0评论
-
一文搞懂Go语言的plugin
要历数Go语言中还有哪些我还没用过的特性,在[Go 1.8版本]中引入的[go plugin]算一个。近期想给一个网关类平台设计一个插件系统,于是想起了go plugin^_^。 Go plugin支持将Go包编译为共享库(.so)的形式单独发布,主程序可以在运行时动态加载这些编译为动态共享库文件的go plugin,从中提取导出(exported)变量或函数的符号并在主程序的包中使用。Go plugin的这种特性为Go开发人员提供更多的灵活性,我们可以用之实现支持热插拔的插件系统。 但不得不提到的一个事实是:go plugin自诞
2227浏览
0推荐
0评论
-
使用go-metrics在Go应用中增加度量
Go语言内置[expvar],基于expvar提供的对基础度量的支持能力,我们可以自定义各种度量(metrics)。但是expvar仅仅是提供了最底层的度量定义支持,对于一些复杂的度量场景,第三方或自实现的metrics包必不可少。 go-metrics包是Go领域使用较多的metrics包,该包是对Java社区依旧十分活跃的[Coda Hale's Metrics library]的不完全Go移植(不得不感慨一下:Java的生态还真是强大)。因此该包在概念上与Coda Hale's Metrics library是基本保持一致的。go-metrics包在文档方面做的还不够,要
2133浏览
0推荐
0评论
-
一文告诉你如何用好uber开源的zap日志库
1. 引子 日志在后端系统中有着重要的地位,通过日志不仅可以直观看到程序的当前运行状态,更重要的是日志可以在程序发生问题时为开发人员提供线索。 在Go生态中,[logrus]可能是使用最多的Go日志库,它不仅提供结构化的日志,更重要的是与标准库log包在api层面兼容。在性能不敏感的领域,logrus确实是不二之选。 但在性能敏感的领域和场景下,logrus便不那么香了,出镜更多的是大厂uber开源的名为[zap的日志库]。之所以在这些场景下zap更香,虽与其以高性能著称不无关系,但其背后的大厂uber
2181浏览
0推荐
0评论
-
使用section.key的形式读取ini配置项
配置文件读取是很多Go项目必备的功能,这方面社区提供的方案也相对成熟稳定。但之前写这部分代码时除了使用了针对不同配置文件格式(比如:ini、toml等)的驱动包之外,很少直接使用第三方包对读取出的配置项的值进行管理。于是我们就面对这样一个问题:其他包如果要使用这些被读取出的配置项的值该如何做呢?我们以读取ini格式承载的配置文件为例,来简单说说。 1. 全局变量法 这是最粗糙的方法,但却是最易理解的方法。我们建立一个config包,在main函数中读取配置文件并将读取到的配置项信
1597浏览
0推荐
0评论
-
通过实例理解Go Execution Tracer
Netflix(奈飞公司)的性能架构师[Brendan Gregg]在其《BPF Performance Tools》一书中对tracing、sampling等概念做了细致描述,以帮助开发人员理解这些概念,并基于这些概念对性能优化辅助工具进行分类,明确它们的适用场合。这里引用部分内容如下: 采样工具(Sampling tools)采用一个测量的子集来描绘目标的粗略情况;这也被称为创建一个profile或profiling(剖析)。profiling工具对运行中的代码采用基于定时器的采样。其缺点是,采样只能提供一个关于目标的粗略的图像,并且可能会遗
1788浏览
1推荐
0评论
-
使用functrace辅助进行Go项目源码分析
在[《像跟踪分布式服务调用那样跟踪Go函数调用链》]一文中,我们介绍了一种跟踪函数调用链的思路,并给出了一种实现[functrace]:github.com/bigwhite/functrace。这个小工具不仅仅是分享给大家的,我自己在工作和学习时也在使用。最近发现这个小工具在阅读和分析某个Go项目源码时也能起到关键的辅助作用。这里就和大家简单讲解一下如何用functrace来辅助Go源码阅读和分析。 程序员的日常离不开“源码阅读和分析”,日常阅读代码的姿势无非是这么几种(或几种的组合): 结合源码编辑器或IDE提
3825浏览
5推荐
1评论
-
一文搞懂Go逃逸分析
翻看了一下自己的[Go文章归档],发现自己从未专门写过有关Go逃逸分析(escape analysis)的文章。关于Go变量的逃逸分析,大多数Gopher其实并不用关心,甚至可以无视。但是如果你将Go应用于性能敏感的领域,要完全压榨出Go应用的性能,那么理解Go逃逸分析就大有裨益了。在本文,我们就一起来理解一下Go的逃逸分析。 1. 逃逸分析(escape analysis)要解决的问题 [C/C++语言出身的程序员]对堆内存(heap)和栈内存(stack)都有着“泾渭分明”的理解。在操作系统演化出现进程虚拟内存地址(vi
2523浏览
0推荐
0评论
-
fasthttp性能真的比标准库http包好很多吗?一文告诉你真相!
1. 背景 Go初学者学习Go时,在编写了经典的“hello, world”程序之后,可能会迫不及待的体验一下Go强大的标准库,比如:用几行代码写一个像下面示例这样拥有完整功能的web server: // 来自https://tip.golang.org/pkg/net/http/#example_ListenAndServe package main import ( "io" "log" "net/http" ) func main() { helloHandler := func(w http.ResponseWriter, req *http.Request) { io.WriteString(w, "Hello, world!\n") } http.HandleFunc("/hello", hell
2287浏览
1推荐
0评论
-
使用reflect包在反射世界里读写各类型变量
Go在标准库中提供的reflect包让Go程序具备运行时的反射能力(reflection),但这种反射能力也是一把“双刃剑”,它在解决一类特定问题方面具有优势,但也带来了逻辑不清晰、性能问题以及难于发现问题和调试等不足。不过从Go诞生伊始就随着Go一起发布的reflect包是Go不可或缺的重要能力,不管你是否使用,都要掌握使用reflect与类型系统交互的基本方法,比如在反射的世界里如何读写各类型变量。本文就来和大家快速过一遍使用reflect包读写Go基本类型变量、复合类型变量的方法以及它们的应用。 1.
1758浏览
0推荐
0评论
-
Go标准库flag包的“小陷阱”
Go语言号称“自带电池(battery-included)”,这意味着Go标准库可开箱即用,为Gopher提供了功能丰富的常用工具包,足以应付多数日常开发所需。尤其在Go语言擅长的领域,Go标准库工具包更是有着广泛的应用。下图是[Go官方2020年用户调查]的结果: 我们看到cli([command-line interface])领域开发占据了Go语言应用的Top2位置,仅次于开发API/RPC服务。而普通cli应用的开发总是离不开标准库的flag包。 flag包估计是很多gopher入门go语言的必经之路。flag使用起来十分简单,功能也不差,常规的命令
1046浏览
0推荐
0评论
-
Go语言“十诫”
本文翻译自John Arundel的《Ten commandments of Go》。全文如下: 作为一名全职的Go语言作家和老师,我花了很多时间和学生们一起,帮助他们写出更清晰、更好、更有用的Go程序。我发现,我给他们的建议可以归纳总结为一套通用原则,在这里我将这些原则分享给大家。 1. 你应该是无聊的 Go社区喜欢共识(consensus)。比如:Go源代码有一个由gofmt强制执行的统一的代码格式规范。同样,无论你要解决什么问题,通常都有一个标准的、类似于Go行事风格的方法来解决。有时它是标准的方式,因为它
999浏览
0推荐
0评论
-
Go泛型语法又出“幺蛾子”:引入type set概念和移除type list中的type关键字
近日,Go泛型语法负责人之一的Ian Lance Taylor发布了一个issue,说明go团队想引入新的type set概念,并去除原Go泛型方案中置于interface定义中的type list中的type关键字。 对于Go泛型来龙去脉不是很了解的童鞋,可以先去看看我看看我之前的文章:《能力越大,责任越大” - Go语言之父详解将于Go 1.18发布的Go泛型》。在那篇文章的结尾,Go设计团队对自己的Go泛型设计方案中的几个方面给出了自己的满意度评价,其中唯一让团队感觉还不是很完美的就是“Type lists in interfaces”:
1481浏览
0推荐
0评论
-
Go标准库http Client的连接行为控制详解
1. http包默认客户端 Go语言以“自带电池”闻名,很多开发者对Go自带的功能丰富的标准库喜爱有加。而在Go标准库中,net/http包又是最受欢迎和最常用的包之一,我们用几行代码就能生成一个支持大并发、性能中上的http server。而http.Client也是用途最为广泛的http客户端,其性能也可以满足多数情况下的需求。知名女gopherJaana Dogan开源的类apache ab的http性能测试工具hey也是直接使用的http.Client,而没有用一些性能更好的第三方库(比如:fasthttp)。 使用http包实现http客户端的最简
1728浏览
0推荐
0评论
-
Go语言中常见的几种反模式
本文翻译自Saif Sadiq的文章《Common anti-patterns in Go》。 众所周知,编码是一门艺术,就像每个拥有精湛艺术并为之感到骄傲的工匠一样,我们作为开发人员也为我们编写的代码感到自豪。为了获得最佳效果,艺术家不断寻找可提高其手艺的方法和工具。同样,作为开发人员,我们也在不断提高自己的技能,并对"如何写出好的代码"这个最重要的问题的答案保持好奇。 弗雷德里克·布鲁克斯(Frederick P. Brooks)在他的书[《人月神话》]中写道: “程序员和诗人一样,工作时只是稍稍脱离了
1287浏览
0推荐
0评论
-
使用Go实现可用select监听的队列
1. 背景与选型 和[《基于Redis Cluster的分布式锁实现以互斥方式操作共享资源》]一文一样,今天要说的Go队列方案也是有一定项目背景的。 5G消息方兴未艾!前一段时间从事了一段时间5G消息网关的研发,但凡涉及类似消息业务的网关,我们一般都离不开队列这种数据结构的支持。这个5G消息网关项目采用的是Go技术栈开发,那么我们应该如何为它选择一个与业务模型匹配且性能不差的实现呢? 如今一提到消息队列,大家第一个想到的一定是[kafka],kafka的确是一款优秀的分布式队列中间件,但对于我
871浏览
0推荐
0评论