一个 Demo 学会使用 Go Delve 调试

大家好,我是煎鱼。 在 Go 语言中,除了 go tool 工具链中的 pprof、trace 等剖析工具的大利器外。常常还会有小伙伴问,有没有更好用,更精细的, 大家总嫌弃 pprof、trace 等工具,不够细,没法一口气看到根因,或者具体变量…希望能够最好能追到代码级别调试的,看到具体变量的值是怎么样的,随意想怎么看怎么看的那种。 为此今天给大家介绍 Go 语言强大的 Delve (dlv)调试工具,来更深入问题剖析。 安装 我们需要先安装 Go delve,若是 Go1.16 及以后的版本,可以直接执行下述命令安装: $ go install github.com/go-delve/delve/cmd/dlv@latest 也可以通过 git clone 的方式安装:

学会使用 GDB 调试 Go 代码

大家好,我是煎鱼。 上一篇文章《一个 Demo 学会使用 Go Delve 调试》我们详细介绍了 Go 语言如何使用 Delve 进行排查和调试,对于问题的解决非常的有帮助。 但调试工具肯定不止只有 Delve,今天我们来介绍第二个神器,那就是:GDB。 GDB 是什么 GDB 是一个类 UNIX 系统下的程序调试工具,允许你看到另一个程序在执行时 “内部 “发生了什么,或者程序在崩溃时正在做什么。 主要可以做四类事情: 启动你的程序,指定任何可能影响其行为的东西。 使你的程序在指定的条件下停止。 检查当你的程序停止时发生了什么。 改变你程序中的东西,这样你就可以试验纠正一个错误的影响,并继续了解另一个错误。 安装 如果是在 MacOS 上的话,可以直接使用 brew 安装:

我周末参加了个架构师大会!

大家好,我是煎鱼。 前两天 GIAC 全球互联网架构大会在深圳举办了,总算是有个长年在深圳举办的大会了,愉快参加了大部分的场次,面基了不少社区网友。 分享一些我听了觉得有意义的记录给大家。希望能和大家一起学习进步。本文分别涉及如下几个议题: 《hits for microservices desgin》 《在企业中的个人成长》 《大规模任务调度在 AfterShip 的高可用实践》 《快手前端实时性能监控和稳定性度量》 《快手中间件 mesh 化实践》 hits for microservices desgin 一开始先介绍了为什么叫 ”hits“。叫 ”hits“ 的主要原因,是业务架构没有技术架构那么明确,没有明确的对与错,是个人的工作经验和总结。 微服务解决什么问题 业内常常说到,微服务,微服务。总归期望微服务解决什么问题。 演讲的作者做了如下的调研:

为什么鼓励可以重塑一个职场人?

大家好,我是煎鱼。 最近在看书的时候看到了一句很经典的话:“重塑一个人行为最好的方式是鼓励”。平时我在多个领域的不同图书、不同面谈场合都能听到过不同的诠释。 可惜的是作者大多都没有指出是 “心理学” 的范畴,都只是表示应该要这么做,没有表示为什么,没有讲解来源,传播的信息非常的 3.5 手。 为此特意咨询了身边的一个心理学科班大佬,自打我认识她以来,每次开会都能看到她点头表示肯定,在我的记忆中非常深刻,非常有意思。 与她咨询过后,得出对应的是理论是 “皮格马利翁效应”。今天就进一步展开来简单学习、思考一下这为何物。 背景 皮格马利翁效应,又称毕马龙效应、罗森塔尔效应或期待效应,是指人(通常是指孩童或学生)在被赋予更高期望以后,他们会表现的更好的一种现象。 美国心理学家罗伯特·罗森塔尔和雷诺尔·雅各布森对此进行了研究。在他们的研究中发现,假设老师对学生的期望加强,学生的表现也会相对加强。 实验 在罗森塔尔的实验中,他们从 1~6 年级各选了 3 个班,对这 18 个班的学生进行了 “未来发展趋势测验”。并将一份 “最有发展前途者” 名单(实际上是随便抽取出来的)交给了校长和相关老师。 在 8 个月后,罗森塔尔和助手们对那 18 个班级的学生进行复试,结果发现:被期望的学生表现出更有适应能力、更有魅力、求知欲更强、智力更活跃等倾向。 通过各种研究和试验得出结论:认为教师的期望会传递给被期望的学生并产生鼓励效应,进而产生改变。

时隔 3 年,Go1.17 增强构建约束!

