JAVA面试部分——后端-线程后篇
3.12 如果在运行当中,遇到线程不够了,会以什么样的方式创建线程
线程池在运行过程中,如果遇到线程不够的情况,会根据线程池的类型和配置进行不同的处理:
对于固定大小的线程池:如果线程因异常结束,会有一个新的线程来替代它。线程池的大小一旦达到最大值就会保持不变。
对于可缓存的线程池:线程池的大小超过了任务所需要的线程,就会回收部分空闲的线程。当任务数增加时,此线程池又可以智能地添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
无论哪种类型的线程池,当需要执行新的任务但所有线程都在忙时,任务会被放入等待队列中,等待其他线程空闲后执行。如果等待队列也已满,且系统允许创建新线程,那么线程池会创建新的线程来处理该任务。如果系统不允许创建新线程,则根据拒绝策略来处理该任务。
3.13 Java多线程引发的问题?
Java多线程可能引发以下问题:
内存资源耗尽:Java中每个线程都会占用一部分内存空间,当线程数过多时,会导致系统内存资源的消耗增加。如果系统内存无法满足所有线程所需的内存,则会引发OutOfMemoryError异常,在这种情况下,系统很可能会崩溃或死锁。
CPU资源利用率降低:过多的线程数会使CPU在调度线程时的负担增加。因为在任何时刻,CPU只有一个核心可以执行线程代码,当线程数过多时,CPU在不停地切换线程上下文,导致CPU利用率低下,从而降低系统性能。
线程安全问题:访问共享的变量或资源,会有并发风险,这里的共享变量或资源指的是:对象的属性,静态变量,共享缓存,数据库等等。所有依赖时序的操作,即使每一步操作都是线程安全的,但是如果存在操作时序不对,比如操作的数据变量未初始化完成,依旧会产生并发问题。
性能问题:从某种程度上来讲,多线程可以提高复杂的运算效率,但是一定程度上多线程可能会带来性能提交上下文切换。线程运行个数超过CPU核心数的时候,CPU就需要对线程进行调度,线程调度中就涉及线程切换,线程的切换的开销是很大的,CPU需要保存当前线程的运行场景,将当前线程的当前运行状态保存好,为载入新的运行线程做准备。这样来来回回其实是很耗费性能的。
为了避免这些问题,需要合理地配置和管理线程资源,确保线程的数量和优先级符合系统的需求和限制。同时,在编写涉及多线程的代码时,需要特别注意线程安全和同步问题,以避免出现竞态条件和数据不一致的问题。
3.14 并行与并发
并行是指多个任务在同一时间段内同时发生,这些任务可能由不同的处理器或者多核CPU来处理。并行通常可以显著提高程序的执行效率,因为它可以同时处理多个任务,而不是在一段时间内依次处理。在并行的情况下,不同的任务可以独立执行,不需要等待其他任务的处理。只有在多处理器或多核的机器上才能真正实现并行。
并发则是指多个任务在同一时间段内交替执行,从外部看来这些任务是同时进行的。并发通常通过在一个时间段内划分成若干个时间片段,然后在这些时间片段中依次执行每个任务来实现。这种方式可以减少等待时间,提高程序的响应速度。例如,在单处理器上运行的程序,通过合理的调度可以使得多个任务交替执行,实现并发的效果。但是,并发仍然需要等待某些任务的时间片段,因此其执行速度仍然受到一定的限制。
简而言之,并行是多个任务同时发生,并发是多个任务交替发生。并行更多地涉及到硬件的并行处理能力,而并发更多地涉及到软件的调度和执行策略。
3.15 多线程访问多个接口的时候怎么保证效率,比如访问A接口2s,B接口3s,如何优化?
在多线程访问A接口和B接口的情况下,可以采取以下优化措施:
使用异步访问:对于需要等待较长时间的接口访问,例如B接口需要等待3秒,可以使用异步访问方式。这样主线程不会被长时间阻塞,可以继续执行其他任务,从而提高整体效率。
合并接口访问:如果A接口和B接口之间存在依赖关系,可以将它们合并在一起进行访问。例如,可以先访问A接口,然后紧接着访问B接口,从而减少总的等待时间。
使用线程池:通过线程池提供的一组线程来处理多个接口的访问请求。线程池可以重复利用已创建的线程,减少创建和销毁线程的开销,提高效率。
优化网络连接:对于网络连接的优化,可以采取一些措施,如使用长连接、减少网络跳转等。这样可以减少网络通信的开销和时间,提高效率。
缓存技术:对于频繁访问的接口,可以使用缓存技术。将已经获取的数据存储在缓存中,避免重复请求相同的接口,从而减少访问时间和网络开销。
综上所述,通过异步访问、合并接口访问、使用线程池、优化网络连接和采用缓存技术等措施,可以优化多线程访问A接口和B接口时的效率。具体优化方案需要根据实际情况进行选择和调整。
3.16 多线程去做io操作,Copy文件如何实现?
在多线程环境下进行文件复制操作可以提高效率,因为可以同时处理多个文件。下面是一种可能的实现方式:
创建一个线程池,线程池的大小根据系统的硬件资源和文件数量来决定。
将需要复制的文件分成多个批次,每个批次包含一定数量的文件。
对于每个批次,向线程池提交一个任务,该任务负责复制该批次的文件。
在每个任务中,使用操作系统提供的文件复制函数(如Java中的File.copy或Java的nio包中的FileChannel.transferTo方法)来复制文件。
在复制过程中,可以设置线程的优先级为低,以避免复制操作占用过多资源导致系统响应缓慢。
等待所有任务完成,完成后的文件可以通过某种方式进行合并,例如使用文件锁或者合并工具。
需要注意的是,在多线程复制文件时,需要确保文件的完整性和一致性。例如,如果一个文件正在被其他程序修改,可能会导致复制操作失败或者复制的文件不完整。因此,在复制前应该检查文件的完整性和一致性,或者等待文件被修改完成后再次尝试复制。
另外,还需要注意文件名冲突的问题。如果多个线程同时复制同一个目录下的文件,可能会出现文件名冲突的情况。可以通过重命名文件或者使用不同的目录来避免这种情况。
总之,多线程复制文件可以提高效率,但需要注意文件的完整性和一致性,以及避免文件名冲突的问题。
3.17 如何杀掉线程或进程?
在程序中终止线程或进程是一个需要谨慎处理的问题,因为如果处理不当,可能会导致程序崩溃或出现其他问题。以下是几种终止线程或进程的最佳方式:
线程同步:使用各种线程同步机制,如信号量、事件等,来控制线程的执行。通过等待或通知线程继续执行,可以安全地终止线程。
异常处理:在线程或进程中抛出异常,导致线程或进程终止。但是,这种方式可能导致程序崩溃或出现其他问题,因此不推荐使用。
正常结束:通过在线程或进程的代码中添加退出条件,使其在满足条件时自动结束执行。这种方式是最安全和最推荐的方式。
操作系统命令:在操作系统级别使用命令来终止线程或进程。例如,在Linux系统中,可以使用kill命令来终止进程。但是,这种方式可能会导致程序崩溃或出现其他问题,因此不推荐使用。
总之,最佳的终止线程或进程的方式是使用线程同步机制和正常结束执行。如果必须使用异常处理或操作系统命令来终止线程或进程,应该谨慎处理,以避免出现程序崩溃或其他问题。
3.18 AQS有了解吗?
Java中的AQS(AbstractQueuedSynchronizer)是一个用于实现并发同步的工具类,它提供了一种实现同步器的框架和实现方式。AQS的核心思想是利用一个先进先出(FIFO)的双向队列来管理线程的竞争和等待。它可以用于实现诸如ReentrantLock、Semaphore、CountDownLatch等同步工具类。
以下是一些AQS的应用:
ReentrantLock:ReentrantLock是一个可重入的互斥锁,它使用AQS来实现锁的功能。在ReentrantLock的实现中,通过继承AQS类并实现其抽象方法,利用state和exclusiveOwnerThread两个状态变量来实现加锁和解锁操作。
CountDownLatch:CountDownLatch是一个等待其他线程完成的操作,它使用AQS来实现等待操作。CountDownLatch内部维护了一个计数器,当计数器为0时,await()方法返回。而countDown()方法则用来减少计数器的值。
Semaphore:Semaphore是一个计数信号量,它使用AQS来实现信号量的功能。如果计数器为0,acquire()方法会阻塞,直到其他线程释放许可证。
除了上述应用之外,AQS还可以用于实现其他类型的同步工具类,如StampedLock等。总之,AQS是Java并发编程中的一个重要组成部分,它提供了一种灵活、高效的方式来实现并发同步。
3.19 说一下 synchroinzed 锁膨胀?
"synchronized"是Java中的一个关键字,用于实现同步。它提供了一种互斥的机制,确保同一时刻只有一个线程可以执行某个方法或代码块。然而,在实际应用中,由于一些情况可能会导致synchronized锁膨胀,进而影响程序的性能。
锁膨胀是指随着系统并发量的增加,锁的持有时间变长,锁的竞争加剧,导致需要更多的内存空间和CPU资源。在Java中,synchronized锁的膨胀通常表现为对象头中的Mark Word的膨胀。
当一个线程持有锁时,该锁会占用一个Mark Word,其中包含了一些元信息,如锁的持有状态、线程持有锁的时间等。随着并发量的增加,线程持有锁的时间变长,Mark Word中的元信息也会不断增加,从而导致Mark Word的膨胀。
锁膨胀会对程序的性能产生负面影响,因为它会增加内存占用和CPU的开销。当锁竞争激烈时,线程需要频繁地获取和释放锁,导致CPU的上下文切换和内存访问的开销增加,进而影响程序的性能。
为了避免锁膨胀对程序性能的影响,可以考虑使用其他并发控制机制,如使用CAS操作实现无锁算法、使用读写锁等。此外,也可以通过合理地设计程序的并发模型、减少锁的持有时间、避免锁的过度使用等方式来降低锁竞争和锁膨胀的风险。
3.20 锁的一些方法及使用
在Java中,常用的锁机制有synchronized和Lock接口。它们提供了一些方法和使用方式,可以用于实现互斥和并发控制。
synchronized:
使用方式:在方法或代码块前加上synchronized关键字即可。
实现方式:通过对象头中的Mark Word标识锁的持有状态,如果Mark Word的值为0,表示未加锁;如果Mark Word的值不为0,表示持有锁,其他线程需要等待该线程释放锁。
优点:自动获取和释放锁,使用简单;支持多个监视器(monitor)锁,允许多个线程同时持有锁。
缺点:不支持可重入性,即一个线程不能重复获取同一个锁;性能较差,因为需要使用对象头中的Mark Word来标识锁的持有状态。
Lock接口:
使用方式:创建一个Lock接口的实现类(如ReentrantLock),然后使用该实现类来加锁和解锁。
实现方式:通过实现Lock接口中的lock()和unlock()方法来实现加锁和解锁操作。
优点:支持可重入性,即一个线程可以多次获取同一个锁;性能较好,因为不需要使用对象头中的Mark Word来标识锁的持有状态。
缺点:需要手动获取和释放锁,使用较为繁琐;不支持多个监视器(monitor)锁,只能有一个线程持有锁。
除了synchronized和Lock接口之外,Java还提供了一些其他的锁机制,如读写锁(ReadWriteLock)、信号量(Semaphore)等。它们各有优缺点,可以根据具体的场景选择合适的锁机制。
3.21 什么是函数式接口,结构上有什么特点,能声明其他东西吗,默认方法有什么?
函数式接口是Java中的一种接口,它只包含一个抽象方法。在Java 8及以后的版本中,函数式接口被用于支持Lambda表达式和函数式编程。
函数式接口在结构上的特点如下:
只包含一个抽象方法。
可以包含默认方法和静态方法。
使用@FunctionalInterface注解进行标识,以确保它符合函数式接口的规范。
除了抽象方法之外,函数式接口还可以声明默认方法和静态方法。默认方法允许在接口中提供方法的默认实现,可以被实现接口的类选择性重写。静态方法则允许在接口中定义与接口本身相关的一些工具方法,类似于工具类的功能。
函数式接口的抽象方法可以用Lambda表达式或方法引用来实现。Lambda表达式是一种简洁的匿名函数写法,可以用来实现函数式接口的抽象方法。方法引用则是指引用现有方法,并传递给其他函数或对象。
默认方法允许在接口中提供默认实现,可以被实现接口的类选择性重写。默认方法主要用于在不影响现有代码的情况下添加新的功能,或者为旧版接口提供新的实现方式。
总之,函数式接口是Java中用于支持函数式编程的一种特殊接口,它只包含一个抽象方法,但可以包含默认方法和静态方法。函数式接口的抽象方法可以用Lambda表达式或方法引用来实现,而默认方法则允许在接口中提供默认实现。
3.22 什么情况会导致内存泄露
在Java中,以下是一些可能导致内存泄露的情况:
静态变量:如果静态变量引用了一个对象,而这个对象没有被其他变量引用,那么这个对象将无法被垃圾回收器回收,从而导致内存泄露。
监听器:如果一个对象持有监听器,但该对象本身被垃圾回收器回收,而监听器没有被正确取消,那么就会造成内存泄露。
集合类:如果集合类中存储了大量的对象,而这些对象没有被正确释放,那么就会造成内存泄露。
缓存:如果缓存中存储了大量的对象,而这些对象没有被正确释放,那么就会造成内存泄露。
未关闭的资源:如果程序中打开了一些资源(如数据库连接、文件流等),但未及时关闭,就会造成内存泄露。
为了避免内存泄露,程序员需要正确使用Java的内存管理机制,如使用弱引用、及时关闭资源、正确处理监听器等。同时,也可以使用一些工具来检测和修复内存泄露,如Java的内存分析工具(Memory Analyzer Tool,MAT)等。
相关文章:

