金九银十面试题之《JUC》

🐮🐮🐮
辛苦牛,掌握主流技术栈,包括前端后端,已经7年时间,曾在税务机关从事开发工作,目前在国企任职。希望通过自己的不断分享,可以帮助各位想或者已经走在这条路上的朋友一定的帮助

目录

  • 前言
  • 内容
    • 📟 Q1:什么是 CAS?
    • 📟 Q2:CAS 有什么问题?
    • 📟 Q3:有哪些原子类?
    • 📟 Q4:AtomicIntger 实现原子更新的原理是什么?
    • 📟 Q5:CountDownLatch 是什么?
    • 📟 Q6: CyclicBarrier 是什么?
    • 📟 Q7:Semaphore 是什么?
    • 📟 Q8: Exchanger 是什么?
    • 📟 Q9:JDK7 的 ConcurrentHashMap 原理?
    • 📟 Q10:JDK8 的 ConcurrentHashMap 原理?
    • 📟 Q11:ArrayList 的线程安全集合是什么?
  • 写在最后

前言

❤️金九银十马上就要来啦,各位小伙伴们有计划跳槽的要开始准备了,博主接下来一段时间会给大家持续更新面试题目,大家持续关注一下,感谢🙏🙏🙏
今天是JUC的面试题,欢迎指正
之前的面试文章链接也给到大家
金九银十面试题之Mysql
金九银十面试题之设计模式
金九银十面试题之数据结构和算法
金九银十面试题之Mybatis
金九银十面试题之《Spring Data JPA、Spring MVC、AOP》
金九银十面试题之《Spring IOC》

内容

📟 Q1:什么是 CAS?

CAS 表示 Compare And Swap,比较并交换,CAS 需要三个操作数,分别是内存位置 V、旧的预期值 A 和准备设置的新值 B。CAS 指令执行时,当且仅当 V 符合 A 时,处理器才会用 B 更新 V 的值,否则它就不执行更新。但不管是否更新都会返回 V 的旧值,这些处理过程是原子操作,执行期间不会被其他线程打断。
在JDK5后,Java类库中才开始使用CAS操作,该操作由Unsafe类里的 compareAndSwapInt 等几 个方法包装提供。HotSpot 在内部对这些方法做了特殊处理,即时编译的结果是一条平台相关的处理器CAS 指令。Unsafe 类不是给用户程序调用的类,因此 JDK9 前只有 Java 类库可以使用 CAS,譬如 juc 包里的 AtomicInteger类中compareAndSet 等方法都使用了Unsafe 类的 CAS 操作实现。

📟 Q2:CAS 有什么问题?

CAS 从语义上来说存在一个逻辑漏洞:如果 V 初次读取时是 A,并且在准备赋值时仍为 A,这依旧不能 说明它没有被其他线程更改过,因为这段时间内假设它的值先改为 B 又改回 A,那么 CAS 操作就会误 认为它从来没有被改变过。
这个漏洞称为 ABA 问题,juc 包提供了一个 AtomicStampedReference,原子更新带有版本号的引用类 型,通过控制变量值的版本来解决 ABA 问题。大部分情况下 ABA 不会影响程序并发的正确性,如果需 要解决,传统的互斥同步可能会比原子类更高效。

📟 Q3:有哪些原子类?

JDK5提供了java.util.concurrent.atomic包,这个包中的原子操作类提供了一种用法简单、性能高 效、 线程安全地更新一个变量的方式。到 JDK 8 该包共有17个类,依据作用分为四种:原子更新基本类型类、 原子更新数组类、原子更新引用类以及原子更新字段类,atomic 包里的类基本都是使用 Unsafe 实现 的包装类。
AtomicInteger 原子更新整形、 AtomicLong 原子更新⻓整型、AtomicBoolean 原子更新布尔类型。 AtomicIntegerArray,原子更新整形数组里的元素、 AtomicLongArray 原子更新⻓整型数组里的元素、 AtomicReferenceArray 原子更新引用类型数组里的元素。
AtomicReference 原子更新引用类型、AtomicMarkableReference 原子更新带有标记位的引用类型, 可以绑定一个 boolean 标记、 AtomicStampedReference 原子更新带有版本号的引用类型,关联一个 整数值作为版本号,解决 ABA 问题。
AtomicIntegerFieldUpdater 原子更新整形字段的更新器、 AtomicLongFieldUpdater 原子更新⻓整形 字段的更新器AtomicReferenceFieldUpdater 原子更新引用类型字段的更新器。

📟 Q4:AtomicIntger 实现原子更新的原理是什么?

