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

【操作系统期末速成】​内存管理|内存的装入模块在装入内存的方式|分配管理方式|页面置换算法|页面置换

  •   🎥 个人主页:深鱼~
  • 🔥收录专栏:操作系统
  • 🌄欢迎 👍点赞✍评论⭐收藏

推荐

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

 前言:

最近在备战期末考试,所以本专栏主要是为了备战期末操作系统这门考试,讲的比较浅显,但是都是期末常考的考点和题型,仅限于“期末不挂”的层面

​​


一、内存管理

1.内存管理的概念

计算机不可能将所有用户进程和系统所需要的全部程序和数据放入主存,因此操作系统必须对内存空间进行合理的划分和有效的动态分配

内存管理的概念就是操作系统对内存的划分和动态分配


2.内存管理功能

(1)内存空间的分配与回收:由操作系统完成主存储器空间的分配和管理

💡(2)地址转换: 将逻辑地址转换成相应的物理地址

(3)内存空间的扩充:利用虚拟存储技术或自动覆盖技术,从逻辑上扩充主存

(4)存储保护:保证各道作业在各自的存储空间内运行,互不干扰


3.将用户源程序变为可在内存中执行的程序的步骤:

(1)编译:由编译程序将用户源代码编译成若干目标模块(把高级语言翻译成机器语言)

(2)链接:由链接程序将编译后形成的一组目标模块及所需的库函数连接在一起,形成一个完整的装入模块(由目标模块生成装入模块,链接后形成完整的逻辑地址)

(3)装入:由装入程序将装入模块装入内存运行,装入后形成物理地址


程序的链接有以下三种方式:

(1)静态链接:在程序运行之前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件(装入模块),之后不再拆开

(2)装入时动态链接:将各目标模块装入内存时,边装入边链接的链接方式

(3)运行时动态链接:在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享


💡(考选择)内存的装入模块在装入内存时,有以下三种方式:

(1)绝对装入:在程序编译时就知道程序需要放在内存中的什么地方,编译后的程序不是从0开始的逻辑地址,而是真实的物理地址按照编译程序产生的绝对地址进行装入

(2)静态可重定位装入:编译后的模块需要连续装入内存,但是在内存中的物理地址可与逻辑地址不同,可以存在一定偏移,比如逻辑地址是0-100,它可以在内存中存储在100-200的内存单元中,需要设定-个偏移量就是100,同时也需要为其分配连续的存储空间,不然通过偏移量是无法找到的,现在就可以通过作业的逻辑地址+偏移量获得作业在内存中的绝对地址(💡考大题)

(3)动态运行时装入:将不同的模块可以装入在不同的内存地址,不同模块可以不连续,但是同一模块还是要连续存放的,同一模块需要设定一个重定位寄存器,每个模块的重定位寄存器中的值就是对应的偏移量。装入程序会把模块装入内存,但是并不会立即将装入模块的相对地址转换为绝对地址,而是把这种地址转换推迟到程序真正执行时才进行

可以将程序分配到不连续的存储区


4.覆盖

覆盖技术的基本思想:将程序分为多个段,常用的段常驻内存,不常用的段在需要时调入内存。

特点:打破了必须将一个进程的全部信息装入主存后才能运行的限制,解决了程序大小超过物理内存总和的问题


5.交换

交换技术的基本思想:内存空间紧张时,系统将内存中的某些进程暂时换出外存,把外存中某些已具备运行条件的进程换入内存


二、分配管理方式

1.连续分配管理方式

连续分配方式是指为一个用户程序分配一个连续的内存空间。主要包括单一连续分配、固定分区分配和动态分区分配

(1)内部碎片:分配给某进程的内存区域中,有些部分没用上

(2)外部碎片:是指内存中的某些空闲分区由于太小而难以利用


<1>单一连续分配(无外部碎片,有内部碎片)

在单一连续分配方式中,内存被分为系统区和用户区,系统区用于存放操作系统相关数据;用户区用于存放用户进程相关数据