JAVA面试部分——后端-线程后篇
3.12 如果在运行当中,遇到线程不够了,会以什么样的方式创建线程 线程池在运行过程中,如果遇到线程不够的情况,会根据线程池的类型和配置进行不同的处理: 对于固定大小的线程池:如果线程因异常结束ÿ…...

C语言辨析——深入理解字符常量与表达式
1. 问题 今天看到一个题目,截图如下。 从答题情况来看,本题的答案是B,那么就意味着A、C、D是错的。但我认为这4个选项都是对的。当然,如果要从4个选项中挑选一个的话,那还是选择B妥当一些。 2. 分析 字符常量的定义…...

Springboot + websocket 实现 一对一 单人聊天
Springboot websocket 实现 一对一 单人聊天 要使用websocket ,需要添加 jar 打开项目中的pom.xml,添加以下内容 创建java端代码 配置websocke的endpoints 配置websocket的server ServerEndpoint(value "/websocket/{username}") 这句话 一定要注意, 这里 路…...

GEE机器学习——利用最短距离方法进行土地分类和精度评定
最短距离方法 最短距离方法(Minimum Distance)是一种常用的模式识别算法,用于计算样本之间的相似度或距离。该方法通过计算样本之间的欧氏距离或其他距离度量,来确定样本之间的相似程度或差异程度。 最短距离方法的具体步骤如下: 1. 数据准备:收集并准备用于训练的数据…...

