【面试深度解析】哔哩哔哩后端面试:JDK 集合源码、线程状态及转换、Future和CompletableFuture、JVM生产命令(下)

news2024/11/19 9:24:47

欢迎关注公号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送!
文中所有相关面试资料可从公号领取

文章导读地址:点击查看文章导读!

感谢你的关注!

前言:
🚀 春招季即将来临,你准备好迎接挑战了吗? 🌟

🎯 【30天面试冲刺计划】 —— 专为大厂面试量身定制!

🔥 跟随学习,一起解锁面试新高度! 🔥

在这里插入图片描述

哔哩哔哩后端面试:JDK 集合源码、(下)

文章目录

  • 哔哩哔哩后端面试:JDK 集合源码、(下)
      • 7、JDK 中的集合:ArrayList、LinkedList、HashMap、HashTable、ConcurrentHashMap
      • 8、线程的状态以及线程状态的转换
      • 9、Future 获得结果怎么处理
      • 10、JUC 工具类用过哪些?
      • 11、JVM 实战过吗,了解命令吗?

7、JDK 中的集合:ArrayList、LinkedList、HashMap、HashTable、ConcurrentHashMap

这里就是 JDK 源码常见的问题了

这里我就不贴出来了,之前已经写过很多篇相关的内容了,如果需要可以自行搜索一下

主要说一下会问哪些问题:ArrayList、LinkedList 底层原理,一个底层是数组,另一个底层是链表

HashMap 底层数据结构?什么时候会扩容?什么时候链表转为红黑树?线程安全吗?

HashTable 线程安全吗?效率高吗?如何保证线程安全(synchronized)? 这个效率不高,使用的不算多,一般使用 ConcurrentHashMap

ConcurrentHashMap 线程安全如何保证?锁的粒度怎样?

8、线程的状态以及线程状态的转换

线程的状态有 6 种:新建 New、就绪 Ready、运行中 Running、阻塞 Blocker、超时等待 Timed Waiting、退出 Terminated

接下来说一下各个状态之间如何转变:

在这里插入图片描述

接下来说一下上边出现的几个方法的含义:

  • wait() 和 sleep():

wait() 来自 Object 类,会释放锁

sleep() 来自 Thread 类,不会释放锁

  • interrupt()

用于停止线程,给线程发出一个中断信号,但是并不会立即中断,会设置线程的中断标志位为 true

一般停止线程都会使用 interrupt() 方法,但是这个方法并不会立即中断正在运行的线程,想要立即停止线程,可以使用 sleep() 和 interrupt() 搭配使用:

从下边输出可以看到,当子线程 sleep() 时,我们在 main 线程中调用了子线程的 interrupt(),那么子线程就会抛出 InterruptedException(只要 sleep() 和 interrupt() 方法碰到一起,就一定会抛出异常,我们可以使用抛出异常的方法,来优雅的停止线程的执行)

public static void main(String[] args) {
    try {
        Thread thread = new Thread(()->{
            try {
                // 让子线程先 sleep
                System.out.println("run begin");
                Thread.sleep(2000);
                System.out.println("run end");
            } catch (InterruptedException e) {
                System.out.println("子线程 sleep 过程中被 interrupt,导致抛出 InterruptedException");
                e.printStackTrace();
            }
        });
        thread.start();
        // 让主线程等子线程启动起来
        Thread.sleep(200);
        // 调用子线程的 interrupt()
        thread.interrupt();
    } catch (InterruptedException e) {
        System.out.println("主线程捕获中断异常");
    }
    System.out.println("end");
}

// 程序输出
run begin
end
子线程 sleep 过程中被 interrupt,导致抛出 InterruptedException
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.alibaba.craftsman.command.PaperMetricAddCmdExe.lambda$main$0(PaperMetricAddCmdExe.java:42)
	at java.lang.Thread.run(Thread.java:748)

  • yield()

让当前线程放弃对 cpu 的占用,放弃的时间不确定,有可能刚刚放弃,马上又获得了 cpu 的时间片

  • LockSupport.park()/unpark()

用于阻塞当前线程,可以通过另一个线程调用 LockSupport.unpark() 方法来唤醒它

9、Future 获得结果怎么处理

Future 可以用于获取异步计算的结果,Future 的使用比较简单,主要有以下四个方法:

