考点1:抽象类和接口的区别

下列对接口的说法,正确的是( )

  • A 接口与抽象类是相同的概念
  • B 若要实现一个接口为普通类则必须实现接口的所有抽象方法
  • C 接口之间不能有继承关系
  • D 一个类只能实现一个接口
显示答案/隐藏答案正确答案: B

A 接口与抽象类是不同的概念。抽象类是用于捕捉子类的通用特性,接口是抽象方法的集合;
B 实现接口必须实现接口的所有方法;
C 接口可以继承一个或多个接口,抽象类只能继承一个类或者实现多个接口;
D 一个类只能继承一个类,但是可以实现多个接口。

自jdk8之后,实现类不必实现接口的所有方法!此题需要添加限制条件!!!!!因为jdk8之后为了引入steam(),增加了default关键字!
java8之后,对接口进行了增强,新增了default和static方法,这两种是不用子类去实现的

考点2:HashSet

有这样一段程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test{ 
public static void main(String [] args){
List list=new ArrayList();
list.add("a");
list.add("b");
list.add("a");
Set set=new HashSet();
set.add("a");
set.add("b");
set.add("a");
System.out.println(list.size()+","+set.size());
}
}

请问运行主要的程序会打印出的是什么()

  • A 2,2
  • B 2,3
  • C 3,2
  • D 3,3
显示答案/隐藏答案正确答案: C

list有序可重复,set无序不可重复

HashSet不能添加重复的元素,当调用add(Object)方法时候,
首先会调用Object的hashCode方法判hashCode是否已经存在,如不存在则直接插入元素;
如果已存在则调用Object对象的equals方法判断是否返回true, 如果为true则说明元素已经存在,如为false则插入元素

考点3:字符串和整数的连接操作

下面这三条语句

1
2
3
System.out.println("is "+ 100 + 5);
System.out.println(100 + 5 +" is");
System.out.println("is "+ (100 + 5));

的输出结果分别是? ( )

  • A is 1005, 1005 is, is 1005
  • B is 105, 105 is, is 105
  • C is 1005, 1005 is, is 105
  • D is 1005, 105 is, is 105
显示答案/隐藏答案正确答案: D

1.”is”说明后面的内容都会被强制转换为string,所以是最后结果是拼接起来的
2.100+5先得到105,然后与is拼接
3.先算括号内的

在java中,“+” 和 “+=” 是经过重载的运算符,而java不允许程序员进行运算符的重载。
如果 “+”之前是String,那么此时,“+” 的作用就是连接两个字符串;
若此时 “+” 后面是基本数据类型的话,可以直接进行连接,若是引用数据类型的话,则会调用该对象的toString()方法。

关键看顺序
String先出现,则其后的int统一当作String来拼接
若两个int先出现,则int会先执行运算
如果有括号,括优先级高于运算符

考点4:start方法才是启动线程

下面程序的运行结果是:( )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void main(String args[]) {

Thread t = new Thread() {
public void run() {
pong();
}
};

t.run();
System.out.print("ping");

}

static void pong() {
System.out.print("pong");
}
}
  • A pingpong
  • B pongping
  • C pingpong和pongping都有可能
  • D 都不输出
  • E pong
  • F ping
显示答案/隐藏答案正确答案: B

t.run是调用的Thead类中的run()方法,t.start才是执行线程,
所以这题就是执行普通run()方法,先输出pong,在输出ping。

考点5:等价类 无效等价类

某程序要求每次输入只能是正整数,并且每次输入的数值要求必须是100的倍数且小于等于500,则下列哪个是正确的无效等价类( )

  • A (0,100)、(100,200)、(200,300)、(300,400)、(400,500)、(500,+∞);
  • B (500,+∞)
  • C (500,+∞)、任意大于0小于500的非100倍数的整数;
  • D (-∞,100)、(100,200)、(200,300)、(300,400)、(400,500)、(500,+∞);
显示答案/隐藏答案正确答案: D

无效等价类和有效等价类相反,即不满足程序输入要求或者无效的输入数据构成的集合

什么是有效等价类

https://baike.baidu.com/item/%E6%97%A0%E6%95%88%E7%AD%89%E4%BB%B7%E7%B1%BB
有效等价类指输入完全满足程序输入的规格说明,有效、有意义的输入数据所构成的集合。利用有效等价类可以检验程序是否满足规格说明所规定的功能和性能。

什么是无效等价类

无效等价类和有效等价类相反,即不满足程序输入要求或者无效的输入数据构成的集合。使用无效等价类,可以鉴别程序异常情况的处理。

在程序设计中,不但要保证所有有效地数据输入能产生正确的输出,同时需要保障在输入错误或者空输入的时候能有异常保护,这样的测试才能保证软件的可靠性。

等价类(满足条件的集合):

$ {100,200,300,400,500}$​

无效等价类:

$(-\infty,100) \bigcup (100,200) \bigcup (200,300) \bigcup (300,400) \bigcup(400,500) \bigcup(500,+\infty)$

考点6:对象流 序列化

以下关于对象序列化描述正确的是

  • A 使用FileOutputStream可以将对象进行传输
  • B 使用PrintWriter可以将对象进行传输
  • C 使用transient修饰的变量不会被序列化
  • D 对象序列化的所属类需要实现Serializable接口
显示答案/隐藏答案正确答案: CD

使用ObjectOutputStream和ObjectInputStream可以将对象进行传输.
声明为static和transient类型的成员数据不能被串行化。
因为static代表类的状态, transient代表对象的临时数据。

考点7:抽象类和接口的区别

jdk1.8中,下面有关java 抽象类和接口的区别,说法错误的是?

  • A 抽象类可以有构造方法,接口中不能有构造方法
  • B 抽象类中可以包含非抽象的普通方法,接口中的方法必须是抽象的,不能有非抽象的普通方法
  • C 一个类可以实现多个接口,但只能继承一个抽象类
  • D 接口中可以有普通成员变量,抽象类中没有普通成员变量
显示答案/隐藏答案正确答案: BD
  1. 接口中不能有构造方法,抽象类中可以有。
    1. 抽象类中构造方法作用:用于初始化抽象类的成员;
    2. 抽象类的构造方法不能像普通类那样直接调用,抽象类的构造方法一般由为继承它的子类使用super调用,或者创建抽象类匿名内部类子类是调用。
  2. 接口中方法默认是public abstract(只能是这两个关键字,或其中一个或都省略)
  3. 接口中的变量默认是public static final(只能是这三个关键字,或其中两个/一个或都省略)

Ps : java中一个类只能继承一个类,但一个接口可以继承多个接口

不能通过调用抽象类的构造器来创建对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package base.abstractandinterface;

public abstract class AbstractTest {
protected int a;
protected String b;

public AbstractTest(int a) {
this.a = a;
}

public AbstractTest(int a, String b) {
this.a = a;
this.b = b;
}

public AbstractTest() {
}

public abstract void show();
}

class A extends AbstractTest {


public A() {
}

public A(int a) {
// 调用父类的构造器
super(a);
}

public A(int a, String b) {
// 调用父类的构造器
super(a, b);
}

@Override
public void show() {
System.out.println("int Class A ...");
System.out.println("a=" + a + ",b=" + b);
}

public static void main(String[] args) {
AbstractTest abstractTest;
// 抽象类不能直接调用构造器进行初始化
abstractTest = new AbstractTest();
// abstractTest = new AbstractTest(20, "helloworld");
abstractTest = new A(20, "helloworld");
abstractTest.show();
}
}

报错如下:

1
'AbstractTest' is abstract; cannot be instantiated
1
2
3
4
5
6
7
abstractTest = new AbstractTest() {
@Override
public void show() {
System.out.println("在匿名内部类方式实现的子类中");
}
};
abstractTest.show();

运行结果:

1
在匿名内部类方式实现的子类中

接口没有构造器

1
2
3
public interface InterfaceTest {
public InterfaceTest();
}

报错如下:

1
Not allowed in interface

考点8:Java基础知识

下面有关Java的说法正确的是( )

  • A 一个类可以实现多个接口
  • B 抽象类必须有抽象方法
  • C protected成员在子类可见性可以修改
  • D 通过super可以调用父类构造函数
  • E final的成员方法实现中只能读取类的成员变量
  • F String是不可修改的,且java运行环境中对string对象有一个对象池保存
显示答案/隐藏答案正确答案: ACDF

解释一下c选项,意思是父类中的protected方法子类在重写的时候访问权限可以修改,其实就是重写的要素之一,换了个说法而已
抽象类可以不具有抽象方法! 抽象类可以不具有抽象方法! 抽象类可以不具有抽象方法! 重要的事情说三遍

考点9:HttpServletRequest方法