数据结构时间复杂度与空间复杂度
文章目录 引入算法 1、时间复杂度1.概念2.大O渐进表示法3.常见时间复杂度计算举例 2、空间复杂度1.概念2.常见空间复杂度计算举例 引入 算法 算法就是一段能将一个物体从初始状态转换到某个目标转态的一个有限长序列方法的统称 算法效率:考虑一个方法是否好&…...

【计算机网络】内容整理
概述 分组交换 分组交换则采用存储转发(整个包必须到达路由器,然后才能在下一个链路上传输)技术。 在发送端,先把较长的报文划分成较短的、固定长度的数据段。 电路交换 在端系统间通信会话期间,预留了端系统间沿路径通信所需…...

【K12】Python写分类电阻问题的求解思路解析
分压电阻类电路问题python程序写法 一个灯泡的电阻是20Ω,正常工作的电压是8V,正常工作时通过它的电流是______A。现在把这个灯泡接到电压是9V的电源上,要使它正常工作,需要给它______联一个阻值为______的分压电阻。 解决思想 …...

数据库面经---10则
数据库范式有哪些: 第一范式(1NF): 数据表中的每一列都是不可分割的原子值。每一行数据在关系表中都有唯一标识,通常是通过主键来实现。第二范式(2NF): 满足第一范式。…...

