操作系统对内存的管理:分配与回收,虚拟内存,内存容量的扩充,内存保护,补充(链接方式、装入方式)

news2024/11/25 2:43:40

内存:即内存条,也称主存储器(简称主存),用于存放数据。

为了缓和CPU和外存(磁盘)的速度矛盾,外存的程序先放入内存才能被CPU处理。

内存地址从0开始,每个内存地址对应一个存储单元。

存储单元的大小依据计算机的编址(按字节编址,则一个存储单元大小是1个字节;按字编址,32位计算机的一个存储单元大小是一个字即32位即4个字节,64位计算机中一个存储单元大小是一个字即64位即8个字节)。

参考:主存储器【计算机组成原理】

内存的分配与回收

内存的分配:程序装入内存时,为进程分配内存空间,并记录内存分配情况(内存分配表)。

内存的回收:程序撤销或者主动归还内存资源时,收回进程占用的内存空间,并修改内存分配表。

1、连续分配管理方式:给每个进程分配的内存区域必须是连续的。

内部碎片:内存中,已经分配给了进程,但没用上的那部分区域。

外部碎片:内存中,部分空闲区域太小,难以分配给进程。

 (1-1)单一连续分配:内存的用户区只能给一道用户程序。适用于早期的单道程序系统。

内存分为系统区(存放操作系统相关的数据)和用户区(用户进程相关数据)。

采用栅栏寄存器(存放系统区和用户区的界限地址)进行内存保护,避免用户访问或修改系统区。

实现简单,没有外部碎片,但只能一道程序,内存利用率低,产生内部碎片。

(1-2)固定分区分配: 内存的用户区分成固定大小的分区(分区大小相等或者分区大小不等)。适用于多道程序。需要分区说明表(数据结构)记录各个分区的分配和回收情况,通常按分区大小排列。

实现简单,无外部碎片;但有内部碎片,内存利用率低,若所有分区都无法满足大程序,用覆盖技术解决,将降低性能。(分区大小相等)缺少灵活性,不利于大程序;(分区大小不等)增加了灵活性,满足不同大小的进程需求。

 (1-3)动态分区分配(可变分区分配):在进程装入内存时,根据进程大小动态建立分区。适用于多道程序。需要空闲分区表/空闲分区链(数据结构)记录各个空闲分区。需要一定的算法动态安排分配。回收分区时需注意合并分区。

没有内部碎片,但有外部碎片。但可用“拼凑”技术解决。(“拼凑”技术即紧凑技术:若各空闲内存空间都不够分配给进程,但总和超过进程大小,将分配给各进程的空间挪到一起,将零碎的空闲空间拼凑成一个大的连续的空闲空间)

动态分区分配算法

首次适应算法

(First Fit)

最佳适应算法

(Best Fit)

最坏适应算法

(Worst Fit)

邻近适应算法

(Next Fit)

分区排序:

按地址递增

分区排序:

按容量递增

分区排序:

按容量递减

分区排序:

按地址递增

从头开始查找,

从第一个大小适合的分区分配

优先从大小最适合的分区分配优先从容量最大的分区分配

从上次查找结束位置开始,

从第一个大小适合的分区分配

综合看性能最好。算法开销小(不需重新排序)大分区容易被保留下来。但容易有外部碎片,算法开销大(需按容量重新排序)减少难以利用的小碎片。但不利于大进程,算法开销大(需按容量重新排序)算法开销小(不需重新排序)。但可能会使高地址的大分区也被用完

动态分区分配的回收分区:

  • 回收区的前后没有空闲分区:空闲分区表/空闲分区链中,添加表项/节点。
  • 回收区的前或后有空闲分区:空闲分区表/空闲分区链中,修改对应的表项/节点。
  • 回收区的前后都有空闲分区:空闲分区表/空闲分区链中,合并对应的表项/节点(删除一个表项/节点,并修改对应的表项/节点)。
2、非连续分配管理方式:给每个进程分配的内存空间是离散的(不连续的)。

