2021年09月03日 java

考点1:

下列说法哪个正确( )

  • A 不需要定义类,就能创建对象
  • B 对象中必须有数据域和方法
  • C 数据域可以是基本类型变量,也可以是一个对象
  • D 数据域必须是基本类型变量

解析

显示答案/隐藏答案正确答案: C

数据域,也就是个成员变量(类的属性),不包括成员方法。成员变量可以是基本数据类型的变量,也可以是引用数据类型的变量(既可以说一个类的引用,如String str)

考点2:成员变量的初始化

程序Demo.java编译运行后输出的结果是:( )

1
2
3
4
5
6
7
8
9
public class Demo{
int x=1;
int y;
public static void main(String [] args){
int z=2;
Demo t=new Demo();
System.out.println(t.x+t.y+z);
}
}
  • A 3
  • B 12
  • C 1
  • D 5

解析

显示答案/隐藏答案正确答案: A

成员变量有默认初始化

成员变量和静态变量是有默认值的。

成员变量为int类型可以不初始化,默认值为0

局部变量必须初始化

局部变量为int类型必须初始化,没有默认值

这题考的是默认初始化问题,但是可以引出另外一个问题:
局部变量参与运算前是必须要初始化的,比如下面的代码就会编译出错,提示y必须要初始化。

1
2
3
4
5
public static void main(String[] args) {
int x = 1;
int y;
int z = x + y;
}

编译器错误提示:

1
The local variable y may not have been initialized

考点3:static 访问控制符

在java中,在同一包内,类Cat里面有个公有方法sleep(),该方法前有static修饰,则可以直接用Cat.sleep()。( )

  • A 正确
  • B 错误

解析

显示答案/隐藏答案正确答案: A

如果是private,则在其他类中
但并且在其他类就不能这么直接用了

访问控制符修饰的成员可见范围

位置 public protected default private
同一个类中
同一个包中
子类中
全局

考点4:

下列表述错误的是?()

  • A int是基本类型,直接存数值,Integer是对象,用一个引用指向这个对象。
  • B 在子类构造方法中使用super()显示调用父类的构造方法,super()必须写在子类构造方法的第一行,否则编译不通过
  • C 封装的主要作用在于对外隐藏内部实现细节,可以增强程序的安全性
  • D finaljava中的修饰符,可以修饰类、接口、抽象类、方法和属性。

解析

显示答案/隐藏答案正确答案: D

abstract和final矛盾

抽象类:子类可以继承和重写;
final:类不允许被重写;
故,final不能修饰抽象类,否则自相矛盾。

考点5:访问控制符

下列哪个修饰符可以使在一个类中定义的成员变量只能被同一包中的类访问?

  • A private
  • B 无修饰符
  • C public
  • D protected

解析

显示答案/隐藏答案正确答案: B

访问控制符修饰的成员可见范围

位置 public protected 无修饰符 private
同一个类中
同一个包中
子类中
全局

包访问权限

无修饰符就是默认权限,也叫包访问权限,只能被同一包内的类访问。

考点6:

已知如下类说明:

1
2
3
4
5
6
7
8
public class Test{
private float f=1.0f;
int m=12;
static int n=1;
public static void main(String args[]){
Test t=new Test();
}
}

在main方法中如下哪些使用是正确的()

  • A t.f = 1.0
  • B this.n
  • C Test.m
  • D Test.n

解析

显示答案/隐藏答案正确答案: D

A. 1.0默认为double类型,float f = 1.0编译出错,如果是float f= 1或者float f=1.0f就可以通过
编译器报错如下

1
Type mismatch: cannot convert from double to float

B. main方式是static修饰的,main方法存在时,当前对象还没有初始化,也就是没有this引用。
编译器报错如下:

1
Cannot use this in a static context

C. m不是static的,需要依附于对象存在,不能通过类名调用。
编译器报错如下:

1
Cannot make a static reference to the non-static field Test.m

考点7:访问控制符

访问权限控制从最大权限到最小权限依次为:public、 包访问权限、protected和private 。( )

  • A 正确
  • B 错误

解析

显示答案/隐藏答案正确答案: B

访问控制符从大到小

位置 public protected 无修饰符 private
同一个类中
同一个包中
子类中
全局

考点8:哪个式子有可能在某个进制下成立

以下哪个式子有可能在某个进制下成立()?

  • A 13*14=204
  • B 12*34=568
  • C 14*14=140
  • D 1+1=3

解析

显示答案/隐藏答案正确答案: A

N进制按权展开

A选项

$$
13 \times 14=204
$$

设在$x$​进制下该式子成立,按$x$​展开得到:

$$
\begin{aligned}
(1\times x^1+3\times x^0)\times (1\times x^1+4\times x^0)&=2\times x^2+0\times x^1+4\times x^0\\
(x+3)\times(x+4)&=2x^2+4\\
x^2+7x+12&=2x^2+4\\
7x+8&=x^2\\
x^2-7x-8&=0
\end{aligned}
$$

这是个一元二次方程,使用韦达定理

$$
x ={-b \pm \sqrt{b^2-4ac}\over 2a}
$$

来求解:

$$
\sqrt{b^2-4ac}=\sqrt{(-7)^2-4\times 1\times(-8)}=\sqrt{81}=9
$$

$$
x_1 ={-b + \sqrt{b^2-4ac}\over 2a}
=\frac{-(-7)+9}{2\times 1}
=\frac{16}{2}=8
$$

