关于Java并发、JVM面试题

news2024/10/4 20:00:15

前言

之前为了准备面试,收集整理了一些面试题。
本篇文章更新时间2023年12月27日。
最新的内容可以看我的原文:https://www.yuque.com/wfzx/ninzck/cbf0cxkrr6s1kniv

并发

进程与线程的区别

  • 线程属于进程,进程可以拥有多个线程。
  • 进程独享内存,线程之间共享进程的内存。
  • 进程是资源分配调度的最小单位,线程是CPU调度的最小单位。
  • 进程的创建、销毁(如分配、销毁内存、I/O设备等)以及上下文切换的开销更大。
  • 同一进程中,多线程之间的通信可以通过相同的空间地址,方便的通信。
  • 进程编程调试简单可靠,但是创建销毁开销大;线程开销小,但是编程调试相对复杂。
  • 进程间不会相互影响;线程挂掉可导致进程挂掉。
  • 进程适应于多核多机分布;线程适合用于多核。

单核 CPU 上运行多个线程效率一定会高吗?

取决于任务类型:IO密集型还是CPU密集型。

说说线程的生命周期和状态?

初始New、就绪Ready、运行Runnable、等待Waiting、有限等待Timed_Waiting、阻塞Blocked、终止Terminated。
https://github.com/Snailclimb/JavaGuide/blob/main/docs/java/concurrent/java-concurrent-questions-01.md

为什么JVM不区分Runnable、Ready两种状态?

JVM层面,只看到Runnable状态。这是因为:
多任务操作系统通常用“时间分片”方式进行抢占式轮转调用。
时间片通常很小,线程用完时间片之后马上放回调度队列末尾, 由于时间片小、线程切换得快,所以区分这两种状态没有意义。

什么是上下文?

线程是CPU资源调度的基本单位,CPU的执行需要线程的状态数据,比如寄存器信息、程序计数器等,这些信息称为上下文信息。

程序计数器:存储了指令的内存地址。
指令寄存器(寄存器的一种):存储了将要执行的指令(指令来自程序计数器中内存地址指向的值),CPU会对指令进行分析,交由对应的目标(逻辑运算单元或控制单元)去执行;

什么是上下文切换?

CPU在处理新任务前,将上下文信息存储到系统内核,并加载新任务的上下文到寄存器和程序计数器。

上下文切换的原因?

● 进程结束;
● 时间片耗尽;
● 进程所需资源没有得到满足时被挂起;
● 让优先级更高的进程先执行时,被挂起;
● 硬件中断程序。

为什么频繁的上下文切换会影响性能?

上下文的保存、恢复由CPU处理,相对于CPU的处理速度来说,上下文切换操作是比较耗时的。

创建线程的方式

  • 继承 Thread 类;
  • 实现 Runnable 接口;
  • 实现 Callbale 接口。

Java 中用到的线程调度算法是什么?

分时调度模型和抢占式调度模型。

请你说一说synchronized和volatile的原理与区别

volatile原理
原理是依靠计算机的基本屏障指令来实现。
synchronized原理
通过获取屏障、释放屏障包装线程安全。
区别
volatile常被称为轻量级锁,跟synchronized相比,volate只能保证变量单个操作的原子性,不具备排他性,也不会引起上下文切换。

什么是死锁?

产生死锁要满足四个必要条件:请求保持、互斥性、不可剥夺、循环等待。

如何避免死锁?

破坏除互斥性之外的死锁条件。

  • 请求保持:可以一次性申请所有资源;
  • 不可剥夺:当申请不够资源时,可以主动释放占有的资源;
  • 循环等待:设置合理的顺序预防。

sleep() 方法和 wait() 方法对比

都可以暂停线程。
区别:sleep不释放锁;wait需要通过notify唤醒线程;sleep是Thread的静态方法、wait是Object的方法。

什么是JMM?

