Java 面向对象 · 交互课程

题库管理Quiz Bank

各课程页随堂测验(<Quiz items>)的题集中在此:可增 / 改 / 删并实时校验,按章节统计题量,导出 JSON 供整理回填。 编辑仅作用于当前会话(客户端内存),导出的 JSON 需教师确认后回填到对应 MDX。

题库管理器(QuizBankManager)

各课程页 <Quiz items={…} /> 里的题集中在这里: 可增 / 改 / 删(实时校验),导出 JSON 供整理回填。当前共 124 题,全部通过校验。

midterm-bank-1

JVM 的全称是( )

A. Java Virtual MachineB. Java Version ManagerC. Java View ModuleD. Java Vector Method

解析:JVM = Java Virtual Machine(Java 虚拟机),负责加载并执行字节码,是实现「一次编写、到处运行」的关键。

midterm-bank-2

Java 源文件的扩展名是( )

A. .classB. .javaC. .jarD. .html

解析:源文件为 .java;编译后生成字节码文件 .class;.jar 是打包后的归档。

midterm-bank-3

编译 Java 源程序使用的命令是( )

A. javaB. javapC. javacD. jar

解析:javac 把 .java 编译成 .class;java 用于运行字节码;javap 反汇编、jar 打包。

midterm-bank-4

Java 语言最大的特点是( )

A. 安全性高B. 支持多线程C. 面向过程编程D. 跨平台可移植性

解析:Java 编译为与平台无关的字节码,靠各平台的 JVM 运行——「一次编写,到处运行」;安全、多线程也是特点,但跨平台是其最大卖点。

00-java-overview-1

要「编写并编译」Java 程序,至少需要安装哪一层?

A. JVM(虚拟机)B. JRE(运行环境)C. JDK(开发工具包)D. 任意一层都可以

解析:JDK = JRE + 开发工具(含 javac 编译器),装了 JDK 就能写、编译并运行;JRE 只能运行,JVM 只是执行引擎。

00-java-overview-2

三层包含关系正确的是( )

A. JVM ⊃ JRE ⊃ JDKB. JDK ⊃ JRE ⊃ JVMC. JRE ⊃ JDK ⊃ JVMD. 三者互不包含

解析:JDK 最大(含开发工具),其内含 JRE,JRE 再含 JVM。开发者装 JDK 即拥有全部能力。

00-java-overview-3

`javac Hello.java` 的产物是( )

A. 可执行的 .exeB. 平台无关的字节码 Hello.classC. 机器指令二进制文件D. HTML 页面

解析:javac 把源码编译成与具体硬件无关的字节码(.class),再由各平台的 JVM 加载执行——这正是跨平台的关键。

00-java-overview-4

运行 `Hello.class` 时,正确的命令是( )

A. java Hello.classB. javac HelloC. java HelloD. run Hello.class

解析:运行用 `java 类名`(不带 .class);JVM 按类名定位字节码。`javac` 是编译,不是运行。

00-java-overview-5

Java 能「一次编写、到处运行」的根本原因是( )

A. 源码直接在各 OS 上重新编译B. 统一先编译成字节码,由各操作系统的 JVM 执行C. Java 程序是纯脚本,无需编译D. 每个平台都内置了 Java 解释器且行为一致

解析:源码 → 字节码(平台无关)→ 各 OS 的 JVM 负责执行。JVM 屏蔽了硬件差异,实现跨平台。

00-java-overview-6

关于 `public static void main(String[] args)`,正确的是( )

A. 它是 Java 程序的固定入口,JVM 启动时从它开始执行B. 方法名可以随意改C. 必须返回一个 intD. 每个类都必须有多个 main

解析:main 是 JVM 约定的程序入口:签名固定为 public static void main(String[] args)。static 表示无需先 new 对象即可调用。

01-class-object-1

关于 Java 中「类」和「对象」,哪个说法正确?

A. 类是运行时才创建的实例B. 类是模板/蓝图,对象是根据类创建的具体实例C. 类和对象是完全一样的东西D. 一个类只能有一个对象

解析:类是对一类事物的抽象描述(字段 + 方法),对象是用 new 依据类创建的具体实例,拥有自己的状态。

01-class-object-2

执行 `new Dog()` 后发生了什么?

A. 只在栈上创建一个引用B. 在堆上分配内存创建对象并调用构造器,变量保存指向它的引用C. 直接修改了类的定义D. 什么都没发生

解析:new 在堆(heap)上为对象分配内存并调用构造器初始化;引用变量(通常在栈上)保存指向该对象的地址。

01-class-object-3

关于构造方法,正确的是( )

A. 必须有 void 返回类型B. 与类同名、无返回类型,new 时自动调用C. 可以有多余的返回值D. 一个类只能有一个构造方法

解析:构造方法与类同名且没有返回类型(连 void 都没有);可重载出多个,若一个都不写编译器提供默认无参构造。

01-class-object-4

`this` 在构造方法首句 `this("Rex", 1)` 中的作用是( )

A. 创建新对象B. 调用本类的另一个重载构造方法C. 引用父类对象D. 声明静态变量

解析:this(...) 把当前对象的初始化委托给同类的另一个构造方法;它必须是构造方法的第一句可执行语句。

01-class-object-5

default(不写修饰符)与 protected 的关键区别是( )

A. 完全一样B. default:同包可见、异包子类继承不到;protected:同包不可见、子类可以C. protected 只能修饰方法D. default 比 private 更严格