以下哪些方法可以取到http请求中的cookie值()?

  • A request.getAttribute
  • B request.getHeader
  • C request.getParameter
  • D request.getCookies
    `
    显示答案/隐藏答案正确答案: BD

下面的方法可用在 Servlet 程序中读取 HTTP 头。这些方法通过 HttpServletRequest 对象可用:

1)Cookie[] getCookies()
返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。

2)Object getAttribute(String name)
以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。

3)String getHeader(String name)
以字符串形式返回指定的请求头的值。Cookie也是头的一种

4)String getParameter(String name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。

考点1:HashMap源码

HashMap的数据结构是怎样的?

  • A 数组
  • B 链表
  • C 数组+链表
  • D 二叉树
显示答案/隐藏答案正确答案: C

HashMap 由数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
JDK8及其以后版本,HashMap的数据结构是数组+链表+红黑树

HashMap内部包含了一个默认大小为 16 Entry 类型的数组 table,其中每个Entry 是一个链表,当链表长度大于等于 8 时会将链表转换为红黑树。

JDK1.7中HashMap存储结构

jdk1.7 中使用个 Entry 数组来存储数据,用key的 hashcode 取模来决定key会被放到数组里的位置,如果 hashcode 相同,或者 hashcode 取模后的结果相同( hash collision ),那么这些 key 会被定位到 Entry 数组的同一个格子里,这些 key 会形成一个链表。在 hashcode 特别差的情况下,比方说所有key的 hashcode 都相同,这个链表可能会很长,那么 put/get 操作都可能需要遍历这个链表,也就是说时间复杂度在最差情况下会退化到 O(n)

JDK1.8中HashMap存储结构

jdk1.8 中使用一个 Node 数组来存储数据,但这个 Node 可能是链表结构,也可能是红黑树结构,如果插入的 key 的 hashcode 相同,那么这些key也会被定位到 Node 数组的同个格子里。如果同一个格子里的key不超过8个,使用链表结构存储。如果超过了8个,那么会调用 treeifyBin 函数,将链表转换为红黑树。那么即使 hashcode 完全相同,由于红黑树的特点,查找某个特定元素,也只需要O(log n)的开销也就是说put/get的操作的时间复杂度最差只有 O(log n),但是真正想要利用 JDK1.8 的好处,有一个限制:key的对象,必须正确的实现了 Compare 接口

HashMap在Node数组中进行哈希查找,
使用链接法处理冲突,
冲突较少时使用链表,
目前版本当冲突的键达到8时,
会把链表转换为红黑树.

1、HashMap 底层的数据是数组被成为哈希桶(默认的初始值为 16 ),每个桶存放的是链表,链表中的每个节点,就是 HashMap 中的每个元素。
2、在 JDK 8 当链表长度大于等于 8 时,就会转成红黑树的数据结构,以提升查询和插入的效率。

考点2:不用编码的java文件编译命令 javac -encoding

语句:char foo='中',是否正确?(假设源文件以GB2312编码存储,并且以javac -encoding GB2312命令编译)

  • A 正确
  • B 错误
显示答案/隐藏答案正确答案: A

测试类:

1
2
3
4
5
6
7
8
package base.ecoding;

public class Test {
public static void main(String[] args) {
char foo='中';
System.out.println(foo);
}
}

这个应该和系统的编码有关,保存为GB2312时,直接使用javac -d . Test.java可以正常编译,因为我的Windows简体中文系统使用的是GBK编码。
所以可以正常编译,但是如果把上面的文件保存为UTF-8编码,再次使用javac -d . Test.java就无法编译,报错如下:

1
2
3
4
5
6
7
8
9
10
11
12
PS G:\dev2\idea_workspace\MyJavaTools\RunableTools\src\base\ecoding> javac -d . .\Test.java
.\Test.java:5: 错误: 编码 GBK 的不可映射字符 (0xAD)
char foo='涓?';
^
.\Test.java:5: 错误: 未结束的字符文字
char foo='涓?';
^
.\Test.java:5: 错误: 未结束的字符文字
char foo='涓?';
^
3 个错误
PS G:\dev2\idea_workspace\MyJavaTools\RunableTools\src\base\ecoding>

正确的编译命令为:javac -d . -encoding UTF-8 .\Test.java,运行也是正常的。

1
2
3
4
PS G:\dev2\idea_workspace\MyJavaTools\RunableTools\src\base\ecoding> javac -d . -encoding UTF-8 .\Test.java
PS G:\dev2\idea_workspace\MyJavaTools\RunableTools\src\base\ecoding> java base.ecoding.Test

PS G:\dev2\idea_workspace\MyJavaTools\RunableTools\src\base\ecoding>

总结

编译java文件时,如果不指定编码时,javac会使用默认的编码,也就是操作系统的编码,如果操作系统的编码和java文件的编码不一致时,就会编译错误。

所以使用javac编译时,都指定文件的编码,这样就不会失败。

1
javac -encoding 文件编码 xxx.java

即使java文件的编码和操作系统的相同,也指定编码。因为这样必然会成功。

考点3:异常处理 运行时异常非运行时异常

下列关于异常处理的描述中,错误的是()。

  • A 程序运行时异常由Java虚拟机自动进行处理
  • B 使用try-catch-finally语句捕获异常
  • C 可使用throw语句抛出异常
  • D 捕获到的异常只能在当前方法中处理,不能在其他方法中处理
显示答案/隐藏答案正确答案: D

运行时异常不需要显示处理

运行时异常可以不处理。当出现这样的异常时,总是由虚拟机接管。
比如我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。
出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。
抛出之后,如果是线程,这个线程也就退出了。
如果是主程序抛出的异常,整个程序也就退出了。
运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。只不过往往不对它处理罢了。
也就是说,如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。

throw和throws的区别

C:throw关键字:语句抛出异常 throws关键字:声明异常(方法抛出一个异常)

1.编译时异常必须显示处理,运行时异常交给虚拟机自行处理。

考点4:HashMap源码

下面有关java hashmap的说法错误的是?

  • A HashMap的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。
  • B HashMap的实现不是同步的,意味着它不是线程安全的
  • C HashMap通过开放地址法解决哈希冲突
  • D HashMap中的key-value都是存储在Entry数组中的
显示答案/隐藏答案正确答案: C

Java8之前HashMap使用链地址法

1.在Java 8 之前,HashMap和其他基于map的类都是通过链地址法解决冲突,它们使用单向链表来存储相同索引值的元素。在最坏的情况下,这种方式会将HashMap的get方法的性能从O(1)降低到O(n)。

Java8 HashMap

为了解决在频繁冲突时hashmap性能降低的问题,Java 8中使用平衡树来替代链表存储冲突的元素。这意味着我们可以将最坏情况下的性能从O(n)提高到O(logn)。

在Java 8中使用常量TREEIFY_THRESHOLD来控制是否切换到平衡树来存储。HashMap一开始使用链表,并在冲突的元素数量超过TREEIFY_THRESHOLD时用平衡二叉树替换链表。目前,这个常量值是8。

不过这一特性在所有基于hash table的类中并没有,例如Hashtable和WeakHashMap。

1. 关于HashMap的一些说法:

a) HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap的底层结构是一个数组,数组中的每一项是一条链表。
b) HashMap的实例有俩个参数影响其性能: “初始容量” 和 装填因子
c) HashMap实现不同步,线程不安全。 HashTable线程安全
d) HashMap中的key-value都是存储在Entry中的。
e) HashMap可以存null键和null值,不保证元素的顺序恒久不变,它的底层使用的是数组和链表,通过hashCode()方法和equals()方法保证键的唯一性

解决冲突的三种方法

f) 解决冲突主要有三种方法:定址法,拉链法,再散列法
HashMap是采用拉链法解决哈希冲突的。 注: 链表法是将相同hash值的对象组成一个链表放在hash值对应的槽位;

开放定址法

开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。 沿此序列逐个单元地查找,直到找到给定 的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。

拉链法

拉链法解决冲突的做法是: 将所有关键字为同义词的结点链接在同一个单链表中 。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0..m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于1,但一般均取α≤1。拉链法适合未规定元素的大小。

2. Hashtable和HashMap的区别:

a) 继承不同

    public class Hashtable extends Dictionary implements Map
    public class HashMap extends AbstractMap implements Map

b) 线程安全不同

Hashtable中的方法是同步的,
而HashMap中的方法在缺省情况下是非同步的。

在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

c) key和value能有null不同

Hashtable中,key和value都不允许出现null值。
在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值为null。

因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。

d) 遍历方式不同

两个遍历方式的内部实现上不同。Hashtable、HashMap都使用了Iterator。
而由于历史原因,Hashtable还使用了Enumeration的方式 。

e) 哈希值的使用不同

哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

f) 内部实现方式的数组的初始大小和扩容的方式。

Hashtable中hash数组默认大小是11,
增加的方式是old*2+1。

HashMap中hash数组的默认大小是16,而且一定是2的指数。

HashMap有子类HashSet

注: HashSet子类依靠hashCode()和equal()方法来区分重复元素。

HashSet内部使用Map保存数据,即将HashSet的数据作为Map的key值保存,这也是HashSet中元素不能重复的原因。而Map中保存key值的,会去判断当前Map中是否含有该Key对象,内部是先通过key的hashCode,确定有相同的hashCode之后,再通过equals方法判断是否相同。

考点5:HashMap源码

在Java中,关于HashMap类的描述,以下正确的是 ()

  • A HashMap使用键/值得形式保存数据
  • B HashMap能够保证其中元素的顺序
  • C HashMap允许将null用作键
  • D HashMap允许将null用作值
显示答案/隐藏答案正确答案: ACD
Map集合类 key value
HashMap 允许为null 允许为null
TreeMap 不允许为null 允许为null
ConcurrentMap 不允许为null 不允许为null
Hashtable 不允许为null 不允许为null

HashMap 不按插入顺序排序,按照哈希值排序。所以无序。
但是不增删改键的情况下,输出是按照一定顺序不变的

HashMap允许一个key为null,多个value为null,而Hashtable不允许有null值

我们常说的Map是无序的,其实这里的描述是不清楚的,我们所说的无序通常是指HashMap无序,因为TreeMap按自然顺序排序,LinkedHashMap按添加元素顺序排序

考点6:常见final类

下面哪些类可以被继承? Java.lang.Thread、java.lang.Number、java.lang.Double、java.lang.Math、 java.lang.ClassLoader

  • A Thread
  • B Number
  • C Double
  • D Math
  • E ClassLoader
显示答案/隐藏答案正确答案: ABE

Thread

Thread可以被继承,用于创建新的线程

1
public class Thread extends Object implements Runnable

Number是抽象类,可以被继承

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Number.html

public abstract class Numberextends Object implements Serializable

Direct Known Subclasses:
AtomicInteger, AtomicLong, BigDecimal, BigInteger, Byte, Double, DoubleAccumulator, DoubleAdder, Float, Integer, Long, LongAccumulator, LongAdder, Short

Number类可以被继承,Integer,Float,Double等都继承自Number类

包装类是final修饰的,无法继承

public final class Double extends Number implements Comparable<Double>

Math类是final类

Math类的声明为

public final class Mathextends Object

ClassLoader是抽象类

ClassLoader可以被继承,用户可以自定义类加载器

public abstract class ClassLoader extends Object

考点1:Java标识符

在JAVA中, 下列标识符合法的是()

  • A 3kyou
  • B @163
  • C name
  • D while
显示答案/隐藏答案正确答案: C

Java中标识符规则

  • 字母数字美元符号$、**下划线_**4种组成,
  • 不能以数字开头,
  • 不能是保留字和关键字
  • 不能是true,false,null等引用常量

C语言标识符规则

  • 标识符由字母(A-Z,a-z)、数字(0-9)、下划线“_”组成,
  • 首字符不能是数字,但可以是字母或者下划线
  • 不能是保留字和关键字

Java标识符字符构成比C语言的多了一个美元符$

考点2:java常识 局部变量 成员变量

局部变量能否和成员变量重名?

  • A 可以,局部变量可以与成员变量重名,这时可用“this”来指向成员变量
  • B 可以,这时可用“local”关键字来指向局部变量
  • C 不能,局部变量不能与成员变量重名
  • D 不能,在一个类中不能有重名变量,不管是成员变量还是函数中的局部变量
显示答案/隐藏答案正确答案: A

java访问变量采用就近原则

JAVA访问变量采用就近原则,局部变量与成员变量重名时,局部变量比较近,使用局部变量。

java采用局部优先的思想。局部变量可以和成员变量相同,使用标识符调用时,优先使用局部变量。在实例方法中出现变量名相同时,可以使用this关键字来调用实例变量。

考点3:Java常识

有以下程序片段且Interesting不是内部类,下列哪个选项不能插入到行1。( )

1.
2. public class Interesting{
3. // 省略代码
4. }
  • A import java.awt.*;
  • B package mypackage;
  • C class OtherClass{ }
  • D public class MyClass{ }
显示答案/隐藏答案正确答案: D

一个.java文件中只能有一个public外部类

在同一个java原文件中,可以有多个class类,但是只有有一个公共的 public class

一个.java文件中,可以有多个类,包括内部类和外部类。

考虑到内部类的原因,一个.java文件可以中可以有多个public类。

但是对于外部类而言,一个.java文件必须只能有一个public类,同时这个类的类名必须和.java的文件名一致(包括大小写)

考点4:内存泄漏

java程序内存泄露的最直接表现是( )

  • A 频繁FullGc
  • B jvm崩溃
  • C 程序抛内存控制的Exception
  • D java进程异常消失
显示答案/隐藏答案正确答案: C

java是自动管理内存的,通常情况下程序运行到稳定状态,内存大小也达到一个 基本稳定的值
但是内存泄露导致Gc不能回收泄露的垃圾,内存不断变大.
最终超出内存界限,抛出OutOfMemoryExpection。

答案 C,依次解释一下相关选项

什么是内存泄漏

首先理解一下内存泄漏的概念,内存泄漏就是对象引用消失了,对象内存却没有被回收

A 答案:FullGC 是老年代内存空间不足的时候,才会触发的,老年代一般是生命周期较长的对象或者大对象,频繁的 FullGC不会可能会影响程序性能(因为内存回收需要消耗CPU等资源),但是并不会直接导致内存泄漏。
B 答案:JVM奔溃的可能是内存溢出引起的,也可能是其他操作导致JVM崩溃,例如设置了错误的JVM参数等。
C 答案:内存异常,最常见的 就是 StackOverFlow了把,内存溢出,其实内存泄漏的最终结果就是内存溢出。所以,基本上C是对的答案。
D 答案:Java 进程异常消失,这个明显不对的。

题目有问题:
“程序抛内存控制的Exception”
java只有OutOfMemoryError,是Error。
java没有OutOfMemoryException。
C#倒是有OutOfMemoryException。

考点5:Java关键字 Java非法标识符

以下为 java 语法保留不能作为类名和方法名使用的是

  • A default
  • B int
  • C implements
  • D throws
显示答案/隐藏答案正确答案: ABCD

Java8关键字default也被使用了,所以正确答案应该全选
implements《注意有s结尾》是java实现接口的关键字,而implement则是普通单词,
default是保留字,
throws是抛出异常的关键字,所以正确答案是ABD

考点6:Java常见数据类型

int,String,*point,union哪些不是 Java 的数据类型?

  • A int
  • B String
  • C *point
  • D union
显示答案/隐藏答案正确答案: CD

*point是指针,java中没有这种类型
union是C系的类型,java中没有

考点7:栈

如果进栈序列为e1,e2,e3,e4,则可能的出栈序列是()
注:一个元素进栈后可以马上出栈,不用等全部进栈

  • A e3,e1,e4,e2
  • B e2,e4,e3,e1
  • C e2,e3,e4,e1
  • D 任意顺序都有可能
显示答案/隐藏答案正确答案: BC

A选项e3先出栈。那么e1,e2,e3进栈,e3出栈,如果e1想要出栈必须要e2先出栈,所以A是不可能的。

B选项
入栈顺序:e1进,e2进去又出来,e3进,e4进
出栈:e2、e4、e3、e1
C选项
入栈顺序:e1进,e2进去又出来,e3进去又出来,e4进
出栈:e2、e3、e4、e1

考点1:Java常识

以下关于构造函数的描述错误的是 ( )

  • A 每个类有且只能有一个构造函数。
  • B 构造函数是类的一种特殊函数,它的方法名必须与类名相同
  • C 构造函数的主要作用是完成对类的对象的初始化工作
  • D 一般在创建新对象时,系统会自动调用构造函数
显示答案/隐藏答案正确答案: A

考点2:异常

代码String str=”123456a”;int i=Integer.parseInt(str);会报异常的是()

  • A java.lang.NullPoninterException
  • B java.lang.NumberFormatException
  • C java.lang.RuntimeException
  • D java.lang.ArrayindexOutOfBoundsException
显示答案/隐藏答案正确答案: B

java.lang.NullPoninterException:变量未被初始化、对象未赋值、对象为空(俗称的空指针异常)
java.lang.NumberFormatException:数据格式转换失败(integer的取值范围为:-127-128,超过范围都会访问false
java.lang.RuntimeException:运行时异常
java.lang.ArrayindexOutOfBoundsException:数组下标越界

考点3:常识

下列关于Java类中方法的定义,正确的是()

  • A 若代码执行到return语句,则将当前值返回,而且继续执行return语句后面的语句。
  • B 只需要对使用基本数据类型定义的属性使用getter和setter,体现类的封装性。
  • C 方法的返回值只能是基本数据类型。
  • D 在同一个类中定义的方法,允许方法名称相同而形参列表不同。
显示答案/隐藏答案正确答案: D

选D
A、一旦执行到return,就不再执行后续的代码。
B、类的封装性可不是这么体现的,数据域和方法都可以被封装。数据域可以是基本数据类型也可以是引用类型。
C、方法的返回值可以是引用类型。
D、这是重载,同一个类中,方法名相同,形参列表不同。

封装是通过访问控制符实现的

https://www.runoob.com/java/java-encapsulation.html

封装性仅仅有get,set方法是不够的,要是成员变量是public的,那么外界就可以随意访问该成员变量。
所以封装要求 成员变量私有,然后提供公有的getter和setter方法来访问成员变量。

考点4:浮点数转整数

下列语句序列执行后,输出结果是()

1
2
3
4
5
6
7
public class ex{
public static void main(String[]args){
int a=13;
a=a/5;
System.out.println(a);
}
}
  • A 1
  • B 2
  • C 3
  • D 4
显示答案/隐藏答案正确答案: B

整数相除之后还是整数,会丢失掉小数部分的数值。

浮点数转整数:丢弃小数部分

a是int类型,13/5得到一个浮点类型,浮点类型转成整数类型的原则是,不四舍五入,只取整数部分,小数部分直接丢弃。.

G:\dev2\idea_workspace\MyJavaTools\RunableTools\src\base\Test.java
1
2
3
4
5
6
7
public class Test {
public static void main(String[] args) {
for (double i = 1.0; i < 2.2; i = i + 0.1000000000000000) {
System.out.println("double(" + i + ") \tto int(" + (int) i+")");
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
double(1.0)	to int(1)
double(1.1) to int(1)
double(1.2000000000000002) to int(1)
double(1.3000000000000003) to int(1)
double(1.4000000000000004) to int(1)
double(1.5000000000000004) to int(1)
double(1.6000000000000005) to int(1)
double(1.7000000000000006) to int(1)
double(1.8000000000000007) to int(1)
double(1.9000000000000008) to int(1)
double(2.000000000000001) to int(2)
double(2.100000000000001) to int(2)

可以看到,double转int的时候,只保留浮点数中的整数部分,小数部分全部丢弃。

考点5:面向对象的三大特征

面向对象的基本特征是()

  • A 封装
  • B 继承
  • C 重载
  • D 多态
显示答案/隐藏答案正确答案: ABD

三大基本特征:封装、继承、多态

1、封装
2、继承
3、多态

五大基本原则

1、单一职责原则(SRP)
2、开放封闭原则(OCP)
3、里氏替换原则(LSP)
4、依赖倒置原则(DIP)
5、接口隔离原则(ISP)

1.单一职责原则

就一个类而言,应该仅有一个引起它变化的原因。

2.开放-封闭原则

一个软件实体应当对扩展开放,对修改关闭

3.里氏代换原则

子类型(subtype)必须能够替换它们的基(父)类型

4.依赖倒转(置)原则

要依赖于抽象,不要依赖于具体

5.接口隔离原则

使用多个专门的接口比使用单一的总接口总要好

考点6:标识符规则

下面哪些标识符是正确的?

  • A MyWorld
  • B parseXML
  • C –value
  • D &maybe
显示答案/隐藏答案正确答案: AB

Java中标识符规则

  • 字母数字美元符号$、**下划线_**4种组成,
  • 不能以数字开头,
  • 不能是保留字和关键字
  • 不能是true,false,null等引用常量

C语言标识符规则

  • 标识符由字母(A-Z,a-z)、数字(0-9)、下划线“_”组成,
  • 首字符不能是数字,但可以是字母或者下划线
  • 不能是保留字和关键字

Java标识符字符构成比C语言的多了一个美元符$

考点7:java有哪些包装类

下面属于java包装类的是?

  • A String
  • B Long
  • C Character
  • D Short
显示答案/隐藏答案正确答案: BCD

基本数据类型及其包装类对照表

基本数据类型 包装类
byte Byte
boolean Boolean
short Short
char Character
int Integer
long Long
float Float
double Double

String既不是包装类,也不是基本类型

考点8:反射机制能做什么

JAVA反射机制主要提供了以下哪些功能?

  • A 在运行时判断一个对象所属的类
  • B 在运行时构造一个类的对象
  • C 在运行时判断一个类所具有的成员变量和方法
  • D 在运行时调用一个对象的方法
显示答案/隐藏答案正确答案: ABCD

A: Class.isInstance();
B: Class.newInstance();
C: Class.getMethod(); Class.getField();
D: Method.invoke();

Class类方法

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html#method.summary
https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#method.summary

image-20210908162522801

考点9:常识 面向对象程序设计优点

面向对象程序设计方法的优点包含:

  • A 可重用性
  • B 可扩展性
  • C 易于管理和维护
  • D 简单易懂
显示答案/隐藏答案正确答案: ABC

考点1:java基础知识 boolean表达式

设有定义 int a=3 ,b=4,c=5; 则以下的表达式中 , 值为 false 的是 ()

  • A a < b && b < c
  • B a <= b
  • C a < ( b + c )
  • D ! ( a < b )

解析

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

拓展:单与和双与的区别

  • &&&都是逻辑运算符,都是判断两边同时真则为真,否则为假;
    • 但是&&当第一个条件不成之后,后面的条件都不执行了,而&则还是继续执行,直到整个条件语句执行完为止。
  • |||都是逻辑只要两个数任意一个为真,条件就为真。
    • 同上,||也具有短路效果。

双与有短路功能,单与可以进行位运算

考点2:java基础知识 Object类

Java中所有类的父类是( )。

  • A Father
  • B Dang
  • C Exception
  • D Object

解析

显示答案/隐藏答案正确答案: D
  • java中Object是所有类的父亲,
  • 所有类的对象都是Class的实例。

考点3:实现多个接口的正确写法

在java中,已定义两个接口B和C,要定义一个实现这两个接口的类,以下语句正确的是()

  • A interface A extends B,C
  • B interface A eimplements B,C
  • C class A implements B,C
  • D class A implements B,implements C

解析

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

实现多个接口时只需要写一个implements

类实现多个接口的时候,只需要一个implements,多个接口通过逗号进行隔开,

先继承类,再实现接口

考点4:Servlet生命周期

J2EE中,当把来自客户机的HTTP请求委托给servlet时,会调用HttpServlet的( )方法

  • A service
  • B doget
  • C dopost
  • D init

解析

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

HttpServlet容器响应Web请求流程

HttpServlet容器响应Web客户请求流程如下:
1)Web客户向Servlet容器发出Http请求;
2)Servlet容器解析Web客户的Http请求;
3)Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息;
4)Servlet容器创建一个HttpResponse对象;
5)Servlet容器调用HttpServlet的service方法,这个方法中会根据request的Method来判断具体是执行doGet还是doPost,把HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象;
6)HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息;
7)HttpServlet调用HttpResponse的有关方法,生成响应数据;
8)Servlet容器把HttpServlet的响应结果传给Web客户。

doGet()

doPost()
是创建HttpServlet时需要覆盖的方法.

Servlet生命周期三个阶段

1.初始化阶段,调用init()方法
2.响应客户请求阶段,调用service()方法
3.终止阶段,调用destroy()方法

考点5:类的加载顺序 父类静态块 子类静态块 main方法 父类构造块 父类构造器 子类构造块 子类构造器

关于以下application,说法正确是什么?

1
2
3
4
5
6
7
8
9
public class Test {
static int x=10;
static {x+=5;}
public static void main(String[] args) //4
{
System.out.println("x="+x);
}
static{x/=3;};
}//9
  • A 4行与9行不能通过编译,因为缺少方法名和返回类型
  • B 编译通过,执行结果是:x=5
  • C 编译通过,执行结果是:x=3
  • D 9行不能通过编译,因为只能有一个静态初始化器

解析

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

类的初始化顺序

G:\dev2\idea_workspace\MyJavaTools\RunableTools\src\base\test\B.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class A{
static {
System.out.println("父类 静态 代码块");
}
public A(){
System.out.println("父类 构造 方法");
}
{
System.out.println("父类 初始化 代码块");
}
}
public class B extends A{
static{
System.out.println("子类 静态 代码块");
}
public B(){
System.out.println("子类 构造 方法");
}
{
System.out.println("子类 初始化 代码块");
}
public static void main(String[] args){
System.out.println("main方法 执行");
{
System.out.println("main方法 代码块1");
}
new B();
{
System.out.println("main方法 代码块2");
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
父类 静态 代码块
子类 静态 代码块
main方法 执行
main方法 代码块1
父类 初始化 代码块
父类 构造 方法
子类 初始化 代码块
子类 构造 方法
main方法 代码块2

静态代码块先于 主方法执行,静态代码块之间遵从代码顺序执行
所以:先初始化静态变量

1
x=10;//x=10

执行第一个静态代码块,

1
x=x+5; //x=15

执行第二静态代码块

1
x=x/3; //x=5

执行主方法: 输出x=5

拓展一下,在类中定义的{}之间被称为构造块,构造块相对于构造方法先执行,构造块之间按照代码编译顺序执行

此外还有普通代码块,存在于方法之中。
贴出参考文章:http://www.cnblogs.com/sophine/p/3531282.html

考点6:还没了解hibernate

下面关于hibernate核心接口说明错误的是?

  • A Configuration 接口:配置Hibernate,根据其启动hibernate,创建SessionFactory 对象
  • B SessionFactory 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的,避免多个线程共享同一个session,是轻量级、一级缓存
  • C QueryCriteria 接口:执行数据库的查询
  • D Transaction 接口:管理事务

解析

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

B选项中应该是Session接口而不是SessionFactory接口
1,Configuration接口:配置Hibernate,根据其启动Hibernate,创建SessionFactory对象;
2,SessionFactory接口:初始化Hibernate,充当数据存储源的,创建session对象,SessionFactory是线程安全的,意味着它的同一个实例可以被应用的多个线程共享,是重量级二级缓存;
3,session接口:负责保存、更新、删除、加载和查询对象,是一个非线程安全的,避免多个线程共享一个session,是轻量级,一级缓存。
4,Transaction接口:管理事务。可以对事务进行提交和回滚;
5,Query和Criteria接口:执行数据库的查询。

考点7:堆外内存 off-heap 还没学到

off-heap是指那种内存()

  • A JVM GC能管理的内存
  • B JVM进程管理的内存
  • C 在JVM老年代内存区
  • D 在JVM新生代内存

解析

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

堆外内存

off-heap叫做堆外内存,将你的对象从堆中脱离出来序列化,然后存储在一大块内存中,这就像它存储到磁盘上一样,但它仍然在RAM中。对象在这种状态下不能直接使用,它们必须首先反序列化,也不受垃圾收集。
序列化和反序列化将会影响部分性能(所以可以考虑使用FST-serialization)使用堆外内存能够降低GC导致的暂停。
堆外内存不受垃圾收集器管理,也不属于老年代,新生代。

考点8:Servlet生命周期

servlet周期包含哪些:

  • A 初始化
  • B 销毁
  • C 请求处理
  • D 开始

解析

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

Servlet生命周期3个阶段

1)初始化阶段:调用init方法
2)响应客户请求:调用service
3)终止:调用destory方法

初始化阶段

在下列时刻servlet容器装载servlet
1 servlet容器启动时,自动装载某些servlet
2 在servlet容器启动后,客户首次向servlet发送请求
3 servlet类文件被更新之后,重新装载servlet

Servlet被装载之后,servlet容器创建一个servlet对象并调用servlet的init方法,在servlet生命周期内,init方法只能被调用一次。

servlet工作原理

客户端发起一个请求,servlet调用service方法时请求进行响应,service对请求的方式进行了匹配,选择调用doPost或者doGet等这些方法,然后进入对应方法中调用逻辑层的方法,实现对客户的响应。

响应客户请求

对于用户到达servlet的请求,servlet容器会创建特定于该请求的ServletRequest和ServletResponse对象,然后调用servlet的service方法,service方法从ServletRequest对象中获取客户请求的信息,处理该请求,并且通过ServletResponse对象向客户端返回响应信息。

终止

当web应用终止或者servlet容器终止或servlet容器重新装载servlet新实例时,servlet容器会调用servlet对象的destory方法,在destory方法中可以释放servlet占用的资源

考点9:类的加载顺序 静态块 main 构造块 构造器

关于以下代码的说明,正确的是( )

1
2
3
4
5
6
7
8
9
10
class StaticStuff
{
static int x=10;
static { x+=5;}
public static void main(String args[ ])
{
System.out.println("x=" + x);
}
static { x/=3;}
}
  • A 4行与9行不能通过编译,因为缺少方法名和返回类型
  • B 9行不能通过编译,因为只能有一个静态初始化器
  • C 编译通过,执行结果为:x=5
  • D 编译通过,执行结果为:x=3

解析

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

同上第5题

考点10:JVM相关 还没学到

关于OutOfMemoryError,下面说法正确的是()?

  • A java.lang.OutOfMemoryError: PermGen space 增加-XX:MaxPermSize这个参数的值的话,这个问题通常会得到解决。
  • B java.lang.OutOfMemoryError: Requested array size exceeds VM limit当你正准备创建一个超过虚拟机允许的大小的数组时,这条错误将会出现
  • C java.lang.OutOfMemoryError: Java heap space 一般情况下解决这个问题最快的方法就是通过-Xmx参数来增加堆的大小
  • D java.lang.OutOfMemoryError: nativeGetNewTLA这个异常只有在jRockit虚拟机时才会碰到

解析

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

关于此题,《深入理解java虚拟机》有关于OOM(OutOfMemory)问题的解释
A:属于运行时常量池导致的溢出,设置-XX:MaxPermSize可以解决这个问题,
B:属于堆空间不足导致的错误,问题比较少见,解决方式和C相同,
C:属于java堆内存问题,一般的手段是通过内存映像分析工具,对Dump出来的堆转储存快照进行分析,重点是确认内存中的对象是否是有必要的,也就是要判断是出现了内存泄漏,还是出现了内存溢出,如果是内存列楼,通过工具检查泄露对象打GC Roots的引用链信息,可以准确的确定出泄露代码的位置,不存在泄露,就应该检查虚拟机的堆参数,如果可以继续调大,可以设置-Xmx解决问题
D:java.lang.OutOfMemoryError: nativeGetNewTLA指当虚拟机不能分配新的线程本地空间(Thread Local Area)的时候错误信息,此错误是线程申请一个新的TLA时产生的,这个异常一般只会发生在jRockit虚拟机,只有过于绝对。

考点1:C语言命名规则

以下叙述中正确的是()

  • A 语言中的关键字不能作变量名,但可以作为函数名
  • B 标识符的长度不能任意长,最多只能包含16个字符
  • C 标识符可以由字母、数字和下划线组成,且第一个字符不得为数字
  • D 用户自定义的标识符必须”见名知义”,如果随意定义,则会出编译错误

解析

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

C语言标识符命名规则

解析:【解析】
C语言中的关键字即不能做变量名也不能做用户函数名,所以A错误。

标识符的命名规则,即:

  1. 由下划线、字母、数字组成,
  2. 且不能以数字开头,可以就是必须以下划线或字母开头,
  3. 也不能和关键字一致。

不同C语言规定标识符的有效长度可能会不同,但没有限制最大长度,所以B错误。

用户定义的标识符只要满足标识符命名规则没有特殊要求,不必一定”见名知义”,所以D错误。

考点2:排错法?

小孙发现某学生成绩管理系统运行后,不能正常处理分数为90分的成绩。于是小孙再次设计了多个成绩数据进行测试,又发现了它对一些特定分数的成绩处理有错。小孙从所有错误结果中归纳征兆,从而确定错误是由于程序对个位数为0的整数成绩处理有误。小孙排错采用的方法是( )。

  • A 归纳排错法
  • B 演绎排错法
  • C 回溯排错法
  • D 穷举排错法

解析

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

考点3:源程序转换为可执行程序要经过的步骤

用高级语言编写的源程序转化为可执行程序,必须经过()。

  • A 汇编和解释
  • B 编辑和链接
  • C 编译和链接
  • D 解释和编译

解析

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

一个计算机程序执行的过程可分为编辑、编译、连接和运行四个过程。用高级语言编写程序的过程称为编辑,之后利用编译程序从源语言编写的源程序产生目标程序的过程称为编译,翻译完的目标程序不能立即被执行,要通过连接将目标程序和有关的系统函数库以及系统提供的其他信息连接起来,形成一个可执行程序。综上所述,用高级语言编写的源程序,将其转化成能在计算机上运行的程序过程是编辑、编译、连接。

考点4:汉字输入码

在拼音输入法中,输入拼音”zhengchang”,其编码属于( )。

  • A 字形码
  • B 地址码
  • C 外码
  • D 内码

解析

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

外码 汉字输入码

汉字输入码是为使用户能够使用西文键盘输入汉字而编制的编码,也叫外码。

汉字输入码分类

汉字输入码有多种不同的编码方案,大致包括:

  1. 音码(以汉语拼音字母和数字为汉字编码)、
  2. 音形码(以拼音为主,辅以字形字义进行编码)、
  3. 形码(根据汉字的字形结构对汉字进行编码)和
  4. 数字码(直接用固定位数的数字给汉字编码)4类。

故正确答案为C选项。

考点5:C++重载运算符

在表达式 +y*z 中, + 是作为成员函数重载的运算符, * 是作为非成员函数重载的运算符。则 operator+ 有______个参数, operator* 有________参数。 ( )

  • A 2、2
  • B 2、1
  • C 1、1
  • D 1、2

解析

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

运算符可重载为成员函数,也可重载为非成员函数函数。

  • 当重载为成员函数时,运算符重载函数的形参个数要比运算符操作数的个数少一个
  • 当重载为非成员函数时,其形参个数应与操作数的个数相同

考点6:位运算

下面有关位运算的一些结论哪些是正确的 ( )

  • A 十二进制数81的二进制数为: 01100001
  • B 十进制数-11的补码为:11110101
  • C 十进制数76和81异或的结果为十进制数28
  • D 位运算(A|B)&C = (A&C)|(B&C)
  • E 加法运算等同于位或运算,如A+B=A|B
  • F 与二进制数00101101等值的十六进制数是2C

解析

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

A选项 N进制数转10进制数:按权展开

十二进制的81转10进制

$$
(81)_{12}=8\times 12^1+1\times 12^0=96+1=97
$$

二进制01100001转10进制

$$
(01100001)_{2}=0+1\times 2^6+1\times 2^5+0+0+0+0+1=2^6+2^5+1=64+32+1=96+1=97
$$

所以A正确

B选项 原码反码补码

正数的原码,反码,补码都一样

原码

原码是直接将一个数值换算成二进制数。最高位为符号位,正数为0,负数为1

反码

正数的反码是就是原码

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

补码的计算规则

计算机以补码的形式保存所有的整数。

  • 正数的补码和原码完全相同,

  • 负数的补码是其反码加1;

    负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1.(即在反码的基础上+1)

$$
(-11)=8+2+1
$$

补码转原码

补码的补码就是原码,就像负负得正一样

二进制十进制转换表

2^n 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
128 64 32 16 8 4 2 0
-11原码 1 0 0 0 1 0 1 1
-11反码 1 1 1 1 0 1 0 0
-11补码 1 1 1 1 0 1 0 1

所以
$$
(-11){原码}=1000 1011 \newline
(-11)
{反码}=1000 0100 \newline
(-11)_{补码}=1111 0101
$$

所以B选项正确

C选项 亦或运算

如果a、b两个值不相同,则异或结果为1。
如果a、b两个值相同,异或结果为0。

相同为0,相异为1

亦或真值表

a b a⊕b
0 0 0
0 1 1
1 0 1
1 1 0

求解过程

76展开:

1
2
3
76-64=12
12-8=4
4-4=0

81展开:

1
2
3
81-64=17
17-16=1
1-1=0
2^n 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
128 64 32 16 8 4 2 0
+76补码 0 1 0 0 1 1 0 0
+81补码 0 1 0 1 0 0 0 1
+76⊕+81补码 0 0 0 1 1 1 0 1

$$
+76⊕81&=&0 0 0 1 1 1 0 1 \newline
&=&16+8+4+1 \newline
&=&29
$$

所以C选项错误

D选项

位运算(A|B)&C = (A&C)|(B&C)

交换律 结合律 分配律

https://www.shuxuele.com/associative-commutative-distributive.html

交换律

符号相同的时候

$a+b=b+a$

结合律

符号相同的时候

$(a+b)+c=a+(b+c)$

$(a\times b) \times c=a\times (b \times c)$

分配率

符号不同的时候

$a\times (b+c)=a\times b+a\times c$

按位或按位与满足分配率

1
2
3
4
5
6
7
8
public class Test2 {
public static void main(String[] args) {
int A=1;
int B=2;
int C=3;
System.out.println(((A | B) & C) == ((A & C) | (B & C)));
}
}

输出结果:

1
true

E选项

1
2
3
4
5
6
7
int A=-4;
int B=5;
int C=6;
System.out.println(A+B);
System.out.println(A|B);
System.out.println(C+B);
System.out.println(C|B);

运行结果:

1
2
3
4
1
-3
11
7

考点1:联系 一对一,一对多,多对多

学校中有多个院系和多名教师,每个教师只能属于一个院系,一个系可以有多名教师,院系和教师之间的关系是( )。

  • A 一对多
  • B 一对一
  • C 一对二
  • D 多对多

解析

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

考点2:数据库范式

在通常情况下,下面的关系中不可以作为关系数据库的关系是()

  • A R1(学生号,学生名,性别)
  • B R2(学生号,学生名,班级号)
  • C R3(学生号,学生名,宿舍号)
  • D R4(学生号,学生名,简历)

解析

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

1NF是第一范式:数据库中的每一项都是不可分割的基本数据项.

而简历中包含学号与姓名,不满足第一范式。

数据库范式1nf,2nf,3nf

1nf: 每一列原子性,不可再分
2nf: 非主键列完全依赖于(联合)主键
3nf: 非主键直接依赖于主键

考点3:DML语句

以下不属于DML的是?

  • A INSERT
  • B DELETE
  • C CREATE
  • D UPDATE

解析

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

DQL DML DDL DCL

数据查询语言DQL: 由select字句,from字句,Where字句组成的查询块
数据操纵语言DML:insert,update,delete
数据定义语言DDL:Create字句,如创建索引。 表 视图等
数据控制语言DCL:Grant字句,Commit字句,用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等。

考点4:索引

关于数据库的描述错误的是:

  • A 创建索引一定能提升查询时间
  • B 主键的数据列要创建索引
  • C 外键的数据列要建立索引
  • D 常见数据库索引有 Hash 索引,B-tree 索引

解析

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

首先明白为什么索引会增加速度,DB在执行一条Sql语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集合。
如果我们对某一字段增加索引,查询时就会先去索引列表中一次定位到特定值的行数,大大减少遍历匹配的行数,所以能明显增加查询的速度。

那么在任何时候都应该加索引么?这里有几个反例:
1、如果每次都需要取到所有表记录,无论如何都必须进行全表扫描了,那么是否加索引也没有意义了。
2、对非唯一的字段,例如“性别”这种大量重复值的字段,增加索引也没有什么意义。
3、对于记录比较少的表,增加索引不会带来速度的优化反而浪费了存储空间,因为索引是需要存储空间的,而且有个致命缺点是对于update/insert/delete的每次执行,字段的索引都必须重新计算更新,这就拖慢了速度

常见的数据库索引是B-tree索引,虽然Hash 索引效率很高,但是他有很多弊端,比如

Hash 索引仅仅能满足”=”,”IN”和”<=>”查询,不能使用范围查询等,这些弊端导致其不是常见的数据库索引。

考点5:数据模型及其数据结构

关系数据模型的基本数据结构是( )

  • A 树
  • B 图
  • C 索引
  • D 关系

解析

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

关系数据模型的逻辑结构是关系
层次数据模型的逻辑结构是
网状数据结构的逻辑结构是

关系模型的数据结构是关系,数据的逻辑结构是二维表。

考点6:SQL创建主键 SQL删除主键

下面Transact-SQL语句中可以用于创建主键的是()

  • A alter table table1 with notcheck add constraint [PK_table1] primary key nonclustered (column1) on primary;
  • B alter table table1 column1 primary key;
  • C alter table table1 column1;
  • D create table table1 (column1 char(13) not null primary,column2 int not) on primary;

解析

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

删除主键

表中删除主键为:

1
alert table table_test drop primary key;

添加主键

表中增加主键为:

1
alert table table_test add primary key(id);

注意add,B,C,D都没有add关键字,可以排除。

考点7:分布式数据库系统DDBS

在DDBS中,数据传输量是衡量查询时间的一个主要指标,导致数据传输量大的主要原因是( )。

  • A 场地间距离过大
  • B 数据库的数据量大
  • C 不同场地间的联接操作
  • D 在CPU上处理通信的代价高

解析

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

DDBS:Distributed DataBase System 分布式数据库系统

考点8:数据库技术的根本目标

数据库技术的根本目标是要解决数据的 ( ) 。

  • A 存储问题
  • B 共享问题
  • C 安全问题
  • D 保护问题

解析

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

数据库的直接目标是解决数据存储问题,根本目标是为了不同用户或应用程序之间的数据共享。

考点9:视图可以从哪里导出

视图是由下面哪两者导出的表()。

  • A 模式、关系
  • B 基本表、视图
  • C 基本关系、关系
  • D 内模式、外模式

解析

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

SQL中,内模式模式、外模式分别对应存储文件基本表、视图

考点10:MySQL SQL注入

Mysql sql注入中使用延时注入时常用的语句是()

  • A wait for delay '0:0:10
  • B sleep(5)
  • C benchmark(100000000,md5(1))
  • D union select

解析

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

函数注入

MySQL benchmark(100000,md5(1))或者sleep(5)
PostgreSQL PG_SLEEP(5)或者 GENERATE_SERIES(1,100000)
MS SQL server WAITFOR DELAY ‘0:05’

这里有一张图片

考点1:Java内存结构图

定义:String s1 = "uml"; String s2 = "uml"; String s3= new String("uml"); String s4= new String("uml");那么,s1==s2;s3 == s4;s1.equals(s3);判断正确与否

  • A T,F,T
  • B F,T,F

解析

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

该题考察的是String类创建的对象在JVM中的内存分配equals”与“==”的区别

  • “==”比较的是地址和值

  • “equals”比较的是

  • s1==s2,比较的是比较的是地址和值,由上图得知两个引用指向的是同一个地址,所以返回true.

  • s3 == s4,比较的是两个new出来开辟的空间对象地址,所以地址不同,返回false.

  • s1.equals(s3),比较的是内容,返回true

==:比较两个引用的地址和值
equals:比较两个引用的值
1、s1==s2 true s1和s2指向字符串常量池中同一个地址
2、s3 和 s4 都显示使用了new,是不同的对象, 当然不相等
3、s1 和 s3 的值都是 “uml”,当然相等

考点2:Applet

在 Applet 中,方法执行的顺序是 ?( )

  • A init(), start(), paint(),stop(),destroy().
  • B init(),paint(),start(),stop(),destroy().
  • C paint(),start(),stop(),destroy().
  • D init(), start(),stop(),destroy(),paint().

解析

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

考点3:abstract和final矛盾

abstract和final可以同时作为一个类的修饰符。( )

  • A 正确
  • B 错误

解析

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

1、abstract期待子类扩展
2、final禁止扩展

abstract和final矛盾

abstract修饰的类需要被继承,而final修饰的类不可被继承,自相矛盾。
拓展:
一、抽象类的使用原则如下:
(1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
(2)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;
(3)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;
(4)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为abstract类。
二、final关键字:
(1)修饰变量 : 变量不可修改;
(1)修饰方法 : 方法不可重写;
(1)修饰类 :类不可继承。

考点4:常识

Web客户端的编程语言JavaScript源自Java,其功能是Java SE的子集。

  • A 对
  • B 错

解析

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

考点5:一切皆对象

以下说法错误的是()

  • A 数组是一个对象
  • B 数组不是一种原生类
  • C 数组的大小可以任意改变
  • D 在Java中,数组存储在堆中连续内存空间里

解析

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

Java中数组是对象,不是基本数据类型(原生类),大小不可变且连续存储,因为是对象所以存在堆中。

  1. 数组的创建使用了new关键字,所以数组是一个对象
  2. java数据类型分为基本数据类型(又叫原生类、内置类)和引用数据类型,数组是后者
  3. 数组在new的时候内存空间就已经分配好了,不允许改变
  4. 数组是一个对象,对象在内存中如何存放同样适用于数组

原生类有8种:int 、double、 boolean 、float 、byte、 short 、long、 char 。数组是引用数据类型,不属于原生类。
数组长度在定义数组的时候就确定了,长度不可变,数组扩容需要使用函数ArrayCopy复制一个新数组
数组是对象,所以存在堆内存中。

考点6:Hibernate

下面关于hibernate核心接口说明错误的是?

  • A Configuration 接口:配置Hibernate,根据其启动hibernate,创建SessionFactory 对象
  • B SessionFactory 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的,避免多个线程共享同一个session,是轻量级、一级缓存
  • C QueryCriteria 接口:执行数据库的查询
  • D Transaction 接口:管理事务

解析

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

B选项中应该是Session接口而不是SessionFactory接口
1,Configuration接口:配置Hibernate,根据其启动Hibernate,创建SessionFactory对象;
2,SessionFactory接口:初始化Hibernate,充当数据存储源的***,创建session对象,SessionFactory是
线程安全的,意味着它的同一个实例可以被应用的多个线程共享,是重量级二级缓存;
3,session接口:负责保存、更新、删除、加载和查询对象,是一个非线程安全的,避免多个线程共享一个session,是轻量级,一级缓存。
4,Transaction接口:管理事务。可以对事务进行提交和回滚;
5,Query和Criteria接口:执行数据库的查询。

考点7:final成员变量不会默认初始化,必须手动初始化

1
2
3
4
5
6
7
class Foo {
final int i;
int j;
public void doSomething() {
System.out.println(++j + i);
}
}

的输出是?

  • A 0
  • B 1
  • C 2
  • D 不能执行,因为编译有错

解析

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

final成员变量的初始化

final作为对象成员存在时,必须初始化;
1、定义时就初始化
2、先定义,后初始化。先定义,然后在构造函数中初始化话,或者在代码块中初始化。

E:\dev2\workspace\NiKeTest\src\finaltest\FinalTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package finaltest;

public class FinalTest {
// final成员变量,定义的时候就赋值
public final int num1 = 1;
// 先定义,后赋值。
public final int num2;
// 先定义,后赋值
public final int num3;

{
// 在代码块中初始化
num3 = 3;
}

public FinalTest(int num) {
// 在构造函数中初始化
this.num2 = num;
}

public static void main(String[] args) {
FinalTest f1 = new FinalTest(2);
FinalTest f2 = new FinalTest(100);
System.out.println(f1.num1);
System.out.println(f1.num2);
System.out.println(f1.num3);
System.out.println("============================");
System.out.println(f2.num1);
System.out.println(f2.num2);
System.out.println(f2.num3);
}
}

运行效果:

1
2
3
4
5
6
7
1
2
3
============================
1
100
3

final成员先定义后赋值的优点: 不同的对象的final成员可以不一样

从上面的代码中可以看出,定义final成员变量时不初始化,而在构造器中初始化的好处就在于。这个final成员的值是可变的。
如果在定义的时候就初始化,或者在代码块中初始化话。
所有的对象的这个final成员都是一样的,做不到不同的对象的final变量不一样这样的功能。

如果定义的时候没有赋值,并且没有构造器,则会在变量处显示错误提示:

1
The blank final field num2 may not have been initialized

如果定义时,没有赋值,并且有构造器,则会在构造器处显示错误提示:

1
The blank final field num4 may not have been initialized

考点8:JDK1.7之前的抽象类和接口特性

在jdk 1.7中,以下说法正确的是( )。

  • A Java中所有的非抽象方法都必须在类内定义
  • B Java中主方法可以不在类内定义,其他方法都必须定义在类内
  • C Java中主方法必须定义在类内,其他方法可以不必定义在类内
  • D Java中所有方法都不必在类内定义

解析

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

我想这题纯粹是想考察JDK1.8和1.9的接口新特性(因为其提到JDK1.7)
JDK1.8接口可以定义default方法和static方法;
JDK1.9接口中可以定义私有方法。
因此在JDK1.7中,接口只能定义抽象方法,既Java中所有的非抽象方法都必须在类内定义。

考点9:volatile关键字

volatile关键字的说法错误的是

  • A 能保证线程安全
  • B volatile关键字用在多线程同步中,可保证读取的可见性
  • C JVM保证从主内存加载到线程工作内存的值是最新的
  • D volatile能禁止进行指令重排序

解析

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

出于运行速率的考虑,java编译器会把经常经常访问的变量放到缓存(严格讲应该是工作内存)中,读取变量则从缓存中读。但是在多线程编程中,内存中的值和缓存中的值可能会出现不一致。
volatile用于限定变量只能从内存中读取,保证对所有线程而言,值都是一致的
但是volatile不能保证原子性,也就不能保证线程安全

1.java的内存模型

java 内存模型规定了所有的变量都存储在主内存中,但是每个线程会有自己的工作内存,线程的工作内存保存了该线程中使用了的变量(从主内存中拷贝的),线程对变量的操作都必须在工作内存中进行,不同线程之间无法直接访问对方工作内存中的变量,线程间变量值从传递都要经过主内存完成

图片说明

2.什么是原子性

一个操作是不可中断的,要么全部执行成功要么全部执行失败,比如银行转账

3.什么是可见性

当多个线程访问同一变量时,一个线程修改了这个变量的值,其他线程就能够立即看到修改的值

4.什么是有序性

程序执行的顺序按照代码的先后顺序执行

1
2
int a = 0; //1
int b = 2; //2

像这2句代码1会比2先执行,但是jvm在正真执行时不一定是1在2之前,

这里涉及一个概念叫做指令重排,处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。

比如上面的代码语句1和语句2谁先执行对最终的程序结果并没有影响,那么就有可能在执行过程中,语句2先执行而语句1后执行。
在指令重排时会考虑指令之间的数据依赖性,比如2依赖了1的数值,那么处理器会保证1在2之前执行。

但是在多线程的情况下,指令重排就会有影响了。

5.volatile功能 volatile到底做了什么

  • 禁止了指令重排
  • 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量值,这个新值对其他线程是立即可见的
  • 不保证原子性(线程不安全)

考点1:子类能访问父类的那些成员

C#、JAVA)扩展方法能访问被扩展对象的public成员

  • A 能
  • B 不能

解析

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

翻译一下,子类方法是否能够访问父类中的public成员。

考点2:构造方法

以下有关构造方法的说法,正确的是:()

  • A 一个类的构造方法可以有多个
  • B 构造方法在类定义时被调用
  • C 构造方法只能由对象中的其他方法调用
  • D 构造方法可以和类同名,也可以和类名不同

解析

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

A 一个类有多个构造方法便是重载的表现。重载参数列表不同。所以A是正确的。
B 构造方法是在对象创建时就被调用,用于初始化。
C 构造方法是给与之对应的对象进行初始化,初始化的动作只执行一次。
D 构造方法必须与所在类的名称同名。

B、构造器在对象被实例化的时候调用
C、构造方法不能由对象中的其他方法调用。都是new出来或者利用了反射。
D、构造方法必须与类同名,且没有返回值(不同于void)。

考点3:线程执行体run() 启动线程start()

以下哪个方法用于定义线程的执行体?

  • A start()
  • B init()
  • C run()
  • D synchronized()

解析

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

run()用于定义线程执行体,
start()用于启动线程

考点4:重载

对于同一类中的两个方法 , 在判断它们是不是重载方法时 , 肯定不考虑( )

  • A 参数个数
  • B 参数类型
  • C 返回值类型
  • D 参数顺序

解析

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

方法重写的注意事项:
构造方法不能被重写,不要问为什么?因为构造方法名必须和类名相同
private修饰的成员方法不能被重写
static修饰的方法不能被重写
final修饰的方法不能被重写
当子类重写了父类中的方法后,子类对象调用该方法时调用的是子类重写后的方法

子类的实例方法不能重写父类的静态方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package extendstest;

public class Parent {
// 父类中的static方法
protected static void staticMethod() {
System.out.println("Static method in parent class");
}

// 父类中的非static方法
public void nonStaticMethod() {
System.out.println("Non static method in parent class");
}

// 父类中的final方法
protected final void finalMethod() {
System.out.println("Final method in parent class");
}
}

class Son extends Parent {
// 子类可以重写父类的protected 非static方法
@Override
public void nonStaticMethod() {
super.nonStaticMethod();
}

// 子类无法重写父类的static方法
@Override
public void staticMethod() {
System.out.println("Static method in parent class");
}

@Override
public final void finalMethod() {
System.out.println("Final method in son class");
}
}

子类的staticMethod方法报错如下:

Multiple markers at this line
    - This instance method cannot override the static method from Father
    - overrides extendstest.Father.canYouSeeStatic
    - The method canYouSeeStatic() of type Son must override or implement a supertype method

意思是子类的实例方法不能重写父类的静态方法

给子类中的staticMethod加上static修饰符:

    // 子类无法重写父类的static方法
    @Override
    public static void staticMethod() {
        System.out.println("Static method in parent class");
    }

还是不可以重写,报错如下:

The method staticMethod() of type Son must override or implement a supertype method

子类的finalMethod方法报错如下:

Multiple markers at this line
    - Cannot override the final method from Parent
    - overrides extendstest.Parent.finalMethod

可以定义与父类同名的Static方法

去掉子类的staticMethod()方法上面的@Override,则不会报错。
这不是重写,无法实现多态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package extendstest;

public class Parent {
// 父类中的static方法
protected static void staticMethod() {
System.out.println("Static method in parent class");
}

// 父类中的非static方法
public void nonStaticMethod() {
System.out.println("Non static method in parent class");
}

// 父类中的final方法
protected final void finalMethod() {
System.out.println("Final method in parent class");
}

public static void main(String[] args) {
Parent parent = new Son();
// 调用的还是父类的静态方法,不能实现多态
parent.staticMethod();
// 调用的是子类的方法,多态
parent.nonStaticMethod();
}
}

class Son extends Parent {
// 子类可以重写父类的protected 非static方法
@Override
public void nonStaticMethod() {
System.out.println("Static method in Son class");
}

// 子类无法重写父类的static方法
// @Override
// 子类可以定义与父类相同的静态方法
public static void staticMethod() {
System.out.println("Static method in Son class");
}

}

运行效果:

1
2
Static method in parent class
Static method in Son class

重写描述的是子类实例方法和父类实例方法的关系

static定义的方法时类方法,通过类名调用。
上面的parent.staticMethod();调用实际上还是类名.staticMethod();
也就是Parent.staticMethod();.所以不会去调用Son类中的同名方法。
如果非要调用子类的同名静态方法的话,需要改成:Son.staticMethod()

static方法如何实现”多态”

使用子类来调用覆盖的static方法,如果子类中有该静态方法,则执行子类的静态方法。
如果子类没有该静态方法,则去父类中查找静态方法,如果有则执行父类的静态方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package extendstest;

public class Parent {
// 父类中的static方法
protected static void staticMethod() {
System.out.println("Static method in parent class");
}

// 父类中的非static方法
public void nonStaticMethod() {
System.out.println("Non static method in parent class");
}

// 父类中的final方法
protected final void finalMethod() {
System.out.println("Final method in parent class");
}

public static void main(String[] args) {
Son son = new Son();
Parent parent = son;
// 调用的还是父类的静态方法,不能实现多态
parent.staticMethod();
// 调用的是子类的方法,多态
parent.nonStaticMethod();
// 调用子类的静态方法,如果子类定义了该静态方法,
// 则调用子类的,如果没有则去父类中查找
// son.staticMethod();
Son.staticMethod();
}
}

class Son extends Parent {
// 子类可以重写父类的protected 非static方法
@Override
public void nonStaticMethod() {
System.out.println("Static method in Son class");
}

// 子类无法重写父类的static方法
// @Override
// 子类可以定义与父类相同的静态方法
public static void staticMethod() {
System.out.println("Static method in Son class");
}

}

运行效果:

1
2
3
Static method in parent class
Static method in Son class
Static method in Son class

此时Son类中重写了父类的静态方法,调用的是重写后的。
如果把Son类中的staticMethod方法注释掉。:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package extendstest;

public class Parent {
// 父类中的static方法
protected static void staticMethod() {
System.out.println("Static method in parent class");
}

// 父类中的非static方法
public void nonStaticMethod() {
System.out.println("Non static method in parent class");
}

// 父类中的final方法
protected final void finalMethod() {
System.out.println("Final method in parent class");
}

public static void main(String[] args) {
Son son = new Son();
Parent parent = son;
// 调用的还是父类的静态方法,不能实现多态
parent.staticMethod();
// 调用的是子类的方法,多态
parent.nonStaticMethod();
// 调用子类的静态方法,如果子类定义了该静态方法,
// 则调用子类的,如果没有则去父类中查找
// son.staticMethod();
Son.staticMethod();
}
}

class Son extends Parent {
// 子类可以重写父类的protected 非static方法
@Override
public void nonStaticMethod() {
System.out.println("Static method in Son class");
}

// // 子类无法重写父类的static方法
// // @Override
// // 子类可以定义与父类相同的静态方法
// public static void staticMethod() {
// System.out.println("Static method in Son class");
// }
}

运行效果:

1
2
3
Static method in parent class
Static method in Son class
Static method in parent class

可以看到,此时调用了从父类继承得到的静态方法。

static方法可以被继承 可以被覆盖 不能被重写

重写,说的是根据运行时的对象类型来决定调用哪个方法,而不是编译时类型。

因为无法使用@Override修饰,所以不是重写。

对于静态方法,我们不应该尝试去重写,而且调用时应该以类进行调用,而不是对象进行调用。

问 static方法可以被重写吗?

答,static方法可以被子类继承,子类可以覆盖继承到的static方法。但是这不叫重写。
因为如果你在同名的static方法上写上@Override注解,编译器会报错。

重写是为了实现多态,多态是在运行的时候根据对象的类型来调用方法的。
如果使用了静态方法,那么在编译期间,就知道调用的是那个静态方法了,这不符合多态的定义。

https://www.jianshu.com/p/df43f5500ea3
静态方法从程序开始运行后就已经分配了内存,也就是说已经写死了。所有引用到该方法的对象(父类的对象也好子类的对象也好)所指向的都是同一块内存中的数据,也就是该静态方法。子类中如果定义了相同名称的静态方法,并不会重写,而应该是在内存中又分配了一块给子类的静态方法,没有重写这一说

考点5:不懂的点:JVM

off-heap是指那种内存()

  • A JVM GC能管理的内存
  • B JVM进程管理的内存
  • C 在JVM老年代内存区
  • D 在JVM新生代内存

解析

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

堆外内存

off-heap叫做堆外内存,将你的对象从堆中脱离出来序列化,然后存储在一大块内存中,这就像它存储到磁盘上一样,但它仍然在RAM中。
对象在这种状态下不能直接使用,它们必须首先反序列化,也不受垃圾收集。
序列化和反序列化将会影响部分性能(所以可以考虑使用FST-serialization)使用堆外内存能够降低GC导致的暂停。
堆外内存不受垃圾收集器管理,也不属于老年代,新生代。

堆外内存意味着把内存对象分配在Java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机)不属于老年代和新生代。

JVM GC回收堆和方法区,排除法选择 B

这样做的结果就是能保持一个较小的堆,以减少垃圾收集对应用的影响。

使用堆外内存能够降低GC导致的暂停。

堆外内存,它和内存池一样,也能缩短垃圾回收时间,但是它适用的对象和内存池完全相反。
内存池往往适用于生命期较短的可变对象,而生命期中等或较长的对象,正是堆外内存要解决的。

堆外内存的特点

https://blog.csdn.net/universe_ant/article/details/52145450
堆外内存有以下特点:

  • 对于大内存有良好的伸缩性
  • 对垃圾回收停顿的改善可以明显感觉到
  • 在进程间可以共享,减少虚拟机间的复制

当然堆外内存也有它自己的问题,

  • 最大的问题就是你的数据结构变得不那么直观,如果数据结构比较复杂,就要对它进行串行化(serialization),而串行化本身也会影响性能。
  • 另一个问题是由于你可以使用更大的内存,你可能开始担心虚拟内存(即硬盘)的速度对你的影响了。

1)程序计数器

几乎不占有内存。用于取下一条执行的指令。

2)堆

所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。
堆被划分为新生代和旧生代,
新生代又被进一步划分为Eden和Survivor区,最后Survivor由FromSpace和ToSpace组成,结构图如下所示:

新生代。新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例旧生代。用于存放新生代中经过多次垃圾回收仍然存活的对象。

3)栈

每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数和中间结果。

4)本地方法栈

用于支持native方法的执行,存储了每个native方法调用的状态

5)方法区

存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。
JVM用永久代(PermanetGeneration)来存放方法区,(在JDK的HotSpot虚拟机中,可以认为方法区就是永久代,但是在其他类型的虚拟机中,没有永久代的概念,有关信息可以看周志明的书)可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值。

考点6:异常处理机制

java关于异常处理机制的叙述哪些正确

  • A catch部分捕捉到异常情况时,才会执行finally部分
  • B 当try区段的程序发生异常时,才会执行catch区段的程序
  • C 在try区段不论程序是否发生异常及捕获到异常,都会执行finally部分
  • D 以上都是

解析

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

finally不执行情况

try块执行时,finally表示总是执行。但是

  1. 在try中调用System.exit(0),强制退出了程序,finally块不执行。
  2. 在进入try块前,出现了异常,此时try没有执行,finally块不执行。

考点7:面向对象三大特性

面向对象的程序设计语言具有()等共同特性。

  • A 封装性
  • B 多态性
  • C 简单性
  • D 复杂性
  • E 继承性

解析

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

面向对象OOP三大特性:

  • 继承
  • 封装
  • 多态

准确来说,基于对象和面向对象是有区别的。
基于对象是封装和继承
面向对象是封装、继承和多态
详见 https://blog.csdn.net/jiaruitao777/article/details/99098027

考点8:IO流 字符流字节流

下面哪个流类不属于面向字符的流()

  • A BufferedWriter
  • B FileInputStream
  • C ObjectInputStream
  • D InputStreamReader

解析

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

既然是字符流,那么一般是reader和writer结尾。
Stream结尾的是字节,Reader结尾的是字符

面向字符的输入流类都是Reader的子类,

面向字符的输出流都是类 Writer 的子类

考点9:堆存放对象 栈存放程序

程序中常采用变量表示数据,变量具有名、地址、值、作用域、生存期等属性。关于变量的叙述,()是正确的。

  • A 根据作用域规则,在函数中定义的变量只能在函数中引用
  • B 在函数中定义的变量,其生存期为整个程序执行期间
  • C 在函数中定义的变量不能与其所在函数的形参同名
  • D 在函数中定义的变量,其存储单元在内存的栈区

解析

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

这里主要说明D为什么是对的

首先说明栈内存和堆内存里存放的是什么

  • 栈内存中存放函数中定义的一些基本类型的变量和对象的引用变量;
  • 堆内存中存放new创建的对象和数组。

简单的来说,堆主要是用来存放对象的,栈主要是用来执行程序的

这么做是因为

  • 栈的存取速度快,栈数据可以共享,但是栈中的数据大小和生存期必须确定,缺乏灵活性中存放一些基本类型的对象和对象句柄
  • 堆是操作系统分配给自己内存,由于从操作系统管理的内存分配,所以再分配和销毁时都需要占用时间,因此用堆的效率非常低,但是优点在于编译器不需要指导从堆里分配多少存储控件,也不需要知道存储的数据要再堆里停留多长事件,因此用堆保存数据时会得到更大的灵活性

参考链接:https://blog.csdn.net/wangbo1998/article/details/80379016

D选项不太严谨,如果定义的是引用类型变量,且没有通过逃逸分析,则可能会被分配到堆中,逃逸分析是jdk1.8默认开启的

D选项我给大家说明一下,我觉得题出的不严谨,如果方法中有引用类型的变量,那么存储是在堆中,引用在栈中

考点10:身份证号的正则表达式

多选题
关于身份证号,以下正确的正则表达式为( )

  • A isIDCard=/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/;
  • B isIDCard=/^[1-9]\d{7}((9\d)|(1[0-2]))(([0|1|2]\d)|3[9-1])\d{3}$/;
  • C isIDCard=/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/;
  • D isIDCard=/^[1-9]\d{5}[1-9]\d{3}((9\d)|(1[9-2]))(([0|1|2]\d)|3[9-1])\d{4}$/;

解析

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

身份证构成

15位身份证的构成:六位出生地区码+六位出身日期码+三位顺序码
18位身份证的构成:六位出生地区码+八位出生日期码+三位顺序码+一位校验码

A选项
^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$

  • [1-9]\d{7},有8位,其中前六位是地址码,后两位是年份,00~99年。
  • ((0\d)|(1[0-2])),有两位,表示月份,第一个括号范围位0009,第二个括号的范围位1012,综合得到00~12,符合月份的定义。
  • (([0|1|2]\d)|3[0-1]),有两位,表示日期,第一个括号的范围位0009或者1019或者2029,第2个括号的范围位3031,综合得到00~31,符合月份的定义。这个其实也不严谨,例如2月份,只有28天,或29天。
  • \d{3}有三位,表示顺序码

B选项
^[1-9]\d{7}((9\d)|(1[0-2]))(([0|1|2]\d)|3[9-1])\d{3}$

  • [1-9]\d{7},有8位,其中前六位是地址码,后两位是年份,00~99年。
  • ((9\d)|(1[0-2])),有两位,表示月份,第一个括号的范围位90~99,一年只有12个月份,没有90月份,更没有99月份,B选项排除。

C选项的
^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$

  • [1-9]\d{5}这六位,表示六位出生地码,
    • ^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$
  • [1-9]\d{3}这四位,表示年
    • ^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$
  • ((0\d)|(1[0-2]))这两位表示,月份,从第一个括号匹配00~09。第二个括号匹配10~12
    • ^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$
    • 所以月份共计匹配范围:00~12符合月份00~12的定义。
  • (([0|1|2]\d)|3[0-1])这两位表示日期,第一个括号匹配0009,1019,2029。第二个括号匹配3031。
    • ^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$
    • 所以日期总计匹配范围:00~31,符合日期的定义。
  • \d{4},表示匹配三位顺序吗+一位校验码。校验码有字母,这里显然不能完全匹配,勉强认为校验码都是数字吧。
    • ^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$

D选项
^[1-9]\d{5}[1-9]\d{3}((9\d)|(1[9-2]))(([0|1|2]\d)|3[9-1])\d{4}$

  • [1-9]\d{5},六位地址码
  • [1-9]\d{3},四位年,1000~9999
  • ((9\d)|(1[9-2])),表示月份,9\d的范围位90~99,一年最多有12个月,没有90个月,更没有99个月。所以D选项错误。

考点1:访问控制权限修饰符

下列修饰符中与访问控制权限无关的是?( )

  • A private
  • B public
  • C protected
  • D final

解析

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

java常见修饰符

权限修饰符

private: 修饰私有变量
默认修饰符default(不用把default写出来): 比private限制更少,但比protected限制更多
protected: 修饰受保护变量
public: 修饰公有变量

状态修饰符

final 最终变量(final修饰类,该类不能被继承,final修饰方法,该方法不能被重写,final修饰变量,该变量不能被重新赋值(相当于常量))
static 静态变量(随着类的加载而加载,优先于对象存在,被所有对象所共享,可以通过类名调用)

抽象修饰符

abstract 抽象类&抽象方法(抽象类不能被实例化,抽象类中不一定有抽象方法,但有抽象方法的类必须定义为抽象类)

考点2:main方法

Java Application 中的主类需包含main方法,以下哪项是main方法的正确形参?( )

  • A String args
  • B String[] args
  • C Char arg
  • D StringBuffer[] args

解析

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

考点3:重载

类 ABC 定义如下:

1
2
3
4
public class ABC{
public double max(double a,double b) {}

}

将以下哪个方法插入行 3 是不合法的。()

  • A public float max(float a, float b, float c){ }
  • B public double max (double c, double d){ }
  • C public float max(float a, float b){ }
  • D private int max(int a, int b, int c){ }

解析

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

重载要求:两同一不同

重载要求方法的参数列表需要不一样(个数,或者参数类型),修改参数名或者修改返回值以及访问权限并没有用

考点4:异常try-catch-finally执行流程

AccessViolationException异常触发后,下列程序的输出结果为( )

1
2
3
4
5
6
7
8
9
10
11
12
13
static void Main(string[] args)  
{
try
{
throw new AccessViolationException();
Console.WriteLine("error1");
}
catch (Exception e)
{
Console.WriteLine("error2");
}
Console.WriteLine("error3");
}
  • A
    1
    2
    error2
    error3
  • B error3
  • C error2
  • D error1

解析

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

考点5:集合HashMap的key和value可以为null,放入时如果key相同,则新value覆盖旧的value

以下java程序代码,执行后的结果是()

1
2
3
4
java.util.HashMap map=new java.util.HashMap();
map.put("name",null);
map.put("name","Jack");
System.out.println(map.size());
  • A 0
  • B null
  • C 1
  • D 2

解析

显示答案/隐藏答案正确答案: C
  • HashMap可以插入null的key或value。
  • 插入的时候,检查是否已经存在相同的key,
    • 如果不存在,则直接插入,
    • 如果存在,则用新的value替换旧的value。
      在本题中,第一条put语句,会将key/value对插入HashMap,而第二条put,因为已经存在一个key为name的项,所以会用新的value替换旧的value,
      因此,两条put之后,HashMap中只有一个key/value键值对。那就是(name,jack)。所以,size为1.

考点6:boolean变量只能和boolean变量比较

已知boolean result = false,则下面哪个选项是合法的:

  • A result=1
  • B result=true;
  • C if(result!=0) {//so something…}
  • D if(result) {//do something…}

解析

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

1、boolean类型只有两个直接量值:true和false.
2、除成员变量会有默认初始值外,其他变量必须在第一次使用之前初始化

boolean类型的默认值是false;

基本数据类型的默认值(成员变量)

其余的7种基本类型默认值:
byte是 (byte)0;
short是 (short)0;
int是 0;
long是 0L;
float 是0.0f;
double 是0.0d;
char是 \u0000.
String是null.

考点7:java关键字和常量

下列不是 Java 关键字的是 ( )

  • A abstract
  • B false
  • C native
  • D sizeof

解析

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

Java中的关键字有哪些

答:1)48个关键字:abstractassertbooleanbreakbytecasecatchcharclasscontinuedefaultdodoubleelseenumextendsfinalfinallyfloatforifimplementsimportintinterfaceinstanceoflongnativenewpackageprivateprotectedpublicreturnshortstaticstrictfpsuperswitchsynchronizedthisthrowthrowstransienttryvoidvolatilewhile

Java保留字

2)2个保留字(现在没用以后可能用到作为关键字):gotoconst

Java特殊直接量 Java常量

3)3个特殊直接量:truefalsenull

考点8:暂时不懂:Jvm垃圾回收

以下哪些jvm的垃圾回收方式采用的是复制算法回收

  • A 新生代串行收集器
  • B 老年代串行收集器
  • C 并行收集器
  • D 新生代并行回收收集器
  • E 老年代并行回收收集器
  • F cms收集器

解析

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

答案AD
新生代串行收集/并行回收器:复制算法;
老年代串行收集/并行回收器:标记-压缩算法;
并行收集器:将串行收集器多线程化,回收策略和串行收集器一致,因此该收集器是新生代为复制算法,老年代为标记-压缩算法。
CMS收集器:Concurrent Mark Sweep,从名字就能知道使用的是多线程的标记-清除算法。

在垃圾的分代回收机制中
新生代一般采用“复制”算法:因为新生代每次都有大批量对象死去,就以少量对象的复制成本完成收集
老年代一般采用“标记-整理/清除”算法:因为对象存活率高,且没有额外内存,故采用“标记-整理”或者“标记-清除”

两个最基本的java回收算法:复制算法和标记清理算法

复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。此为新生代最常用的算法
标记清理:一块区域,标记可达对象(可达性分析),然后回收不可达对象,会出现碎片,那么引出 标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象

两个概念:新生代和年老代

新生代:初始对象,生命周期短的
永久代:长时间存在的对象

整个java的垃圾回收是新生代和年老代的协作,这种叫做分代回收
P.S:Serial New收集器是针对新生代的收集器,采用的是复制算法
Parallel New(并行)收集器,新生代采用复制算法,老年代采用标记整理
Parallel Scavenge(并行)收集器,针对新生代,采用复制收集算法
Serial Old(串行)收集器,新生代采用复制,老年代采用标记整理
Parallel Old(并行)收集器,针对老年代,标记整理 CMS收集器,基于标记清理
G1收集器:整体上是基于标记 整理 ,局部采用复制

综上:新生代基本采用复制算法,老年代采用标记整理算法。cms采用标记清理

考点9:int赋值给Integer时自动装箱 Integer自动装箱时-128~+127范围内使用缓存数组中的值 Integer和int比较时自动拆箱然后比较值

1
2
3
4
5
6
Integer a1=17,b2=17;
Integer b1=2017,b2=2017;
Integer c1=new Integer(17);
Integer c2=new Integer(17);
Integer d1=new Integer(2017);
int d2=2017;

以下语句返回值为 true 的2是()

  • A a1==a2
  • B d1==d2
  • C b1==b2
  • D c1==c2

解析

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

Integer缓存-128到+127

A,B. Integer a1 = 17; 语句执行的是valueOf()方法

G:\java\java8\jdk-8u221\src.zip!\java\lang\Integer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
......
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];

static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;

cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);

// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}

private IntegerCache() {}
}
......
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
......

对于-128到127之间的数, Integer直接从数组中取, 故a1, a2指向的是同一个对象, A正确.

其余都是new出来的对象, 显然地址都不相同.

int与Integer比较时 只比较值

int类型与Integer类型比较时, 先将Integer拆箱, 再比较值, 故B正确.

考点10:正则表达式身份证号

关于身份证号,以下正确的正则表达式为( )

  • A isIDCard=/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/;
  • B isIDCard=/^[1-9]\d{7}((9\d)|(1[0-2]))(([0|1|2]\d)|3[9-1])\d{3}$/;
  • C isIDCard=/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/;
  • D isIDCard=/^[1-9]\d{5}[1-9]\d{3}((9\d)|(1[9-2]))(([0|1|2]\d)|3[9-1])\d{4}$/;

解析

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

正确选项
A选项:isIDCard=/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/
C选项:isIDCard=/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/

常用正则表达式

^:起始符号,^x表示以x开头
$:结束符号,x$表示以x结尾
[n-m]:表示从n到m的数字
\d:表示数字,等同于[0-9]
X{m}:表示由m个X字符构成,\d{4}表示4位数字

身份证构成 15位 18位

15位身份证的构成:六位出生地区码+六位出身日期码+三位顺序码
18位身份证的构成:六位出生地区码+八位出生日期码+三位顺序码+一位校验码

C选项的构成:
[1-9]\d{5}:六位出生地区码,出生地区码没有以0开头,因此第一位为[1-9]
[1-9]\d{3}:八位出生日期码的四位年份,同样年份没有以0开头。
((0\d)|(1[0-2])):八位出生日期码的两位月份,| 表示或者,月份的形式为0\d或者是101112
(([0|1|2]\d)|3[0-1]):八位出生日期码的两位日期,日期由01至31。
\d{4}:三位顺序码+一位校验码,共四位。

A选项的构成:
[1-9]\d{7}:六位出生地区码+两位出生日期码的年份,这里的年份指后两位,因此没有第一位不能为0的限制,所以合并了。
后面的与C选项类似了。
好吧其实我也是第一次知道身份证还有15位的。