020、二级Java选择题综合知识点(持续更新版)
1. 排序二叉树的遍历结果为有序序列的是:中序遍历
解释:中序遍历是一种遍历二叉树的方式,按照“左子树 -> 根节点 -> 右子树”的顺序访问节点。在排序二叉树(BST)中,这种遍历顺序会得到一个递增的有序序列,因为左子树中的所有节点值都小于根节点,而右子树中的节点值都大于根节点。
举例:给定一个排序二叉树:
10
/ \
5 15
/ \ \
3 7 18
其中序遍历结果为:3, 5, 7, 10, 15, 18,这是一个递增的有序序列。
2. 数据库系统减少数据堆积,都不能避免一切数据的重复
解释:数据库系统通过多种技术(如数据规范化、索引、约束等)减少冗余数据和重复信息的堆积,但在实际应用中,由于设计缺陷、业务需求等原因,仍然无法完全避免数据重复。例如,不同用户可能会输入相同的客户信息。
举例:在一个电商系统中,不同用户可能会重复创建相同商品的信息,导致数据冗余。虽然数据库可以通过唯一性约束和索引减少重复,但完全避免则较为困难。
3. 数据模型的三个要素:数据结构、数据操作、数据约束
解释:
- 数据结构:表示数据的组织方式,包括实体、属性和关系等。
- 数据操作:指对数据进行的操作方式,如插入、删除、查询和更新等。
- 数据约束:指在数据操作过程中对数据施加的限制条件,如唯一性、完整性等。
举例:在关系数据库中,表的设计就是数据结构;SQL语句如SELECT
、UPDATE
就是数据操作;外键约束、唯一性约束就是数据约束。
4. 关系的完整性:实体完整性、参照完整性、用户自定义完整性
解释:
- 实体完整性:要求每个关系的主键值是唯一且不为空的。
- 参照完整性:外键必须引用有效的主键,保证引用的关联关系存在。
- 用户自定义完整性:用户根据业务需求自定义的约束,如年龄必须大于18岁。
举例:在学生表中,学生ID为主键(实体完整性),课程表中的学生ID为外键(参照完整性),成绩必须在0到100之间(用户自定义完整性)。
5. 数据模型包括:概念模型、逻辑模型、物理模型
解释:
- 概念模型:以实体-关系图(ER图)表示现实世界中的数据。
- 逻辑模型:将概念模型转换为数据库中的表结构设计。
- 物理模型:具体到数据库的存储方式,如文件、索引的实现。
举例:在一个图书管理系统中,概念模型定义了“书籍”、“作者”等实体及其关系;逻辑模型转换为数据库表如books
、authors
;物理模型则包括表的存储方式和索引结构。
6. 数据库系统的三级模式:外模式、概念模式、内模式
解释:
- 外模式:指用户或应用程序所看到的视图,是数据库的定制化表示。
- 概念模式:数据库的整体结构或全局视图,定义了数据库的逻辑结构。
- 内模式:数据库的物理存储方式和存取路径。
举例:在银行系统中,外模式可能是用户看到的账户余额和交易记录;概念模式是整个银行系统的数据模型;内模式则是数据如何在磁盘上存储。
7. 长度为n的顺序表上查找一个数据,平均情况下需要比较的次数:(n+1)/2
解释:顺序查找是一种线性查找算法,平均比较次数为(n+1)/2,表示在最坏情况下需要查找n次,在最好的情况下查找1次,取平均就是(n+1)/2。
举例:如果顺序表长度为5,那么平均需要比较的次数为(5+1)/2 = 3次。
8. 具有2n个结点的完全二叉树,叶子结点个数为n
解释:在完全二叉树中,叶子结点占总节点数的一半。因此,若完全二叉树有2n个结点,则叶子结点的数量为n。
举例:若完全二叉树有6个结点,则叶子结点有3个。
9. 在栈中,栈顶指针的动态变化决定栈中元素的个数
解释:栈是一种后进先出(LIFO)的数据结构,栈顶指针指示栈顶元素的位置。当栈顶指针移动时,表示元素被压入或弹出。
举例:每次压栈时,栈顶指针增加;弹栈时,栈顶指针减少。栈中元素的个数取决于栈顶指针的位置。
10. 循环队列是队列的一种顺序存储结构
解释:循环队列是一种特殊的队列结构,首尾相连,形成一个环。当队列尾部到达末端时,若前部有空位,可以回绕使用这些空位。
举例:一个大小为5的队列,存储元素时,当尾指针到达位置4后,若位置0空闲,则下一个元素存储在位置0。
11. 在循环队列中,队头指针和队尾指针的动态变化决定队列的长度
解释:在循环队列中,队头指针指向队列的第一个元素,队尾指针指向队列的下一个可用位置。队列的长度由队头和队尾指针的差值计算。
举例:若队头指针为1,队尾指针为4,则队列中有3个元素。
12. 正确创建一个 FileInputStream
对象的语句是:FileInputStream(File file)
或 FileInputStream(String name)
或 FileInputStream(FileDescriptor fdObj)
解释:FileInputStream
是 Java 中用于读取文件的字节输入流类。可以通过以下三种方式来创建 FileInputStream
对象:
- 传递
File
对象:通过一个具体的文件对象来创建流。 - 传递文件路径:通过字符串表示的文件路径来创建流。
- 传递
FileDescriptor
对象:通过文件描述符来创建流。
举例:
File file = new File("example.txt");
FileInputStream fis1 = new FileInputStream(file);
FileInputStream fis2 = new FileInputStream("example.txt");
FileDescriptor fd = new FileDescriptor(); // 文件描述符通常通过低级操作获得
FileInputStream fis3 = new FileInputStream(fd);
13. 属于字符输入流的是:InputStreamReader
解释:InputStreamReader
是将字节流转换为字符流的桥梁类,主要用于将 InputStream
转换为 Reader
,从而可以按字符读取数据。
举例:
FileInputStream fis = new FileInputStream("example.txt");
InputStreamReader isr = new InputStreamReader(fis);
这里,InputStreamReader
将字节流 FileInputStream
转换为字符流,方便处理字符数据。
14. Reader
是用于读取字符流的抽象类。直接已知子类有:BufferedReader
、CharArrayReader
、FilterReader
、InputStreamReader
、PipeReader
、StringReader
解释:Reader
是 Java 中处理字符输入流的基础类,它是一个抽象类,无法直接实例化。子类扩展了 Reader
的功能,用于不同类型的字符数据输入场景。
举例:
BufferedReader
:提供缓冲机制,提高读取效率。CharArrayReader
:将字符数组作为输入源。InputStreamReader
:将字节流转换为字符流。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine(); // 读取控制台输入
15. 字符流实现了字符数据的读写,字节流实现了字节数据的读写
解释:在 Java 中,字符流(如 Reader
和 Writer
)用于处理字符数据,特别是 Unicode 字符;而字节流(如 InputStream
和 OutputStream
)则用于处理原始的字节数据,适用于二进制文件。
举例:
- 字节流:处理图片、音频文件等二进制数据。
FileInputStream fis = new FileInputStream("image.jpg");
- 字符流:处理文本文件。
FileReader fr = new FileReader("text.txt");
16. 字节流默认不使用缓冲区;字符流使用缓冲区;字节流操作的基本单元为字节;字符流操作的基本单元为 Unicode 码元
解释:
- 字节流直接读取或写入字节,不使用缓冲区,操作较为底层。
- 字符流会将数据存入缓冲区,处理的是编码后的字符。
- 字节流的基本单位是字节,而字符流的基本单位是 Unicode 字符。
举例:
- 字节流读写:
FileInputStream fis = new FileInputStream("binary.dat");
- 字符流读写:
FileReader fr = new FileReader("text.txt");
BufferedReader br = new BufferedReader(fr); // 使用缓冲区
17. 字节流通常用于二进制数据,它可以处理任意类型数据,但不支持直接读取 Unicode 码元;字符流通常处理文本数据,支持 Unicode 码元
解释:字节流适合处理图片、视频等二进制数据,因为它只处理字节,不考虑字符编码。而字符流主要用于处理文本数据,支持读取和写入 Unicode 字符集的数据。
举例:
- 字节流:
FileInputStream fis = new FileInputStream("image.jpg");
- 字符流:
FileReader fr = new FileReader("document.txt");
18. ASCII 用 8 位表示一个字符,Unicode 用 16 位表示一个字符,因此 Unicode 中汉字和英文的占用空间是一样的
解释:ASCII 编码采用 8 位(二进制)表示字符,主要用于英语字符。Unicode 编码统一采用 16 位,因此无论是英文字符还是汉字都占用相同的存储空间。
举例:
- 一个英文字符‘A’在 ASCII 中占 1 字节,在 Unicode 中占 2 字节。
- 一个汉字‘你’在 Unicode 中同样占 2 字节。
19. DataInputStream 是 InputStream 抽象类的子类,不属于接口
解释:DataInputStream
是用于读取 Java 基本数据类型的字节输入流类。它继承了 InputStream
,但不是接口,而是具体类。
举例:
FileInputStream fis = new FileInputStream("data.bin");
DataInputStream dis = new DataInputStream(fis);
int value = dis.readInt(); // 读取一个整数
20. FileInputStream 是将文件作为流的方式读取,它是按照文件的顺序从 0 位置开始读取;RandomAccessFile 是随机读取数据,读取的位置不一定从 0 开始
解释:FileInputStream
从文件的开头按顺序读取数据,而 RandomAccessFile
允许你在文件的任意位置进行读写操作。
举例:
- 顺序读取:
FileInputStream fis = new FileInputStream("file.txt");
int data = fis.read(); // 从文件开头开始读取
- 随机读取:
RandomAccessFile raf = new RandomAccessFile("file.txt", "r");
raf.seek(10); // 跳到文件的第10个字节开始读取
int data = raf.read();
21. Java 中处理字节流的抽象类有 InputStream 和 OutputStream
解释:InputStream
和 OutputStream
是 Java 中处理字节输入和输出流的两个抽象类。所有字节流类(如 FileInputStream
和 ByteArrayInputStream
)都继承自这两个类。
举例:
ByteArrayInputStream
:从字节数组中读取数据。FileInputStream
:从文件中读取字节数据。
FileInputStream fis = new FileInputStream("file.bin");
22. 过滤流:为了方便读取或写入,对字节流或字符流进行包装
解释:过滤流(Filter Stream)是对其他输入流或输出流进行包装,使其具备额外的功能,比如缓冲、数据转换等。过滤流本身不处理数据筛选,只是增强流的功能。
举例:
BufferedInputStream
是InputStream
的一个过滤流,实现了缓冲读取功能:
FileInputStream fis = new FileInputStream("file.txt");
BufferedInputStream bis = new BufferedInputStream(fis); // 增加缓冲区
23. DataOutputStream 是 OutputStream 的子类,具备数据类型或格式转换的功能
解释:DataOutputStream
是一种输出流,允许将 Java 基本数据类型(如 int
、double
)以二进制形式写入输出流中,并实现数据的编码和格式转换。
举例:
FileOutputStream fos = new FileOutputStream("data.bin");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeInt(12345); // 将整数以二进制形式写入
24. write() 方法:向输出流写入数据;flush() 方法:强制清空缓冲区;close() 方法:关闭输出流并释放资源
解释:
write()
用于将数据写入输出流。flush()
用于强制清空缓冲区,将所有缓冲区中的数据写入目标设备(如文件)。close()
用于关闭流并释放系统资源。
举例:
FileOutputStream fos = new FileOutputStream("file.txt");
fos.write("Hello, World!".getBytes());
fos.flush(); // 强制将数据写入文件
fos.close(); // 关闭文件流
25. FileWriter 用来写入字符文件的便捷类;FileReader 用来读取字符文件的便捷类
解释:FileWriter
和 FileReader
分别是 Java 中用于写入和读取字符文件的便捷类。FileWriter
用于将字符写入文件,FileReader
用于从文件中读取字符数据。它们是字符流的实现,主要处理文本数据。
举例:
- 写入字符到文件:
FileWriter writer = new FileWriter("example.txt");
writer.write("Hello, World!");
writer.close();
- 读取字符文件:
FileReader reader = new FileReader("example.txt");
int data;
while ((data = reader.read()) != -1) {
System.out.print((char) data);
}
reader.close();
26. 线程是进程的组成部分,一个进程可以拥有多个线程,而一个线程必须依赖于一个进程
解释:在操作系统中,进程是程序的执行实例,而线程是进程中的一个执行路径。一个进程可以包含多个线程,这些线程共享进程的资源。线程是执行任务的最小单位。
举例:
在 Java 中,一个进程可以通过创建多个线程来实现多任务处理:
public class MyThread extends Thread {
public void run() {
System.out.println("Thread is running...");
}
}
MyThread thread1 = new MyThread();
thread1.start(); // 启动线程
27. 一个类通过关键字 implements
声明自己使用一个或者多个接口;extends
是继承某个类,继承之后可以使用父类的方法,也可以重写父类的方法;implements
是实现多个接口,接口的方法一般为空,必须重写才能使用
解释:
extends
关键字用于继承类,子类可以继承父类的属性和方法,也可以重写父类方法。implements
用于实现接口,接口中定义的方法必须在类中实现。
举例:
// 类继承
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}
// 实现接口
interface Playable {
void play();
}
class Player implements Playable {
public void play() {
System.out.println("Playing the game");
}
}
28. Java 中线程模型包含三部分:①一个虚拟的 CPU;②该 CPU 执行的代码;③代码所操作的数据
解释:在 Java 的多线程模型中,每个线程看似拥有一个虚拟的 CPU,它执行指定的代码,并且能够操作该线程的局部数据或共享数据。
举例:
public class MyRunnable implements Runnable {
public void run() {
System.out.println("Thread is running...");
}
}
Thread thread = new Thread(new MyRunnable());
thread.start();
在这个示例中,run()
方法中的代码在虚拟的 CPU 上执行。
29. ClassCastException
异常类的父类是 RuntimeException
解释:ClassCastException
是在运行时抛出的异常,表示尝试将对象强制转换为不兼容的类型。它的父类是 RuntimeException
,这意味着它是非检查异常,不需要显式处理。
举例:
Object obj = "Hello";
Integer num = (Integer) obj; // 抛出 ClassCastException 异常
30. 没有根结点或没有叶子结点的数据结构一定是非线性结构
解释:如果数据结构没有根结点或叶子结点,说明它不是树状结构或链式结构,这种结构通常被称为非线性结构,例如图。图中的节点之间的关系不是线性的,而是复杂的连接关系。
举例:
在图(Graph)数据结构中,节点可以任意连接,没有固定的根节点或叶子节点。
// 图的表示法
Map<Integer, List<Integer>> graph = new HashMap<>();
graph.put(1, Arrays.asList(2, 3));
graph.put(2, Arrays.asList(1, 4));
graph.put(3, Arrays.asList(1, 4));
31. 算法的优劣与算法描述语言有关,与运行算法程序的环境无关
解释:算法的好坏主要取决于算法的设计,而不是程序运行的硬件或软件环境。虽然环境可能影响程序的运行效率,但算法本身的时间复杂度、空间复杂度等才是衡量其优劣的关键标准。
举例:
无论是在慢速计算机上运行还是在快速计算机上运行,O(n)
的线性搜索算法始终比 O(n^2)
的冒泡排序算法更加高效。
32. 字节码是 Java 虚拟机执行的特点之一
解释:Java 程序在编译后生成字节码(.class
文件),字节码是与平台无关的中间代码,Java 虚拟机会将字节码转换为机器码并在不同平台上执行。
举例:
当你编译 Java 代码时,它会生成字节码文件:
javac MyProgram.java // 生成 MyProgram.class
这个 .class
文件就是字节码。
33. 内存跟踪技术属于垃圾回收机制
解释:Java 中的垃圾回收机制自动管理内存,内存跟踪技术通过追踪不再被引用的对象,释放它们占用的内存,避免内存泄漏。
举例:
在 Java 中,开发者无需手动管理内存释放,JVM 会自动进行垃圾回收。
34. public
指明变量为公有;protected
指明变量为保护访问,可被同一个包中其他类、不同包中该类的子类以及该类自己访问和引用;final
指明变量为常量;默认(friendly)表示只能被同一个包中的类访问和引用
解释:
public
:任何类都可以访问。protected
:只能被同包内的类及子类访问。final
:表示常量或不可被继承/修改的类或方法。- 没有修饰符(friendly):只能被同包内的类访问。
举例:
public class MyClass {
public int publicVar;
protected int protectedVar;
final int constant = 10;
int friendlyVar;
}
35. 算术右移运算符 >>
;算术左移运算符 <<
;逻辑右移运算符 >>>
解释:
>>
:算术右移,保留符号位,将高位补符号位的值。<<
:算术左移,右边补 0。>>>
:逻辑右移,不保留符号位,左边补 0。
举例:
int a = -8; // 二进制为 11111111 11111111 11111111 11111000
System.out.println(a >> 2); // 结果为 -2,保留符号位
System.out.println(a >>> 2); // 结果为 1073741822,不保留符号位
36. JScrollPane
是带滚动条的面板,主要通过移动 JViewport
(视口)来实现
解释:JScrollPane
是 Java Swing 中的一个组件,用于为内容提供滚动条。当内容超出可视范围时,JScrollPane
会显示水平或垂直滚动条,并通过 JViewport
控制可视内容的显示范围。
举例:
JTextArea textArea = new JTextArea(10, 30);
JScrollPane scrollPane = new JScrollPane(textArea);
37. java.awt.event
包中定义的事件适配器包括:ComponentAdapter
、ContainerAdapter
、FocusAdapter
、KeyAdapter
、MouseMotionAdapter
、MouseAdapter
、WindowAdapter
解释:这些适配器类用于简化事件处理机制。它们是相应事件监听器的空实现,开发者可以重写其中所需的部分,而不必实现接口的所有方法。
举例:
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
System.out.println("Key pressed");
}
});
38. 对于 catch
子句的排列,如果有多个异常,子类异常应该在父类异常之前捕获
解释:在捕获异常时,应该先捕获最具体的异常(即子类异常),再捕获通用异常(即父类异常),否则子类异常将永远不会被执行。
举例:
代码:
try {
// 可能抛出异常的代码
} catch (FileNotFoundException e) {
System.out.println("File not found exception");
} catch (IOException e) {
System.out.println("IO exception");
} catch (Exception e) {
System.out.println("General exception");
}
在这个示例中,FileNotFoundException
是 IOException
的子类,所以应先捕获子类异常,再捕获父类异常。如果顺序反了,父类异常会拦截所有异常,子类异常永远不会被处理。
39. 为 JButton
添加事件监听器需要调用 addActionListener()
方法
解释:在 Java Swing 中,JButton
是用于创建按钮的组件,ActionListener
用于处理按钮的点击事件。要为按钮添加事件处理器,必须调用 addActionListener()
方法,并传递一个 ActionListener
接口的实现类。
举例:
JButton button = new JButton("Click me");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked");
}
});
40. GridBagLayout
是 Java 中最灵活的布局管理器
解释:GridBagLayout
是 Java Swing 中的一种布局管理器,它允许组件以网格形式排列,但可以控制每个组件占据的行、列数,以及对齐方式。它比 GridLayout
更灵活,因为组件可以跨越多行或多列。
举例:
JFrame frame = new JFrame();
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
frame.add(new JButton("Button 1"), gbc);
gbc.gridx = 1;
frame.add(new JButton("Button 2"), gbc);
41. 用户自定义异常的语法要求继承自 Exception
或其子类
解释:Java 允许开发者创建自己的异常类来处理特定的异常情况。自定义异常类必须继承自 Exception
或它的子类,通常重写构造方法以添加自定义信息。
举例:
class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
public class TestCustomException {
public static void main(String[] args) {
try {
throw new CustomException("This is a custom exception");
} catch (CustomException e) {
System.out.println(e.getMessage());
}
}
}
42. 程序中可以捕获的异常必须是 Throwable
类的子类
解释:Java 中所有可抛出的异常都是 Throwable
类的子类。Throwable
有两个直接子类:Error
和 Exception
。Error
通常用于严重的系统错误,Exception
用于程序中可预见的异常。
举例:
try {
throw new Exception("An exception occurred");
} catch (Throwable t) {
System.out.println("Caught Throwable: " + t.getMessage());
}
43. FileOutputStream
和 FileWriter
的区别在于:前者处理字节流,后者处理字符流
解释:FileOutputStream
用于将字节写入文件,而 FileWriter
用于将字符写入文件。它们适用于不同的数据类型。
举例:
- 使用
FileOutputStream
写字节:
FileOutputStream fos = new FileOutputStream("binary.dat");
fos.write(65); // 写入字节 65 (对应 ASCII 'A')
fos.close();
- 使用
FileWriter
写字符:
FileWriter writer = new FileWriter("text.txt");
writer.write("Hello");
writer.close();
44. synchronized 关键字确保线程安全
解释:synchronized
关键字用于确保同一时刻只有一个线程可以访问某个资源(如方法或代码块),从而防止并发线程之间的竞争条件(race condition)。
举例:
public synchronized void increment() {
count++;
}
public void incrementSyncBlock() {
synchronized(this) {
count++;
}
}
通过 synchronized
,保证多个线程在访问 increment()
方法时是互斥的,避免数据不一致问题。
45. 匿名内部类是一种没有名字的类,通常用于简化代码
解释:匿名内部类是在定义和实例化类时合并为一个步骤,没有显式地命名类。它们经常用于实现接口或扩展类,尤其在事件处理、线程等场景中使用。
举例:
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println("Thread is running");
}
});
thread.start();
匿名内部类通过简化代码,减少了类定义的冗余。
46. Servlet 是 Java EE 的一项技术,用于处理 HTTP 请求和响应
解释:Servlet 是服务器端的 Java 程序,用于处理 Web 应用中的客户端请求(通常是 HTTP 请求),并生成响应。它是 Java Web 开发的核心组件之一。
举例:
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("Hello, World!");
}
}
47. Java 中的 try-with-resources
语句用于确保资源在使用后自动关闭
解释:try-with-resources
语句用于自动管理资源,比如文件或数据库连接,它确保在 try
代码块执行完后,资源会被自动关闭,避免资源泄漏。需要实现 AutoCloseable
接口的资源可以放入 try
中。
举例:
try (FileWriter writer = new FileWriter("output.txt")) {
writer.write("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
在这个例子中,无需显式调用 close()
,FileWriter
会在 try
结束后自动关闭。
48. getServletContext()
方法用于获取 ServletContext
解释:ServletContext
是一个对象,代表 Web 应用的上下文,所有 Servlet 共享同一个 ServletContext
。可以通过 getServletContext()
方法在 Servlet 中获取该对象。
举例:
public void init() throws ServletException {
ServletContext context = getServletContext();
String appConfig = context.getInitParameter("configName");
}
这里 ServletContext
用于在不同的 Servlet 之间共享数据或资源。
49. 通过 doGet()
方法处理 GET 请求,通过 doPost()
方法处理 POST 请求
解释:在 Java Servlet 中,doGet()
方法用于处理来自客户端的 HTTP GET 请求,而 doPost()
用于处理 POST 请求。两者的主要区别在于数据传输方式:GET 在 URL 中传递参数,POST 在请求体中传递参数。
举例:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("GET request handled");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("POST request handled");
}
50. 过滤器 Filter
是 Servlet 技术的一部分,用于拦截和修改请求和响应
解释:过滤器是 Java Web 应用中的组件,它在请求到达 Servlet 之前或响应返回客户端之前,对请求和响应进行预处理或后处理。典型的应用场景包括日志记录、身份验证和数据压缩等。
举例:
@WebFilter("/filterExample")
public class ExampleFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Request is being filtered");
chain.doFilter(request, response); // 继续执行请求
}
}