// 检查任务是否完成
boolean isTaskDone = future.isDone();
// 等待任务完成
Object result = future.get();
// 带超时的等待
Object result = future.get(1, TimeUnit.SECONDS);
// 取消任务
boolean isCancelled = future.cancel(true);

使用 Future 时,需要正确处理抛出的异常:

  • InterruptedException 表示在等待过程中线程被中断
  • ExecutionException 表示任务执行过程中抛出了异常
try {
    Object result = future.get();
} catch (InterruptedException e) {
    // 处理中断异常
    Thread.currentThread().interrupt(); // 重新设置中断状态
} catch (ExecutionException e) {
    // 处理执行异常,这通常意味着任务抛出了异常
} catch (TimeoutException e) {
    // 如果设置了超时时间,但没有在规定时间内完成任务
}

10、JUC 工具类用过哪些?

上边既然说到了 Future,接下来可以说一下 CompletableFuture,因为 CompletableFuture 使用的还是比较多的,通过 CompletableFuture 大大加快任务的计算速度

其实 CompletableFuture 用起来也比较简单,将一些比较耗时的操作,比如 IO 操作等结果放到 CompletableFuture 中去,当需要用的时候,再从 CompletableFuture 中取出来即可

当然在实际使用中还有一些问题需要注意:

第一点:使用自定义的线程池,避免核心业务和非核心业务竞争同一个池中的线程

如果在使用中,没有传入自定义线程池,将使用默认线程池 ForkJoinPool 中的共用线程池 CommonPool(CommonPool的大小是CPU核数-1,如果是IO密集的应用,线程数可能成为瓶颈)

如果执行两个任务时,传入了自定义的线程池,使用 thenRun 和 thenRunAsync 还有一点小区别;

  • 当使用 thenRun 执行第二个任务时,将会使用和第一个任务相同的线程池
  • 当使用 thenRunAsync 执行第二个任务时,那么第一个任务会使用自己传入的线程池,而第二个任务则会使用 ForkJoin 线程池。(thenAccept、thenApply同理)

在实际使用时,建议使用自定义的线程池,并且根据实际情况进行线程池隔离。避免核心业务与非核心业务竞争同一个池中的线程,减少不同业务之间相互干扰

第二点:线程池循环引用导致死锁

public Object doGet() {
  // 创建一个有 10 个核心线程的线程池
  ExecutorService threadPool1 = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(100));
  CompletableFuture cf1 = CompletableFuture.supplyAsync(() -> {
  //do sth
    return CompletableFuture.supplyAsync(() -> {
        System.out.println("child");
        return "child";
      }, threadPool1).join();//子任务
    }, threadPool1);
  return cf1.join();
}

对于上边代码,如果同一时刻有 10 个请求到达,threadPool1 被打满,而 cf1 的 子任务也需要使用到 threadPool1 的线程,从而导致子任务无法执行,而且父任务依赖于子任务,也无法结束,导致死锁

而像其他一些 JUC 的工具类也要了解:

  • Semaphore:信号量,用于控制访问特定资源的线程数量
  • CountDownLatch:可以阻塞线程,等待指定数量的线程执行完毕之后再放行,直到所有的线程都执行完毕之后,才可以将所有线程放行。比如需要读取 6 个文件的数据,最后合并 6 个文件的数据,那么就可以创建 6 个线程读取,并且使用 CountDownLatch 让主线程阻塞等待子线程读取完毕塞,当所有子线程都读取完毕之后,再放行

11、JVM 实战过吗,了解命令吗?

这里说一下 JVM 相关的命令吧,先不说 JVM 调优的内容了,说起来太多了

  • jps:查看 Java 进程,主要用于获取 Java 进程的 pid
  • jstat:查看运行时堆的相关情况
# 进程 ID 515460 ,采样间隔 250 ms,采样数 4
jstat -gc 515460 250 4
  • jinfo:查看正在运行的 Java 程序的扩展参数
# 打印虚拟机参数
jinfo -flags <pid>
  • jmap:查看堆内存的使用情况
# 生成堆转储快照 dump 文件,如果堆内存较大,该命令比较耗时,并且该命令执行过程中会暂停应用,线程系统慎用
jmap -dump:format=b,file=heapdump.hprof 13736
  • jhat:hat 命令会解析 Java 堆转储文件,并且启动一个 web server,再用浏览器就可以查看 dump 出来的 heap 二进制文件
jhat ./heapdump.hprof
  • jstack:用于生成 Java 虚拟机当前时刻的线程快照,生成线程快照的主要目的是定位线程出现长时间停顿的原因