AtomicInteger 原子更新整形、 AtomicLong 原子更新⻓整型、AtomicBoolean 原子更新布尔类型。以
getAndIncrement 原子方式将当前的值加1,首先在for死循环中取得AtomicInteger里存储的数 值,第二步对 AtomicInteger 当前的值加 1 ,第三步调用 compareAndSet 方法进行原子更新,先检查当前数值是否等于 expect,如果等于则说明当前值没有被其他线程修改,则将值更新为 next,否则 会更新失败返回 false,程序会进入 for 循环重新进行 compareAndSet 操作。
atomic 包中只提供了三种基本类型的原子更新,atomic 包里的类基本都是使用 Unsafe 实现的, Unsafe只提供三种CAS方法:compareAndSwapInt、compareAndSwapLong 和
compareAndSwapObject ,例如原子更新 Boolean 是先转成整形再使用 compareAndSwapInt 。

📟 Q5:CountDownLatch 是什么?

CountDownLatch 是基于执行时间的同步类,允许一个或多个线程等待其他线程完成操作,构造方法接 收一个 int 参数作为计数器,如果要等待 n 个点就传入 n。每次调用 countDown 方法时计数器减
1, await 方法会阻塞当前线程直到计数器变为0,由于c点ountDown 方法可用在任何地方,所以 n 个 既可以是 n 个线程也可以是一个线程里的 n 个执行步骤。

📟 Q6: CyclicBarrier 是什么?

循环屏障是基于同步到达某个点的信号量触发机制,作用是让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障才会解除。构造方法中的参数表示拦截线程数量,每个线程调用await 方法告诉 CyclicBarrier 自己已到达屏障,然后被阻塞。还支持在构造方法中传入一个 Runnable 任务,当线程到 达屏障时会优先执行该任务。适用于多线程计算数据,最后合并计算结果的应用场景。
CountDownLacth 的计数器只能用一次,而 CyclicBarrier 的计数器可使用 reset 方法重置,所以 CyclicBarrier 能处理更为复杂的业务场景,例如计算错误时可用重置计数器重新计算。

📟 Q7:Semaphore 是什么?

信号量用来控制同时访问特定资源的线程数量,通过协调各个线程以保证合理使用公共资源。信号量可以用于流量控制,特别是公共资源有限的应用场景,比如数据库连接。
Semaphore 的构造方法参数接收一个 int 值,表示可用的许可数量即最大并发数。使用 acquire 方法
获得一个许可证,使用 release 方法归还许可,还可以用 tryAcquire 尝试获得许可。

📟 Q8: Exchanger 是什么?

交换者是用于线程间协作的工具类,用于进行线程间的数据交换。它提供一个同步点,在这个同步点两 个线程可以交换彼此的数据。
两个线程通过 exchange 方法交换数据,第一个线程执行 exchange 方法后会阻塞等待第二个线程执 行该方法,当两个线程都到达同步点时这两个线程就可以交换数据,将本线程生产出的数据传递给对 方。应用场景包括遗传算法、校对工作等。

📟 Q9:JDK7 的 ConcurrentHashMap 原理?

ConcurrentHashMap 用于解决 HashMap 的线程不安全和 HashTable 的并发效率低,HashTable 之 所以效率低是因为所有线程都必须竞争同一把锁,假如容器里有多把锁,每一把锁用于锁容器的部分数 据,那么多线程访问容器不同数据段的数据时,线程间就不会存在锁竞争,从而有效提高并发效率,这 就是 ConcurrentHashMap 的锁分段技术。首先将数据分成 Segment 数据段,然后给每一个数据段配一把锁,当一个线程占用锁访问其中一个段的数据时,其他段的数据也能被其他线程访问。
get 实现简单高效,先经过一次再散列,再用这个散列值通过散列运算定位到 Segment,最后通过散列 算法定位到元素。get 的高效在于不需要加锁,除非读到空值才会加锁重读。get 方法中将共享变量定 义为 volatile,在 get 操作里只需要读所以不用加锁。
put 必须加锁,首先定位到 Segment,然后进行插入操作,第一步判断是否需要对 Segment 里的 HashEntry 数组进行扩容,第二步定位添加元素的位置,然后将其放入数组。
size 操作用于统计元素的数量,必须统计每个 Segment 的大小然后求和,在统计结果累加的过程中, 之前累加过的 count 变化几率很小,因此先尝试两次通过不加锁的方式统计结果,如果统计过程中容器
大小发生了变化,再加锁统计所有 Segment 大小。判断容器是否发生变化根据 modCount 确定。

📟 Q10:JDK8 的 ConcurrentHashMap 原理?

主要对 JDK7 做了三点改造:

  1. 取消分段锁机制,进一步降低冲突概率。
  2. 引入红黑树结构,同一个哈 希槽上的元素个数超过一定阈值后,单向链表改为红黑树结构。
  3. 使用了更加优化的方式统计集合内的元 素数量。具体优化表现在:在 put、resize 和 size 方法中设计元素总数的更新和计算都避免了锁,使用 CAS 代替。
    get 同样不需要同步,put 操作时如果没有出现哈希冲突,就使用 CAS 添加元素,否则使用 synchronized 加锁添加元素。

