面灵AI

腾讯后端开发岗面经 15

时间
2026-09
来源
牛客网

《面试题目》

  1. 手撕:设计限流类并实现 allow(userId, timestamp),同一用户 10 秒内请求超过 3 次时返回 false
  2. 介绍实习期间负责的业务
  3. 如何保证 Kafka 消息投递成功?
  4. 如何避免消息被重复消费?
  5. 线程池参数如何设置?
  6. 请做一下自我介绍
  7. 手撕:实现 BitMap 的 Get、Set 和 Delete 操作
  8. Map 的用途和常见实现有哪些?
  9. Unordered Map 的底层原理是什么?
  10. 红黑树主要用于解决什么问题?
  11. 介绍实习业务和个人承担的工作
  12. 实习项目中最困难的部分是什么?
  13. 方案是如何设计的,主要考虑了哪些因素?
  14. 设计方案时如何评估性能?
  15. 日常如何与产品经理协作?
  16. 与产品经理出现分歧时如何处理?
  17. 遇到高压情况时如何解决?
  18. 是否发现并推动过公司架构优化,最终是否落地?
  19. 介绍实习经历
  20. 算法:实现 LRU 的变形题
  21. 给定一个请求体,分析其中的网络安全漏洞
  22. 如何防止中间人攻击,常见加密手段有哪些?
  23. 微信扫码支付中,用户、商家和微信服务器三方如何交互?
  24. 用户加载付款码后断网,是否还能完成扣款?
  25. 二维码和一维码的本质是什么,是动态还是固定的?
  26. 为什么付款码是动态的而收款码通常固定?
  27. 动态付款码如何绑定并识别固定用户?
  28. 商家和用户都断网时,支付产品应如何设计体验?
  29. MySQL 和 PostgreSQL 有什么区别,各自有哪些优缺点?
  30. Go 和 Java 有什么区别?
  31. Go 使用 Channel 替代锁适用于哪些场景?
  32. 介绍项目关键字段、核心流程及其设计原因
  33. 智能运维业务主要解决什么问题?
  34. 打卡流程如何实现?
  35. 定位功能如何实现?
  36. MySQL 索引失效的场景有哪些?
  37. 如何分析一条 SQL 语句?
  38. 若依框架的登录流程和关键细节是什么?
  39. 线上请求响应变慢时如何排查?

《参考解析》

限流类与滑动窗口

10 秒 3 次是典型的滑动窗口限流。题目给的是单调递增的时间戳,所以可以只用两个变量:记录当前窗口的起点 windowStart 和窗口内已通过的计数。新请求进来时,若 timestamp − windowStart ≥ 10 秒就重置窗口并把计数置 1;否则计数加一,超过 3 就返回 false。若时间戳不保证递增,就要用双端队列保存窗口内的请求时间戳,每次弹出过期的再判断长度。面试官通常会继续追问并发安全和多实例:单机 map 只保护本进程,多实例要放到 Redis,用 Lua 脚本把”读计数 + 判断 + 写回”做成原子操作,或者改用令牌桶。

Kafka 不丢不重

投递成功靠生产者侧:acks=all、合理的 retries,并开启幂等生产者(enable.idempotence=true,同时保证 max.in.flight.requests.per.connection 不超过 5),需要跨会话、跨分区保证就上事务。重复消费的根因是”业务处理成功但位移没提交”或反过来。正确做法是手动提交位移,把业务写入与位移更新放进同一个事务或同一张表,再给业务加唯一键或去重表做幂等——Kafka 只保证至少一次,精确一次要靠消费端自己兜。

线程池参数怎么定

CPU 密集型任务核心线程数取核数(或核数 + 1);IO 密集型可以按”核数 ×(1 + 等待时间 / 计算时间)“估一个初值。队列必须有界,并配 CallerRunsPolicy 这类拒绝策略把压力顶回上游形成背压。真实数字只能压测出来:先按公式给初值,再看 QPS、P99 延迟、队列积压量和拒绝次数逐步调。线程数不是越大越好,线程切换开销和下游容量都是硬约束。

MySQL 与 PostgreSQL

MySQL 主流引擎 InnoDB 默认可重复读,靠 MVCC 加间隙锁实现;索引是聚簇的,主键即数据,二级索引叶子存主键、查询非索引列要回表。PostgreSQL 默认读已提交,堆表加多版本,支持更丰富的数据类型(JSONB、数组、范围类型)、更完整的 SQL 能力(窗口函数、CTE)和更活跃的扩展生态(PostGIS、pgvector),DDL 也能放进事务。选型应该落到团队技术栈和具体需求的匹配度上,只回答”PG 更先进”没有说服力。

Go 与 Java,以及 Channel 替代锁的场景

Go 编译出静态二进制,goroutine 由运行时按 M:N 调度,channel 是语言级通信原语;Java 跑在 JVM 上,生态和中间件积累更厚。channel 适合”数据在多个 goroutine 之间转移所有权”的场景:生产者消费者、扇入扇出、超时取消、任务流水线。共享状态的简单读写用 mutex 更直接,拿 channel 去做计数器或复杂共享结构反而更难读、更容易出错。CSP 的思路是”用通信来共享内存”,不等于 channel 一定比锁快。

微信扫码支付与断网

付款码支付是商家侧发起的:用户手机展示付款码,商家扫码枪把码传给商家系统,商家系统带码请求微信完成扣款。所以用户出示付款码后自己断网,扣款仍可能成功——付款码是微信服务端生成的短时令牌,与用户账户绑定,且通常一次性、每分钟刷新,这样既完成身份识别也防止被拍照盗用;扣款成功与否由商家侧的请求决定。收款码则绑定商家账户,是长期稳定的,由用户扫码后在自己手机上调起支付,用户不联网就付不了。两边都断网时,付款码链路连请求都发不出去,只能走离线记账,恢复后再对账冲正。这类设计题面试官想看的是资金安全与可用性怎么权衡,以及失败时如何明确告知用户,绝不能让人误以为已支付成功。

索引失效与慢 SQL 排查

先用 EXPLAIN 看 type、key、rows、Extra 判断是否真的走了索引,再逐条排查:索引列上做了函数或运算、隐式类型转换(字符串列传数字)、前导模糊 LIKE '%x'、联合索引不满足最左前缀、OR 两侧有一侧没索引、范围条件之后的列失去有序性。还有一类是优化器估算回表代价过高而主动放弃索引,这严格说不是”失效”而是选择,答的时候应当区分开。线上慢 SQL 靠慢查询日志和 performance_schema 定位,再结合执行计划与数据分布决定是加索引、改写法还是改表结构。

原帖为系列合集的第 6 段(面经 06)在标题处即被截断,没有留下题目内容,故未收录。