2021年09月05日 java3

考点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到底做了什么

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