(2-1)分页存储管理

  • 内存划分成大小相等的分区(称为页框/页帧/物理块/物理页面/内存块),每个分区有编号(称为页框号/页帧号/物理块号/物理页号/内存块号),页框号从0开始。
  • 进程也划分成与页框大小相等的部分(称为页/页面),每个部分有编号(称为页号/页面号),页号从0开始。
  • 以页框为单位为进程分配内存空间。程序执行时,进程的页面复制到内存中的页框中。
  • 进程的各个页面在内存中的存放是离散的,但每个页面内部的存放是连续的。
  • 通过页表(数据结构)来记录进程的页面与实际存放的内存块的映射关系。

页表(又称慢表):【数据结构】

  • 在内存中,通常存放在系统区的进程控制块(PCB)中。
  • 记录进程的页面与实际存放的内存块的映射关系(包括页号,内存中的页框号等)。
  • 一个进程对应一张页表。一个页面对应一个页表项。页号从0开始。
  • 页表的页表项是连续存放的,因此页号可隐含(即不记录页号,不占存储空间)。

  • 页面大小:一个页面占多少存储空间。
  • 页表长度:页表中有多少页表项,即有多少页面。
  • 页表项长度:一个页表项占多少存储空间。

页表太大时,采用多级页表机制:

一个页面对应一个页表项,将页面分组,使用多个页表。内存中一个页框存放一个页表(页表长度 = 页框大小 / 页表项长度)。

例如:两级页表

  • 二级页表(若干个):记录页面在内存的地址。
  • 页目录表(又称外层页表/顶层页表,一个):所有二级页表的目录。记录二级页表在内存的地址。

(若使用虚拟存储技术,页目录表在内存,其他页表在外存中需要时才调入内存。各级页表中还将记录是否在内存、在外存的地址等信息)

地址转换机构: 

页表寄存器(PTR):

存放 页表在内存中的起始地址F 和 页表长度M。

  • 进程未执行前,页表在内存中的起始地址和页表长度是存放在进程控制块(PCB)中。
  • 进程被调度时,操作系统内核才将页表在内存中的起始地址和页表长度放入页表寄存器中。

页表长度用于判断逻辑地址中的页号是否越界(若页号\geq页表长度,则页号越界)。

快表(又称联想寄存器):

  • 英文缩写TLB,Translation Lookaside Buffer。
  • 在CPU中。访问速度比内存中的页表(慢表)快。
  • 存放最近访问过的页表项的副本。(即存放页表的部分副本)

逻辑地址 到 物理地址 的转换

逻辑地址(又称虚拟地址/相对地址):程序员视角的地址。

物理地址(又称绝对地址):实际在内存中的地址。

页号 = 逻辑地址 / 页面大小  【除法取整数部分】

页内偏移量(又称页内地址) = 逻辑地址 % 页面大小  【除法取余数部分】

若逻辑地址是二进制表示,且页面大小是2的整数幂(例如:2^{k}),则:

页内偏移量为逻辑地址的末尾k位。逻辑地址的其他二进制位为页号。

页表的起始地址:进程执行前,在PCB中;进程执行时,在页表寄存器中。

页表中页面对应页表项的起始地址:页表的起始地址 + 页号 * 页表项长度

页面在内存中的起始地址:页框号 * 页框大小

实际的物理地址:页面在内存中的起始地址 + 页面偏移量

地址转换过程: 

  1. 根据逻辑地址,获取页号和页内偏移量。
  2. 根据页表寄存器中的页表长度,检查逻辑地址中的页号是否越界,若越界,发出越界中断。
  3. 在快表中查询,若快表命中,直接获得页面在内存中的起始地址。若快表未命中,根据页表寄存器中的页表起始地址和逻辑地址中的页号,在内存的页表中查询,获取页面在内存中的起始地址。
  4. 根据页面在内存中的起始地址和页内偏移量,得到实际的物理地址。
  5. 根据实际的物理地址,在内存获取相应的数据。

