2025 年 Java 校招 120 道含实操面试题目及答案完整合集

Java校招120道面试题目合集及答案(含实操)

一、Java基础

1. Java语言有哪些特点?

答案:Java具有简单性、面向对象、平台无关性等特点。
实操:创建一个简单的Java程序,演示面向对象的封装特性。

// 定义一个学生类,封装姓名和年龄属性
class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 提供公共的访问方法
    public String getName() { return name; }
    public int getAge() { return age; }
}

public class Main {
    public static void main(String[] args) {
        Student student = new Student("张三", 20);
        System.out.println(student.getName() + " 年龄: " + student.getAge());
    }
}

2. 什么是Java虚拟机(JVM)?

答案:JVM是执行字节码的虚拟计算机,实现了“一次编写,到处运行”。
实操:使用javap命令查看字节码。

# 编译Java文件
javac Main.java
# 查看字节码
javap -c Main

3. "static"关键字的作用?

答案:static修饰的成员属于类,而非实例。
实操:创建静态工具类计算圆的面积。

public class MathUtils {
    // 静态常量
    public static final double PI = 3.14159;

    // 静态方法
    public static double calculateArea(double radius) {
        return PI * radius * radius;
    }
}

// 使用静态成员
double area = MathUtils.calculateArea(5.0);

4. Java支持的数据类型有哪些?

答案:基本数据类型和引用数据类型。
实操:演示自动装箱与拆箱。

Integer numObj = 10; // 自动装箱
int num = numObj;    // 自动拆箱
System.out.println(num + 5); // 输出15

5. 方法覆盖(Overriding)与重载(Overload)的区别?

答案:覆盖发生在父子类,重载在同一类中。
实操:实现方法覆盖与重载。

class Animal {
    public void makeSound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() { // 方法覆盖
        System.out.println("汪汪汪");
    }

    public void makeSound(int times) { // 方法重载
        for (int i = 0; i < times; i++) {
            System.out.print("汪 ");
        }
    }
}

6. 什么是构造方法?

答案:构造方法用于初始化对象。
实操:创建带参数的构造方法。

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getInfo() {
        return name + ",年龄:" + age;
    }
}

Person p = new Person("李四", 25);
System.out.println(p.getInfo());

7. Java支持多继承吗?

答案:Java类不支持多继承,但接口可以多实现。
实操:实现多接口。

interface Flyable {
    void fly();
}

interface Swimmable {
    void swim();
}

class Duck implements Flyable, Swimmable {
    @Override
    public void fly() { System.out.println("鸭子飞"); }
    @Override
    public void swim() { System.out.println("鸭子游"); }
}

8. 值传递与引用传递的区别?

答案:Java中基本类型是值传递,对象是引用传递。
实操:验证引用传递。

class Point {
    int x, y;
    public Point(int x, int y) { this.x = x; this.y = y; }
}

public class Main {
    public static void main(String[] args) {
        Point p = new Point(10, 20);
        modify(p);
        System.out.println("x=" + p.x + ", y=" + p.y); // 输出x=100, y=200
    }

    public static void modify(Point pt) {
        pt.x = 100;
        pt.y = 200;
    }
}

9. 进程与线程的区别?

答案:进程是资源分配单位,线程是执行单元。
实操:使用jconsole监控Java进程与线程。

# 启动示例程序
java -cp . Main
# 启动监控工具
jconsole

10. 创建线程的方式有哪些?

答案:继承Thread类、实现Runnable接口等。
实操:使用ExecutorService创建线程池。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        for (int i = 0; i < 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("执行任务: " + taskId + ",线程: " + Thread.currentThread().getName());
                try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
            });
        }
        
        executor.shutdown();
    }
}

二、多线程与并发

11. 如何实现线程同步?

答案:使用synchronized关键字或ReentrantLock
实操:使用synchronized实现线程安全的计数器。

class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

12. 什么是线程安全?

答案:多个线程访问共享资源时不会导致数据不一致。
实操:对比ArrayListVector的线程安全性。

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

public class ThreadSafetyDemo {
    public static void main(String[] args) throws InterruptedException {
        // 使用非线程安全的ArrayList
        List<Integer> arrayList = new ArrayList<>();
        
        // 使用线程安全的Vector
        List<Integer> vector = new Vector<>();

        // 启动多个线程添加元素
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                arrayList.add(i);
                vector.add(i);
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                arrayList.add(i);
                vector.add(i);
            }
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("ArrayList size: " + arrayList.size()); // 可能小于2000
        System.out.println("Vector size: " + vector.size());       // 总是2000
    }
}

13. 解释Java中的锁机制

答案:Java提供synchronizedLock接口实现锁机制。
实操:使用ReentrantLock实现可重入锁。

import java.util.concurrent.locks.ReentrantLock;

class Resource {
    private final ReentrantLock lock = new ReentrantLock();

    public void accessResource() {
        lock.lock();
        try {
            // 执行临界区代码
            System.out.println(Thread.currentThread().getName() + " 获取锁");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            System.out.println(Thread.currentThread().getName() + " 释放锁");
        }
    }
}

14. 什么是死锁?如何避免?

答案:死锁是两个或多个线程互相等待对方释放资源的情况。
实操:模拟死锁并分析。

public class DeadlockDemo {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("线程1获取锁1");
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                synchronized (lock2) {
                    System.out.println("线程1获取锁2");
                }
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("线程2获取锁2");
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                synchronized (lock1) {
                    System.out.println("线程2获取锁1");
                }
            }
        });

        t1.start();
        t2.start();
    }
}

15. 什么是volatile关键字?

答案:保证变量的可见性,禁止指令重排序。
实操:使用volatile实现线程间通信。

public class VolatileDemo {
    private static volatile boolean flag = false;

    public static void main(String[] args) {
        new Thread(() -> {
            while (!flag) {
                // 等待flag变为true
            }
            System.out.println("线程收到通知,flag已变为true");
        }).start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        flag = true;
        System.out.println("主线程已设置flag为true");
    }
}

16. 解释Java中的wait()和notify()方法

答案:用于线程间的协作,必须在synchronized块中调用。
实操:使用生产者-消费者模型演示。

class SharedResource {
    private int data;
    private boolean available = false;

    public synchronized void produce(int value) {
        while (available) {
            try { wait(); } catch (InterruptedException e) {}
        }
        data = value;
        available = true;
        notifyAll();
    }

    public synchronized int consume() {
        while (!available) {
            try { wait(); } catch (InterruptedException e) {}
        }
        available = false;
        notifyAll();
        return data;
    }
}

17. 什么是线程池?如何创建?

