Java 深入理解及常见易错点整理

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给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。

什么情况下需要序列化:

  1. 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候。
  2. 当你想用套接字在网络上传送对象的时候。
  3. 当你想通过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。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值