Java高频一(持续更新)

本文详细探讨了Java中sleep与wait方法的区别,深入剖析了HashMap的内部结构、扩容机制和哈希算法,还涵盖了final、finalize与finally的差异,以及Object类方法、内存管理、垃圾回收、并发控制等内容。

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

1.Java中sleep方法和wait方法的区别?
1)sleep是线程中的方法,wait是Object中的方法
2)sleep会释放锁,wait不会释放锁
3)sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字
4)sleep不需要被唤醒,但是wait需要

2深入理解HashMap与Hash算法
1)HashMap的数据结构
JDK1.7之前底层是数组和链表
JDK1.8以后是数组和链表或红黑树,因为当数据太多的时候,用链表查询效率比较低,所以引入红黑树
2)什么时候链表转化为红黑树?
链表的长度大于8,且数组长度大于等于64(默认是16,经过两次扩容),否则会先数组扩容
3)put和get方法
先根据key值计算出Hash值–>根据Hash值算出数组的下标–》
key:如果key为空,返回0,key.hashCode()和key.hashCode向右无符号位16位做一个异或运算
下标:得到的hash值与n-1进行与运算,得到数组的下标,n是数组的长度
如果n是2的次方的条件下:(n-1)&hash的效果和hash%n的效果一样,且效率更高
4)为什么HashMap要把hashCode做一个运算改进?
为了让算出来的数组下标会更加分散

3.HashMap的扩容机制是怎样的?
1)什么条件下扩容?
HashMap最主要的数据结构是数组,一般情况下,是放在数组上的,如果数组已经有元素,就会发生Hsah冲突,那么就会使用链表或者红黑树的结构进行存储。
HashMap默认的大小是16,阈值为0.75,每次扩容2倍
2)扩容会发生什么?
扩容后原有的元素也需要重新散列,因为数组变长,元素在数组上的位置也可能发生改变‘

4.final、finalize和finally的不同之处?
final是一个修饰符,可以修饰变量,方法和类,修饰变量会变成常量,修饰方法不能重写,修饰类不能继承
finally是一个关键字,与try、catch一起用于异常处理,finally块一定会被执行,无论try是否发生了异常
finalize方法是对象被回收之前调用的方法,给对象自己一个最后复活自己的机会,但是什么时候调用finalize没有保证

5.Object类中有哪些方法?
Object类是所有类的基类
clone(): 创建并返回此对象的副本。
equals():判断是否相等
finalize() :当垃圾收集确定不再有对该对象的引用时,垃圾收集器在对象上调用该对象。
getClass() :返回此 Object的运行时类
hashCode() :返回对象的哈希码值。
notify() :唤醒正在等待对象监视器的单个线程。
notifyAll():唤醒正在等待对象监视器的所有线程。
toString():返回对象的字符串表示形式。
wait():导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。
wait(long timeout) :导致当前线程等待,直到另一个线程调用 notify()方法或该对象的 notifyAll()方法,或者指定的时间已过。
wait(long timeout, int nanos) :导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法,或者某些其他线程中断当前线程,或一定量的实时时间。

6.HashCode有什么用?与equals有什么关系?
HashCode就像是一个签名,比较对象时,如果HashCode一样,两个对象可能一样。如果HashCode不一样,两个对象就肯定不一样,之所以先用HashCode比较一次,是因为equals的效率比HashCode低,所以先用HashCode筛选一下,再用equlas比较,可以减少equals的使用,从而提高效率。

7.‘==’ 和 ‘equals’ 的区别?
先说 ==
对于基本数据类型, == 比较的是 值 是否相等
对于引用数据类型,== 比较的是 引用 是否相等
equals
equals本质上其实和 == 一样的,只是有一些类中重写了equals方法,比如String类,将比较引用重写为比较值

8.ArrayList和LinkedList的区别?
底层实现结构 ArrayList是数组,LinkedList是双向链表
查询ArrayList比LinkedList快,增删LinkedList
LinkedList需要更多的内存

9.Collection和Collections的区别?
Collection是一个接口,是List和Set的父接口
Collections是一个工具类,提供了一系列的静态方法来辅助容器操作