解析:两者在「同包」和「异包子类」两个上下文恰好相反,是访问控制最常考的辨析点。

01-class-object-6

把属性设为 private 并提供 public getter/setter 的目的是( )

A. 让程序运行更快B. 数据保护:外部只能经受控入口访问/修改,便于校验C. 避免使用 newD. 让对象变成静态的

解析:封装的核心:隐藏内部状态,对外只暴露受控接口,在方法里做校验后再改数据,防止被误改。

02-lang-basics-1

Java 中整型常量(字面量)的默认类型是?

A. `long`B. `int`C. `short`D. `byte`

解析:整型字面量默认是 **int**;要 `long` 必须加后缀 `L`(如 `100L`)。

02-lang-basics-2

下列哪个不是 Java 的流程控制语句?

A. if-elseB. forC. whileD. class

解析:`class` 是类声明关键字,与流程控制无关;if/for/while/switch/do-while 才是控制结构。

02-lang-basics-3

执行 `final double PI = 3.14;` 之后再写 `PI = 3.14159;` 会发生什么?

A. PI 被更新为 3.14159B. 运行时报错C. 编译错误:不能给 final 变量重新赋值D. 输出警告但可运行

解析:`final` 变量一旦赋值不可再改,重复赋值在编译期就被拒绝。注意:`final` 引用指向的对象内容仍可修改。

02-lang-basics-4

下列哪种循环「至少会执行一次」循环体?

A. forB. whileC. do-whileD. 三种都至少一次

解析:`do-while` 先执行后判断,所以至少跑一次;`for`/`while` 先判断,条件一开始为假就一次不跑。

02-lang-basics-5

`String[] s = new String[5];` 下列哪个索引会抛 `ArrayIndexOutOfBoundsException`?

A. `s[0]`B. `s[4]`C. `s[5]`D. 不会越界

解析:长度为 5 的数组合法索引是 **0~4**;`s[5]` 越界,运行时抛 `ArrayIndexOutOfBoundsException`。

02-lang-basics-6

`a = 0` 时,表达式 `a > 0 && b()` 中方法 `b()` 会被调用几次?

A. 0 次B. 1 次C. 2 次D. 编译错误

解析:**`&&` 短路**:左边为 false 时结果已确定为 false,右边 `b()` 根本不求值。`&` 才不短路。

02-lang-basics-7

方法 `void f(int n)` 内部执行 `n = n * 2;`,调用后实参的值会改变吗?

A. 会,实参被翻倍B. 不会,Java 是传值:形参只是实参的拷贝C. 看编译器决定D. 只有 final 变量才不变

解析:**Java 只有传值**:基本类型传的是数值拷贝,改形参不影响实参。引用类型传的是地址拷贝——能改对象内容,但不能让实参指向新对象。

03-oop-overview-1

下列**不属于**面向对象核心概念的是( )

A. 封装B. 继承C. 多态D. 顺序执行

解析:顺序执行是面向过程的特征;封装、继承、多态是面向对象的三大支柱。

03-oop-overview-2

`Dog d = new Dog();` 中,变量 `d` 里存的是( )

A. 对象本身B. 对象在堆上的引用(地址)C. 类名D. 构造方法

解析:new 在堆上创建对象,局部变量 d 只保存指向它的引用——所以两个引用可以指向同一对象。

03-oop-overview-3

「模拟服务大厅」案例中,`Customer` 类的主要属性可能是( )

A. 姓名、排队号B. 机器指令C. 内存地址D. 函数指针

解析:抽象类的属性来自现实实体的共同特征:顾客有姓名、持有一张号票的号码。

03-oop-overview-4

构造方法的特征是( )

A. 必须有返回类型B. 与类同名、无返回类型,用于初始化对象C. 可以重载为任意名字D. 只能有一个

解析:构造方法与类同名、没有返回类型(连 void 都没有),专门在 new 时初始化对象;它可以重载。

03-oop-overview-5

`package` 声明的主要作用不包括( )

A. 组织类B. 避免命名冲突C. 控制访问D. 提高运行速度

解析:包是命名空间与访问控制机制,不改变程序运行速度。

03-oop-overview-6

类与对象的关系最准确的描述是( )

A. 类是对象的模板,对象是类的实例B. 对象是类的模板,类是对象的实例C. 两者完全等价D. 对象包含类

解析:类抽象同类事物的共同特性(模板),对象按类创建出来的具体个体(实例)。

04-encapsulation-inheritance-1

把属性设为 private 并提供 public getter/setter 的目的是( )

A. 让程序运行更快B. 数据保护:外部只能经受控入口访问/修改,便于校验C. 避免使用 newD. 让对象变成静态的

解析:封装的核心:隐藏内部状态,对外只暴露受控接口,在方法里做校验后再改数据,防止被误改。

04-encapsulation-inheritance-2

default(不写修饰符)与 protected 的关键区别是( )

A. 完全一样B. default:同包可见、异包子类继承不到;protected:同包不可见、子类可以C. protected 只能修饰方法D. default 比 private 更严格

解析:两者在「同包」和「异包子类」两个上下文恰好相反,是访问控制最常考的辨析点。

04-encapsulation-inheritance-3

子类继承父类后,下面哪个说法正确?

A. 只能继承私有成员B. 可以继承 public/protected 的字段与方法,但构造器不会被继承C. 完全不能继承任何内容D. 必须重写所有方法