大家好,我是煎鱼。 Go1.17rc1 在前几天终于正式发布了: 看到 Go1.17 增加了一个新特性,是面向 Go 构建时的构建约束的增强。认真一看,是一个时隔 3 年的提案了,原本还在 Go2 和 Go1 之间左右摇摆,这下在 6 月底 Russ Cox 就输出了新草案:《Bug-resistant build constraints — Draft Design》。紧接着直接计划在 Go1.17 发布了。 一气呵成,真实版高效能了。 如下图: 之前小咸鱼有遇到好几个朋友,在报错时压根不知道 Go 有这个约束语法,以为只是个单纯的注释,直接不明所以然,感觉科普之路任重道远。

Go 内存模型:happens-before 原则

大家好,我是煎鱼。 在日常工作中,如果我们能够了解 Go 语言内存模型,那会带来非常大的作用。这样在看一些极端情况,又或是变态面试题的时候,就能够明白程序运行表现下的很多根本原因了。 当然,靠一篇普通文章讲完 Go 内存模型,不可能。因此今天这篇文章,把重点划在给大家讲解 Go 语言的 happens-before 原则这 1 个细节。 开吸,和煎鱼揭开他的神秘面纱! 内存模型定义是什么 既然要了解 happens-before 原则,我们得先知道 The Go Memory Model(Go 内存模型)定义的是什么,官方解释如下: The Go memory model specifies the conditions under which reads of a variable in one goroutine can be guaranteed to observe values produced by writes to the same variable in a different goroutine.

分享 Go 使用 Context 的正式姿势

大家好,我是煎鱼。 在 Go 语言中,Goroutine(协程),也就是关键字 go 是一个家喻户晓的高级用法。这起的非常妙,说到 Go,就会想到这一门语言,想到 goroutine 这一关键字,而与之关联最深的就是 context。 背景 平时在 Go 工程中开发中,几乎所有服务端(例如:HTTP Server)的默认实现,都在处理请求时新起 goroutine 进行处理。 但一开始存在一个问题,那就是当一个请求被取消或超时时,所有在该请求上工作的 goroutines 应该迅速退出,以便系统可以回收他们正在使用的任何资源。 当年可没有 context 标准库。很折腾。因此 Go 官方在 2014 年正式宣发了 context 标准库,形成一个完整的闭环。 但有了 context 标准库,Go 爱好者们又奇怪了,前段时间我就被问到了:“Go context 的正确使用姿势是怎么样的”?

详解 Go 团队不建议用的 unsafe.Pointer

大家好,我是煎鱼。 大家在学习 Go 的时候,肯定都学过 “Go 的指针是不支持指针运算和转换” 这个知识点。为什么呢? 首先,Go 是一门静态语言,所有的变量都必须为标量类型。不同的类型不能够进行赋值、计算等跨类型的操作。 那么指针也对应着相对的类型,也在 Compile 的静态类型检查的范围内。同时静态语言,也称为强类型。也就是一旦定义了,就不能再改变它。 错误的示例 func main(){ num := 5 numPointer := &num flnum := (*float32)(numPointer) fmt.Println(flnum) } 输出结果: # command-line-arguments ...: cannot convert numPointer (type *int) to type *float32 在示例中,我们创建了一个 num 变量,值为 5,类型为 int,准备干一番大事。

Go SliceHeader 和 StringHeader,你知道吗?

大家好,我是煎鱼。 在 Go 语言中总是有一些看上去奇奇怪怪的东西,咋一眼一看感觉很熟悉,但又不理解其在 Go 代码中的实际意义,面试官却爱问… 今天要给大家介绍的是 SliceHeader 和 StringHeader 结构体,了解清楚他到底是什么,又有什么用,并且会在最后给大家介绍 0 拷贝转换的内容。 一起愉快地开始吸鱼之路。 SliceHeader SliceHeader 如其名,Slice + Header,看上去很直观,实际上是 Go Slice(切片)的运行时表现。 SliceHeader 的定义如下: type SliceHeader struct { Data uintptr Len int Cap int } Data:指向具体的底层数组。

群里又吵起来了,Go 是传值还是传引用?

大家好,我是煎鱼。 前几天在咱们的 Go 交流群里,有一个小伙伴问了 “xxx 是不是引用类型?” 这个问题,引发了将近 5 小时的讨论: 兜兜转转回到了日经的问题,几乎每个月都要有人因此吵一架。就是 Go 语言到底是传值(值传递),还是传引用(引用传递)? Go 官方的定义 本部分引用 Go 官方 FAQ 的 “When are function parameters passed by value?”,内容如下。 如同 C 系列的所有语言一样,Go 语言中的所有东西都是以值传递的。也就是说,一个函数总是得到一个被传递的东西的副本,就像有一个赋值语句将值赋给参数一样。