面试官:请简要介绍一下 Java 中的多线程,以及如何创建一个线程。
王铁牛:多线程就是多个线程同时执行嘛。创建线程可以通过继承 Thread 类或者实现 Runnable 接口。
面试官:回答得不错。那线程池的核心参数有哪些,分别有什么作用?
王铁牛:线程池的核心参数有 corePoolSize、maximumPoolSize、keepAliveTime、unit 和 workQueue。corePoolSize 是核心线程数,maximumPoolSize 是最大线程数,keepAliveTime 是线程池中的线程在超出 corePoolSize 后,多余的空闲线程的存活时间,unit 是 keepAliveTime 的时间单位,workQueue 是任务队列。
面试官:很好。再问一个,说说 HashMap 的底层实现原理。
王铁牛:HashMap 底层是数组加链表加红黑树。当链表长度大于 8 且数组长度大于 64 时,链表会转换为红黑树。
第一轮提问结束。
面试官:谈谈 JVM 的内存结构。
王铁牛:JVM 内存结构包括堆、栈、方法区、程序计数器、本地方法栈。堆是存放对象实例的地方,栈是存放局部变量等,方法区存放类信息等。
面试官:那类加载机制有哪些?
王铁牛:类加载机制有加载、验证、准备、解析、初始化。
面试官:如何优化 JVM 的性能?
王铁牛:呃……可以调整堆大小,设置垃圾回收器之类的吧。
第二轮提问结束。
面试官:Spring 框架中依赖注入的方式有哪些?
王铁牛:有构造器注入、setter 注入。
面试官:Spring Boot 的自动配置原理是什么?
王铁牛:不太清楚,大概是能自动配置一些东西吧。
面试官:MyBatis 的动态 SQL 有哪些?
王铁牛:有 if、where、foreach 等。
第三轮提问结束。
面试官:好,今天的面试就到这里,回去等通知吧。
答案:
- 多线程:多线程是指程序中包含多个执行单元,这些执行单元可以同时执行不同的任务。创建线程的方式有两种,一种是继承 Thread 类,重写 run 方法;另一种是实现 Runnable 接口,实现 run 方法。
- 线程池核心参数:
- corePoolSize:核心线程数,当提交的任务数小于 corePoolSize 时,线程池会创建新线程来执行任务。
- maximumPoolSize:最大线程数,当提交的任务数大于 corePoolSize 且任务队列已满时,线程池会创建新线程来执行任务,直到线程数达到 maximumPoolSize。
- keepAliveTime:线程池中的线程在超出 corePoolSize 后,多余的空闲线程的存活时间。
- unit:keepAliveTime 的时间单位。
- workQueue:任务队列,用于存放提交的任务。
- HashMap 底层实现原理:HashMap 底层是数组加链表加红黑树。当链表长度大于 8 且数组长度大于 64 时,链表会转换为红黑树。HashMap 通过 key 的哈希值计算出在数组中的位置,然后将键值对存储在该位置对应的链表或红黑树中。
- JVM 内存结构:
- 堆:存放对象实例。
- 栈:存放局部变量等。
- 方法区:存放类信息等。
- 程序计数器:记录当前线程执行的字节码指令地址。
- 本地方法栈:用于执行本地方法。
- 类加载机制:
- 加载:将字节码文件加载到内存中。
- 验证:验证字节码文件的正确性。
- 准备:为类的静态变量分配内存并设置初始值。
- 解析:将符号引用转换为直接引用。
- 初始化:执行类的初始化代码。
- 优化 JVM 性能:
- 调整堆大小:根据应用程序的需求调整堆的大小,避免内存溢出或内存浪费。
- 设置垃圾回收器:选择合适的垃圾回收器,提高垃圾回收的效率。
- 优化代码:减少对象的创建和销毁,避免频繁的垃圾回收。
- Spring 依赖注入方式:
- 构造器注入:通过构造函数传递依赖对象。
- setter 注入:通过 setter 方法传递依赖对象。
- Spring Boot 自动配置原理:Spring Boot 会根据项目中引入的依赖自动配置相关的组件和配置。它通过条件注解等方式,根据类路径下的依赖和配置信息,自动选择合适的配置类和组件进行加载和配置,从而简化了项目的配置过程。
- MyBatis 动态 SQL:
- if:根据条件判断是否包含该 SQL 片段。
- where:自动处理 SQL 语句中的 where 子句,避免 where 关键字后面多余的 and 或 or。
- foreach:用于循环遍历集合,生成对应的 SQL 片段。