秋招后端开发面试题 - Java多线程(上)

news/2024/5/14 23:32:50

目录

  • Java多线程
    • 前言
    • 面试题
      • 线程和进程?
      • 说说线程有几种创建方式?
      • 为什么调用 start() 方法时会执行 run() 方法,那怎么不直接调用 run() 方法?
      • 线程有哪些常用的调度方法?
      • 线程有几种状态?
      • 守护线程了解吗?
      • 线程间有哪些通信方式?
      • 并发和并行?
      • 同步和异步?
      • 为什么使用多线程?
      • 使用多线程可能带来的问题?
      • 什么是线程上下文切换?
      • 什么是线程死锁?
      • 死锁产生的条件?
      • 如何避免死锁?
      • 那死锁问题怎么排查呢?
      • 活锁和饥饿锁了解吗?
      • 线程间如何同步?
      • sleep() 和 wait()?
      • 为什么 wait() 方法不定义在 Thread 中?
      • 说说你对原子性、可见性、有序性的理解?
      • 如何保证变量的可见性?
      • 那说说什么是指令重排?
      • 指令重排有限制吗?happens-before 了解吗?
      • as-if-serial 又是什么?单线程的程序一定是顺序的吗?
      • volatile 关键字?
      • volatile 实现原理了解吗?
      • 解释双重校验锁实现单例的原理?
      • volatile 可以保证原子性吗?


Java多线程

前言

已经找到工作了,分享秋招时的笔记。祝大家都能顺利找到自己心仪的工作。


面试题

线程和进程?

进程(Process):

  • 进程是操作系统分配资源的基本单位,是程序的一个执行实例
  • 每个进程都有自己独立的内存空间,包括代码、数据、堆栈等
  • 进程之间相互独立,一个进程的崩溃不会影响其他进程
  • 进程间通信需要使用操作系统提供的机制,如管道、消息队列、共享内存等

线程(Thread):

  • 线程是进程的一个执行流,是进程的一部分
  • 线程共享进程的内存空间,因此线程间通信相对更容易
  • 线程可以更轻量级地创建和销毁,开销小

联系与区别:

  • 线程是进程的一部分,一个进程可以包含多个线程
  • 进程是独立的执行环境,拥有独立的内存空间,而线程共享进程的内存空间
  • 进程之间的切换开销较大,涉及上下文切换。线程切换开销相对较小
  • 进程间通信通常需要操作系统提供的机制,而线程间通信相对更容易,可以通过共享内存等方式实现

说说线程有几种创建方式?

  • 继承 Thread 类:重写 run() 方法,调用 start() 方法启动线程
  • 实现 Runnable 接口:重写 run() 方法,调用 start() 方法启动线程
  • 实现 Callable 接口:重写 call() 方法
  • 使用匿名类或 Lambda 表达式
  • 使用线程池

为什么调用 start() 方法时会执行 run() 方法,那怎么不直接调用 run() 方法?

  • 调用 start() 方法会创建一个新线程,然后新线程执行 run() 方法,从而实现多线程并发运行
  • 如果直接调用 run() 方法,就会在当前线程执行,不会启动新线程,就不会实现多线程并发执行

线程有哪些常用的调度方法?

  • wait():使线程进入等待状态
  • join():让线程等待另一个线程执行完成
  • notify()唤醒等待中的一个线程
  • notifyAll()唤醒所有等待中的线程
  • yield():让当前线程让出 CPU 资源
  • interrupt()中断线程
  • isInterrupted()检查线程的中断状态
  • sleep():使线程进入休眠状态

线程有几种状态?

![[image-20230329090159344.png]]

  • 初始状态
  • 运行状态
  • 阻塞状态:需要等待锁释放
  • 等待状态:线程需要等待其他线程做出一些特定动作 (通知或中断)
  • 超时等待状态:可以在指定时间后自行返回
  • 终止状态:线程已经运行完毕

守护线程了解吗?

Java 线程分为两类,分为守护线程用户线程

  • 守护线程服务性质的线程,在所有用户线程结束时会自动结束。通常用来执行后台任务,比如垃圾回收、资源管理等。不影响 JVM 的退出
  • 用户线程:用户手动创建的线程,在程序执行期间一直存在,直到主线程执行完成或者被手动终止。用户线程会影响 JVM 的退出