是java语言规范的一部分,定义了final、volate、synchronized关键字的行为,确保做了同步的java代码正确运行在不同架构的处理器上。
对于开发人员来说,它为我们解答了三个问题:

  • 原子性问题:规定了除long、double以外的基本数据类型、引用类型的读、写操作具有原子性;规定被volate修饰的long、double共享变量具有原子性。
  • 可见性、有序性方面:它通过happens-before来解答。

什么是happens-before规则?

JMM定义了一些动作,如锁的申请、释放,变量读、写,Thread.join等,如果动作A和动作B具有 happens-before 关系,称 A happens-before B,JMM会保证A的结果对B可见,并且是有序的。

其中一条关于volate变量的规则:对volatile变量的写操作 happens-before 后续的针对该变量的读操作。注意的是,要有时间上的先后顺序。

volate如何保证变量的可见性?

禁用CPU高速缓存,线程对此共享变量的操作是在主存进行,而不是在线程私有的数据副本。

volate如何 保证变量的有序性/禁止重排序?

基于内存屏障保证。
一般来说,处理器支持那种内存重排序,就会提供相应的禁止重排序的指令,比如说LoadLoad

sleep(0)的意义

本质上是触发系统重新进行一次CPU竞争。因为在CPU竞争采用抢占式的系统中,线程需要进行抢占CPU资源,抢到之后会霸占CPU。
其它方面,可以埋入一个安全点,让GC线程进行工作。

如果“可数循环”for(int)太长,需要等循环结束,才达到安全点,这会推迟GC回收工作。

Java 6 之后synchronized的优化

自旋锁、适应性自旋锁、锁消除、锁粗化、轻量级锁。

synchronized 底层原理

通过监视器保证线程安全。在代码块前后插入监视器,线程要获取监视器的持有权才能

synchronized锁升级过程

  • 无锁状态 - 没有线程获取锁,synchronized块直接进入。
  • 偏向锁 - 锁偏向于第一个获得它的线程,如果线程没有改变则不需要撤销偏向。
  • 轻量级锁 - 如果有另一个线程试图获得偏向锁,则会膨胀为轻量级锁,会有点 CAS 操作。
  • 重量级锁 - 当竞争加剧,CAS操作无法 resolved 时,会进一步升级为重量级锁,会进入互斥区,性能降低。
  • 批量重入锁 - 如果一个线程多次进入同步块,可以使用批量重入避免多次加锁。

synchronized锁降级过程

synchronized 和 volatile 有什么区别?

性能上volate更好,对原子性的保证有些差别,volate只保证单个共享变量读写操作的原子性,如i=1。synchronized可以保证多个操作的原子性。

ReentrantReadWriteLock 适合什么场景?

需要线程安全、读多写少的场景。

线程持有读锁还能获取写锁吗?

不能。反之可以,即持有写锁可以获取读锁。

ThreadLocal 有什么用?

每个线程多有自己的本地变量,避免了多线程操作共享变量,从而避免了线程安全问题。

ThreadLocal 原理了解吗?

ThreadLocal内部有一个静态类ThreadLocalMap,这个类是基于数组实现的hash表,数组元素继承了弱引用类,元素中包含key和value,其中key是弱引用。
每个Thread都拥有一个独立的ThreadLocalMap实例,这样就达到了封闭的效果。

ThreadLocal中Map的key为什么要使用弱引用?

key引用指向的是ThreadLocal,使用弱引用可以保证线程销毁的时候,ThreadLocal能及时被回收。

ThreadLocal为什么需要手动回收value?

如果线程一直运行,那么就一直持有ThreadLocalMap的实例的强引用,导致指向value的引用链也是强引用,这样GC线程无法回收。

ThreadLocal 内存泄露问题是怎么导致的?

假如线程一直运行,那么对value的引用是强引用,不会被回收,而ThreadLocal是弱引用,可以回收。

为什么使用线程池?

创建线程是比较重的操作,频繁的创建、销毁影响性能;
实现线程池可以实现资源隔离,达到一定程度的流量控制效果;
同时,由线程池维护线程,降低自己维护线程出错概率

线程池核心参数?

