面试

浏览该分类下的所有文章

面试现场【List篇】

List是Java集合接口,常用实现ArrayList(数组,查询快,容量不足时按1.5倍扩容)和LinkedList(链表,增删快)。ArrayList适合读多写少,LinkedList适合写多读少。List可重复有序,Set不重复无序且基于Map。Vector已少用,线程安全List可用Collections.synchronizedList或CopyOnWriteArrayList;后者写时复制实现并发读,但占内存多且读到旧数据。排序用list.sort或Collections.sort,遍历删除用Iterator.remove或list.removeIf避免fast‑fail。

面试现场【多线程篇】

面试围绕多线程展开,阐述使用多线程提升资源利用率和并发能力的原因及适用场景,如大文件读写、耗时任务和定时任务。解释线程安全的含义,并给出常用解决方案:原子类、CountDownLatch、并发集合、synchronized、Lock 及分布式锁。说明 synchronized 通过 monitorenter/monitorexit 实现锁机制及其字节码标志。比较 synchronized 与 ReentrantLock 的锁释放方式、可公平性、可中断性、超时获取和 tryLock。简述公平锁概念并介绍 CAS 的工作原理及在 AtomicInteger 中的应用。

面试现场【Redis篇】

Redis 4.0 前单线程处理网络 I/O 与 Set/Get,避免锁竞争并使用 epoll 实现高效 I/O;4.0 后引入多线程用于大数据异步删除。持久化提供 AOF(追加日志)和 RDB(快照)两种方式,4.0 还支持二者混合。AOF 先执行命令再写日志,存在数据丢失和阻塞风险;RDB 可通过 save 同步阻塞或 bgsave 子进程异步生成快照,写时复制保证数据可修改。高可用方案包括主从复制、哨兵自动故障转移和 Cluster。Cluster 将键映射至 16384 个哈希槽,采用 CRC16 取模实现节点选择,解决写和存储扩展问题。

每日一题(2022/1/20)

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

每日一题(2022/1/19)

本文给出一道面试题:在保持 `String s` 引用不变的前提下,使其输出从 `abc` 变为 `abcd`。常规做法如 `StringBuilder.append()` 或 `String.replace()` 均不可行。正确方案是通过反射修改 `String` 的内部 `value`(char[])字段:获取字段、设为可访问、写入新字符数组即可。但在 JDK 11 及以上运行时会抛出 `IllegalArgumentException`,因为 `value` 为 `final` 且受模块系统的非法反射访问限制。文章说明了 `setAccessible(true)` 的作用并解释异常产生的原因。