20192306 2019-2020-2《数据结构与面向对象程序设计》课程总结
20192306 2020-2021-1 《数据结构与面向对象程序设计》课程总结
一、课程内容总结
1. 第一章 绪论
1.1 Java程序设计语言
-
Java平台:Java SE、Java EE、Java ME
-
类定义: public class XXX{};
-
main方法的定义是固定的:public static void main(String [] args){}
-
注释://单行;/* */多行
-
标识符和保留字
- 常见的标识符有:class、public、static、void、main、String、args、System、out、println等,我们命名的在程序中使用的标识符可以由任意字母、数字、下划线和美元符号组成,但不能以数字开头。
- 常见的保留字有:package、this、do、if、throw、boolean、double、protected、else、import等。
- 空白:包括空格、制表符和换行符。
1.2 程序开发
- 程序设计语言
- 机器语言:取决于CPU
- 汇编语言:机器语言的助记符
- 高级语言:可移植
- 第四代语言
- 三类错误
- 编译时错误:语法错误
- 运行时错误:异常处理
- 逻辑错误:可通过调试来定位错误
1.3 问题求解
-
理解问题
-
设计方案
-
考虑方案的选择并优化方案
-
实现方案
-
测试方案并修改存在的问题
1.4 软件开发行为
- 四个基本的开发行为:
- 建立需求:做什么?
- 生成设计:如何做?
- 实现设计:设计到代码
- 测试:做对没?
- 三种代码
- 伪代码
- 产品代码
- 测试代码
1.5 面向对象程序设计
- 基本术语:
- 对象
- 属性
- 方法
- 类
......
- 面向对象三要素:封装,继承,多态
2. 第二章 数据和表达式
2.1 字符串
- print及print方法
- Systom.out对象表示输出设备或是文件,默认时指的是屏幕。
- println将光标换到下一行的行首。(printf)
- print输出之后不会换到下一行。(print)
-
字符串连接:"+"。(“qqwrtt”+“asdfgg”)
-
转义字符
- \b:回退键
- \t:制表符
- \n;换行
- \r:回车
- \ ":双引号
- \ ':单引号
- \ \:反斜杠
2.2 变量和赋值
- 赋值:=
2.3 基本数据类型
-
8 种基本类型(byte,short,int,long,float,double,boolean,char)
-
6种数字类型(byte,short,int,long,float,double)
-
4种整数类型(byte,short,int,long),
-
char占两个字节
-
boolean只有true和false
2.4 表达式
-
算术运算:+、-、*、/、%
-
关系运算:、>、>=、<、<=、==、!=
-
逻辑运算:&&、||、!
-
运算符优先级:从左到右的结合律,具有相同优先级的算术运算符从左到右依次计算。表达式中的优先级可以通过圆括号来改变。
-
自增,自减:i++、i--
2.5 数据转换
-
基本类型之间的转换:加宽转换与缩窄转换。
-
赋值转换
-
提升
-
强制类型转换
2.6 读输入数据
-
输入System.in
-
输出System.out.println
3. 第三章 使用类和对象
3.1 创建对象
new:返回指向新建对象的引用
3.2 String 类
-
String (String str)
-
char charAt (int index)
-
int compareTo (String str)
......
3.3 包
Java标准类库中的类按包来组织。每个类都属于一个具体的包。详情查字典。
3.4 Random类
3.5 Math类
用Math.XXX()来调用。
3.6 格式化输出
-
NumberFormat:有两个方法getCurencyInstance和getPercentInstance返回用于格式化数值的对象。getCurencyInstance返回货币格式对象,getPercentInstance返回百分比格式对象。
-
DecimalFormat:按惯例使用new运算符来实例化对象。
-
print,println,printf方法。
3.7 枚举类型
-
列出这个类型的变量的所有可能取值。
-
常用enum。
3.8 包装类
-
包装类是一种特殊的基本类型,能够按对象的方式处理基本类型。
-
自动包装与拆包。
4. 第四章 条件和循环
4.1 布尔表达式
- 控制流:顺序(存储程序)、分支(条件语句,特殊情况、循环(自动化)
4.2 if语句
-
if
-
if...else
-
if...else if ... esle
4.3 数据比较
-
浮点数的比较:计算两个差值的绝对值,在与公差进行比较。
-
字符比较:Unicode顺序,大小写字母,数字要联系ASCII表中的编码。
-
对角比较:equals。
4.4 switch语句
switch(){
case :
case :
default:
}
4.5 while语句
-
break可以跳出多重循环。
-
continue语句也类似,但是要再次计算循环条件,如果仍未真,则再次执行循环体。
4.6 迭代器
迭代器也是一个对象,可以使用它的一些方法每次处理集合中的一个元素。也就是说,迭代器可以按需一项项地处理每一个元素。
4.7 do 语句
4.8 for 语句
5. 第五章 编写类
5.1 再谈类和对象
-
类:属性(变量/常量)+方法(函数)。
-
类是对象的抽象\蓝图,对象是类的实例化。
5.2 类的剖析
UML类图:实现、关联、聚合、组合、继承。
5.3 封装
public、private
5.4 方法的剖析
-
return:返回值
-
局部数据:作用域只在其声明所在的方法内。
5.5 静态类成员
-
静态变量(static):有时也称类变量,它由类的所有实例共享,在一个对象中修改静态变量的值,就等于修改了其他所有对象中该静态变量的值。
-
静态方法:不需要为了调用方法而实例化类的一个对象,只能访问静态变量或局部变量。
5.6 类关系
UML类图
5.7 方法设计
5.8 方法重载
-
参数类型与数量
-
不管返回值
5.9 测试
-
评审
-
缺陷测试:发现错误,质量保证
-
单元测试:模块测试,确保方法的正确性
-
集成测试:系统大组件的正确性
-
系统测试:与需求保持一致性
-
测试驱动开发,在编写方法前先编写测试用例,从而为正在开发的系统提供功能。
5.10 调试
6. 第六章 图形用户界面
6.1 GUI元素
-
三类对象:组件、事件、QieTing器。
-
使用GUI编写java程序
- 实例化并建立必要的组件
- 定义当具体事件发生时的对策从而实现侦听器类
- 建立侦听器与产生感兴趣的事件各组件之间的联系
-
四要素:组件、容器、布局、事件
-
框架和面板
框架可以作为独立的窗口显示,但面板只能作为另一个容器的一部分来显示
6.2 更多的组件
-
文本域
-
复选框
-
单选按钮
-
滑动条
-
组合框
6.3 布局管理器
GUI的外观有包含层次及每个容器的布局管理器来确定
-
流布局管理器
-
边界布局管理器
-
网络布局管理器
-
盒子布局管理器
-
包含层次
6.4 鼠标和键盘事件
6.5 对话框
6.6 一些重要细节
-
边框:给组件分组并引起注意。
-
提示工具和助记符:在不适合使用的时候,应该让组件失败。
6.7 GUI设计
- 基本准则
- 了解用户
- 预防用户的错误
- 优化用户的能力
- 一致性
- 任何GUI的设计应坚持一致性和实用性相结合的基本原则。
7. 第七章 数组
7.1 数组元素
从0开始,0到length-1
7.2 数组的声明及使用
-
用new实例化,指定大小,之后数组大小不能改变。如:int [] arr = new int[1127]
-
Java中访数组元素不能越界,用数组的length属性控制,
-
第一次声明数组可以使用初值表代替new实例化数组
7.3 对象数组
对象数组的实例化,只是分配了保存引用的空间,每个元素中保存的对象还必须分别实例化。
7.4 命令行参数
args[0]的值是类名,args是字符串数组。
7.5 变长参数表
7.6 二维数组
8. 第八章 继承
8.1 创建子类
-
extends继承,Java只支持单继承
-
super与this常用于调用构造方法
-
抽象类继承
8.2 方法的重写
- 定义上的区别:
- 重载是类中关系,指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。
- 重写是类间关系,指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。
8.3 类层次
-
类层次中公共特性放父类中
-
Object类是所有类的父类
-
abstract抽象类达抽象概念,不能用new实例化
-
抽象类的子类:实现父类的抽象方法变成具体类,不实现父类抽象方法仍要用abstract修饰
8.4 可见性
8.5 设计继承
9. 第九章 多态
9.1 后绑定
-
多态引用在不同的时候可以指向不同类型的对象
-
多态引用运行时才将方法调用与它的定义绑定在一起
9.2 通过继承实现多态
引用变量可以指向声明继承于它的任意类的任何对象
9.3 接口
-
interface,implements 等价于class,extends
-
接口是一组抽象方法,与抽象类一样不能被实例化
-
接口层次:接口可以继承接口;类可以实现接口,但不能继承接口。
-
Comparable接口:compareTo()
9.4 通过接口实现多态
-
和class一样,接口可以用来声明对象引用变量
-
接口引用可以指向实现这个接口的任意类的作何对象
-
方法的参数可以是多态的
10. 第十章 异常
10.1 异常处理
-
错误和异常代表不常见的或不正确处理的对象
-
错误不用捕获
-
处理异常:在异常发生的地方处理;在程序的其他地方处理
10.2 不捕获异常
-
程序中出现异常不捕获异常,程序会崩溃
-
调用栈跟踪:第一行给出原因,异常类型;栈的第一行给出产生异常的代码(这个般就是产生异常的原因)
10.3 try-catch 语句
-
Java中把正常流程放try块中,错误(异常)处理放catch块中
-
每个catch子句处理try块中可能抛出的一种特定类型的异常
-
注意多个catch一定把父类放后面处理
-
finally:总会执行,用于资源管理
10.4 异常传播
-
如果没有在异常发生处捕获及处理,异常会被传播给调用的方法
-
catch
-
throw:方法中抛出Checked Exception,方法声明中必须有throws。
10.5 异常类的层次
-
Error及其子类写程序不用处理
-
Java异常处理是要处理Exception类及其子类:
-
RuntimeException及其子类也不用处理(Unchecked Exception),是免检异常;
-
产生RuntimeException的问题在调用代码
-
Multi-catch:类之间不能有继承关系
-
自定义异常
10.6 I/O异常
-
几乎所有的IO API都可能抛出异常
-
异常:除0、数组越界、找不到类、找不到方法……
-
流:字节流、字符流
-
标准流:System.in、System.out、System.err
11. 第十一章 递归
11.1 递归思想
11.2 递归程序设计
11.3 使用递归
12. 第十二章 算法分析
12.1 算法效率
12.2 增长函数和大O符号
计算复杂度
12.3 比较增长函数
13. 第十三章 查找与排序
13.1 查找
-
线性查找:可以设置哨兵提高查找效率。
-
二分查找:从中间开始,要求表是有序的,每次比较后可以减少查找池中的一半元素。
-
分块查找:先二分查找,再线性查找。
-
哈希查找:直接通过关键字找到存储地址,是的查找时间可以常数级。
-
散列查找
13.2 排序
-
选择排序:分别将每个值放在排好序的最终位置,从而完成一组值的排序。
-
插入排序:将一个具体的值插入到表中已有序的子系列中,从而完成一组值的排序。
-
冒泡排序:重复地比较表中的相邻元素,如果它们不符合要求则交换他们。
-
快速排序:根据一个任意选定的划分元素来对表进行划分,然后再递归地对划分元素两边的字段进行排序,从而完成对表的排序。
-
归并排序:递归地对分表,知道每个子表只含有一个元素时为止,然后再将子表按序合并,从而完成对表的排序。
13.3 分析查找和排序算法
-
考虑当问题大小增大时算法的渐进复杂度。
-
考虑每个算法的最优情形和最差情形。
14. 第十四章 栈
14.1 集合的介绍
-
集合是收集并组织其他对象的对象,它定义了访问及管理成为集合元素的其他对象的而一种具体方式。
-
集合中元素之间的组织方式通常由它们加入集合的次序和元素之间的某些固有的关系决定。
14.2 栈集合
-
后进先出
-
push将元素添加到栈顶
-
pop删除栈顶元素
-
peek查看栈顶元素
-
isEmpty判断栈是否为空
-
size判断栈中元素的个数
14.3 继承、多态和泛型
14.4 栈的ADT
栈接口定义为Stack,是对泛型T进行操作的。
14.5 使用栈:计算后缀表达式
-
计算机容易识别后缀表达式。
-
可用栈操作
- 从左到右扫描表达式
- 操作数入栈
- 遇到操作符则pop两个数计算后再push。
14.6 异常
- 后缀表达式计算中潜在的异常情况:
- 入栈时栈满
- 出栈时栈空
- 扫描完表达式时栈中的值多于1个
14.7 使用数组实现栈
14.8 ArrayStack类
定义ArrayStack类来表示基于数组实现的、可保存泛型T对象的栈集合。
14.9 将引用作为链
与有固定大小的数组不一样,链表没有容量上限,被看成是一个动态结构,它的大小总随着所保存的元素个数在变大或变小。
14.10 管理链表
-
访问元素
-
插入结点
-
删除结点
-
哨兵结点
14.11 没有链的元素
-
定义一个独立的结点类,用来将元素连在一起。
-
双向链表。
14.12 使用链实现栈
- 链表实现栈
- 插入/删除都在栈顶
- Top指向栈顶元素
- 数组可以随机存取,随时取得某个数,但是链表必须从头开始
- 需要遍历链表while(head != null){操作};
14.13 使用java.util.Stack 类实现栈
14.14 包
15. 第十五章 队列
15.1 队列ADT
-
队列是一个线性集合,它在一端添加元素,在另一端删除元素————先进先出。
-
接口中一般有以下功能:
- enqueue:将元素插入到队尾。
- dequeue:从队头删除元素。
- first:检测队头的元素。
- isEmpty:判定队列是否为空。
- size:断定队列中的元素个数。
15.2 使用队列:编码K值
Caesar密码
15.3 使用队列:模拟票务柜台
提出假设、模拟实现
15.4 实现队列:使用链表
使用LinearNode对象的链表实现队列,必须在链表的两段进行操作,还要用一个整型变量count记录队列中的元素个数。
15.5 实现队列:使用数组
使用一个循环数组来实现队列,定义类Circular-ArrayQueue。将数组当做一个环来使用,第一个下标接在最后一个下标的后面。
16. 第十六章 树
16.1 树
节点+边
-
子节点
-
兄弟结点
-
满二叉树
-
完全二叉树
16.2 树的遍历
-
先序遍历
-
中序遍历
-
后序遍历
-
层序遍历
16.3 树的实现策略
数组
16.4 二叉树的实现
16.5 决策树
简单的决策树可用一棵二叉树来表示。诊断时,从根节点的问题开始,根据答案选择适当的路径直至到达叶结点。
17. 第十七章 二叉查找树
17.1 二叉查找树
- 查找类:
- getRoot()返回根节点
- getParent()返回父结点
- getChildCount返回孩子结点数
- getFirstChild()返回第一个孩子结点
- getNextChild()返回下一个兄弟结点
- isEmpty()判定树是否为空树
- depth()求树的深度
- traverse()遍历树
- 插入类:
- tree()构造函数,初始化置空数
- assign()给当前结点赋值
- insert()插入操作,可以是结点或子树
- 删除类:
- makeEmpty()将树清空
- Delete()删除操作,可以是节点或子树
17.2 二叉查找树的实现
17.3 平衡二叉查找树
18. 第十八章 队和优先队列
18.1 堆
完全二叉树
-
addElement(),向堆中添加一个新元素。
-
removeMin(),删除最小值,并重构堆。
-
removeMax(),删除最大值,并重构堆。
-
findMin(),寻找最小值。
18.2 堆的实现
18.3 堆排序
-
可以使用数组形式,用顺序结构存储最为合适。
-
最小堆(小顶堆)
-
最大堆(大顶堆)
18.4 优先队列
具有相同优先级的项按先进先出的规则排列。
19. 第十九章图
19.1 无向图
图中表示边的顶点对是无序的图是无向图,意味着两点间的连接是双向的。
19.2 有向图
图中的边是顶点的有序对的图为有向图,意味着有向图的边是有方向的边。
19.3 带权图
图中每条边都对应一个权值的图成为带权图,有时也称为网络。
19.4 常用的图算法
-
广度优先遍历
-
深度优先遍历
-
无向图的最小生成树(Prim、Kruscal)
-
有向图的拓扑排序
-
有向图的最短路径求解(迪杰斯特拉)
19.5 图的实现策略
-
邻接表
-
邻接矩阵
二、作业总结
作业1:安装虚拟机
作业2:第一周作业
- 对专业的认识和期望
- 虚拟机安装
- Linux命令的学习
- 实验楼Linux命令实践学习
作业3:使用VIM编辑器编写Java程序
- 任务1:使用VIM编辑器编写Java程序。要求输入2个Int类型的数值m和n,当m不为0时,计算(m!)+(m的n次方),并输出。当m为0时提示重新输入。
- 任务2:使用VIM编辑器编写Java程序。要求输入1个Int类型的数值n。当m>0时,输出一个m行的三角形(丑或漂亮的三角形都行)。当m小于等于0时提示重新输入。
作业4:编写简单的类
- 编写一个类(书、人、动物、汽车、球员、游课程、戏角色等),定义类的属性和方法。
- 编写测试类(暂用包含main方法的类),new一个上面类的对象并初始化,然后调用类的属性和方法。
- 编译运行通过,代码传到码云。
作业5:复数计算器
实现复数类加减乘除运算和比较大小,要求使用Comparable接口、要求自定义接口、要求使用继承。
作业6:类继承作业
编写一个类,要求实现继承,可以以游戏、书籍、球员、复数等为例。
- 必须包含至少1个抽象方法。
- 必须测试,测试参数来自命令行参数。
- 简单测试一下Object类的方法。
- 要求能够实现两个对象的比较(Comparable接口)
作业7:栈实践
用数组实现自己的栈,ArrayStackADT,需要包含栈的常规操作(push、pop、peek、size、isEmpty等),并测试。
作业8:二分查找实践
给Searching类添加二分查找算法的递归实现方法。创建驱动程序来演示这个实现机制。
- 编程实现递归。
- 创建一个测试类,测试递归实现的二分查找是否正确。
作业9:排序
使用选择和插入排序法,写出第3次排序的结果:3 1 9 3 6 2 10。
作业10:查找及ASL作业
给定关键字序列19 14 23 1 68 20 84 27 55 11 10 79,试分别用顺序查找、折半查找、二叉排序树查找、散列查找(用线性探查法和链地址法)来实现查找。试画出它们的对应存储形式(顺序查找的顺序表,二分查找的判定树,二叉排序树查找的二叉排序树,两种散列查找的散列表),并求出每一种查找的成功平均查找长度。其中,散列函数H(k)=k%13。
作业11:树计算
- 有1023个结点的完全二叉树,其高度是多少?叶结点数是多少?
- 高度为h的完全二叉树至少有多少个结点?至多有多少个结点?
- 已知一棵度为m的树中有n1个度为1的结点,n2个度为2的结点,…,nm个度为m的结点,问该树中有多少个叶结点?
作业12:二叉树的建立和层序遍历法实践
- 给定一个序列AB#CD###E#F##建立一颗树,根据“二叉树的生成”算法构造这颗树。
- 使用层序遍历方法完成遍历并测试。
作业13:哈夫曼编码测试
画出哈夫曼树,写出各个叶子节点的编码。
作业14:地图染色问题
给图染色,具体算法如下:
- 将图的结点按照度数递减的次序排列。
- 用第一种颜色对第一个结点着色,并按照结点排列的次序对与前面着色点不邻接的每一点着以相同颜色。
- 用第二种颜色对尚未着色的点重复步骤2,直到所有点着色完为止。
作业15:Dijkstra(迪杰斯特拉)算法测试
使用Dijkstra(迪杰斯特拉)算法计算单源(V1出发)最短路径。
作业16:最小生成树测试
- 画出Prim算法的最小生成树的生成过程
- 画出Kruscal算法的最小生成树的生成过程
- 计算最小权值
三、实验报告总结
实验一:linux命令行和编写简单java程序
- 基于命令行和IDEA(Intellj IDEA 简易教程](http://www.cnblogs.com/rocedu/p/4421202.html)进行简单的Java程序编辑、编译、运行和调试。
- 练习Linux基本命令;
- 学习Java程序的JDB调试技能:https://www.cnblogs.com/rocedu/p/6371262.html
- 编写简单的Java程序。
实验二:编写简单的计算器
- 编写简单的计算器,完成加减乘除模运算。
- 要求从键盘输入两个数,使用判定语句选择一种操作,计算结果后输出,然后使用判定和循环语句选择继续计算还是退出。
- 编写测试代码,测试验证。(https://www.cnblogs.com/rocedu/p/4472842.html)
实验三:面向对象程序设计
- 初步掌握单元测试和TDD
- 理解并掌握面向对象三要素:封装、继承、多态
- 初步掌握UML建模
实验四:Java Socket编程与密码学
- Java Socket编程
- Java和密码学
- 编写有理数/复数计算器
- 远程有理数计算器
- 远程复数计算器
实验五:Android程序设计
- Android Stuidio的安装测试
- Activity测试
- UI测试
- 布局测试
- 事件处理测试
实验六:线性结构之链表
- 通过键盘输入一些整数,建立一个链表
- 实现节点插入、删除、输出操作
- 使用冒泡排序法或者选择排序法根据数值大小对链表进行排序
- 在android上实现以上操作
实验七:查找与排序
- 定义一个Searching和Sorting类,并在类中实现linearSearch,SelectionSort方法,最后完成测试
- 重构你的代码
- 参考http://www.cnblogs.com/maybe2030/p/4715035.html ,学习各种查找算法并在Searching中补充查找算法并测试
- 补充实现课上讲过的排序方法:希尔排序,堆排序,二叉树排序等
- 编写Android程序对实现各种查找与排序算法进行测试
实验八:树
- 参考教材完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)
- 基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如给出中序HDIBEMJNAFCKGL和后序ABDHIEJMNCFGKL,构造出附图中的树
- 自己设计并实现一颗决策树
- 输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果
实验九:图
- 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)
- 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)
- 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环
- 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出
- 完成有向图的单源最短路径求解(迪杰斯特拉算法)
代码托管链接
- 给出statistic.sh的运行结果,说明本学期的代码量目标达到没有?
代码总量约为9000行,虽然没有达到目标,但是基于现实情况,这个量还可以。 - 加点代码,改点代码是理解的最好方式,参考编程的智慧,谈谈你的心得
我认为修改代码是非常好的学习方式,无论是参考别人的代码,根据自己的理解进行修改,还是对自己原有的代码修改优化,都是对编程能力的考验。 - 积极主动敲代码做到没?教材实践上有什么经验教训?
基本上做到了
教材上的代码只是参考,再具体实践中不一定是能运行的,有的代码也没有必要那么长,还是要有自己的理解,尝试找到能力范围中的最优代码。
课程收获与不足
- 收获
我觉得自己最大的收获就是学会了自主学习。不会自学,这是我进入大学以来暴露出的很致命的问题,这门课刚开始的时候真的是十分痛苦,后来慢慢的去尝试自己看书,查资料,自学能力有所提高。 - 不足
不足就是编程能力不行,尤其是后面数据结构的部分,理论知识懂了,但实践起来有困难。 - 结对学习是不是真正贯彻了?写一下你提供的帮助或接受了什么帮助,并对老师提供参考建议
并没有,除了实验四中的硬性要求,几乎没有进行结对学习,最多就是单方面的请教。我觉得可以适当的增加一些需要结对完成的作业。
问卷调查
- 你平均每周投入到本课程有效学习时间有多少?
差多15个小时左右 - 每周的学习效率有提高吗?你是怎么衡量的?
不能说每周都有提高,但是总体上是比刚开始好很多,衡量标准就是参考别人代码的比例。 - 蓝墨云班课的使用对你的学习有促进吗?有什么建议和意见吗?
- 有,可以按需查看所需要的资源。
- 可以把资源按照知识点分类,不要按周。
- 你觉得这门课老师应该继续做哪一件事情?
坚持这种授课方式,继续鼓励大家自主学习。 - 你觉得这门课老师应该停止做哪一件事情?
停止全英文的考试,英语水平真的有限,那些题拍照翻译也不准。