面试官:第一轮提问开始。首先,说说Java中的多线程有哪些实现方式?
王铁牛:嗯,多线程实现方式嘛,有继承Thread类,还有实现Runnable接口。
面试官:不错,回答正确。那创建线程池有几种方式?
王铁牛:有ThreadPoolExecutor和Executors这两种方式来创建线程池。
面试官:很好。再问一个,在多线程环境下,如何保证数据的一致性?
王铁牛:这个嘛,我想想……可以用锁,比如synchronized关键字。
面试官:第一轮提问结束,表现还不错。接下来第二轮提问。说说JVM的内存结构。
王铁牛:JVM内存结构包括堆、栈、方法区这些。
面试官:那垃圾回收算法有哪些?
王铁牛:有标记清除算法、标记整理算法、复制算法。
面试官:还行。HashMap在多线程环境下会出现什么问题?
王铁牛:会出现链表成环之类的问题吧。
面试官:第二轮提问完毕。现在进入第三轮提问。Spring框架的核心特性有哪些?
王铁牛:Spring的核心特性嘛,有依赖注入、面向切面编程。
面试官:那Spring Boot的优势是什么?
王铁牛:嗯……能快速搭建项目。
面试官:最后一个问题,MyBatis的缓存机制是怎样的?
王铁牛:好像有一级缓存和二级缓存。
面试官:三轮提问结束。整体表现有好有坏,复杂问题回答得不是很清晰。回家等通知吧。
答案:
- Java多线程实现方式:
- 继承Thread类:创建一个类继承Thread类,重写run方法,然后通过创建该类的实例来启动线程。例如:
class MyThread extends Thread {
@Override
public void run() {
System.out.println("This is a thread.");
}
}
MyThread thread = new MyThread();
thread.start();
- 实现Runnable接口:创建一个类实现Runnable接口,实现run方法,然后将该类实例作为参数传递给Thread类的构造函数来创建线程。例如:
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("This is a runnable thread.");
}
}
Thread thread = new Thread(new MyRunnable());
thread.start();
- 创建线程池的方式:
- ThreadPoolExecutor:可以通过ThreadPoolExecutor类来创建线程池,它提供了更灵活的参数设置。例如:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(),
new ThreadPoolExecutor.CallerRunsPolicy());
- Executors:通过Executors类的静态方法可以创建一些预定义的线程池,如newFixedThreadPool、newSingleThreadExecutor、newCachedThreadPool等。例如:
ExecutorService executor = Executors.newFixedThreadPool(5);
- 多线程环境下保证数据一致性:
- synchronized关键字:可以修饰方法或代码块,保证同一时刻只有一个线程能访问被修饰的资源。例如:
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
}
- JVM内存结构:
- 堆:是JVM中最大的一块内存区域,用于存储对象实例。
- 栈:每个线程都有自己的栈,用于存储局部变量、方法调用等。
- 方法区:存储类信息、常量、静态变量等。
- 垃圾回收算法:
- 标记清除算法:先标记出所有需要回收的对象,然后统一回收。
- 标记整理算法:标记出存活对象,然后将存活对象向一端移动,清理端边界以外的内存。
- 复制算法:将内存分为两块,每次只使用其中一块,当这块内存满了,将存活对象复制到另一块,然后清理原来的那块。
- HashMap在多线程环境下的问题:在多线程环境下,可能会出现链表成环(形成死循环)的问题,尤其是在扩容时。这是因为多线程同时进行put操作可能导致链表结构被破坏。
- Spring框架的核心特性:
- 依赖注入:通过容器将依赖对象注入到目标对象中,实现对象之间的解耦。
- 面向切面编程:将横切关注点(如日志、事务等)与业务逻辑分离。
- Spring Boot的优势:
- 快速搭建项目:提供了自动配置功能,能快速创建一个基于Spring的项目。
- 内置服务器:内置了Tomcat等服务器,方便项目部署。
- 简化配置:减少了大量繁琐的XML配置。
- MyBatis的缓存机制:
- 一级缓存:是SqlSession级别的缓存,在同一个SqlSession中查询相同数据时,会直接从缓存中获取。
- 二级缓存:是namespace级别的缓存,多个SqlSession可以共享。开启二级缓存后,数据会先放入一级缓存,当SqlSession关闭时,会将一级缓存的数据同步到二级缓存。