1. 什么是java字节码?
它是程序的一种低级表示,可以运行在java的虚拟机上。将程序抽象成字节码可以保证java程序员的代码能够运行在各种设备上。
2. Math.abs(-2147483648)的返回值是什么?
返回值是-2147483648。这是个奇怪的结果,但是是真的,这是一个整数溢出的典型例子。
3. 将double变量初始化为无穷大
可以使用java的内置常数
Double.POSITIVE_INFINITY//或者
Double.NEGATIVE_INFINITY
4. 变量使用前未进行初始化
java会抛出一个编译异常
5. Java表达式1/0和1.0/0.0的值
1/0 会产生一个运行时除以零异常(终止程序);1.0/0.0 的值是Infinity(无穷大)
1/0 -1/0 0/0 //均产生异常;
1.0/0 -1.0/0 0.0/0 //分别为Infinity -Infinity NaN
1/0.0 -1/0.0 0/0.0 //分别为Infinity -Infinity NaN
1.0/0.0 -1.0/0.0 0.0/0.0 //分别为Infinity -Infinity NaN
6. String类的深入理解
- String是final类,这意味着,这个类不能被继承,也不可有子类,其中的方法默认都是final方法。
- String类是通过char数组来保存字符串的。
- String类对字符串的操作都是对新字符串操作。也就是说,String对象一旦被创建就不会改变,也就是说,String对象一旦被创建就不会改变,
- 任何改变操作都不会改变原字符串,而是生成新的对象,任何改变操作都不会改变原字符串,而是生成新的对象。
字符串常量池:
每当我们创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串不可变,所以常量池中一定不存在两个相同的字符串。
静态常量池和运行时常量池:
静态常量池:即 .class 文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。
运行时常量池:是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。
字符串常量池详见https://blog.csdn.net/myjess/article/details/108857477
7. length、length()、size()
length不是方法,是属性,数组的属性。
size()方法是针对集合(list,map,set)。
length()是字符串String的一个方法。
8. 两个对象的hashCode()相同,则equals()也一定为 true吗?
不对,两个对象的hashCode()相同,equals()不一定 true。
String str1 = "通话";
String str2 = "重地";
System.out.println(String.format("str1:%d | str2:%d",str1.hashCode(),str2.hashCode()));//str1:1179395 | str2:1179395
System.out.println(str1.equals(str2));//false
在散列表中,hashCode()相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。
9. final 在 java 中有什么作用?
- final 修饰的类叫最终类,该类不能被继承。
- final 修饰的方法不能被重写。
- final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
10. java 中的Math.round(-1.5) 等于多少?
四舍五入的原理是在参数上加 0.5 然后做向下取整。
答案为: -1
11. String str=“i” 与 String str=new String(“i”)一样吗?
不一样,因为内存的分配方式不一样。
String str="i"的方式,java 虚拟机会将其分配到常量池中。而 String str=new String(“i”) 则会被分到堆内存中。
12. 如何将字符串反转?
// StringBuffer reverse
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("abcdefg");
System.out.println(stringBuffer.reverse()); // gfedcba
// StringBuilder reverse
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("abcdefg");
System.out.println(stringBuilder.reverse()); // gfedcba
13. ArrayList 和 LinkedList 的区别是什么?
最明显的区别是 ArrrayList底层的数据结构是数组,支持随机访问,而 LinkedList 的底层数据结构是双向循环链表,不支持随机访问。使用下标访问一个元素,ArrayList 的时间复杂度是 O(1),而 LinkedList 是 O(n)。
14. 如何实现数组和 List 之间的转换?
List转换成为数组:调用ArrayList的toArray方法。
数组转换成为List:调用Arrays的asList方法。
15. 什么是 java 序列化?什么情况下需要序列化?
简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。
什么情况下需要序列化:
- 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候。
- 当你想用套接字在网络上传送对象的时候。
- 当你想通过RMI传输对象的时候。
16. throw 和 throws 的区别?
throws是用来声明一个方法可能抛出的所有异常信息,throws是将异常声明但是不处理,将异常往上传,谁调用我就交给谁处理。而throw则是指抛出的一个具体的异常类型。
17. 抽象类能使用 final 修饰吗?
不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类-----即修饰类时 static 和 final 不能共存
18. 多线程中的 sleep() 和 wait() 有什么区别?
sleep():方法是线程类(Thread)的静态方法,让调用线程进入睡眠状态,让出执行机会给其他线程,等到休眠时间结束后,线程进入就绪状态和其他线程一起竞争cpu的执行时间。因为sleep() 是static静态的方法,他不能改变对象的机锁,当一个synchronized块中调用了sleep() 方法,线程虽然进入休眠,但是对象的机锁没有被释放,其他线程依然无法访问这个对象。
wait():wait()是Object类的方法,当一个线程执行到wait方法时,它就进入到一个和该对象相关的等待池,同时释放对象的机锁,使得其他线程能够访问,可以通过notify,notifyAll方法来唤醒等待的线程。
19. java中this和super关键字的作用
this是对象内部指代自身的引用,同时也是解决成员变量和局部变量同名问题。
this可以调用成员变量,不能调用局部变量。
this也可以调用成员方法,但是在普通方法中可以省略this,在构造方法中不允许省略,且必须是构造方法的第一条语句,而且在静态方法当中不允许出现this关键字。
super代表对当前对象的直接父类对象的引用,super可以调用直接父类的成员变量(注意权限修饰符的影响,比如不能访问private成员)。
super可以调用直接父类的成员方法(注意权限修饰符的影响,比如不能访问private成员)。
super可以调用直接父类的构造方法(只限构造方法中使用,且必须是第一条语句)。
20. 运行时异常和非运行时异常区别
运行时异常是运行时报错:比如ClassCastException(类转换异常)、IndexOutOfBoundsException(数组越界)、NullPointerException(空指针)、ArrayStoreException(数据存储异常,操作数组时类型不一致)、IO操作的BufferOverflowException异常。
非运行时异常是还未运行可见的错误,可以try、catch捕获异常。
21. 构造器是否可被重写?
构造器不能被继承,所有不能重写,但能重载
22. ArrayList、Vector、LinkedList的存储性能和特性
ArrayList是以数组形式存储对象,因为它是存放在连续位置上,插入和删除麻烦,但查询效率高,连续的数组有序的可以根据索引查找。
LinkedList将对象存储在独立的空间,每个空间保留了下一个链接的索引,查询效率低,但修改、删除效率高。
Vector使用了Synchronized方法(线程安全的),性能低于ArrayList。
ArrayList和vector的区别?
同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程不安全的,不是同步的 。
数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半。
23. List、Map、Set三个接口存取元素时,各有什么特点?
List 允许数据重复,有序的,调用get()来明确说明取第几个。
Set 不允许重复数据,内部有排序,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。
Map 是通过键值对存储数据,键是唯一的,相同数据会覆盖,用get(Object key)方法根据key获得相应的value。