Redis 通过在 DB 前构建高速缓存,显著提升 TPS 与 QPS,但若缓存设计不当会出现三大问题。①缓存击穿:热点数据在高并发下刚失效,所有请求涌向 DB。解决方案包括不设过期或加随机失效时间、预热热点数据、使用分布式锁只让一个请求查询 DB 并写回缓存。②缓存穿透:查询不存在的键导致每次都穿透到 DB。常用办法是缓存空值或使用布隆过滤器在查询前快速判断键是否可能存在。③缓存雪崩:大量键同时失效或 Redis 故障,使流量瞬间冲击 DB。防护措施有为键设置基准+随机失效时间、接口限流、服务熔断以及部署 Redis 哨兵或 Cluster 实现高可用。通过这些手段可保证缓存层的稳定性,防止对后端数据库造成致命压力。

面试中围绕 Java List 进行问答,阐述了 List 为接口,常用实现为 ArrayList(基于数组,支持快速随机访问,容量不足时按 1.5 倍扩容)和 LinkedList(基于链表,插删更快)。说明了两者的适用场景:ArrayList 适合查询多、增删少;LinkedList 适合增删多、查询少,并比较了 List 与 Set、Vector 的区别。进一步介绍了线程安全的 List 方案:Collections.synchronizedList 与 CopyOnWriteArrayList,后者采用写时复制实现读写分离,但存在内存占用大和读取旧数据的缺点。最后给出 List 排序及遍历时安全删除元素的常用写法。

Redis 常用于实现分布式锁,文章系统梳理了七种方案并分析其优缺点。首先阐述锁的基本特性(互斥、超时、可重入、高可用、安全),随后依次介绍:① SETNX+EXPIRE 的非原子问题;② 将过期时间写入 value 的时间同步风险;③ 用 Lua 脚本实现 SETNX 与 EXPIRE 原子化;④ SET EX PX NX 命令的基本用法及仍存在的误删、业务未完成即失效问题;⑤ 在 value 中加入唯一标识并通过 Lua 脚本校验后删除,进一步防止误删;⑥ Redisson 框架的 WatchDog 机制自动延长锁生存期,解决锁提前失效;⑦ Redlock 多节点算法,利用多数节点成功加锁并在超时内释放,提升在 Redis 集群故障下的安全性。文章强调,单机方案虽易实现但易出错,推荐使用 Redisson 或 Redlock 以获得更可靠的分布式锁。

小邹说明多线程用于提高资源利用率和CPU并发能力,典型场景有高并发读写、耗时任务异步处理和定时任务。线程安全指多线程访问同一对象时无需额外同步仍能得到正确结果,常用手段包括原子类、CountDownLatch、Semaphore、java.util.concurrent集合、synchronized、Lock及分布式锁。synchronized 通过 monitorenter/monitorexit 实现对象头锁,方法级使用 ACC_SYNCHRONIZED 标志。ReentrantLock 需手动释放、可设公平性、支持可中断、超时及 tryLock。CAS(Compare‑And‑Swap)是乐观锁实现方式,AtomicInteger 等基于 CAS 完成无锁同步。

Redis 采用单线程模型处理网络 I/O 与大多数命令,4.0 起支持多线程用于大数据异步删除。单线程避免锁竞争、利用内存高速和 I/O 多路复用,使性能卓越。为防止数据丢失,Redis 提供三种持久化:AOF(记录操作日志)、RDB(内存快照)和 4.0 引入的混合持久化。AOF 采用写后日志,可能出现短暂数据丢失并阻塞主线程;RDB 通过 save(阻塞)和 bgsave(子进程)生成快照,写时采用写时复制保证并发。高可用方案包括主从复制、Sentinel 自动故障转移以及 Redis Cluster。Cluster 将键通过 CRC16 哈希映射到 16384 个槽位,由不同 Master 负责,实现写入与存储的水平扩展。

代码演示了 Java 中字符串比较的细节。`s1` 通过 `new String("xiaozou")` 在堆中创建了独立对象,`s2` 直接引用常量池中的字面量,两者地址不同,`s1 == s2` 为 `false`。调用 `s1.intern()` 时,若常量池已有相同内容的字符串,则返回该池中对象的引用,否则将其加入池中。因为常量池已经存在 `"xiaozou"`,`s3` 获得的正是 `s2` 的引用,故 `s2 == s3` 为 `true`。文章通过源码解释说明了 `intern()` 的工作原理及其在字符串共享中的作用。