内存中只能有一道用户程序,用户程序独占整个用户区空间


<2>固定分区分配(无外部碎片,有内部碎片)

它将用户内存空间划分为若干固定大小的分区,每个分区只装入一道作业,当有空闲分区时,便可再从外存的后备队列中选择适当大小的作业装入该分区

固定分区分配分为分区大小相等分区大小不等两种方式


<3>动态分区分配(没有内部碎片,但有外部碎片)

动态分区分配不预先分配内存,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。(某些空闲分区由于太小而难以利用)


动态分区分配的策略有以下几种算法:

(1)首次适应算法First-Fit

每次都从低地址开始查找,选择第一个能够满足大小的空闲分区

优点:综合看性能最好。算法开销小,回收分区后一般不需要对空闲分区队列重新排序

(2)最佳适应算法Best-Fit

优先使用更小的空闲分区,将空闲分区按照容量递增链接,每次寻找大小能够满足的第一个空闲分区
优点:会有更多的大分区被保留下来,更能满足大进程需求
缺点:开销大,产生很多小碎片

(3)最坏适应算法Worst-Fit

为了防止留下太多细碎的空闲空间,每次分配时优先使用最大的空闲分区。可以将空闲分区按照容量递减链接

缺点:由于每次都使用最大的空闲分区,因此较大的连续分区会很快被利用完,导致大进程到来时可能不足以分配

优点:可以减少难以利用的小碎片

(4)邻近适应算法Next-Fit

由于首次适应算法每次都从链头开始查找,可能导致低地址 部分出现很多小的空闲分区,而每次查找时都会遍历这些分区,增加了查找开销。因此将空闲分区按照地址递增的顺序排成一个循环链表,每次都从上次结束的位置开始查找,使用第一个满足的空闲分区

优点:不用每次都从低地址的小分区开始检索


2.非连续分配管理方式

非连续分配概念

如果可以将一个进程分散的装入到许多不相邻的分区中,便可以充分的利用内存

<1>基本分页存储的管理方式(💡考大题:根据页表求地址)

将用户进程的地址空间也分为与页框大小相等的一个个区域,称为页、或称页面,每个页面也有一个编号,即页号,页号也是从0开始的

各个页面不必连续存放,也不必按先后顺序来,可以放到不相邻的各个页框中

 

<2>基本地址变换机构

步骤:
(1)根据逻辑地址计算出页号、页内偏移量
(2)判断页号是否越界
(3)查询页表,找到页号对应的页表项,确定页面存放的内存块号
(4)用内存块号和页内偏移量得到物理地址
(5)访间目标内存单元

(💡考大题)例题:

例:若页而大小L为1K字节,页号2对应的内存块号b=8,将逻辑地址A=2500转换为物理地址E

答:1KB=1024B,说明页内偏移量占10位

页号2对应的内存号b=8

第一步:计算页号、页内偏移量

页号P=A/L=2500/1024=2

页内偏移量W=A%L=2500%1024=452

第二步:求块号

页号为2,对应的内存块号为8

第三步:求物理地址

E=b*L+W=8*1024+452=8644

<3>分段存储管理方式

进程的地址空间,按照程序程序自身的逻辑关系划分为若干个段,每个段都有一个段名,每段从0开始编址

<4>段页式管理方式

先分段,再将各段分页,再将内存空间分为大小相同的内存块,然后进程内各个分页装入各个内存块中


局部性原理

时间局部性:如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(因为程序中存在大量的循环)

空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。因为很多数据在内存中都是连续存放的)


虚拟内存的基本概念

基于局部性原理,在程序装入时,可以将程序中很快会用到的部分装入内存,暂时用不到的部分留在外存,就可以让程序开始执行。

在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,然后继续执行程序。若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存。在操作系统的管理下,在用户看来似乎有一个比实际内存大得多的内存,这就是虚拟内存


虚拟内存技术的实现

虚拟内存技术的实现需要建立在离散分配的内存管理方式的基础上

虚拟内存的实现有以下三种方式:

1.请求分页存储管理

