并发基础面试题第一篇

1.为什么要使用并发编程

提升多核CPU的利用率:一般来说一台主机上会有多个cpu核心,我们可以创建多个线程,理论上讲操作系统可以将多个线程分配给不同的CPU执行,每个CPU执行一个线程,这样就提高了CPU的使用效率。

简单来说:

  • 充分利用多核CPU的计算能力;
  • 方便进行业务拆分,提升应用性能

2.并发编程有什么缺点

并发编程的目的就是为了提高程序的执行效率,提高程序的运行速度,但是并发编程并不总是能提高程序运行速度的,而且并发编程可能会遇到很多问题。上下文切换,线程安全,死锁等问题

3.并发编程三个必要因素

原子性:原子性指一个或多个操作要么全部执行成功,要么全部执行失败。

可见性:一个线程对共享变量的修改,另一个线程能够立刻看到。(synchronized,volatile)

有序性:程序的执行顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序)。

4.在Java程序中怎么保证多线程的运行安全

出现线程安全问题的原因一般都是三个原因:

线程切换带来的原子性问题,解决办法:使用多线程之间的同步synchronized或者使用锁lock

缓存导致的可见性问题,解决办法:synchronized,Lock,volatile,可以解决可见性问题。

编译优化带来的有序性问题,解决办法,Happens-Before规则可以解决有序性问题。

5.并行和并发的区别

并行:同一时间多个处理器同时处理多个任务

并发:单位时间,一个处理器处理多个任务,按时间片轮流处理多个任务。

6.什么是上下文切换

多线程编程中一般线程的个数大于CPU核心的个数,而一个CPU核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU采取的策略是为每个线程分配时间片并轮转的形式,当一个线程时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。

7.守护线程和用户线程有什么区别

用户线程:运行在前台,执行具体的任务,如程序的主线程,连接网络的子线程等都是用户线程

守护线程:运行在后台,为其他前台线程服务。也可以说守护线程是JVM中非守护线程的佣人。一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作。

8.什么是线程死锁,死锁相关面试题

什么是死锁?

死锁是指两个或者两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞现象,若无外力作用,它们都将无法推进下去。此时系统产生了死锁。

多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期的阻塞,因此程序不可能正常终止。

举例:哲学家就餐问题

形成死锁的四个必要条件?

互斥条件:在一段时间内某资源只能由一个线程占用。如果此时还有其他进程请求资源,就只能等待,直到占有资源的进程用完释放。

占有且等待条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程阻塞,但又对自己已获得的其他资源保持不放。

不可抢占资源:别人已经占有了某项资源,你不能因为自己也需要该资源,就去吧别人的资源抢过来。

循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。(哲学家就餐问题)

如果避免死锁?

避免一个线程同时获得多个锁

避免一个线程在锁内同时占有多个资源,尽量保证每个锁只占用一个资源。

尝试使用定时锁,使用lock.tryLock(timeOut)来替代使用内部锁机制

9.Java线程有几种状态

在Java thread state枚举类中定义了6种线程状态,它们分别是,新建状态NEW,运行状态Runnable,阻塞状态Blocked,等待状态Waiting,延迟等待状态Timed Waiting和终止状态

Terminated。

10.Java创建线程的方式

继承Thread类

实现Runnable接口

实现Calllable接口,并结合Future来创建线程

11.说一下runnable和callable的区别

相同点:

都是接口

都可以编写多线程程序

都采用Thread.start()启动线程

不同点:

Runnable接口run方法没有返回值,Callable接口call方法有返回值;是个泛型,和Future或者FutureTask配合可以用来获取异步执行的结果。

Runnable接口run方法只能抛出运行时异常,且无法捕获处理;Callable接口call方法允许抛出异常,可以捕获异常信心。Callable接口支持返回执行结果,需要调用FutureTask.get()得到,此方法会阻塞主线程的继续往下执行,如果不调用不会阻塞。

12.Future和FutureTask的区别

  • Future 是一个接口,它表示一个异步计算的结果。
  • 通过 Future 可以提交一个任务,并在将来的某个时候获取任务的执行结果。
  • Future 提供了 get() 方法用于获取任务执行的结果,该方法会阻塞当前线程直到任务执行完成并返回结果。
  • Future 还提供了 isDone()cancel() 等方法用于检查任务是否已经完成和取消任务的执行。
  • FutureTaskFuture 接口的一个实现类,它同时实现了 Runnable 接口,因此可以作为任务提交给线程池执行。
  • FutureTask 可以用来包装一个 Callable 或者 Runnable 对象,使其具有异步执行和获取执行结果的能力。
  • FutureTask 提供了 get() 方法用于获取任务执行的结果,同样会阻塞当前线程直到任务执行完成并返回结果。
  • FutureTask 还提供了 cancel() 方法用于取消任务的执行,以及 isDone() 等方法用于检查任务是否已经完成。