解析:子类继承父类可访问的(public/protected)字段和方法;构造器不会被继承——子类要自己定义构造器。

04-encapsulation-inheritance-4

Java 中一个类最多能 extends 几个父类?

A. 0 个B. 1 个C. 2 个D. 任意多个

解析:Java 是单继承:一个类只能 extends 一个直接父类。要复用多份能力,用接口(implements)。

04-encapsulation-inheritance-5

子类方法「签名与父类完全相同、重新实现」称为?

A. 重载(Overload)B. 覆盖/重写(Override)C. 隐藏(Shadow)D. 组合

解析:覆盖发生在子类与父类之间、签名相同;重载发生在同一个类内部、参数列表不同。

04-encapsulation-inheritance-6

`Printer is-a Device`、`Printer has-a InkCartridge` 分别表示( )

A. 都是继承B. 前者继承关系,后者包含(组合)关系C. 前者组合,后者继承D. 两者都无关系

解析:is-a 用 extends 表达继承;has-a 用成员引用表达组合——两种不同的复用手段。

05-interface-polymorphism-1

`Animal a = new Dog();` 后调用 `a.speak()`(Dog 已重写),执行的是?

A. Animal 的版本B. Dog 的版本(运行期按实际对象类型动态绑定)C. 编译报错D. 两个都执行

解析:上转型后,被重写的方法在运行期按实际对象类型分派——这正是多态。

05-interface-polymorphism-2

实现多态的必要条件**不包括**( )

A. 继承B. 方法重写C. 向上转型D. 方法重载

解析:多态三条件:继承 + 重写 + 向上转型;重载是同名不同参,与多态分派无关。

05-interface-polymorphism-3

Java 中用于定义接口的关键字是( )

A. classB. interfaceC. abstractD. implement

解析:interface 声明接口;类用 implements(带 s)实现它。

05-interface-polymorphism-4

接口中的方法默认是( )的

A. public staticB. public abstractC. private finalD. protected default

解析:接口方法默认 public abstract——只有声明、没有实现。

05-interface-polymorphism-5

类实现多个接口的写法是( )

A. extends A, BB. implements A, BC. inherits A, BD. uses A, B

解析:一个类可以实现多个接口,从而获得「多继承」效果;但只能 extends 一个父类。

05-interface-polymorphism-6

实现接口时漏写 `public` 会怎样?

A. 运行期警告B. 编译报错(视为缩小访问权限)C. 自动补上 publicD. 方法变成 static

解析:接口方法默认 public,实现类必须保持 public,否则「缩小访问权限」编译失败。

05-interface-polymorphism-7

`IUsb dev = new Phone();` 后 `dev.connect()` 执行的是?

A. 接口里的实现B. Phone 的 connect()(动态绑定)C. 编译错误D. 随机选一个

解析:接口变量指向实现类对象,调用时按实际对象类型分派——接口回调是多态的体现。

05-interface-polymorphism-8

关于接口与抽象类,正确的是( )

A. 一个类只能实现一个接口B. 接口可以有普通成员变量C. 不相关的类可以实现同一接口D. 接口可以定义构造方法

解析:接口与实现类不构成继承体系,手机和宠物这类不相关对象也能共同实现 IUsb;接口无构造方法、变量只能是常量。

06-exception-inner-1

Java 中用于抛出异常的关键字是( )

A. tryB. catchC. throwD. class

解析:throw new XxxException(...) 显式抛出;方法签名用 throws 声明可能抛出的异常类。

06-exception-inner-2

内部类是指定义在( )中的类

A. 方法内B. 另一个类内C. 包中D. 接口中

解析:定义在另一个类内部的类,可直接访问外围类所有成员(含 private)。

06-exception-inner-3

捕获异常使用的代码块是( )

A. try-catchB. if-elseC. for-eachD. switch-case

解析:try 包裹可能出错的代码,catch 处理对应异常,finally 执行清理。

06-exception-inner-4

多异常 catch 中,子类与父类的顺序是( )

A. 父类在前B. 子类在前C. 随意D. 只能写一个

解析:子类在前、父类在后;父类在前会让后面的子类分支不可达 → 编译报错。

06-exception-inner-5

关于内部类,正确的是( )

A. 不能访问外围类的 private 成员B. 可直接访问外围类所有成员(含 private)C. 必须用 public 修饰D. 编译后与外围类无关

解析:内部类最大便利就是直接访问外围类成员(含 private);编译产物为 Outer$Inner.class。

06-exception-inner-6

匿名类适合什么场景?

A. 长期复用的核心类B. 只使用一次的监听者/回调C. 定义常量D. 替代继承

解析:没有名字、创建时定义类体,适合一次性监听者;不宜过长,可读性较弱。

07-gui-basics-1

Swing 组件所在的包是( )

A. java.awtB. javax.swingC. java.ioD. java.net

解析:AWT 在 java.awt,Swing 在 javax.swing——组件以 J 打头。

07-gui-basics-2

GUI 程序中的事件通常由( )触发

A. 用户操作或系统事件B. 线程调度C. 数据库查询D. 文件读写

解析:GUI 是事件驱动的:点击、输入等用户操作产生事件,由监听器响应。

07-gui-basics-3

Swing 组件通常继承自( )体系

A. Component / JComponentB. ThreadC. ExceptionD. Runnable