(2-2)分段存储管理

  • 程序按照自身逻辑分成若干个段,用户给每个段定义段名,每个段的段长不同。
  • 以段为单位为进程分配内存空间。
  • 各段在内存的存放是离散的;每个段的内部的存放是连续的。
  • 通过段表记录进程的各段与段在内存中的地址的映射关系。
  • 段表寄存器存放段表的起始地址F和段表长度M。进程未执行前,F和M存放在PCB中。

段表:

  • 在内存中。记录进程的段号、段长、段在内存中的起始地址(即段基址)等。
  • 一个段表项对应一个段,段表中有多少段表项就表示进程有多少段。
  • 每个段表项长度相同,段表项连续存放,段号可隐含(即不占存储空间)。

段表的起始地址:进程执行前,在PCB中;进程执行时,在页表寄存器中。

段表中段对应段表项的存放地址:段表起始地址+段号*段表项长度

段在内存中的起始地址:对应段表项中的段基址

实际的物理地址:段在内存中的起始地址+段内地址

用户需提供段名和段内地址。编译程序会把段名转换为段号。

逻辑地址可拆分为段号和段内地址。段号的位数代表进程最多分多少段;段内地址的位数代表段长最大是多少。

地址转换过程: 

  1. 通过用户提供的逻辑地址,获取段号和段内地址。
  2. 根据段表寄存器中的段表长度,判断逻辑地址中的段号是否越界,若段号\geq段表长度,则越界,发出越界中断。
  3. 在快表中查,若快表命中,直接找到对应段表项。若快表未命中,根据段表寄存器中的段表起始地址和逻辑地址中的段号,在内存的段表中查,获得对应段表项。
  4. 根据段表项中的段长,判断逻辑地址中的段内地址是否越界,若段内地址\geq段长,则越界,发出越界中断。
  5. 根据段表项中的段基址和逻辑地址中的段内地址,获取实际的物理地址。
  6. 根据实际的物理地址,从内存获取相应数据。

 

分页存储管理和分段存储管理的区别

分页存储管理和分段存储管理的区别
分页存储管理分段存储管理
以页框为单位为进程分配内存空间以段为单位为进程分配内存空间
页框大小相同段长不同
页表记录页号、在内存中的页框号

段表记录段号、段长、在内存中的起始地址

用户只需提供助记符

即分页的地址空间是一维的。

用户需提供段名和段内地址

即分段的地址空间是二维的。

页是信息的物理单位。

分页由系统完成,对用户不可见

段是信息的逻辑单位。

分段对用户可见,用户显示给出段名

提高内存的空间利用率。

不会产生外部碎片,会产生少量内部碎片。

方便用户编程,方便信息共享和保护。会产生外部碎片。

注:只有纯代码/可重入代码可以共享(纯代码/可重入代码:不能修改的信息。不属于临界资源)

(2-3)段页式存储管理(分段和分页的结合)

  • 内存分成若干个大小相等的页框。
  • 程序按自身逻辑分段,各段再分成若干个大小相等的页面。页面大小与内存的页框大小相同。
  • 通过段表记录各段的各页面在内存中的地址。段表包括段号、页表长度、页表在内存中的起始地址。
  • 段表寄存器存放段表的起始地址F和段表长度M。进程未执行前,F和M存放在PCB中。
  • 一个进程对应一个段表,一个段表项对应一个段,一个段对应一个页表,一个页表项对应一个页面。

用户提供段名和段内地址,编译程序将段名转换为段号,系统将段内地址转化为页号和页内偏移量。

逻辑地址可拆分成:段号、页号、页内偏移量(又称页内地址)。段号的位数表示进程最多分多少段,页号的位数表示每个段最多有多少页面,页内偏移量的位数表示页面大小是多少或内存的页框大小是多少。