核心线程数、最大线程数、阻塞队列、拒绝策略、线程的存活时间、线程工厂;

拒绝策略有哪些?

直接抛出异、用调用线程执行当前任务、直接丢弃当前任务、丢去最早未处理的。

线程池处理任务流程?

大概流程:首先如果工作线程数小于核心线程数,那么就创建一个新线程并执行任务,否则,加入到阻塞队列,假设这个是有界的,当队列满了之后,就会判断是否达到最大线程数限制,没有达到的话,就创建一个线程并执行任务;如果达到最大线程数的限制,那么就触发拒绝策略。

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         * Proceed in 3 steps:
         *
         * 1. If fewer than corePoolSize threads are running, try to
         * start a new thread with the given command as its first
         * task.  The call to addWorker atomically checks runState and
         * workerCount, and so prevents false alarms that would add
         * threads when it shouldn't, by returning false.
         *
         * 2. If a task can be successfully queued, then we still need
         * to double-check whether we should have added a thread
         * (because existing ones died since last checking) or that
         * the pool shut down since entry into this method. So we
         * recheck state and if necessary roll back the enqueuing if
         * stopped, or start a new thread if there are none.
         *
         * 3. If we cannot queue task, then we try to add a new
         * thread.  If it fails, we know we are shut down or saturated
         * and so reject the task.
         */
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

设置多少线程数比较合适?

基于任务类型来判断。
CPU密集型的话,线程数可以设置得跟核数一样多。
IO密集型的话,考虑到可能经常阻塞,可以设置为核数得两倍。

AQS 是什么?

抽象队列同步器,是一个抽象类,可以用来构建锁和同步器。

AQS 原理是什么?

AQS的思想是我们有一定量的共享资源,当线程获取到足够的共享资源时,可以执行任务,否则就插入到队列。

内部核心组成包括 一个虚拟的双休队列CLH以及一个被volate修饰的state变量。

以可重入锁为例子,申请到资源的时候,state + 1,重入的时候继续+1,当state=0的时候,其它线程才能申请到这个锁。

Semaphore 的原理是什么?

基于AQS实现的一个共享锁。其思想是将适量的共享资源放入state变量,线程的执行需要申请到足够的资源才能执行。

用过 CountDownLatch 么?什么场景下用的?

将线程阻塞在一个地方,直到所有线程的任务执行完毕。

比如进行文件读取。

CountDownLatch有没有可以改进的地方呢?

结合CompletableFuture 使用。

JVM面试题

讲一下垃圾回收机制

在Java中,程序员不需要显式的去释放一个对象的内存,JVM会自动释放。
JVM中,有一类线程是垃圾回收线程,当堆内存不足的时候,会执行扫描、回收工作。

class加载机制

类是由类加载器及其子类实现。
类的声明周期包括:加载、连接、初始化、使用、卸载。

对象是否存活?

引用类型

垃圾回收算法

内存分配策略

Full GC触发条件

程序计数器是什么?

一个行号指示器,用于标识下一条要执行的命令的位置。

Java 虚拟机栈的作用?

线程调用方法进行入栈操作,相关信息被封装到栈帧中,包括本地变量表、动态连接、方法出口、操作栈等信息;当方法执行完成,就进行一个出栈操作。

堆的作用是什么?

存放对象的实例。

方法区的作用是什么?

存放被虚拟机加载的类型信息、静态变量、常量、即时编译器编译后的代码缓存等数据。

运行时常量池的作用是什么?

存放字面量和符号引用。

直接内存是什么?

不属于运行时内存区域,不受JVM管理,不受JVM堆大小的限制。

直接内存导致的溢出一个明显的特征就是堆快照文件明显看不出异常,快照文件很小,而程序直接、间接使用了直接内存(如NIO),那么就可以考虑检查直接内存。

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

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

相关文章

【项目】玩具租赁博客测试报告

