当前位置: 首页 > news >正文

【高频面试题】JVM篇

文章目录

  • 一、JVM组成
    • 1.什么是程序计数器
    • 2.什么是Java堆?
    • 3.能不能介绍一下方法区(元空间)
    • 4.你听过直接内存吗
    • 5.什么是虚拟机栈
    • 6.垃圾回收是否涉及栈内存?
    • 7.栈内存分配越大越好吗?
    • 8.方法内的局部变量是否线程安全?
    • 9.什么情况下会导致栈内存溢出?
    • 10.堆栈的区别是什么
  • 二、类加载器
    • 11.什么是类加载器,类加载器有哪些
    • 12.什么是双亲委派模型?
    • 13.JVM为什么采用双亲委派机制?
    • 14.说一下类装载的执行过程
  • 三、垃圾回收
    • 15.强引用、软引用、弱引用、虚对象什么时候可以被垃圾器回收
      • 15.1 对象什么时候可以被垃圾器回收
    • 16.JVM 垃圾回收算法有哪些?
      • 16.1 标记清除算法
      • 16.2 标记整理算法( 标记清除算法的升级---多了一个整理阶段)
      • 16.3 复制算法
    • 17.说一下JVM中的分代回收
      • 17.1 MinorGC、 Mixed GC 、 FullGC的区别是什么
    • 18.说一下JVM有哪些垃圾回收器?
    • 19.详细聊一下G1垃圾回收器
  • 四、JVM实践
    • 20.JVM 调优的参数可以在哪里设置
    • 21.用的 JVM 调优的参数都有哪些?
    • 22.说一下 JVM 调优的工具?
    • 23.Java内存泄露的排查思路?
    • 24.CPU飙高排查方案与思路?

JVM是什么:
JVM(Java虚拟机)是Java程序的 运行环境,它是Java平台的核心组成部分之一。JVM提供了一个 运行Java字节码的虚拟机,负责将 Java程序解释和执行。

Java程序员可以在JVM上编写和运行Java程序,而不用考虑底层操作系统的差异性。JVM的特性使得Java具备了跨平台性,同一份Java代码可以在不同的操作系统上运行
在这里插入图片描述
组成部分如下:
在这里插入图片描述

一、JVM组成

1.什么是程序计数器

程序计数器:线程私有的,内部保存的字节码的行号。用于记录正在执行的字节码指令的地址。(通俗的来说就是记录当前线程的程序执行的字节码指令的行号)

在这里插入图片描述


2.什么是Java堆?

线程共享的区域:主要用来保存对象实例数组等,当堆中没有内存空间可分配给实例,也无法再扩展时,则抛出OutOfMemoryError异常。

Java1.8-JVM内存结构

在这里插入图片描述
其中:堆分为两部分
年轻代
包括三部分,Eden区和两个大小严格相同的Survivor区,根据JVM的策略,在经过几次垃圾收集后,任然存活于Survivor的对象将被移动到老年代区间。

老年代
主要保存生命周期长的对象,一般是一些老的对象

元空间
保存的类信息静态变量常量编译后的代码

Java1.7-JVM内存结构

唯一的不同就是在java8的JVM中,元空间是在本地内存中的,而java7当中元空间是作为方法区/永久代存在于堆空间中的

在这里插入图片描述
因而在1.8之后做出改动,主要是为了防止OMM内存泄漏,因为元空间(方法区/永久代)保存的是类信息静态变量常量编译后的代码,随着程序不断庞大,实现很难预估元空间的大小,久而久之就会产生OMM。

在旧的Java版本(如Java 7及更早版本)中,方法区和永久代(PermGen)都是的一部分,用于存储类的结构信息、常量池、静态变量等。但永久代容易导致内存溢出的问题,因为它的大小是固定的,并且无法在运行时动态调整。
为了解决这个问题,并改进类的元数据的存储方式,Java 8 引入了元空间(Metaspace)。元空间通过使用本地内存来存储类的元数据,有效地解决了永久代的限制和内存溢出问题。与永久代不同,元空间的大小并不受堆内存大小的限制,而是受系统的物理内存限制

元空间还具有自动调整大小的能力,可以根据需要动态地分配和释放内存。这使得元空间更具灵活性和可靠性,并能更好地适应各种应用程序的需求。