10.HashTable和HashMap有什么不同之处?
hashTable 线程安全 HashMap非线程安全
HashMap的性能比HashMap高
HashMap的Key可以为null,(为null时,总是存储在数组的第一个节点上,经常会Hash冲突)HashTable不可以为null
HashMap初始容量为16,HashTable初始容量为11,负载因子都是0.75,HashMap每次扩大两倍,HashTable每次扩大两倍 + 1

11.Java中 ++ 操作符是线程安全的吗?
不是线程安全的操作,先读取变量值,然后增加,然后再存储回内存。
比如count = 0; 线程1 执行 count++ ,线程2 也执行count++,读取值时都读取到count = 0,执行+1后,
写回内存为1,但实际应该为2.

12.Java中如何实现序列化,有什么意义?
为什么要序列化?
网络传输的数据必须都是二进制,但是在Java中都是对象,是没有办法在网络中进行传输的,所以就需要对Java对象进行序列化,而且这个要求这个算法时可逆的。
Java原生序列化
只要让类实现Serializable接口就行,序列化具体的实现是由ObjectOutputStream和ObjectInputStream来实现的

13.抽象类和接口的区别?
接口是对动作的抽象,抽象类是对根源的抽象
抽象类单继承,接口可以多继承
抽象类可以有构造器和而具体方法,接口没有

14.String s = new String(“abc”); 创建了几个对象?
两个 一个是常量池中的"abc" 另一个是在堆中new出来的String对象

15.重载和重写的区别?
重载发生在同一个类中,表示一个类中可以有多个名称相同的方法,但这些方法参数的个数、类型、顺序不同
重写是指子类继承来自父类的方法,并重写这个方法,相当于把原本来的方法覆盖了

16.什么是用户线程?什么是内核线程?
在Java中,基本我们说的线程(Thread)实际上都应该叫做”用户线程“,而对应到操作系统,还有另外一种线程,叫做”内核线程“。
用户线程和内核线程之间必然存在某种关系,多对一模型,一对一模型和多对多模型
多对一模型
多个用户线程对应到一个内核线程上,线程的创建、调度、同步的所有细节全部由进程的用户空间线程库处理
优点:用户线程的很多操作对内核来说都是透明的,不需要用户态和内核态的频繁切换,使线程的创建、调度、同步等非常快
缺点:由于多个用户线程对应到同一个内核线程,如果其中一个用户线程阻塞,那么其他用户线程也无法执行;内核并不知道用户态有哪些线程,无法像内核线程一样实现较完整的调度、优先级等;
一对一模型
即一个用户线程对应一个内核线程,内核负责每个线程的调度
优点:(比如JVM几乎把所有对线程的操作都交给了内核)实现线程模型的容器(JVM)简单,所以我们经常听到在Java中使用线程一定要慎重就是这个原因。
缺点:对用户线程的大部分操作都会映射到内核线程上,引起用户态和内核态的频繁切换;内核为每个线程都映射调度实体,如果系统出现大量线程,会对系统有影响。

17.什么是JVM,与JDK有什么区别?
JVM:Java VirtualMachine,中文称Java虚拟机
JVM是Java程序运行的底层平台,与Java支持库一起构成了Java程序的执行环境
JRE = JVM + Java标准库
JDK = JRE + 开发调试工具

18.JVM的跨平台与跨语言?
跨平台:我们写的一个类,在不同的操作系统上执行,效果是一样的,这就是JVM的跨平台性
跨语言:JVM只识别字节码,所以JVM是和语言解耦的,没有直接关联,JVM运行的不是Java文件,而是经过JavaC编译成的.class文件。还有像Groovy、Kotlin、Scala等语言,也是编译成字节码,在JVM上运行。

19.JVM运行时数据区有哪些?
运行时数据区的定义:Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。
根据JVM规范,标准的JVM运行时包括以下部分
线程私有:
程序计数器
Java虚拟机栈
本地方法栈
线程共享:
堆内存
方法区
运行时常量池(在堆中)

20.什么是堆内存?堆内存包含哪些部分?
堆是JVM上最大的内存区域,我们申请的几乎所有对象,都是在这里存储的。
以Hotspot为例,堆空间为了方便GC模块进行对象分配和回收,可以把对空间进行以下划分:
新生代(Eden + s0 + s1) 8 : 1 : 1
老年代

21.什么是内存溢出?
内存溢出(OOM- Out Of Memory) 是指JVM可用内存不足。
JVM运行需要使用的内存超出最大可用值,会导致JVM出现异常
常见的OOM有以下几种
栈溢出
堆溢出
方法区溢出
本机直接内存溢出