线程间有哪些通信方式?

  • 共享变量:线程通过读写共享内存中的变量进行通信
  • 锁机制:使用锁来限制对共享资源的访问,从而实现线程的同步和互斥
  • wait-notify 机制:一个线程可以通过 wait 方法进入等待状态,等待其他线程调用 notify/notifyAll 来唤醒
  • 使用管道流:管道流可以在两个线程之间进行数据传输
  • 阻塞队列:一个线程可以通过向队列中添加元素来与其他线程进行通信

并发和并行?

  • 并发:系统能够同时执行多个任务,不一定是同时执行,而是通过任务的切换和调度来实现多个任务交替执行
  • 并行:系统中同时执行多个任务,每个任务在独立的处理器上执行,各个任务之间相互独立

同步和异步?

  • 同步:调用一个函数或方法后,必须等待完成并返回结果,才能继续执行
  • 异步:调用一个函数或方法后,不用等待完成,会通过回调函数、事件触发等机制来处理最终的结果

为什么使用多线程?

  • 提高程序性能:在多核 CPU 上,多线程可以充分利用多核并行处理任务,加快程序的执行速度
  • 提高资源利用率:多线程可以充分利用 CPU 和内存等资源
  • 异步处理:多线程可以实现异步操作,例如在后台加载数据、文件下载等,提高系统的响应性

使用多线程可能带来的问题?

  • 内存泄露
  • 死锁
  • 线程不安全
  • 性能问题

什么是线程上下文切换?

  • 线程上下文切换是指在多线程环境中,由于多个线程共享 CPU 的执行时间
  • 当一个线程的执行时间片用完或者需要切换到另一个线程时,操作系统会暂停当前线程的执行,保存其上下文,然后加载另一个线程的上下文,执行线程

什么是线程死锁?

  • 死锁是多个线程因相互等待对方持有的资源而无法继续执行的僵局状态

死锁产生的条件?

  • 互斥条件:资源只能被一个线程占用
  • 请求并保持条件:已经获得资源的进程请求其他资源,同时不释放已有资源
  • 不剥夺条件:已经占有的资源不能其他的线程抢占
  • 循环等待条件:多个进程之间形成环路,每个进程都在等待下一个进程所占有的资源

如何避免死锁?

  • 破坏死锁的四个必要条件
    • 互斥条件:使用资源分级,避免资源互斥
    • 请求与保持条件:线程在获取资源前释放已持有的资源
    • 不剥夺条件:允许抢占已持有的资源
    • 循环等待条件:强制线程按照一定的顺序获取资源
  • 避免无限期等待
    • 设置资源的超时时间,如果超时未获取,线程放弃或者重试
  • 使用死锁检测和解除机制
    • 定期检测系统中是否存在死锁
  • 使用锁的顺序
    • 确定锁的获取顺序,所有线程按照相同的顺序获取锁

那死锁问题怎么排查呢?

  • 确认是否发生了死锁:查看日志,如果出现线程堵塞的异常情况可能是死锁问题
  • 定位死锁位置:通过分析线程堆栈信息,定位出现死锁的代码位置
  • 确认锁的粒度:确认锁的粒度是否过大,如果锁的粒度过大,容易出现死锁问题
  • 检查锁的维护方式:检查锁是否正常释放
  • 分析并发访问情况:了解多线程请求锁的顺序和时间
  • 制定解决方案:根据以上情况制定解决方案,如调整锁的粒度、优化代码逻辑、增加重试机制
  • 测试验证:在实际系统中测试解决方案是否有效,如果没有解决问题,按照以上步骤继续排查

活锁和饥饿锁了解吗?

  • 活锁:两个或多个线程都在互相等待对方执行某个操作,形成死循环
  • 饥饿锁:某个线程一直无法获取需要的资源

线程间如何同步?

线程间的同步需要通过互斥锁、条件变量和信号量等机制来实现

  • 互斥锁
    • 互斥锁是一种最基本的同步机制,可以实现对共享资源的互斥访问。
    • 当某个线程进入临界区进行访问时,其他线程需要等待,直到该线程离开临界区,释放锁资源,才能再继续访问共享资源
  • 条件变量
    • 条件变量是一种用于线程间等待和通知的机制
    • 当某个线程进入临界区后,如果发现共享资源不满足当前需求,那它就可以将自己休眠,释放锁资源,等待其他线程改变共享资源状态并发送通知以后,再重新唤醒
  • 信号量
    • 信号量是一种更高级的线程同步机制,可以实现多个线程之间的同步操作。
    • 当某个线程需要访问共享资源时,请求获取信号量。如果有其他线程正在使用该共享资源,则该线程进入休眠状态等待信号量被释放。当共享资源被释放时,信号量发出通知,并将等待资源的线程唤醒

