第一轮面试 面试官:先聊聊Java基础,Java中基本数据类型有哪些? 王铁牛:基本数据类型有int、double、float、char、boolean、byte、short、long这8种。 面试官:不错,回答得很准确。那自动装箱和拆箱是怎么回事? 王铁牛:自动装箱就是Java自动将基本数据类型转为包装类型,比如int转Integer;拆箱就是反过来,包装类型转基本数据类型。 面试官:回答得挺好。那说说ArrayList和LinkedList在存储结构上有什么区别? 王铁牛:ArrayList是基于数组实现的,LinkedList是基于链表实现的。
第二轮面试 面试官:接下来谈谈多线程,线程有哪些状态? 王铁牛:有新建、就绪、运行、阻塞、死亡这几种状态。 面试官:很好。那什么是线程安全? 王铁牛:嗯……就是多个线程访问的时候,不会出现数据不一致之类的问题。 面试官:那在多线程环境下,HashMap为什么不安全? 王铁牛:呃……好像是因为在扩容的时候可能会出现死循环,还有数据覆盖啥的。
第三轮面试 面试官:聊聊框架,Spring的IOC是什么? 王铁牛:IOC就是控制反转,把对象创建和管理的控制权交给Spring容器。 面试官:不错。那Spring Boot有什么优势? 王铁牛:它简化了Spring应用的搭建和开发,内置了很多依赖,能快速上手。 面试官:那MyBatis的一级缓存和二级缓存是怎么回事? 王铁牛:一级缓存是SqlSession级别的,二级缓存是mapper级别的,但是具体怎么工作的,我……有点不太清楚。
面试总结:从整体面试情况来看,你在一些基础知识点的掌握上表现还可以,像Java基本数据类型、线程状态等回答得比较准确。然而,在一些稍微深入的问题上,比如多线程环境下HashMap不安全的具体原理,以及MyBatis缓存的详细工作机制,回答得不是很清晰。我们后续会综合评估所有面试者的情况,你回家等通知吧,无论结果如何,我们都会在一周内给你回复。
问题答案:
- Java基本数据类型:包括byte(1字节)、short(2字节)、int(4字节)、long(8字节)、float(4字节)、double(8字节)、char(2字节)、boolean(1位,在虚拟机规范中未明确规定具体大小)。这些基本数据类型是Java语言的基础,用于存储简单的数据值。
- 自动装箱和拆箱:自动装箱是Java编译器在编译期自动将基本数据类型转换为对应的包装类型,例如
int i = 10; Integer integer = i;这里i就自动装箱成了Integer对象。拆箱则相反,是将包装类型转换回基本数据类型,如Integer integer = 10; int i = integer;。这一机制使得基本数据类型和包装类型在使用上更加便捷。 - ArrayList和LinkedList存储结构区别:ArrayList基于动态数组实现,它的优点是随机访问效率高,因为可以通过数组下标直接定位元素。缺点是插入和删除操作在非尾部位置时效率低,需要移动大量元素。LinkedList基于双向链表实现,每个节点包含前驱、后继和数据域。它的优点是插入和删除操作效率高,只需修改相邻节点的指针。缺点是随机访问效率低,需要从头或尾开始遍历链表查找元素。
- 线程状态:新建(New):线程被创建但尚未启动。就绪(Runnable):线程调用
start()方法后进入就绪状态,等待CPU调度执行。运行(Running):线程获得CPU时间片正在执行。阻塞(Blocked):线程因为某些原因暂停执行,如等待锁、I/O操作等。死亡(Terminated):线程执行完毕或因异常退出。 - 线程安全:当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象是线程安全的。简单说就是多个线程操作共享资源时,不会出现数据不一致、错误等问题。
- 多线程环境下HashMap不安全:在JDK1.7及之前,HashMap在扩容时采用头插法,当多个线程同时进行扩容时,可能会形成环形链表,导致死循环。同时,在多线程put操作时,可能会出现数据覆盖的情况。在JDK1.8中,虽然采用尾插法解决了环形链表问题,但在多线程下put操作仍可能出现数据覆盖,因为没有同步机制。
- Spring的IOC:控制反转(Inversion of Control),是一种设计思想。传统应用程序中,对象的创建和管理由应用程序自身负责。而在Spring框架中,将对象的创建、初始化、销毁等控制权交给Spring容器,应用程序只需要使用这些对象即可。通过依赖注入(Dependency Injection,DI)这种方式来实现IOC,比如通过构造函数注入、setter方法注入等,使得组件之间的依赖关系由容器来管理,降低了组件之间的耦合度。
- Spring Boot优势:它简化了Spring应用的搭建和开发过程。内置了大量的依赖,如Tomcat、Spring等,开箱即用,减少了繁琐的配置。提供了自动配置功能,能根据项目中的依赖自动配置Spring应用。还支持快速构建微服务,方便部署和监控,大大提高了开发效率。
- MyBatis一级缓存和二级缓存:一级缓存是SqlSession级别的缓存,在同一个SqlSession中,执行相同的SQL查询时,MyBatis会先从一级缓存中查找数据,如果有则直接返回,不再执行SQL查询。当SqlSession执行
commit、rollback等操作修改数据时,一级缓存会被清空。二级缓存是mapper级别的缓存,多个SqlSession可以共享二级缓存。MyBatis默认不开启二级缓存,需要手动配置。开启后,当一个SqlSession查询数据时,先从二级缓存找,如果没有再查数据库,查询结果会放入二级缓存。二级缓存的生命周期比一级缓存长,只有当mapper对应的namespace下执行了修改操作,才会清空该namespace下的二级缓存。