互联网大厂 Java 面试:核心知识、框架与中间件大考验
严肃的面试官坐在桌前,面前放着求职者王铁牛的简历。王铁牛有些紧张地走进面试房间,坐下后,面试开始了。
第一轮提问 面试官:首先问几个 Java 核心知识的问题。Java 中基本数据类型有哪些? 王铁牛:嗯,有 byte、short、int、long、float、double、char、boolean。 面试官:回答得不错。那在 Java 里,什么是多态,多态有什么作用? 王铁牛:多态就是一个对象有多种形态嘛。作用就是提高代码的可扩展性和可维护性。 面试官:很好。那说说 Java 中抽象类和接口的区别。 王铁牛:抽象类可以有普通方法和抽象方法,而接口里基本都是抽象方法,并且接口里变量默认是常量。
第二轮提问 面试官:接下来考考你 JUC 和多线程相关的。什么是线程池,为什么要使用线程池? 王铁牛:线程池就是管理线程的一个池子。使用线程池可以减少创建和销毁线程的开销,提高性能。 面试官:那线程池有哪些状态? 王铁牛:这个……好像有运行、关闭啥的,具体我有点记不清了。 面试官:再问你,JUC 里的 CountDownLatch 是怎么用的,有什么场景? 王铁牛:它好像是用来计数的,场景嘛……我也不太确定。
第三轮提问 面试官:现在来问些框架和中间件的问题。Spring 的 IOC 和 AOP 是什么,有什么作用? 王铁牛:IOC 是控制反转,把对象的创建和管理交给 Spring 容器。AOP 是面向切面编程,能实现日志、事务等功能。 面试官:那 Spring Boot 相比 Spring 有什么优势? 王铁牛:Spring Boot 好像更简单,能快速搭建项目,有自动配置啥的。 面试官:说说 MyBatis 的工作原理。 王铁牛:这个……就是和数据库交互,具体原理我讲不太清楚。
面试接近尾声,面试官合上手中的资料。 面试官:王铁牛,今天的面试就到这里了。你对于一些基础问题回答得还可以,但对于部分复杂的知识点掌握得不够扎实。我们会综合评估你的表现,你回家等通知吧。
答案解析
- Java 基本数据类型:Java 中有 8 种基本数据类型,分别是 4 种整数类型(byte 占 1 字节,范围 -128 到 127;short 占 2 字节;int 占 4 字节,是最常用的整数类型;long 占 8 字节,定义时数字后要加 L),2 种浮点类型(float 占 4 字节,定义时数字后要加 F;double 占 8 字节,是常用的浮点类型),1 种字符类型(char 占 2 字节,用来存储单个字符),1 种布尔类型(boolean 只有 true 和 false 两个值)。
- 多态:多态是指同一个行为具有多个不同表现形式或形态的能力。在 Java 中,多态的实现方式主要有方法重载(在一个类中,有多个方法名相同但参数列表不同的方法)和方法重写(子类重写父类的方法)。多态的作用在于提高代码的可扩展性和可维护性,例如在父类引用指向子类对象时,可以根据实际的子类对象调用不同的方法,而不需要修改调用代码。
- 抽象类和接口的区别:
- 抽象类是用 abstract 关键字修饰的类,它可以包含普通方法和抽象方法(用 abstract 修饰,只有方法声明没有方法体)。抽象类不能被实例化,只能被继承,子类必须实现抽象类中的抽象方法。
- 接口是一种特殊的抽象类型,接口中的方法默认是 public abstract 的,变量默认是 public static final 的。一个类可以实现多个接口,但只能继承一个抽象类。接口更强调一种行为的规范,而抽象类更侧重于对一类事物的抽象。
- 线程池:线程池是一种线程使用模式,它预先创建一定数量的线程并将其存储在一个“池子”中。当有任务提交时,线程池会从池中取出一个空闲线程来执行该任务。使用线程池的好处主要有:减少线程创建和销毁的开销,因为创建和销毁线程是比较消耗资源的操作;提高响应速度,任务提交后可以立即有线程来执行;便于线程的管理,可以对线程的数量、生命周期等进行统一管理。
- 线程池的状态:线程池有 5 种状态,分别是:
- RUNNING:能接受新任务,也能处理阻塞队列中的任务。
- SHUTDOWN:不接受新任务,但能处理阻塞队列中的任务。
- STOP:不接受新任务,也不处理阻塞队列中的任务,会中断正在执行的任务。
- TIDYING:所有任务都已终止,工作线程数量为 0,线程池会转换到 TIDYING 状态,然后会执行 terminated() 钩子方法。
- TERMINATED:terminated() 方法执行完成后,线程池进入此状态。
- CountDownLatch:CountDownLatch 是 JUC 包中的一个同步工具类,它允许一个或多个线程等待其他线程完成操作。它通过一个计数器来实现,计数器的初始值是线程的数量。每当一个线程完成自己的任务后,计数器的值就会减 1。当计数器的值为 0 时,表示所有线程都已经完成任务,等待的线程就可以继续执行。常见的使用场景比如在主线程中等待多个子线程完成数据加载等操作后再继续执行后续逻辑。
- Spring 的 IOC 和 AOP:
- IOC(Inversion of Control)控制反转,是 Spring 的核心思想之一。传统的开发中,对象的创建和依赖关系的管理是由程序员手动完成的,而在 Spring 中,对象的创建和管理交给了 Spring 容器。Spring 容器通过读取配置文件或注解来创建对象,并将对象之间的依赖关系注入到对象中,这样就实现了对象的创建和使用的分离,提高了代码的可维护性和可测试性。
- AOP(Aspect Oriented Programming)面向切面编程,是一种编程范式,它允许开发者在不修改原有业务逻辑的基础上,对程序进行增强。在 Spring 中,AOP 主要用于实现一些与业务逻辑无关的功能,如日志记录、事务管理、权限验证等。Spring AOP 通过代理模式实现,有 JDK 动态代理和 CGLIB 代理两种方式。
- Spring Boot 相比 Spring 的优势:
- 快速搭建项目:Spring Boot 提供了很多开箱即用的 Starter 依赖,通过添加这些依赖可以快速集成各种功能,无需手动配置大量的依赖。
- 自动配置:Spring Boot 可以根据项目中添加的依赖自动进行配置,大大减少了配置文件的编写。
- 内嵌服务器:Spring Boot 内嵌了 Tomcat、Jetty 等服务器,无需单独部署服务器,直接运行项目即可。
- 监控和管理:Spring Boot Actuator 提供了对应用的监控和管理功能,方便开发者了解应用的运行状态。
- MyBatis 的工作原理:
- 加载配置文件:MyBatis 首先会加载配置文件(如 mybatis-config.xml),该文件中包含了数据库连接信息、映射文件的位置等配置。
- 创建 SqlSessionFactory:根据配置文件创建 SqlSessionFactory,它是 MyBatis 的核心工厂类,负责创建 SqlSession 对象。
- 创建 SqlSession:SqlSession 是 MyBatis 与数据库交互的会话,它提供了执行 SQL 语句的方法。
- 执行 SQL 语句:通过 SqlSession 获取 Mapper 接口的代理对象,调用 Mapper 接口的方法,MyBatis 会根据映射文件(如 UserMapper.xml)中的 SQL 语句和参数信息,将 SQL 语句发送到数据库执行,并将结果封装成 Java 对象返回。
- 关闭会话:使用完 SqlSession 后,需要关闭会话以释放资源。