
以下是百度校招Java开发岗和Java架构师的部分面试题及答案:
其他面试题答案如下:
实操场景:验证JDK和JRE的安装与区别
# 检查JDK版本
java -version
javac -version
# 查看JDK安装路径
which java
which javac
# 验证JRE是否包含编译器
# 尝试在仅安装JRE的环境中执行javac命令,会提示"command not found"代码示例:
public class EqualsDemo {
public static void main(String[] args) {
// 基本类型比较
int a = 10;
int b = 10;
System.out.println("基本类型比较: " + (a == b)); // true
// 引用类型比较
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("引用地址比较: " + (str1 == str2)); // false
System.out.println("值比较: " + str1.equals(str2)); // true
// 字符串常量池比较
String str3 = "world";
String str4 = "world";
System.out.println("常量池引用比较: " + (str3 == str4)); // true
}
}代码示例:
// 1. final类不能被继承
final class FinalClass {
public void print() {
System.out.println("Final Class");
}
}
// 2. final方法不能被重写
class Parent {
public final void finalMethod() {
System.out.println("Final Method");
}
}
class Child extends Parent {
// 以下代码会编译错误,无法重写final方法
// public void finalMethod() {}
}
// 3. final变量必须初始化且不可修改
class FinalVariableDemo {
final int MAX_COUNT = 100;
final String NAME;
public FinalVariableDemo(String name) {
this.NAME = name; // 必须在构造函数中初始化
}
public void test() {
// MAX_COUNT = 200; // 编译错误,无法修改final变量
}
}实操场景:性能对比测试(String vs StringBuilder)
public class StringPerformanceTest {
public static void main(String[] args) {
int loopCount = 10000;
// 使用String拼接
long startTime = System.currentTimeMillis();
String str = "";
for (int i = 0; i < loopCount; i++) {
str += i;
}
long endTime = System.currentTimeMillis();
System.out.println("String拼接耗时: " + (endTime - startTime) + "ms");
// 使用StringBuilder拼接
startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < loopCount; i++) {
sb.append(i);
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder拼接耗时: " + (endTime - startTime) + "ms");
}
}代码示例:实现多继承特性
// 接口定义
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
// 抽象类定义
abstract class Animal {
abstract void eat();
}
// 实现类
class Duck extends Animal implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("鸭子会飞");
}
@Override
public void swim() {
System.out.println("鸭子会游泳");
}
@Override
void eat() {
System.out.println("鸭子吃水草");
}
}实操场景:文件复制工具实现
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class FileCopyDemo {
public static void main(String[] args) {
String sourceFile = "source.txt";
String targetFile = "target.txt";
// 1. 使用传统字节流
try (InputStream is = new FileInputStream(sourceFile);
OutputStream os = new FileOutputStream(targetFile)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
System.out.println("传统字节流复制完成");
} catch (IOException e) {
e.printStackTrace();
}
// 2. 使用NIO.2 Files工具类
try {
Path sourcePath = Paths.get(sourceFile);
Path targetPath = Paths.get(targetFile);
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
System.out.println("NIO.2复制完成");
} catch (IOException e) {
e.printStackTrace();
}
}
}代码示例:文件操作工具类
import java.io.IOException;
import java.nio.file.*;
import java.util.List;
public class FileUtils {
// 检查文件是否存在
public static boolean checkFileExists(String filePath) {
Path path = Paths.get(filePath);
return Files.exists(path);
}
// 创建新文件
public static void createFile(String filePath) throws IOException {
Path path = Paths.get(filePath);
Files.createFile(path);
}
// 创建目录
public static void createDirectory(String dirPath) throws IOException {
Path path = Paths.get(dirPath);
Files.createDirectories(path);
}
// 删除文件或目录
public static void delete(String path) throws IOException {
Files.deleteIfExists(Paths.get(path));
}
// 复制文件
public static void copy(String source, String target) throws IOException {
Path sourcePath = Paths.get(source);
Path targetPath = Paths.get(target);
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
}
// 移动文件
public static void move(String source, String target) throws IOException {
Path sourcePath = Paths.get(source);
Path targetPath = Paths.get(target);
Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
}
// 读取文件内容
public static List<String> readAllLines(String filePath) throws IOException {
Path path = Paths.get(filePath);
return Files.readAllLines(path);
}
// 写入文件内容
public static void writeLines(String filePath, List<String> lines) throws IOException {
Path path = Paths.get(filePath);
Files.write(path, lines);
}
}实操场景:容器性能对比测试
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class ContainerPerformanceTest {
public static void main(String[] args) {
int loopCount = 100000;
// 测试ArrayList
testList(new ArrayList<>(), loopCount);
// 测试LinkedList
testList(new LinkedList<>(), loopCount);
// 测试HashMap
testMap(new HashMap<>(), loopCount);
// 测试ConcurrentHashMap
testMap(new ConcurrentHashMap<>(), loopCount);
}
private static void testList(List<Integer> list, int count) {
long startTime = System.currentTimeMillis();
// 添加元素
for (int i = 0; i < count; i++) {
list.add(i);
}
// 随机访问元素
for (int i = 0; i < count; i++) {
list.get(i);
}
long endTime = System.currentTimeMillis();
System.out.println(list.getClass().getSimpleName() + "耗时: " + (endTime - startTime) + "ms");
}
private static void testMap(Map<Integer, Integer> map, int count) {
long startTime = System.currentTimeMillis();
// 添加元素
for (int i = 0; i < count; i++) {
map.put(i, i);
}
// 随机访问元素
for (int i = 0; i < count; i++) {
map.get(i);
}
long endTime = System.currentTimeMillis();
System.out.println(map.getClass().getSimpleName() + "耗时: " + (endTime - startTime) + "ms");
}
}实操场景:自定义HashMap实现
import java.util.LinkedList;
public class CustomHashMap<K, V> {
private static final int DEFAULT_CAPACITY = 16;
private LinkedList<Entry<K, V>>[] table;
public CustomHashMap() {
table = new LinkedList[DEFAULT_CAPACITY];
for (int i = 0; i < DEFAULT_CAPACITY; i++) {
table[i] = new LinkedList<>();
}
}
public void put(K key, V value) {
int index = getIndex(key);
LinkedList<Entry<K, V>> bucket = table[index];
// 检查是否已存在相同key
for (Entry<K, V> entry : bucket) {
if (entry.key.equals(key)) {
entry.value = value;
return;
}
}
// 添加新元素
bucket.add(new Entry<>(key, value));
}
public V get(K key) {
int index = getIndex(key);
LinkedList<Entry<K, V>> bucket = table[index];
for (Entry<K, V> entry : bucket) {
if (entry.key.equals(key)) {
return entry.value;
}
}
return null;
}
private int getIndex(K key) {
return Math.abs(key.hashCode()) % DEFAULT_CAPACITY;
}
static class Entry<K, V> {
K key;
V value;
public Entry(K key, V value) {
this.key = key;
this.value = value;
}
}
}实操场景:多线程环境下的并发操作
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ConcurrentHashMapDemo {
private static final int THREAD_COUNT = 10;
private static final int LOOP_COUNT = 1000;
public static void main(String[] args) throws InterruptedException {
ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
// 多线程并发写入
for (int i = 0; i < THREAD_COUNT; i++) {
final int threadId = i;
executor.submit(() -> {
for (int j = 0; j < LOOP_COUNT; j++) {
map.put(threadId * LOOP_COUNT + j, j);
}
});
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
// 验证结果
System.out.println("Map size: " + map.size());
System.out.println("Expected size: " + (THREAD_COUNT * LOOP_COUNT));
}
}代码示例:实现归并排序对LinkedList排序
import java.util.LinkedList;
public class LinkedListMergeSort {
public static <T extends Comparable<T>> LinkedList<T> sort(LinkedList<T> list) {
if (list == null || list.size() <= 1) {
return list;
}
// 分割链表
LinkedList<T> left = new LinkedList<>();
LinkedList<T> right = new LinkedList<>();
int mid = list.size() / 2;
for (int i = 0; i < mid; i++) {
left.add(list.removeFirst());
}
right.addAll(list);
// 递归排序左右两部分
left = sort(left);
right = sort(right);
// 合并已排序的链表
return merge(left, right);
}
private static <T extends Comparable<T>> LinkedList<T> merge(LinkedList<T> left, LinkedList<T> right) {
LinkedList<T> result = new LinkedList<>();
while (!left.isEmpty() && !right.isEmpty()) {
if (left.peek().compareTo(right.peek()) <= 0) {
result.add(left.removeFirst());
} else {
result.add(right.removeFirst());
}
}
// 添加剩余元素
result.addAll(left);
result.addAll(right);
return result;
}
}代码示例:三种创建线程的方式
// 1. 继承Thread类
class MyThread extends Thread {
@Override
public void run() {
System.out.println("继承Thread类创建的线程: " + Thread.currentThread().getName());
}
}
// 2. 实现Runnable接口
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("实现Runnable接口创建的线程: " + Thread.currentThread().getName());
}
}
// 3. 实现Callable接口
import java.util.concurrent.*;
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "实现Callable接口创建的线程: " + Thread.currentThread().getName();
}
}
public class ThreadCreationDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 方式1: 继承Thread类
MyThread thread1 = new MyThread();
thread1.start();
// 方式2: 实现Runnable接口
Thread thread2 = new Thread(new MyRunnable());
thread2.start();
// 方式3: 实现Callable接口
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new MyCallable());
System.out.println(future.get());
executor.shutdown();
}
}实操场景:自定义线程池配置
import java.util.concurrent.*;
public class ThreadPoolDemo {
public static void main(String[] args) {
// 创建自定义线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
60, // 空闲线程存活时间
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100), // 任务队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
// 提交任务
for (int i = 0; i < 20; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " is running on thread: " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task " + taskId + " completed");
});
}
// 关闭线程池
executor.shutdown();
}
}代码示例:使用synchronized和Lock实现线程安全
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
// 1. 使用synchronized关键字
class SynchronizedCounter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
// 2. 使用Lock接口
class LockCounter {
private int count = 0;
private final Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
}
// 3. 使用原子类
import java.util.concurrent.atomic.AtomicInteger;
class AtomicCounter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
}代码示例:自定义锁实现
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
class CustomLock {
private static class Sync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
if (getState() == 0) {
throw new IllegalMonitorStateException();
}
setExclusiveOwnerThread(null);
setState(0);
return true;
}
@Override
protected boolean isHeldExclusively() {
return getState() == 1;
}
}
private final Sync sync = new Sync();
public void lock() {
sync.acquire(1);
}
public void unlock() {
sync.release(1);
}
public boolean tryLock() {
return sync.tryAcquire(1);
}
}实操场景:内存溢出测试
import java.util.ArrayList;
import java.util.List;
public class OutOfMemoryDemo {
public static void main(String[] args) {
// 堆内存溢出
heapOutOfMemory();
// 栈内存溢出
// stackOverflow();
}
private static void heapOutOfMemory() {
List<byte[]> list = new ArrayList<>();
while (true) {
list.add(new byte[1024 * 1024]); // 每次添加1MB数据
}
}
private static void stackOverflow() {
stackOverflow(); // 递归调用导致栈溢出
}
}实操场景:GC日志分析
# 运行程序时开启GC日志
java -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xms256m -Xmx256m OutOfMemoryDemo
# 典型GC日志分析
2025-06-26T10:30:45.123+0800: 0.234: [GC (Allocation Failure) [PSYoungGen: 65536K->256K(76288K)] 65536K->65536K(251392K), 0.0012345 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
# 日志解读:
# 1. GC发生时间: 2025-06-26T10:30:45.123+0800
# 2. GC类型: 新生代GC (Allocation Failure表示内存分配失败触发GC)
# 3. 新生代内存变化: 65536K->256K(76288K)
# 4. 堆内存变化: 65536K->65536K(251392K)
# 5. GC耗时: 0.0012345秒代码示例:自定义类加载器
import java.io.*;
public class CustomClassLoader extends ClassLoader {
private String classPath;
public CustomClassLoader(String classPath) {
this.classPath = classPath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] classData = loadClassData(name);
if (classData == null) {
throw new ClassNotFoundException();
}
return defineClass(name, classData, 0, classData.length);
} catch (IOException e) {
throw new ClassNotFoundException(name, e);
}
}
private byte[] loadClassData(String name) throws IOException {
String path = classPath + File.separatorChar +
name.replace('.', File.separatorChar) + ".class";
try (InputStream is = new FileInputStream(path);
ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
return bos.toByteArray();
}
}
public static void main(String[] args) throws Exception {
CustomClassLoader loader = new CustomClassLoader("/path/to/classes");
Class<?> clazz = loader.loadClass("com.example.MyClass");
Object obj = clazz.getDeclaredConstructor().newInstance();
System.out.println(obj.getClass().getClassLoader());
}
}实操场景:JVM参数配置
# 典型的JVM性能调优参数配置示例
java -Xms512m -Xmx512m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m \
-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/java_heapdump.hprof \
-jar myapplication.jar
# 参数说明:
# -Xms512m: 初始堆大小512MB
# -Xmx512m: 最大堆大小512MB
# -Xmn256m: 新生代大小256MB
# -XX:MetaspaceSize=128m: 元空间初始大小128MB
# -XX:MaxMetaspaceSize=256m: 元空间最大大小256MB
# -XX:+UseG1GC: 使用G1垃圾收集器
# -XX:MaxGCPauseMillis=200: 最大GC停顿时间200毫秒
# -XX:+HeapDumpOnOutOfMemoryError: 发生OOM时生成堆转储文件
# -XX:HeapDumpPath=/var/log/java_heapdump.hprof: 堆转储文件路径实操场景:索引优化测试
-- 创建测试表
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
age INT,
gender VARCHAR(10),
email VARCHAR(100),
create_time DATETIME
);
-- 添加测试数据
INSERT INTO user (name, age, gender, email, create_time)
VALUES ('张三', 25, '男', 'zhangsan@example.com', NOW()),
('李四', 30, '男', 'lisi@example.com', NOW()),
('王五', 28, '女', 'wangwu@example.com', NOW());
-- 创建复合索引
CREATE INDEX idx_name_age_gender ON user (name, age, gender);
-- 执行计划分析
EXPLAIN SELECT * FROM user WHERE name = '张三' AND age = 25 AND gender = '男';
-- 索引覆盖测试
EXPLAIN SELECT name, age, gender FROM user WHERE name = '张三';实操场景:演示脏读、不可重复读和幻读
-- 设置事务隔离级别为读未提交(会出现脏读)
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- 会话1: 开启事务
START TRANSACTION;
UPDATE user SET age = 31 WHERE name = '李四';
-- 会话2: 查询(会读到未提交的数据,出现脏读)
SELECT * FROM user WHERE name = '李四';
-- 会话1: 回滚事务
ROLLBACK;
-- 设置事务隔离级别为可重复读(MySQL默认级别,解决不可重复读,但可能出现幻读)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 会话1: 开启事务并查询
START TRANSACTION;
SELECT * FROM user WHERE age > 25;
-- 会话2: 插入新记录
INSERT INTO user (name, age, gender) VALUES ('赵六', 35, '男');
COMMIT;
-- 会话1: 再次查询(两次查询结果一致,解决不可重复读)
SELECT * FROM user WHERE age > 25;
-- 会话1: 插入相同条件的记录(会出现Duplicate key错误,说明出现幻读)
INSERT INTO user (name, age, gender) VALUES ('赵六', 35, '男');实操场景:配置MySQL主从复制
# 主库配置 (my.cnf)
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-do-db=test_db
# 从库配置 (my.cnf)
[mysqld]
server-id=2
relay-log=mysql-relay-bin
log-bin=mysql-bin
# 主库操作
CREATE USER 'repl_user'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;
# 从库操作
CHANGE MASTER TO
MASTER_HOST='主库IP',
MASTER_USER='repl_user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.xxxxxx',
MASTER_LOG_POS=xxxxxx;
START SLAVE;
SHOW SLAVE STATUS\G代码示例:实现快速排序
public class QuickSort {
public static void sort(int[] arr) {
if (arr == null || arr.length <= 1) {
return;
}
quickSort(arr, 0, arr.length - 1);
}
private static void quickSort(int[] arr, int left, int right) {
if (left < right) {
int pivotIndex = partition(arr, left, right);
quickSort(arr, left, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, right);
}
}
private static int partition(int[] arr, int left, int right) {
int pivot = arr[right];
int i = left - 1;
for (int j = left; j < right; j++) {
if (arr[j] <= pivot) {
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, right);
return i + 1;
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}代码示例:实现二分查找
public class BinarySearch {
public static int search(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1; // 未找到
}
}代码示例:斐波那契数列(动态规划优化)
public class Fibonacci {
// 递归实现(效率低)
public static int fibRecursive(int n) {
if (n <= 1) {
return n;
}
return fibRecursive(n - 1) + fibRecursive(n - 2);
}
// 动态规划实现(高效)
public static int fibDynamic(int n) {
if (n <= 1) {
return n;
}
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
// 优化空间复杂度的动态规划
public static int fibOptimized(int n) {
if (n <= 1) {
return n;
}
int a = 0;
int b = 1;
int result = 0;
for (int i = 2; i <= n; i++) {
result = a + b;
a = b;
b = result;
}
return result;
}
}代码示例:反转链表
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public class ReverseLinkedList {
// 迭代方法
public static ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
// 递归方法
public static ListNode reverseListRecursive(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode newHead = reverseListRecursive(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
}以上代码示例和实操场景展示了Java开发中的核心技术点和面试高频考点。通过实际动手操作这些示例,你可以更深入地理解相关概念和技术,为面试做好充分准备。
百度校招,Java 开发岗,Java 架构师,面试题,历年经典,Java 基础,并发编程,JVM,Spring 框架,微服务,分布式,数据库,算法,数据结构,网络编程
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。