总的来说,Future 接口是用来表示异步计算的结果,而 FutureTask 类是 Future 接口的一个实现,它提供了更多的功能,如可以作为任务提交给线程池执行,并且可以直接包装 Callable 或者 Runnable 对象。

13.sleep()和wait()的区别

类的不同:sleep是Thread线程类的静态方法,wait是Object类的方法。

是否释放锁:sleep不释放锁,wait释放锁

用途不同:wait通常被用于线程间交互/通信,sleep通常被用于暂停执行。

用法不同:wait方法被调用后,线程不会自动苏醒,需要别的线程调用同一对象上的notify()或者notifyAll()方法。sleep方法执行完后,线程会自动苏醒。或者可以使用wait(long timeout)超时后线程会自动苏醒。

14.为什么线程通信的方法wait(),notify(),notifyAll()被定义在Object类里?

因为java中所有的类都继承了Object类,Java想让任何对象都可以作为锁,并且wait,notify等方法用于等待对象的锁或者唤醒线程,在Java的线程中并没有可供任何对象使用的锁,所以任意对象调用方法一定定义在Object类中。

15.为什么方法wait(),notify(),notifyAll()必须在同步方法或者同步块中被调用?

当一个线程需要调用对象的wait()方法的时候,这个线程必须拥有该对象的锁,接着它就会释放这个对象锁并进入等待状态直到有其他线程调用这个对象的notify或者notifyAll方法。同样的,当一个线程调用对象的notify或者notifyAll方法的时候,它就会释放这个对象的锁,以便其他线程可以得到这个对象锁。由于所有的这些方法都需要线程持有对象的锁,这样就只能通过同步来实现,所以它们只能在同步方法或者同步块中被调用。

        

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

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

相关文章

怎么开发一个预约小程序_一键预约新体验

预约小程序,让生活更便捷——轻松掌握未来,一键预约新体验 在快节奏的现代生活中,我们总是在不断地奔波,为了工作、为了生活,不停地忙碌着。然而,在这繁忙的生活中,我们是否曾想过如何更加高效…

邮件群发提高成功率的技巧?如何群发邮件?

邮件群发有哪些注意事项?怎么有效分析邮件群发效果? 邮件群发已经成为一种高效的信息传递手段。然而,很多人发现,尽管发送了大量的邮件,但回应率却并不理想。那么,如何才能在邮件群发中提高成功率呢&#…

【flutter启动分析】