当某个槽内的元素个数达到 7 且 table 容量不小于 64 时,链表转为红黑树。当某个槽内的元素减少到 6 时,由红黑树重新转为链表。在转化过程中,使用同步块锁住当前槽的首元素,防止其他线程对当前 槽进行增删改操作,转化完成后利用 CAS 替换原有链表。由于 TreeNode 节点也存储了 next 引用,因 此红黑树转为链表很简单,只需从 first 元素开始遍历所有节点,并把节点从 TreeNode 转为 Node 类 型即可,当构造好新链表后同样用 CAS 替换红黑树。

📟 Q11:ArrayList 的线程安全集合是什么?

可以使用 CopyOnWriteArrayList 代替 ArrayList,它实现了读写分离。写操作复制一个新的集合,在新 集合内添加或删除元素,修改完成后再将原集合的引用指向新集合。这样做的好处是可以高并发地进行 读写操作而不需要加锁,因为当前集合不会添加任何元素。使用时注意尽量设置容量初始值,并且可以 使用批量添加或删除,避免多次扩容,比如只增加一个元素却复制整个集合。
适合读多写少,单个添加时效率极低。CopyOnWriteArrayList 是 fail-safe 的,并发包的集合都是这种 机制,fail-safe 在安全的副本上遍历,集合修改与副本遍历没有任何关系,缺点是无法读取最新数据。这 也是 CAP 理论中 C 和 A 的矛盾,即一致性与可用性的矛盾。

写在最后

希望博主收集的内容能帮到大家,祝大家能找到一个好的工作,过好的生活,如有错误欢迎指正。 💐💐💐

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

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

相关文章

Linux | Ubuntu18.04安装RTX 4060显卡驱动完整教程

文章目录 概述一、定义介绍二、操作教程(一)、前期准备1.进入终端界面2.关闭界面显示器3.禁用其他显卡驱动4.卸载残余显卡驱动5.下载驱动(二)、安装驱动1.给驱动程序赋予权限2.安装驱动3.检查结果(三)、后续问题1.黑屏问题概述 本节详细介绍了如何在ubuntu18系统安装4060显卡的…

pnpm的高级使用

我整理了一些pnpm的高级使用: 并行安装:pnpm通过并行安装依赖项来提高安装速度。默认情况下,它会使用计算机的最大线程数来并行安装依赖项。你也可以使用--recursive选项来并行安装所有子项目的依赖项。 冻结依赖:pnpm支持将依赖…

06微服务间的通信方式

一句话导读 微服务设计的一个挑战就是服务间的通信问题,服务间通信理论上可以归结为进程间通信,进程可以是同一个机器上的,也可以是不同机器的。服务可以使用同步请求响应机制通信,也可以使用异步的基于消息中间件间的通信机制。同…

【云原生|Kubernetes】14-DaemonSet资源控制器详解

【云原生|Kubernetes】14-DaemonSet资源控制器详解 文章目录 【云原生|Kubernetes】14-DaemonSet资源控制器详解简介典型用法DaemonSet语法规则Pod模板Pod 选择算符在选定的节点上运行 Pod DaemonSet的 Pods 是如何被调度的污点和容忍度DaemonSet更新和回滚DaemonSet更新策略执…

MySQL登录成功后密码修改

场景 最近想通过CLI登录一台远古MySQL,结果遇到CLI密码不对,但是,GUI程序之前自动记住密码能够正常登录使用。 思路 通过GUI方式登录,修改密码后,再让新密码生效后,重新使用CLI方式登录MySQL 解决 通过…

Vue2-简介、模板语法、数据绑定、MVVM、数据代理、事件处理

