java面试题

本文详细解释了JDK、JRE和JVM的关系,hashCode与equals的差异,String、StringBuffer和StringBuilder的区别,以及equals与==的区别。此外,涵盖了ArrayList和LinkedList的不同,ConcurrentHashMap的扩容机制,Spring的IoC,AQS和ReentrantLock的对比,以及为何不推荐使用Executors创建线程池和线程池的状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.JDK、JRE、JVM之间的关系。

答:jdk包含jre,jre包含了jvm。jdk包含标准开发包,提供编译运行java程序所需的各种工具和资源。jre用于运行字节码文件。jvm用于执行java字节码文件,所以凡是某个代码编译后是java字节码,那就都能在jvm上运行。

2.hashCode()与equals()之间的关系。

答:首先,如果两个对象的hashCode值不相同,则一定是两个不同的对象,但是如果两个对象的hashCode值相同,不代表这两个对象一定是同一个对象,如果两个对象是同一个对象,那么hashcode值一定相同。

在java的一些集合类中,在比较两个对象是否相等时,会更具上面的原则,先调用对象的hashCode()方法,计算hash值,如果hash值不同则直接认为两个对象不同,如果hashcode相同,那么进一步调用equals()方法进行比较。

3.String,StringBuffer,StringBuilder的区别。

答:String是不可变的,如果修改,则会生成一个新的字符串对象,然后修改变量的指向。

StringBuffer是可变的,线程安全的,StringBuilder可变的,是线程不安全的,如果是单线程StringBuilder效率更高。

4.==和equals方法的区别

答:==如果是基本数据类型,比较的是值,如果是应用类型,比较的是引用地址。

equals的比较要看各个类重写equals方法之后的逻辑,比如String,虽然是引用类型,但是重写了equals方法,方法内部是比较各个字符是否相等。

5.List和Set的区别。

答:List:有序,按对象插入的顺序保存对象,可重复,允许多个null元素对象,可以使用iterator取出所有元素后逐一遍历。

set:无需,不可重复,最多只允许有一个null元素,使用iterator取出所有元素后逐一遍历。

6.ArrayList和LinkedList区别。

答:首先他们的底层数据结构不同,ArrayList底层是基于数组实现的,LinkedList底层是基于链表实现的。由于数据结构不同,所以应用场景也不同,ArrayList适合随机查找,LinkedList适合添加和删除。另外ArrayList和LinkedList都实现了List接口,但是LinkedList还额外实现了Deque接口,所以LinkedList还可以当作队列。

7.ConcurrentHashMap的扩容机制。

答:1.7版本:1.7版本的ConcurrentHashMap是基于Segment分段实现的,每个Segment相对于一个小型的hashMap,每个segment内部会进行扩容,和hashmap的扩容逻辑类似,先生成新的数组,然后将旧数组的元素转移到新数组中,扩容的判断是每个segment单独判断,判断是否超过阈值。

1.8版本:1.8版本的ConcurrentHashMap不在基于segment实现,每个线程进行put时,如果发现ConcurrentHashMap正在扩容,那么该线程也加入一起进行扩容,如果某个线程put时没有在扩容,则将key-value添加到ConcurrentHashMap中,判断是否超过阈值,超过则进行扩容,ConcurrentHashMap支持多线程扩容,扩容前先生成一个新数组,转移元素时,将新数组分组,将每个分组交给不同的线程对元素进行转移,每个线程负责一个或多个分组。

8.jdk1.7到jdk1.8hashMap发生了什么变化?

答:1.7底层是基于链表+数组,1.8是基于链表+数组+红黑树,加入红黑树的目的是提供hashMap插入和查询整体效率。1.7采用的是头插法,1.8采用的是尾插法,1.8需要判断链表元素的个数,所以需要遍历链表统计个数,正好使用尾插法。1.7中哈希算法比较复杂,存在各种右移和异或运算,1.8进行了简化,因为复杂的哈希算法的目标是提高散列性,来提供hashmap的整体效率,1.8中增加了红黑树,所以可以适当的简化哈希算法,节省cpu资源。

9.Spring中的IOC。

答:IOC(控制反转)。就是将对象的创建和对象内属性的赋值交给Spring容器,并且配置对象之间的关系。这样开发者可以更加关注业务逻辑的实现,以及模块化和松耦合的方式构建应用进程。

10.AQS的理解,AQS如何实现可重入锁。

答:AQS是一个java线程同步框架,是jdk中很多锁工具的和兴实现框架。

在AQS中维护了一个信号量State和一个线程组成的双向链表队列,其中,这个线程队列,就是用来给线程排队的,state用来控制线程排队或者放行,在不同场景下,有不同的意义。在可重入锁的场景下,state用来表示加锁次数,0表示无锁,每加一次锁,state加一,释放锁,state-1。

11.Sychronized和ReentrantLock的区别。
  • Sychronized是一个关键字,ReentrantLock是一个类
  • Sychronized自动加锁和释放锁,ReentrantLock需要手动加锁和释放锁
  • Sychronized是jvm层面的锁,ReentrantLock是api层面的锁
  • Sychronized是非公平锁,ReentrantLock可以选择公平锁和非公平锁
  • Sychronized锁的是对象,锁的信息保存在对象中,ReentrantLock通过state表示锁的状态
  • Sychronized底层有一个锁升级的过程。
12.为什么不建议使用Executors来创建线程池?

 

13.线程池的5中状态。

Running,shutdown,stop,tidying,termined.

14.线程的创建方式。5种

继承Thread类

实现Runable接口

实现Callable接口

 

线程池

匿名内部类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值