面试官:欢迎你来面试,先简单介绍一下你自己吧。
王铁牛:面试官您好,我叫王铁牛,之前有过一些Java开发的经验,熟悉各种Java基础操作。
面试官:第一轮提问开始。首先,说说Java中多线程的实现方式有哪些?
王铁牛:可以通过继承Thread类,或者实现Runnable接口,还有实现Callable接口这几种方式。
面试官:回答得不错。那再问你,线程池的核心参数都有哪些,分别有什么作用?
王铁牛:核心参数有corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。corePoolSize是核心线程数,maximumPoolSize是最大线程数,keepAliveTime是线程存活时间,unit是时间单位,workQueue是任务队列,threadFactory是线程工厂,handler是拒绝策略。
面试官:很好。最后一个问题,如何创建一个线程池?
王铁牛:可以通过ThreadPoolExecutor类来创建,传入那几个核心参数就行。
面试官:第一轮表现不错。接下来第二轮提问。讲讲HashMap的底层数据结构和扩容机制。
王铁牛:HashMap底层是数组+链表+红黑树。扩容机制就是当元素个数超过阈值(容量*负载因子)时就会扩容,扩容是2倍。
面试官:那HashMap在多线程环境下会出现什么问题?
王铁牛:会出现死循环、数据丢失等问题。
面试官:如何解决HashMap在多线程环境下的问题?
王铁牛:可以用ConcurrentHashMap,它是线程安全的。
面试官:第二轮回答得还可以。进入第三轮提问。说说Spring框架中IoC和AOP的概念。
王铁牛:IoC就是控制反转,把对象的创建和依赖注入交给Spring容器。AOP是面向切面编程,用来处理横切关注点。
面试官:Spring Boot的自动配置原理是什么?
王铁牛:就是通过@EnableAutoConfiguration注解,它会根据类路径下的依赖自动配置。
面试官:MyBatis的缓存机制了解吗?
王铁牛:有一级缓存和二级缓存,一级缓存是SqlSession级别的,二级缓存是namespace级别的。
面试官:好的,今天的面试就到这里,回去等通知吧。
答案:
- 多线程实现方式:
- 继承Thread类:通过继承Thread类并重写run方法来创建线程。
- 实现Runnable接口:实现Runnable接口的run方法,然后将其作为参数传递给Thread类的构造函数来创建线程。
- 实现Callable接口:实现Callable接口的call方法,通过FutureTask包装器来创建线程并获取返回值。
- 线程池核心参数及作用:
- corePoolSize:核心线程数,当提交的任务数小于corePoolSize时,会创建新线程来执行任务。
- maximumPoolSize:最大线程数,当提交的任务数大于corePoolSize且workQueue已满时,会创建新线程直到线程数达到maximumPoolSize。
- keepAliveTime:线程存活时间,当线程数大于corePoolSize时,多余的线程在空闲指定时间后会被销毁。
- unit:时间单位,指定keepAliveTime的时间单位。
- workQueue:任务队列,用于存放提交的任务,当线程数达到corePoolSize时,新任务会放入此队列。
- threadFactory:线程工厂,用于创建线程,可自定义线程的名称、优先级等。
- handler:拒绝策略,当线程数达到maximumPoolSize且workQueue已满时,会调用此策略来处理新提交的任务。
- 创建线程池:通过ThreadPoolExecutor类,传入corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler这些参数来创建。
- HashMap底层数据结构和扩容机制:
- 底层数据结构:是数组+链表+红黑树。初始时是一个数组,当链表长度超过8且数组容量大于64时,链表会转换为红黑树。
- 扩容机制:当元素个数超过阈值(容量*负载因子)时就会扩容,扩容是2倍。扩容时会重新计算元素的位置并插入新数组。
- HashMap在多线程环境下的问题及解决方法:
- 问题:会出现死循环、数据丢失等问题。比如在扩容时可能导致链表形成环形结构,导致后续遍历死循环;在多线程put时可能导致数据覆盖丢失。
- 解决方法:使用ConcurrentHashMap,它通过分段锁机制保证线程安全,在put等操作时不会像HashMap那样出现上述问题。
- Spring框架中IoC和AOP的概念:
- IoC(控制反转):把对象的创建和依赖注入交给Spring容器,而不是在代码中直接创建和管理对象,降低了对象之间的耦合度。
- AOP(面向切面编程):用来处理横切关注点,比如日志记录、事务管理等,将这些功能从业务逻辑中分离出来,以提高代码的可维护性和复用性。
- Spring Boot自动配置原理:通过@EnableAutoConfiguration注解,它会根据类路径下的依赖自动配置相关的Bean。Spring Boot会根据引入的starter依赖,自动猜测并配置应用所需的各种组件和配置,极大地简化了应用的配置过程。
- MyBatis缓存机制:
- 一级缓存:是SqlSession级别的缓存,在同一个SqlSession中查询相同数据时,会直接从缓存中获取,不会再次查询数据库。
- 二级缓存:是namespace级别的缓存,多个SqlSession可以共享二级缓存。开启二级缓存后,当一个SqlSession查询数据并放入二级缓存后,其他SqlSession查询相同数据时可以从二级缓存获取。