得物Java后端一面面经

得物 · Java后端开发工程师 · 一面 · 2026-06

《面试题目》

  1. delayqueue 怎么分发到多个机器
  2. 优惠券乐观锁,Redisson,锁粒度,不同用户抢同一个券
  3. 积分榜,XXL-Job 怎么实现的?延迟队列不支持多实例,XXL-Job 支持多实例,冲突了怎么处理?数据库表怎么设计的?
  4. ZSet 是怎么样的,和正常的 K-V 有什么区别?
  5. 向量数据库怎么跟大模型交互
  6. HashMap 链表转红黑树条件,为什么要转红黑树
  7. ==equals 有什么区别
  8. 重写 equals 为什么要重写 hashcode
  9. 线程池核心参数,拒绝策略
  10. synchronized 和 ReentrantLock 分别在什么场景用
  11. 什么场景事务会失效
  12. MySQL 联合索引 (a,b,c)where b=1, c=2 能否走索引

《参考解析》

  1. HashMap 链表转红黑树的条件与原因:JDK1.8 中当单个桶内链表长度达到 8 且数组容量达到 64 时,链表转换为红黑树;这是因为链表在冲突严重时查询复杂度退化为 O(n),而红黑树能把查询复杂度稳定在 O(log n);数组容量小于 64 时优先选择扩容而非树化,是因为容量小时冲突大概率是哈希分布不均导致的,扩容能更根本地缓解冲突。
  2. 重写 equals 为什么要重写 hashCode:Java 规范要求”相等的对象必须有相同的哈希值”,如果只重写 equals 不重写 hashCode,两个逻辑相等的对象可能因为默认的 hashCode(基于内存地址)不同,被哈希表判定为不同的桶位置,导致 HashMap/HashSet 中出现重复元素或查找失败等不一致行为。
  3. 联合索引最左匹配下的失效判断:联合索引 (a,b,c) 遵循最左前缀原则,查询条件 where b=1 and c=2 没有包含最左列 a,因此无法使用该联合索引(除非查询优化器识别到可以走索引跳跃扫描,但 MySQL 默认不支持这一特性),只能走全表扫描或该表上的其他单独索引。
  4. 优惠券乐观锁与 Redisson:乐观锁通过版本号(version字段)或 CAS 判断更新时数据是否被其他事务修改过,适合读多写少、冲突概率不高的场景;秒杀抢券这种瞬时高并发写冲突场景,通常配合 Redisson 分布式锁控制同一用户/同一券的操作互斥,锁粒度应细化到”券ID+用户ID”级别,避免锁粒度过粗(如整张券表)造成不必要的排队等待。