解析:组件的公共属性/方法(大小、位置、字体、颜色、可见性)都来自 Component/JComponent。

07-gui-basics-4

GUI 设计四步的正确顺序是( )

A. 注册事件→建容器→加组件→设外观B. 建容器→加组件→设外观→注册事件C. 设外观→注册事件→建容器→加组件D. 加组件→建容器→注册事件→设外观

解析:先有外层容器与布局,再放组件、调外观,最后绑定事件响应。

07-gui-basics-5

`JButton` 相比 AWT `Button` 的明显优势是( )

A. 只能显示图标B. 可同时显示文字与图标C. 不需要事件监听D. 不能放进容器

解析:Swing 组件功能更强、更美观——JButton 支持文字+图标同时显示。

07-gui-basics-6

在画布上绘制图形时,充当「绘图笔」的类是( )

A. FontB. ColorC. GraphicsD. Image

解析:所有绘制都通过 Graphics 对象完成:drawLine/drawRect/drawOval/drawString…;Font/Color/Image 分别是字体、颜色、图像素材。

07-gui-basics-7

Swing 中处理按钮点击事件的监听器接口是( )

A. ActionListenerB. MouseListenerC. KeyListenerD. WindowListener

解析:Button 响应 ActionEvent,监听接口为 ActionListener,关键方法 actionPerformed。

07-gui-basics-8

事件委托模型中,事件源把事件传递给( )

A. 已注册的监听器B. 容器C. 布局管理器D. 线程池

解析:事件源注册监听器;事件发生时系统把事件对象交给已注册的监听器处理——源与处理器分离,便于扩展复用。

07-gui-basics-9

BorderLayout 的五个区域不包括( )

A. CENTERB. NORTHC. CORNERD. SOUTH

解析:BorderLayout 只有 NORTH/SOUTH/EAST/WEST/CENTER 五个区域,没有 CORNER。

07-gui-basics-10

容器使用 FlowLayout,窗口变窄时组件会( )

A. 保持单行被压缩B. 换到下一行、每行重新居中C. 重叠在左上角D. 自动隐藏

解析:FlowLayout 一行放不下就换行,且每行水平居中——这正是它对窗口大小变化的适应方式。

08-applet-1

Applet 程序( )

A. 有 main() 方法自己启动B. 没有 main(),由容器加载并管理生命周期C. 必须运行在浏览器外D. 不能接收参数

解析:Applet 没有 main():容器下载字节码、new 出对象,并按页面/焦点状态调用 init/start/stop/destroy。

08-applet-2

Applet 生命周期中只执行一次的方法是( )

A. start()B. stop()C. init()D. paint()

解析:init() 与 destroy() 各只执行一次;start() ⇄ stop() 随窗口焦点交替,可多次。

08-applet-3

用户切到别的标签页再切回来,容器依次调用的方法是( )

A. stop() → start()B. destroy() → init()C. init() → destroy()D. start() → stop()

解析:失焦调 stop() 暂停,重新聚焦调 start() 恢复——start/stop 可交替多次。

08-applet-4

Applet 中读取 HTML <param> 传进来的参数用( )

A. getParameter(name)B. getArgs()C. System.getProperty()D. readLine()

解析:getParameter(String) 返回 String,无此参数返回 null——容器把外部配置交给程序。

08-applet-5

「容器」概念的核心价值是( )

A. 让程序跑得更快B. 为程序提供运行时资源并屏蔽平台差异C. 替代 Java 编译器D. 只能运行在浏览器里

解析:容器提供输入输出等基础设施、划定安全边界,使同一程序可在多种容器中运行——「一次编写,到处运行」。

08-applet-6

Applet 如今被弃用(legacy)的主要原因是( )

A. Java 语言被废除B. 现代浏览器移除了 Java 插件C. Applet 不能绘图D. JDK 不再支持 Swing

解析:浏览器移除 NPAPI 插件、JDK 17 起 java.applet 包被弃用;「程序+容器」的思想则在 HTML5/小程序等新容器中延续。

09-mvc-pattern-1

在 Erase-MVC 中,玩家按键、菜单命令(开始/暂停/继续)与 200ms Timer 心跳,最终都经哪一层进入 Model?

A. View(GameView)B. Controller(GameController)C. 组合根(EraseApp)D. GameStateListener

解析:Controller 是唯一的状态修改入口:keyPressed→board.handleKey、菜单→board.startGame/pause/resume、Timer→board.tick;View 只读重绘,Listener 只负责通知。

09-mvc-pattern-2

Erase-MVC 的 GameBoard(Model)为什么能 headless(不开窗口)做单元测试?

A. 因为它实现了 SerializableB. 因为它不含任何 AWT/Swing 依赖,只有状态与规则C. 因为它继承自 JPanelD. 因为 Controller 帮它做了渲染

解析:Model 零 AWT/Swing 依赖、只含游戏状态与规则,test/ModelTest.java 可直接构造并验证规则;旧版 GameBox 把渲染混进模型才无法脱离窗口测试。

09-mvc-pattern-3

GameBoard 状态变化(如消行计分)后,GameView 是如何被通知去重绘的?

A. GameView 用循环不断轮询 getScore()B. GameBoard 直接调用 view.repaint()C. GameBoard 触发 fireStateChanged(),经 GameStateListener 接口回调已注册监听器的 stateChanged()D. Controller 在 handleKey 后调用 repaint()

