1. 基础知识
1.1 Golang 值类型、引用类型分别有哪些
值类型:int、float
引用类型: string、切片...
1.2 如果我先声明了 一个长度为 5 的 int 切片,传递到另一个 func,做了 append 会发生什么?原来的切片会被改变吗
不会,因为发生扩容了,会导致原先切片底层指向的数组发生改变指向新的数组,原切片不会受到影响
1.3 声明一个长度为 1024 的 string 复制到新的变量,内存占用情况?
string 是只读的引用类型,赋值时会做前拷贝,仅拷贝元信息, 内存占用几乎不会发生变化
1.4 了解 Golang Map 的底层实现吗
Hash ,如何防止哈希冲突的?
不太清楚
1.5 按顺序声明了 3 个 defer,最后一个 defer 发生 panic,前面的还会执行吗
不会,panic 触发会中断程序,向上传播,其余的 defer 不会执行
1.6 不同的 Goroutine 之间发生 panic可以在其他 Gorotine Recover 到吗
不可以,panic 只会在触发它的 goroutine 内向上传播,不会跨越 goroutine 边界;
1.7 Goroutine 顺序交替打印
通过 sync.waitGroup 包,执行完成后打印
还有其他办法吗?
不太清楚了
1.8 读取已经关闭的 channel 会发生什么?
如果 channel 中有剩余的数据,会持续读取,直到 ok = true,会返回零值和 false
1.9 向已经关闭的 channel 写入数据会发生什么?
会发生 panic,channel 本身是一个 struct,关闭后会把 closed 字段标记为 true,此时如果写入数据会触发 panic
1.10 Gorm 用过 Preload 吗,有了解过生成出来的 SQL 长什么样吗?
用过preload,但是不清楚生成的 sql 是怎样的,个人理解应该是两条 sql 语句,preload 的数据是后查询的,根据父语句查询出来的数据作为 where 条件进行关联查询
1.11 Gorm 如何实现 upsert?
可以用 clauses下的 OnConflict 方法实现,定义冲突列和要执行的操作,OnUpdate、DoNonthing 等,本质上是用 mysql 的 on Duplicate Key
2. 数据库
2.1 说说事务的 4 个隔离级别
- 读未提交
- 读已提交
- 可重复读
- 串行化读
2.2 说说它们的区别
读未提交
- 存在脏读和幻读、不可重复读
- 脏读:是指读取到其他事务修改且还没有提交的数据
- 幻读:是读取到其他事务新增/删除但是还没有提交的数据
- 不可重复读:两个事务同时修改同一条数据,事务 A 中先读取数据,事务 B 修改了这条数据,事务 A 再次读取时,数据发生了变化
读已提交:解决了脏读问题,但是仍然存在幻读和不可重复读问题
可重复读:解决了脏读和不可重复读,仍然存在幻读问题。InnoDb 默认的隔离级别
串行化读:解决了上述问题,本质上是让每个事务顺序提交,所以性能相对比较差
2.3 都用过哪些索引类型?
- 主键索引
- 普通索引
- 联合索引
2.4 用过聚簇索引和非聚簇索引吗?
只了解聚簇索引是吧索引和数据放在一起,mysql 的主键索引就是聚簇索引。其他的没深入了解过
2.5 说说 MVCC
多版本并发控制,只了解 mysql 是通过多版本控制的方式来实现读操作不堵塞写操作的,具体原理不太清楚。
2.6 有 A、B、C 三个字段,abc 和 ac 频繁读取,如何设置索引?
设置一个 acb 字段的符合索引,遵循最左前缀原则,a优先级最高,ac 频繁读取,所以设置 acb
为什么只设置一个?
已经存覆盖索引,重复设置索引冗余了,导致发生不必要的回表查询
3. 消息队列
3.1 用的消息队列中间件?
asynq,是基于 redis 的 pubsub + list 实现的
3.2 是如何保证任务不丢失的?
持久化, 所有 task 会被持久化保存
3.3 是如何保证消费不丢失的
通过状态标记,每个任务有对应的执行状态,被分别存储到不同的消息队列里
3.4 怎么实现订单超时取消?
通过延迟队列实现, 本质是借助 redis 的 zset + 轮询机制,查询到 score < 未来时间戳,标记为过期,触发消费
4. 分布式
4.1 了解过 go-zero 吗?
无
4.2 你们直接接触过分布式吗?
简单了解过
4.3 微服务对比单体服务差异和优缺点?
- 服务复用
- 对于单体项目,不同模块之间只要更新了代码,整体都需要重新部署,而微服务只用更新对应的服务就可以了
- 不同服务可以部署多个主机,提升性能
- 缺点:运维成本高、迭代心理负担重
5. 运维
5.1 你们有做 CI/CD 吗?
有运维同事负责,本身是用了 jenkins 的 freestyle 构建的,用了 gitlab 插件 通过 hook 做自动化部署,本身是用了 Supervisor 做进程管理来进行部署的
5.2 监控方面
我们用了 sentry-gin,做了监控埋点,主要监控支付异常问题,还有全局请求耗时指标之类的
5.3 网关方面
本身是用的 Nginx
面试总结
- channel 和 goroutine 方面还是太薄弱了,详细到某些场景设计就答不出来
- 分布式没有接触过,自己做的最佳实践不是完整项目没什么参考价值
- 运维方面,k8s 不太熟, 需要做好准备
- 面试结果:待更新

评论区
评论加载中...