Go 翻山越岭——常见业务问题

6 minute read

上回说到通过工具 readelf 和 dlv 调试 Go 语言程序,为什么需要这么做调试代码呢?我单纯地想写个代码,不行吗,常见业务不都是代码实现没有听谁说过要进行底层调试啊。关于业务,写代码当然可以,而当我们面临性能问题时,就需要涉及算法与数据结构。糟糕,你一说到算法我就心虚。如果你算法基础薄一点,没关系,东方不亮西方亮,算法走不通,我们走查看修改底层代码做起,仅需要细心和逻辑推理就能解决部分问题。因此,今天的主题是“探究 Go 语法背后的秘密”。

常见业务场景

你说写业务不用关心底层,OK,那我们今天先讲原理,直接上业务场景。

场景1,这两段代码运行速度怎样?第一个比第二个快?

 1// 代码1
 2package main
 3
 4type person struct {
 5    age int
 6}
 7
 8func main() {
 9    var a = &person{111}
10    fmt.Println(a)
11}
 1// 对比代码2
 2package main
 3
 4type person struct {
 5    age int
 6}
 7
 8func main() {
 9    var b = person {111}
10    var a = &b
11    fmt.Println(a)
12}

场景2,类型转换的原理是怎样的?

1package main
2
3func main() {
4    var a = "hello"
5    var b = []byte(a)
6    println(b)
7}

场景3,怎么找到 make 和 new 这种 Go 语言自带数据结构的具体实现?

场景4,有一个中台服务,划分了许多用户等级,具体规则如下:(以下场景都没遇到过,不过可以来做分析)

初级会员,发帖数 > 10

中级会员,充值 > 1000 RMB

高级会员,发帖数 > 100 ,充值 > 10000 RMB

如果其中项目数量 = 几百,那么每个项目都应该有自己的会员规则吗?也就是说,我们需要单独定制这么几百个代码吗?

场景5,有一个数据查询服务的需求,我们想要做成一个统一的流程,目标是想简化部门的数据获取需求:

(1)由用户提供查询条件,但用户分散在不同领域或部门,并且没有统一标准,并且会经常变。

(2)需要用到代理去查询不同模块的数据

(3)外部模块没有统一的数据获取规范

如果每次用户修改了数据并提出了需求,我们就一定要写一遍代码吗?(小剧透:所以我们需要去做一套中间数据获取层)

场景6,公司非常看好 gRPC,尤其在上 K8s 之后 gPRC 显得更云原生些,我们想从 Thrift 切换到 gRPC,但是之前的项目都是 Thrift,怎么办?

(1)之前的项目已经有几千甚至上万的 Thrift 服务、已经有单独的仓库去管理 Thrift IDL

(2)想提供 gRPC 接口

(3)目前的解决方案是手动把 Thrift IDL 按照 pb 文件的格式模仿抄写一遍,但效率太低。

场景7,我是个 DBA,了解 MySQL 的索引机制,了解哪些数据表是数据量比较大的核心表,我也可以将用户代码中的 SQL 都提前出来,不过我希望在上线的时候能够自动做一些工作,比如做一个拦截器,提醒用户要给表加索引才能添加数据(这个问题在我们实际线上会经常遇到,一旦发生还是比较蠢的)。

(1)我是 SQL 专家

(2)我知道怎么获取到表的索引 (3)我可以把用户代码里的SQL扫描出来

场景8,我们公司是做 ToB 的服务,我们的软件会先编译完再卖出去,比如我们公司是用 Go 开发的,假如我们是卖 gRPC 服务的,而用户想要在此基础上做一些定制,他们也有自己的开发人员,比如说实现内部的 RPC 协议。用户想定制,而我们想不给他们源代码并且能够支持他们的定制需求,这就需要些技术手段来解决。(特别是 Go 语言的生态还不是很完善,并且每个方案都有自己的缺陷)

总共罗列了 8 个业务场景,我们可以通过探究 Go 语法背后的秘密就能去解决的问题,有没有哪个场景是你所遇到的?下回我将进行一一细致地讲解。