解析:Model 不持有 View 引用,只认识 GameStateListener 接口;状态变更统一 fireStateChanged(),View(构造时 addListener 注册)收到 stateChanged 再 repaint()——Model 对 Swing 零依赖。

09-mvc-pattern-4

下列哪一项最准确地描述了 GameView 与 GameBoard 的关系?

A. 通过 getter 只读访问,不修改任何模型状态B. 可以读写 GameBoard 的任意字段C. 继承自 GameBoard 并复用其渲染代码D. 完全不依赖 GameBoard

解析:View 只读 Model(getPx/getScore/getStick…),收到 stateChanged 通知后 repaint();它不修改任何游戏规则状态——这是「View 只读」的约束。

09-mvc-pattern-5

关于 Erase-MVC 的依赖方向,下列说法正确的是?

A. Model import View 类以调用 repaint()B. View 直接 new 出 ControllerC. Controller→Model、View→Model(只读)、Model→View(仅经接口回调)D. 三层互相双向依赖

解析:单向依赖:Controller 依赖 Model;View 只读依赖 Model;Model 仅经 GameStateListener 接口回调通知 View,不 import 任何 AWT/Swing 类——依赖方向可审计。

09-mvc-pattern-6

若要把 Erase-MVC 的 Swing 窗口换成 HTML5 Web 前端(游戏规则不变),主要需要重写哪一层?

A. Model(GameBoard)B. View(GameView/GameFrame)C. Controller(GameController)D. Shape

解析:View 负责渲染与窗口;换前端只重写 View 层(并重新注册为监听器),Model 的规则与 Controller 的命令入口保持不变——这正是 MVC 职责分离带来的可替换性。

09-io-1

要从文件读取一个以二进制存储的 int 值,最合适的流是( )

A. FileInputStreamB. DataInputStreamC. BufferedReaderD. ObjectInputStream

解析:DataInputStream 提供 readInt() 直接读基本类型;FileInputStream 只给原始字节需自己拼装,BufferedReader 是字符流。

09-io-2

一个对象要被 ObjectOutputStream.writeObject() 序列化,必须满足( )

A. 实现 Serializable 接口B. 继承 OutputStreamC. 重写 toString() 方法D. 是 final 类

解析:对象需 implements java.io.Serializable(标记接口),否则抛 NotSerializableException。

09-io-3

new File("a/b.txt").isAbsolute() 的返回值是( )

A. trueB. falseC. 编译错误D. 运行时异常

解析:"a/b.txt" 是相对路径,isAbsolute() 返回 false;绝对路径以盘符或根开头(如 C:\ 或 /)。

09-io-4

要按行读取一个文本文件(readLine),应使用( )

A. InputStreamB. BufferedReaderC. DataInputStreamD. ObjectInputStream

解析:readLine() 是 BufferedReader(字符输入流)的方法;字节流没有「按行」的概念。

09-io-5

给 FileInputStream 套一层 BufferedInputStream 的主要目的是( )

A. 改变文件内容B. 减少读写磁盘的系统调用次数,提升性能C. 把字节转换成字符D. 对数据加密

解析:缓冲流攒够一批再 I/O,减少频繁系统调用;它不改变内容、也不做编码转换。

09-io-6

要把字节流按 UTF-8 解码成字符流,应使用( )

A. InputStreamReaderB. FileReaderC. BufferedReaderD. PrintStream

解析:InputStreamReader(new FileInputStream(...), "UTF-8") 是字节→字符的桥梁;FileReader 不指定编码(用默认平台编码)。

09-io-7

给 Player 的 password 字段加上 transient 后,执行 writeObject(player) 时它会( )

A. 照常写入字节流B. 不写入字节流(被排除)C. 写入但被加密D. 导致编译错误

解析:transient 字段被序列化机制跳过、不占字节,常用于密码、缓存等不该持久化的数据。

09-io-8

static 字段在对象序列化时会( )

A. 随每个实例一起写入B. 不写入(它属于类,不属于实例)C. 只在文件头写一次D. 写入但值固定为默认值

解析:静态字段属于「类」而非「实例」,序列化只保存实例状态,static 字段从不被写出。

09-io-9

Player 引用了一个 Board 对象(board 字段)。要把 player 完整序列化,必须满足( )

A. 只要 Player 实现 Serializable 即可B. Board 也必须实现 SerializableC. Board 必须重写 clone()D. board 字段要加 final

解析:序列化沿引用递归整棵对象图,被引用的类(Board)同样需要 implements Serializable,否则抛 NotSerializableException。

10-thread-1

Java 中创建新线程的方式不包括( )

A. 继承 Thread 类B. 实现 Runnable 接口C. 实现 Serializable 接口D. 使用线程池

解析:Serializable 是序列化接口,与线程无关;继承 Thread、实现 Runnable、线程池都是创建/管理线程的方式。

10-thread-2

启动一个线程的方法是( )

A. run()B. start()C. sleep()D. wait()

解析:start() 让线程进入 RUNNABLE,由调度器安排执行;直接调 run() 只是普通方法调用,不会开新线程。

10-thread-3

线程调用 start() 之后进入( )状态

A. NEWB. WAITINGC. RUNNABLED. TERMINATED

解析:start() 使线程从 NEW 进入 RUNNABLE——正在执行或就绪等待调度,二者合称 RUNNABLE。

10-thread-4

同步多线程共享数据时使用的关键字是( )

A. staticB. synchronizedC. finalD. private

