2024年JAVA面试题总结
2024-04-02 21:46:56 0 举报
AI智能生成
登录查看完整内容
2024年Java面试题总结涵盖了Java基础知识、数据结构与算法、Java集合框架、多线程与并发、JVM、设计模式和Spring框架等核心知识点。文件类型包括PDF、Word和HTML,针对不同的学习方式提供多种格式选择。面试题总结涵盖了Java面试中最常见的问题,如Java基础知识中的面向对象编程、Java集合框架中的ArrayList与LinkedList的异同点、多线程与并发中的线程池和Synchronized关键字等。文件被设置为公开共享,允许用户下载和学习。每个知识点后都附有详细的解析,帮助读者更好地理解。面试题总结还提供了补充资料和推荐阅读材料,以便读者进一步深入研究。
作者其他创作
大纲/内容
1.树化 :单个槽中链表长度 > 8 a.数组容量如果小于64,优先扩容 b.如果数组容量大于等64,转红黑树2.树退化: a.扩容时,原来红黑树上一部分数据可能会转移到别的槽中,当红黑树中的元素小于等于6时,退化成链表b.调用remove方法删除数据时,删除之前校验红黑树根节点 左儿子 左孙子 右儿子是否存在,如果有一个不存在,退化成链表
● 1.7 数组 + 链表● 1.8 数组 + (链表 | 红黑树)
链表插入节点时,1.7 是头插法,1.8 是尾插法
1.7 1.8区别
hashmap(必问☆☆☆☆☆)
● ArrayList 基于数组,需要连续内存随机访问快(指根据下标访问)尾部插入、删除性能可以,其它部分插入、删除都会移动数据,因此性能会低可以利用 cpu 缓存,局部性原理 (了解)● LinkedList ○ 基于双向链表,无需连续内存 ○ 随机访问慢(要沿着链表遍历) ○ 头尾插入删除性能高 ○ 占用内存多
arraylist linkedlist(☆☆☆☆)
Java 中的值传递和引用传递(☆☆☆)
重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同会让这两个方法成为不同的方法,但是方法返回值和访问修饰符的不同不会影响,发生在编译时。
重写:发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private 则子类就不能重写该方法。
重载和重写的区别(☆☆☆☆)
String 是不可变的对象,每次对 String 类型进行改变的时候其实是产生了一个新的 String 对象,然后指针指向新的 String 对象;
StringBuffer 是线程安全的可变字符序列。
StringBuilder 线程不安全,速度更快,单线程使用。
对于三者使用的总结:1. 操作少量的数据 = String 2. 单线程操作字符串缓冲区下操作大量数据 = StringBuilder 3. 多线程操作字符串缓冲区下操作大量数据 = StringBuffffer
String、StringBuffer、StringBuilder 的区别(☆☆☆☆☆)
final关键字主要用在三个地方:变量、方法、类。对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。当用final修饰一个类时,表明这个类不能被继承。final类中的所有成员方法都会被隐式地指定为final方法。使用final方法的原因有两个:第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。
final 关键字的一些用法(☆☆☆☆)
实现:抽象类的子类使用extends 来继承;接口必须使用 implements 来实现接口。构造函数:抽象类可以有构造 函数;接口不能有。main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main方法。实现数量:类可以实现很多个接口;但是只能继承一个抽象类。访问修饰符:接口中的方法默认使用public 修饰;抽象类中的方法可以是任意访问修饰符。
接口和抽象类的区别是什么(☆☆☆☆☆)
List 和 Set 是存储单列数据的集合, Map 是存储键和值这样的双列数据的集合; List 中存储的数据是有顺序,并且允许重复; Map 中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的, Set 中存储的数据是无序的,且不允许有重复
基础篇(☆☆☆☆☆)
1) 继承Thread2)实现Runnable接口3) 使用 Callable接口 (可以使用CompletableFuture )
如何创建线程(☆☆☆☆)
线程的生命周期?线程有几种状态(☆☆☆☆☆)
volatile帮我们解决了:内存可见性问题指令重排序问题不能保证变量操作的原子性(Atomic)
Volatile(☆☆☆)
1、降低资源消耗;提高线程利用率,降低创建和销毁线程的消耗。 2、提高响应速度;任务来了,直接有线程可用可执行,而不是先创建线程,再执行。 3、提高线程的可管理性;线程是稀缺资源,使用线程池可以统一分配调优监控。
为什么
7个参数
执行流程
为什么用线程池?解释下线程池参数(必问☆☆☆☆☆)
工作中线程池都手动创建,指定最大线程数 队列长度 拒绝策略选择abort抛出异常,有效控制内存大小避免内存溢出
java 中常见的几种线程池(☆☆☆☆)
tomcat线程池
https://blog.csdn.net/weixin_42272869/article/details/123082657
默认线程池会创建大量线程,建议手写线程池做替代
任务存在内存中,如果服务宕机,任务会丢失,存在风险
使用mq优化
@Async注解 尽量不要使用
框架实现线程池
1.一个查询接口中 包含了好几个sql查询,串行去做,整体耗时比较长 2.微服务架构,一个接口包含好几个远程调用 尝试使用java中CompletableFuture做异步调用来优化性能,默认forkjoin线程池,最多只支持15个线程,手写了一个线程池,调用时主动让它去使用我们实现的线程池,将线程数扩大
有没有做过性能调优?有没有遇到过难题?
自己实现线程池
你在工作中有没有用过线程池?(必问☆☆☆☆☆)
sychronized是⼀个关键字,ReentrantLock是⼀个类
sychronized 底层 c++编写的,reentrantLock底层使用java代码实现了aqs容器
ReentrantLock需要程序员⼿动加锁与释放锁
sychronized是⾮公平锁,ReentrantLock可以选择公平锁或⾮公平锁(可选)
Sychronized和ReentrantLock的区别(☆☆☆☆)
● 悲观锁的代表是 synchronized 和 Lock 锁 ○ 其核心思想是【线程只有占有了锁,才能去操作共享变量,每次只有一个线程占锁成功,获取锁失败的线程,都得停下来等待】
● 乐观锁的代表是 AtomicInteger AtomicStampReference,使用 cas 来保证原子性 ○ 其核心思想是【无需加锁,每次只有一个线程能成功修改共享变量,其它失败的线程不需要停止,不断重试直至成功】
悲观锁 vs 乐观锁(☆☆)
Segment 段(大数组) + HashEntry(小数组) + 链表,每个 Segment 对应一把锁,如果多个线程访问不同的 Segment,则不会冲突
1.7
Node 数组 + 链表或红黑树,数组的每个头节点作为锁,如果多个线程访问的头节点不同,则不会冲突
1.8
● Hashtable 并发度低,整个 Hashtable 对应一把锁,同一时刻,只能有一个线程操作它● ConcurrentHashMap 并发度高,整个 ConcurrentHashMap 对应多把锁,只要线程访问的是不同锁,那么不会冲突
hashtable区别
concurrentHashMap(☆☆☆)
线程本地对象,数据保存在当前线程中,属于线程安全
应用场景:接收请求之后,请求头中包含用户信息,可以在拦截器中将数据存放在threadlocal中,这样后续service controlller都可以获取到这个数据,保证线程安全
底层是一个ThreadLocalMap,每个线程都持有一个,key是threadlocal对象,value就是他的值
原理:底层数据结构长什么样
ThreadLocal(☆☆☆)
并发篇(☆☆☆☆☆)
存储位置不同cookie 存放在客户端电脑,是一个磁盘文件。Ie 浏览器是可以从文件夹中找到。session 是存放在服务器内存中的一个对象。 chrome 浏览器进行安全处理,只能通过浏览器找到。Session 是服务器端会话管理技术,并且 session 就是 cookie 实现的。
session创建完之后会使用uuid进行关联,返回给前端浏览器记录在cookie中,下一次访问时就可以使用cookie中的uuid找到session并获取到里边数据
1.使用tomcat自带session同步机制,耗流量,实时性不高
2.使用nginx sticky机制,哪个实例存session对这个用户来说只使用这个实例,容易出现宕机之后重新登录
3.使用spring - session将session存放在redis中实现分布式session
4.使用jwt,在令牌中存放用户信息,不存在tomcat中
问题:多个tomcat或者多个服务实例 无法共享session
cookie 和 session 的区别(☆☆☆☆)
HTTP 中重定向和请求转发的区别(☆☆)
get请求建议将参数放在url中,但是这只是http规范中的建议,也可以将数据放在body中
post一般将参数放在body中,也可以传递文件
Get 和 Post 的区别(☆☆☆)
header 加密算法、是否压缩
payload载荷 业务数据+jwt固有数据
签名 验证jwt是否被人篡改
分成三个部分
jwt业务数据本身是没有加密,只是通过base64编码更有利于在网上传输,如果数据中包含敏感数据,建议使用加密算法加密
如果主动失效,必须在redis中再存一份,否则只能实现被动失效(过期)
课程中着重提到过jwt json web token
token 可以理解成类似于当前会员卡,就是在后端保存用户数据,需要使用会员卡访问数据,相当于是一个凭证。一般token使用类似于uuid字符串生成
什么是Token(☆☆☆☆)
跨域问题;跨域指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器对JavaScript 施加的安全限制。所谓同源指的是:协议、域名、端口号都相同,只要有一个不相同,那么都是非同源。
使用ajax的jsonp
nginx 转发:利用nginx反向代理,将请求分发到部署相应项目的tomcat服务器,当然也不存在跨域问题
使用cors:写一个配置类实现WebMvcConfigurer接口或者配置FilterRegistrationBean 网关也可以配置跨域,如果网关配置了跨域,后边微服务一般不需要配置
解决方案:
如何解决跨域问题(☆☆☆☆)
http和https的区别?(☆☆☆)
java web(☆☆☆☆)
结构是b+树,b+树上每个非叶子节点里边值,都会出现在子节点中,作为子节点最小值
叶子节点中存放全量数据,用双向指针前后连接,方便快速范围查询
回表, 查询非聚簇索引之后获取到主键值,再回到聚簇索引找到这一行数据
聚簇索引 主键索引树,叶子节点存放的是真实数据地址非聚簇索引 其他索引树,叶子节点存放的是主键id值
可以不加,不推荐
非主键索引树依赖主键索引去进行回表,主键索引树存放对应的数据
如果mysql发现一张表没有主键,选择字段中第一个不会重复字段作为主键索引树。如果每个字段都有可能重复,生成隐藏列作为主键索引树
mysql能不能不加主键?
mysql索引结构(必问☆☆☆☆☆)
1.等号左边字段不要参与运算
2.like查询以%作为开头,会导致索引失效
3.等号左边是字符串,右边必须用引号将值包裹起来,否则比如传123,导致索引失效
4.最左匹配原则
5.索引尽量选择区分度好的字段,筛选效果会比较出色
mysql索引添加原则
1.分析type判断索引命中情况
使用 force index(索引名) 强制使用某个索引
2.分析索引是否用错 key
3.查看样本值rows确定索引区分度是否合理
4.extra是否实用特殊技术降低性能
开发过程中可以使用explain对sql进行分析
1.看接口返回时间,查日志看耗时
2.mysql slow log将超过1秒的sql打印到文件中
怎么知道sql执行慢了?
1.优化sql结构,只查需要的数据,只查需要的字段,尽量减少表之间关联
2.explain查看执行计划
3.如果1和2都解决不了可能是表结构设计、数据过大,考虑es、分库分表方式优化、将查询数据汇总统计表中
怎么解决sql慢的问题
关心过业务系统里面的sql耗时吗?统计过慢查询吗?对慢查询都怎么优化过?
原来的问题,如何发现
explain、小表驱动大表、索引、汇总表
优化方案
结论:优化后的时间
项目中找一个案例
sql调优(必问☆☆☆☆☆)
多个数据库操作要同时提交或者回滚
A 原子性
不能出现数据中间状态 A扣减了B没加上
C 一致性
事务与事务之间关系,有多重不同隔离级别处理
I 隔离性
事务提交之后就算服务器宕机,重启服务也应该保留提交之后状态
D 持久性
事务的四个特性及含义(☆☆☆)
● InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。● MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据,数据放在另外一个文件中。● InnoDB支持事务,而MyISAM不支持事务● InnoDB支持行级锁,而MyISAM支持表级锁myisam在宕机时表数据会损坏,需要使用repair命令修复
MySQL存储引擎MyISAM与InnoDB区别(☆☆)
分库 将数据库增加,库0库1,按照某个字段做拆分,提升了访问 磁盘IO 和 最大连接数
分表 单纯将同一个表拆成多个,根据某个分表key塞到不同的表中,降低某张表的单表数据量提升查询性能
分库和分表
1.sharding jdbc中设计好分库key 分表key
2.查询必须要传递分库key和分表key,如果不传某个参数导致多查表或者库
3.分页、统计功能对所有表都进行操作获取数据,在内存中进行组合
分库分表流程
总结:分库分表只能说是一个比较下等策略,很多种sql查询中无法获得比较好性能,唯一提升性能点:分库之后磁盘io和最大连接数下降,分表将某个表数据量降下来。但是真实在使用中会导致大量未传分库分表key sql性能下降
分库分表实现方式(☆☆☆)
mysql(☆☆☆☆)
1.操作内存,最大可以达到每秒几万笔
2.单线程,没有线程上下文切换开销
3.io使用非阻塞多路复用机制
使用场景:缓存
为什么使用redis,redis特点是什么?(☆☆☆☆☆)
key value结构,不建议存放太多key value,如果数量比较多,建议放hash
场景:验证码、jwt
string
队列、栈
使用场景比较少,实现任务队列
list
去重无序集合
1.用户登陆记录 2.好友推荐 3.抽奖
set
类似于java hashmap 去重 key value
记录用户信息、记录医生档案、记录商品信息
hash
有序集合
排行榜
zset
redis的基本数据结构(☆☆☆☆☆)
https://www.jianshu.com/p/475b800b56b7
redis高级数据结构用法(☆☆☆)
访问不存在key 通过旁路缓存机制,每次都访问mysql
布隆过滤器认为数据存在,不一定存在。认为数据不存在,一定不存在
实现方案:redisson自带的布隆过滤器实现,将数据存放在redis中
2.布隆过滤器 bloom filter
穿透
给商品放到缓存的时候,使用定时任务批量放置,而且给商品设置相同过期时间
解决方案:给商品设置过期时间增加随机数
雪崩
一个key属于热点key,失效之后,会有大量请求打到mysql,原因是因为一个请求过来将mysql数据查询出来之后写入缓存需要花一定的时间,这个时间内大量的请求还是会进入到mysql
解决方案:如果发现缓存不存在,要写数据到缓存,提交加一把分布式锁
解决方案2:通过程序定时将热点key循环从数据库查询最新值刷新到缓存,不使用cach aside机制,保证永远不失效
击穿
穿透 击穿 雪崩(☆☆☆☆☆)
实现读写分离,当主节点宕机时,只能读数据无法写入,需要人工介入
主从架构
单独配置哨兵集群,监控主从,自动做主从切换
缺点:单个节点如果数据量过大,无法解决
哨兵架构
不需要部署额外节点,只需要部署多个master,每个master挂载一到多个slave
每个master分槽 16384
数据读和写要根据 key hash值(crc)计算出槽位,找到对应master进行数据读写
集群架构(redis cluster)
redis高可用(☆☆☆☆)
将所有写操作命令记录下来
rewrite重写机制压缩文件
文件数据量会比较大,而且存在无效命令 set a 1 set a 2
数据及时时比较高,不大容易丢数据
aof
将内存整个数据用二进制方式写入到磁盘中,快照
优点:恢复数据比较快
缺点:生成文件很耗时cpu磁盘io,生成频率降低一些每隔多少命令、每隔多少时间,如果在间隔发生宕机,数据可能会丢失
rdb
同时打开aof和rdb,优先使用aof。rdb文件做离线备份、离线分析rdb-tools分析redis中存在大key/大value 包括哪些key没有设置过期时间
持久化方式(☆☆☆☆)
1.设置过期时间,导致延迟可能比较长(取决于失效时间,设置短了数据库压力大,设置长了一致性差)
第一次删除是为了保证其他线程可以从数据库读取数据(可能读到老数据)
休眠时间是为了等待数据库更新结束,稍微设置长一点300ms-500ms,根据业务时间来定
再次删除缓存是为了避免第一次缓存删除之后用户拿到了老数据更新到了缓存
2.延迟双删
如何保证redis和mysql数据一致性(redis必问☆☆☆☆☆)
1.get key检查是否数据失效了,如果失效直接删除
2.遍历所有数据库,采样每次20个key,对里边过期key进行删除,如果发现删除量大于阈值,继续采样20个,直到不满足要求
key删除策略(☆☆☆)
如果redis使用的内存已经达到maxmemory配置的值时,会触发强制清理策略,清理策略由配置文件的maxmemory-policy参数来控制,有以下这些清理策略:volatile-lru:使用LRU算法对设置了过期时间的key进行清理(默认值)allkeys-lru:使用LRU算法对所有key进行清理volatile-lfu:使用LFU算法对设置了过期时间的key进行清理(redis 4.0版本开始支持)allkeys-lfu:使用LFU算法对所有key进行清理(redis 4.0版本开始支持)volatile-random:对所有设置了过期时间的key进行随机清理allkeys-random:从所有key进行随机清理volatile-ttl:清理生存时间最小的一部分keynoeviction:不做任何清理,拒绝执行所有的写操作
内存满了之后淘汰策略(☆☆)
redis(☆☆☆☆)
comfirm机制,发消息时编写回调处理失败时的场景,记录日志、发消息通知、记录数据库、重试
生产者到交换机
return机制,在生产者发现交换机到队列失败的时候会触发return回调,代码中实现告警、日志记录、记录数据库、通知负责人
交换机到队列
开启本地重试,重试3次之后如果失败,交给错误消息交换机实现错误处理消费者,将数据保存到数据库通知业务负责人处理紧急问题
队列到消费者
交换机
队列
消息
mq客户端程序默认将所有组件都开启持久化
mq持久化
保证消息可靠性(☆☆☆☆)
实现比较繁琐,一般不推荐
死信交换机 + 死信队列
rabbitmq新版本插件,3.8之后推荐使用
延迟交换机
文章延迟发布
延迟消单
用户注册之后,发送延迟消息1天给rabbitmq,一天之后消费消息发送短信给用户
短信延迟发送
业务场景:
延迟队列的实现(☆☆☆)
案例:消费者操作数据库时索引没有生效,导致消费处理时间过长,在数据库层面发生阻塞
优化方案:解决消费者慢的问题,加上索引之后,消费时长由原来的20秒变成了3秒内,提升消费效率
RabbitMQ如何解决消息积压问题(☆☆☆)
使用的是3.8版本,有一种仲裁队列,将数据默认复制到5个节点,保证数据可靠性
你们项目中的rabbitmq集群是使用什么方式搭建的?(☆☆☆)
消费者把消息处理完,没有成功返回ack给mq(网络原因、服务宕机),mq会重新投递消息
为何会产生重复消费?
所谓幂等指的是操作执行一次和执行多次结果是一样的
1.处理成功就在redis中存放业务唯一id,在执行时检查业务id是否已经处理过,如果处理过就直接结束
2.如果业务本身幂等,则不用额外处理
3.利用数据库唯一索引来避免数据重复插入
解决方案
保证幂等
MQ消息重复消费怎么办(mq必问☆☆☆☆☆)
rabbitmq(☆☆☆☆)
#{} 是占位符,预编译处理,${}是字符串替换。 Mybatis 在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值; Mybatis 在处理${}时,就是把${}替换成变量的值。 使用#{}可以有效的防止 SQL 注入,提高系统安全性。
在mybatis 中,${} 和 #{} 的区别是什么?
每个sql session内存存放缓存,实用性不高,当sql执行在不同sqlsession就会失效。namespace 参数 方法一致,不允许中间出现任何update、delete、insert
一级缓存
namespace级别开启缓存,跨sql session共享,实用性也不高,两次查询之间不能插入任何这个namespace下的增删改
二级缓存
谈一下你对mybatis 缓存机制的理解
mybatis(☆☆☆☆)
1.请求和响应整体流程DispacherServlet控制
2.根据url找到处理器(写的controller方法),但是处理器写法有5种 requestmapping beanname,所以需要使用处理器映射器,根据url找到对应的处理器和拦截器
3.要去调用处理器方法,但是处理器有5种,通过适配器模式将他们转换成统一的适配器对象,方便后续代码编写,增强代码可维护性和扩展性
4.调用 处理器方法、拦截器方法 preHandle postHandle afterCompletion
5.获取处理器返回model and view 对象,里边包含的是数据模型和视图名,通过视图解析器,转换成视图对象(包含模板文件)
6.调用视图对象中render渲染,将模板文件和数据整合到一块生成html
Spring mvc的执行流程(☆☆☆☆)
2.进行依赖注入,根据类中@Autowired等注解,将对象注入到属性中
3.一系列aware接口,实现之后会在对应的对象处理完之后进行回调 BeanNameAware会在bean的名称确定之后产生回调
4.实现Bean后置处理器 BeanPostProssor,可以在bean初始化之前和之后对bean进行增强,对bean属性赋值或者整个替换bean
@PostConstructor
实现InitializingBean接口
5.初始化
DisposableBean接口
@PreDestroy注解
6.bean清理
spring生命周期(☆☆☆☆☆)
A是spring注解 R是jdk注解
A默认是按类型,如果类型有超过一个以上对象,直接报错。@Qualify注解实现按名字注入
R提供了按名字和类型注入,默认使用按名字注入
注入流程不同
@Autowired 与@Resource的区别(☆☆☆☆)
@Transactional只能用在public方法上面,原因是spring要求被代理的方法必须是public,否则事务不会生效。
抛出的异常被捕获
rollbackFor属性设置错误 ,rollbackfor默认只能对runtimeException回滚,如果要对所有异常回滚,写成Exception.class
Spring事务失效的几种情况(☆☆☆☆)
起步依赖 依赖打包
自动配置 通过依赖jar包就可以将对象注入到spring容器中
监控actuator springboot-admin
内置tomcat
SpringBoot优点(☆☆☆)
gateway网关
feign远程调用
ribbon负载均衡器
nacos/eureka注册中心
nacos配置中心
流控 hystrix/sentinel(阿里)
监控 skywalking
其他组件
SpringCloud常用组件(☆☆☆)
spring(必问☆☆☆☆☆)
框架(☆☆☆☆☆)
虚拟机栈,执行方法时候,每个方法执行开始都会创建栈帧,放在里边
本地方法栈:native方法创建栈帧
程序计数器记录的是当前线程虚拟机指令执行到了哪一行,方便线程之前切换时候进行恢复
线程独有
方法区:常量池 + 类字节码文件
堆:new出来的对象
线程共有
java的内存模型(☆☆)
对象创建完先放入eden区
伊甸园区eden
年轻代回收之后,将存活对象从eden搬运到s0或者s1,后续每次回收会在s0和s1之间来回搬运,直接到达老年年龄
s0 s1 幸存者区
年轻代
在s区域待够N次(默认16)垃圾回收之后,进入到老年代,老年代的对象只有full gc可以回收
老年代
堆内存泄漏:当一个对象不使用的时候,要解除关联,如果只往堆放数据,但是不解除关联就会导致使用的内存到达堆内存的上限,再放入数据就会产生内存溢出
装载文件,找到对象大小最大数据,去看引用关系,找到对应类
jvisualvm
MAT
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:test.dump
堆内存泄漏定位和解决
堆(☆☆)
bootstrap c++代码编写 加载Java的核心类库
ext 扩展类加载器 ext 子目录
application 应用类加载器,程序classpath中jar包
jdk自带的类加载器三种
从application -> ext -> bootstrap 先让父类加载器去加载,如果所有父辈类加载器都不能加载,再由我来加载
双亲委派机制(☆☆☆)
jdk9之后,一般推荐使用g1(年轻+老年)
年轻代用多线程来回收,如果多核CPU能获取更好回收效率
CMS让系统得到最短停顿时间,让用户业务请求停顿降低到最低
jdk1.8用 parNew(年轻代) + CMS(老年代)
项目中用的垃圾回收机制是哪一种(☆☆)
jvm(☆☆)
2024年JAVA面试题总结
0 条评论
回复 删除
下一页