地址转换过程: 

  1. 根据逻辑地址,获得段号、页号、页内偏移量。
  2. 根据段表寄存器中的段表长度,判断逻辑地址中的段号是否越界,若段号\geq段表长度,则越界,发出越界中断。
  3. 根据段号和页号,在快表中查,若快表命中,直接获得页面在内存中的页框号,跳转到8。
  4. 若快表未命中,根据段表寄存器中的段表起始地址和逻辑地址中的段号,获得对应段表项。
  5. 根据段表项中的页表长度,判断逻辑地址中的页号是否越界,若页号\geq页表长度,则越界,发出越界中断。
  6. 根据段表项中的页表起始地址和逻辑地址中的页号,在页表中查询,获得对应页表项。
  7. 根据页表项中的页面在内存中的页框号和逻辑地址中的页内偏移量,获得实际的物理地址。
  8. 根据实际的物理地址,在内存获取相应的数据。

虚拟内存

(以请求分页存储管理为例)

在离散分配的基础上,物理上内存容量不变,逻辑上通过外存进行了扩充,使用户感觉内存容量比实际的大很多,就是虚拟内存。

传统存储的特征:一次性,驻留性。即程序一次性调入内存,并常驻内存,直到运行结束。

虚拟内存的特征:多次性,对换性,虚拟性。即程序存放在外存中,程序装入时,很快使用的页面先调入内存。程序运行时,用到的页面再调入内存;若内存空闲空间不够,通过一定置换算法,先将暂时用不到的页面从内存调出到外存,再将需要的页面调入内存。

虚拟内存需具备请求调页和页面置换功能。即需要的页面调入内存,空间不够时,不需要的页面调出到外存。

虚拟内存基于局部性原理。时间局部性:现在访问的信息将来可能仍访问。空间局部性:现在访问的信息附近的将来可能被访问。

地址转换过程

  1. 根据逻辑地址,获取页号和页内偏移量。
  2. 检查页号是否越界,若越界,发出越界中断。
  3. 在快表中查询,若快表命中,直接获得页面在内存中的起始地址。若快表未命中,在内存的页表中查询,根据页表项的状态位,判断页面是否调入内存,若已调入内存,获取页面在内存中的起始地址,并将页表项复制到快表。若未调入内存,发生缺页中断,系统进行中断处理(将页面从外存调入内存),获得页面在内存中的起始地址,修改页表项并将页表项复制到快表。
  4. 根据页面在内存中的起始地址和页内偏移量,得到实际的物理地址。
  5. 根据实际的物理地址,在内存获取相应的数据。
传统存储管理和虚拟内存的区别
传统存储管理虚拟内存

页表包括页号、在内存的地址。

页表包括页号、在内存中的地址、状态位(是否在内存)、访问字段(最近访问几次或上次访问时间,用于页面置换做参考)、修改位(调入内存后是否修改)、在外存中的地址。

需要缺页中断机构(需判断页面是否已在内存,若不在,则发生缺页中断,系统将页面从外存调入内存,有可能需要页面置换)。

缺页中断属于内中断。一条指令可能多次缺页中断。

页表项需要通过状态位检查页面是否在内存中;

若页面不在内存,需要请求调页;

若内存空间不够,需根据一定算法进行页面置换(将某页面从内存调出到外存,需要的页面调入内存);

页面调入内存后,需修改页表项,并将页表项复制到快表中。

页面分配策略

 驻留集:操作系统为进程分配的内存块的集合。

抖动/颠簸:分配的内存空间太小或者页面置换算法设计不当,会导致页面频繁调入调出。

工作集:某时间间隔里,进程实际被访问页面的集合。驻留集大小一般不能小于工作集大小。

页面分配、置换策略:

  • 固定分配局部置换:系统给进程分配的内存空间大小固定,缺页时进程在自己的内存区域进行页面置换。
  • 可变分配局部置换:系统给进程分配一定的内存空间,缺页时进程在自己的内存区域进行页面置换;系统检测到页面置换频繁或着缺页率低,将适当调整分配给进程的内存空间。
  • 可变分配全局置换:系统给进程分配一定的内存空间,缺页时系统将分配空闲内存空间,若没有空闲内存空间,将任意进程的未锁定页面调出到外存,再将需要的页面调入内存。