深度学习基本介绍-李沐
目录 AI分类:模型分类:广告案例: bilibili视频链接:https://www.bilibili.com/video/BV1J54y187f9/?p2&spm_id_frompageDriver&vd_sourcee6a6e7fec41c59c846c142eb5ef1da0b AI分类: 模型分类: 图…...

【上分日记】第369场周赛(分类讨论 + 数学 + 前缀和)
文章目录 前言正文1.3000. 对角线最长的矩形的面积2.3001. 捕获黑皇后需要的最少移动次数3.3002. 移除后集合的最多元素数3.3003. 执行操作后的最大分割数量 总结尾序 前言 终于考完试了,考了四天,也耽搁了四天,这就赶紧来补这场周赛的题了&a…...

CMake Error at CMakeLists.txt:14 (project): The CMAKE_CXX_COMPILER:
报错 CMake Error at CMakeLists.txt:14 (project):The CMAKE_CXX_COMPILER:arm-none-eabi-g 解决办法1 Arm GNU Toolchain Downloads – Arm Developer x86_64 linux上: x86_64 Linux hosted cross toolchains AArch32 bare-metal target (arm-none-eabi)arm-g…...

Sqoop与其他数据采集工具的比较分析
比较Sqoop与其他数据采集工具是一个重要的话题,因为不同的工具在不同的情况下可能更适合。在本博客文章中,将深入比较Sqoop与其他数据采集工具,提供详细的示例代码和全面的内容,以帮助大家更好地了解它们之间的差异和优劣势。 Sq…...

