无题

无题
李阳1. Java基础
1. 谈谈你对AQS的理解
AQS是多线程同步器,它是J.U.C包中多个组件的底层实现,如Lock、CountDownLatch、Semaphore等都用到了AQS.
从本质上来说,AQS提供了两种锁机制,分别是排它锁,和 共享锁。
排它锁,就是存在多线程竞争同一共享资源时,同一时刻只允许一个线程访问该共享资源,也就是多个线程中只能有一个线程获得锁资源,比如Lock中的ReentrantLock重入锁实现就是用到了AQS中的排它锁功能。
共享锁也称为读锁,就是在同一时刻允许多个线程同时获得锁资源,比如CountDownLatch和Semaphore都是用到了AQS中的共享锁功能。
2. 你能说一下什么是受检异常和非受检异常吗?
在 Java 中,异常主要分为受检异常和非受检异常。
受检异常是指继承自 Exception,但不继承 RuntimeException 的异常。编译器会强制检查,必须通过 try-catch 捕获或者 throws 抛出,这类异常一般是业务可预期、可恢复的异常,比如 IOException、SQLException 等。
非受检异常包括 RuntimeException 和 Error。编译器不强制处理,通常是代码逻辑问题或者 JVM 层面的严重错误,比如 NullPointerException、IndexOutOfBoundsException,还有 OOM、栈溢出这类 Error。
简单来说,受检异常是编译期必须处理的,非受检异常是运行时才会出现的问题。我回答完毕,谢谢面试官。
3. 请说一下对象的创建过程
面试官您好,Java 对象创建过程我是这样理解的:
- 首先 JVM 会检查这个类有没有被加载过,如果没有,就先进行类加载。
- 然后在堆内存中为对象分配内存空间。
- 接着给对象的成员变量默认初始化,比如 int 变成 0,引用变成 null。
- 再执行我们代码里写的显式赋值和构造方法,给对象赋上真正的初始值。
- 最后把对象地址赋值给引用变量,对象就创建完成了。
4. 简单说一下你对序列化和反序列化的理解
序列化和反序列化是 Java 中用于处理对象 “跨存储 / 跨网络传输” 的核心机制:
- 序列化:把内存中的 Java 对象,转换成字节序列(二进制数据)的过程。比如把一个 User 对象转成字节流,方便存到文件里、或者通过网络传给另一台服务器。要实现序列化,只需要让类实现
Serializable标记接口就行。 - 反序列化:和序列化相反,是把字节序列重新转换成内存中可用的 Java 对象的过程。比如从文件里读出之前存的字节数据,还原成原来的 User 对象,能直接调用对象的方法、获取属性。
举个通俗的例子:序列化就像把行李箱(对象)打包成快递包裹(字节序列),方便运输;反序列化就是收到包裹后,拆开还原成原来的行李箱。
5. String、StringBuffer、StringBuilder区别
String、StringBuffer、StringBuilder 最主要就两点区别:能不能改、线程安不安全。
- String 是不可变的,每次拼接、修改,其实都是新建一个字符串,频繁修改会很慢、很占内存。
- StringBuilder 是可变的,修改直接在原对象上改,效率最高,但线程不安全,单线程用它最多。
- StringBuffer 也是可变的,效率比 StringBuilder 慢一点,但它加了锁,线程安全,适合多线程环境。