目录 一、项目背景 二、项目功能 三、功能测试 一、项目背景 玩具租赁系统采用前后端分离的方法来实现&#xff0c;同时使用了数据库来存储相关的数据&#xff0c;同时将其部署到云服务器上。前端主要有十五个页面构成&#xff1a;用户注册、管理员注册、登录页、用户和管理…

java浅拷贝BeanUtils.copyProperties引发的RPC异常 | 京东物流技术团队

背景 近期参与了一个攻坚项目&#xff0c;前期因为其他流程原因&#xff0c;测试时间已经耽搁了好几天了&#xff0c;本以为已经解决了卡点&#xff0c;后续流程应该顺顺利利的&#xff0c;没想到 人在地铁上&#xff0c;bug从咚咚来~ 没有任何修改的服务接口&#xff0c;抛出…

IT安全:实时网络安全监控

了解庞大而复杂的网络环境并非易事&#xff0c;它需要持续观察、深入分析&#xff0c;并对任何违规行为做出快速反应。这就是为什么实时网络安全监控工具是任何组织 IT 安全战略的一个重要方面。 网络攻击和合规性法规是 IT 安全的两个主要驱动因素。同时&#xff0c;数据泄露…

Spring Cloud Gateway 常见过滤器的基本使用

目录 1. 过滤器的作用 2. Spring Cloud Gateway 过滤器的类型 2.1 内置过滤器 2.1.1 AddResponseHeader 2.1.2 AddRequestHeader 2.1.3 PrefixPath 2.1.4 RequestRateLimiter 2.1.5 Retry 2.2 自定义过滤器 1. 过滤器的作用 过滤器通常用于拦截、处理或修改数据流和事…

Springboot+vue的医疗报销系统(有报告),Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的医疗报销系统&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的医疗报销系统&#xff0c;采用M&#xff08;model&a…

百度沧海文件存储CFS推出新一代Namespace架构

随着移动互联网、物联网、AI 计算等技术和市场的迅速发展&#xff0c;数据规模指数级膨胀&#xff0c;对于分布式文件系统作为大规模数据场景的存储底座提出了更高的要求。已有分布式文件系统解决方案存在着短板&#xff0c;只能适应有限的场景&#xff1a; >> 新型分布式…

【产品经理】axure中继器的使用——表格增删改查分页实现

笔记为个人总结笔记&#xff0c;若有错误欢迎指出哟~ axure中继器的使用——表格增删改查分页实现 中继器介绍总体视图视频预览功能1.表头设计2.中继器3.添加功能实现4.删除功能实现5.修改功能实现6.查询功能实现7.批量删除 中继器介绍 在 Axure RP9 中&#xff0c;中继器&…

IntelliJ IDEA Apache Dubbo,IDEA 官方插件正式发布!

作者&#xff1a;刘军 最受欢迎的 Java 集成开发环境 IntelliJ IDEA 与开源微服务框架 Apache Dubbo 社区强强合作&#xff0c;给广大微服务开发者带来了福音。与 IntelliJ IDEA 2023.2 版本一起&#xff0c;Jetbrains 官方发布了一款全新插件 - Apache Dubbo in Spring Frame…

matlab列优先与高维矩阵重构

由于matlab在列化a(:)以及reshape(a)等操作中是列优先的&#xff0c;所以要重构出新的高维度矩阵&#xff0c;通常要把reshape和permute结合起来使用。 先到 http://caffe.berkeleyvision.org/ 下载 训练好的model bvlc_reference_caffenet.caffemodel; 更多caffe使用也请参看…

C#编程艺术:Fizzler库助您高效爬取www.twitter.com音频

数据是当今数字时代的核心资源&#xff0c;但是从互联网上抓取数据并不容易。本文将教您如何利用C#编程艺术和Fizzler库高效爬取Twitter上的音频数据&#xff0c;让您轻松获取所需信息。 Twitter简介 Twitter是全球最大的社交媒体平台之一&#xff0c;包含丰富的音频资源。用…

机器学习系列--R语言随机森林进行生存分析(1)