3.能不能介绍一下方法区(元空间)

在不同的JVM实现中,方法区存在位置是不一样的。
这里举例在jdk1.7时的jvm
在这里插入图片描述

方法区(Method Area)是各个线程共享的内存区域
主要存储类的信息运行时常量池
虚拟机启动的时候创建关闭虚拟机时释放
如果方法区域中的内存无法满足分配请求,则会抛出OutOfMemoryError: Metaspace
在这里插入图片描述
普通常量池
可以看作是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息

通俗的说,就是记录了虚拟机指令和执行的类名、方法名等信息的映射关系

编译阶段:常量池的符号引用为这种#+数字,因为只是编译阶段,没到运行阶段,只需要直到机器指令和方法、类名等等的映射关系,能找到对应上就算编译通过

在这里插入图片描述
运行时常量池
在类加载阶段,JVM会将符号引用解析为直接引用(将符号替换为真实的地址值),并将其存储在常量池中,以供运行时使用。

*常量池是 .class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址

在这里插入图片描述


4.你听过直接内存吗

直接内存:并不属于JVM中的内存结构不由JVM进行管理。是虚拟机的系统内存,常见于NIO(非阻塞io)操作时,用于数据缓冲区,它分配回收成本较高,但读写性能高

直接内存最直接的体现就是常规IO和NIO的区别:
我们都知道NIO是非阻塞的,IO是传统阻塞式

IO传统阻塞式

在这里插入图片描述

相当于java程序不能直接去读系统内存给的数据,需要一个媒介就是堆内存java缓冲区

NIO非阻塞式
在这里插入图片描述

相比较IO是直接到直接内存读数据,所以只要将磁盘文件读到直接内存,数据准备就绪,程序切换到内核态就直接从直接内存读数据


5.什么是虚拟机栈

通俗来说就是线程的方法栈

Java Virtual machine Stacks (java 虚拟机栈)

每个线程运行时所需要的内存,称为虚拟机栈,先进后出

每个栈由多个栈帧(frame)组成(一个栈帧代表一个方法占用的内存),对应着每次方法调用时所占用的内存

每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法

也就是一个方法(主方法)可以调用其他很多别的方法(子方法)

在这里插入图片描述


6.垃圾回收是否涉及栈内存?

垃圾回收主要指就是堆内存,当栈帧弹栈以后,内存就会释放


7.栈内存分配越大越好吗?

未必,默认的栈内存通常为1024k
栈帧过大会导致线程数变少,例如,机器总内存为512m,目前能活动的线程数则为512个,如果把栈内存改为2048k,那么能活动的栈帧就会减半

很好理解,机器内存就那么多,单独把栈内存调大了,那么栈帧的个数自然的得变少,所以对应的线程数就会变少


8.方法内的局部变量是否线程安全?

如果方法内局部变量没有逃离方法的作用范围,它是线程安全
如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全

通俗来说,就是看方法内的局部变量是不是完全包围在方法内(像如果是作为方法参数传过来的、作为返回值返回的都可以算是逃离了方法的作用范围),这样别的线程可以肆意修改方法内的局部变量

在这里插入图片描述


9.什么情况下会导致栈内存溢出?

栈帧过多导致栈内存溢出,典型问题:递归调用
在这里插入图片描述

栈帧过大导致栈内存溢出(基本上不存在)

栈的容量较小:相对于堆内存而言,栈内存的容量通常比较有限。每个线程都有自己的栈空间,而每个栈的大小通常只有几MB到几十MB。这限制了栈帧的大小,使得栈溢出的概率较低。


10.堆栈的区别是什么

分配对象和数据类型:堆内存用于分配Java对象数组。所有通过关键字new创建的对象以及通过反射或JNI创建的对象都存储在堆中。而栈内存主要用于存储基本数据类型的变量方法调用时的局部变量。

存储位置:堆内存位于JVM的堆区,是一个共享的内存区域。栈内存位于JVM的栈区每个线程都有自己的独立栈

内存管理方式内存的分配和回收由Java虚拟机的垃圾回收器负责管理。垃圾回收器会自动回收不再使用的对象,并释放对应的内存空间。而内存的分配和回收是由编译器自动管理的,当方法执行结束或变量超出作用域时,栈上的内存会自动被释放