何时调入页面:

  • 预调页策略:进程运行前,进程首次调入时,由程序员指出调入部分,一次将若干个相邻的页面调入内存。
  • 请求调页策略:进程运行期间,发生缺页时将页面从外存调入到内存。

从何处调入页面:

  • 外存的对换区足够大:页面从外存的文件区复制到外存的对换区,在对换区和内存之间调入调出。
  • 外存的对换区不大:不会被修改的数据直接从文件区调入内存(不需要写回外存,下次需要再从文件区调入内存);会被修改的数据复制到对换区,在对换区和内存之间调入调出。
  • UNIX方式:第一次使用的页面都从文件区调入内存,调出的页面放入对换区,需要时再从对换区调入。

在外存和内存之间调入调出,需要启动I/O操作,将产生一定的系统开销。

缺页率 = 访问的页面不在内存的次数 / 访问页面总次数

为获取更大的虚拟地址空间,除了磁盘(硬盘),还会扩展到固态硬盘,甚至网络硬盘。

参考:虚拟存储

虚拟存储技术是内存容量扩充的一种方式。

内存保护

多道程序时,内存中存放多个进程,各个进程必须只能访问各自的内存区域,确保不会越界访问。

即本进程的内存区域:可读可写;非本进程的内存区域:不可读写;共享的内存区域:根据授权。

  • 方法1:重定位寄存器(又称基址寄存器)+界地址寄存器(又称限长寄存器)。分别存放进程在内存中的起始地址和最大逻辑地址。
  • 方法2:下限寄存器+上限寄存器。分别存放进程在内存中的起始地址和结束地址。

补充:

链接方式:静态链接、装入时动态链接、运行时动态链接。

  • 静态链接:程序装入内存前,就已经将各目标模块和相关的库函数链接成完整的可执行文件(装入模块),也就确定了完整的逻辑地址。链接完成后,装入模块再装入内存运行。
  • 装入时动态链接:程序在装入内存时,边装入边链接,形成完整的逻辑地址。链接完成后,已在内存。
  • 运行时动态链接:程序在运行时,使用到的模块装入内存并链接,没有用到的模块不用装入内存链接。链接完成后,已在内存。

装入方式:绝对装入、可重定位装入(又称静态重定位)、动态运行时装入(又称动态重定位)。

  • 绝对装入:单道程序系统,编译时就知道在内存的位置,编译程序将逻辑地址转为物理地址。装入程序按照装入模块中的地址将相关数据装入内存中。(装入模块中的地址已经是物理地址)
  • 可重定位装入:又称静态重定位。装入模块的地址从0开始,指令或数据的地址都是相对于起始地址的逻辑地址;装入内存时对地址进行重定位,一次将逻辑地址全部转为物理地址。(装入模块中的地址是逻辑地址,装入内存时转为物理地址。运行期间不能移动,不能再申请内存)
  • 动态运行时装入:又称动态重定位。装入模块的地址从0开始,指令或数据的地址都是相对于起始地址的逻辑地址;装入内存时依然是逻辑地址。需要重定位寄存器存放装入模块在内存中的起始地址。程序运行时,通过重定位寄存器中的起始地址和逻辑地址得到物理地址。(装入模块中的地址是逻辑地址,装入内存时依然是逻辑地址,运行时转为物理地址。内存地址可以不连续,运行期间可以移动)

程序放入内存运行时,系统会建立相应的进程。进程在内存中包括两部分:程序段(存放指令等)和数据段(存放变量等)。

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

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

相关文章

以太网基础学习(三)——UDP协议

一、UDP协议概述 UDP(User Datagram Protocol,用户数据报协议)是一种无连接协议,它不像TCP协议那样需要在发送和接收数据前进行握手和释放,而是直接把数据发送出去,也不会对数据进行可靠传输和流量…

