2026 Java后端面试“三剑客”:集合、JUC、Redis 高频考点解析

张开发
2026/4/3 20:49:36 15 分钟阅读
2026 Java后端面试“三剑客”:集合、JUC、Redis 高频考点解析
2026 Java后端面试热点题库集合 JUC Redis 高频基础中档题精讲本文精选2026年Java后端面试中最热门、最高频的基础到中档难度题目涵盖Java集合框架、JUC并发编程、Redis缓存三大核心模块。建议收藏反复研读一、Java 集合框架Collection Framework1. HashMap 底层原理与扩容机制 ⭐⭐⭐⭐⭐面试频率极高 |难度基础核心要点// HashMap 核心结构JDK 1.8transientNodeK,V[]table;// 哈希桶数组transientintsize;// 元素个数intthreshold;// 扩容阈值 capacity * loadFactorfinalfloatloadFactor;// 负载因子默认0.75JDK 1.8 的优化改进数组链表红黑树当链表长度≥8且数组长度≥64时链表转为红黑树查询复杂度从O(n)降至O(log n)尾插法扩容时采用尾插法避免了JDK 1.7头插法导致的死循环问题扩容优化扩容时不再重新计算hash而是通过(e.hash oldCap) 0判断位置高频追问Q为什么HashMap的容量必须是2的幂次方答案为了使用位运算替代取模运算提升性能。当容量为2^n时hash % capacity等价于hash (capacity - 1)位运算效率远高于取模。QHashMap在JDK 1.7和1.8中的主要区别特性JDK 1.7JDK 1.8数据结构数组链表数组链表红黑树插入方式头插法尾插法扩容重新计算hash优化只需判断高位线程安全不安全死循环风险不安全数据覆盖2. ConcurrentHashMap 线程安全实现 ⭐⭐⭐⭐⭐面试频率极高 |难度中档JDK 1.7 vs JDK 1.8 实现对比// JDK 1.7分段锁SegmentfinalSegmentK,V[]segments;// 默认16个Segment最多16个线程并发写// JDK 1.8CAS synchronizedvolatileNodeK,V[]table;// 锁粒度细化到桶级别JDK 1.8 的核心优化取消Segment锁粒度从段级降到桶级并发度大幅提升CAS synchronized使用CAS进行无锁插入冲突时用synchronized锁定头节点size计算优化使用CounterCell数组分散计数减少竞争put() 流程详解// JDK 1.8 put 流程简化版finalVputVal(Kkey,Vvalue,booleanonlyIfAbsent){// 1. 计算hashinthashspread(key.hashCode());intbinCount0;for(NodeK,V[]tabtable;;){NodeK,Vf;intn,i,fh;// 2. 数组未初始化先初始化if(tabnull||(ntab.length)0)tabinitTable();// 3. 目标桶为空CAS插入无锁elseif((ftabAt(tab,i(n-1)hash))null){if(casTabAt(tab,i,null,newNodeK,V(hash,key,value,null)))break;}// 4. 正在扩容协助扩容elseif((fhf.hash)MOVED)tabhelpTransfer(tab,f);// 5. 桶非空synchronized锁定头节点else{synchronized(f){// 链表/红黑树插入逻辑...}}}addCount(1L,binCount);returnnull;}3. ArrayList vs LinkedList ⭐⭐⭐⭐对比维度ArrayListLinkedList底层结构Object数组双向链表随机访问O(1)O(n)尾部插入O(1)扩容时O(n)O(1)中间插入O(n)O(1)查找O(n)内存占用较少较多需存储指针适用场景查询多、随机访问频繁插入删除二、JUC 并发编程java.util.concurrent1. AQSAbstractQueuedSynchronizer原理 ⭐⭐⭐⭐⭐面试频率极高 |难度中档AQS是JUC包的基石框架ReentrantLock、CountDownLatch、Semaphore等都基于它实现。核心架构publicabstractclassAbstractQueuedSynchronizerextendsAbstractOwnableSynchronizer{// 核心状态volatile保证可见性privatevolatileintstate;// CLH队列双向链表privatetransientvolatileNodehead;privatetransientvolatileNodetail;}核心思想state同步状态volatile保证线程可见性FIFO队列CLH变体队列管理等待线程CAS操作保证状态更新的原子性独占式获取锁流程// ReentrantLock.lock() 最终调用publicfinalvoidacquire(intarg){// 1. 尝试获取锁子类实现if(!tryAcquire(arg)// 2. 获取失败加入队列acquireQueued(addWaiter(Node.EXCLUSIVE),arg))selfInterrupt();}高频追问QAQS为什么使用双向链表而不是单向链表答案支持取消节点需要修改前驱节点的next指针支持从尾部快速插入保证入队操作的原子性支持唤醒后继节点需要快速找到下一个等待线程2. 线程池核心参数与执行流程 ⭐⭐⭐⭐⭐面试频率极高 |难度中档七大核心参数publicThreadPoolExecutor(intcorePoolSize,// 核心线程数intmaximumPoolSize,// 最大线程数longkeepAliveTime,// 空闲线程存活时间TimeUnitunit,// 时间单位BlockingQueueRunnableworkQueue,// 任务队列ThreadFactorythreadFactory,// 线程工厂RejectedExecutionHandlerhandler// 拒绝策略)任务提交流程提交任务 ↓ 线程数 corePoolSize ? ↓ 是 ↓ 否 创建核心线程 队列是否已满 ↓ ↓ 是 ↓ 否 执行任务 线程数 maxPoolSize ? 加入队列 ↓ 是 ↓ 否 创建非核心线程 执行拒绝策略 ↓ 执行任务四种拒绝策略策略说明AbortPolicy直接抛出RejectedExecutionException默认CallerRunsPolicy由调用线程执行任务DiscardPolicy静默丢弃任务DiscardOldestPolicy丢弃队列最老的任务重试提交高频追问Q线程池中的Worker为什么要继承AQS答案Worker继承AQS是为了控制线程中断lock()线程开始执行任务时加锁state1unlock()任务执行完毕解锁state0shutdown()只中断空闲线程state0的线程shutdownNow()中断所有线程3. synchronized vs ReentrantLock ⭐⭐⭐⭐⭐对比维度synchronizedReentrantLock实现方式JVM层面monitorAPI层面AQS锁的获取自动获取/释放手动lock/unlock灵活性低高可中断、超时、公平锁条件变量一个wait/notify多个Condition性能JDK 1.6后优化接近略优某些场景可重入性支持支持synchronized 锁升级过程无锁 → 偏向锁 → 轻量级锁 → 重量级锁三、Redis 缓存Redis 五种基本数据类型及使用场景String验证码、计数器、分布式锁。Hash存储对象信息用户信息。List消息队列、关注列表。Set去重、抽奖、共同好友。ZSet排行榜核心是 跳表 SkipList。持久化机制RDB vs AOFRDB快照全量备份恢复快但可能丢失最后一次备份后的数据。AOF日志记录每一条写指令数据安全性高但文件大、恢复慢。最佳实践混合持久化RDBAOF。缓存三大问题穿透、击穿、雪崩 ⭐⭐⭐⭐⭐面试频率极高 |难度基础问题定义原因解决方案缓存穿透查询不存在的数据直接打到DB恶意攻击、数据不存在① 布隆过滤器 ② 缓存空值缓存击穿热点key过期大量请求打到DB热点key过期瞬间① 互斥锁 ② 逻辑过期缓存雪崩大量key同时过期DB压力激增集中过期、Redis宕机① 随机过期时间 ② 多级缓存 ③ 熔断限流解决方案详解// 1. 缓存穿透 - 布隆过滤器ComponentpublicclassBloomFilterHelper{AutowiredprivateRedissonClientredisson;publicbooleanmightContain(Stringkey){RBloomFilterStringbloomFilterredisson.getBloomFilter(userFilter);returnbloomFilter.contains(key);}}// 2. 缓存击穿 - 互斥锁publicStringgetWithLock(Stringkey){Stringvalueredis.get(key);if(valuenull){// 获取分布式锁if(redissonLock.tryLock(key,10,TimeUnit.SECONDS)){try{// 双重检查valueredis.get(key);if(valuenull){valuedb.query(key);redis.setex(key,3600,value);}}finally{redissonLock.unlock(key);}}}returnvalue;}// 3. 缓存雪崩 - 随机过期时间publicvoidsetWithRandomExpire(Stringkey,Stringvalue){intexpire3600newRandom().nextInt(300);// 3600~3900秒redis.setex(key,expire,value);}Redis 分布式锁实现 ⭐⭐⭐⭐⭐面试频率极高 |难度中档演进过程# 阶段1SETNX EXPIRE非原子操作可能死锁SETNX lock:order:123trueEXPIRE lock:order:12330# 阶段2SET NX EX原子操作SET lock:order:123 random_value NX EX30# 阶段3Redisson生产环境推荐Redisson 分布式锁原理// Redisson 使用示例RLocklockredisson.getLock(myLock);try{// 尝试加锁最多等待10秒锁30秒后自动释放booleanisLockedlock.tryLock(10,30,TimeUnit.SECONDS);if(isLocked){// 执行业务逻辑}}finally{lock.unlock();}Watch Dog 自动续期机制获取锁成功后启动看门狗线程看门狗每隔10秒默认检查锁是否仍被持有如果仍持有自动续期到30秒解决业务执行时间超过锁过期时间的问题Redis 为什么这么快⭐⭐⭐⭐答案要点纯内存操作所有数据在内存中读写速度极快单线程模型避免多线程上下文切换和竞争开销IO多路复用基于epoll/kqueue处理高并发连接高效数据结构SDS、跳表、压缩列表等优化RESP协议简单高效的序列化协议注意Redis 6.0 引入多线程但仅限于网络IO命令执行仍是单线程。四、面试技巧总结回答结构化模板1. 先给出核心结论是什么 2. 详细解释原理为什么 3. 对比/演进过程深度 4. 实际应用场景广度 5. 可能的问题与优化亮点高频考点速查表模块必会题目集合HashMap扩容、ConcurrentHashMap锁机制、红黑树转换条件JUCAQS原理、线程池参数、volatile/CAS/synchronized原理Redis缓存三问题、分布式锁、持久化RDB/AOF、主从复制结语本文涵盖了2026年Java后端面试中最热门的基础到中档难度题目。建议读者理解原理不要死记硬背要理解底层机制动手实践自己写代码验证加深理解举一反三从一个知识点延伸到相关知识点祝你面试顺利拿到心仪的Offer版权声明本文为原创内容转载请注明出处。更新时间2026年4月交流讨论欢迎在评论区交流面试经验

更多文章