解析:synchronized 保证同一时刻只有一个线程执行同步方法/代码块,用于保护共享资源。

10-thread-5

死锁产生的四个必要条件包括互斥、占有并等待、____、循环等待

A. 可抢占B. 可共享C. 不可抢占D. 可中断

解析:四条件:互斥、占有并等待、不可抢占(非剥夺)、循环等待——破坏任一条件即可预防死锁。

10-thread-6

线程同步的目的是防止____条件引发的数据不一致

A. 编译B. 竞态C. 链接D. 缓冲

解析:竞态条件:多线程交替访问共享资源,结果依赖执行顺序——用 synchronized/Lock 等同步机制避免。

10-thread-7

主线程对线程 t 调用 t.join() 的作用是( )

A. 等待 t 结束后主线程才继续B. 立即终止 tC. 让 t 暂停一会儿D. 提高 t 的优先级

解析:join() 实现「联合」:调用方挂起直到目标线程结束(或超时)——如顾客等蛋糕师做完蛋糕。

10-thread-8

线程生命周期中不可恢复的终态是( )

A. BLOCKEDB. WAITINGC. TIMED_WAITINGD. TERMINATED

解析:run() 执行结束后进入 TERMINATED:线程死亡,不能再次 start();其余状态都可回到 RUNNABLE。

10-thread-9

生产者–消费者模型中,缓冲已满时生产者线程的正确做法是( )

A. 继续把产品放入缓冲B. 调用 wait() 挂起并释放锁C. 调用 sleep(100) 过一会儿再试D. 直接抛出异常退出

解析:缓冲满=条件不满足:在同步方法中调用 wait(),释放监视器锁并无限期挂起;消费者取走产品后 notifyAll() 唤醒它重新检查。

10-thread-10

线程被 notifyAll() 唤醒后、继续执行之前必须( )

A. 立即执行 wait() 之后的代码B. 重新拿到监视器锁并用 while 复查条件C. 再次调用 start()D. 释放所有资源

解析:唤醒≠条件一定满足:被唤醒的线程要重新竞争监视器锁,并用 while 循环复查条件——用 if 不复查会在多生产者场景下超产。

10-thread-11

Java 中线程优先级的取值范围是( )

A. 0 ~ 9B. 1 ~ 10C. 0 ~ 10D. 1 ~ 9

解析:Thread.MIN_PRIORITY=1、NORM_PRIORITY=5(默认)、MAX_PRIORITY=10;子线程继承创建者线程的优先级。

10-thread-12

多个就绪线程中,把某线程 t 的优先级设为 10 意味着( )

A. t 一定总是最先执行B. t 被调度的概率更高,但不保证一定先执行C. t 会立即抢占其他正在执行的线程D. t 的执行速度变快

解析:优先级只影响调度概率:JVM/操作系统不保证高优先级一定先执行;长时运行的高优先级任务还可能让低优先级线程饿死。

11-jdbc-1

在 JDBC 中,DriverManager.getConnection(...) 返回的 Connection 对象,其**实际类型**由什么决定?

A. 编译期写死的类名B. 运行期按 URL 匹配到的具体驱动实现C. 操作系统版本D. JDK 版本号

解析:Connection 是接口;DriverManager 在运行期根据 JDBC URL 从已注册驱动中挑选匹配的实现(如 MySQL 的 ConnectionImpl)——这正是多态:编译期依赖接口、运行期定实现。

11-jdbc-2

调用 Class.forName("com.mysql.jdbc.Driver") 的主要作用是( )

A. 触发驱动类 static 块,把自身注册进 DriverManagerB. 直接建立数据库连接C. 创建 Statement 对象D. 读取结果集

解析:forName 加载驱动类并触发其 static 初始化块,驱动在块内调用 DriverManager.registerDriver 完成自注册;之后 getConnection 才能按 URL 找到它。

11-jdbc-3

执行 SELECT 查询并返回一个 ResultSet 的方法是( )

A. executeUpdate()B. executeQuery()C. executeLargeUpdate()D. prepareStatement()

解析:executeQuery 用于 SELECT,返回结果集;executeUpdate 用于增删改,返回受影响行数。

11-jdbc-4

对 guestbook 表执行 INSERT / UPDATE / DELETE 时,应调用( )

A. executeQuery()B. rs.next()C. executeUpdate()D. con.close()

解析:增删改用 executeUpdate(sql),返回受影响的行数(>0 表示成功);它不返回结果集。

11-jdbc-5

下列能从根本上防止 SQL 注入的做法是( )

A. 把用户输入拼进 SQL 字符串B. 使用 PreparedStatement 预编译并用占位符 ? 传值C. 给用户输入的字符串加单引号D. 只允许管理员访问数据库

解析:PreparedStatement 把命令与数据分离:SQL 先预编译,数据通过 setXxx 以参数传入,不会被当作 SQL 执行——这是防注入的标准做法。

11-jdbc-6

JDBC 中释放资源的正确顺序是( )

A. 先关 Connection,再关 Statement/ResultSetB. 顺序无所谓C. 只需关 ConnectionD. 先关 ResultSet/Statement,再关 Connection

解析:资源释放顺序与创建相反:先关闭依赖它的 ResultSet、Statement,最后关闭 Connection——避免使用已关闭的对象。

11-jdbc-7

guestbook 表里只有 id=1、2、3 三行,执行 `stmt.executeUpdate("update guestbook set title='x' where id=9")` 的返回值是( )