ARM_汇编流水灯

ARM_汇编流水灯 .text .global _start _start: 设置GPIOE寄存器的时钟使能ldr r0,0x50000A28ldr r1,[r0] 从r0为起始地址的4字节数据取出存入r1orr r1,r1,#(0x01<<4) 第4位设置为1 表示开启时钟使能orr r1,r1,#(0x01<<5) 第5位设置为1 表示开启时钟使能str r1…

求推荐好用的可视化大屏软件?强推奥威BI

在博览中心、会议中心、监控中心等场合下&#xff0c;经常看到很多炫酷的企业可视化大屏&#xff0c;将复杂的企业数据可视化展现&#xff0c;高大上、实用性一个不缺。那&#xff0c;可视化大屏做得好的软件有哪些&#xff1f;首推奥威BI软件。 奥威BI软件&#xff1a;零编程…

ST表(RMQ问题)

ST表能够O(1)地解决区间[l,r]之间最值问题 1.建表&#xff0c;首先明白ST[i][j]&#xff0c;表示的是区间[i, i(1<<j)-1]的最值&#xff0c;区间大小为2^j。首先初始化ST[i][0]a[i]。 void init&#xff08;&#xff09;{for(int i1; i<n; i){ST[i][0]a[i];} } 因为…

如何配置防火墙?看这篇就够了

大家好&#xff0c;我是老杨。 在互联网时代&#xff0c;网络安全的问题不用多说了&#xff0c;配置防火墙是非常必要的。 在网络的世界里&#xff0c;要由防火墙过滤的就是承载通信数据的通信包。 防火墙是位于内部网和外部网之间的屏障&#xff0c;也是系统的第一道防线。…

06.数据解析-xpath

1、什么是xpath ​ XPath (XML Path Language) 是一门在 HTML\XML 文档中查找信息的语言&#xff0c;可用来在 HTML\XML 文档中对元素和属性进行遍历。 W3School官方文档&#xff1a;http://www.w3school.com.cn/xpath/index.asp 2、认识xml 知识点&#xff1a; html和xml…

如何使用 Xunit 框架进行单元测试和集成测试

在软件开发过程中&#xff0c;测试是至关重要的一环。测试驱动开发&#xff08;Test-Driven Development&#xff0c;TDD&#xff09;是一种常用的开发方法论&#xff0c;它强调在编写代码之前先编写测试用例&#xff0c;然后通过不断迭代的方式来实现功能。为了帮助开发者更好…

解决项目报错:@org.springframework.beans.factory.annotation.Autowired(required=true)

项目使用mybatis&#xff0c;启动时报错&#xff1a; Description: Field toolsDetailsService in com.cvit.applet.controller.ToolsDetailsController required a bean of type com.cvit.applet.mapper.ToolsDetailsMapper that could not be found. The injection point has…

上门按摩小程序|同城上门按摩软件开发|上门按摩系统;

上门按摩小程序的开发具有许多优势&#xff0c;下面就给大家介绍下按摩小程序功能: 上门按摩小程序的优势 方便快捷&#xff1a;上门按摩小程序提供在线预约服务&#xff0c;用户可以通过手机随时随地预约按摩师上门服务&#xff0c;避免了传统预约方式的繁琐和不确定性。 个性…

面向对象设计-UML六种箭头含义

目录 UML概述UML语义UML表示法 六种常用关系标识方法泛化实现依赖关联聚合组合 本文参考文章 https://blog.csdn.net/qq_25091281/article/details/123801862 UML概述 UML (Unified Modeling Language)为面向对象软件设计提供统一的、标准的、可视化的建模语言。适用于描述以…

Vue、js底层深入理解笔记

