- 博客(28)
- 收藏
- 关注
原创 性能优化 | Go Ballast 让内存控制更加丝滑
关于 Go GC 优化的手段你知道的有哪些?比较常见的是通过调整 GC 的步调,以调整 GC 的触发频率。设置 GOGC设置 debug.SetGCPercent()这两种方式的原理和效果都是一样的,GOGC 默认值是 100,也就是下次 GC 触发的 heap 的大小是这次 GC 之后的 heap 的一倍。我们都知道 GO 的 GC 是标记-清除方式,当 GC 会触发时全量遍历变量进行标记,当标记结束后执行清除,把标记为白色的对象执行垃圾回收。值得注意的是,这里的回收仅仅是标记内存可以返回给操作系统,并不
2021-11-17 15:10:58
895
原创 gin 源码阅读(5) - 灵活的返回值处理
gin 源码阅读系列文章列表:gin 源码阅读(1) - gin 与 net/http 的关系gin 源码阅读(2) - http请求是如何流入gin的?gin 源码阅读(3) - gin 路由的实现剖析gin 源码阅读(4) - 友好的请求参数处理hi,大家好,我是 haohongfan。上一篇文章是关于如何快速解析客户端传递过来的参数的,参数解析出来后就开始了我们的业务的开发流程了。业务处理的过程 gin 并没有给出对应的设计,这给业务开发带来了很多不方便的地方,很多公司会基于 gin 做二次开发,定制
2021-10-20 18:20:08
1085
原创 聊聊我对 GraphQL 的一些认知
每隔一段时间就能看到一篇 GraphQL 的文章,但是打开文章一看,基本上就是简单的介绍下 GraphQL 的特性。很多文章其实就是 github 上找个 GraphQL 的项目,然后按照对应的 demo 跑起来而已。有些文章明显是没有完整的项目实践经历,却在狂吹 GraphQL 的各种优点,让不熟悉 GraphQL 的同学以为这是神丹妙药,弄不好还要在项目中实践一番。因为项目的背景(后面会讲到),我有幸参与过 GraphQL 在实际项目中的落地,本篇文章我会谈谈我对 GraphQL 的一些理解,当然这个也
2021-10-09 14:12:21
250
原创 开发中的一些坑
本篇文章罗列一些开发业务时遇到的那些坑。微服务银弹当前的市面上各种微服务,DDD的课收割了一波又一波的韭菜,有同学听完了课就要迫不及待的尝试一下。学习新知识的动力当然值得肯定,但是具体落地需要根据公司实际场景来。某前同事找我咨询架构相关的事情,跟他一番交流让我彻底无语了。这是他们公司 JAVA 架构师落地的方案(2个开发,其中一个还是架构师,真是闹)。姑且不论架构师水平如何,当我看到 2 个后端开发,拆出了 17 个服务时,我的建议是立即开除这个人。我们在一个公司有一定的技术话语权时,想落地我们学到的技术时
2021-09-24 23:11:41
225
原创 开发中的坑2:MQ 也能做 RPC 调用?
hi, 大家好,我是 haohongfan。最近浏览 帖子[1] 的时候看到一个有意思的吐槽。大概意思是架构师没有选用 RPC 框架来做服务间调用,而选择用 MQ 来代替。是不是很意外?当然不出意外的,评论区炸了!现在提出一些疑问:这个架构师的做法对吗 ?MQ 是否能做 RPC 调用 ?RPC 框架的职责回答上面问题之前,稍微捋一下 RPC 框架。目前市面上比较流行的 RPC 框架其实并不多。Java: SpringCloud,Dubbo 等Go: Dubbogo,go-micro,rpcx,go-zero
2021-09-24 23:10:48
230
原创 Go interface 原理剖析--类型转换
hi, 大家好,我是 haohongfan。可能你看过的 interface 剖析的文章比较多了,这些文章基本都是从汇编角度分析类型转换或者动态转发。不过随着 Go 版本升级,对应的 Go 汇编也发生了巨大的变化,如果单从汇编角度去分析 interface 变的非常有难度,本篇文章我会从内存分配+汇编角度切入 interface,去了解 interface 的原理。限于篇幅 interface 有关动态转发和反射的内容,请关注后续的文章。本篇文章主要是关于类型转换。efaceifaceefacefunc&n
2021-09-24 23:09:54
194
原创 Goland 这些实操技巧,你可能还不会!
工欲善其事必先利其器。对于开发工程师同样如此,一个合适的开发工具能够有效提升我们的开发效率和定位问题的能力。Golang IDE 被 Gopher 接受的其实不太多,Goland 和 VSCode 应该是占比重最大的。vim-go 真心就不推荐了,入门曲线太过陡峭,太过华而不实(vim 党不要喷我),我们就写程序而已,何苦为难自己呢。我日常开发中,Goland,Vscode 一般会配合使用。对于 VsCode 来说,我唯一觉得不方便的是 VSCode 的 Debug 功能,配置起来麻烦,而且总有种很卡的感觉
2021-09-24 23:09:14
224
原创 这些 Goland 技巧,学会开发效率翻倍
hi, 大家好,我是 hhf。《Goland 这些实操技巧,你可能还不会!》介绍了日常开发中一些比较好用的技巧。本篇文章继续介绍一些其他比较好用的技巧。自定义结构 tagGoland 一个很好用的功能:tag 自动补全。在 struct 结构里,可以在字段类型后敲入 json 或 xml 向结构添加标记。Goland 默认的 json 都是下滑线格式的。但是有的时候会有特殊的需求。举个例子:公司对接口返回值的字段是有统一的要求,大部分情况下 json 格式的返回值以下滑线居多,但是也有驼峰格式的。如果遇到这
2021-09-24 23:08:36
282
原创 透过内存看 Slice 和 Array的异同
hi, 大家好,我是 hhf。有这么一个 Go 面试题:请说出 slice 和 array 的区别?这简直就是送分题。但是你如何回答才能让面试官满意呢?我这里就不贴这道题的答案了。但是我想内存方面简单分析下 slice 和 array 的区别。Arrayfunc main() { as := [4]int{10, 5, 8, 7} fmt.Println("as[0
2021-09-24 23:07:50
133
原创 如何欺骗 Go Mod ?
hi,大家好,我是 haohongfan。最近在做 prometheus 生态的 cortex 优化工作,遇到一个比较坑的 go mod 的问题,这里分享一下。我为什么将标题称为:如何欺骗 Go mod 呢?这个挺有意思的,这里先卖个关子,不过确实是突破了 Go mod 的相关特性。(嗯,曹大的 Go mod 十宗罪又可以增加一宗了)在正式展开这个话题之前,需要简单的介绍下 cortex 和 thanos 这两个项目。Prometheus 的局限性说到业务开发基本上都离不开监控系统,Prometheus 做
2021-09-24 23:07:12
319
原创 gin 源码阅读(3) - gin 路由的实现剖析
hi, 大家好,我是 hhf。往期回顾:gin 源码阅读(1) - gin 与 net/http 的关系gin 源码阅读(2) - http请求是如何流入gin的?上面两篇文章基本讲清楚了 Web Server 如何接收客户端请求,以及如何将请求流转到 gin 的逻辑。gin 原理剖析说到这里,就完全进入 gin 的逻辑里面了。gin 已经拿到 http 请求了,第一件重要的事情肯定就是重写路由了,所以本节内容主要是分析 gin 的路由相关的内容。其实 gin 的路由也不是完全自己写的,其实很重要的一部分代
2021-09-24 23:06:28
424
原创 gin 源码阅读(2) - http请求是如何流入gin的?
本篇文章是 gin 源码分析系列的第二篇,这篇文章我们主要弄清一个问题:一个请求通过 net/http 的 socket 接收到请求后, 是如何回到 gin 中处理逻辑的?我们仍然以 net/http 的例子开始func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { &nb
2021-09-24 23:05:22
185
原创 gin 源码阅读(1) - gin 与 net/http 的关系
gin 是目前 Go 里面使用最广泛的框架之一了,弄清楚 gin 框架的原理,有助于我们更好的使用 gin。这个系列 gin 源码阅读会逐步讲明白 gin 的原理,欢迎关注后续文章。gin 概览想弄清楚 gin, 需要弄明白以下几个问题:request数据是如何流转的gin框架到底扮演了什么角色请求从gin流入net/http, 最后又是如何回到gin中gin的context为何能承担起来复杂的需求gin的路由算法gin的中间件是什么gin的Engine具体是个什么东西net/http的requeset,
2021-09-24 16:53:36
237
原创 如何欺骗 Go Mod ?
hi,大家好,我是 haohongfan。最近在做 prometheus 生态的 cortex 优化工作,遇到一个比较坑的 go mod 的问题,这里分享一下。我为什么将标题称为:如何欺骗 Go mod 呢?这个挺有意思的,这里先卖个关子,不过确实是突破了 Go mod 的相关特性。(嗯,曹大的 Go mod 十宗罪又可以增加一宗了)在正式展开这个话题之前,需要简单的介绍下 cortex 和 thanos 这两个项目。Prometheus 的局限性说到业务开发基本上都离不开监控系统,Prometheus 做
2021-08-30 10:34:35
265
原创 见微知著| 带你透过内存看 Slice 和 Array的异同
hi, 大家好,我是 hhf。有这么一个 Go 面试题:请说出 slice 和 array 的区别?这简直就是送分题。但是你如何回答才能让面试官满意呢?我这里就不贴这道题的答案了。但是我想内存方面简单分析下 slice 和 array 的区别。Arrayfunc main() { as := [4]int{10, 5, 8, 7} fmt.Println("as[0
2021-08-24 12:07:35
133
原创 Goland 这些实操技巧,你可能还不会!
工欲善其事必先利其器。对于开发工程师同样如此,一个合适的开发工具能够有效提升我们的开发效率和定位问题的能力。Golang IDE 被 Gopher 接受的其实不太多,Goland 和 VSCode 应该是占比重最大的。vim-go 真心就不推荐了,入门曲线太过陡峭,太过华而不实(vim 党不要喷我),我们就写程序而已,何苦为难自己呢。我日常开发中,Goland,Vscode 一般会配合使用。对于 VsCode 来说,我唯一觉得不方便的是 VSCode 的 Debug 功能,配置起来麻烦,而且总有种很卡的感觉
2021-08-19 16:15:42
411
原创 Goland 这些技巧,学会能让开发效率翻倍!
hi, 大家好,我是 hhf。《Goland 这些实操技巧,你可能还不会!》介绍了日常开发中一些比较好用的技巧。本篇文章继续介绍一些其他比较好用的技巧。自定义结构 tagGoland 一个很好用的功能:tag 自动补全。在 struct 结构里,可以在字段类型后敲入 json 或 xml 向结构添加标记。Goland 默认的 json 都是下滑线格式的。但是有的时候会有特殊的需求。举个例子:正常情况下,公司对接口返回值字段有统一的要求,大部分情况下 json 格式的返回值以下滑线居多,但是也有驼
2021-08-17 14:16:57
827
1
原创 Go interface 原理剖析--类型转换
hi, 大家好,我是 haohognfan。可能你看过的 interface 剖析的文章比较多了,这些文章基本都是从汇编角度分析类型转换或者动态转发。不过随着 Go 版本升级,对应的 Go 汇编也发生了巨大的变化,如果单从汇编角度去分析 interface 变的非常有难度,本篇文章我会从内度分配+汇编角度切入 interface,去了解 interface 的原理。限于篇幅 interface 有关动态转发和反射的内容,请关注后续的文章。本篇文章主要是关于类型转换,以及相关的容易出现错误的地方。e
2021-08-10 10:19:32
197
原创 Go timer 是如何被调度的?
hi,大家好,我是 haohongfan。本篇文章剖析下 Go 定时器的相关内容。定时器不管是业务开发,还是基础架构开发,都是绕不过去的存在,由此可见定时器的重要程度。我们不管用 NewTimer, timer.After,还是 timer.AfterFun 来初始化一个 timer, 这个 timer 最终都会加入到一个全局 timer 堆中,由 Go runtime 统一管理。全局的 timer 堆也经历过三个阶段的重要升级。Go 1.9 版本之前,所有的计时器由全局唯一的四叉堆维护,协程间竞
2021-06-08 10:40:37
195
原创 Go sync.Pool 浅析
hi, 大家好,我是 haohongfan。sync.Pool 应该是 Go 里面明星级别的数据结构,有很多优秀的文章都在介绍这个结构,本篇文章简单剖析下 sync.Pool。不过说实话 sync.Pool 并不是我们日常开发中使用频率很高的的并发原语。尽管用的频率很低,但是不可否认的是 sync.Pool 确实是 Go 的杀手锏,合理使用 sync.Pool 会让我们的程序性能飙升。本篇文章会从使用方式,源码剖析,运用场景等方面,让你对 sync.Pool 有一个清晰的认知。使用方式sync.Po
2021-05-18 10:30:20
580
原创 你真的懂 golang reslice 吗
package mainfunc a() []int { a1 := []int{3} a2 := a1[1:] return a2}func main() { a()}看到这个题, 你的第一反应是啥?(A) 编译失败(B) panic: runtime error: index out of range [1] with length 1(C) [](D) 其他第一感觉: 肯定能编译过, 但是运行时一定会panic的. 但事与愿违竟然能够正常运行, 结果是:[]疑问
2021-05-14 14:22:39
360
原创 疑惑: Go const 会导致程序结果错乱 ?
const 是 Go 里面我们经常使用的关键字, 基本上很难玩出花来. 不过某些特殊情况下 const 会出现你意想不到的结果场景模拟某公司某次营销活动中, 会根据用户 VIP 级别送用户一些优惠券, 最大面值520. 某用户发现自己购买的 500 元钱的商品, 使用 520 的优惠券来支付, 理论上能 0 元购买的商品, 最后却需要支付一个天文数字.这个场景是我自己随便想的, 如果过于夸张, 请原谅我. ^^ 下面我们用代码大概模拟下这个场景:func main() { var totalPr.
2021-05-14 14:21:56
128
原创 当 Go struct 遇上 Mutex
struct 是我们写 Go 必然会用到的关键字, 不过当 struct 遇上一些比较特殊类型的时候, 你注意过你的程序是否正常吗 ?一段代码type URL struct { Ip string Port string mux sync.RWMutex params url.Values}func (c *URL) Clone() URL { newUrl := URL{} newUrl.Ip = c.Ip newUrl.params = url.
2021-05-14 14:21:13
632
原创 一文完全掌握 Go math/rand
Go 获取随机数是开发中经常会用到的功能, 不过这个里面还是有一些坑存在的, 本文将完全剖析 Go math/rand, 让你轻松使用 Go Rand.开篇一问: 你觉得 rand 会 panic 吗 ?源码剖析math/rand 源码其实很简单, 就两个比较重要的函数func (rng *rngSource) Seed(seed int64) { rng.tap = 0 rng.feed = rngLen - rngTap //... x := int32(seed) for i :
2021-05-14 14:20:33
680
1
原创 这可能是最容易理解的 Go Mutex 源码剖析
Hi,大家好,我是 haohongfan。上一篇文章《一文完全掌握 Go math/rand》,我们知道 math/rand 的 global rand 有一个全局锁,我的文章里面有一句话:“修复方案: 就是把 rrRand 换成了 globalRand, 在线上高并发场景下, 发现全局锁影响并不大.”, 有同学私聊我“他们遇到线上服务的锁竞争特别激烈”。确实我这句话说的并不严谨。但是也让我有了一个思考:到底多高的 QPS 才能让 Mutex 产生强烈的锁竞争 ?到底加锁的代码会不会产生线上问题? 到底
2021-05-14 14:18:58
180
原创 最清晰易懂的 Go WaitGroup 源码剖析
hi,大家好,我是haohongfan。本篇主要介绍 WaitGroup 的一些特性,让我们从本质上去了解 WaitGroup。关于 WaitGroup 的基本用法这里就不做过多介绍了。相对于《这可能是最容易理解的 Go Mutex 源码剖析》来说,WaitGroup 就简单的太多了。源码剖析Add()Wait()type WaitGroup struct { noCopy noCopy state1 [3]uint32}WaitGroup 底层结构看起来简单,但 WaitGroup
2021-05-14 14:17:44
164
原创 看过这篇剖析,你还不懂 Go sync.Map 吗?
hi, 大家好,我是 haohongfan。本篇文章会从使用方式和源码角度剖析 sync.Map。不过不管是日常开发还是开源项目中,好像 sync.Map 并没有得到很好的利用,大家还是习惯使用 Mutex + Map 来使用。下面这段代码,看起来很有道理,其实是用错了(背景:并发场景中获取注册信息)。instance, ok := instanceMap[name]if ok { return instance, nil}initLock.Lock()defer initLock
2021-05-14 14:14:11
175
原创 这一次,彻底搞懂 Go Cond
hi,大家好,我是 haohongfan。本篇文章会从源码角度去深入剖析下 sync.Cond。Go 日常开发中 sync.Cond 可能是我们用的较少的控制并发的手段,因为大部分场景下都被 Channel 代替了。还有就是 sync.Cond 使用确实也蛮复杂的。比如下面这段代码:package mainimport ( "fmt" "time")func main() { done := make(chan int, 1) go func() { time.Sleep(5
2021-05-14 14:11:21
503
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人