A. 1B. 0C. -1D. 抛出异常

解析:executeUpdate 返回受影响行数:WHERE id=9 匹配不到任何行,所以影响 0 行、返回 0——语句本身执行成功,只是没有数据被改。

11-jdbc-8

对 UPDATE / DELETE 语句,为什么强烈建议带上 WHERE 条件?

A. 不带 WHERE 语法不合法B. 防止误改/误删整张表的所有行C. 为了查询速度更快D. 数据库强制要求

解析:不带 WHERE 的 UPDATE / DELETE 会作用在整张表的每一行上,一个手滑就可能全表被改或被删光;带上 WHERE 把影响范围限定在匹配的行内(本课程的 CRUD 实验也强制要求 WHERE)。

11-jdbc-9

执行 con.setAutoCommit(false) 之后,紧接着执行的 UPDATE 语句会怎样?

A. 每条语句执行完立即提交生效B. 变更处于未提交状态,要等 commit() 才生效C. 语句不会执行D. 只能执行 SELECT

解析:setAutoCommit(false) 关闭自动提交后,多条 SQL 组成一个事务:变更先成为「pending(未提交)」状态,只有本事务自己看得见;commit() 之后才永久生效,rollback() 则会被全部丢弃。

11-jdbc-10

转账事务里 A 扣款成功、B 加款时抛出异常,正确的处理是( )

A. 忽略异常继续执行后续操作B. 调用 con.rollback(),把 A 的扣款也撤销C. 等程序结束后再手工改回 A 的余额D. 直接删除 B 的账户

解析:事务要求「全成功或全失败」(原子性):任一步失败就在 catch 里 con.rollback(),所有未提交变更(包括已成功的 A 扣款)被丢弃,数据回到事务开始前的状态——这正是转账场景必须用事务的原因。

12-collections-1

Java 集合框架中,保证元素**唯一、不允许重复**的接口是( )

A. ListB. SetC. MapD. Queue

解析:Set 接口语义就是「无序、不重复」:add 一个已存在的元素会被忽略(返回 false),由 equals() 判定是否重复。

12-collections-2

HashMap 实现的是哪个接口?

A. ListB. SetC. MapD. Collection

解析:HashMap 是 Map 接口的哈希表实现;注意 Map 不属于 Collection 体系,它有自己的 put/get/remove/keySet/entrySet。

12-collections-3

List 与 Set 的主要区别是( )

A. List 有序且允许重复,Set 无序且不重复B. List 不重复,Set 可重复C. 两者完全相同D. Set 支持按下标访问

解析:List:有序、允许重复、按下标访问;Set:无序、不重复、自动去重。这是集合选型的第一道分叉。

12-collections-4

已知 Map<String,Integer> scores = new HashMap<>(); scores.put("Tom",88);,则 scores.get("Jerry") 的返回值是( )

A. 88B. 0C. nullD. 抛出异常

解析:get(key) 按 key 取 value:key 不存在时返回 null(不抛异常)。"Jerry" 从未 put 过,所以是 null。

12-collections-5

用 List<String> list = new ArrayList<String>(); 声明集合后,list.get(0) 不需要强转的原因是( )

A. 运行时集合会自动把元素变成 StringB. 泛型参数在编译期指定了元素类型,编译器保证取出即 StringC. ArrayList 内部只存字符串D. Java 规定 get 永远返回 Object

解析:泛型是编译期机制:List<String> 让编译器知道 get 返回 String,自动处理强转;运行时字节码里类型参数已被擦除。

12-collections-6

Java 的类型擦除意味着:编译后 List<String> 在字节码中变成( )

A. List<String>(原样保留)B. 裸的 List,元素按 Object 处理C. String[] 数组D. Map<String,String>

解析:类型擦除:泛型参数在编译后被去掉,字节码里只剩裸 List;运行时无法区分 List<String> 与 List<Integer>——所以泛型检查只发生在编译期。

12-collections-7

已知 List<String> strings = new ArrayList<>(); strings.add("Tom");,接着写 List raw = strings; raw.add(123);(能编译通过),则执行 String s = strings.get(1); 时会( )

A. 返回 123B. 返回 nullC. 抛出 ClassCastExceptionD. 编译错误

解析:类型擦除后运行时没有类型检查:原始类型 raw 绕过编译期检查,Integer 被混进集合;取回时编译器插入的 (String) 强转失败,抛 ClassCastException。

12-collections-8

与 ArrayList 相比,数组(如 int[])的优势是( )

A. 长度可以动态增长B. 自带 add() / remove() 等内置操作C. 可以直接存基本类型、无需装箱D. 支持泛型声明

解析:数组能直接装 int/char 等基本类型,无装箱开销;集合只能装对象(数字要装箱成 Integer)。动态增长与内置操作是集合的优势,不是数组的。

12-collections-9

HashMap 中,当某个桶里的链表长度达到多少时,JDK 会把它转成红黑树?

A. 4B. 8C. 16D. 32

解析:JDK HashMap 的 TREEIFY_THRESHOLD=8:一条链长到 8 就转红黑树,把该桶最坏查找从 O(n) 拉回 O(log n)。链表阶段是 O(n),冲突越多越慢。

12-collections-10

HashMap 里 `put(key, value)` 后,key 落在哪个桶主要由什么决定?