答案:线程池管理线程的创建和复用,提高性能。
实操:使用Executors工厂类创建不同类型的线程池。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolDemo {
    public static void main(String[] args) {
        // 创建固定大小的线程池
        ExecutorService fixedPool = Executors.newFixedThreadPool(5);
        
        // 创建缓存线程池
        ExecutorService cachedPool = Executors.newCachedThreadPool();
        
        // 创建单线程池
        ExecutorService singlePool = Executors.newSingleThreadExecutor();
        
        // 执行任务
        fixedPool.submit(() -> System.out.println("任务执行"));
        
        // 关闭线程池
        fixedPool.shutdown();
    }
}

18. 解释Callable和Future接口

答案:Callable有返回值,Future用于获取异步结果。
实操:使用Callable和Future实现异步计算。

import java.util.concurrent.*;

public class CallableFutureDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Callable<Integer> task = () -> {
            Thread.sleep(2000);
            return 100;
        };

        Future<Integer> future = executor.submit(task);
        System.out.println("等待结果...");
        System.out.println("结果: " + future.get());
        executor.shutdown();
    }
}

19. 什么是原子操作?

答案:不可中断的操作,Java提供了Atomic类实现原子操作。
实操:使用AtomicInteger实现无锁计数器。

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicDemo {
    private static AtomicInteger counter = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.incrementAndGet();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.incrementAndGet();
            }
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("计数器值: " + counter.get()); // 输出2000
    }
}

20. 什么是并发集合?

答案:线程安全的集合,如ConcurrentHashMapCopyOnWriteArrayList等。
实操:使用ConcurrentHashMap统计单词频率。

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentCollectionDemo {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> wordCount = new ConcurrentHashMap<>();
        String[] words = {"apple", "banana", "apple", "cherry", "banana"};

        for (String word : words) {
            wordCount.compute(word, (k, v) -> (v == null) ? 1 : v + 1);
        }

        System.out.println(wordCount); // 输出 {apple=2, banana=2, cherry=1}
    }
}

三、集合框架

21. Java集合框架的主要接口有哪些?

答案:主要接口包括CollectionListSetMap等。
实操:创建不同类型的集合。

import java.util.*;

public class CollectionFrameworkDemo {
    public static void main(String[] args) {
        // List示例
        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");
        
        // Set示例
        Set<Integer> set = new HashSet<>();
        set.add(1);
        set.add(2);
        set.add(2); // 重复元素,不会被添加
        
        // Map示例
        Map<String, Integer> map = new HashMap<>();
        map.put("one", 1);
        map.put("two", 2);
    }
}

22. ArrayList和LinkedList的区别是什么?

答案:ArrayList基于数组,LinkedList基于链表。
实操:对比两种列表的插入性能。

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ListPerformanceDemo {
    public static void main(String[] args) {
        int size = 100000;
        
        // 测试ArrayList插入性能
        List<Integer> arrayList = new ArrayList<>();
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < size; i++) {
            arrayList.add(0, i); // 在头部插入
        }
        long endTime = System.currentTimeMillis();
        System.out.println("ArrayList插入时间: " + (endTime - startTime) + "ms");
        
        // 测试LinkedList插入性能
        List<Integer> linkedList = new LinkedList<>();
        startTime = System.currentTimeMillis();
        for (int i = 0; i < size; i++) {
            linkedList.add(0, i); // 在头部插入
        }
        endTime = System.currentTimeMillis();
        System.out.println("LinkedList插入时间: " + (endTime - startTime) + "ms");
    }
}

23. HashMap和Hashtable的区别是什么?

答案:HashMap非线程安全,Hashtable线程安全。
实操:对比HashMap和Hashtable的使用。

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class MapDifferenceDemo {
    public static void main(String[] args) {
        // HashMap允许null键和null值
        Map<String, String> hashMap = new HashMap<>();
        hashMap.put(null, "value");
        hashMap.put("key", null);
        
        // Hashtable不允许null键和null值
        Map<String, String> hashtable = new Hashtable<>();
        // hashtable.put(null, "value"); // 抛出NullPointerException
        // hashtable.put("key", null);    // 抛出NullPointerException
    }
}

24. 如何实现集合的排序?

答案:使用Collections.sort()Stream.sorted()
实操:对自定义对象列表进行排序。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Student implements Comparable<Student> {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public int compareTo(Student other) {
        return Integer.compare(this.score, other.score);
    }

    @Override
    public String toString() {
        return name + ": " + score;
    }
}

public class SortingDemo {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("张三", 85));
        students.add(new Student("李四", 72));
        students.add(new Student("王五", 90));

        Collections.sort(students);
        System.out.println(students); // 按分数升序排列
    }
}

25. 什么是迭代器(Iterator)?

答案:用于遍历集合的接口,支持元素的删除操作。
实操:使用迭代器遍历并删除元素。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");

        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            if (element.equals("B")) {
                iterator.remove(); // 安全删除元素
            }
        }

        System.out.println(list); // 输出 [A, C]
    }
}

26. 什么是Java 8的Stream API?

答案:用于处理集合的流式操作,支持过滤、映射、聚合等。
实操:使用Stream API进行数据处理。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamDemo {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 过滤偶数并计算平方和
        int sum = numbers.stream()
                .filter(n -> n % 2 == 0)
                .map(n -> n * n)
                .reduce(0, Integer::sum);

        System.out.println("偶数的平方和: " + sum); // 输出 220
    }
}

27. 什么是TreeMap和TreeSet?

答案:基于红黑树实现,元素按自然顺序或指定比较器排序。
实操:使用TreeSet存储自定义对象。

import java.util.TreeSet;

class Person implements Comparable<Person> {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person other) {
        return Integer.compare(this.age, other.age);
    }

    @Override
    public String toString() {
        return name + ": " + age;
    }
}

public class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet<Person> people = new TreeSet<>();
        people.add(new Person("张三", 25));
        people.add(new Person("李四", 20));
        people.add(new Person("王五", 30));

        System.out.println(people); // 按年龄升序排列
    }
}

28. 什么是CopyOnWriteArrayList?

答案:写时复制的线程安全列表,适用于读多写少的场景。
实操:多线程环境下使用CopyOnWriteArrayList。

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteArrayListDemo {
    public static void main(String[] args) {
        List<String> list = new CopyOnWriteArrayList<>();
        
        // 线程1添加元素
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                list.add("元素" + i);
            }
        });
        
        // 线程2遍历元素
        Thread t2 = new Thread(() -> {
            for (String element : list) {
                System.out.println(element);
            }
        });
        
        t1.start();
        t2.start();
    }
}

29. 什么是LinkedHashMap?

答案:维护插入顺序或访问顺序的HashMap。
实操:使用LinkedHashMap实现LRU缓存。

import java.util.LinkedHashMap;
import java.util.Map;

public class LRUCacheDemo extends LinkedHashMap<Integer, Integer> {
    private final int capacity;

    public LRUCacheDemo(int capacity) {
        super(capacity, 0.75f, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
                return size() > capacity;
            }
        };
        this.capacity = capacity;
    }

    public static void main(String[] args) {
        LRUCacheDemo cache = new LRUCacheDemo(3);
        cache.put(1, 1);
        cache.put(2, 2);
        cache.put(3, 3);
        cache.get(1); // 访问元素1,使其变为最近使用
        cache.put(4, 4); // 超出容量,移除最久未使用的元素2

        System.out.println(cache); // 输出 {3=3, 1=1, 4=4}
    }
}