$$
x_2={-b - \sqrt{b^2-4ac}\over 2a}
=\frac{-(-7)-9}{2\times 1}
=\frac{-2}{2}
=-1
$$

得到 $x_1=8$​​ , $x_2=-1$​​,

没有$-1$进制,排除$x_2$​​.

所以在$8$​​进制下,这个式子成立。A选项正确

B选项

$$
12\times 34=568
$$

设在x进制下,这个式子成立,则:

$$
\begin{aligned}
(x+2)(3x+4)&=5x^2+6x+8\\
3x^2+4x+6x+8&=5x^2+6x+8\\
3x^2+4x&=5x^2\\
4x&=2x^2\\
2x&=x^2\\
x^2-2x&=0\\
x(x-2)&=0\\
\end{aligned}
$$

解得

$$
x_1=0,x_2=2
$$

没有0进制,$x_1$​排除,

$N$​进制的最大的数为$N-1$​

2进制的最大的数为1,式子$12\times 34=568$中2,3,4,5,6,8都大于2进制的数1.

$x_2$​​排除所以式子不成立,B选项错误

C选项

$$
\begin{aligned}
(x+4)(x+4)&=x^2+4x\\
x^2+4x+4x+16&=x^2+4x\\
4x+16&=0\\
\end{aligned}
$$

解得$x=-4$。没有$-4$进制,C选项错误

D选项

$$\begin{aligned}
1\times x^0+1\times x^0&=3\times x^0\\
2 \times x^0&=3\times x^0\\
0&=1\times x^0\\
0&=1\times 1\\
\end{aligned}
$$

得到
$$
0=1
$$
实际上,0不等于1D选项错误

考点9:线程安全

下列那些方法是线程安全的(所调用的方法都存在)

  • A public class MyServlet implements Servlet { public void service (ServletRequest req, ServletResponse resp) { BigInteger I = extractFromRequest(req); encodeIntoResponse(resp,factors); } }
  • B public class MyServlet implements Servlet { private long count =0; public long getCount() { return count; } public void service (ServletRequest req, ServletResponse resp) { BigInteger I = extractFromRequest(req); BigInteger[] factors = factor(i); count ++; encodeIntoResponse(resp,factors); } }
  • C public class MyClass { private int value; public synchronized int get() { return value; } public synchronized void set (int value) { this.value = value; } }
  • D public class Factorizer implements Servlet { private volatile MyCache cache = new MyCache(null,null); public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = cache.getFactors(i); if (factors == null) { factors = factor(i); cache = new MyCache(i,factors); } encodeIntoResponse(resp,factors); }

解析

显示答案/隐藏答案正确答案: ACD

这种题排版真变态:
A

1
2
3
4
5
public class MyServlet implements Servlet {
public void service (ServletRequest req, ServletResponse resp) {
BigInteger I = extractFromRequest(req); encodeIntoResponse(resp,factors);
}
}

B

1
2
3
4
5
6
7
8
9
10
public class MyServlet implements Servlet {
private long count =0;
public long getCount() { return count; }
public void service (ServletRequest req, ServletResponse resp) {
BigInteger I = extractFromRequest(req);
BigInteger[] factors = factor(i);
count ++;
encodeIntoResponse(resp,factors);
}
}

C

1
2
3
4
5
public class MyClass { 
private int value;
public synchronized int get() { return value; }
public synchronized void set (int value) { this.value = value; }
}

D

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Factorizer implements Servlet {
private volatile MyCache cache = new MyCache(null, null);

public void service(ServletRequest req, ServletResponse resp) {
BigInteger i = extractFromRequest(req);
BigInteger[] factors = cache.getFactors(i);
if (factors == null) {
factors = factor(i);
cache = new MyCache(i, factors);
}
encodeIntoResponse(resp, factors);
}
}

自定义Servlet时尽量不要定义成员变量,多线程环境下定义的成员变量会成为线程共享变量,导致数据不一致问题。
A 无状态的,天然线程安全
B 存在静态条件变量count
C 涉及写的set方法使用了synchronize关键字,线程安全
D 使用了volatile关键字和null的判断,可能不存在重排序的问题,不懂这个 欢迎指正,说的可能不对。

怎样做到线程安全

一个对象是否安全取决于它是否被多个线程访问(访问时访问对象的方式)。
要使对象线程安全,那么需要采用同步的机制来协同对对象可变状态的访问。(java这边采用synchronized,其他还有volatile类型的变量,显式锁以及原子变量)

当某个多线程访问同一个可变状态时候没有同步,则会出现错误,解决办法:

1、不在线程之间共享该变量
2、将该变量修改为不可变变量
3、访问状态时候使用同步

安全性的解释:

当多线程访问某个类时,这个类始终能表现出正确的行为(不管运行时采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同),那么这个类安全的。

  • 无状态对象一定是线程安全的。
  • 在实际情况下,尽可能使用户现有的线程安全对象,比如用Vector而不是ArrayList。

原子性 可见性 有序性

要想并发程序正确地执行,必须要保证“原子性”、“可见性”以及“有序性”。只要有一个没有被保证,就有可能会导致程序运行不正确。

考点10:CMS垃圾回收器

CMS垃圾回收器在那些阶段是没用用户线程参与的

  • A 初始标记
  • B 并发标记
  • C 重新标记
  • D 并发清理

解析

显示答案/隐藏答案正确答案: AC