文章目录 1. Vue中列表组件的key值有什么作用&#xff1f;2. [1, 2, 3].map(parseInt)结果 1. Vue中列表组件的key值有什么作用&#xff1f; 这个是修改数组的情况下 还有增删的情况下 删除12&#xff0c;添加67 结果 带key的dom节点发生改变&#xff0c;内容未改变 不带key…

Linux: 基础IO

学习目标 1.C接口与系统调用接口的差别 2.文件描述符, 重定向, 一切皆文件, 缓冲区 3.fd与FILE, 系统调用和库函数的关系 4.系统中的inode 5.软硬链接 6.动静态库 预备知识 1.文件 内容 属性 2.文件的所有操作: a. 对内容的操作 b.对属性的操作 3.文件在磁盘(硬件)上, 我…

通过IP地址管理提升企业网络安全防御

在今天的数字时代&#xff0c;企业面临着越来越多的网络安全威胁。这些威胁可能来自各种来源&#xff0c;包括恶意软件、网络攻击和数据泄露。为了提高网络安全防御&#xff0c;企业需要采取一系列措施&#xff0c;其中IP地址管理是一个重要的方面 1. IP地址的基础知识 首先&a…

04训练——基于YOLO V8的自定义数据集训练——训练结果说明

YOLOv8的训练执行情况指标说明 运行YOLO V8的训练代码将会看到以下执行的情况。 在上图中,我们可以看到每一轮训练的指标情况,YOLOv8训练过程中的输出指标具体介绍如下: • Epoch: 当前的训练轮数,一轮表示所有的训练数据都被模型处理一次。例如,1/100表示第一轮训练,总…

高效截屏方法,你值得拥有!在Windows10中截屏的3种方法

本文介绍如何在Windows 10中捕获屏幕截图&#xff0c;包括使用键盘组合、使用Snipping Tool、Snipp&Sketch Tool或Windows游戏栏。 使用WindowsPrtSc组合键截图 在Windows 10中捕获屏幕截图的最简单方法是按下键盘上的PrtScWindows键盘组合。你将看到屏幕短暂闪烁&#x…

微信小程序发布流程

前言 上周写了如何写一个小程序&#xff0c;然后经过查资料&#xff0c;改bug&#xff0c;找chatgpt美化页面&#xff0c;我写了一个计算代谢率的小工具&#xff0c;写完了之后该怎么办呢&#xff0c;当然是发布上架&#xff0c;然后我就开始了发布的折腾 提交代码 这一步很…

线性表相关知识

1.简述 线性表&#xff0c;全名为线性存储结构。使用线性表存储数据的方式可以这样理解&#xff0c;即“把所有数据按照顺序&#xff08;线性&#xff09;的存储结构方式&#xff0c;存储在物理空间”。 按照空间分类&#xff1a; 顺序存储结构&#xff1a;数据依次存储在连续…

可爱的回调函数

目录 一、作者声明&#xff1a; 二、什么回调函数&#xff1f; 三、库函数qsort为例&#xff0c;讲解回调函数 一、作者声明&#xff1a; 标题中的可爱纯纯是用来凑字数&#xff0c;没有特殊含义&#xff0c;因为可爱的平台不让用四个字作为标题&#xff01; 如果平台允许我…

上海未来产业创投联盟启动成立,和鲸Heywhale成为首批发起单位

第三届“海聚英才”全球创新创业峰会于近期举办&#xff0c;会上正式启动成立“上海未来产业创投联盟”&#xff0c;上海和今信息科技有限公司等 31 家单位成为首批发起单位。 为进一步坚定产业投资信心&#xff0c;营造最优人才生态&#xff0c;9月20日下午&#xff0c;第三届…

mstp vrrp bfd 实验

LSW1配置 <Huawei>sys Enter system view, return user view with CtrlZ. [Huawei]sys lsw1 [lsw1]vlan batch 10 20 30 [lsw1]int g0/0/1 [lsw1-GigabitEthernet0/0/1]port link-type access [lsw1-GigabitEthernet0/0/1]port default vlan 10 [lsw1-GigabitEthernet0…