🥔:成功之后就能光明正大地回望所有苦难 VUE-Day1 Vue简介1、Vue是什么?2、谁开发的? 发展历程?3、Vue的特点4、容器和实例、实例中的el和data总结 Vue模板语法插值语法指令语法 数据绑定1.单向数据绑定(v-…

51单片机学习--DS18B20温度读取温度报警器

需要先编写OneWire模块,再在DS18B20模块中调用OneWire模块的函数 先根据原理图做好端口的声明: sbit OneWire_DQ P3^7;接下来像之前一样把时序结构用代码模拟出来: unsigned char OneWire_Init(void) {unsigned char i;unsigned char Ac…

opencv基础49-图像轮廓02-矩特征cv2.moments()->(形状分析、物体检测、图像识别、匹配)

矩特征(Moments Features)是用于图像分析和模式识别的一种特征表示方法,用来描述图像的形状、几何特征和统计信息。矩特征可以用于识别图像中的对象、检测形状以及进行图像分类等任务。 矩特征通过计算图像像素的高阶矩来提取特征。这些矩可以…

Towards Open World Object Detection【论文解析】

Towards Open World Object Detection 摘要1 介绍2 相关研究3 开放世界目标检测4 ORE:开放世界目标检测器4.1 对比聚类4.2 RPN自动标注未知类别4.3 基于能量的未知标识4.4 减少遗忘 5 实验5.1开放世界评估协议5.2 实现细节5.3 开放世界目标检测结果5.4 增量目标检测结果 6 讨论…

javaweb监听器和juery技术

监听servlet创建 package com.hspedu.listener;import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener;/*** 老韩解读* 1. 当一个类实现了 ServletContextListener* 2. 该类就是一个监听器* 3. 该类可…

VoxWeekly|The Sandbox 生态周报|20230807

欢迎来到由 The Sandbox 发布的《VoxWeekly》。我们会在每周发布,对上一周 The Sandbox 生态系统所发生的事情进行总结。 如果你喜欢我们内容,欢迎与朋友和家人分享。请订阅我们的 Medium 、关注我们的 Twitter,并加入 Discord 社区&#xf…

OpenCV和PIL图像对象转换

OpenCV和PIL(Python Imaging Library)都是常用的Python图像处理库。它们都有自己的图像对象类型,因此在使用它们时需要进行相应的转换。 下面是OpenCV图像对象和PIL图像对象之间的转换方法: 将OpenCV图像对象转换为PIL图像对象&…

npm发包中一些操作备忘

1、npm发布相关命令 发布 npm publish 发布beta版 npm publish --tag beta 取消发布 npm unpublish --force 2、lerna发布相关命令 发布 lerna publish 其他的的官方文档里面比较全 lerna中文文档

【Vue3】keep-alive 缓存组件

当在 Vue.js 中使用 <keep-alive> 组件时&#xff0c;它将会缓存动态组件&#xff0c;而不是每次渲染都销毁和重新创建它们。这对于需要在组件间快速切换并且保持组件状态的情况非常有用。 <keep-alive> 只能包含&#xff08;或者说只能渲染&#xff09;一个子组件…

CANoe通过Frame Histogram窗口统计报文周期(方便快捷)

文章目录 效果展示1.插入Frame Histogram窗口2.Activate3.运行CANoe&#xff0c;停止后查看write窗口 效果展示 统计报文周期信息输出在write窗口。 1.插入Frame Histogram窗口 2.Activate 3.运行CANoe&#xff0c;停止后查看write窗口 统计报文周期信息输出在write窗口。

安卓开发上位机基于Qt qwidget第一次一些事

话说为什么要用Qt搞安卓&#xff0c;那肯定是因为熟悉Qt啊&#xff0c;总不能能在学java那一套东西吧&#xff0c;我相信Qt搞出来的性能上会好很多…… 目录 1、是开发环境搭建 2、关文件读写权限问题 3、关于调试 4、AP热点模式IP地址不是固定的 5、比较顺利的点 1…

04-2_Qt 5.9 C++开发指南_SpinBox使用

文章目录 1. SpinBox简介2. SpinBox使用2.1 可视化UI设计2.2 widget.h2.3 widget.cpp 1. SpinBox简介 QSpinBox 用于整数的显示和输入&#xff0c;一般显示十进制数&#xff0c;也可以显示二进制、十六进制的数&#xff0c;而且可以在显示框中增加前缀或后缀。 QDoubleSpinBox…

Shell编程基础(十三)正则表达式

正则表达式 正则表达式元数据普通元字符扩展元字符 总结^ 和 \< 的区别 以及 $ 和 \> 的区别* ? {}的区别 正则表达式 格式&#xff1a;^ 表达式 $ 在不同的场景下&#xff0c;定义是一样&#xff0c;但使用要按照具体的命令去调用&#xff0c;中间的表达式都是通用的…

机器学习笔记:李宏毅ChatGPT课程1:刨析ChatGPT

ChatGPT——Chat Generative Pre-trained Transformer 1 文字接龙 每次输出一个概率分布&#xff0c;根据概率sample一个答案 ——>因为是根据概率采样&#xff0c;所以ChatGPT每次的答案是不一样的&#xff08;把生成式学习拆分成多个分类问题&#xff09;将生成的答案加到…

Linux(进程)

Linux&#xff08;进程&#xff09; 1. 冯诺依曼结构体系2 . 操作系统&#xff08;OS&#xff09;3.进程task_ struct内容分类查看进程查看PID以及PPIDfork()Linux操作系统进程的状态僵尸进程孤儿进程进程优先级其他概念 1. 冯诺依曼结构体系 冯诺依曼结构也称普林斯顿结构&am…