2.请求分段存储管理

3.请求段页式存储管理


缺页中断

在请求分页系统中,每当要访问的页面不在内存中时,便产生一个缺页中断,请求操作系统将所缺的页调入内存。此时应将缺页的进程阻塞(调页完成唤醒),若内存中有空闲块,则分配一个块,将要调入的页装入该块 ,若此时内存中没有空闲块,则要淘汰某页,若被淘汰的页在内存期间被修改过,则要将其写回外存


快表

快表就是存放在[高速缓冲存储器]的部分页表。作为页表的Cache,它的作用与页表相似,但是提高了访问速率。由于采用页表做地址转换,读写内存数据时CPU要访问两次主存。有了快表,有时只要访问一次高速缓冲存储器,一次主存,这样可加速查找并提高指令执行速度。

地址转换流程

1.按照逻辑地址中的页号查快表

2.若该页*己存在*快表中,则由页架号和单元号形成绝对地址

3.若该页*不在*快表中,则再查主存页表,与单元号形成绝对地址,同时将该页登记到快表中

4.当快表填满后,又要登记新页时,则需要按照一定替换策略淘汰一个旧的登记项


💡 页面置换算法

最佳置换算法(OPT)

最佳页面置换算法选择的被淘汰页面是以后永不使用的页面,或是在最长时间内不再被访问的页面,以便保证获得最低的缺页率,但是,人们无法预知进程在内存下的若干页面中的哪个是未来最长时间内不再被访问的,因为该算法无法实现

先进先出页面置换算法(FIFO)

优先淘汰最早进入内存的页面,即再内存中驻留时间最久的页面

最近最久未使用置换算法(LRU)

选择最近最长时间未访问过的页面予以淘汰,它认为过去一段时间内未访问过的页面,在最近的将来可能也不会被访问。该算法为每个页面设置一个访问字段,来记录页面自上次被访问以来所经历的时间,淘汰页面时选择现有页面中值最大的予以淘汰

近期最少使用算法(LFU算法

选择近期最少访问的页面作为被替换的页面


页面抖动

概念:刚刚换出到外存的页面马上要调入内存,刚刚调入内存的页面马上要调出到外存

原因:系统为进程分配的物理块大小不足。内存驻留的进程太多


页面置换策略

固定分配局部置换:

系统为每个进程分配一定数量的内存块(物理块),在整个运行期都不改变。若进程在运行过程中发生了缺页,则只能在本进程的内存页面中选出一个进行调出,再调回需要的页面

缺点:不好确定一个进程到底应该分配多大的实际内存才合理

可变分配全局置换:

系统为每个进程分配一定数量的内存块。操作系统还会保持一个空闲物理块的队列。若某个进程发生缺页,可以从空闲物理块中取出一块分配给该进程。如果空闲物理块没有了,那么会选择一个未锁定(不那么重要,可能是其它进程的)的页面换出到外存,再将物理块分配给缺页的进程

缺点:在空闲物理块没有的情况下,如果将其它进程的页面调出外存,那么这个进程就会拥有较小的驻留集(即拥有的物理块),如此会导致该进程的缺页率(访问某个页面,这个页面不在内存中的概率)上升

可变分配局部置换:

刚开始为每个进程分配一定数量的物理块。当进程发生缺页时,只允许从当前进程的物理块中选出一个换出内存。如果当前进程在运行的时候频繁缺页,系统会为该进程动态增加一些物理块,直到该进程缺页率趋于适中程度;如果说一个进程在运行过程中缺页率很低或者不缺页,则可以适当减少该进程分配的物理块。通过这些操作可以保持多道程序的并发度较高

与可变分配全局置换 区别:

可变分配全局置换:只要发生缺页,就会分配新的物理块

可变分配局部置换:根据缺页率动态增加或者减少物理块的数量


真题速通

💡1.根据页表求地址

由页表可知,绝对页号是8,物理地址=E=b(块号)*L(页面大小)+W(偏移量)=1Kx8+451=1024x8+451=8643


💡2.页面置换

在一个请求分页存储管理系统中,一个作业的页面走向4,3,2,1,4,3,5,4,3,2,1,5.当分配给作业的物理块数为3时,试计算采用下述页面淘汰算法时的缺页率(假设开始执行时主存中没有页面),并比较结果

1) 最佳置换算法(从左往右看,第一次出现的地方,最远的那个被替换)

