互联网大厂面试:Java 核心、并发、框架与中间件知识大考验
在互联网大厂宽敞明亮的面试室里,气氛略显紧张。严肃的面试官坐在桌前,对面坐着求职者王铁牛,他表面镇定,内心却有些忐忑。面试正式开始。
第一轮提问 面试官:首先问几个 Java 核心知识的问题。Java 中基本数据类型有哪些? 王铁牛:Java 的基本数据类型有 byte、short、int、long、float、double、char、boolean。 面试官:回答得不错。那你说说 Java 中多态的实现方式有哪些? 王铁牛:多态的实现方式主要有继承和接口。通过父类引用指向子类对象,或者接口引用指向实现类对象,在运行时根据实际对象类型调用相应方法。 面试官:很好。再问一个,Java 中异常处理机制是怎样的? 王铁牛:Java 的异常处理机制主要通过 try、catch、finally 关键字来实现。try 块中放置可能抛出异常的代码,catch 块用于捕获并处理异常,finally 块中的代码无论是否发生异常都会执行。
第二轮提问 面试官:接下来考察一下 JUC、JVM 和多线程方面的知识。JUC 包中常用的锁有哪些? 王铁牛:JUC 包中常用的锁有 ReentrantLock、ReentrantReadWriteLock 等。 面试官:可以。那说说 JVM 的内存模型是怎样的? 王铁牛:嗯……JVM 内存模型包括堆、栈、方法区等,堆是存放对象实例的,栈是存储局部变量和方法调用信息的。 面试官:回答得大致正确。再问你,多线程中如何实现线程同步? 王铁牛:可以使用 synchronized 关键字和 Lock 接口来实现线程同步。
第三轮提问 面试官:现在来问一些框架和中间件的问题。Spring 框架的核心特性有哪些? 王铁牛:Spring 的核心特性有 IoC(控制反转)和 AOP(面向切面编程)。 面试官:不错。那 Spring Boot 相对于 Spring 有哪些优势? 王铁牛:Spring Boot 简化了 Spring 项目的配置,有自动配置功能,能快速搭建项目。 面试官:很好。最后问你,Redis 有哪些数据结构,在业务场景中如何应用? 王铁牛:Redis 有字符串、哈希、列表、集合、有序集合这些数据结构。嗯……在业务场景中,字符串可以用于缓存,哈希可以存对象,其他的……用在什么地方我有点说不太清楚。
面试官:好的,今天的面试就到这里。你先回家等通知吧,我们会综合评估后给你答复。
答案解析
- Java 基本数据类型:Java 有 8 种基本数据类型,可分为四大类。整数类型:byte(1 字节)、short(2 字节)、int(4 字节)、long(8 字节);浮点类型:float(4 字节)、double(8 字节);字符类型:char(2 字节);布尔类型:boolean(理论上 1 位,但实际实现通常按 1 字节处理)。
- Java 多态的实现方式:
- 继承:通过子类继承父类,父类引用可以指向子类对象。在调用方法时,会根据实际对象类型调用相应的方法,实现运行时多态。例如:
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
animal.sound();
}
}
- **接口**:一个类可以实现多个接口,接口引用指向实现类对象。同样在调用接口方法时,会根据实际实现类来执行相应逻辑。
3. Java 异常处理机制: - try 块:包含可能抛出异常的代码。 - catch 块:用于捕获特定类型的异常,并在其中进行处理。可以有多个 catch 块,按顺序匹配异常类型。 - finally 块:无论 try 块中是否发生异常,finally 块中的代码都会执行。常用于释放资源,如关闭文件、数据库连接等。示例代码:
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("除数不能为零: " + e.getMessage());
} finally {
System.out.println("finally 块执行");
}
- JUC 包中常用的锁:
- ReentrantLock:可重入锁,支持公平锁和非公平锁。相比于 synchronized 关键字,它提供了更灵活的锁控制,如可中断锁、定时锁等。示例代码:
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private final ReentrantLock lock = new ReentrantLock();
public void doSomething() {
lock.lock();
try {
// 业务逻辑
} finally {
lock.unlock();
}
}
}
- **ReentrantReadWriteLock**:读写锁,允许多个线程同时进行读操作,但写操作是独占的。适用于读多写少的场景,提高并发性能。
5. JVM 内存模型: - 堆:是 JVM 中最大的一块内存区域,用于存储对象实例和数组。垃圾回收主要在堆上进行。 - 栈:每个线程都有自己的栈,栈中存储局部变量、方法调用信息和操作数栈等。栈帧是栈中的基本单位,每个方法调用都会创建一个栈帧。 - 方法区:存储类的信息、常量池、静态变量等。在 JDK 8 及以后,方法区由元空间替代。 6. 多线程中实现线程同步的方式: - synchronized 关键字:可以修饰方法或代码块。修饰方法时,该方法在同一时间只能被一个线程访问;修饰代码块时,指定要同步的对象。示例:
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public void decrement() {
synchronized (this) {
count--;
}
}
}
- **Lock 接口**:以 ReentrantLock 为例,通过 lock() 方法加锁,unlock() 方法解锁。相比 synchronized 更灵活,可实现更复杂的锁逻辑。
7. Spring 框架的核心特性: - IoC(控制反转):将对象的创建和依赖关系的管理交给 Spring 容器,降低代码的耦合度。例如通过 XML 配置或注解(如 @Component、@Autowired)来实现对象的注入。 - AOP(面向切面编程):将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,通过代理模式在特定的切入点执行额外的逻辑。 8. Spring Boot 相对于 Spring 的优势: - 自动配置:Spring Boot 基于约定大于配置的原则,通过自动配置减少了大量的 XML 配置文件,能快速搭建项目。 - 起步依赖:提供了一系列的起步依赖,方便引入所需的依赖库,简化了依赖管理。 - 嵌入式服务器:内置了 Tomcat、Jetty 等服务器,可直接运行项目,无需额外配置服务器。 9. Redis 数据结构及业务场景应用: - 字符串(String):用于缓存数据,如缓存数据库查询结果、用户会话信息等。可以使用 set、get 等命令操作。 - 哈希(Hash):适合存储对象,将对象的属性和值存储为哈希的字段和值。例如存储用户信息,每个用户的属性作为一个字段。 - 列表(List):可用于实现消息队列、任务队列等。通过 lpush、rpop 等命令进行元素的添加和移除。 - 集合(Set):用于存储唯一元素,可实现去重功能。还可以进行交集、并集、差集等操作,如共同好友的计算。 - 有序集合(Sorted Set):每个元素有一个分数,根据分数进行排序。常用于排行榜、热门列表等场景。