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