随机森林&#xff08;Breiman 2001a&#xff09;&#xff08;RF&#xff09;是一种非参数统计方法&#xff0c;需要没有关于响应的协变关系的分布假设。RF是一种强大的、非线性的技术&#xff0c;通过拟合一组树来稳定预测精度模型估计。随机生存森林&#xff08;RSF&#xff0…

【Pytorch】学习记录分享8——PyTorch自然语言处理基础-词向量模型Word2Vec

【Pytorch】学习记录分享7——PyTorch自然语言处理基础-词向量模型Word2Vec 1. 词向量模型Word2Vec)1. 如何度量这个单词的&#xff1f;2.词向量是什么样子&#xff1f;3.词向量对应的热力图&#xff1a;4.词向量模型的输入与输出![在这里插入图片描述](https://img-blog.csdni…

solidity案例详解(七)复杂众筹合约

自己原创智能合约&#xff0c;有作业需求可加下面的图片中的裙 1、在 Remix 中&#xff0c;以 Account1 完成“众筹项目”合约的编译和部署。&#xff08;显示合约、函数、状态变量、结构体、事件的命名&#xff09; 2、在 Remix 中&#xff0c;以 Account2 完成“参与众筹”合…

【架构】企业信息安全体系架构详解

企业信息安全体系架构来说,是包含技术、运维、管理3个层面。本文说的安全架构,主要集中讨论偏研发技术层面的安全架构。 安全性是软件研发技术体系,系统架构设计阶段的一个关键DFX能力,与可靠性、可服务性、性能等架构属性并列。由于安全性设计自身的特点,涉及到系统架构…

【ARMv8M Cortex-M33 系列 2.1 -- Cortex-M33 使用 .hex 文件介绍】

文章目录 HEX 文件介绍英特尔十六进制文件格式记录类型hex 示例Cortex-M 系列hex 文件的使用 HEX 文件介绍 .hex 文件通常用于微控制器编程&#xff0c;包括 ARM Cortex-M 系列微控制器。这种文件格式是一种文本记录&#xff0c;用于在编程时传递二进制信息。.hex 文件格式最常…

Python+OpenCV 零基础学习笔记(1):anaconda+vscode+jupyter环境配置

文章目录 前言相关链接环境配置&#xff1a;AnacondaPython配置OpenCVOpencv-contrib:Opencv扩展 Notebook:python代码笔记vscode配置配置AnacondaJupyter文件导出 前言 作为一个C# 上位机&#xff0c;我认为上位机的终点就是机器视觉运动控制。最近学了会Halcon发现机器视觉还…

『Linux升级路』冯诺依曼体系结构与操作系统

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;Linux &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、冯诺依曼体系结构 &#x1f4d2;1.1为什么要有体系结构 &#x1f4d2;1.2…

23款奔驰GLC260L升级原厂540全景影像 高清环绕的视野

嗨 今天给大家介绍一台奔驰GLC260L升级原厂360全景影像 新款GLC升级原厂360全景影像 也只需要安装前面 左右三个摄像头 后面的那个还是正常用的&#xff0c;不过不一样的是 升级完成之后会有多了个功能 那就是新款透明底盘&#xff0c;星骏汇小许 Xjh15863 左右两边只需要更换…

Next Station of Flink CDC

摘要&#xff1a;本文整理自阿里云智能 Flink SQL、Flink CDC 负责人伍翀&#xff08;花名&#xff1a;云邪&#xff09;&#xff0c;在 Flink Forward Asia 2023 主会场的分享。Flink CDC 是一款基于 Flink 打造一系列数据库的连接器。本次分享主要介绍 Flink CDC 开源社区在过…

【TensorFlow 精简版】TensorFlow Lite

目录 一 TensorFlow Lite简介 二 开发 三 开始使用 一 TensorFlow Lite简介 TensorFlow Lite 是一组工具&#xff0c;可帮助开发者在移动设备、嵌入式设备和 loT 设备上运行模型&#xff0c;以便实现设备端机器学习。 针对设备端的机器学习进行的优化&#xff1a; ① 延时&…