22.什么是内存泄漏?与内存溢出有什么关系?
内存泄漏(Memory Leak)是指本来无用的对象却继续占用内存,没有在恰当的时机释放占用的内存
不使用的内存,却没有被释放,这个就叫做内存泄漏
如果存在严重的严重泄漏问题,随着时间的推移,则必然会引起内存溢出
内存泄漏一般是程序BUG和资源管理问题,内存溢出则是内存空间不足和内存泄漏的最终结果

23.对象头包含哪些部分?
对象头、实例数据、对其填充
对象头包括两部分信息,一部分用于存储对象自身运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。另一部分是类型指针,指向类的元数据的指针,JVM通过这个指针来确定这个对象是哪个类的实例。如果对象是数组,还有一块用于记录数组长度数据

24.设置堆空间的最大值应该考虑哪些因素?
需要根据系统的配置来决定,需要给操作系统和JVM其他内存区(栈、方法区)留下一定的剩余空间
默认 推荐使用70%~80%左右

25.Java8默认使用多个垃圾收集器是什么?
是并行垃圾收集器(Paralell GC)

26.什么是并行垃圾收集?
并行垃圾收集,是指使用多个GC worker线程并行的执行垃圾收集,能充分利用多核CPU的能力,缩短垃圾收集的暂停时间
除了单线程的GC是,其他的垃圾收集器,比如PS,CMS,G1等新的垃圾收集器都使用了多个线程来并行执行GC工作

27.什么是STW(stop the world)?什么是安全点?什么是安全区域?
STW
因为GC过程中,所有应用线程都需要暂停之后才能执行GC,这时就称为STW,或者叫GC暂停。
安全点
用户线程暂停,GC线程要开始工作,但是要确保用户线程暂停的这行字节码指令是不会导致引用关系的变化。所以JVM在字节码指令中,选一些指令,作为“安全点”,比如方法调用、循环跳转、异常跳转等,一般是这些指令才会产生安全点。为什么它叫安全点,GC是要暂停业务线程,并不是抢占式中断(立马把业务线程中断)而是主动式中断
主动式中断是设置一个标志,这个标志是中断标志,各业务线程在运行过程中会不停的主动去轮询这个标志,一旦发现中断标志为True,就会在自己最近的“安全点”上主动终端挂起
安全区域
安全区域是指能够确保在某一段代码片段中,引用关系不会发生改变,因此,在这个区域内任意地方开始垃圾收集都是安全的

28.如果CPU使用率突然飙升,你会怎么排查?
1.先通过top命令找到消耗cpu很高的进程id
top命令是Linux下最常用的命令之一,它可以实时显示正在执行进程的CPU使用率、内存使用率以及系统负载等信息。
2.执行top -p 进程id 单独监控该进程
3.在第2步的监控界面输入H,获取当前进程下的所有线程信息
4.找到线程cpu特别高的线程编号
5.执行jstack 线程id 对当前的进程做dump,输出所有的线程信息
同时将第四步得到的线程十进制编号转为16进制,在堆栈信息里面去查找对应线程内容
6.解读线程信息,定位具体代码

29.CMS、G1垃圾回收器中的三色标记你了解吗?
三色标记法是一种垃圾回收法,它可以让JVM不发生或仅短时间发生STW(Stop The World),从而达到清楚JVM内存垃圾的目的
三色标记法将对象的颜色分为了黑、灰、白三种颜色
黑色:该对象已经被标记过了,且该对象下的属性也全部都被标记过了
灰色:对象已经被垃圾收集器扫描过了,但是对象中还存在没有扫描的引用
白色:表示对象没有被垃圾收集器访问过,即表示不可达

30.什么是双亲委派机制?他有什么作用?
双亲委派机制的意思是除了顶层的启动类加载器之外,其余的类加载器,在加载之前,都会委派给它的父加载器进行加载,这样一层一层向上传递,知道祖先们都无法胜任,它才会真正的加载
通过带有优先级的层级关可以避免类的重复加载
保证Java程序安全稳定运行,Java核心API定义类型不会被随意替换
启动类加载器(BootStrap)
拓展类加载器(Extension)
应用程序类加载器(Application)
自定义类加载器(Custom)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迪迦敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值