携程后端面经合集:限流、消息可靠性与交易系统设计
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
2026 年 3 月 18 日:限流与算法
- 最熟悉的项目是什么,是否已经上线?
- 本地缓存结合令牌桶怎样控制频率,令牌如何补充?
- 发消息的服务部署在多台机器时,怎样改造限流方案?
- RateLimiter 的实现思路是什么?
- AT 模式和死信队列分别解决什么问题,二者有什么关系?
- 只使用 MySQL 时如何避免超卖?
- RabbitMQ 消息到达后,消费者写 MySQL 失败怎么办?
- 如何利用辅助编程工具解决开发问题?
- Java 类的公共父类是什么,重写 equals 时为什么要一并考虑 hashCode?
- 如何实现快速排序?
- 一个很大的整数数组中,如何找最大的 10 个数?
- 如何统计长整型数二进制表示中 1 的数量?
- 在数量为 2³¹ 的整数集合里,怎样查找重复值,存在负数时怎样映射位图?
2026 年 1 月 6 日:序列化、JVM 与幂等
- Spring Boot 提供了哪些便利,通过什么机制实现?
- Protobuf 与 JSON 的编码方式有什么区别,如果自己设计序列化框架会怎样做?
- Feign 如何把接口方法声明转换成 HTTP 请求?
- MySQL 各类日志有什么作用,主从复制和 MVCC 怎样工作?
- 慢 SQL 怎样分析和优化?
- new 一个对象会经历什么,内存通常在哪里分配?
- JVM 为什么采用分代思路,了解哪些垃圾回收器?
- 如何看待辅助编程工具,平时具体用于哪些工作?
- Redis 分布式锁和业务幂等分别怎样实现?
- Redis String 的 SDS 结构是什么,数据量增大时怎样处理?
- 布隆过滤器有什么用途,业务数据过期后怎样维护它?
- 策略模式怎样解耦逻辑,Map 和注解能起什么作用?
- 消息队列解决什么问题,可靠性和延迟执行怎样实现?
- Bitmap 有什么用途,Java String 的内存占用受哪些因素影响?
- 如何制定前后端的参数、返回值、分层和代码规范?
- 对称加密和非对称加密有什么区别?
- 如何判断一个很大的整数是否为质数?
- HTTPS 怎样验证证书可信性,对称与非对称密码分别用在哪里?
2026 年 1 月 3 日:异步解耦与搜索
- 实习项目原有基础是什么,哪些部分由你完成?
- 同步调用改成 Kafka 异步处理,会引入哪些问题?
- 幂等与消息一致性有什么区别,Kafka 不可用时怎样处理?
- Elasticsearch 响应慢时怎样优化?
- 倒排索引与 MySQL 字符串索引有什么区别,ES 怎样实现模糊搜索?
- 分布式系统和单点系统有什么差异?
- Redisson 在项目中解决了什么问题,它是否自动减少流量?
2025 年 12 月 15 日至 26 日:并发与交易
- 项目中有哪些难点和亮点?
- 字符串字面量赋值时可能创建几个对象,判断依赖什么条件?
- JVM 内存区域和常见参数有哪些?
- 常见垃圾回收算法有哪些,CMS 使用哪类算法?
- 线程池有哪些参数与拒绝策略,8 核 CPU 的线程数应该怎样确定?
- CAS 和 AQS 的实现原理是什么?
- MySQL 怎样实现事务,更新语句与 MVCC 有什么关系?
- Redis 有哪些数据类型,跳表怎样工作?
- Redis 所谓“单线程”指什么,是否所有工作都由同一线程完成?
- 怎样应对缓存击穿、防止重复创建订单?
- Spring 事务怎样生效,哪些调用方式会让事务失效?
- 消息重复投递时,消费者怎样保证业务只执行一次?
- 怎样把有序数组构造成二叉树,再输出前序遍历?
- 令牌桶有哪些局限,怎样改进?
- 设计转账系统时,余额与流水怎样保持一致?
- 收款账号不合法时,已经执行的付款操作怎样处理?
- TCC 的空回滚与悬挂是什么?
- 热点账号的行锁发生排队甚至超时时,怎样处理?
- 给定若干面额和目标金额,如何求凑出金额的最少硬币数?
2025 年 12 月 8 日:旅游业务系统设计
- 如何设计每秒十万级请求、目标延迟低于 500 毫秒的抢票系统,并保证库存准确?
- 同一酒店在多个渠道销售时,价格怎样同步?
- 如何向百万在线用户推送航班动态,并按航线和用户等级安排优先级?
- 十亿级订单怎样分库分表,如何支持按用户、时间和目的地查询?
- 用户大量查询不存在的酒店编号时,怎样保护数据库?
- 未支付订单超时后怎样回收库存并通知用户?
- 酒店库存、支付单和通知跨多个系统时,怎样设计一致性方案?
- 酒店搜索怎样兼顾文本相关性、价格、评分与库存新鲜度?
- 酒店秒杀达到每秒五万次下单时,怎样防止超卖和系统过载?
- 服务堆内存持续上涨并频繁 OOM,怎样分析和处理?
- 多个服务实例同时修改酒店价格时,怎样保证写入正确?
- 日均 10 TB 的日志检索平台怎样设计,如何按订单号和用户编号检索?
- MySQL 与 Redis 中的酒店库存怎样保持一致?
- 第三方航司接口持续慢响应时,怎样设计超时与熔断?
- 如何支持附近酒店的高并发检索?
- 订单号怎样保证全局唯一,并容纳时间和业务信息?
- 十亿条历史订单怎样迁移到 ClickHouse,并维持线上查询可用?
- 核心预订服务怎样设计多活架构,应对单机房故障?
2025 年 12 月 5 日:基础知识
- InnoDB 与 MyISAM 有什么区别,B+ 树相较 B 树有什么特点?
- 什么是回表,联合索引为什么有最左前缀的使用特点?
- ACID、隔离级别和间隙锁分别解决什么问题?
- 乐观锁与悲观锁怎样实现?
- 进程和线程有什么区别,进程之间怎样通信?
- kill 命令通过什么机制影响进程,创建子进程时操作系统做了什么?
- 为什么需要虚拟内存,用户态、内核态和系统调用有什么关系?
- 从 URL 到页面显示经过什么过程,HTTP 连接怎样复用?
- TCP 怎样保证可靠传输,UDP 适合哪些场景?
- HashMap 怎样扩容,ConcurrentHashMap 怎样保证并发安全?
- synchronized 的实现与锁状态有什么关系,CAS 怎样处理 ABA?
- 怎样判断对象是否可回收,不同代的回收有什么特点?
- Redis 为什么适合缓存?
- RabbitMQ 怎样组织顺序消费,消息积压如何处理,和 Kafka 怎样选型?
《参考解析》
消费失败与重复消费要放在一起回答
先完成本地事务,再确认消息。写库失败时保留可重试状态;超过重试次数的消息进入可检查的失败记录或死信队列。因为“事务已提交、确认尚未送达”也会导致再次投递,所以业务请求编号应有唯一约束。对余额、库存等修改,幂等检查与真正写入应在同一事务中完成。
位图先定义值域
2³¹ 是数据个数,不代表整数的取值范围只有这么大。如果输入允许所有 32 位有符号整数,可以把值减去最小有符号整数,映射到 0 至 2³²-1;完整位图需要 2³² 位,即 512 MiB。内存不够时,按值域或哈希分区,逐块处理。位运算和偏移计算应在足够宽的整数类型中完成。
最少硬币数
令 dp[a] 为凑出金额 a 的最少硬币数。dp[0]=0,对每个正金额尝试最后使用的面额 c:若 a-c 可达,就用 dp[a-c]+1 更新。最终状态不可达则说明无解。时间 O(目标金额×面额数),空间 O(目标金额);这要求每种面额可重复使用。
把转账的不变量说清楚
同库转账可以在一个事务中校验账号、扣款、入账并记录流水,用稳定的业务编号挡住重试。跨服务时再讨论 TCC 或其他分布式事务方案。Try 应预留资源,Confirm 和 Cancel 都应幂等;Cancel 先于 Try 到达时要记录取消事实,让后来的 Try 识别并停止,避免悬挂。热点账户应先控制并发和排队,不能为了少等锁而绕过余额正确性。
订单超时回收是一场状态竞争
支付回调与超时任务可能同时到达。用条件更新让订单只从“待支付”进入一个后续状态,成功改变状态的一方才执行对应库存动作。超时消息可以延迟、重复,消费者仍以数据库状态为准;任务丢失则由扫描尚未处理的超时订单补齐。
多维查询不必都压在分片主库
先按核心交易访问路径选择分片键,例如用户编号;订单号需要能定位分片。目的地统计、跨用户报表等查询可以交给同步出来的检索或分析数据。同步链路要能重放、核对,页面也要明确自己读取的是实时交易状态还是存在延迟的分析结果。
抢票系统区分查询与真正下单
十万 QPS 首先要问是查询还是创建订单。静态班次与票价信息可以缓存,下单入口则控制进入库存处理环节的并发量。库存预占、订单创建和超时释放用明确的状态转换衔接,同一请求重试不得多次占票。500 毫秒是要通过压测验证的目标,需要分别测排队、库存操作、写库和远程调用,不能用一张架构图保证。
多渠道价格同步先确定谁能改价
为同一房型和日期确定价格权威来源,变更带版本号或递增序列,渠道拒绝旧版本覆盖新值。同步失败可以重试,再通过定期比对补齐遗漏。真正下单时应校验报价有效期和当前可成交价,把“页面上看到的报价”与“已经确认的订单价格”区分开。
多活的难点是故障时谁有写入权
可以让不同酒店或业务分片有明确的主写区域,其他区域承担读取或接入。主写区域故障时,切换流程必须阻止旧区域继续写入,否则两个机房可能各自卖出同一份库存。异步复制有数据延迟,同步确认有跨地域时延;需要按可接受的数据损失和恢复时间选择方案,并通过故障演练验证。