929 日 , 2025 20:06:53
面试小tips

1.arraylist和linklist的区别

操作 ArrayList LinkedList
查第n个元素 ⚡ 超快 (直接定位) 🐢  (要一个个数)
在末尾添加 ⚡  ⚡ 
在中间插入/删除 🐢  (要移动后面所有元素) ⚡  (改个链接就行)
内存占用 ✅  (只存数据) ❌  (还要存前后指针)

2.hashMap1.7和hashMap1.8的区别

特性 HashMap 1.7 HashMap 1.8
数据结构 数组 + 单链表 数组 + 链表/红黑树
插入方式 头插法(新元素放链表头部) 尾插法(新元素放链表尾部)
哈希冲突 链表可能很长,查询变慢 链表超8转红黑树,查询更快
扩容时机 先扩容再插入 先插入再判断扩容
死锁问题 ❌ 多线程可能死锁 ✅ 减少死锁风险
  • DK 1.7:像单行道 – 车多就堵死,还容易出事故(死锁)

  • JDK 1.8:像智能立交 – 车多时自动开启高架(红黑树),通行更高效

3.ConcurrentHashMap 与 HashMap、Hashtable 对比

特性 HashMap Hashtable ConcurrentHashMap
线程安全 ❌ 不安全 ✅ 安全 ✅ 安全
性能 ⚡ 最快 🐢 最慢 ⚡ 很快
锁机制 无锁 全表锁 分段锁/CAS
多线程 会出错 安全但慢 安全且快
  • HashMap自由市场 – 谁都能买卖,但可能混乱

  • Hashtable只有一个门的仓库 – 安全但效率低,一次只能进一个人

  • ConcurrentHashMap现代化超市 – 多个收银台,不同柜台可以同时结账

4.ConcurrentHashMap1.7和ConcurrentHashMap1.8的区别

特性 ConcurrentHashMap 1.7 ConcurrentHashMap 1.8
锁粒度 段锁(锁一个Segment) 桶锁(锁单个数组元素)
锁机制 ReentrantLock CAS + synchronized
数据结构 数组 + 链表 数组 + 链表/红黑树
并发度 Segment数量决定 桶数量决定,更高
哈希冲突 链表可能很长 链表超8转红黑树
  • JDK 1.7传统大商场 – 分成几个大区,每个区一个收银台

  • JDK 1.8现代超市 – 每个货架都有自助扫码,真正并行结算

5.线程和进程的区别

方面 进程 (Process) 线程 (Thread)
资源占用 大(独立内存空间) 小(共享进程内存)
创建销毁 慢(重量级) 快(轻量级)
切换成本 高(要切换整个环境) 低(只需切换少量上下文)
通信方式 复杂(管道、消息队列等) 简单(直接读写共享内存)
独立性 独立,一个崩溃不影响其他 相互影响,一个线程崩溃可能导致整个进程崩溃
资源 拥有独立的内存、文件句柄等 共享进程的资源
  • 进程独立的公司 – 有自己独立的办公室、资金、资源

  • 线程公司里的员工 – 共享办公室资源,一起完成任务

进程是资源分配的单位,线程是CPU调度的单位。线程轻量,共享资源;进程重量,资源独立。

6.Java创建对象的方式

  • new 关键字(最常用)
  • Person person = new Person();
  • 反射(通过类名创建)
  • Person person = Person.class.newInstance();
  • clone()(复制对象)
  • Person person2 = (Person) person1.clone();
  • 反序列化(从文件恢复对象)
  • Person person = (Person) objectInputStream.readObject();
  • 工厂方法(通过方法创建)
  • Person person = Person.create();

7.单例模式懒汉式

// 懒汉式
public class Singleton {
// 延迟加载保证多线程安全
Private volatile static Singleton singleton; // 第1行:声明单例实例
private Singleton(){} // 第2行:私有构造方法
public static Singleton getInstance(){ // 第3行:获取实例的公共方法
if(singleton == null){ // 第4行:第一次检查
synchronized(Singleton.class){ // 第5行:加锁
if(singleton == null){ // 第6行:第二次检查
singleton = new Singleton(); // 第7行:创建实例
}
}
}
return singleton; // 第8行:返回实例
}
}

总结:

  • 延迟加载:只有调用 getInstance() 时才创建对象

  • 线程安全:通过双重检查和同步锁保证

  • 性能优化:只有第一次创建时需要同步,后续调用直接返回实例

8.JVM

  • JVM 是什么?

JVM(Java虚拟机) – 就像一台”虚拟的电脑”,专门用来运行Java程序。

  • JVM 的三大核心功能:
  • 内存管理 – 自动分配和回收内存

  • 跨平台 – “一次编译,到处运行”

垃圾回收 – 自动清理不再使用的对象

区域 存放什么 特点
所有对象 最大,GC主要区域
局部变量、方法调用 线程私有,速度快
方法区 类信息、常量 共享,存放元数据
  • 记住核心:
  • new 的对象 → 放在
  • 局部变量 → 放在
  • 类信息、常量 → 放在方法区
  • GC → 主要清理中的对象

9.synchronized 锁升级的过程

为什么要有锁升级:性能优化!

  • 无竞争:用偏向锁,开销最小

  • 轻度竞争:用自旋锁,避免线程切换

  • 激烈竞争:用重量级锁,避免CPU空转

简单总结:

锁状态 适用场景 特点 开销
无锁 新创建对象 直接访问
偏向锁 单线程访问 记录线程ID 很小
轻量级锁 轻度竞争 自旋等待 中等
重量级锁 激烈竞争 线程阻塞 很大

核心思想:根据竞争激烈程度,自动选择最合适的锁级别,平衡性能和功能!

10.CAS

CAS 是什么?

  • CAS(Compare And Swap) – 比较并交换,是一种无锁的原子操作。

CAS 原理

// CAS 的三个参数:
// V:要更新的变量(内存值)
// E:期望的值(我认为应该的值)
// N:新值(我要设置的值)

boolean CAS(V, E, N) {
    if (V == E) {     // 比较:内存值是否等于期望值
        V = N;        // 交换:如果相等就更新为新值
        return true;  // 成功
    }
    return false;     // 失败
}

优点:

  • 高性能:无锁,避免线程阻塞和切换

  • 线程安全:保证原子性操作

缺点:

  • ABA问题
  • 循环时间长开销大
  • 只能保证一个变量的原子性