Java语言中凡是没有方法体的方法都是抽象方法
- 错,object类中就有很多方法没有方法体,但它们都不是抽象方法
- 例如:public native int hashCode();
- 这个方法底层调用了C++写的动态链接程序
- 前面修饰符列表中没有abstract,有一个native,表示调用JVM本地程序
以下代码执行结果
public static void main(String[] args) {System.out.println(m());}public static int m () {int i = 100;try {return i;} finally {i++;}}//字节码文件反编译之后int i = 1oo;int j = i;i++;return j;
100
final 、finally 、fianalize 有什么区别
- final是一个关键字,表示最终的,不变的
- finally也是一个关键字,和try联合使用,使用在异常处理机制中,finally语句块中的代码是一定会执行的
- finalize() 是Object类中的标识符,作为方法名出现,JVM的GC垃圾回收器负责调用
这么多的集合中,用哪个集合最多
- ArrayList集合用的最多
- 因为往数组末尾添加元素,效率不受影响,而且我们检索查找某个元素的操作比较多
- 数组的内存地址是连续的,每个元素占用的空间大小相同,知道首元素内存地址,然后知道下标,通过数学表达式就能计算出元素的内存地址,所以检索效率高
JVM中的内存划分
- JDK6.0(包含)以前
- 寄存器(程序计数器):存储计算机硬件(CPU)相关的内容
- 本地方法栈内存:存储和操作系统相关的内容
- 本地方法栈:俗称“栈内存”,正在运行的方法
- 堆内存:存储隐式和显式new出来的东西
- 方法区:存储字节码文件对象(类文件class)
- JDK7.0
- 寄存器(程序计数器):存储计算机硬件(CPU)相关的内容
- 本地方法栈内存:存储和操作系统相关的内容
- 本地方法栈:俗称“栈内存”,正在运行的方法
- 堆内存:存储隐式和显式new出来的东西
- 方法区:将方法区划归到堆内存中
- JDK(8.0)以后
- 寄存器(程序计数器):存储计算机硬件(CPU)相关的内容
- 本地方法栈内存:存储和操作系统相关的内容
- 本地方法栈:俗称“栈内存”,正在运行的方法
- 堆内存:存储隐式和显式new出来的东西
- 元空间:存储特殊值的空间
String类面试题
String类面试题1
字符串的字面值常量存储于内存中的“字符串常量池中
public static void main(String[] args) {String str1 = new String("HelloWorld");String str2 = new String("HelloWorld");System.out.println(str1 == str2);//falseSystem.out.println("============================");String str3 = "HelloWorld";//常量池==>字符串常量池String str4 = "HelloWorld";//常量池==>字符串常量池System.out.println(str3 == str4);//trueSystem.out.println("============================");String str5 = new String("Hello");String str6 = new String("World");System.out.println(str1 == (str5 + str6));//堆 堆 falseSystem.out.println("============================");String str7 = "Hello";String str8 = "World";System.out.println(str3 == (str7 + str8));//常量池 == 堆 falseSystem.out.println("============================");System.out.println(str3 == "Hello" + "World");//true}
String类面试题2
public class StringDemo02 {public static final String str1 = "HelloWorld";public static final String str2 = "HelloWorld";public static final String str3 = "Hello";public static final String str4 = "World";public static final String str5;public static final String str6;public static final String str7;public static final String str8;static {str5 = "HelloWorld";str6 = "HelloWorld";str7 = "Hello";str8 = "World";}public static void main(String[] args) {System.out.println(str1 == str2);System.out.println(str5 == str6);System.out.println(str1 == str5);System.out.println("=========================================");System.out.println(str1 == (str3 + str4));//true常量池 == 常量池System.out.println(str5 == (str7 + str8));//false}}
String类笔试题3
public static void main(String[] args) {String str1 = "HelloWorld";//String对象数量和位置:1个(常量池)String str2 = new String("HelloWorld");//String对象数量和位置:2个(常量池1个,堆内存1个)String str3 = "H" + "e" + "l" + "l" + "o" + "W" + "o" + "r" + "l" + "d";//String对象数量和位置:1个(常量池)String s1 = "H";String s2 = "e";String s3 = "l";String s4 = "l";String s5 = "o";String s6 = "W";String s7 = "o";String s8 = "r";String s9 = "l";String s10 = "d";String str4 = s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;//String对象数量和位置:8个(常量池7个,堆内存1个)}
Integer面试题
Integer面试题1
当包装类型对象和基本数据类型比较,包装类型会根据从简原则拆箱再和基本数据类型比较
public static void main(String[] args) { int num1 = 987; int num2 = 987; System.out.println(num1 == num2); System.out.println("====================="); Integer num3 = new Integer(654); Integer num4 = new Integer(654); System.out.println(num3 == num4);//false System.out.println("====================="); Integer num5 = 321; Integer num6 = 321; System.out.println(num5 == num6);//false System.out.println("====================="); Integer num7 = 123;//Integer类的cache数组的中内容(-128~127) Integer num8 = 123; System.out.println(num7 == num8); System.out.println("====================="); Integer num9 = 200; int num10 = 200; System.out.println(num9 == num10);//从简原则 System.out.println(num10 == num9);// }Integer面试题2
public class IntegerDemo02 { public static final Integer num1 = 200; public static final Integer num2 = 200; public static final Integer num3 = 50; public static final Integer num4 = 150; public static final Integer num5; public static final Integer num6; public static final Integer num7; public static final Integer num8; static { num5 = 200; num6 = 200; num7 = 50; num8 = 150; } public static void main(String[] args) { System.out.println(num1 == num2); System.out.println(num3 == num7); System.out.println("====================="); System.out.println(num1 == (num3 + num4)); System.out.println(num5 == (num7 + num8)); } }Integer面试题3
- 包装类整型的特殊数据:
- 在底层缓冲了一个长度为256的对应包装类型的数组,存储-128~127的该类型的对象,如果在范围内,拿数组中对象进行复用,如果不在范围内,new新的该类型的对象
- 包装类字符型的特殊数据:
- 在底层缓冲了一个长度为128的对应包装类型的数组,存储ASCII码表上的所有字符对象,如果在范围内,拿数组中对象进行复用,如果不在范围内,new新的该类型的对象
包装类布尔型的特殊数据:
在底层缓冲了两个Boolean对象,分别存储true和false,如果使用拿对应的对象进行复用 ```java public static void main(String[] args) { Double num1 = 0.0; Double num2 = 0.0; System.out.println(num1 == num2);//false 对象比较的是内存地址,Double类对象没有缓存对象
Character num3 = ‘a’; Character num4 = ‘a’; System.out.println(num3 == num4);//true
Boolean num5 = true; Boolean num6 = true; System.out.println(num5 == num6);//true
Integer i1 = 128;
Integer i2 = 128;
int i3 = 128;
int i4 = 128;
System.out.println(i1 == i2);//false,比较地址,128超过Integer缓存对象
System.out.println(i3 == i4);//true,比较数据值
System.out.println(i1 == i3);//true,i1自动拆箱按照基本数据类型比较
//包装类对象与基本数据类型进行比较时,就会把包装类对象自动拆箱,按照基本数据类
型的规则进行比较
Collection集合面试题
使用多态的形式创建Collection集合对象,而多态的特点主要和方法有关,当多态的对象调用方法,先虚调用父类或父接口中的方法,如果有执行子类或实现类重写后的方法,如果没有,编译报错,在打印集合对象时,其实就是调用集合多态对象的toString(),调用该toString()会先需调用父接口Collection中的toString(),通过查看源码发现ACollection接口及其父接口都没有toString(),代码应该编译报错,但实际上并没有报错,为什么?
所有的接口都继承Object的抽象形式,所有的接口都含有Object类中方法的抽象形式
重写hashCode()时重要参数为什么是31?
- 为了减少hashCode值的重复概率,这个数必须是质数
- 这个数不宜过小(原因:过小增大重复概率)
- 这个数不宜过大(原因:过大会有可能超出int范围,造成数据的精度的损失,增大重复概率)
- .通过”泊松分布”计算出数字29和31是较为合适的数字
- 通过数学科学计数法的改写,29可以写成2^5-3,31可以写成2^5-1,31的格式和整数取值范围相似或者二进制满位原因,最终选择31
HashMap集合默认的加载因子为什么是0.75
默认加载因子(0.75)在时间和空间成本上寻求一种折中,加载因子过高虽然减少了空间开销,但同时也增加了查询(时间)成本;加载因子过低虽然减少了查询(时间)开销,但同时也增加了空间成本