flutter启动分析的入口: void main() {runApp(const MyApp()); } main函数会调用runapp(); void runApp(Widget app) { //生成对象给下面两个领域 //Flutter Framework ---调用到---胶水对象---》Flutter 的C++ Engine(so库这种)final WidgetsBinding binding = WidgetsF…

Oracle小机利用ZFS实现在线存储迁移

1.ZFS介绍 2004年:Sun Microsystems 开始研发 ZFS 文件系统。ZFS 最初是作为 Solaris 操作系统的一部分而开发的,旨在解决传统文件系统的一些限制和问题。 2010年:Oracle 收购了 Sun 公司,从而获得了 ZFS 文件系统的所有权和控制权…

node 中的 nextTick 和 vue 中的 nextTick 的区别

node 中的 nextTick node 中的 nextTick 是 node 自带全局的变量 process 的一个方法,process.nextTick 是一个微任务,在 node 的所有微任务中最先执行,是优先级最高的微任务。浏览器中是没有这一个方法的。 vue 中的 nextTick vue 中的 n…

只为兴趣,2024年你该学什么编程?

讲动人的故事,写懂人的代码 当你想学编程但不是特别关心找工作的时候,选哪种语言学完全取决于你自己的目标、兴趣和能找到的学习资料。一个很重要的点,别只学一种语言啊!毕竟,"门门都懂,样样皆通",每种编程语言都有自己的优点和适合的用途,多学几种可以让你的…

鸿蒙开发 一 (二)、熟悉鸿蒙之剑 ArkTS

ArkTS是HarmonyOS主要应用开发语言,以后也别在弄那个 java 和鸿蒙的混合版了, 没必要浪费时间, 一步到位, 学新的吧。 简介 ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,保…

网络工程师(强化训练)-网络互联与互联网

网络工程师 以下关于OSPF路由协议的描述中,错误的是向整个网络中每一个路由器发送链路代价信息。相比于TCP,UDP的优势为开销较小。以太网可以传送最大的TCP段为1480字节。IP数据报经过MTU较小的网络时需要分片。假设一个大小为1500字节的报文分为2个较小…

【如何应用OpenCV对图像进行二值化】

使用OpenCV进行图像二值化是一个常见的图像处理任务。以下是一个简单的步骤说明,以及相应的Python代码示例。 步骤说明: 读取图像:首先,使用OpenCV的imread函数读取图像。灰度化:将彩色图像转换为灰度图像&#xff0…

LeetCode 1702.修改后的最大二进制字符串:脑筋急转弯(构造,贪心)

【LetMeFly】1702.修改后的最大二进制字符串:脑筋急转弯(构造,贪心) 力扣题目链接:https://leetcode.cn/problems/maximum-binary-string-after-change/ 给你一个二进制字符串 binary ,它仅有 0 或者 1 组…

Day 20 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

最大二叉树 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下: 二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构造出的最大二叉树。右子树是通过数组中最大值右边部分构造出的最大二叉树。 通过给定的数组构建最大二叉…

【鸿蒙千帆起】《开心消消乐》完成鸿蒙原生应用开发,创新多端联动用户体验

《开心消消乐》已经完成鸿蒙原生应用开发,乐元素成为率先完成鸿蒙原生应用开发的20游戏厂商之一。作为一款经典游戏,《开心消消乐》已经拥有8亿玩家,加入鸿蒙原生应用生态,将为其带来更优的游戏性能和更多创新体验。自9月25日华为…

中国500米分辨率月最大EVI数据集

增强型植被指数(EVI)是在归一化植被指数(NDVI)改善出来的,根据大气校正所包含的影像因子大气分子、气溶胶、薄云、水汽和臭氧等因素进行全面的大气校正,EVI大气校正分三步,第一步是去云处理。第…

结构体和结构体指针的区别

1.定义区别 结构体的定义如下: struct 结构体名 {数据类型 成员变量名1;数据类型 成员变量名2;// 可以有更多的成员变量 };例如,定义一个表示学生的结构体: struct Student {int id;char name[20];int age; };上述定义了一个名为Student的…

Glide系列-自定义ModuleLoader

在当今快速发展的移动应用领域,图片的高效加载和显示对于提供流畅用户体验至关重要。Glide作为一款强大的图片加载库,已经成为Android开发者的首选工具之一。但是,你有没有遇到过Glide默认不支持的模型类型,或者需要对图片加载过程…

【SQL Sever】3. 用户管理 / 权限管理

1. 创建登录名/用户/角色 在SQL Server中,创建用户通常涉及几个步骤。 首先,你需要创建一个登录名,然后你可以基于这个登录名在数据库中创建一个用户。 以下是如何做到这一点的步骤和相应的SQL语句: 创建登录名 首先&#xff0c…

什么是尾调用优化

尾调用优化(Tail Call Optimization,TCO)是一种编译器或解释器的优化技术,旨在减少函数调用的内存消耗。尾调用发生在一个函数的最后一个操作是调用另一个函数时。在这种情况下,如果编译器能够优化,它可以将…

Centos离线安装ansible

Centos离线安装ansible 1、首先是互联网环境,安装python,创建虚拟环境,更新pip和setuptools python3 -m venv venv_2 # 此处 venv_2 也是自定义的虚拟环境名字 退出虚拟环境deactivate 进入虚拟环境source ~/ansible/bin/activate pip i…

Python零基础从小白打怪升级中~~~~~~~文件和文件夹的操作 (1)

第七节:文件和文件夹的操作 一、IO流(Stream) 通过“流”的形式允许计算机程序使用相同的方式来访问不同的输入/输出源。stream是从起源(source)到接收的(sink)的有序数据。我们这里把输入/输…

Vue3中ref,setup辨析

setup参考:vue3-setup-基本使用_vue3 setup mounted-CSDN博客 Vue3中的ref是一个函数,用于在setup函数中创建一个响应式的变量。ref函数接受一个初始值,返回一个响应式的对象。在setup函数中可以通过ref函数创建响应式变量,并将其…