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 错误
解析
显示答案/隐藏答案
正确答案: B1、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
中,数组存储在堆中连续内存空间里
解析
显示答案/隐藏答案
正确答案: CJava中数组是对象,不是基本数据类型(原生类),大小不可变且连续存储,因为是对象所以存在堆中。
- 数组的创建使用了new关键字,所以数组是一个对象
- java数据类型分为基本数据类型(又叫原生类、内置类)和引用数据类型,数组是后者
- 数组在new的时候内存空间就已经分配好了,不允许改变
- 数组是一个对象,对象在内存中如何存放同样适用于数组
原生类有8种:int 、double、 boolean 、float 、byte、 short 、long、 char 。数组是引用数据类型,不属于原生类。
数组长度在定义数组的时候就确定了,长度不可变,数组扩容需要使用函数ArrayCopy复制一个新数组
数组是对象,所以存在堆内存中。
考点6:Hibernate
下面关于hibernate核心接口说明错误的是?
- A
Configuration
接口:配置Hibernate
,根据其启动hibernate
,创建SessionFactory
对象 - B
SessionFactory
接口:负责保存、更新、删除、加载和查询对象,是线程不安全的,避免多个线程共享同一个session
,是轻量级、一级缓存 - C
Query
和Criteria
接口:执行数据库的查询 - D
Transaction
接口:管理事务
解析
显示答案/隐藏答案
正确答案: BB选项中应该是Session接口而不是SessionFactory接口
1,Configuration接口:配置Hibernate,根据其启动Hibernate,创建SessionFactory对象;
2,SessionFactory接口:初始化Hibernate,充当数据存储源的***,创建session对象,SessionFactory是
线程安全的,意味着它的同一个实例可以被应用的多个线程共享,是重量级二级缓存;
3,session接口:负责保存、更新、删除、加载和查询对象,是一个非线程安全的,避免多个线程共享一个session,是轻量级,一级缓存。
4,Transaction接口:管理事务。可以对事务进行提交和回滚;
5,Query和Criteria接口:执行数据库的查询。
考点7:final成员变量不会默认初始化,必须手动初始化
1 | class Foo { |
的输出是?
- A 0
- B 1
- C 2
- D 不能执行,因为编译有错
解析
显示答案/隐藏答案
正确答案: Dfinal成员变量的初始化
final作为对象成员存在时,必须初始化;
1、定义时就初始化
2、先定义,后初始化。先定义,然后在构造函数中初始化话,或者在代码块中初始化。
1 | package finaltest; |
运行效果:
1 | 1 |
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 | int a = 0; //1 |
像这2句代码1会比2先执行,但是jvm在正真执行时不一定是1在2之前,
这里涉及一个概念叫做指令重排,处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。
比如上面的代码语句1和语句2谁先执行对最终的程序结果并没有影响,那么就有可能在执行过程中,语句2先执行而语句1后执行。
在指令重排时会考虑指令之间的数据依赖性,比如2依赖了1的数值,那么处理器会保证1在2之前执行。
但是在多线程的情况下,指令重排就会有影响了。
5.volatile功能 volatile到底做了什么
- 禁止了指令重排
- 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量值,这个新值对其他线程是立即可见的
- 不保证原子性(线程不安全)