30. 如何遍历Map?

答案:可以使用keySet()、entrySet()或forEach()方法。
实操:演示三种遍历Map的方式。

import java.util.HashMap;
import java.util.Map;

public class MapTraversalDemo {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("A", 1);
        map.put("B", 2);
        map.put("C", 3);

        // 方式1:使用keySet()
        for (String key : map.keySet()) {
            System.out.println(key + " : " + map.get(key));
        }

        // 方式2:使用entrySet()
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }

        // 方式3:使用forEach()
        map.forEach((key, value) -> System.out.println(key + " : " + value));
    }
}

四、异常处理

31. Java异常处理机制是什么?

答案:通过try-catch-finally和throws关键字实现。
实操:捕获并处理异常。

public class ExceptionHandlingDemo {
    public static void main(String[] args) {
        try {
            int result = divide(10, 0);
            System.out.println("结果: " + result);
        } catch (ArithmeticException e) {
            System.out.println("捕获到异常: " + e.getMessage());
        } finally {
            System.out.println("执行finally块");
        }
    }

    public static int divide(int a, int b) {
        return a / b; // 会抛出ArithmeticException
    }
}

32. 检查型异常(Checked Exception)和非检查型异常(Unchecked Exception)的区别是什么?

答案:检查型异常必须被捕获或声明抛出,非检查型异常不强制。
实操:演示两种异常的区别。

import java.io.FileInputStream;
import java.io.IOException;

public class ExceptionTypeDemo {
    public static void main(String[] args) {
        // 检查型异常,必须处理
        try {
            FileInputStream fis = new FileInputStream("file.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 非检查型异常,不强制处理
        int[] arr = new int[5];
        System.out.println(arr[10]); // 抛出ArrayIndexOutOfBoundsException
    }
}

33. throw和throws的区别是什么?

答案:throw用于手动抛出异常,throws用于声明方法可能抛出的异常。
实操:自定义异常并使用throw和throws。

class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

public class ThrowThrowsDemo {
    public static void main(String[] args) {
        try {
            validateAge(-5);
        } catch (CustomException e) {
            System.out.println(e.getMessage());
        }
    }

    public static void validateAge(int age) throws CustomException {
        if (age < 0) {
            throw new CustomException("年龄不能为负数");
        }
    }
}

34. 什么是finally块?

答案:无论是否发生异常,finally块中的代码总会执行。
实操:演示finally块的执行。

public class FinallyDemo {
    public static void main(String[] args) {
        try {
            int result = 10 / 0;
        } catch (ArithmeticException e) {
            System.out.println("捕获到除零异常");
        } finally {
            System.out.println("执行finally块");
        }
    }
}

35. 什么是自定义异常?

答案:用户自定义的异常类,继承自Exception或其子类。
实操:创建自定义异常类。

class InvalidEmailException extends Exception {
    public InvalidEmailException(String message) {
        super(message);
    }
}

public class CustomExceptionDemo {
    public static void main(String[] args) {
        try {
            validateEmail("invalid_email");
        } catch (InvalidEmailException e) {
            System.out.println(e.getMessage());
        }
    }

    public static void validateEmail(String email) throws InvalidEmailException {
        if (!email.contains("@")) {
            throw new InvalidEmailException("无效的邮箱地址");
        }
    }
}

36. 什么是try-with-resources语句?

答案:自动关闭实现了AutoCloseable接口的资源。
实操:使用try-with-resources读取文件。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TryWithResourcesDemo {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

37. 什么是异常链(Exception Chaining)?

答案:将一个异常包装在另一个异常中,保留原始异常信息。
实操:实现异常链。

class DatabaseException extends Exception {
    public DatabaseException(String message, Throwable cause) {
        super(message, cause);
    }
}

public class ExceptionChainingDemo {
    public static void main(String[] args) {
        try {
            connectToDatabase();
        } catch (DatabaseException e) {
            System.out.println("数据库连接失败: " + e.getMessage());
            System.out.println("原始异常: " + e.getCause());
        }
    }

    public static void connectToDatabase() throws DatabaseException {
        try {
            // 模拟数据库连接失败
            throw new RuntimeException("连接超时");
        } catch (RuntimeException e) {
            throw new DatabaseException("无法连接数据库", e);
        }
    }
}

38. 如何自定义异常处理机制?

答案:通过实现Thread.UncaughtExceptionHandler接口。
实操:设置全局异常处理器。

public class CustomExceptionHandler implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("线程 " + t.getName() + " 抛出异常: " + e.getMessage());
        // 可以添加日志记录或其他处理逻辑
    }

    public static void main(String[] args) {
        Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler());
        
        Thread t = new Thread(() -> {
            throw new RuntimeException("测试异常");
        });
        
        t.start();
    }
}

39. 什么是断言(Assertion)?

答案:用于调试的机制,验证程序中的假设。
实操:使用断言检查参数。

public class AssertionDemo {
    public static void main(String[] args) {
        int age = -5;
        assert age >= 0 : "年龄不能为负数";
        System.out.println("年龄: " + age);
    }
}

// 启用断言运行程序
// java -ea AssertionDemo

40. 解释Java中的错误(Error)和异常(Exception)的区别

答案:Error表示系统级错误,无法恢复;Exception表示可处理的异常情况。
实操:演示StackOverflowError。

public class ErrorDemo {
    public static void main(String[] args) {
        recursiveMethod();
    }

    public static void recursiveMethod() {
        recursiveMethod(); // 无限递归,会导致StackOverflowError
    }
}

五、IO与NIO

41. Java中有几种类型的流?