内存分配速度内存的分配速度相对较慢,因为需要进行复杂的垃圾回收算法和对象定位操作。而内存的分配速度较快,仅仅是简单地进行指针移动。

内存空间大小限制堆内存的大小一般比栈内存大得多。堆内存的大小可以通过JVM的配置参数进行调整。而内存的大小是由线程的启动参数决定的,每个线程的栈大小通常是固定的。

对象的生命周期堆内存中的对象生命周期可以很长,可以在程序的任意位置被引用和访问。而内存中的局部变量生命周期与方法调用密切相关,当方法执行结束时,栈上的局部变量会自动销毁。

总结来说,堆内存主要用于存储Java对象和数组,由垃圾回收器管理,分配和回收速度相对较慢;而栈内存主要用于存储基本数据类型的变量和方法调用时的局部变量,由编译器自动管理,分配和回收速度相对较快。两者在内存管理方式、存储位置、分配速度和大小等方面有较大的区别。


二、类加载器

11.什么是类加载器,类加载器有哪些

类加载器
JVM只会运行二进制文件,类加载器的作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来。
在这里插入图片描述
类加载器包括四种

启动类加载器(加载像库里自带的类string integer等等(BootStrap ClassLoader):加载JAVA_HOME/jre/lib目录下的库
扩展类加载器(ExtClassLoader):主要加载JAVA_HOME/jre/lib/ext目录中的类
应用类加载器(加载自己java程序写的类(AppClassLoader):用于加载classPath下的类
自定义类加载器(很少自己写加载器(CustomizeClassLoader):自定义类继承ClassLoader,实现自定义类加载规则。
在这里插入图片描述


12.什么是双亲委派模型?

加载某一个类,先委托上一级的加载器进行加载,如果上级加载器也有上级,则会继续向上委托,如果该类委托上级没有被加载子加载器尝试加载该类
举例:

假设有一个Student类,需要加载
这个时候就会定位到AppclassLoader(应用类加载器),发现应用记载器有上级加载器,就先不加载,看看上级加载器里面有没有加载过的Student类,一直往上找,发现都没有加载过的Student类,那么此时AppclassLoader才会去加载Student类

在这里插入图片描述
假设有一个String类,需要加载,也是定位到AppclassLoader(应用类加载器)往上委托直到找到启动类加载器,找到了加载好的String类,直接加载。
在这里插入图片描述


13.JVM为什么采用双亲委派机制?

JVM采用双亲委派机制(Parent Delegation Model)是为了解决两个主要问题:
安全性避免类的重复加载

安全性体现在:
确保核心Java库的安全性,避免恶意代码通过自定义的类伪装成核心类库,从而提高系统的安全性。

例如下面我们自己创建一个String包装类,此时核心类库是本身就会加载这个类,这个时候就会报错,不允许加载自定义的核心库的类。

双亲委派机制可以确保核心Java库的安全性。当一个类需要被加载时,首先会委派给父类加载器进行查找和加载只有在父类加载器无法找到该类时才会由当前类加载器自己去加载。

在这里插入图片描述
在这里插入图片描述

避免类的重复加载体现在
通过双亲委派机制,当一个类需要被加载时,首先由父类加载器尝试加载,如果父类加载器已经加载了该类,就直接返回;否则,再由子类加载器尝试加载。这种机制可以确保在整个类加载器层次结构中每个类只被加载一次避免了类的重复加载,提高了运行效率


14.说一下类装载的执行过程

类在装载的时候会经历7个过程:

在这里插入图片描述

  • 加载:查找和导入class文件
  • 验证:保证加载类的准确性
  • 准备:为类变量分配内存并设置类变量初始值
  • 解析:把类中的符号引用转换为直接引用
  • 初始化:对类的静态变量,静态代码块执行初始化操作
  • 使用:JVM 开始从入口方法开始执行用户的程序代码
  • 卸载:当用户程序代码执行完毕后,JVM便开始销毁创建的Class对象。

详细参考链接:【JVM】类装载的执行过程


三、垃圾回收

15.强引用、软引用、弱引用、虚对象什么时候可以被垃圾器回收

15.1 对象什么时候可以被垃圾器回收

垃圾回收,回收的是针对于堆的
在这里插入图片描述

简单一句就是:如果一个或多个对象没有任何的引用指向它了,那么这个对象现在就是垃圾,如果定位了垃圾,则有可能会被垃圾回收器回收。

如果要定位什么是垃圾,有两种方式来确定,第一个是引用计数法,第二个是可达性分析算法

引用计数法(不常用)

一个对象被引用了一次,在当前的对象头上递增一次引用次数(ref=1),如果这个对象的引用次数为0(ref=0),代表这个对象可回收
在这里插入图片描述
但是当对象间出现了循环引用的话,则引用计数法就会失效
在这里插入图片描述

可达性分析算法
现在的虚拟机采用的都是通过可达性分析算法来确定哪些内容是垃圾。

比如下面的例子
X,Y这两个节点是可回收的
Java 虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象
扫描堆中的对象,看是否能够沿着 GC Root 对象 为起点的引用链找到该对象,找不到,表示可以回收
在这里插入图片描述
哪些对象可以作为 GC Root ?

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
    在这里插入图片描述

  • 方法区中类静态属性引用的对象
    在这里插入图片描述

  • 方法区中常量引用的对象
    在这里插入图片描述

  • 本地方法栈中 JNI(即一般说的 Native 方法)引用的对象


16.JVM 垃圾回收算法有哪些?

参考链接:GC详解、GC四大算法和GC Root

总共分为三种:
标记清除算法:垃圾回收分为2个阶段,分别是标记和清除,效率高,有磁盘碎片,内存不连续

标记整理算法:标记清除算法一样,将存活对象都向内存另一端移动,然后清理边界以外的垃圾,无碎片,对象需要移动,效率低

复制算法:将原有的内存空间一分为二,每次只用其中的一块,正在使用的对象复制到另一个内存空间中,然后将该内存空间清空,交换两个内存的角色,完成垃圾的回收;无碎片,内存使用率低

16.1 标记清除算法

标记清除算法,是将垃圾回收分为2个阶段,分别是标记和清除
1.根据可达性分析算法得出的垃圾进行标记
2.对这些标记为可回收的内容进行垃圾回收

注意:标记GC Root引用链的对象,回收的就是没有被标记的
在这里插入图片描述

缺点:

  • 需要两次扫描,耗时严重。

先扫描一次,对存活的对象进行标记。
再次扫描,回收没有被标记的对象。

  • 会产生内存碎片,导致内存空间不连续。

当需要分配一个较大的内存块时,由于没有足够的连续内存空间,可能会导致分配失败即内存溢出。

16.2 标记整理算法( 标记清除算法的升级—多了一个整理阶段)

优缺点同标记清除算法,解决了标记清除算法的碎片化的问题,同时,标记压缩算法多了一步,对象移动内存位置的步骤,其效率也有有一定的影响。

相比较标记清除算法在垃圾回收后,会将活着的对象滑动到一侧,这样就能让空出的内存空间是连续的。
在这里插入图片描述

16.3 复制算法

相当于把一块堆内存分成两半来用,一般拿来存对象,另一半拿来做垃圾回收后的整理收纳仓(必须为空闲空间)

复制算法需要将存活的对象一个区域复制到另一个区域(空白区域),然后直接清空存活对象和待回收对象的那一片区域

注意:要求堆内存的使用比例不超过50%,因为每次垃圾回收时,需要保证目标区域有足够的空间来存放从源区域复制过来的对象。

在这里插入图片描述
优点:
在垃圾对象多的情况下,效率较高
清理后,内存无碎片

缺点:
分配的2块内存空间,在同一个时刻,只能使用一半,内存使用率较低


17.说一下JVM中的分代回收

一、堆的区域划分
堆被分为了两份:新生代和老年代【1:2】
对于新生代,内部又被分为了三个区域。Eden区幸存者区survivor(分成from和to)【8:1:1】

二、对象回收分代回收策略

  • 新创建的对象,都会先分配到eden区
  • 当伊甸园内存不足,标记伊甸园与 from(现阶段没有)的存活对象
  • 将存活对象采用复制算法复制到to中,复制完毕后,伊甸园和 from 内存都得到释放
  • 经过一段时间后伊甸园的内存又出现不足,标记eden区域to区存活的对象,将其复制到from区
  • 当幸存区对象熬过几次回收(最多15次),晋升到老年代(幸存区内存不足或大对象会提前晋升)

参考链接:【JVM】JVM中的分代回收

17.1 MinorGC、 Mixed GC 、 FullGC的区别是什么

STW(Stop-The-World):暂停所有应用程序线程,等待垃圾回收的完成

MinorGC、 Mixed GC 、 FullGC 相当于垃圾回收的等级:
在这里插入图片描述

MinorGC:【young GC】发生在新生代的垃圾回收,暂停时间短(STW)
Mixed GC新生代 + 老年代部分区域的垃圾回收,G1 收集器特有
FullGC新生代 + 老年代完整垃圾回收,暂停时间长(STW),应尽力避免


18.说一下JVM有哪些垃圾回收器?

在jvm中,实现了多种垃圾收集器,包括:

  1. 串行垃圾收集器
    Serial 作用于新生代,采用复制算法
    Serial Old 作用于老年代,采用标记-整理算法

  2. 并行垃圾收集器(JDK8默认使用此垃圾回收器
    Parallel New作用于新生代,采用复制算法
    Parallel Old作用于老年代,采用标记-整理算法

  3. CMS(并发)垃圾收集器
    针对老年代垃圾回收的

  4. G1垃圾收集器(在JDK9之后默认使用
    应用于新生代和老年代

详细参考链接:


19.详细聊一下G1垃圾回收器


四、JVM实践

20.JVM 调优的参数可以在哪里设置


21.用的 JVM 调优的参数都有哪些?


22.说一下 JVM 调优的工具?


23.Java内存泄露的排查思路?


24.CPU飙高排查方案与思路?

相关文章:

【高频面试题】JVM篇

文章目录 一、JVM组成1.什么是程序计数器2.什么是Java堆?3.能不能介绍一下方法区(元空间)4.你听过直接内存吗5.什么是虚拟机栈6.垃圾回收是否涉及栈内存?7.栈内存分配越大越好吗?8.方法内的局部变量是否线程安全?9.什么…...

第十三次CCF计算机软件能力认证

第一题:跳一跳 近来,跳一跳这款小游戏风靡全国,受到不少玩家的喜爱。 简化后的跳一跳规则如下:玩家每次从当前方块跳到下一个方块,如果没有跳到下一个方块上则游戏结束。 如果跳到了方块上,但没有跳到方块的…...

无人驾驶实战-第十二课(强化学习自动驾驶系统)(完)

在七月算法上报了《无人驾驶实战》课程,老师讲的真好。好记性不如烂笔头,记录一下学习内容。 课程入口,感兴趣的也可以跟着学一下。 ————————————————————————————————————————— 强化学习&#xff…...

【flask sqlalchmey】一次性将返回的列表对象或者 一行数据对象转成dict---flask-sqlalchemy输出json格式数据

def model_to_dict(object):return {c.name: getattr(object, c.name) for c in object.__table__.columns}#将一组数据转为list def scalars_to_list(object):return [model_to_dict(c) for c in object]class Sysdict(Base,SerializerMixin):__bind_key__ forest_fire_contr…...

goland插件推荐Rider UI Theme Pack

推荐一个goland配色插件Rider UI Theme Pack,里面自带visual assist配色,配色截图如下: 直接在plugins里面进行搜索或者在插件home page下载后进行安装均可。 总算找到一统vscode 和goland二者优势的插件了。...

人工智能面试常识-10

目录 1. 人工智能的常见用途和应用有哪些? 2. 什么是智能代理,它们如何在人工智能中使用?...

Android JNI开发从0到1,java调C,C调Java,保姆级教程详解

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂,风趣幽默",感觉非常有意思,忍不住分享一下给大家。 👉点击跳转到教程 第一步首先配置Android studio的NDK开发环境,首先在Android studio中下载NDK…...

STM32基于CubeIDE和HAL库 基础入门学习笔记:功能驱动与应用

文章目录: 一:LED与按键驱动程序 main.c 1.闪灯 led.h led.c 2.按键控制LED亮灭 key.h key.c 二:蜂鸣器与继电器驱动程序 main.c 1.蜂鸣器 buzzer.h buzzer.c delay.h delay.c 2.继电器 relay.h relay.c 三&#xff1…...

创建型模式 (Creational Patterns) 玄子Share 设计模式 GOF 全23种 + 七大设计原则

玄子Share 设计模式 GOF 全23种 七大设计原则 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NWLAOFtO-1691793071647)(./assets/%E7%8E%84%E5%AD%90Share%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20GOF%20%E5%85%A823%E7%A7%8D%20%20%E4%B8%83%E…...

【脚踢数据结构】队列(顺序和链式)

(꒪ꇴ꒪ ),Hello我是祐言QAQ我的博客主页:C/C语言,Linux基础,ARM开发板,软件配置等领域博主🌍快上🚘,一起学习,让我们成为一个强大的攻城狮!送给自己和读者的一句鸡汤🤔&…...

linux添加磁盘

一、linux虚拟机添加一块新的硬盘 四步: (1) (2)为硬盘进行分区 (3)初始化硬盘分区 (4)挂载 在虚拟机上添加一块硬盘 (1)、 虚拟机添加一块新的硬盘作为数据盘 (2) ls…...

图片懒加载

什么是图片懒加载? 懒加载也叫做延迟加载、按需加载,指的是在长网页中延迟加载图片 数据,是一种较好的网页性能优化的方式。在比较长的网页或应用中, 如果图片很多,所有的图片都被加载出来,而用户只能看到可…...

scope,deep穿透的实际应用

一.父组件代码 <template><div id"app"><h1 class"box"><pageName> </pageName></h1></div> </template><script> import pageName from "../src/components/pageName.vue"; export de…...

Multipass虚拟机设置局域网固定IP同时实现快速openshell的链接

本文只介绍在windows下实现的过程&#xff0c;Ubuntu采用22.04 安装multipass后&#xff0c;在卓面右下角Open shell 就可以链接默认实例Primary&#xff0c;当然如果你有多个虚拟机&#xff0c;可以针对不同内容单独建立终端的链接&#xff0c;而本文仅仅用Primary来说明。 …...

Webpack5 core-js和babel-loader区别和用法

文章目录 core-js是什么&#xff0c;有什么用&#xff1f;为什么使用了babel-loader对js进行兼容性配置还需要core-js?core-js的具体用法总结 core-js是什么&#xff0c;有什么用&#xff1f; core-js是一个流行的JavaScript库&#xff0c;它提供了对新的JavaScript特性、API…...

软考高级架构师——5、系统规划分析与设计方法

系统计划主要用于描述从项目提出、选择到确立的过程&#xff0c;包括系统项目的提出与可行性 分析&#xff0c;系统方案的制订、评价和改进&#xff0c;新旧系统的分析和比较&#xff0c;以及现有软件、硬件和数据 资源的有效利用等问题。 1、项目的提出与选择 项目的立项目标…...

区块链学习6-长安链部署:如何创建特定共识节点数和同步节点数的链

正常prepare的时候只支持4 7 13 16个节点个数&#xff0c;想要创建10个节点&#xff0c;其中5个是共识节点&#xff0c;如何实现&#xff1f; 1. 注释掉prepare.sh的这几行&#xff1a; 2. 修改 crytogen的模板文件&#xff1a; 如果是cert模式&#xff1a;chainmaker-crypt…...

北航基于openEuler构建工业机器人操作系统,打造“开箱即用”的机器人基础软件平台

北京航空航天大学是国家“双一流”建设高校&#xff0c;以建设扎根中国大地的世界一流大学为发展目标。北京航空航天大学在机器人领域一直处于行业前沿&#xff0c;以其亮眼的成果和优秀的师资力量&#xff0c;成为国内机器人领域的重要参与者和建设者。机器人操作系统是机器人…...

孤儿进程与僵尸进程

进程退出 关于进程退出有两个函数 exit和 _exit&#xff1a;其主要差别是在于是否直接退出。 其流程主要区别如下&#xff1a; 孤儿进程&#xff08;不存在危害&#xff09; 父进程运行结束&#xff0c;但子进程还在运行&#xff08;未运行结束&#xff09;&#xff0c;这…...

redis的基础命令01

1、操作库的指令 1、清除当前库---flushdb 2、清除所有库---flushAll 2、操作key的指令 最常用的指令get、set 1&#xff09;set key value 2&#xff09;get key 基础指令 1、del 删除单个&#xff1a;del key 、批量删除&#xff1a;del key1 key2 key3 2、exists 判断key是否…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...