面试官:第一轮提问开始,首先问你,说说Java中的多线程有哪些实现方式?
王铁牛:嗯……可以通过继承Thread类,或者实现Runnable接口。
面试官:回答得不错。那再问一个,线程池有哪些参数,分别有什么作用?
王铁牛:线程池有corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler这些参数。corePoolSize是核心线程数,maximumPoolSize是最大线程数,keepAliveTime是线程存活时间,unit是时间单位,workQueue是任务队列,threadFactory是线程工厂,handler是拒绝策略。
面试官:很好。最后一个问题,简述一下HashMap的底层实现原理。
王铁牛:这个……HashMap底层是数组加链表加红黑树,当链表长度大于8且数组长度大于64时会转成红黑树。
面试官:好,第一轮提问结束。
第二轮提问。说说JVM的内存模型,包括哪些区域?
王铁牛:JVM内存模型包括程序计数器、虚拟机栈、本地方法栈、堆、方法区。
面试官:那类加载机制有哪些?
王铁牛:类加载机制有加载、验证、准备、解析、初始化。
面试官:再问一个,简述一下Spring的核心特性。
王铁牛:Spring的核心特性有依赖注入、面向切面编程、IoC容器。
面试官:第二轮提问完毕。
第三轮提问。MyBatis的缓存机制是怎样的?
王铁牛:呃……这个不太清楚。
面试官:Dubbo的集群容错策略有哪些?
王铁牛:大概……有失败重试、快速失败、并发调用、备份调用这些吧。
面试官:最后,说说RabbitMq的工作模式。
王铁牛:这个……我知道有直连模式、扇形模式,还有其他的……
面试官:好,面试结束,回去等通知吧。
答案:
- 多线程实现方式:
- 继承Thread类:创建一个类继承Thread类,重写run方法,然后创建该类的实例并调用start方法启动线程。
- 实现Runnable接口:创建一个类实现Runnable接口,实现run方法,然后创建Thread类的实例并将该实现类的实例作为参数传入Thread的构造函数,最后调用start方法启动线程。
- 线程池参数及作用:
- corePoolSize:核心线程数,线程池在完成预热后,会尽量保持这个数量的线程。
- maximumPoolSize:最大线程数,当任务队列满了且线程数小于最大线程数时,会创建新线程来执行任务。
- keepAliveTime:线程存活时间,当线程数大于核心线程数时,多余的线程在空闲多长时间后会被销毁。
- unit:时间单位,指定keepAliveTime的时间单位。
- workQueue:任务队列,用于存放提交的任务。
- threadFactory:线程工厂,用于创建线程,可自定义线程的一些属性。
- handler:拒绝策略,当任务队列满且线程数达到最大线程数时,如何处理新提交的任务。
- HashMap底层实现原理:
- HashMap底层是数组加链表加红黑树的结构。
- 初始化时会创建一个默认大小的数组。
- 当插入键值对时,会通过键的哈希值计算出在数组中的位置。
- 如果该位置为空,则直接插入新节点。
- 如果不为空,且键相同,则覆盖值。
- 如果不为空且键不同,则形成链表,当链表长度大于8且数组长度大于64时,链表会转成红黑树以提高查找效率。
- JVM内存模型区域:
- 程序计数器:记录当前线程执行的字节码指令地址。
- 虚拟机栈:每个方法执行时会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
- 本地方法栈:与虚拟机栈类似,用于执行本地方法。
- 堆:存放对象实例,是垃圾回收的主要区域。
- 方法区:存储已被虚拟机加载的类信息、常量、静态变量等数据。
- 类加载机制:
- 加载:将类的字节码文件加载到内存中。
- 验证:检查字节码文件的正确性、安全性等。
- 准备:为类的静态变量分配内存并设置初始值。
- 解析:将符号引用转换为直接引用。
- 初始化:执行类的静态代码块和为静态变量赋值。
- Spring核心特性:
- 依赖注入:通过IoC容器将对象之间的依赖关系注入到对象中。
- 面向切面编程:可以在不修改原有代码的基础上,对业务逻辑进行增强。
- IoC容器:负责创建、管理和装配对象,实现对象之间的解耦。
- MyBatis缓存机制:
- 一级缓存:是SqlSession级别的缓存,在同一个SqlSession中查询相同的数据时,会直接从缓存中获取,不会再次查询数据库。
- 二级缓存:是namespace级别的缓存,多个SqlSession可以共享二级缓存。开启二级缓存后,数据会先存到一级缓存,当SqlSession关闭时,会将一级缓存中的数据同步到二级缓存。
- Dubbo集群容错策略:
- 失败重试:失败后重新调用,直到成功。
- 快速失败:只要有一次调用失败,就立即返回错误。
- 并发调用:多个服务实例同时调用,只要有一个成功就返回。
- 备份调用:当主调用失败时,调用备份服务。
- RabbitMq工作模式:
- 直连模式:消息会被发送到绑定了指定路由键的队列中。
- 扇形模式:消息会被发送到所有绑定了该交换机的队列中。
- 主题模式:通过绑定键和路由键的匹配规则,将消息发送到相应的队列。
- 头模式:通过消息头中的属性进行匹配来发送消息到队列。