当页面走向为第一个1的时候,向后找第一次出现的地方最远的那个(4,3,2中2离的最远),后面如果有,说明没有缺页,就不用管,下一个就是5;然后再走到2,这个时候发现后面没有3,4,那么默认3,4都在最后一个位置(即最后一个5的后面),所以随机置换一个3/4都可以

缺页率=7/12

2)先进先出置换算法(看这行元素出现的次数,淘汰掉次数最大的)

当页面走向为第一个1的时候,看物理页这行,4出现3次,3出现2次,2出现1次,那么就需要置换出现最多次数的那个(也就是4)

缺页率=9/12

3)最近最久未使用算法(从右往左看,第一次出先的地方,最远的那个被替换)

当页面走向为第一个1的时候,看页面走向这行,从右往左看,4出现的最远,置换4 

缺页率=10/12

相关文章:

【操作系统期末速成】​内存管理|内存的装入模块在装入内存的方式|分配管理方式|页面置换算法|页面置换

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;操作系统&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到…...

图和网络笔记

文章目录 1. A X 0 AX0 AX02. A T Y 0 A^TY0 ATY03. A X 0 AX0 AX0和 A T Y 0 A^TY0 ATY0的关系 1. A X 0 AX0 AX0 一个图可以由节点和边组成&#xff0c;假设我们有一个节点notes &#xff1a;n4,边edges&#xff1a;m5的有向图&#xff0c;表示如下 通过以上电路…...

请求外部系统报错

报错信息&#xff1a; nested exception is com.google.common.util.concurrent.ExecutionError: java.lang.NoSuchMethodError: com.google.common.net.HostAndPort.getHostText()Ljava/lang/String; 在网上看了好几篇文章&#xff0c;和我的都不符合。 后面自己发现是我的系…...

电路板维修【四】

【开关电源输出电压偏低不稳&#xff0c;用示波器立马锁定故障范围】&#xff1a;https://www.bilibili.com/video/BV1pf421D73K?vd_source3cc3c07b09206097d0d8b0aefdf07958 可以用示波器查看MOS的输出波形来查看其是否损坏&#xff1a; 电源芯片的供电电压来回跳变&#xf…...

(程序设计语言)传值、传引用

1、传值&#xff08;传递值&#xff09;&#xff1a; 在传值的情况下&#xff0c;函数接收到的是参数的一个副本&#xff0c;而不是参数本身。这意味着函数内部对参数的修改不会影响到原始值。传值通常用于基本数据类型&#xff08;如整数、浮点数、布尔值等&#xff09;的传递…...

一次基类类型对象无法被传递问题的分析

看下面一段代码&#xff1a; // proj2.cpp #include <iostream> using namespace std; class CharShape { public:CharShape(char ch) : _ch(ch) {};virtual void Show() 0; protected:char _ch; // 组成图形的字符 }; class Triangle : public CharShape { public:Tr…...

windows设置Redis服务后台自启动

问题 在日常开发过程中&#xff0c;redis是我们常用的缓存工具&#xff0c;但是由于redis对于Linux系统进行开发的&#xff0c;在Linux系统里可以通过修改redis.conf从而从而实现后台启动。 daemonize no 改成 daemonize yes 但是在window上如何也进行后台运行呢&#xff0c…...

掌握Linux常用命令,扫平面试需求障碍

cd 切换目录。 > cd ../ #切换到父级目录 > cd /tmp # 切换到/tmp目录 > cd ~ # 切换到当前用户的家目录 ls命令 查看文件与目录的命令&#xff0c;list 的缩写。 > ls -l #列出长数据串&#xff0c;包含文件的属性与权限数据等 > ls -a #列出隐藏…...