这里扩展一个使用 jstack 打印线程快照信息,来解决 CPU 占用 100% 问题的解决方案:

# 显示 cpu 使用率,执行完该命令后,输入 P,按照 cpu 使用率排序
top -c
# 找到 cpu 使用率最高的那个 java 进程,记下进程 id
# 显示这个进程中所有【线程】的详细信息,包括每个线程的 CPU 使用率、内存使用情况、线程状态
top -Hp <进程id>
# 找到占用 cpu 使用率最高的线程,记下线程 id
# 将线程 id 通过下边这行命令转成 16 进制
printf "%x\n" <线程id>
# 定位哪段代码导致的 cpu 使用率过高:jstack 43987 | grep '0x41e8' -C5--color'
# jstack 生成该进程的堆栈信息,通过线程的 16 进制线程 id 过滤出指定线程的信息
# -C5 表示显示匹配行的 5 行上下文
# --color:高亮显示,方便阅读
jstack <进程id> | grep '<16进制线程id>' -C5--color

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1419060.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android创建工程

语言选择Java&#xff0c;我用的Java 最小SDK&#xff1a;就是开发的APP支持的最小安卓版本 Gradle 是一款Google 推出的基于 JVM、通用灵活的项目构建工具&#xff0c;支持 Maven&#xff0c;JCenter 多种第三方仓库;支持传递性依赖管理、废弃了繁杂的xml 文件&#xff0c;转而…

【JaveWeb教程】(32)SpringBootWeb案例之《智能学习辅助系统》的详细实现步骤与代码示例(5)文件上传的实现

目录 SpringBootWeb案例052. 文件上传2.1 简介2.2 本地存储 SpringBootWeb案例05 前面我们已经实现了员工信息的条件分页查询以及删除操作。 关于员工管理的功能&#xff0c;还有两个需要实现新增和修改员工。 本节的主要内容&#xff1a; 文件上传 2. 文件上传 在我们完成…

GMS测试BTSfail-CVE-2022-20451

描述&#xff1a; 项目需要过GMS兼容性测试&#xff0c;BTS这块我们环境没有&#xff0c;送检之后出现了一个BTS的Alert&#xff0c;这个是必须要解决的。下面的warning可以不考虑。 这个是patch问题&#xff0c;根据代理提供的pdf文件找到一个id:为A-235098883的补丁&#xf…

前缀和入门(c++语言)

在讲算法之前&#xff0c;我们先来思考一个问题&#xff1a;小明有n个编号为1~n的篮子&#xff0c;每个篮子里装有ai个苹果&#xff0c;求从 x至y 的篮子里的苹果数量之和。 如果没学过前缀和的同学&#xff0c;可能会打出这样的代码&#xff1a; 这种算法要得出一个区间之和&…

数字艺术展厅有什么好处,搭建数字艺术展厅要注意什么

引言&#xff1a; 数字艺术展厅是一种利用数字科技手段搭建的艺术展览空间&#xff0c;通过数字化展示艺术品&#xff0c;能够为观众带来全新的艺术体验。那么数字艺术展厅有什么好处&#xff0c;搭建数字艺术展厅要注意什么呢&#xff1f; 一、数字艺术展厅的好处 1.创新艺术…

(2023)逆转诅咒:由“A is B”训练的LLM没有学到“B is A”

The Reversal Curse: LLMs trained on “A is B” fail to learn “B is A” 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 2. 实验和结果 4. 讨论和未来工作 0. 摘要 我们…

动手学深度学习(一)深度学习介绍2

目录 二、起源 三、深度学习的成功案例&#xff1a; 四、特点&#xff1a; 五、小结&#xff1a; 二、起源 为了解决各种各样的机器学习问题&#xff0c;深度学习提供了强大的工具。 虽然许多深度学习方法都是最近才有重大突破&#xff0c;但使用数据和神经网络编程的核心思…

代码随想录算法训练营DAY6 | 哈希表(1)

DAY5休息一天&#xff0c;今天重启~ 哈希表理论基础&#xff1a;代码随想录 Java hash实现 &#xff1a;java 哈希表-CSDN博客 一、LeetCode 242 有效的字母异位词 题目链接&#xff1a;242.有效的字母异位词 思路&#xff1a;设置字典 class Solution {public boolean isAnag…

C/C++ - 内存管理(C++)

