1.关于对象成员占用内存的说法哪个正确?( )
A 同一个类的对象共用同一段内存
B 同一个类的对象使用不同的内存段,但静态成员共享相同的内存空间
C 对象的方法不占用内存
D 以上都不对
答案 B
静态成员属于类成员,在方法区分配内存,而不是堆。静态变量属于类本身,成员变量属于类的某个实例。
image.png
2.有如下一段程序:
public class Test{
private static int i=1;
public int getNext(){
return i++;
}
public static void main(String [] args){
Test test=new Test();
Test testObject=new Test();
test.getNext();
testObject.getNext();
System.out.println(testObject.getNext());
}
}
请问最后打印出来的是什么?()
A 2
B 3
C 4
D 5
答案 B
return i++, 先返回i,然后i+1;
第一次调用getNext()方法时,返回的是1,但此时i=2;
第二次调用 getNext()方法时,返回的是2,但此时i=3;
第三次调用 getNext()方法时,返回的是3,但此时i=4;
3.下面有关java hashmap的说法错误的是?
A HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。
B HashMap 的实现不是同步的,意味着它不是线程安全的
C HashMap通过开放地址法解决哈希冲突
D HashMap中的key-value都是存储在Entry数组中的
答案C
-
开放定址法:线性探测再散列、二次探测再散列、再随机探测再散列;
-
再哈希法:换一种哈希函数;
-
链地址法 :在数组中冲突元素后面拉一条链路,存储重复的元素;
-
建立一个公共溢出区:其实就是建立一个表,存放那些冲突的元素。
什么时候会产生冲突
HashMap中调用 hashCode() 方法来计算hashCode。
由于在Java中两个不同的对象可能有一样的hashCode,所以不同的键可能有一样hashCode,从而导致冲突的产升。
HashMap底层是 数组和链表 的结合体。底层是一个线性数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候,就会初始化一个数组。数组是 Entry[] 数组,静态内部类。 E ntry就是数组中的元素,每个 Map.Entry 其实就是一个key-value对,它持有一个指向下一个元素的引用 next ,这就构成了链表。所以 很明显是链地址法。
具体过程:
当我们往HashMap中put元素的时候:当程序试图将一个key-value对放入HashMap中时,
1 . 程序首先根据该 key 的 hashCode() 返回值决定该 Entry 的存储位置;
2 . 若 Entry 的存储位置上为 null ,直接存储该对象;若不为空,两个 Entry 的 key 的 hashCode() 返回值相同,那它们的存储位置相同,
3 . 循环遍历链表,如果这两个 Entry 的 key 通过 equals 比较返回 true,新添加 Entry 的 value 将覆盖集合中原有 Entry 的 value,但key不会覆盖;如果这两个 Entry 的 key 通过 equals 比较返回 false,新添加的 Entry 将与集合中原有 Entry 形成 Entry 链,而且新添加的 Entry 位于 Entry 链的头部
HashMap是采用拉链法解决哈希冲突的。
4.下面有关java classloader说法正确的是()?
A ClassLoader就是用来动态加载class文件到内存当中用的
B JVM在判定两个class是否相同时,只用判断类名相同即可,和类加载器无关
C ClassLoader使用的是双亲委托模型来搜索类的
D Java默认提供的三个ClassLoader是Boostrap ClassLoader,Extension ClassLoader,App ClassLoader
E 以上都不正确
答案 A C D
JDK中提供了三个ClassLoader,根据层级从高到低为:
- Bootstrap ClassLoader,主要加载JVM自身工作需要的类。
- Extension ClassLoader,主要加载%JAVA_HOME%\lib\ext目录下的库类。
- Application ClassLoader,主要加载Classpath指定的库类,一般情况下这是程序中的默认类加载器,也是ClassLoader.getSystemClassLoader() 的返回值。(这里的Classpath默认指的是环境变量中配置的Classpath,但是可以在执行Java命令的时候使用-cp 参数来修改当前程序使用的Classpath)
JVM加载类的实现方式,我们称为 双亲委托模型:
如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委托给自己的父加载器,每一层的类加载器都是如此,因此所有的类加载请求最终都应该传送到顶层的Bootstrap ClassLoader中,只有当父加载器反馈自己无法完成加载请求时,子加载器才会尝试自己加载。
双亲委托模型的重要用途是为了解决类载入过程中的安全性问题。
假设有一个开发者自己编写了一个名为Java.lang.Object的类,想借此欺骗JVM。现在他要使用自定义ClassLoader来加载自己编写的java.lang.Object类。然而幸运的是,双亲委托模型不会让他成功。因为JVM会优先在Bootstrap ClassLoader的路径下找到java.lang.Object类,并载入它
5.关于继承和实现说法正确的 是 ? ( )
A 类可以实现多个接口,接口可以继承(或扩展)多个接口
B 类可以实现多个接口,接口不能继承(或扩展)多个接口
C 类和接口都可以实现多个接口
D 类和接口都不可以实现多个接口
答案 A
image.png
6.This调用语句必须是构造函数中的第一个可执行语句。
A 正确
B 错误
答案 B
this()才必须是构造函数中的第一个可执行语句,用this调用语句并不需要。
7.JAVA中,下列语句哪一个正确()
A class中的constructor不可省略
B constructor必须与class同名,但方法不能与class同名
C constructor在一个对象被new时执行
D 一个class只能定义一个constructor
答案 C
答案 C
A 省略构造函数,编译器会自动生成。
D 构造函数可以重载
B 方法是可以和类名同名的,和构造方法唯一的区别就是,构造方法没有返回值
8.在JAVA中,下列哪些是Object类的方法()
A synchronized()
B wait()
C notify()
D notifyAll()
E sleep()
答案 BCD
A synchronized Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
B C D 都是Object类中的方法
notify(): 是唤醒一个正在等待该对象的线程。
notifyAll(): 唤醒所有正在等待该对象的线程。
E sleep 是Thread类中的方法
wait 和 sleep的区别:
wait指线程处于进入等待状态,形象地说明为“等待使用CPU”,此时线程不占用任何资源,不增加时间限制。
sleep指线程被调用时,占着CPU不工作,形象地说明为“占着CPU睡觉”,此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制。
9.在Java线程状态转换时,下列转换不可能发生的有()?
A 初始态->运行态
B 就绪态->运行态
C 阻塞态->运行态
D 运行态->就绪态
image.png
image.png image.png
10.往OuterClass类的代码段中插入内部类声明, 哪一个是错误的:
A
class InnerClass{
public static float func(){return f;}
}
B
abstract class InnerClass{
public abstract float func(){}
}
C
static class InnerClass{
protected static float func(){return f;}
}
D
public class InnerClass{
static float func(){return f;}
}
答案 ABCD
主要考核了这几个知识点:
1.静态内部类才可以声明静态方法
2.静态方法不可以使用非静态变量
3.抽象方法不可以有函数体
11.以下关于Object类的说法正确的是()
A Java中所有的类都直接或间接继承自Object,无论是否明确的指明,无论其是否是抽象类。
B Java中的接口(interface)也继承了Object类
C 利用“==”比较两个对象时,Java调用继承自Object的equals方法,判断是否相等。
D 如果类的定义中没有重新定义toString()方法,则该类创建的对象无法使用toStrig()方法。
答案 A
A,Object是所有类的直接或者间接父类。
B,接口没有继承Object类。(一旦继承,Object中可以有实例方法的)
C,Object的equals方法,只有一句话,return this==object。这句话说反了。
D,和A一样,都是Object的子类了,肯定有Object的方法:hashCode、equals、toString、clone、notify、notifyall、wait、finalize、getClass
12.静态变量static在不同的实例中地址是否一样?他们储存在什么区域?()
A 地址一样,在堆栈区。
B 地址不一样,在堆栈区。
C 地址一样,在全局区。
D 地址不一样,在全局区。
答案 C
static变量也称作静态变量,静态变量和非静态变量的区别是:
静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。
而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
13.transient变量和下面哪一项有关()?
A Serializable
B Cloneable
C Runnable
D Throwable
E Comparable
答案 A
- 在序列化的时候,被transient或者static修饰的属性,不可以序列化。
- 一个类可以被序列化,那么它的子类也可以被序列化。
- 序列化可以实现深复制,而Object中的clone实现的就只是浅复制。
14.下面哪些写法能在 java8 中编译执行()
A dir.listFiles((File f)->f.getName().endsWith(“.Java”));
B dir.listFiles((File f)=>f.getName().endsWith(“.Java”));
C dir.listFiles((_.getName().endsWith(“.Java”)));
D dir.listFiles( f->f.getName().endsWith(“.Java”));
答案 A D
Lanbda表达式的主要作用就是代替匿名内部类的繁琐语法, 它由三部分组成:
(1) 形参列表。形参列表允许省略形参类型。如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略。
(2) 箭头(→)。必须通过英文中画线和大于符号组成。
(3)代码块。如果代码块只包含一条语句,Lambda表达式允许省略代码块的花括号,那么那条语句就不要用花括号表示语句结束。Lambda代码块只有一条return语句,甚至可以省略return关键字。Lambda表达式需要返回值,而它的代码块中仅有一套省略了return的语句。Lambda表达式会自动返回这条语句的值。
由此可见,应该是A和D正确。
15.有关hashMap跟hashTable的区别,说法正确的是?
A HashMap和Hashtable都实现了Map接口
B HashMap是非synchronized,而Hashtable是synchronized
C HashTable使用Enumeration,HashMap使用Iterator
D Hashtable直接使用对象的hashCode,HashMap重新计算hash值,而且用与代替求模
答案 A B C D
image.png
16.在jdk1.8之前,下列哪一种叙述是正确的( )
A abstract修饰符可修饰字段、方法和类
B 抽象方法的body部分必须用一对大括号{ }包住
C 声明抽象方法,大括号可有可无
D 声明抽象方法不可写出大括号
答案 D
abstract修饰符用来修饰类和成员方法
1:用abstract修饰的类表示抽象类,抽象类位于继承树的抽象层,抽象类不能被实例化。
2:用abstract修饰的方法表示抽象方法,抽象方法没有方法体。抽象方法用来描述系统具有什么功能,但不提供具体的实现。
Abstract是Java中的一个重要关键字,可以用来修饰一个类或者一个方法。 修饰一个方法时,表示该方法只有特征签名(signature),没有具体实现,而是把具体实现留给继承该类的子类。一个类中只要有一个abstract 方法,那么这个类就要被声明为abstract,但是其中可以有非abstract方法。 abstract类可以使得类的设计者能够创建方法的原型,而真正的实现留给使用这个类的人。
17.以下说法错误的是()
A 虚拟机中没有泛型,只有普通类和普通方法
B 所有泛型类的类型参数在编译时都会被擦除
C 创建泛型对象时请指明类型,让编译器尽早的做参数检查
D 泛型的类型擦除机制意味着不能在运行时动态获取List<T>中T的实际类型
答案 D
链接:
1、创建泛型对象的时候,一定要指出类型变量T的具体类型。争取让编译器检查出错误,而不是留给JVM运行的时候抛出类不匹配的异常。
2、JVM如何理解泛型概念 —— 类型擦除。事实上,JVM并不知道泛型,所有的泛型在编译阶段就已经被处理成了普通类和方法。 处理方法很简单,我们叫做类型变量T的擦除(erased) 。 总结:泛型代码与JVM ① 虚拟机中没有泛型,只有普通类和方法。 ② 在编译阶段,所有泛型类的类型参数都会被Object或者它们的限定边界来替换。(类型擦除) ③ 在继承泛型类型的时候,桥方法的合成是为了避免类型变量擦除所带来的多态灾难。 无论我们如何定义一个泛型类型,相应的都会有一个原始类型被自动提供。原始类型的名字就是擦除类型参数的泛型类型的名字。
/* 通过反射在运行时动态获取List<t>中T的实际类型 */
public class GetGeneric {
public List<String> list;
public static void main(String[] args) throws NoSuchFieldException, SecurityException {
Type t = GetGeneric.class.getDeclaredField("list").getGenericType();
if (ParameterizedType.class.isAssignableFrom(t.getClass())) {
for (Type t1 : ((ParameterizedType) t).getActualTypeArguments()) {
System.out.print(t1);
}
}
}
}
Java编程思想这样理解泛型的擦除
Java泛型是使用擦除来实现的,这意味着当你在使用泛型时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象。因此List<String>和List<Integer>在运行时实际上是相同的类型。这两种类型都被擦除成它们的“原生”类型,即List。
18.下列语句正确的是:
A 形式参数可被字段修饰符修饰
B 形式参数不可以是对象
C 形式参数为方法被调用时真正被传递的参数
D 形式参数可被视为local variable
答案 D
A:形式参数只能被final修饰
B:形式参数可以是对象
C:形式参数被调用时被传递的是实际参数的拷贝
D:local variable:局部变量
19.ArrayList和Vector主要区别是什么?
A Vector与ArrayList一样,也是通过数组实现的,不同的是Vector支持线程的同步
B Vector与ArrayList一样,也是通过数组实现的,不同的是ArrayList支持线程的同步
C Vector是通过链表结构存储数据,ArrayList是通过数组存储数据
D 上述说法都不正确
答案 A
Vector支持线程的同步,也就是内部加锁的
但是效率低,因此在新版jdk中加入线程不安全的Arraylist
20.关于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虚拟机时才会碰到
答案 A B C
java.lang.OutOfMemoryError: PermGen space
查了一下为"永久代"内存大小不足,“永久代”的解释应该为JVM中的方法区,主要用于存储类信息,常量,静态变量,即时编译器编译后代码等。本错误仅限于Hotspot虚拟机,本区进行垃圾回收很少,不够直接加大简单粗暴。
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
直接翻译报错信息:数组过长导致堆内存溢出,加大堆内存或者减少数组长度。
java.lang.OutOfMemoryError: Java heap space
堆内存不足,直接增大堆内存。
网友评论