sleep() 和 wait()?

在多线程中,sleep() 和 wait() 方法都可以暂停线程的执行

  • sleep() 方法不会释放锁,wait() 会释放锁
  • sleep() 方法通常用于暂停执行,wait() 通常用于线程间通信
  • sleep() 方法在暂停指定时间后,自动恢复运行;wait() 方法调用后,需要其他线程调用 notify/notifyAll 方法唤醒
  • sleep() 方法是 Thread 类方法,wait() 是 Object 类方法

为什么 wait() 方法不定义在 Thread 中?

  • wait() 方法用于线程间通信,通过释放对象的锁并让线程进入等待状态,每个对象都拥有对象锁,因此定义在 Object 类
  • sleep() 方法是让当前线程暂停执行,不涉及对象类,因此定义在 Thread 类中

说说你对原子性、可见性、有序性的理解?

  • 原子性:
    • 原子性指一个操作不可分割的,要么完全执行,要么完全不执行
    • 原子性确保了操作的不可分割性
  • 可见性:
    • 可见性指一个线程对共享数据进行修改后其他线程立即能知道这个修改
    • 可见性确保了线程间共享数据的同步性
  • 有序性:
    • 有序性指程序执行的顺序和代码顺序一致

如何保证变量的可见性?

  • 使用 volatile 关键字:将变量声明为 volatile,每次访问该变量时都会从主存中读取最新的值,而不是使用线程的缓存
  • 使用 synchronized 或 Lock:使用同步机制来确保对变量的访问时互斥的
  • 使用原子类:原子类的操作是原子的,可以保证对变量的修改可见
  • 使用并发集合:使用线程安全的并发集合类,如 ConcurrentHashMap
  • 使用线程间通信:可以使用线程间通信机制,确保线程间的操作顺序和可见性

那说说什么是指令重排?

  • 指令重排是处理器和编译器的一种优化手段
  • 通过优化指令的执行顺序,充分利用处理器的执行单元,减少指令的等待时间,提高程序的执行效率

指令重排有限制吗?happens-before 了解吗?

  • 指令重排有限制,有两个规则 happens-beforeas-if-serial
  • happens-before 规则用来定义多线程间操作的执行顺序
    如果操作 A happens-before 操作 B,那么在程序执行中,A 的效果对 B 可见

as-if-serial 又是什么?单线程的程序一定是顺序的吗?

  • as-if-serial 规则是 Java 内存模型的另一个重要原则
    允许虚拟机在保证多线程正确性的前提下进行指令重排,只要重排后的执行结果和原始执行顺序一致即可
  • 单线程的程序一定是顺序执行的

volatile 关键字?

volatile 关键字可以保证可见性有序性

  • 保证可见性:线程读取变量的值都从主存中读取
  • 保证有序性:volatile 关键字可以禁止指令重排

volatile 实现原理了解吗?

  • volatile 实现可见性和有序性的关键在于内存屏障
  • 内存屏障是一种硬件或软件层面的机制,可以确保在特定位置的操作不会发生在内存屏障之前或之后
  • volatile 变量的读写操作会插入内存屏障,保证读写 volatile 变量时不会指令重排

解释双重校验锁实现单例的原理?

双重校验锁是一种常用于实现线程安全懒汉式单例模式的优化方式

  1. 首次检查:在双重校验锁中,首先检查对象实例是否被创建,如果没有才进行同步
  2. 同步块:在单例对象还没有创建的时候,使用synchronized对代码块加锁,并通过两次检查对象是否被实例化,保证只有一个线程执行了同步块内的代码
  3. volatile 关键字:使用 volatile 关键字确保线程之间的可见性和禁止指令重排序,避免出现另一个线程获得不完全初始化的实例
//双重校验锁实现对象单例(线程安全)
public class Singleton {private volatile static Singleton uniqueInstance;private Singleton() {}public  static Singleton getUniqueInstance() {//先判断对象是否已经实例过,没有实例化过才进入加锁代码if (uniqueInstance == null) {//类对象加锁synchronized (Singleton.class) {if (uniqueInstance == null) {uniqueInstance = new Singleton();}} }return uniqueInstance;}}

volatile 可以保证原子性吗?