Pandas实战100例 | 案例 31: 转换为分类数据
案例 31: 转换为分类数据 知识点讲解 在处理包含文本数据的 DataFrame 时,将文本列转换为分类数据类型通常是一个好主意。这可以提高性能并节省内存。Pandas 允许将列转换为 category 类型。 分类数据类型: category 类型适用于那些只包含有限数量不同值的列&…...

椋鸟C语言笔记#33:文件的顺序读写
萌新的学习笔记,写错了恳请斧正。 目录 光标(文件位置指示器) 文件的顺序读写 fgetc 使用实例 fputc 使用实例 fgets fputs 使用实例 fscanf fprintf fread fwrite 使用实例 光标(文件位置指示器) 我们…...

Transformer - Attention is all you need 论文阅读
虽然是跑路来NLP,但是还是立flag说要做个project,结果kaggle上的入门project给的例子用的是BERT,还提到这一方法属于transformer,所以大概率读完这一篇之后,会再看BERT的论文这个样子。 在李宏毅的NLP课程中多次提到了…...

安装配置Flink
安装配置Flink 1.上传安装包到Linux 2.解压到指定路径 tar -zxf ./flink-1.14.0-bin-scala_2.12.tgz /usr/local/src/3.修改环境变量 vi ~/.bashrc#往最后加入 export FLINK_HOME /usr/local/src/flink-1.14.0/ export PATH$PATH:$FLINK_HOME/bin#激活环境变量 source ~/.…...

解决Spss没有创建虚拟变量的选项的问题
这个是今天用spss想创建虚拟变量然后发现我的spss没有。 然后能怎么办我就百度呗, 说是在扩展里连接扩展中心 天哪,谁能连上,我连不上 于是就找到了从github上下载到本地,然后安装到spss中 目录 解决方法 点击code 再点击D…...

