文章目录
- 1. 单选题
- 2. 编程题
1. 单选题
1. 下列选项中关于 java 中 super 关键字的说法正确的是 ()
A: super 关键字是在子类对象内部指代父类对象的引用.
B : super 关键字不仅可以指代子类的直接父类,还可以直接指代父类的父类.
C : 子类通过 super 关键字只能调用父类的方法,而不能调用父类的属性.
D : 子类通过 super 关键字只能调用父类的属性,而不能调用父类的方法 .
答案 : A 正确 ,我们可以通过 super 访问父类的 方法和属性 以及 父类的构造函数
B : 错误 , super 直接指向子类的父类,而不能直线子类的爷爷辈 (父类的父类)
C , D 都错 ,super 关键字 可以访问 父类的属性和 方法
2. A派生出子类B,B派生出子类C,并且在java源代码中有如下声明:
A a0=new A(); // 1
A a1=new B(); // 2
A a2=new C(); // 3
以下哪个说法是正确的?
A : 第1行,第2行和第3行的声明都是正确的
B : 第1,2,3行都能通过编译,但第2,3行运行时出错
C : 第1,2行能通过编译,但第3行编译出错
D : 只有第1行能通过编译
答案 : 这里涉及到 继承 的知识 , B 是 A 的子类 , C 是 A 的子类 , 看 第一行 A a0 = new A (); 是没问题的 , A 通过自己的构造函数 构造 a0 对象 ,
第二行 A a1 = new B(); 这也是没问题的 , 这里涉及到了向上转型 . 父类引用引用了子类对象 关于 向上转型 我在多态的文章中说过 多态 不记得可以看看这个 .
第三行 同样也是没问题的 继承具有传递性 , B 继承了 A , C 又继承了 B , 所以 C 是具有 A 的性质 , A a3 = new C() , 同样 也会触发 向上转型 .
3. 以下说法错误的是()
A 数组是一个对象
B 数组不是一种原生类
C 数组的大小可以任意改变
D 在Java中,数组存储在堆中连续内存空间里
答案 :
A : 正确 数组是一个对象
B : 正确 数组不是一种原生类 而是数组是通过基本类型来定义的 , 比如 : int[] a = new int[100]; ,
C : 错误 数组一旦定义好了 就无法任意改变,没法自动扩容 , 我们想要对数组扩容需要使用 copyOf 方法
将 arr 数组扩容 2 倍
D : 正确 数组 是通过 关键字 new 创建出来的 , 通过 new 创建的 都是存放在 堆中的 , 数组在堆中 占用的空间是连续的.
4. Test.main() 函数执行后的输出是()
A : 11 17 34
B : 22 74 74
C : 6 7 7
D : 22 34 17
答案 : D
图一 :
图二 :
图三 :
图四 :
5. 关于Java的异常处理机制的叙述哪些正确?
A 如果程序发生错误及捕捉到异常情况了,才会执行finally部分
B 其他选项都不正确
C 当try区段的程序发生异常且被catch捕捉到时,才会执行catch区段的程序
D catch部分捕捉到异常情况时,才会执行finally部分
答案 :
A : finally 不管程序是否出现异常都会执行, 所以 A 错误
C : 正确
D : 与 A 一样 , D 错误
B : C 正确 ,所以 B 错误
6. 如何跳出Array的forEach循环?()
A break
B return true
C return false
D 以上都不是
答案 : 选 A , Array 可以看作 一个数组,我们相同过 forEach 遍历, 那么 就可以通过 break 来跳出 循环 , 假设我们的 跳出 Array 的 forEach 循环再 一个 方法里 ,且返回值 不是 布尔类型,那么 B 和 C 是不是就报错了 ,那么 就无法跳出循环了.
7. 一个以”.java”为后缀的源文件
A 只能包含一个类,类名必须与文件名相同
B 只能包含与文件名相同的类以及其中的内部类
C 只能有一个与文件名相同的类,可以包含其他类
D 可以包含任意类
答案 : 关于.java 文件 是可以 包含多个类的, 但是 只能存在一个 public 规定的类 ,且这个类必须和文件名相同
A 错误 : 一个 .java 文件可以 包含多个 类 ,
B 错误 : .java 文件 不仅可以 又内部类 ,还可以有其他的类 ,注意 只有 一个 public 修饰的类
C 正确
D 错误 : 只能存在 一个 被 public 修饰的类
8. 如下Java语句 , 执行后, x的值是()
double x= 3.0;
int y=5;
x/=--y;
A 3
B 0.6
C 0.4
D 0.75
答案 : 这里 会先执行 --y , y 就变成 了 4 ,然后 3.0 / 4 就为 0.75
9. 下列代码运行后输出结果为()
A cnt=5
B cnt=2
C cnt=3
D cnt=6
答案 : A , 当前代码考察的是 静态代码块 执行顺序 , 关于静态代码块 ,代码块,构造方法的执行顺序在继承那篇文章是说过的
简单复习一下 :
1、父类静态代码块优先于子类静态代码块执行,且是最早执行
2、父类实例代码块和父类构造方法紧接着执行
3、子类的实例代码块和子类构造方法紧接着再执行
4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行
简单来说 就是 静态代码块 > 代码块 > 构造方法 , 题目中的静态变量在 静态代码块之前,所以会先执行 静态变量 (定义) ,然后再进行静态代码块 最终结果 为 5
10. 以下程序的运行结果 :
A : 666 B : 667 C : 677 D: 676
答案 : 本题很简单 ,就考了 一个 后置++ 的使用 , 这里 第一个 print 语句 先将 6 打印 ,然后 第二个 print 语句 因为 这里是 后置 ++ ,会先使用 a 的值 ,再 ++ ,所以 第二个 print 语句打印的还是 6 , 最后 一个print 语句打印的就是 7
2. 编程题
题目一 : 两种排序方法_牛客题霸_牛客网 (nowcoder.com)
分析 :
代码 :
package T_j.T_3_15;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String[] str = new String[n];
for (int i = 0; i < n; i++) {
str[i] = sc.next();
}
// 1、 判断是否符合长度排序
boolean flagLength = isSortLength(str);
// 2. 判断是否符合字典序排序
boolean flagZidian = isSortZidian(str);
if (flagLength && flagZidian) {
System.out.println("both");
} else if (flagZidian) {
System.out.println("lexicographically");
} else if (flagLength) {
System.out.println("lengths");
} else {
System.out.println("none");
}
}
public static boolean isSortZidian(String[] str) {
for (int i = 1; i < str.length; i++) {
String ret1 = str[i - 1];
String ret2 = str[i];
int j = 0;
for (; j < ret1.length() && j < ret2.length(); j++) {
char a = ret1.charAt(j);
char b = ret2.charAt(j);
// 字符 本质上是 一个 ASCII 码值 所以可以直接比较
if (a < b) {
break;
} else if (a > b) {
return false;
} else {
// a == b 的情况
continue;
}
}
// 判断 ret1 和 ret2 前面的字符都相同 如果 ret1 的长度 大于 ret2 的长度 ,那么 不符合要求
if (j >= ret2.length()) {
return false;
}
}
return true;
}
// 判断长度
public static boolean isSortLength(String[] str) {
for (int i = 1; i < str.length; i++) {
if (str[i - 1].length() >= str[i].length()) {
return false;
}
}
return true;
}
}
其实这里 判断字典序排序 可以使用 一个方法 就可以代替我们 一个一个字符的比较 , 这个方法就是 compareTo
将上面 判断是否按照字典序排序的方法换成下面这个 , 一样可以通过.
public static boolean isSortZidian2(String[] str) {
for (int i = 0; i < str.length - 1; i++) {
// 用当前字符串和后一个字符比较 , 如果字典序大于后一个,
// 说明排序混乱直接返回 false
if (str[i].compareTo(str[i + 1]) > 0) {
return false;
}
}
return true;
}
题目二 : 求最小公倍数__牛客网 (nowcoder.com)
本道题 比较简单
第一种方法 : 假设是求 A 和 B 的最小公倍数 先求出最最大公约数 然后 通过 公式 : , A * B / (A 和 B 的最大公约数)
这里 求 最大公约数 就可以使用 辗转相除法 (通过 欧几里得算法得出来的)
规定 : (A,B) 表示 A 和 B 的最大公约数
(A,B) = (A * k + B , B) = (B , A) = (B * K + A , A)
简单解释一下上面 :
比如 我们想要求 10 和 6 的最大公约数 : (10 , 6) = (4 + 6 , 6) = (4,6) = (4, 4 + 2) = (4,2) = (2 +2 , 2) = (2,2) = (2 , 0 + 2) = (2,0) = 2
最终我们的 最大公约数 就是 2 .
辗转相除法 :
m = 10 , n = 6 ,
m % n = 10 % 6 = 4
m = n = 6
n = 4
m % n = 6 % 4 = 2
m = 4
n = 2
m % n = 4 % 2 = 2
m = 2
n = 2
m % n = 2 % 2 = 0
m = n = 2
n = 0
此时我们的最大公约 就求出来了 , 是不是 就与 欧几里得算法 有点像.
有了 最大公约数 , 那么最小公倍数 不就有手机行
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int mn = m * n;
int c = m;
while (n != 0) {
c = m % n;
m = n;
n = c;
}
System.out.println(mn / m);
}
}
另外 还有一种方法 : m * n 得到最大的 公倍数 , 然后 – , 找到最小的 公倍数
public static void main(String[] args) {
// 最小公倍数
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
int c = a * b;
int d = c;
while(c != a && c != b){
c--;
if(c % a == 0 && c % b ==0){
d = c;
}
}
System.out.println(d);
}