堆栈 C中的栈和堆是用于存储变量和对象​​的两个主要内存区域。栈是一种自动分配和释放内存的区域&#xff0c;用于存储局部变量和函数调用的上下文。栈上的内存分配和释放是自动进行的&#xff0c;无需手动管理。堆是动态分配内存的区域&#xff0c;用于存储动态创建的对象和…

Blender教程(基础)-内插面、分离、环切、倒角-08

一、内插面 菜单位置如下图位置。 单击需要处理的面&#xff0c;出现一个黄色的圈。 1、菜单选中内插 鼠标悬停在黄色圈内单击左键可以来回实现内插&#xff0c;但是发现并不好操作。 2、快捷键内插 在选中需要操作的面之后&#xff0c;鼠标移动到外面&#xff0c;键盘在英…

计算机设计大赛 基于图像识别的跌倒检测算法

前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于图像识别的跌倒检测算法 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/…

Java图形化界面基本案例

案例&#xff1a; public class exer1 {JFrame snew JFrame("练习");//菜单JMenuBar jMenuBarnew JMenuBar();JMenu wenjiannew JMenu("文件");JMenu bianjinew JMenu("编辑");JMenuItem zidongnew JMenuItem("自动换行");JMenuItem f…

斜率优化dp模型整理

300. 任务安排1&#xff08;300. 任务安排1 - AcWing题库&#xff09; 思路&#xff1a;很明显这些任务是按顺序排好的&#xff0c;我们能执行的操作只是对它们进行分批&#xff0c;我们可以发现每一批之前的开始时间s&#xff0c;影响的不仅仅是当前这一批的结束时间&#xff…

Java强训day9(选择题编程题)

选择题 class Person {String name "No name";public Person(String nm) {name nm;} } class Employee extends Person {String empID "0000";public Employee(String id) {super(" ");//要调用父类的有参构造方法否则报错empID id;} } pu…

常用芯片学习——AMS1117芯片

AMS1117 1A 低压差线性稳压器 使用说明 AMS1117 是一款低压差线性稳压电路&#xff0c;该电路输出电流能力为1A。该系列电路包含固定输出电压版本和可调输出电压版本&#xff0c;其输出电压精度为士1.5%。为了保证芯片和电源系统的稳定性&#xff0c;XBLWAMS1117 内置热保护和…

秋招面试—浏览器原理篇

浏览器原理篇 1.什么是XSS、CSRF,怎么预防&#xff1f; &#xff08;1&#xff09;XSS(跨站脚本攻击)&#xff1a;攻击者将恶意代码植入到浏览器页面中&#xff0c;盗取存储在客户端的Cookie&#xff1b; ​ XSS分为&#xff1a;①存储型&#xff1a;论坛发帖、商品评论、用户…

大型电商系统商城源码_架构_订单系统_OctShop

中国的电商差不多发展到今天已经有20多年的历史啦&#xff0c;特别是过去的10年里其发展速度与竞争是相当的激烈&#xff0c;发展出了各种各样的模式如&#xff1a;B2B、B2C、B2B2C、O2O、社交电商等等。对于广大的企业或商家来说&#xff0c;电商是一个不可或缺的销售渠道&…

猫咪不吃东西怎么办?公认适口性好的生骨肉冻干分享

猫咪不吃东西怎么办&#xff1f;遇到这类情况主人需要仔细观察并分析情况。如果猫咪出现其他异常症状&#xff0c;如呕吐、腹泻、体温异常等&#xff0c;可能是生病了&#xff0c;应及时就医。如果猫咪没有其他异常症状&#xff0c;那猫咪不吃东西怎么办&#xff1f;可能是猫粮…

JAVA多线程并发补充

AQS 是一个抽象父类 全称是 AbstractQueuedSynchronizer&#xff0c;是阻塞式锁和相关的同步器工具的框架。 用 state 属性来表示资源的状态&#xff08;分独占模式和共享模式&#xff09;&#xff0c;子类需要定义如何维护这个状态&#xff0c;控制如何获取锁和释放锁 getSt…

Windows系统云服务器自定义域名解析导致网站无法访问怎么解决?

本文九河云介绍Windows实例内部自定义域名解析与本地网络域名解析不一致导致无法访问网站的问题描述、问题原因和解决方案。 问题描述 在Windows实例内部通过浏览器无法访问某网站&#xff0c;但在其他设备上可以正常访问&#xff0c;排查发现Windows实例内部自定义域名解析与…