wxWidgets实战:使用mpWindow绘制阻抗曲线
选择模型时,需要查看model的谐振频率,因此需要根据s2p文件绘制一张阻抗曲线。 如下图所示: mpWindow 左侧使用mpWindow,右侧使用什么? wxFreeChart https://forums.wxwidgets.org/viewtopic.php?t44928 https://…...

深度学习15—(迁移学习)冻结和解冻神经网络模型的参数
冻结与解冻代码: def freeze_net(net):if not net:returnfor p in net.parameters():p.requires_grad Falsedef unfreeze_net(net):if not net:returnfor p in net.parameters():p.requires_grad True 这段代码定义了两个函数:freeze_net 和 unfree…...

强化学习应用(八):基于Q-learning的无人机物流路径规划研究(提供Python代码)
一、Q-learning简介 Q-learning是一种强化学习算法,用于解决基于马尔可夫决策过程(MDP)的问题。它通过学习一个价值函数来指导智能体在环境中做出决策,以最大化累积奖励。 Q-learning算法的核心思想是通过不断更新一个称为Q值的…...

常见面试题之HTML
行内元素有哪些?块级元素有哪些? 空(void)元素有那些? HTML 中的行内元素(inline elements)通常用于在一行内显示,不会独占一行的空间。常见的行内元素有: <span>:用于对文本…...

数据结构与算法教程,数据结构C语言版教程!(第三部分、栈(Stack)和队列(Queue)详解)六
第三部分、栈(Stack)和队列(Queue)详解 栈和队列,严格意义上来说,也属于线性表,因为它们也都用于存储逻辑关系为 "一对一" 的数据,但由于它们比较特殊,因此将其单独作为一章,做重点讲解。 使用栈…...

使用Docker部署PDF多功能工具Stirling-PDF
1.服务器上安装docker 安装比较简单,这种安装的Docker不是最新版本,不过对于学习够用了,依次执行下面命令进行安装。 sudo apt install docker.io sudo systemctl start docker sudo systemctl enable docker 查看是否安装成功 $ docker …...

linux安装系统遇到的问题
这两天打算攻克下来网络编程,发现这也确实是很重要的一个东西,但我就奇了怪了,老师就压根没提,反正留在我印象的就一个tcp/ip七层网络。也说正好,把linux命令也熟悉熟悉,拿着我大一课本快速过过 连接cento…...

groovy XmlParser 递归遍历 xml 文件,修改并保存
使用 groovy.util.XmlParser 解析 xml 文件,对文件进行修改(新增标签),然后保存。 是不是 XmlParser 没有提供方法遍历每个节点,难道要自己写? 什么是递归? 不用说,想必都懂得~ …...

小程序基础学习(多插槽)
先创建插槽 定义多插槽的每一个插槽的属性 在js文件中启用多插槽 在页面使用多插槽 组件代码 <!--components/my-slots/my-slots.wxml--><view class"container"><view class"left"> <slot name"left" ></slot>&…...

爬虫补环境jsdom、proxy、Selenium案例:某条
声明: 该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关 一、简介 爬虫逆向补环境的目的是为了模拟正常用户的行为,使爬虫看起来更像是一个真实的用户在浏览网站。这样可以…...

电子学会C/C++编程等级考试2021年09月(四级)真题解析
C/C++编程(1~8级)全部真题・点这里 第1题:最佳路径 如下所示的由正整数数字构成的三角形: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。你的任务就是求出最佳路径…...

DevExpress历史安装文件包集合
Components - DevExpress.NET组件安装包此安装程序包括所有 .NET Framework、.NET Core 3 和 .NET 5、ASP.NET Core 和 HTML/JavaScript 组件和库(Web和桌面应用程序开发只需要安装此文件即可)。 注意:自DevExpress21.1版本之后,该…...

科技云报道:“存算一体”是大模型AI芯片的破局关键?
科技云报道原创。 在AI发展历史上,曾有两次“圣杯时刻”。 第一次发生在2012年10月,卷积神经网络(CNN)算法凭借比人眼识别更低的错误率,打开了计算机视觉的应用盛世。 第二次是2016年3月,DeepMind研发的…...