c语言之文件打开模式

在c语言中&#xff0c;文件打开模式如下 r读模式: 允许对文件读取信息。若文件不存在&#xff0c;则会报错 w写模式&#xff1a; 允许向文件写入信息&#xff0c;若文件不存在&#xff0c;则创建一个文件 #include<stdio.h>int main() {FILE *fp;int i;char ay;fpfo…...

与禹老师学前端vue3学习汇总

24.5.15&#xff1a; 创建Vue3工程 1.确定自己电脑有没有nodejs环境&#xff0c;在cmd中输入node&#xff0c;如果出现Node.js的版本号说明已经有这个环境了&#xff0c;否则搜索Node.js安装 2.先在D盘创建一个文件夹Vue3_Study&#xff0c;然后在这个空文件夹中右键选择终端…...

Linux网络编程——HTTP协议的理解与运用

目录 前言 一、认识URL 二、认识HTTP样例 三、HTTP的报头内容 1.url 2. Content-Type 3.Method 方法 1.GET方法 2.POST方法 4、状态码 5.cookie和session 前言 我们知道&#xff0c;协议就是一种约定&#xff0c;客户端与服务端统一的用这种约定进行传输数据。我们…...

RestTemplate接口请求发送json、form数据格式以及处理接口错误状态码400 null

在使用RestTemplate发送HTTP请求时&#xff0c;你可以通过不同的方式发送JSON或表单数据&#xff08;application/x-www-form-urlencoded&#xff09;。同时&#xff0c;处理接口错误状态码&#xff08;如400&#xff09;和返回null的情况也是很重要的。以下是一些示例代码&…...

《Python编程从入门到实践》day29

# 昨日知识点回顾 修改折线图文字和线条粗细 矫正图形 使用内置格式 # 今日知识点学习 15.2.4 使用scatter()绘制散点图并设置样式 import matplotlib.pyplot as plt import matplotlib matplotlib.use(TkAgg)plt.style.use(seaborn-v0_8) # 使用内置格式 fig, ax plt.subpl…...

UIKit之图片浏览器

功能需求 实现一个图片浏览器&#xff0c;点击左右按钮可以切换背景图&#xff0c;且更新背景图对应的索引页和图片描述内容。 分析&#xff1a; 实现一个UIView的子类即可&#xff0c;该子类包含多个按钮。 实现步骤&#xff1a; 使用OC语言&#xff0c;故创建cocoa Touch类…...

如何查看SNMP设备的OID

什么是OID和MIB OID OID 代表对象标识符。 OID 唯一地标识 MIB 层次结构中的托管对象。 这可以被描述为一棵树&#xff0c;其级别由不同的组织分配。MIB MIB&#xff08;管理信息基&#xff09;提供数字化OID到可读文本的映射。 使用MIB Browser扫描OID 我的设备是一台UPS SN…...

什么?你设计接口什么都不考虑?

如果让你设计一个接口&#xff0c;你会考虑哪些问题&#xff1f; 1.接口参数校验 接口的入参和返回值都需要进行校验。 入参是否不能为空&#xff0c;入参的长度限制是多少&#xff0c;入参的格式限制&#xff0c;如邮箱格式限制 返回值是否为空&#xff0c;如果为空的时候是…...

2024年3月 青少年等级考试机器人理论真题二级

202403 青少年等级考试机器人理论真题二级 第 1 题 一个机器小车&#xff0c;用左右两个电机分别控制左右车轮&#xff0c;左侧电机转速是100rpm&#xff0c;右侧电机转速是50rpm&#xff0c;则此机器小车&#xff1f;&#xff08; &#xff09; A&#xff1a;原地右转 B&am…...

C语言学习【printf函数和scanf函数】

C语言学习【printf函数和scanf函数】 printf()函数和scanf()函数可以让用户与程序交流&#xff0c;是输入/输出函数 printf()函数 请求printf()函数打印数据的指令要与待打印数据的类型相匹配。例如&#xff0c;打印整数时使用%d&#xff0c;打印字符时使用%c。这些符号被称…...