  • volatile 关键字不能保证对变量的操作是原子性

秋招后端开发面试题系列目录
一、Java
1.1 Java基础上
1.2 Java基础下
1.3 Java集合
1.4 JavaIO
1.5 Java多线程上
1.6Java多线程下
二、JVM
2.1 JVM底层原理
2.2 垃圾回收器
2.3 垃圾回收算法
2.4 类加载机制
2.5 运行时数据区
三、MySQL
3.1 MySQL基础
3.2 事务
3.3 索引
3.4 锁机制
3.5 MVCC
四、Redis
4.1 Redis基础
4.2 缓存原理
五、中间件
5.1 RabbitMQ
六、Spring开源框架
6.1 Spring
6.2 Spring MVC
6.3 Spring Boot
6.4 MyBatis
七、操作系统
八、计算机网络
九、设计模式
十、微服务架构
十一、Spring Cloud分布式
11.1 分布式基础
11.2 Spring Cloud
11.3 GateWay
11.4 Nacos
11.5 OpenFeign
11.6 Ribbon
十二、算法
十三、项目


http://www.mrgr.cn/p/00125343

相关文章

《面向云计算的零信任体系第1部分:总体架构》行业标准正式发布

中华人民共和国工业和信息化部公告2024年第4号文件正式发布行业标准:YD/T 4598.1-2024《面向云计算的零信任体系 第1部分:总体架构》(后简称“总体架构”),并于2024年7月1日正式施行。 该标准由中国信通院牵头&#xf…

蓝桥杯ctf2024 部分wp

数据分析 1. packet 密码破解 1. cc 逆向分析 1. 欢乐时光 XXTEA #include<stdio.h> #include<stdint.h> #define DELTA 0x9e3779b9 #define MX (((z>>5^y<<2)(y>>3^z<<4))^((sum^y)(key[(p&3)^e]^z))) void btea(unsigned int* v…

工业异常检测

工业异常检测在业界和学界都一直是热门&#xff0c;近期其更是迎来了全新突破&#xff1a;与大模型相结合&#xff01;让异常检测变得更快更准更简单&#xff01; 比如模型AnomalyGPT&#xff0c;它克服了以往的局限&#xff0c;能够让大模型充分理解工业场景图像&#xff0c;判…

常用算法代码模板 (3) :搜索与图论

AcWing算法基础课笔记与常用算法模板 (3) ——搜索与图论 常用算法代码模板 (1) &#xff1a;基础算法 常用算法代码模板 (2) &#xff1a;数据结构 常用算法代码模板 (3) &#xff1a;搜索与图论 常用算法代码模板 (4) &#xff1a;数学知识 文章目录 0 搜索技巧1 树与图的存…

OpenHarmony 项目实战:智能体重秤

一、简介 本 demo 基于 OpenHarmony3.1Beta 版本开发&#xff0c;该样例能够接入数字管家应用&#xff0c;通过数字管家应用监测体重秤上报数据&#xff0c;获得当前测量到的体重&#xff0c;身高&#xff0c;并在应用端形成一段时间内记录的体重值&#xff0c;以折线图的形式…

在 UOS 统信安装 dotnet sdk 失败 提示 failed the verification

在 UOS 统信安装 dotnet sdk 失败 提示 You cannot install /home/lindexi/packages-microsoft-prod.deb that failed the verification, please go to Security Center - Security Tools - Application Security to adjust这是群里的伙伴报告的问题,从错误提示看需要在安全工…

制作一个能构建 dotnet AOT 的 gitlab ruuner 的 Debian docker 镜像

我的需求是需要有一个能够构建出 dotnet 的 AOT 包的环境,要求这个环境能解决 glibc 兼容依赖的问题,能打出来 x64 和 arm64 的 AOT 的包,且能够运行 gitlab runner 对接自动构建需求 以下是我列举的需求支持制作能在 UOS 系统和麒麟系统上运行的包 支持制作出来的包是 AOT …

个人学习总结__打开摄像头、播放网络视频的以及ffmpeg推流

前言 最近入手了一款非常便宜的usb摄像头&#xff08;买回来感觉画质很低&#xff0c;没有描述的4k&#xff0c;不过也够用于学习了&#xff09;,想着利用它来开启流媒体相关技术的学习。第一步便是打开摄像头&#xff0c;从而才能够对它进行一系列后续操作&#xff0c;诸如实…

将要上市的自动驾驶新书《自动驾驶系统开发》中摘录片段

全书共分15章&#xff1a;第1章是自动驾驶系统的概述&#xff08;场景分类、开发路径和数据闭环等&#xff09;&#xff0c;第2章简介自动驾驶的基础理论&#xff0c;即计算机视觉和深度学习等&#xff0c;第3&#xff5e;4章是自动驾驶的软硬件平台分析&#xff0c;包括传感器…

【PyTorch与深度学习】2、PyTorch张量的运算API(上)

课程地址 最近做实验发现自己还是基础框架上掌握得不好&#xff0c;于是开始重学一遍PyTorch框架&#xff0c;这个是课程笔记&#xff0c;这个课还是讲的简略&#xff0c;我半小时的课听了一个半小时。 1. 张量 1.1 张量操作 &#xff08;1&#xff09;chunk&#xff1a;将一…

Web前端开发之CSS_2

关系选择器CSS盒子模型弹性盒子模型文档流浮动清除浮动定位 1. 关系选择器 1.1 后代选择器 E F{} 选择所有被 E 元素包含的 F 元素&#xff0c;中间用空格隔开 <ul> <li>后代列表1</li> <div> <ol> <li>后代列表2</li> </ol>…

Vue从入门到精通-01-Vue的介绍和vue-cli

MVVM模式 Model&#xff1a;负责数据存储 View&#xff1a;负责页面展示 View Model&#xff1a;负责业务逻辑处理&#xff08;比如Ajax请求等&#xff09;&#xff0c;对数据进行加工后交给视图展示 关于框架 为什么要学习流行框架 1、企业为了提高开发效率&#xff1a;…

linux的压缩与备份

一、打包 格式&#xff1a;tar -参数 <打包文件名> <打包的目标> 作用&#xff1a;将文件或者目录打包 重要参数&#xff1a;-f 使用归档文件&#xff0c;一定要加上这个参数 -c 新建打包文件 -x 解包文件 -t 可以不用解包就能查看包文件内容 -v 打包和解包时显…

读天才与算法:人脑与AI的数学思维笔记13_Coq证明助手

读天才与算法:人脑与AI的数学思维笔记13_Coq证明助手1. 计算机 1.1. 对于计算机来说,它就很擅长处理这种重复而机械且计算量庞大的任务 1.1.1. 在速度与准确性等方面,计算机是远超过手工计算的 1.2. 计算机只能执行指令,并无自主创造力 1.…

Android --- 常见UI组件

TextView 文本视图 设置字体大小&#xff1a;android:textSize"20sp" 用sp 设置颜色&#xff1a;android:textColor"#00ffff" 设置倍距(行距)&#xff1a;android:lineSpacingMultiplier"2" 设置具体行距&#xff1a;android:lineSpacingExtra&q…

学习STM32第二十天

低功耗编程 一、修改主频 STM32F4xx系列主频为168MHz&#xff0c;当板载8MHz晶振时&#xff0c;系统时钟HCLK满足公式 H C L K H S E P L L N P L L M P L L P HCLK \frac{HSE \times PLLN}{PLLM \times PLLP} HCLKPLLMPLLPHSEPLLN​&#xff0c;在文件stm32f4xx.h中可修…

Django初步了解

目录 一、什么是Django 二、Django的设计模式 三、涉及的英文缩写及其含义 四、安装&#xff08;官方教程&#xff09; 一、什么是Django Django是一个Python Web框架&#xff0c;可以快速开发网站&#xff0c;提供一站式的解决方案&#xff0c;包括缓存、数据库ORM、后台…

甘特图是什么?利用甘特图来优化项目管理流程

在现代项目管理中,图表是一种强大而直观的工具,可以帮助项目经理和团队成员清晰地了解并掌控整个项目进程。其中,甘特图是最常用和最有效的图表之一。 甘特图是一种条形图,可以用来直观地展示项目中各个任务的进度、持续时间和相互关系。它由一个横轴和一个纵轴组成。横轴代表时…

STM32入门_江协科技_1~2_OB记录的自学笔记_STM32简介

1.综述 1.1. 课程简介 手打代码是加入了实操&#xff0c;增加学习效果&#xff1b; STM最小系统板面包板的硬件平台&#xff1b; 配套0.96寸的显示屏&#xff0c;便于调试&#xff1b; 因为使用面板板&#xff0c;所以如果程序现象不出来也有可能是硬件连接的问题&#xff1b; …

YOLOv8改进项目汇总-超全改进-ultralyticsPro介绍:订阅了《芒果YOLOv8原创改进专栏》的读者免费赠送,包括很多稀有改进

&#x1f525;&#x1f525;&#x1f525;专注于YOLOv8改进&#xff0c;NEW - YOLOv8 &#x1f680; in PyTorch >, Support to improve Backbone, Neck, Head, Loss, IoU, LA, NMS and other modules&#x1f680; Makes YOLOv8 improvements easy again 芒果出品 YOLOv8…