面灵AI→

Touka Games Golang 后端实习 一面二面已 OC

轮次
一面、二面
结果
已OC
时间
2026-09
来源
牛客网

《面试题目》

一面(约 31 分钟,技术面)

  1. 你先介绍一下你自己。
  2. 你第一个高并发秒杀系统就是你自己做的吗?
  3. 你是部署到哪里跑测试的?
  4. 压测脚本是用什么做的?
  5. 你是怎么测的?跑了多少个 Goroutine 同时测?
  6. 为什么并发两千多的时候,QPS 只有一千多?
  7. 现在请求某一个商品,它在 Redis 里缓存的数据可能需要刷新,你是怎么做的?
  8. 并发有很多请求要查询某一个商品,发现 Redis 里没有,你是怎么操作的?
  9. 100 个请求都要请求这个数据,是去 MySQL 里查 100 次吗?
  10. 最后 MQ 怎么打给 MySQL?100 个请求同时来了,Redis 里都空了,这 100 条消息都是做同样的事情吗?
  11. 我现在是去查一个数据、不是往里面插入,你说一下应该怎么操作?
  12. 你的 Golang 是自己自学的?
  13. 一个空的 interface 和一个空的 struct 该在什么地方用?
  14. 说的是空接口,你在什么地方有用?
  15. 自己尝试封装过 error 吗,就是自己去封装一层错误处理?
  16. 封装之后,外面拿到这个错误,你怎么判断这是哪个错误?
  17. 写代码时想判断错误是什么错误,然后可能在服务器这边做不同的处理,你知道该怎么判断吗?
  18. 你用过 Linux 系统吗?
  19. 服务部署上去之后,你是直接用 IP 去访问它的服务吗?
  20. 部署服务都是用 Docker 在上面吗?你写的那些功能都是直接丢到服务器上跑?
  21. 比如自己生成一个可执行文件,然后上去跑那种,你试过吗?
  22. 我现在要部署到服务器上,Golang 写的代码要用一个可执行程序部署上去,你跟我说一下该怎么做?
  23. 现在随便给你一个数,我想求它对 1024 的余数,有什么很快的方法能够算出来?
  24. 开学是大三了吧?大三就不用上课了吗?
  25. 你实习是希望以后就留在这里,还是说就想来练手就走?
  26. 假如你转正了,你期望的薪资大概是多少?
  27. 你现在开发过程中,对 AI 大概是怎样的使用方式?
  28. 你做一个项目,AI 做的东西和你自己做了多少,AI 做了多少?
  29. AI 写的代码你有觉得有什么问题吗?你有看过吗?

二面(约 22 分钟,业务面)

  1. 咱们先做一下自我介绍。
  2. 上一轮的面试有没有跟你讲我们做的业务大概是哪块的?
  3. 你平时对海外的业务有了解吗?
  4. 你说到了广告,你对广告有了解吗?无论是国内还是海外。
  5. 后端分为游戏后端、变现侧后端、风控后端等方向,你对这些有了解过吗?或者更想尝试哪个方向?后续的职业规划是什么?
  6. 你们这个中台,参与的是有几个人呢?
  7. 你主要负责哪一块?
  8. 你接手的这期间,这个中台有做一些新的开发吗?还是主要就是做维护?
  9. 咱们有比如说自己独立地做过一些中台的模块或者是项目吗?不一定是上线的。
  10. 你能帮忙分为几个模块,简单介绍一下你的这个系统吗?为什么做它、需求怎么来的?实现是你全部参与还是有人一起?你分了哪几个维度去实现它的目标和需求?
  11. 你用 AI 用得多么?
  12. 你现在用 AI 的话,你都会用到哪些?就是你在什么时候会用 AI?
  13. 【场景题】比如我现在需要你帮忙开发一个短剧维护中台,要在这个中台上显示当前所有短剧、所有短剧需要热度排序、可以预览短剧并展示一定的数据、支持上传下载,以及与前端 APP 的一个交互。如果让你做这样的一个后台,你会在哪些阶段用到 AI、怎么用?

《参考解析》