A. key.hashCode() 对桶数取模(hashCode() % n)B. 插入的先后顺序C. value 的大小D. 随机分配

解析:put 时先算 key.hashCode(),再对桶数取模定位桶;同桶的 key 挂成链表。所以 hashCode() 设计得好(分布均匀)HashMap 才快——这也是为什么重写 equals() 通常要同时重写 hashCode()。

13-network-1

在 Java Socket 编程中,负责**监听端口、等待客户端接入**的是哪个类?

A. SocketB. ServerSocketC. InputStreamD. URL

解析:ServerSocket 绑定端口并进入监听;accept() 阻塞等待,每来一个客户端就返回一个新的 Socket。普通 Socket 是客户端用来主动连接服务端的。

13-network-2

服务端调用 serverSocket.accept() 的作用是( )

A. 关闭服务器B. 为当前接入的客户端返回一个专属 SocketC. 直接读取数据内容D. 向所有客户端广播

解析:accept() 阻塞直到有客户端连上,然后返回一个代表这条连接的 Socket;服务端通常随即为它起一个线程处理收发(网络版 ERASE 的 ServThreadPerClient)。

13-network-3

TCP 建立连接时的三次握手顺序是( )

A. SYN → SYN-ACK → ACKB. ACK → SYN → SYN-ACKC. SYN → ACK → SYN-ACKD. 连续三个 ACK

解析:客户端先发 SYN,服务端回 SYN-ACK(确认并给出自己的序号),客户端再发 ACK;三步完成后连接才正式建立。TCP 面向连接、可靠有序。

13-network-4

Java 里通过 Socket 发送一个对象时,应使用( )

A. os.writeObject(obj)B. out.println(obj)C. System.out.print(obj)D. obj.send()

解析:writeObject() 把实现了 Serializable 的对象序列化成字节写入输出流;对端用 readObject() 还原。网络版 ERASE 每帧发的就是 PlayInfo 对象。

13-network-5

网络版 ERASE 里,服务端为**每个接入的客户端**各起一个线程(ServThreadPerClient)处理收发,这主要体现了哪个模块的知识?

A. 集合框架与泛型B. 多线程机制C. 数据库 JDBCD. 图形用户界面

解析:accept() 返回后立刻 new Thread(...) 处理该客户端——每个客户端一条线程并发收发,正是模块7 多线程 + 网络结合落到真实项目。

13-network-6

客户端要向服务端**发送**数据,应使用( )

A. clientSocket.getInputStream()B. clientSocket.getOutputStream()C. serverSocket.accept()D. new ServerSocket(port)

解析:发数据走输出流 getOutputStream()(writeObject / flush);收数据走输入流 getInputStream()(readObject)。方向别搞反——输出流是「出去」。

13-network-7

开发**实时视频通话**应用时,传输层协议更适合选( )

A. TCP,因为可靠必达B. UDP,因为延迟低、丢一帧可接受C. 必须 TCP,UDP 不能传音视频D. 两者完全一样

解析:实时音视频是「速度优先」场景:新画面帧到了旧帧直接丢弃,重传早已过时的帧毫无意义——UDP 不建连、无确认、头部小,延迟最低。要保序保真(网页/聊天/对战)才选 TCP。

13-network-8

TCP 能保证数据**按发送顺序**到达接收方,靠的是( )

A. 每个分段带序号 + 确认重传机制B. UDP 式的广播传输C. 应用层自己排序D. 端口号大小决定顺序

解析:TCP 为每个分段编号,接收方按序号重组;丢了由确认+重传补上——所以数据既必达又有序。UDP 各数据报独立传输,到达顺序可能与发送顺序不一致。

13-network-9

CodePlayground 前端把 Java 源码提交给后端编译运行、并接收回传的结果,采用的传输方式是( )

A. WebSocket + STOMP(全双工,后端可主动推送结果)B. 普通 HTTP GET 轮询C. 表单 POST 后刷新页面D. 下载一个 jar 包到本地运行

解析:编译+运行耗时数秒:普通 HTTP 请求只能傻等或轮询;WebSocket 是全双工通道,后端跑完立刻经 STOMP 目的地(user/queue/result)把结果推回前端,无需轮询。

13-network-10

在 CodePlayground 里提交一段含 `for(;;){}` 死循环的程序,沙箱最可能返回的状态是( )

A. ok(跑完为止)B. timeout(超时后强杀整棵进程树)C. compile_error(javac 报错)D. runtime_error(抛出异常)

解析:死循环编译能通过、运行时也不会抛异常,只会一直跑——沙箱对运行设了时间上限(默认 10 秒),到点强杀进程树并返回 timeout,服务端不会被拖死。

13-network-11

TCP 三次握手中,**第三步**由客户端发送的报文是( )

A. SYNB. SYN-ACKC. ACKD. RST

解析:顺序是:① 客户端发 SYN → ② 服务端回 SYN-ACK → ③ 客户端再发 ACK。第三步的 ACK 确认后,两端才同时进入 ESTABLISHED。SYN 是第一步、SYN-ACK 是第二步都由对方发起。

13-network-12

客户端向一个**没有服务在监听**的端口发起连接,服务端最可能回( )

A. SYN-ACKB. ACKC. RST(复位)D. FIN

解析:端口无对应服务时,内核直接回 RST(Reset)报文,客户端表现为 Connection refused——连接被复位、未建立。正常三次握手才会出现 SYN-ACK / ACK。