一、Java基础类(打底必问,绑定B2B场景)
1. 问:HashMap和ConcurrentHashMap的区别?在B2B项目里怎么用?
回答模板 :
核心区别是线程安全和实现方式:
- HashMap:非线程安全,底层数组+链表/红黑树,B2B项目中仅用于单线程的本地临时数据存储(如单个订单的参数封装);
- ConcurrentHashMap:线程安全,JDK1.8后用
CAS+Synchronized分段锁(替代1.7的分段桶),无锁竞争时性能接近HashMap,并发冲突时仅锁住当前桶,不影响其他桶。 - B2B落地:我们用ConcurrentHashMap存储"企业客户实时订单缓存"(key:订单号,value:订单信息),支撑日均5万+订单的并发读写,相比Hashtable性能提升80%,且避免了HashMap的并发扩容死循环问题。
2. 问:equals和hashCode的关系?B2B项目里有什么应用?
回答模板 :
核心规则:① equals相等,hashCode必须相等;② hashCode相等,equals不一定相等;
- B2B落地:在B2B供应商信息缓存场景中,自定义SupplierDO类重写equals(按供应商ID+名称判断相等)和hashCode(基于ID计算),放入HashSet做重复供应商去重,同时保证HashMap中以SupplierDO为key时的正确性,避免重复缓存同一供应商数据。
3. 问:线程池的核心参数有哪些?B2B项目里怎么配置?
回答模板 :
核心参数(7个):corePoolSize(核心线程数)、maximumPoolSize(最大线程数)、keepAliveTime(空闲线程存活时间)、workQueue(任务队列)、threadFactory(线程工厂)、handler(拒绝策略);
- B2B落地:我们针对B2B批量下单场景配置线程池:
✅ corePoolSize=10(日常批量任务基线)、maximumPoolSize=50(峰值扩容);
✅ workQueue用ArrayBlockingQueue(容量1000),避免无界队列导致OOM;
✅ 拒绝策略用CallerRunsPolicy(峰值时由提交线程执行,避免任务丢失); - 项目效果:批量处理供应商订单的效率从原来的200条/秒提升至1000条/秒,支撑日均10万+批量订单处理。
二、锁相关(B2B库存/订单核心场景)
1. 问:synchronized和Lock(ReentrantLock)的区别?B2B项目里怎么选?
回答模板:
| 维度 | synchronized | ReentrantLock |
|---|---|---|
| 锁类型 | 隐式锁(自动释放) | 显式锁(手动lock/unlock) |
| 灵活性 | 不可中断、不可超时、非公平 | 可中断、可超时、可公平/非公平 |
| 性能 | 高并发下略差(JDK1.6后优化) | 高并发下更优,支持细粒度控制 |
- B2B落地:
✅ 简单场景(如单个库存扣减方法):用synchronized,无需手动释放,避免漏解锁;
✅ 复杂场景(如B2B批量锁多个SKU库存):用ReentrantLock的tryLock(3, TimeUnit.SECONDS),超时放弃加锁,避免死锁,同时用公平锁保证企业客户下单的公平性。
2. 问:乐观锁和悲观锁的区别?B2B项目里怎么用?
回答模板:
- 悲观锁:认为一定会并发冲突,先加锁再操作(如synchronized、数据库行锁),适合写多读少场景;
- 乐观锁:认为不会冲突,操作时加版本号/时间戳,提交时校验(如数据库version字段),适合读多写少场景;
- B2B落地:库存扣减用"悲观锁(Redisson分布式锁)+ 乐观锁(数据库version)"双重保障:
✅ 分布式锁防止跨节点并发扣减(悲观锁);
✅ 数据库乐观锁(update stock set num=num-1 where sku_id=? and version=?)兜底,即使分布式锁异常,也能避免超卖,库存一致性达99.99%。
三、多线程(B2B批量处理核心)
1. 问:CompletableFuture在B2B项目里怎么用?解决了什么问题?
回答模板 :
CompletableFuture用于实现异步并行处理,解决B2B批量任务串行执行效率低的问题;
-
B2B落地:企业客户批量导入1000条商品数据时,用CompletableFuture并行处理:
java// 拆分任务为10个分片,并行处理 List<CompletableFuture<Void>> futures = goodsList.stream() .chunked(100) // 按100条分片 .map(chunk -> CompletableFuture.runAsync(() -> importGoods(chunk), executor)) .collect(Collectors.toList()); CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); -
项目效果:批量导入耗时从原来的5分钟降至30秒,支撑日均200+企业客户的商品导入需求。
2. 问:怎么避免多线程死锁?B2B项目里有哪些实践?
回答模板 :
死锁核心原因:互斥、持有并等待、不可剥夺、循环等待;
- B2B落地实践:
✅ 固定加锁顺序:批量扣减多个SKU库存时,按SKU ID升序加锁,避免循环等待;
✅ 超时释放:用ReentrantLock的tryLock设置超时时间,3秒未获取锁则放弃,避免长期持有;
✅ 定期巡检:通过Jstack排查线程状态,上线前做死锁检测,杜绝生产环境死锁。
四、MySQL数据库(B2B大表/高并发查询核心)
1. 问:B2B项目里千万级订单表怎么优化查询性能?
回答模板 :
核心思路是"减少扫描数据、利用索引、分散压力",具体落地:
- 索引优化:建联合索引
idx_user_status_time (user_id, order_status, create_time),遵循最左前缀,避免select *,用覆盖索引减少回表; - 分页优化:大分页用延迟关联(join子查询查主键,再关联主表),避免limit 100000,20扫描大量数据;
- 分库分表:按user_id哈希分16张表,只查对应分表,查询效率提升90%;
- 数据归档:超过6个月的历史订单归档到冷表,热表仅保留近期数据,减少数据量;
- 项目效果:订单列表查询接口响应从500ms降至80ms,支撑日均10万+订单查询。
2. 问:MySQL的事务隔离级别有哪些?B2B项目里用的哪个?为什么?
回答模板 :
隔离级别(从低到高):读未提交、读已提交、可重复读(RR)、串行化;
- B2B落地:用可重复读(RR) ,原因:
✅ 避免脏读、不可重复读、幻读(InnoDB通过间隙锁解决幻读);
✅ 相比串行化性能更高,满足B2B订单交易的一致性要求; - 避坑点:RR级别下,批量更新订单状态时用for update加行锁,避免幻读导致的更新遗漏。
五、Redis分布式锁(B2B库存扣减核心)
1. 问:B2B项目里怎么实现Redis分布式锁?有哪些避坑点?
回答模板 :
基于Redisson实现(比原生RedisTemplate更健壮),核心流程:
- 加锁:
RLock lock = redisson.getLock("lock:stock:" + skuId),设置30s超时,watchdog自动续期(避免长事务锁超时); - 执行业务:校验库存→扣减库存;
- 解锁:try-finally保证锁释放,避免业务异常导致死锁;
- 避坑点:
✅ 不用SETNX+EXPIRE(非原子操作,易丢锁);
✅ 加锁时绑定客户端ID,避免误解锁其他线程的锁;
✅ 结合数据库乐观锁兜底,即使分布式锁异常,也能避免超卖; - 项目效果:彻底解决B2B高并发库存超卖问题,支撑日均5万+批量下单请求。
六、分布式事务(B2B订单履约核心)
1. 问:B2B项目里分布式事务怎么落地?解决了什么问题?
回答模板 :
B2B订单履约流程(订单创建→库存扣减→财务结算→物流生成)跨3个微服务,分场景落地:
- 核心场景(订单+库存):用Seata AT模式(强一致性),通过@GlobalTransactional注解管控,Seata自动生成undo_log,异常时回滚,保证原子性;
- 非核心场景(结算+物流):用RocketMQ事务消息(最终一致性),订单履约成功后发送半事务消息,确认结算完成后提交消息,触发物流生成;
- 优化:缩短事务范围,把日志、通知等非核心操作移出事务,提升并发;
- 项目效果:订单履约异常率从1.2%降至0.05%,财务对账效率提升80%。
七、消息中间件(B2B异步解耦核心)
1. 问:B2B项目里选RocketMQ还是Kafka?怎么解决消息丢失/重复消费?
回答模板 :
选型:选RocketMQ(金融级可靠性),适合B2B交易场景,Kafka适合大数据日志采集;
- 消息丢失解决:
✅ 生产者:同步发送+ACK确认,retries=3重试;
✅ Broker:同步刷盘+主从复制;
✅ 消费者:手动提交offset,消费成功后再确认; - 重复消费解决:核心是消费幂等化,基于订单号/交易流水号,用Redis的setnx做校验,即使重复消费也不会重复扣库存;
- 项目效果:消息丢失率降至0,重复消费率从0.8%降至0,支撑日均1万+金融交易消息处理。
2. 问:B2B项目里消息堆积怎么解决?
回答模板 :
核心思路是"扩容+优化消费+分流":
- 临时扩容:增加消费者实例,水平扩展消费能力;
- 消费优化:拆分消费逻辑,异步处理,减少数据库IO;
- 架构优化:用RocketMQ的消息队列负载均衡,慢消费任务分流到专属消费组;
- 兜底:设置堆积告警,超过阈值自动触发扩容,避免影响核心业务;
- 项目效果:批量下单场景的消息堆积时长从1小时降至5分钟。
八、其他高频延伸问题(B2B项目专属)
1. 问:B2B项目里Redis和MySQL怎么保证数据一致性?
回答模板 :
首选"先更库,再删缓存+MQ重试":
- 更新MySQL后删除Redis缓存,下次查询自动加载最新数据;
- 删除缓存失败则发MQ重试,保证最终删除;
- 高并发场景加延迟双删,避免脏读;
- 给缓存设置30分钟过期时间兜底,即使异常也能自动失效。
2. 问:B2B项目里MySQL怎么同步到ES?
回答模板 :
用CloudCanal监听MySQL binlog(row格式)实现增量同步:
- 全量初始化:上线时同步历史数据到ES;
- 增量同步:解析binlog的增删改操作,自动同步到ES;
- 优化:过滤测试数据,字段映射转换,定时对比数据兜底;
- 项目效果:商品检索接口响应从500ms降至50ms,支撑日均20万+检索请求。
总结(核心记忆点)
- 所有技术回答都要绑定B2B场景(库存扣减、订单履约、批量处理),量化成果(响应时间、并发量、一致性率);
- 核心痛点:库存超卖、数据一致性、高并发查询、消息可靠传输,对应解决方案要记牢;
- 避坑细节:分布式锁自动续期、事务范围缩短、消费幂等化,是面试加分关键。