第一轮面试 面试官:首先问几个基础问题。讲讲Java中ArrayList和HashMap的区别。 王铁牛:ArrayList是有序的,按顺序存放元素,HashMap是无序的,通过键值对存储。 面试官:不错,回答得很清晰。那HashMap在JDK1.7和JDK1.8中有什么主要区别? 王铁牛:呃……1.8好像是用红黑树优化了吧,解决了链表过长查找慢的问题。 面试官:嗯,基本要点抓住了。再说说ArrayList扩容机制是怎样的? 王铁牛:当元素数量达到容量时,会扩容为原来的1.5倍,然后把旧数据复制到新数组。 面试官:回答得很好。
第二轮面试 面试官:接下来问些多线程和JUC相关的。讲讲线程池的核心参数有哪些? 王铁牛:有核心线程数、最大线程数、存活时间,还有阻塞队列。 面试官:很好。那线程池的拒绝策略有哪些? 王铁牛:有AbortPolicy,直接抛出异常;还有DiscardPolicy,丢弃任务不处理。 面试官:嗯,回答得不错。那在高并发场景下,如何合理配置线程池参数? 王铁牛:呃……就是根据任务类型和数量吧,具体怎么配我还不是特别清楚。 面试官:好吧。
第三轮面试 面试官:最后问些框架相关的。Spring的IOC和AOP是什么? 王铁牛:IOC是控制反转,把对象创建和管理交给Spring容器;AOP是面向切面编程,能在不修改代码的情况下增加功能。 面试官:回答得不错。那Spring Boot相比于Spring有什么优势? 王铁牛:Spring Boot简化了配置,能快速搭建项目,内置了很多依赖。 面试官:很好。那MyBatis的一级缓存和二级缓存有什么区别? 王铁牛:一级缓存是SqlSession级别的,二级缓存是Mapper级别的,二级缓存能跨SqlSession。 面试官:嗯。Dubbo在分布式系统中有什么作用? 王铁牛:它是个分布式服务框架,能实现服务治理,像服务注册、发现这些。 面试官:那RabbitMQ在项目中一般用于什么场景? 王铁牛:用于异步处理、解耦,还有削峰填谷。 面试官:最后说说xxl - job在项目中的应用场景。 王铁牛:它是个分布式任务调度平台,能做定时任务这些。 面试官:好的,今天的面试就到这里。你的基础知识掌握得还可以,但在一些深入问题上还有欠缺。回去等通知吧,我们会综合评估所有候选人后,再决定是否录用你。
问题答案
- ArrayList和HashMap的区别:
- 数据结构:ArrayList基于数组实现,有序存储元素;HashMap基于哈希表,以键值对形式存储,无序。
- 存储方式:ArrayList按顺序添加元素,通过索引访问;HashMap根据键的哈希值计算存储位置,通过键获取值。
- 应用场景:ArrayList适合需要顺序访问、频繁插入删除元素的场景;HashMap适合根据键快速查找值的场景。
- HashMap在JDK1.7和JDK1.8中的主要区别:
- 数据结构:JDK1.7采用数组 + 链表;JDK1.8采用数组 + 链表 + 红黑树。当链表长度超过8且数组容量大于64时,链表转换为红黑树,提高查找效率。
- 哈希计算:JDK1.8优化了哈希计算,减少哈希冲突。
- 插入方式:JDK1.7采用头插法,多线程下可能形成环形链表;JDK1.8采用尾插法,避免此问题。
- ArrayList扩容机制:
- 初始容量为10。当添加元素导致元素个数达到容量大小时,新容量为原容量的1.5倍(原容量右移一位再加原容量)。
- 创建新数组,将旧数组元素复制到新数组。
- 线程池的核心参数:
- 核心线程数:线程池长期维持的线程数,即使线程处于空闲状态也不会被销毁。
- 最大线程数:线程池能容纳的最大线程数。
- 存活时间:非核心线程在空闲状态下能存活的最长时间。
- 阻塞队列:用于存放任务的队列,当核心线程都在执行任务时,新任务会进入队列等待。
- 线程池的拒绝策略:
- AbortPolicy:直接抛出RejectedExecutionException异常,阻止系统正常运行。
- DiscardPolicy:丢弃任务,不做任何处理。
- DiscardOldestPolicy:丢弃队列中最老的任务,尝试提交新任务。
- CallerRunsPolicy:由调用线程处理该任务,降低新任务提交速度。
- 高并发场景下合理配置线程池参数:
- 任务类型:CPU密集型任务,核心线程数 = CPU核心数 + 1;IO密集型任务,核心线程数 = CPU核心数 * 2。
- 任务数量:预估任务数量,结合阻塞队列容量,合理设置最大线程数。若任务数量波动大,可适当增大最大线程数和阻塞队列容量。
- Spring的IOC和AOP:
- IOC(控制反转):将对象创建和管理的控制权从应用程序转移到Spring容器,实现解耦。通过依赖注入(DI)方式,容器为对象提供依赖对象。
- AOP(面向切面编程):将与业务逻辑无关的通用功能(如日志、事务管理)抽象为切面,在不修改原有业务代码的情况下,将切面功能切入到业务流程中。
- Spring Boot相比于Spring的优势:
- 简化配置:采用默认配置,减少XML配置,通过注解和自动配置快速搭建项目。
- 快速开发:内置大量依赖,如Tomcat、Spring MVC等,可快速创建独立运行的Spring应用。
- 生产就绪:提供监控、健康检查等功能,方便应用在生产环境部署和管理。
- MyBatis的一级缓存和二级缓存区别:
- 作用域:一级缓存是SqlSession级别的,在同一个SqlSession内有效;二级缓存是Mapper级别的,多个SqlSession可共享。
- 生命周期:一级缓存随SqlSession关闭而消失;二级缓存可跨SqlSession,应用重启才会清空。
- 应用场景:一级缓存用于减少同一个SqlSession内相同SQL查询;二级缓存用于减少不同SqlSession间相同SQL查询,提高系统性能。
- Dubbo在分布式系统中的作用:
- 服务治理:提供服务注册、发现功能,使服务提供者和消费者能相互找到对方。
- 负载均衡:支持多种负载均衡策略,如随机、轮询等,将请求均匀分配到多个服务实例。
- 远程调用:采用高性能的RPC协议,实现不同服务间的远程方法调用。
- RabbitMQ在项目中的应用场景:
- 异步处理:将耗时操作放入消息队列,主线程继续执行,提高系统响应速度。
- 解耦:使不同模块通过消息队列通信,降低模块间耦合度。
- 削峰填谷:在高并发时,消息队列缓存消息,避免系统因瞬间高流量而崩溃。
- xxl - job在项目中的应用场景:
- 定时任务:可设置任务执行周期,如每天凌晨执行数据清理任务。
- 分布式任务调度:在分布式系统中,协调多个节点执行任务,保证任务按计划执行。