Java面试八股文

面试准备,java八股文学习。

Java面试八股文

1. Java中线程的实现方式

可以有三种,四种,五种。追其底层,只有一种,基于Runnable。

1.1 继承Thread类,重写run方法

Thread类实现了runnable

1.2 实现Runnable接口,重写run方法

其中有lambda表达式实现,称为第五种

1.3 实现Callable,重写call方法,配合FutureTask

想拿到返回结果,Thread和Runnable不能实现,此方法可以拿到返回结果。

FutureTask实现了RunnableFuture接口,RunnableFuture继承了Runnable和Future两个接口。

1.4 基于线程池构建线程

ThreadPoolExecutor,每次构建的线程是Worker,Worker实现了Runnable

2. Java中线程的状态

五种、六种、七种。

2.1 五种,传统的线程状态,操作系统层面

2.2 六种,Java给线程准备的(优先回答)

2.3 七种,将六种状态划分中的运行和就绪态拆开

3. Java中如何停止线程

3.1 stop,强制结束,(不用)

3.2 使用共享变量,(很少会用)

手动添加全局共享变量flag,线程内部通过while(flag)控制,通过修改flag破坏死循环。

3.3 interrupt方式

线程内部的中断标记位interrupt,通过isInterrupted()来查询线程的中断标记位状态,interrupt()来中断线程(置true),interrupted获取中断标记位再归位(false)。

如果线程正在休眠,修改了interrupt位,会抛出异常,让run方法结束。也就是在线程的WAITINGTIMED_WATING状态即可停止线程。

4. Java中sleep和wait方法的区别

4.1 sleep是Thread类中的static方法,wait是Object类方法

4.2 sleep是TIMED_WAITING,休眠结束自动被唤醒,wait输入WAITING,需手动唤醒

4.3 有锁时sleep不会释放锁,wait会

4.4 sleep有锁没锁都可执行,wait只有在有锁才能执行

wait方法会将持有锁的线程从owner进去WaitSet集合,修改ObjectMonitor对象(ObjectMonitor负责维护锁的状态,实现底层的锁机制),不持有synchronized锁,无法操作。

5. 并发编程的三大特性

5.1 原子性

5.2 可见性

5.3 有序性

内容太多,记不完:https://www.bilibili.com/video/BV1Av4y187hf?p=6

6. 什么是CAS,有什么优缺点

Compare And Swap。

比较和交换,CPU并发原语,替换内存某个位置值时,先查看内存值是否与预期一致,一致则替换,返回true。不一致返回false。

优点:不必让线程进入阻塞状态,不必挂起,避免用户态和内核态切换。

缺点:

  • 不停地while循环执行CAS,消耗CPU(解决:指定最大循环上限,超出则失败/挂起线程)。
  • 只能保证对一个变量的操作是原子性的,无法实现多行代码原子性,存在ABA问题(解决:为变量增加版本信息)。
  • 并发量大时竞争多,成功率低,性能下降。(解决:LongAdder,将累加操作分摊到多个变量(cell)中,线程选择一个累加,需要获取累加结果时求cell总和)

7. @Contended注解有什么用

解决伪共享问题(解决缓存行同步带来的性能问题)

CPU缓存L1时默认以缓存行为单位来存储,一般为64字节,缓存行中有数据改变则缓存行无效,需重新加载整个缓存行,影响CPU性能。

@Contended注解将当前类属性独占缓存行(剩余空间填无意义数据),避免缓存行失效造成的性能问题。

需要被频繁修改的变量添加@Contended注解独占缓存行,不会影响其他变量。

8. Java中的四种引用类型

强、软、弱、虚

8.1 强引用:把一个对象赋给引用变量

1
User user = new User();

最常见,始终处于可达状态,不会被垃圾回收机制回收(在函数内定义,弹栈后会被回收),造成Java内存泄露的主要原因之一。

8.2 软引用:SoftReference

系统内存足够不会被回收,内存空间不足会被回收。软引用用在内存敏感程序作为缓存使用。

8.3 弱引用

只有弱引用的对象,只要垃圾回收机制一进行,不管内存够不够,总会回收该对象的内存。解决内存泄露问题。

8.4 虚引用

不能单独使用。主要作用是跟踪对象被垃圾回收的状态。

通常与ReferenceQueue(引用队列)一起使用。当虚引用关联的对象被垃圾回收器回收时,虚引用会被放入与之关联的引用队列中。通过检查引用队列中的虚引用,可以得知对象已经被回收了。