秒杀系统的压测与缓存击穿:QPS 只有一千多,通常不是「并发上不去」,而是瓶颈在别处:压测客户端自己先到极限(Goroutine 数不等于有效并发连接,压测机和被测服务抢同一台机器的 CPU 与网卡)、HTTP 连接没有复用导致握手开销占满、日志和 JSON 序列化这类同步开销、全局锁竞争、以及 Redis 单线程命令排队。排查顺序是先看压测机与被测机的 CPU/网卡/连接数,再用 pprof 看火焰图,最后才怀疑业务逻辑。缓存刷新有两条路:一是写 DB 后主动更新缓存(简单但并发下可能写入乱序),二是删缓存让读请求回源(更常用),配合逻辑过期避免热点 key 同时回源。缓存击穿(key 不存在或刚过期、100 个请求全部打到 MySQL)的正解是「只放一个请求过去」:用 Redis SETNX 加锁让单个请求重建、其余短暂自旋或返回旧值;或者逻辑过期 + 异步刷新,读请求先返回旧值;再用布隆过滤器拦住数据库里根本不存在的 key。100 条消息打给 MySQL 也不该是 100 次写:把请求合并成一条重建任务,消息带唯一业务键做幂等消费,消费端只让第一个成功、其余丢弃。

Go 空接口与空结构体:interface{}(Go 1.18 后可以写 any)用来承载任意类型,常见于 JSON 编解码的中间结构、日志字段、容器类库和反射场景;它的代价是装箱与类型断言的开销,能用泛型或具体类型就别用它。struct{} 是零大小类型,不占内存,典型用法是 map[string]struct{} 做集合(value 不占空间)、chan struct{} 做信号通知(只关心事件不关心数据)、以及没有状态的方法接收者。两者的区别是:空接口表达「什么类型都可能」,空结构体表达「没有数据」,面试时把使用场景和代价一起说清就够了。

error 封装与判断:封装用 fmt.Errorf("查询订单失败: %w", err),%w 保留错误链。上层判断不要比字符串,用 errors.Is(err, ErrNotFound) 判断是不是某个哨兵错误,用 errors.As(err, &target) 提取具体错误类型再读它的字段(比如 code、httpStatus)。自定义错误实现 Error() string 接口,需要携带上下文就定义结构体错误类型,并在跨层传递时始终用 %w 包一层而不是新建一个错误,否则错误链就断了。业务码不要塞进错误字符串里靠前缀匹配,那是典型的事故来源。

部署与交付:本地 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o app 交叉编译出静态可执行文件,scp 或发布系统推送到服务器,用 systemd 托管(Restart=always、限定运行用户、日志交给 journald),前面挂 Nginx 做反向代理与 TLS 终结,配域名而不是裸 IP 加端口。更规范的做法是多阶段 Docker 构建(构建阶段带 Go 工具链,运行阶段只留二进制和时区文件),配健康检查、优雅退出(监听 SIGTERM 后停收新请求并等待在途请求结束)、灰度与回滚。别用 root 直接 nohup ./app & 这种跑法。

位运算求 1024 的余数:1024 是 2 的 10 次方,对非负整数而言 x % 1024 完全等价于 x & 1023,位与比取模快,也是面试官想听的点。负数要先取绝对值或用补码语义处理,Go/Java 里负数取模结果符号跟被除数走,直接位与会得到不同的值。推广一下:任何 % 2^k 都能转成与 2^k - 1 的位与,反过来「判断能否被 2 的幂整除」也是同理。编译器对常量 2 的幂本来就会做这个优化,但面试里能主动指出来是加分项。

短剧维护中台的 AI 使用场景:分阶段说更清楚。需求阶段用 AI 把一句话需求拆成用户故事和字段清单(短剧名、封面、集数、状态、热度分、上传人),自己再核对业务口径;设计阶段用 AI 出表结构草稿、接口契约草稿和状态机图,热度排序的算分口径必须自己定(播放量、完播率、时间衰减怎么加权);编码阶段用 AI 生成 CRUD、分页、热度排序的样板代码,上传下载改成对象存储的预签名 URL,AI 辅助写转码与截图预览的调用;测试阶段用 AI 造 Mock 数据和边界用例(超大文件、断点续传、并发上传同名文件);上线后用 AI 读慢查询日志提优化建议。要明确说出 AI 不负责的部分:权限模型、与 APP 的接口契约、存储与转码选型、以及任何涉及数据口径的决定,这些都是人来拍板。反问环节可以问业务方向、团队是传统编程还是 AI coding 为主、公司是否提供 token、以及前三个月对新人的预期,这些问题能显示你在认真评估匹配度。