答案:字节流和字符流,分别对应InputStream/OutputStream和Reader/Writer。
实操:使用字节流复制文件。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ByteStreamDemo {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("output.txt")) {
            
            int byteRead;
            while ((byteRead = fis.read()) != -1) {
                fos.write(byteRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

42. 什么是Java NIO?

答案:非阻塞IO,基于通道(Channel)和缓冲区(Buffer)。
实操:使用NIO复制文件。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class NioDemo {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("output.txt");
             FileChannel inChannel = fis.getChannel();
             FileChannel outChannel = fos.getChannel()) {
            
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            
            while (inChannel.read(buffer) != -1) {
                buffer.flip();
                outChannel.write(buffer);
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

43. 什么是缓冲区(Buffer)?

答案:NIO中用于存储数据的对象,有position、limit和capacity属性。
实操:使用ByteBuffer读写数据。

import java.nio.ByteBuffer;

public class BufferDemo {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(10);
        
        // 写入数据
        buffer.put((byte) 'A');
        buffer.put((byte) 'B');
        buffer.put((byte) 'C');
        
        // 切换到读模式
        buffer.flip();
        
        // 读取数据
        while (buffer.hasRemaining()) {
            System.out.print((char) buffer.get() + " ");
        }
        
        // 清空缓冲区
        buffer.clear();
    }
}

44. 什么是通道(Channel)?

答案:NIO中用于与数据源交互的双向通道。
实操:使用FileChannel读取文件。

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ChannelDemo {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileChannel channel = fis.getChannel()) {
            
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int bytesRead = channel.read(buffer);
            
            while (bytesRead != -1) {
                buffer.flip();
                
                while (buffer.hasRemaining()) {
                    System.out.print((char) buffer.get());
                }
                
                buffer.clear();
                bytesRead = channel.read(buffer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

45. 什么是Selector?

答案:NIO中用于多路复用的选择器,可监控多个通道的IO事件。
实操:简单的Selector示例。

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;
import java.util.Set;

public class SelectorDemo {
    public static void main(String[] args) throws IOException {
        Selector selector = Selector.open();
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.socket().bind(new InetSocketAddress(8080));
        serverChannel.configureBlocking(false);
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            int readyChannels = selector.select();
            if (readyChannels == 0) continue;

            Set<SelectionKey> selectedKeys = selector.selectedKeys();
            Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

            while (keyIterator.hasNext()) {
                SelectionKey key = keyIterator.next();

                if (key.isAcceptable()) {
                    // 处理连接事件
                } else if (key.isReadable()) {
                    // 处理读取事件
                }

                keyIterator.remove();
            }
        }
    }
}

46. 什么是字符流和字节流?

答案:字节流处理原始字节,字符流处理字符数据。
实操:使用字符流写入文件。

import java.io.FileWriter;
import java.io.IOException;

public class CharacterStreamDemo {
    public static void main(String[] args) {
        try (FileWriter writer = new FileWriter("output.txt")) {
            writer.write("Hello, World!\n");
            writer.write("这是一个字符流示例。");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

47. 什么是序列化和反序列化?

答案:将对象转换为字节流和从字节流恢复对象的过程。
实操:实现对象的序列化和反序列化。

import java.io.*;

class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return name + ", " + age + "岁";
    }
}

public class SerializationDemo {
    public static void main(String[] args) {
        // 序列化
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
            Person person = new Person("张三", 25);
            oos.writeObject(person);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 反序列化
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
            Person restoredPerson = (Person) ois.readObject();
            System.out.println(restoredPerson);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

48. 如何实现自定义序列化?

答案:通过实现writeObject()和readObject()方法。
实操:自定义序列化示例。

import java.io.*;

class CustomSerializable implements Serializable {
    private static final long serialVersionUID = 1L;
    private int value;

    public CustomSerializable(int value) {
        this.value = value;
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeInt(value * 2); // 自定义序列化逻辑
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        value = in.readInt() / 2; // 自定义反序列化逻辑
    }

    public int getValue() {
        return value;
    }
}

49. 什么是Java中的文件过滤器?

答案:用于过滤文件的接口,实现FilenameFilter或FileFilter。
实操:使用文件过滤器列出所有txt文件。

import java.io.File;
import java.io.FilenameFilter;

public class FileFilterDemo {
    public static void main(String[] args) {
        File dir = new File(".");
        
        FilenameFilter filter = (dir1, name) -> name.endsWith(".txt");
        
        File[] txtFiles = dir.listFiles(filter);
        
        if (txtFiles != null) {
            for (File file : txtFiles) {
                System.out.println(file.getName());
            }
        }
    }
}

50. 如何实现文件加密和解密?

答案:使用Java Cryptography Architecture (JCA)。
实操:使用AES加密文件。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.*;
import java.security.NoSuchAlgorithmException;

public class FileEncryptionDemo {
    public static void main(String[] args) throws Exception {
        // 生成密钥
        SecretKey secretKey = KeyGenerator.getInstance("AES").generateKey();
        
        // 加密文件
        encryptFile("plain.txt", "encrypted.bin", secretKey);
        
        // 解密文件
        decryptFile("encrypted.bin", "decrypted.txt", secretKey);
    }

    public static void encryptFile(String inputFile, String outputFile, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        
        try (FileInputStream fis = new FileInputStream(inputFile);
             FileOutputStream fos = new FileOutputStream(outputFile);
             CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {
            
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                cos.write(buffer, 0, bytesRead);
            }
        }
    }

    public static void decryptFile(String inputFile, String outputFile, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, key);
        
        try (FileInputStream fis = new FileInputStream(inputFile);
             CipherInputStream cis = new CipherInputStream(fis, cipher);
             FileOutputStream fos = new FileOutputStream(outputFile)) {
            
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = cis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        }
    }
}

六、反射与注解

51. 什么是Java反射?

答案:运行时动态获取类的信息并操作类的机制。
实操:使用反射创建对象并调用方法。

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

class MyClass {
    private String message;

    public MyClass(String message) {
        this.message = message;
    }

    public void printMessage() {
        System.out.println("Message: " + message);
    }
}

public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        // 获取Class对象
        Class<?> clazz = Class.forName("MyClass");
        
        // 创建对象
        Constructor<?> constructor = clazz.getConstructor(String.class);
        Object obj = constructor.newInstance("Hello, Reflection!");
        
        // 调用方法
        Method method = clazz.getMethod("printMessage");
        method.invoke(obj);
    }
}

52. 如何获取Class对象?

答案:三种方式:Class.forName()、类名.class、对象.getClass()
实操:演示三种获取Class对象的方式。

public class GetClassDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        // 方式1:使用Class.forName()
        Class<?> clazz1 = Class.forName("java.util.ArrayList");
        
        // 方式2:使用类名.class
        Class<?> clazz2 = ArrayList.class;
        
        // 方式3:使用对象.getClass()
        ArrayList<String> list = new ArrayList<>();
        Class<?> clazz3 = list.getClass();
        
        System.out.println(clazz1 == clazz2); // 输出true
        System.out.println(clazz2 == clazz3); // 输出true
    }
}

53. 什么是Java注解?

答案:为程序元素(类、方法等)添加元数据的机制。
实操:定义和使用自定义注解。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation {
    String value() default "default";
    int count() default 1;
}

// 使用注解
class MyClass {
    @MyAnnotation(value = "Hello", count = 3)
    public void doSomething() {
        System.out.println("执行方法");
    }
}

54. 什么是元注解?

答案:用于定义注解的注解,如@Retention@Target等。
实操:演示元注解的使用。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyTypeAnnotation {
    String value();
}

@MyTypeAnnotation("这是一个类注解")
class MyAnnotatedClass {
    // 类定义
}

55. 如何通过反射获取注解信息?

答案:使用getAnnotation()方法。
实操:通过反射读取注解信息。

import java.lang.reflect.Method;

@interface MyAnnotation {
    String value();
}

class MyClass {
    @MyAnnotation("测试注解")
    public void myMethod() {}
}

public class AnnotationReflectionDemo {
    public static void main(String[] args) throws Exception {
        Method method = MyClass.class.getMethod("myMethod");
        MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
        
        if (annotation != null) {
            System.out.println("注解值: " + annotation.value());
        }
    }
}

56. 什么是Java动态代理?

答案:运行时创建代理类的机制,实现AOP等功能。
实操:使用动态代理记录方法调用时间。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface Calculator {
    int add(int a, int b);
}

class CalculatorImpl implements Calculator {
    @Override
    public int add(int a, int b) {
        return a + b;
    }
}

class TimeHandler implements InvocationHandler {
    private final Object target;

    public TimeHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = method.invoke(target, args);
        long endTime = System.currentTimeMillis();
        System.out.println(method.getName() + " 执行时间: " + (endTime - startTime) + "ms");
        return result;
    }
}

public class DynamicProxyDemo {
    public static void main(String[] args) {
        Calculator target = new CalculatorImpl();
        
        Calculator proxy = (Calculator) Proxy.newProxyInstance(
                Calculator.class.getClassLoader(),
                new Class<?>[]{Calculator.class},
                new TimeHandler(target)
        );
        
        int result = proxy.add(3, 5);
        System.out.println("结果: " + result);
    }
}

57. 什么是Java模块系统(Java 9+)?

答案:Java 9引入的模块化系统,使用module-info.java定义模块。
实操:创建简单的模块化项目。

// module-info.java
module mymodule {
    exports com.example.mypackage;
    requires java.base;
    requires java.sql;
}

// com/example/mypackage/MyClass.java
package com.example.mypackage;

public class MyClass {
    public static void sayHello() {
        System.out.println("Hello from module!");
    }
}

58. 什么是Java 8的方法引用?

答案:简化Lambda表达式的语法,直接引用已有方法。
实操:使用方法引用。

import java.util.Arrays;
import java.util.List;

public class MethodReferenceDemo {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        
        // 使用方法引用
        names.forEach(System.out::println);
        
        // 等价的Lambda表达式
        names.forEach(name -> System.out.println(name));
    }
}

59. 什么是Java 8的函数式接口?

答案:只包含一个抽象方法的接口,可用@FunctionalInterface注解。
实操:定义和使用函数式接口。

@FunctionalInterface
interface MyFunction {
    int apply(int a, int b);
}

public class FunctionalInterfaceDemo {
    public static void main(String[] args) {
        // 使用Lambda表达式实现函数式接口
        MyFunction add = (a, b) -> a + b;
        
        int result = add.apply(3, 5);
        System.out.println("结果: " + result);
    }
}

60. 什么是Java中的本地方法(Native Method)?

答案:用其他语言(如C、C++)实现的Java方法。
实操:声明本地方法。

public class NativeMethodDemo {
    // 声明本地方法
    public native void nativeMethod();
    
    // 加载本地库
    static {
        System.loadLibrary("mylib");
    }
    
    public static void main(String[] args) {
        new NativeMethodDemo().nativeMethod();
    }
}

七、数据库连接

61. 如何连接Java与数据库?

答案:使用JDBC API。
实操:连接MySQL数据库并查询数据。

import java.sql.*;

public class JdbcDemo {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydb";
        String username = "root";
        String password = "password";

        try (Connection conn = DriverManager.getConnection(url, username, password);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {

            while (rs.next()) {
                System.out.println(rs.getInt("id") + ", " + rs.getString("name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

62. 什么是JDBC?

答案:Java Database Connectivity,用于与数据库交互的API。
实操:使用PreparedStatement插入数据。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JdbcPreparedStatementDemo {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydb";
        String username = "root";
        String password = "password";

        String sql = "INSERT INTO users (name, age) VALUES (?, ?)";

        try (Connection conn = DriverManager.getConnection(url, username, password);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setString(1, "李四");
            pstmt.setInt(2, 30);
            pstmt.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

63. 什么是数据库连接池?

答案:管理数据库连接的技术,提高性能和资源利用率。
实操:使用HikariCP连接池。

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class ConnectionPoolDemo {
    public static void main(String[] args) {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        config.setUsername("root");
        config.setPassword("password");
        config.setMaximumPoolSize(10);
        
        HikariDataSource dataSource = new HikariDataSource(config);

        try (Connection conn = dataSource.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {

            while (rs.next()) {
                System.out.println(rs.getString("name"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

64. 什么是事务?

答案:一组不可分割的数据库操作序列。
实操:使用JDBC管理事务。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TransactionDemo {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydb";
        String username = "root";
        String password = "password";

        try (Connection conn = DriverManager.getConnection(url, username, password)) {
            conn.setAutoCommit(false);

            try (PreparedStatement pstmt1 = conn.prepareStatement("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
                 PreparedStatement pstmt2 = conn.prepareStatement("UPDATE accounts SET balance = balance + 100 WHERE id = 2")) {

                pstmt1.executeUpdate();
                pstmt2.executeUpdate();

                conn.commit();
            } catch (SQLException e) {
                conn.rollback();
                e.printStackTrace();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

65. 什么是SQL注入?如何防止?

答案:通过构造恶意SQL语句攻击数据库,使用PreparedStatement防止。
实操:演示SQL注入及防范。

// 不安全的代码(存在SQL注入风险)
String username = "' OR '1'='1";
String sql = "SELECT * FROM users WHERE username = '" + username + "'";

// 安全的代码
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users WHERE username = ?");
pstmt.setString(1, username);

66. 什么是ORM?

答案:对象关系映射,将对象模型映射到数据库表。
实操:使用Hibernate实现ORM。

import javax.persistence.*;

@Entity
@Table(name = "users")
class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "username")
    private String username;
    
    // getters and setters
}

67. 如何使用Java 8的Stream处理数据库结果?

答案:将ResultSet转换为Stream。
实操:将数据库查询结果转换为Stream。

import java.sql.*;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

public class JdbcStreamDemo {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydb";
        String username = "root";
        String password = "password";

        try (Connection conn = DriverManager.getConnection(url, username, password);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {

            Stream<ResultSet> stream = streamResultSet(rs);
            stream.forEach(row -> {
                try {
                    System.out.println(row.getString("username"));
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            });

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static Stream<ResultSet> streamResultSet(ResultSet rs) {
        Spliterator<ResultSet> spliterator = Spliterators.spliteratorUnknownSize(
                new ResultSetIterator(rs), Spliterator.ORDERED);
        return StreamSupport.stream(spliterator, false);
    }

    static class ResultSetIterator implements java.util.Iterator<ResultSet> {
        private final ResultSet resultSet;
        private boolean hasNext;

        ResultSetIterator(ResultSet resultSet) {
            this.resultSet = resultSet;
            try {
                this.hasNext = resultSet.next();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public boolean hasNext() {
            return hasNext;
        }

        @Override
        public ResultSet next() {
            if (!hasNext) {
                throw new java.util.NoSuchElementException();
            }
            try {
                ResultSet current = resultSet;
                hasNext = resultSet.next();
                return current;
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

68. 什么是数据库索引?

答案:提高数据库查询效率的数据结构。
实操:创建数据库索引。

// 使用JDBC创建索引
Statement stmt = conn.createStatement();
stmt.executeUpdate("CREATE INDEX idx_username ON users (username)");

69. 什么是存储过程?如何在Java中调用?

答案:预编译的数据库程序,使用CallableStatement调用。
实操:调用存储过程。

try (Connection conn = DriverManager.getConnection(url, username, password);
     CallableStatement cstmt = conn.prepareCall("{call get_user_count(?)}")) {
    
    cstmt.registerOutParameter(1, Types.INTEGER);
    cstmt.execute();
    
    int count = cstmt.getInt(1);
    System.out.println("用户数量: " + count);
}

70. 如何优化数据库查询性能?

答案:使用索引、优化查询语句、分页等。
实操:分页查询示例。

int pageSize = 10;
int pageNumber = 2;
int offset = (pageNumber - 1) * pageSize;

String sql = "SELECT * FROM users LIMIT ? OFFSET ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    pstmt.setInt(1, pageSize);
    pstmt.setInt(2, offset);
    
    try (ResultSet rs = pstmt.executeQuery()) {
        while (rs.next()) {
            // 处理结果
        }
    }
}

八、网络编程

71. 什么是Socket编程?

答案:使用套接字实现网络通信的编程方式。
实操:实现简单的TCP客户端-服务器。

// 服务器端
try (ServerSocket serverSocket = new ServerSocket(8080);
     Socket socket = serverSocket.accept();
     BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
     PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
    
    String inputLine;
    while ((inputLine = in.readLine()) != null) {
        out.println("服务器收到: " + inputLine);
    }
}

// 客户端
try (Socket socket = new Socket("localhost", 8080);
     PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
     BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
     BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) {
    
    String userInput;
    while ((userInput = stdIn.readLine()) != null) {
        out.println(userInput);
        System.out.println("服务器响应: " + in.readLine());
    }
}

72. 什么是URL类?

答案:表示统一资源定位符的类。
实操:使用URL读取网页内容。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;

public class URLDemo {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://www.example.com");
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(url.openStream()))) {
                
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

73. 什么是HTTP客户端?

答案:用于发送HTTP请求的客户端。
实操:使用Java 11的HttpClient发送请求。

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class HttpClientDemo {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newHttpClient();
        
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.example.com/data"))
                .build();
        
        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(HttpResponse::body)
                .thenAccept(System.out::println)
                .join();
    }
}

74. 什么是NIO2(AIO)?

答案:异步IO,基于回调机制。
实操:使用AsynchronousSocketChannel实现异步服务器。

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

public class AIODemo {
    public static void main(String[] args) throws Exception {
        AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open()
                .bind(new InetSocketAddress(8080));
        
        server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
            @Override
            public void completed(AsynchronousSocketChannel client, Void attachment) {
                server.accept(null, this); // 继续接受下一个连接
                
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                client.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
                    @Override
                    public void completed(Integer result, ByteBuffer buffer) {
                        buffer.flip();
                        // 处理数据
                        buffer.clear();
                        client.read(buffer, buffer, this);
                    }

                    @Override
                    public void failed(Throwable exc, ByteBuffer buffer) {
                        try {
                            client.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            }

            @Override
            public void failed(Throwable exc, Void attachment) {
                exc.printStackTrace();
            }
        });
        
        Thread.sleep(1000000); // 保持服务器运行
    }
}

75. 什么是WebSocket?

答案:双向通信的网络协议。
实操:使用Java API实现WebSocket客户端。

import javax.websocket.*;
import java.net.URI;

@ClientEndpoint
public class WebSocketClient {
    private Session session;

    public WebSocketClient(String uri) {
        try {
            WebSocketContainer container = ContainerProvider.getWebSocketContainer();
            session = container.connectToServer(this, URI.create(uri));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("连接打开: " + session.getId());
    }

    @OnMessage
    public void onMessage(String message) {
        System.out.println("收到消息: " + message);
    }

    @OnClose
    public void onClose(Session session, CloseReason reason) {
        System.out.println("连接关闭: " + reason);
    }

    public void sendMessage(String message) {
        session.getAsyncRemote().sendText(message);
    }
}

76. 什么是防火墙?

答案:网络安全设备,控制网络流量。
实操:配置简单的防火墙规则。

# 使用iptables阻止外部访问8080端口
iptables -A INPUT -p tcp --dport 8080 -j DROP

77. 什么是代理服务器?

答案:位于客户端和服务器之间的中间服务器。
实操:通过代理服务器发送HTTP请求。

import java.net.*;
import java.io.*;

public class ProxyDemo {
    public static void main(String[] args) {
        try {
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.example.com", 8080));
            URL url = new URL("https://www.example.com");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
            
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()))) {
                
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

78. 什么是网络协议?

答案:网络通信的规则和标准。
实操:实现简单的UDP通信。

// 发送方
try (DatagramSocket socket = new DatagramSocket()) {
    String message = "Hello, UDP!";
    byte[] buffer = message.getBytes();
    InetAddress address = InetAddress.getByName("localhost");
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, 8888);
    socket.send(packet);
}

// 接收方
try (DatagramSocket socket = new DatagramSocket(8888)) {
    byte[] buffer = new byte[1024];
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    socket.receive(packet);
    String message = new String(packet.getData(), 0, packet.getLength());
    System.out.println("收到: " + message);
}

79. 什么是RESTful API?

答案:基于HTTP协议的API设计风格。
实操:使用Spring Boot创建简单的REST API。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class RestApiDemo {
    public static void main(String[] args) {
        SpringApplication.run(RestApiDemo.class, args);
    }

    @GetMapping("/hello/{name}")
    public String sayHello(@PathVariable String name) {
        return "Hello, " + name + "!";
    }
}

80. 什么是JSON?如何在Java中处理JSON?

答案:轻量级数据交换格式,使用Jackson等库处理。
实操:使用Jackson解析JSON。

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonDemo {
    public static void main(String[] args) {
        String json = "{\"name\":\"张三\",\"age\":30}";
        
        try {
            ObjectMapper mapper = new ObjectMapper();
            Person person = mapper.readValue(json, Person.class);
            System.out.println(person.getName() + ", " + person.getAge());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Person {
    private String name;
    private int age;

    // getters and setters
}

九、设计模式

81. 什么是单例模式?

答案:确保一个类只有一个实例。
实操:实现线程安全的单例模式。

public class Singleton {
    private static volatile Singleton instance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

82. 什么是工厂模式?

答案:定义创建对象的接口,由子类决定实例化哪个类。
实操:实现简单工厂模式。

interface Shape {
    void draw();
}

class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}

class ShapeFactory {
    public Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        }
        return null;
    }
}

83. 什么是观察者模式?

答案:对象间一对多的依赖关系。
实操:实现简单的观察者模式。

import java.util.ArrayList;
import java.util.List;

interface Observer {
    void update(String message);
}

class ConcreteObserver implements Observer {
    private String name;
    
    public ConcreteObserver(String name) {
        this.name = name;
    }
    
    @Override
    public void update(String message) {
        System.out.println(name + " 收到消息: " + message);
    }
}

interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers(String message);
}

class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }
    
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    
    @Override
    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

84. 什么是装饰器模式?

答案:动态地给对象添加额外职责。
实操:实现咖啡装饰器。

interface Beverage {
    String getDescription();
    double cost();
}

class Espresso implements Beverage {
    @Override
    public String getDescription() {
        return "浓缩咖啡";
    }
    
    @Override
    public double cost() {
        return 1.99;
    }
}

abstract class CondimentDecorator implements Beverage {
    protected Beverage beverage;
    
    public CondimentDecorator(Beverage beverage) {
        this.beverage = beverage;
    }
}

class Milk extends CondimentDecorator {
    public Milk(Beverage beverage) {
        super(beverage);
    }
    
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", 牛奶";
    }
    
    @Override
    public double cost() {
        return beverage.cost() + 0.3;
    }
}

85. 什么是策略模式?

答案:定义一系列算法并封装,使它们可以互相替换。
实操:实现支付策略。

interface PaymentStrategy {
    void pay(double amount);
}

class CreditCardStrategy implements PaymentStrategy {
    private String cardNumber;
    private String cvv;
    
    public CreditCardStrategy(String cardNumber, String cvv) {
        this.cardNumber = cardNumber;
        this.cvv = cvv;
    }
    
    @Override
    public void pay(double amount) {
        System.out.println("使用信用卡支付: " + amount);
    }
}

class PayPalStrategy implements PaymentStrategy {
    private String email;
    
    public PayPalStrategy(String email) {
        this.email = email;
    }
    
    @Override
    public void pay(double amount) {
        System.out.println("使用PayPal支付: " + amount);
    }
}

class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
    
    public void checkout(double amount) {
        paymentStrategy.pay(amount);
    }
}

86. 什么是适配器模式?

答案:将一个类的接口转换成客户希望的另一个接口。
实操:实现电源适配器。

interface EuropeanPlug {
    void plugInEuropeanSocket();
}

class EuropeanDevice implements EuropeanPlug {
    @Override
    public void plugInEuropeanSocket() {
        System.out.println("欧洲设备插入欧洲插座");
    }
}

interface USAPlug {
    void plugInUSASocket();
}

class USADevice implements USAPlug {
    @Override
    public void plugInUSASocket() {
        System.out.println("美国设备插入美国插座");
    }
}

class PlugAdapter implements EuropeanPlug {
    private USAPlug usaPlug;
    
    public PlugAdapter(USAPlug usaPlug) {
        this.usaPlug = usaPlug;
    }
    
    @Override
    public void plugInEuropeanSocket() {
        usaPlug.plugInUSASocket();
        System.out.println("使用适配器转换为欧洲插头");
    }
}

87. 什么是模板方法模式?

答案:定义算法骨架,将一些步骤延迟到子类实现。
实操:实现烹饪模板。

abstract class CookingRecipe {
    public final void cook() {
        prepareIngredients();
        cookIngredients();
        serve();
    }
    
    protected abstract void prepareIngredients();
    
    protected abstract void cookIngredients();
    
    protected void serve() {
        System.out.println("上菜");
    }
}

class PastaRecipe extends CookingRecipe {
    @Override
    protected void prepareIngredients() {
        System.out.println("准备意大利面和酱料");
    }
    
    @Override
    protected void cookIngredients() {
        System.out.println("煮意大利面,加热酱料");
    }
}

88. 什么是责任链模式?

答案:将请求的发送者和接收者解耦。
实操:实现请假审批链。

abstract class Approver {
    protected Approver successor;
    
    public void setSuccessor(Approver successor) {
        this.successor = successor;
    }
    
    public abstract void processRequest(int days);
}

class TeamLeader extends Approver {
    @Override
    public void processRequest(int days) {
        if (days <= 3) {
            System.out.println("团队领导批准请假 " + days + " 天");
        } else if (successor != null) {
            successor.processRequest(days);
        }
    }
}

class DepartmentManager extends Approver {
    @Override
    public void processRequest(int days) {
        if (days <= 7) {
            System.out.println("部门经理批准请假 " + days + " 天");
        } else if (successor != null) {
            successor.processRequest(days);
        }
    }
}

89. 什么是状态模式?

答案:允许对象在内部状态改变时改变它的行为。
实操:实现电梯状态。

interface ElevatorState {
    void openDoor();
    void closeDoor();
    void goUp();
    void goDown();
}

class IdleState implements ElevatorState {
    private Elevator elevator;
    
    public IdleState(Elevator elevator) {
        this.elevator = elevator;
    }
    
    @Override
    public void openDoor() {
        System.out.println("电梯门打开");
        elevator.setState(elevator.getDoorOpenState());
    }
    
    @Override
    public void closeDoor() {
        System.out.println("电梯门已关闭");
    }
    
    @Override
    public void goUp() {
        System.out.println("电梯上升");
        elevator.setState(elevator.getMovingUpState());
    }
    
    @Override
    public void goDown() {
        System.out.println("电梯下降");
        elevator.setState(elevator.getMovingDownState());
    }
}

class Elevator {
    private ElevatorState doorOpenState;
    private ElevatorState doorClosedState;
    private ElevatorState movingUpState;
    private ElevatorState movingDownState;
    
    private ElevatorState currentState;
    
    public Elevator() {
        doorOpenState = new DoorOpenState(this);
        doorClosedState = new DoorClosedState(this);
        movingUpState = new MovingUpState(this);
        movingDownState = new MovingDownState(this);
        
        currentState = doorClosedState;
    }
    
    // getters and setters
}

90. 什么是建造者模式?

答案:将一个复杂对象的构建与表示分离。
实操:实现电脑建造者。

class Computer {
    private String cpu;
    private String ram;
    private String storage;
    
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
    
    public void setRam(String ram) {
        this.ram = ram;
    }
    
    public void setStorage(String storage) {
        this.storage = storage;
    }
    
    @Override
    public String toString() {
        return "CPU: " + cpu + ", RAM: " + ram + ", Storage: " + storage;
    }
}

interface ComputerBuilder {
    void buildCpu();
    void buildRam();
    void buildStorage();
    Computer getComputer();
}

class GamingComputerBuilder implements ComputerBuilder {
    private Computer computer;
    
    public GamingComputerBuilder() {
        this.computer = new Computer();
    }
    
    @Override
    public void buildCpu() {
        computer.setCpu("Intel i9");
    }
    
    @Override
    public void buildRam() {
        computer.setRam("32GB");
    }
    
    @Override
    public void buildStorage() {
        computer.setStorage("1TB SSD");
    }
    
    @Override
    public Computer getComputer() {
        return computer;
    }
}

class ComputerDirector {
    private ComputerBuilder builder;
    
    public ComputerDirector(ComputerBuilder builder) {
        this.builder = builder;
    }
    
    public Computer constructComputer() {
        builder.buildCpu();
        builder.buildRam();
        builder.buildStorage();
        return builder.getComputer();
    }
}

十、性能优化

91. 如何优化Java应用程序的性能?

答案:从代码、JVM参数、数据库等多方面优化。
实操:使用StringBuilder替代String拼接。

// 优化前
String result = "";
for (int i = 0; i < 1000; i++) {
    result += i; // 会创建大量临时对象
}

// 优化后
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i); // 性能更好
}
String result = sb.toString();

92. 什么是JVM调优?

答案:调整JVM参数以提高性能。
实操:设置堆内存大小。

java -Xms512m -Xmx1024m MyApp

93. 什么是垃圾回收(GC)?

答案:自动回收不再使用的内存。
实操:监控GC情况。

java -XX:+PrintGCDetails -XX:+PrintGCTimeStamps MyApp

94. 如何分析内存泄漏?

答案:使用工具如VisualVM、MAT等。
实操:使用jstat监控堆内存使用。

jstat -gc <pid> 1000 10

95. 什么是对象池?

答案:重用对象以减少创建和销毁开销。
实操:实现简单的对象池。

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ObjectPool<T> {
    private ConcurrentLinkedQueue<T> pool;
    private ScheduledExecutorService executorService;

    public ObjectPool(final int minObjects) {
        // 初始化对象池
        initialize(minObjects);
    }

    public ObjectPool(final int minObjects, final int maxObjects, final long validationInterval) {
        // 初始化对象池
        initialize(minObjects);

        // 定时检查,维持对象池最小大小
        executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleWithFixedDelay(() -> {
            int size = pool.size();
            if (size < minObjects) {
                int sizeToBeAdded = minObjects - size;
                for (int i = 0; i < sizeToBeAdded; i++) {
                    pool.add(createObject());
                }
            } else if (size > maxObjects) {
                int sizeToBeRemoved = size - maxObjects;
                for (int i = 0; i < sizeToBeRemoved; i++) {
                    pool.poll();
                }
            }
        }, validationInterval, validationInterval, TimeUnit.SECONDS);
    }

    public T borrowObject() {
        T object;
        if ((object = pool.poll()) == null) {
            object = createObject();
        }
        return object;
    }

    public void returnObject(T object) {
        if (object == null) {
            return;
        }
        this.pool.offer(object);
    }

    public void shutdown() {
        if (executorService != null) {
            executorService.shutdown();
        }
    }

    private void initialize(final int minObjects) {
        pool = new ConcurrentLinkedQueue<>();
        for (int i = 0; i < minObjects; i++) {
            pool.add(createObject());
        }
    }

    protected T createObject() {
        // 由子类实现创建对象的逻辑
        return null;
    }
}

96. 什么是线程池?

答案:管理线程的创建和复用。
实操:自定义线程池。

import java.util.concurrent.*;

public class CustomThreadPoolDemo {
    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("执行任务: " + taskId + ", 线程: " + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        executor.shutdown();
    }
}

97. 如何优化数据库查询?

答案:使用索引、优化SQL语句、避免N+1查询等。
实操:使用EXPLAIN分析查询。

EXPLAIN SELECT * FROM users WHERE age > 30;

98. 什么是缓存?如何在Java中实现缓存?

答案:临时存储数据以提高访问速度。
实操:使用Guava Cache实现本地缓存。

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import java.util.concurrent.TimeUnit;

public class CacheDemo {
    private static Cache<String, String> cache = CacheBuilder.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build();

    public static String getData(String key) {
        String data = cache.getIfPresent(key);
        if (data == null) {
            data = fetchFromDatabase(key);
            cache.put(key, data);
        }
        return data;
    }

    private static String fetchFromDatabase(String key) {
        // 从数据库获取数据
        return "Data for " + key;
    }
}

99. 什么是懒加载?

答案:延迟加载数据直到需要使用。
实操:实现懒加载单例。

public class LazySingleton {
    private static LazySingleton instance;
    
    private LazySingleton() {}
    
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

100. 如何进行代码性能分析?

答案:使用工具如JProfiler、YourKit等。
实操:使用Java Mission Control进行性能分析。

jcmd <pid> JFR.start duration=60s filename=recording.jfr

十一、安全

101. 什么是SQL注入?如何防止?

答案:通过构造恶意SQL语句攻击数据库。
实操:使用PreparedStatement防止SQL注入。

// 不安全的代码
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";

// 安全的代码
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users WHERE username = ? AND password = ?");
pstmt.setString(1, username);
pstmt.setString(2, password);

102. 什么是XSS攻击?如何防止?

答案:跨站脚本攻击,注入恶意脚本。
实操:对用户输入进行转义。

import org.owasp.encoder.Encode;

public class XSSPrevention {
    public static String escapeHTML(String input) {
        return Encode.forHtml(input);
    }
}

103. 什么是CSRF攻击?如何防止?

答案:跨站请求伪造,冒充合法用户。
实操:使用CSRF令牌。

// 生成CSRF令牌
String token = UUID.randomUUID().toString();
session.setAttribute("csrfToken", token);

// 在表单中包含令牌
<form>
    <input type="hidden" name="csrfToken" value="${csrfToken}">
    <!-- 其他表单字段 -->
</form>

// 验证令牌
if (!token.equals(session.getAttribute("csrfToken"))) {
    throw new SecurityException("Invalid CSRF token");
}

104. 如何进行密码加密?

答案:使用哈希算法加随机盐。
实操:使用BCrypt加密密码。

import org.mindrot.jbcrypt.BCrypt;

public class PasswordHashing {
    public static String hashPassword(String password) {
        return BCrypt.hashpw(password, BCrypt.gensalt());
    }

    public static boolean checkPassword(String password, String hashedPassword) {
        return BCrypt.checkpw(password, hashedPassword);
    }
}

105. 什么是HTTPS?如何配置?

答案:HTTP的安全版本,使用SSL/TLS加密。
实操:配置Spring Boot应用使用HTTPS。

server:
  port: 8443
  ssl:
    key-store: classpath:keystore.p12
    key-store-password: yourpassword
    key-store-type: PKCS12
    key-alias: tomcat

106. 什么是JWT?如何使用?

答案:JSON Web Token,用于安全传输信息。
实操:生成和验证JWT。

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtUtil {
    private static final String SECRET_KEY = "yoursecretkey";
    private static final long EXPIRATION_TIME = 86400000; // 24小时

    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    public static String validateToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJ
---

你可能感兴趣的:(java开发,java,面试,python)