
1. 电商场景下的Java技术栈全景解析最近帮一位准备大厂面试的朋友复盘电商项目发现很多候选人对技术栈的理解停留在框架名称的堆砌。实际上大厂面试官更关注技术选型与业务场景的契合度。以典型电商系统为例我们拆解下真实场景中的技术决策逻辑。电商系统的核心特征是三高高并发、高可用、高一致性。这决定了技术栈的选型方向Spring Boot作为基础框架其自动装配特性快速搭建微服务Starter机制完美适配电商模块化需求如支付Starter、库存StarterRedis的5种使用姿势缓存、分布式锁、秒杀队列、会话存储、实时统计不同场景需要选择不同的数据结构和持久化策略分库分表组件选型ShardingSphere与MyCat的抉择关键在SQL兼容性需求消息中间件的场景化选择订单事务用RocketMQ、日志处理用Kafka、延迟消息用RabbitMQ技术栈不是越新越好某跨境电商曾因盲目上马Service Mesh导致库存计算延迟最终回退到Spring Cloud1.1 商品服务的架构演进商品详情页的架构变迁最能体现技术栈的进化单体时代JSPMySQL面临的主要是Tomcat线程池打满问题缓存时代Redis本地缓存需解决缓存穿透布隆过滤器与数据一致性双删策略静态化时代NginxCDN配合Ajax加载动态内容服务化时代商品基础数据、价格、库存拆分为独立服务面临分布式事务挑战智能化时代基于用户画像的千人千面推荐引入TensorFlow Serving// 典型的多级缓存实现 public ProductDetail getProduct(Long id) { // 1. 查本地缓存 ProductDetail detail localCache.get(id); if(detail ! null) return detail; // 2. 查Redis detail redisTemplate.opsForValue().get(product:id); if(detail ! null) { localCache.put(id, detail); return detail; } // 3. 查数据库防穿透 detail productMapper.selectById(id); if(detail null) { redisTemplate.opsForValue().set(product:id, null, 5, TimeUnit.MINUTES); } else { redisTemplate.opsForValue().set(product:id, detail, 30, TimeUnit.MINUTES); } return detail; }1.2 交易系统的技术难点订单创建流程看似简单实则暗藏玄机分布式锁防止重复提交关键要设置合理的锁粒度用户维度而非订单维度库存扣减采用Redis Lua脚本保证原子性注意超卖和少卖两种异常情况分布式事务TCC模式比Saga更适合资金操作但开发成本更高降级策略当风控系统响应超时是阻断交易还是放行需要根据业务阶段动态调整某次大促中我们发现Redis集群的hot key导致库存扣减延迟最终通过本地缓存Redis分片解决2. 高频面试题深度剖析2.1 Redis缓存击穿实战方案面试官常问你们的缓存击穿解决方案是什么 多数人回答用互斥锁但大厂期待更立体的回答预防阶段热点数据预加载通过历史访问数据预测提前写入缓存多级缓存架构本地缓存分布式缓存本地缓存设置不同的过期时间应对阶段互斥锁的优化采用Redis的SETNX实现注意设置合理的锁超时时间缓存空对象对不存在的key也缓存防止反复查询数据库熔断机制当缓存失效请求超过阈值直接返回默认值// 改进版的缓存查询 public Product getProductWithLock(Long id) { String lockKey lock:product: id; try { // 尝试获取锁 while (!redisTemplate.opsForValue().setIfAbsent(lockKey, 1, 10, TimeUnit.SECONDS)) { Thread.sleep(100); } // 查缓存 Product product getFromCache(id); if (product ! null) return product; // 查数据库 product dbQuery(id); if (product ! null) { updateCache(id, product); } else { // 缓存空对象 redisTemplate.opsForValue().set(product:id, null, 5, TimeUnit.MINUTES); } return product; } finally { redisTemplate.delete(lockKey); } }2.2 分布式ID生成方案对比电商场景下订单ID的生成方式直接影响系统性能方案优点缺点适用场景UUID简单无中心化无序索引效率低日志系统数据库自增绝对有序单点故障性能瓶颈小型系统Redis INCR性能较好持久化问题临时活动雪花算法高性能趋势递增时钟回拨问题主流电商系统美团Leaf高可用可监控架构复杂大型分布式系统在日订单量百万级的系统中我们采用改良版雪花算法时间戳部分改用业务日期而非机器时间避免时钟回拨工作进程ID通过ZK动态分配支持容器化部署序列号部分增加随机前缀防止被爬虫推测订单量3. 系统设计题应答策略3.1 秒杀系统设计要点当面试官要求设计秒杀系统时建议按照以下结构回答架构分层前端静态资源CDN化按钮灰度倒计时随机偏移网关限流令牌桶、黑名单Redis HyperLogLog服务层库存预热、内存标记Redis原子扣减数据层MQ削峰填谷最终一致性关键实现// 秒杀核心逻辑 public boolean seckill(Long userId, Long itemId) { // 内存标记过滤无效请求 if(!itemCache.containsKey(itemId)) { return false; } // Redis原子扣减 String stockKey seckill:stock: itemId; Long remain redisTemplate.opsForValue().decrement(stockKey); if(remain 0) { // 回滚库存 redisTemplate.opsForValue().increment(stockKey); return false; } // 异步创建订单 mqTemplate.send(seckill_order, new OrderMessage(userId, itemId)); return true; }容灾方案降级策略当Redis不可用时切换本地库存需要提前分配库存额度熔断配置Hystrix线程池隔离避免雪崩数据核对定时任务补偿丢失的订单3.2 分布式事务场景题如何保证购物车清空和订单创建的一致性这类问题考察TCC模式的掌握Try阶段购物车服务锁定选中的商品状态改为待结算订单服务预生成订单号冻结优惠券Confirm阶段购物车服务删除锁定的商品订单服务正式创建订单扣减优惠券Cancel阶段购物车服务解除商品锁定订单服务释放优惠券实际编码中要注意幂等性设计Confirm/Cancel可能被重复调用4. 性能优化实战技巧4.1 JVM调优电商场景实践电商系统的JVM参数需要特别配置年轻代大小根据订单创建频率调整高峰期需要更大Eden区垃圾收集器CMS已淘汰G1更适合大堆内存场景关键参数示例-Xms4g -Xmx4g -XX:MaxGCPauseMillis200 -XX:InitiatingHeapOccupancyPercent35 -XX:UseG1GC -XX:MaxMetaspaceSize512m典型问题排查流程通过jstat -gcutil观察GC频率使用jmap -histo定位内存泄漏对象用arthas的trace命令分析接口耗时4.2 MySQL查询优化案例商品搜索接口的优化过程原始SQLSELECT * FROM products WHERE title LIKE %手机% ORDER BY sales DESC LIMIT 100;问题全表扫描filesort第一阶段优化添加联合索引(category_id, sales)改为分品类查询终极方案使用Elasticsearch实现搜索MySQL只存储基础信息通过canal实现数据同步5. 面试中的项目陈述技巧5.1 STAR法则的进阶用法不要简单复述项目功能要突出技术决策Situation日均订单量10万→100万的瓶颈是什么Task需要将接口响应时间从500ms降到200msAction引入Redis集群本地缓存而非简单地扩容服务器Result不仅提升性能还节省了30%的服务器成本5.2 技术深挖应对策略当面试官追问为什么选择RabbitMQ而不是Kafka时业务场景需要延迟消息订单超时关闭数据量级日均百万消息RabbitMQ足够团队因素已有RabbitMQ运维经验扩展考量插件机制支持动态扩缩容最后分享一个真实案例在解释CAP理论时有位候选人用电商库存作为例子在618大促时我们选择AP而非CP允许短暂超卖后续通过补货和补偿券解决这比直接拒绝用户体验更好。这种业务结合理论的回答往往能获得加分。