Java 17 + Spring Boot + Kafka + Redis:互联网大厂电商场景面试实录|燕双非的三轮拷问
场景:互联网大厂电商技术岗面试
人物:严肃面试官、搞笑水货程序员燕双非
第一轮:订单与库存的高并发设计
面试官:假设你负责一个秒杀活动,用户下单量瞬时暴涨。你会先从哪些技术点入手?
燕双非:我会先把 Spring Boot 项目起起来,然后用 Redis 做库存预扣,Kafka 异步削峰,保证数据库别直接被打爆。
面试官:不错,方向是对的。那你说说为什么不用同步扣库存直接落库?
燕双非:因为同步的话大家一起挤数据库,可能会把 MySQL 挤成早高峰地铁。我一般会先在 Redis 里做原子扣减,再把消息发到 Kafka,后面异步生成订单。
面试官:很好,至少你知道“先挡流量,再落库”。那如果 Kafka 消息重复消费了怎么办?
燕双非:嗯……重复就重复吧,反正人类也会重复点刷新。技术上应该是做幂等,比如订单号唯一索引、消费记录表、或者 Redis 去重。
面试官:回答得还可以,说明你不是完全靠感觉写代码。
面试官:再说说 MyBatis 和数据库连接池,你会怎么选?
燕双非:MyBatis 比较适合订单、库存这种 SQL 可控的场景,HikariCP 连接池性能也更稳,别拿 C3P0 去扛大促,容易被老板追着打。
第二轮:会员、支付与风控链路
面试官:电商订单创建后,接下来是支付、优惠券、风控、通知。你怎么设计接口鉴权和安全方案?
燕双非:可以用 Spring Security + JWT。用户登录后签发 token,前后端分离时每次请求带上 token,网关或过滤器校验即可。
面试官:JWT 的优点和风险各是什么?
燕双非:优点是无状态,扩容方便;风险是 token 一旦签发,撤销不太方便,得配合黑名单、短过期时间和刷新机制。
面试官:很好。那支付回调的幂等怎么做?
燕双非:支付回调可能会重试,所以订单状态更新要做幂等控制,比如只允许从“待支付”流转到“已支付”,并且通过唯一流水号防止重复入账。
面试官:继续。风控系统要怎么做实时拦截?
燕双非:可以把用户画像、下单频率、设备指纹之类的数据实时汇总,配合规则引擎或者简单策略判断。复杂一点可以走 Kafka 流式处理,或者接入独立风控服务。
面试官:还行,已经开始像个做过业务的人了。那如果支付链路里要加审计日志和性能监控呢?
燕双非:日志用 Logback 或 SLF4J 统一输出,监控可以接 Micrometer,再把指标上报到 Prometheus 和 Grafana。慢接口再用链路追踪看一下,可能是数据库慢,也可能是 MQ 堆积。
面试官:不错,至少你知道不是让用户“耐心等待”就能解决问题。
第三轮:商品搜索、推荐与实时互动
面试官:现在我们要做商品搜索和实时推荐,还要支持前台客服与用户在线沟通。你会怎么设计?
燕双非:搜索可以用 Elasticsearch 做商品索引,推荐可以结合用户行为日志和简单画像。实时沟通可以用 WebSocket,客服端和用户端建立长连接。
面试官:如果搜索结果要支持高亮、分页和排序,你会怎么考虑?
燕双非:高亮和分页是 ES 的基本操作,排序要结合热度、销量、价格等字段。分页别深翻页太狠,不然 ES 也会喘。
面试官:那推荐里的埋点数据怎么传?
燕双非:前端埋点先发到后端,再通过 Kafka 进入日志或行为分析链路。后面可以做离线统计,也可以做实时计算。
面试官:客服聊天呢?你怎么保证消息不丢?
燕双非:WebSocket 负责实时推送,消息落库做持久化,必要时结合 Redis 记录在线状态。断线重连后还能补发未读消息,不然客服一句“在的亲”发出去,用户没收到就尴尬了。
面试官:最后一个问题:如果你的接口里要支持文档式 API 管理和自动生成说明,你会用什么?
燕双非:Swagger/OpenAPI,方便前后端联调,也方便测试和维护。
面试官:行,今天就到这里吧。你回家等通知吧。
面试问题详细解答
1. 秒杀场景为什么要用 Redis 预扣库存 + Kafka 异步下单?
秒杀活动的核心矛盾是“瞬时流量远大于系统平均承载能力”。如果请求直接同步写数据库,数据库会因为锁竞争和连接耗尽而成为瓶颈。Redis 适合做高并发原子操作,可以先做库存预扣;Kafka 适合做消息缓冲和削峰填谷,把下单请求异步化,后端消费者再慢慢落库。这样可以把高峰压力从数据库转移到缓存和消息队列,系统更稳定。
2. Kafka 消息重复消费如何处理?
消息队列通常只保证至少一次投递,因此重复消费是常见问题。常见做法包括:业务幂等设计、数据库唯一约束、消费日志表、Redis 去重键、状态机控制等。比如订单创建接口可以基于业务单号做唯一索引,消费者收到重复消息时插入失败或直接忽略,从而避免重复下单。
3. 为什么电商订单链路常用 MyBatis 而不是完全依赖 JPA?
电商订单、库存、支付等核心链路往往对 SQL 可控性、性能和复杂查询要求较高。MyBatis 更适合显式编写 SQL,便于做索引优化、分库分表适配和复杂条件查询。JPA 更偏向对象关系映射,开发效率高,但在复杂业务场景里有时不如 MyBatis 透明可控。实际项目里也常混合使用