备忘录

一面(70min)
1.HashMap扩容条件是什么?为什么容量是2的幂次?
2.ConcurrentHashMap在JDK1.8中如何保证线程安全?
3.快速失败(fail-fast)和安全失败(fail-safe)的区别?
4.Synchronized和ReentrantLock的区别?
5.SpringAOP的实现原理及动态代理方式?
6.Redis持久化方式RDB和AOF的区别?
7.MySQL索引最左匹配原则的原理?
8.如何设计一个秒杀系统?
9.Spring Bean的作用域及线程安全问题?
10.Zookeeper的ZAB协议流程?

  1. HashMap扩容条件是什么?为什么容量是2的幂次?

    • 扩容条件:当HashMap中元素数量(size)超过阈值(threshold = 容量 × 负载因子)时,触发扩容。默认负载因子为0.75,容量初始为16,因此默认阈值为12。
    • 容量为2的幂次原因:通过位运算(hash & (容量-1))快速计算元素存储位置,提升效率。2的幂次减1的二进制为全1,能保证哈希值低位充分参与运算,减少哈希冲突。
  2. ConcurrentHashMap在JDK1.8中如何保证线程安全?

    • 摒弃JDK1.7的分段锁(Segment),采用CAS + synchronized实现线程安全。
    • 对链表头节点或红黑树的根节点使用synchronized加锁,仅锁定当前操作的桶,减小锁粒度。
    • 插入元素时,通过CAS操作保证节点更新的原子性,避免加锁开销。
  3. 快速失败(fail-fast)和安全失败(fail-safe)的区别?

    • 快速失败:迭代集合时,若其他线程修改集合结构(如增删元素),会立即抛出ConcurrentModificationException。原理是通过modCount(修改次数)检测并发修改,常见于ArrayList、HashMap等。
    • 安全失败:迭代时操作的是集合的副本,因此不会抛出异常,但可能读取到旧数据。原理是基于集合快照迭代,常见于CopyOnWriteArrayList、ConcurrentHashMap等。
  4. Synchronized和ReentrantLock的区别?

    特性 Synchronized ReentrantLock
    锁实现 JVM层面隐式锁 JDK层面显式锁(API实现)
    灵活性 自动释放,无法中断 可手动释放,支持中断、超时获取、公平锁
    条件变量 不支持 支持多个Condition,实现更精细的等待/唤醒
    性能 JDK1.6后优化(偏向锁、轻量级锁),性能接近 高并发下性能更优
  5. Spring AOP的实现原理及动态代理方式?

    • 原理:基于动态代理,在目标方法执行前后插入增强逻辑(如日志、事务),实现无侵入式功能扩展。
    • 动态代理方式:
      • JDK动态代理:基于接口,通过Proxy类生成代理对象,目标类必须实现接口。
      • CGLIB动态代理:基于继承,通过生成目标类的子类实现代理,无需接口,但不能代理final类/方法。
      • Spring默认策略:目标类有接口则用JDK代理,否则用CGLIB(可配置强制使用CGLIB)。
  6. Redis持久化方式RDB和AOF的区别?

    特性 RDB AOF
    原理 定期生成内存数据的二进制快照 记录每一条写命令到日志文件
    持久化频率 低(如每小时一次),可能丢失数据 高(如每秒同步或每写一条同步),数据更安全
    文件大小 小,恢复快 大,恢复慢
    恢复速度 慢(需重新执行所有命令)
    适用场景 数据备份、容忍部分数据丢失 对数据安全性要求高(如金融场景)
  7. MySQL索引最左匹配原则的原理?

    • 对于联合索引(如(a, b, c)),MySQL会优先匹配最左前缀(即先匹配a,再a+b,再a+b+c)。
    • 原理:联合索引按左到右的顺序构建B+树,查询条件中若跳过最左列(如仅用bb+c),则无法使用索引,需全表扫描。
    • 示例:where a=1 and b=2可命中索引,where b=2 and c=3无法命中。
  8. 如何设计一个秒杀系统?

    • 前端限流:按钮置灰、验证码、排队机制,减少无效请求。
    • 接口限流:使用Redis+Lua脚本或令牌桶算法,限制每秒请求数。
    • 削峰填谷:引入消息队列(如RabbitMQ),异步处理订单,避免瞬时流量压垮数据库。
    • 库存控制:Redis预存库存,原子操作(如decr)判断库存是否充足,避免超卖。
    • 数据库优化:分库分表、读写分离,订单表按用户ID哈希分片。
    • 缓存策略:热点商品信息缓存,减少数据库访问。
  9. Spring Bean的作用域及线程安全问题?

    • 作用域:
      • singleton(默认):全局单例,整个容器中只有一个实例。
      • prototype:每次获取创建新实例。
      • request/session/application:Web环境下,分别对应请求、会话、应用生命周期。
    • 线程安全:
      • singleton bean若存在可修改的成员变量,多线程并发访问可能不安全(需加锁或使用ThreadLocal)。
      • prototype bean每次创建新实例,无线程安全问题,但创建成本高。
  10. Zookeeper的ZAB协议流程?
    ZAB(ZooKeeper Atomic Broadcast)是ZooKeeper保证数据一致性的核心协议,分为三个阶段:

    1. 选举阶段:集群启动或Leader故障时,所有节点参与选举,选出新Leader(票数过半的节点)。
    2. 同步阶段:新Leader与Follower同步数据,确保所有节点数据一致(Follower更新到Leader的最新状态)。
    3. 广播阶段:正常运行时,Leader接收客户端写请求,通过两阶段提交(提议-确认)将数据同步到所有Follower,保证数据原子性。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