shell正则表达式

sort命令 以行为单位对文件内容进行排序&#xff0c;也可以根据不同的数据类型来排序 比较原则是从首字符向后&#xff0c;依次按ASCII码值进行比较&#xff0c;最后将他们按升序输出。 sort 对行内容进行升序排序 XXX | sort 选项 sort 选项 文件 常用选项&#x…...

react组件渲染性能优化之函数组件-useCallback使用

useCallback主要就是对函数进行缓存,useCallBack这个Hooks主要是解决React.memo不能缓存事件的问题 useCallBack(fn, dependencies) &#xff1a;fn想要缓存的函数&#xff0c;dependencies有关是否更新 fn 的所有响应式值的一个列表 比如&#xff1a;UseCallBackOptimize组件…...

【C++】:string类的基本使用

目录 引言一&#xff0c;string类对象的常见构造二&#xff0c;string类对象的容量操作三&#xff0c;string类对象的访问及遍历操作四&#xff0c;string类对象的修改操作五&#xff0c;string类非成员函数六&#xff0c;整形与字符串的转换 引言 string 就是我们常说的"…...

多线程的代码案例

目录 单例模式 饿汉模式 懒汉模式 阻塞队列 生产者消费者模型意义: 阻塞队列使用方法 实现阻塞队列 阻塞队列实现生产者消费者模型 定时器 实现简单的定时器 工厂模式 线程池 为啥呢? 从池子里面取 比 创建线程 效率更高 线程池的创建 怎么填坑 ThreadPoolExec…...

什么是Java中的设计模式?请列举几种常见的设计模式

一、引言 在软件开发中&#xff0c;设计模式是解决特定设计问题的最佳实践或通用解决方案。Java作为一种广泛使用的编程语言&#xff0c;其设计模式在软件设计和架构中起着至关重要的作用。设计模式不仅提高了代码的可读性和可维护性&#xff0c;还使得代码更加灵活和可扩展。…...

绘制奇迹:Processing中的动态图形与动画

&#x1f680; 欢迎回到Processing的世界&#xff0c;你的艺术编程航程刚刚开始。在我们的入门篇中&#xff0c;你已经学会了如何用Processing绘制基本的静态图形。现在&#xff0c;让我们一起探索Processing强大的动态图形和动画功能&#xff0c;释放你的创造力&#xff0c;走…...

Django视图Views

Views视图 HttpRequest 和HttpResponse Django中的视图主要用来接受web请求&#xff0c;并做出响应。视图的本质就是一个Python中的函数视图的响应分为两大类 1)以Json数据形式返回(JsonResponse) 2)以网页的形式返回 2.1)重定向到另一个网页 (HttpRe…...

国内智能搜索工具实战教程

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…...

WebSocket or SSE?即时通讯的应用策略【送源码】

最近在研究H5推送&#xff0c;发现除了我们常用的WebSocket以外&#xff0c;其实还有一种协议也能实现H5推送&#xff0c;那就是SSE协议。 而且&#xff0c;当前主流的大模型平台&#xff0c;比如ChatGPT、通义千问、文心一言&#xff0c;对话时采用的就是SSE。 什么是SSE协议…...

QT实现Home框架的两种方式

在触摸屏开发QT界面一般都是一个Home页面&#xff0c;然后button触发进入子页面显示&#xff0c;下面介绍这个home框架实现的两种方式&#xff1a; 1.方式一&#xff1a;用stackedWidget实现 &#xff08;1&#xff09;StackedWidget控件在Qt框架中是一个用于管理多个子窗口或…...

机器学习笔记03

1.线性回归&#xff08;linear regression&#xff09; 是利用回归方程&#xff08;函数&#xff09;对一个或者多个自变量&#xff08;特征值&#xff09;和因变量&#xff08;目标值&#xff09;之间关系进行建模的一种分析方法。 线性模型&#xff1a; 1.线性关系&#xff1…...

【全面介绍下Spring】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…...