互联网大厂面试:Java 核心、JUC、JVM 等知识大考验
王铁牛怀揣着紧张与期待,坐在了互联网大厂的面试会议室里,对面的面试官一脸严肃,手中拿着王铁牛的简历,一场激烈的技术问答即将拉开帷幕。
第一轮面试开始 面试官:首先问你几个 Java 核心知识的问题。Java 中基本数据类型有哪些? 王铁牛:这个我知道,有 byte、short、int、long、float、double、char、boolean。 面试官:不错,回答得很准确。那 Java 中 String 类为什么是不可变的? 王铁牛:因为 String 类被 final 修饰,它的成员变量也是 final 的,一旦创建就不能被修改。 面试官:很好,基础很扎实。那说说 Java 中 == 和 equals 的区别。 王铁牛:== 比较的是对象的引用地址,而 equals 方法默认也是比较引用地址,但像 String 等类重写了 equals 方法,用来比较对象的内容。 面试官:非常棒,看来你对 Java 核心知识掌握得很牢固。
第二轮面试开始 面试官:接下来考考你 JUC 和多线程相关的问题。什么是 JUC? 王铁牛:JUC 就是 java.util.concurrent 包,它提供了并发编程的工具类。 面试官:对的。那在 Java 中创建线程有几种方式? 王铁牛:有三种,继承 Thread 类、实现 Runnable 接口、实现 Callable 接口。 面试官:很好。那说说 synchronized 和 ReentrantLock 的区别。 王铁牛:嗯……这个,好像都是用来加锁的,具体区别我有点说不太清了。 面试官:没关系,这个问题稍微复杂一些。简单来说,synchronized 是 Java 的关键字,是隐式锁,而 ReentrantLock 是类,是显式锁,使用起来更灵活。
第三轮面试开始 面试官:现在问你一些框架相关的问题。Spring 的核心特性有哪些? 王铁牛:Spring 的核心特性有 IoC(控制反转)和 AOP(面向切面编程)。 面试官:不错。那 Spring Boot 有什么优点? 王铁牛:Spring Boot 可以快速搭建项目,简化配置,有很多 starter 依赖,能让开发更高效。 面试官:很好。那 MyBatis 中 #{} 和 {} 的区别是什么? **王铁牛**:这个……我记得好像一个是预编译,一个不是,但具体哪个是哪个我有点乱了。 **面试官**:#{} 是预编译处理,能防止 SQL 注入,而 {} 是直接替换,可能会有 SQL 注入风险。整体来看,你对一些基础问题掌握得还可以,但对于一些稍微复杂的问题,理解还不够深入。你先回家等通知吧,后续如果有结果会及时联系你。
答案详解
- Java 中基本数据类型:
- Java 中有 8 种基本数据类型,分为 4 类。
- 整数类型:byte(1 字节)、short(2 字节)、int(4 字节)、long(8 字节)。
- 浮点类型:float(4 字节)、double(8 字节)。
- 字符类型:char(2 字节)。
- 布尔类型:boolean(理论上 1 位,但实际实现可能不同)。
- Java 中 String 类为什么是不可变的:
- String 类被 final 修饰,意味着它不能被继承。
- 它的成员变量 value 是一个 final 的 char 数组,一旦初始化就不能再指向其他数组,且 String 类没有提供修改这个数组内容的方法,所以 String 对象一旦创建就不可变。不可变的好处有提高性能、安全性、可以作为 HashMap 的键等。
- Java 中 == 和 equals 的区别:
- == 是一个比较运算符,对于基本数据类型,比较的是值是否相等;对于引用数据类型,比较的是对象的引用地址是否相同。
- equals 是 Object 类的方法,默认实现是比较引用地址。但很多类如 String、Integer 等重写了 equals 方法,用来比较对象的内容是否相等。
- 什么是 JUC:
- JUC 即 java.util.concurrent 包,是 Java 提供的用于并发编程的工具包,包含了很多用于处理并发问题的类和接口,如线程池、锁、并发集合等。
- 在 Java 中创建线程有几种方式:
- 继承 Thread 类:创建一个类继承 Thread 类,重写 run 方法,然后创建该类的对象并调用 start 方法启动线程。
- 实现 Runnable 接口:创建一个类实现 Runnable 接口,实现 run 方法,然后将该类的对象作为参数传递给 Thread 类的构造函数,再调用 start 方法启动线程。
- 实现 Callable 接口:创建一个类实现 Callable 接口,实现 call 方法,该方法有返回值。需要使用 FutureTask 来包装 Callable 对象,再将 FutureTask 对象传递给 Thread 类的构造函数,调用 start 方法启动线程,最后可以通过 FutureTask 的 get 方法获取线程执行的结果。
- synchronized 和 ReentrantLock 的区别:
- 语法层面:synchronized 是 Java 的关键字,是隐式锁,会自动加锁和解锁;ReentrantLock 是一个类,是显式锁,需要手动调用 lock 和 unlock 方法来加锁和解锁。
- 锁的获取和释放:synchronized 在发生异常时会自动释放锁;ReentrantLock 需要在 finally 块中确保锁被释放,否则可能会导致死锁。
- 锁的特性:ReentrantLock 提供了更多的特性,如可中断锁、公平锁等。
- Spring 的核心特性:
- IoC(控制反转):也称为依赖注入(DI),是指将对象的创建和依赖关系的管理交给 Spring 容器,而不是由对象自己来创建和管理。这样可以降低代码的耦合度,提高可维护性和可测试性。
- AOP(面向切面编程):是一种编程范式,它允许开发者在不修改原有代码的基础上,对程序进行增强。AOP 主要用于处理一些横切关注点,如日志记录、事务管理、权限验证等。
- Spring Boot 的优点:
- 快速搭建项目:提供了很多 starter 依赖,只需要添加相应的依赖,就可以快速搭建一个完整的项目。
- 简化配置:采用了约定大于配置的原则,减少了大量的配置文件,提高了开发效率。
- 内嵌服务器:内置了 Tomcat、Jetty 等服务器,不需要单独部署服务器。
- 生产就绪:提供了健康检查、监控等功能,方便在生产环境中使用。
- MyBatis 中 #{} 和 ${} 的区别:
- #{}:是预编译处理,MyBatis 会将 #{} 解析为一个占位符(?),然后使用 PreparedStatement 来执行 SQL 语句,这样可以防止 SQL 注入。
- **{} 直接替换为传入的值,可能会导致 SQL 注入风险。一般在需要动态传入表名、列名等情况时使用 ${}。