《深入理解计算机系统(CSAPP)》第9章虚拟内存 - 学习笔记

写在前面的话:此系列文章为笔者学习CSAPP时的个人笔记,分享出来与大家学习交流,目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记,在复习回看时发现部分内容存在一些小问题,因时间紧张来不及再次整理总结,希望读者理解。


《深入理解计算机系统(CSAPP)》第3章 程序的机器级表示 - 学习笔记_友人帐_的博客-CSDN博客

《深入理解计算机系统(CSAPP)》第5章 优化程序性能 - 学习笔记_友人帐_的博客-CSDN博客

《深入理解计算机系统(CSAPP)》第6章 存储器层次结构 - 学习笔记_友人帐_的博客-CSDN博客

《深入理解计算机系统(CSAPP)》第7章 链接- 学习笔记_友人帐_的博客-CSDN博客

《深入理解计算机系统(CSAPP)》第8章 异常控制流 - 学习笔记_友人帐_的博客-CSDN博客

《深入理解计算机系统(CSAPP)》第9章虚拟内存 - 学习笔记_友人帐_的博客-CSDN博客


第九章 虚拟内存

在这里插入图片描述

内存管理单元(Memory Management Unit, MMU):专用硬件,利用存放在主存中的查询表来动态翻译虚拟地址,该表的内容由操作系统管理。

1. 地址空间

  • 地址空间(address space):一个非负整数地址的有序集合:{0, 1, 2, …}

  • 线性地址空间(linear address space):地址空间中的整数是连续的,则称为线性地址空间

  • 物理地址空间(physical address sapce): M = 2 m M=2^m M=2m个物理地址的集合{0, 1, 2, 3, …, M-1}

  • 虚拟地址空间(virtual address space): N = 2 n N=2^n N=2n个虚拟地址的集合{0, 1, 2, 3,…, N-1}

虚拟地址的思想:允许每个数据对象有多个独立的地址,其中每个地址都选自一个不同的地址空间。

为什么要使用虚拟内存Virtual Memory(VM)?

  • 有效使用主存:使用DRAM作为部分虚拟地址空间的缓存
  • 简化内存管理:每个进程都使用统一的线性地址空间
  • 独立地址空间:个进程不能影响其他进程的内存;用户程序无法获取特权内核信息和代码

2. 虚拟内存作为缓存的工具

虚拟内存:存放在磁盘上、有N个连续字节的数组。

磁盘上这个数组的内容被缓存在物理内存中(DRAM cache),缓存块被称为页(页面大小为 P = 2 p P=2^p P=2p)。

虚拟页分类:

  • 未分配的:VM系统还未分配(或者创建)的页。未分配的块没有任何数据和它们相关联,因此也就不占用任何磁盘空间。
  • 缓存的:当前已缓存在物理内存中的已分配页。
  • 未缓存的:未缓存在物理内存中的已分配页。

在这里插入图片描述

2.1 DRAM缓存的组织结构

DRAM若不命中,会产生巨大的不命中开销,因此采用:

  • 大的虚拟页面。标准4KB,可达到4MB/页。
  • DRAM缓存使用全相联映射:任何虚拟页都可以放置在任何物理页中。
  • 不命中时使用了更复杂精密的替换算法。
  • DRAM缓存使用写回法(磁盘访问时间长)。

2.2 页表(Page Table, PT)

存放**页表条目(Page Table Entry, PTE)**的数组,将虚拟页地址映射到物理页地址。DRAM中的每个进程都有自己的页表。

在这里插入图片描述

  • 如果设置了有效位,那么地址字段就表示DRAM中相应的物理页的起始位置,这个物理页中缓存了该虚拟页。
  • 如果没有设置有效位,
    • 那么一个空地址表示这个虚拟页还未被分配。
    • 否则,这个地址就指向该虚拟页在磁盘上的起始位置。

2.3 页命中

要访问的虚拟内存中的内容存在于物理内存中,即DRAM缓存命中。

2.4 缺页

DRAM缓存不命中称为缺页(page fault)。

缺页处理:

在这里插入图片描述

以访问VP3,选择VP4作为牺牲页为例:

  1. CPU引用了VP3中的一个字,地址翻译硬件从内存中读取PTE3,有效位为0推断出VP3未被缓存,并且触发一个缺页异常

  2. 缺页异常调用内核中的缺页异常处理程序,该程序会选择一个牺牲页,在此例中就是存放在PP3中的VP4。如果VP4已经被修改了,那么内核就会将它复制回磁盘。接着内核将VP4的页表条目有效位置0。

  3. 接下来,内核从磁盘复制VP3到内存中的PP3,更新PTE3,随后异常处理程序返回,重新执行导致缺页的指令,然后页命中。

使用按需页面调度:只有当不命中时,才换入页面。

2.5 分配页面

内核在磁盘上分配一个新的虚拟内存页,并且将某个PTE指向这个新的位置(该虚拟页在磁盘上的起始位置)。

仅是分配,未载入内存,有效位是0。
在这里插入图片描述

2.6 虚拟内存效率高的原因

尽管在整个运行过程中程序引用的不同页面的总数可能超出物理内存总的大小,但是局部性原则保证了在任意时刻,程序将趋向于在一个较小的活动页面(active page)集合上工作,这个集合叫做工作集(working set)或者常驻集合(resident set)。在初始开销,也就是将工作集页面调度到内存中之后,接下来对这个工作集的引用将导致命中,而不会产生额外的磁盘流量。

如果工作集的大小超出了物理内存的大小,这时页面将不断地换进换出,叫做抖动(thrashing),性能暴跌。

3. 虚拟内存作为内存管理的工具

核心思想:每个进程都拥有一个独立的虚拟地址空间。

页表将虚拟地址映射到物理地址,多个虚拟页面可以映射到同一个共享物理页面上。

在这里插入图片描述

  • 简化链接

独立的地址空间允许每个进程的内存映像使用相同的基本格式,而不管代码和数据实际存放在物理内存的何处(结构一致)。

在这里插入图片描述

  • 简化加载

使向内存中加载可执行文件和共享对象文件更容易。

要把目标文件中.text和.data节加载到一个新创建的进程中,Linux加载器为代码和数据段分配虚拟页,把它们标记为无效的(即未被缓存的),将页表条目指向目标文件中适当的位置。

加载器从不从磁盘到内存实际复制任何数据。而是在每个页初次被引用时,由虚拟内存系统会按照需要自动地调入数据页。

  • 简化共享

将不同进程中适当的虚拟页面映射到相同的物理页面,使得进程共享代码和数据,而不必在各进程私有区域内重复复制。

在这里插入图片描述

  • 简化内存分配

当一个运行在用户进程中的程序要求额外的堆空间时(如调用ma1loc的结果),操作系统分配适当多个连续的虚拟内存页面,并且将它们映射到物理内存中任意位置的物理页面。

4. 虚拟内存作为内存保护的工具

通过在PTE上扩展许可位以对访问控制做权限限制。
在这里插入图片描述

(内核模式才可访问;可读;可写;可执行)

内存管理单元(MMU)每次访问数据都要检查许可位。如果一条指令违反了这些许可条件,那么CPU就触发一个一般保护故障,将控制传递给一个内核中的异常处理程序。Linux shell一般将这种异常报告为"段错误(segmentation fault)"。

5. 地址翻译

地址翻译就是由一个虚拟地址A获得其物理地址(DRAM)的过程。若结果未空,则说明虚拟地址A是无效的地址,或其对应的内容存储在磁盘上。

在这里插入图片描述

5.1 基于页表的地址翻译

在这里插入图片描述

  • 页表基址寄存器CR3(Page Table Base Register, PTBR):CR3控制寄存器指向第一级页表(L1)的起始位置。CR3的值是每个进程上下文的一部分,每次上下文切换时,CR3的值都会被恢复。
  • 由VPN在页表中匹配PTE,获取PPN,与页偏移量PO拼接得到物理地址。
  • VPO与PPO是相同的。

(1)页面命中时硬件执行步骤:

第1步:处理器生成一个虚拟地址,并把它传送给MMU。

第2步:MMU生成PTE地址(PTEA),并从高速缓存/主存请求得到PTE。

第3步:高速缓存/主存向MMU返回PTE。

第4步:MMU构造物理地址,并把它传送给高速缓存/主存。

第5步:高速缓存/主存返回所请求的数据字给处理器。

在这里插入图片描述

  • 整个过程完全由硬件处理。
  • 需要访存两次(在高速缓存/主存中获取PTE以构造虚拟地址、由物理地址在高速缓存/主存找数据)。

(2)缺页异常时执行步骤:

第1步:处理器生成一个虚拟地址,并将其传送给MMU。

第2步:MMU生成PTE地址(PTEA),并从高速缓存/主存请求得到PTE。

第3步:高速缓存/主存向MMU返回PTE。

第4步:PTE中的有效位是零,所以MMU触发缺页异常,传递CPU中的控制到操作系统内核中的缺页异常处理程序。

第5步:缺页处理程序确定出物理内存中的牺牲页,如果这个页面已经被修改了,则把它换出到磁盘。

第6步:缺页处理程序页面调入新的页面,并更新内存中的PTE。

第7步:缺页处理程序返回到原来的进程,再次执行导致缺页的指令。
在这里插入图片描述

  • 由硬件、OS内核协作完成。
  • 2x2次访存,(1次内存写入磁盘+1次磁盘写入内存)。

5.2 结合高速缓存和虚拟内存

在这里插入图片描述

高速缓存采用物理寻址,多个进程同时在高速缓存中有存储块和共享来自相同虚拟页面的块。

注意,页表条目可以缓存,就像其他的数据字一样。

5.3 利用快表TLB加速地址翻译

后备缓冲器(Translation Lookaside Buffer, TLB)。

目的:为了减少寻找PTE的开销。

TLB是MMU中一个小的、具有高相联度的缓存,实现虚拟页号VPN向物理页号PPN的映射,页数很少的页表可以完全放在TLB中。

在这里插入图片描述

(1)访问TLB

TLB的每行都保存着一个由单个PTE组成的块。MMU使用虚拟地址的VPN部分来访问TLB:将VPN划分为TLB的组选择和行匹配的标记字段。

在这里插入图片描述

(2)TLB的命中与不命中操作

在这里插入图片描述

注意:不命中时MMU从L1缓存中取出相应的PTE,并同时存放在TLB中、提供给MMU。

5.4 多级页表

目的:压缩页表的大小。

思想:虚拟地址空间中每个虚拟页不一定全部都分配,也即都还未被使用,也就没必要保存一条PTE在页表中占用空间。

(1)二级页表示例

  • **基本情况:**假设32位虚拟地址空间被分为4KB的页,每个页表条目都是4字节。分配情况:内存的前2K个页面分配给了代码和数据,接下来的6K个页面还未分配,再接下来的1023个页面也未分配,接下来的1个页面分配给了用户栈。

**使用一级页表:**需要有 2 32 2 12 = 2 20 = 1 M \frac{2^{32}}{2^{12}}=2^{20}=1M 212232=220=1M个PTE。

使用二级页表:

一级页表中的每个PTE负责映射虚拟地址空间中一个4MB的片(chunk),这里每一片都是由1024个连续的页面组成的。一级页表中仅需要1K个PTE。

如果片 i i i中的每个页面都未被分配,那么一级 P T E i PTE_i PTEi就为空。如果在片 i i i中至少有一个页是分配了的,那么一级 P T E i PTE_i PTEi就指向一个二级页表的基址。二级页表中的每个PTE都负责映射一个4KB的虚拟内存页面。
在这里插入图片描述

  • 为什么二级页表可以减少内存要求:

①如果一级页表中的一个PTE是空的,那么相应的二级页表就根本不会存在。

②只有一级页表才需要总是在主存中(因为使用最频繁);虚拟内存系统可以在需要时创建、页面调入或调出二级页表,这就减少了主存的压力;只有最经常使用的二级页表才需要缓存在主存中。

(2)K级页表的地址翻译

  • 虚拟地址被划分成为k个VPN和1个VPO,每个 V P N i VPN_i VPNi都是一个到第 i i i级页表的索引。

  • 前k-1级页表中的每个PT都指向下一级的某个页表的基址。

  • 第k级页表中的每个PTE包含某个物理页面的PPN,或者一个磁盘块的地址。

为了构造物理地址,在能够确定PPN之前,MMU必须访问k个PTE。对于只有一级的页表结构,PPO和VPO是相同的。

在这里插入图片描述

通过将不同层次上页表的PTE缓存起来,带多级页表的地址翻译并不比单级页表慢很多。

5.5 一个端到端的地址翻译示例

(1)基本假设

  • 内存是按字节寻址的。
  • 虚拟地址是14位长的(n=14)。
  • 物理地址是12位长的(m=12)。
  • 页面大小是64字节(P=64)。
  • TLB是四路组相联的,总共有16个条目。
  • L1d-cache是物理寻址、直接映射的,行大小为4字节,而总共有16个组。

(2)虚拟地址和物理地址的格式

每个页面大小为64B,需要6位地址做页内偏移量。故低6位为VPO、PPO,其余的作为VPN和PPN。

在这里插入图片描述

(3)TLB的格式

TLB是四路组相联的,总共有16个条目。故共有4组,需要2位作为组索引TLBI,其余作为标记TLBT。

(TLB是利用VPN的位进行虚拟寻址的)
在这里插入图片描述

(4)页表格式

采用单级页表。共需要 2 14 2 6 = 2 8 = 256 \frac{2^{14}}{2^{6}}=2^{8}=256 26214=28=256条PTE(虚拟页面大小/页面大小)

使用VPN来进行标识,VPN并不是页表的一部分,也不存储在内存中。

在这里插入图片描述

(5)Cache格式

由每行4字节,需要块内偏移量2位;

直接映射(1行就是1组),共16个组,需要4位组索引。

使用物理地址寻址。

在这里插入图片描述

(6)读取示例

  1. TLB读取命中示例

假设CPU读取0x03d4处的1个字节:

  • CPU给出的即虚拟地址,故写出VPN和VPO,在VPN中划分出TLBT和TLBI:

在这里插入图片描述

  • 先上TLB中去寻找第0x3组中有无标记为0x03的块,发现有且valid为1。故此时TLB命中,不存在缺页故障,找到PPN为0x0D

  • MMU将来自PTE的PPN和来自虚拟地址的VPO连接起来,形成物理地址0x354。

  • MMU将物理地址发给高速缓存L1,缓存从物理地址中划分出块内偏移CO(0x0)、组索引CI(0x5)和缓存表及CT(0x0D)。在Cache中找到对应块,且valid有效,读出在偏移量CO处的数据字节0x36返回给MMU,由MMU传递给CPU。

  1. TLB不命中示例

如果TLB不命中,那么MMU必须从页表中的PTE中取出PPN。如果得到的PTE是无效的,那么就产生一个缺页,内核必须调入合适的页面,重新运行这条加载指令。

  1. TLB命中但是Cache不命中

另一种可能性是PTE是有效的,但是所需要的内存块在缓存中不命中。

6. Core i7/Linux内存系统

6.1 虚拟内存系统

(1)四级页表层次结构

在这里插入图片描述

(2)地址翻译概况

在这里插入图片描述

为了简化,没有显示i-cache、i-TLB和L2统一TLB。

(3)各级页表中条目格式

第1~3级

每个条目引用一个4KB子页表。注意PS位

当P=1时:地址字段包含一个40位,对于的下一级页表的基地址。

当P=0时:前面保存的都是磁盘上的页表位置。
在这里插入图片描述
在这里插入图片描述

第4级

注意D位

P=1时:地址字段包括一个40位PPN,指向物理内存中某一页的基地址。

当P=0时:前面保存的都是磁盘上的页表位置。

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

(4)页表翻译过程

当MMU翻译每一个虚拟地址时:

  • 每次访问一个页时,MMU都会设置A位,称为引用位(reference bit)。内核可以用这个引用位来实现它的页替换算法。
  • 每次对一个页进行了写之后,MMU都会设置D位,又称修改位或脏位(dirty bit)。修改位告诉内核在复制替换页之前是否必须写回牺牲页
  • 内核可以通过调用一条特殊的内核模式指令来清除引用位或修改位。

下图给出了Core i7MMU如何使用四级的页表来将虚拟地址翻译成物理地址。

36位VPN被划分成四个9位的片,每个片被用作到一个页表的偏移量。CR3寄存器包含L1页表的物理地址。VPN1提供到一个L1PET的偏移量,这个PTE包含L2页表的基地址。VPN2提供到一个L2PTE的偏移量,以此类推。

在这里插入图片描述

6.2 单个进程的虚拟地址空间

在这里插入图片描述

物理内存:方便内核访问物理内存中任何特定的位置。

(1)Linux虚拟内存区域

在这里插入图片描述

任务结构中的一个条目指向mm_struct,它描述了虚拟内存的当前状态:

  • pgd指向第一级页表(页全局目录)的基址;
  • mmap指向一个vm_area_structs(区域结构)的链表,其中每个vm_area_structs都描述了当前虚拟地址空间的一个区域。当内核运行这个进程时,就将pgd存放在CR3控制寄存器中。

其中,每个vm_area_structs包含:

  • vm_start:指向这个区域的起始处。
  • vm_end:指向这个区域的结束处。
  • vm_prot:描述这个区域内包含的所有页的读写许可权限。
  • vm_flags:描述这个区域内的页面是与其他进程共享的,还是这个进程私有的(还描述了其他一些信息)。
  • vm_next:指向链表中下一个区域结构。

(2)Linux缺页异常处理

缺页处理程序检查:

  • 地址是否合法?搜索区域链表,确认地址在(合法的某个区域内?否则,非法->段错误
  • 访问是否合法?有读、写或执行区域内页面的权限。否则,违反许可,触发保护异常->段错误

在这里插入图片描述

7. 内存映射

Linux通过将一个虚拟内存区域与一个磁盘上的对象(object)关联起来,以初始化这个虚拟内存区域的内容,这个过程称为内存映射(memory mapping)。

虚拟内存区域可以映射到两种类型的对象中的一种:

  • 磁盘上的普通文件(eg,一个可执行目标文件)
    • 文件区被分成页大小的片,对虚拟页面初始化
  • 匿名文件(内核创建,全是二进制零)
    • 首次访问该区域的虚拟页会引发缺页异常->分配一个全零的物理页(demand-zero pagei请求二进制零的页)
    • 一旦该页面被修改,即和其他页面一样

无论在哪种情况中,一旦一个虚拟页面被初始化了,它就在一个由内核维护的专门的交换文件(swap file),之间换来换去。交换文件也叫做交换空间(swap space)或者交换区域。

7.1 再看共享对象

两个进程映射了同一个共享对象,两个进程的虚拟地址可以是不同的:

在这里插入图片描述

对于每个映射私有对象的进程,相应私有区域的页表条目都被标记为只读,并且区域结构被标记为私有的写时复制。只要没有进程试图写它自己的私有区域,它们就可以继续共享物理内存中对象的一个单独副本。

然而,只要有一个进程试图写私有区域内的某个页面,那么这个写操作就会触发一个保护故障。当故障处理程序注意到保护异常是由于进程试图写私有的写时复制区域中的一个页面而引起的,它就会在物理内存中创建这个页面的一个新副本,更新页表条目指向这个新的副本,然后恢复这个页面的可写权限,当故障处理程序返回时,CPU重新执行这个写操作,现在在新创建的页面上这个写操作就可以正常执行了。

在这里插入图片描述

7.2 再看fork函数

当fork函数被当前进程调用时,内核为新进程创建各种数据结构,并分配给它一个唯一的PID。

为了给这个新进程创建虚拟内存,它创建了当前进程的mm_struct、区域结构和页表的原样副本。它将两个进程中的每个页面都标记为只读,并将两个进程中的每个区域结构都标记为私有的写时复制

当fork在新进程中返回时,新进程现在的虚拟内存刚好和调用fork时存在的虚拟内存相同。

当这两个进程中的任一个后来进行写操作时,写时复制机制就会创建新页面,因此,也就为每个进程保持了私有地址空间的抽象概念。

即:

  • 完全copy,标为只读,也使得能够共享虚拟内存对应的物理空间
  • 写操作时,写时复制机制就会创建新页面,保持了每个进程的私有地址空间

7.3 再看execve函数

假设调用execve("a.out", NULL, NULL)

execve函数在当前进程中加载并运行包含在可执行目标文件a.out中的程序,用a.out程序有效地替代了当前程序。加载并运行a.out需要以下几个步骤:

  • 删除当前进程虚拟地址的用户部分中的已存在的区域结构(页表、结构体、vm_area_strcut链表)。
  • 映射私有区域(创建自己的新的区域结构)。为新程序的代码、数据、bss和栈区域创建新的区域结构,所有这些新的区域都是私有的、写时复制的。
    • 代码和数据区域被映射为a.out文件中的.text和.data区。
    • bss区域是请求二进制零的,映射到匿名文件,其大小包含在a.out中。
    • 栈和堆区域也是请求二进制零的,初始长度为零。
  • 映射共享区域。将共享对象动态链接到这个程序,然后再映射到用户虚拟地址空间中的共享区域内。
  • 设置程序计数器(PC)。设置当前进程上下文中的PC,使之指向代码区域的入口点。

7.4 使用mmap函数的用户级内存映射

Linux进程可以使用rmap函数来创建新的虚拟内存区域,并将对象映射到这些区域中。

void *mmap(void *start, int len, int prot, int flags, int fd, int offset)

从fd指定磁盘文件的offset处,映射len个字节到一个新创建的虚拟内存区域,该区域从地址stat处开始。

  • start:虚拟内存的起始地址,通常定义为NULL
  • prot:虚拟内存区域的访问权限
    • PROT_READ(可读)
    • PROT_WRITE(可写)
    • PROT_EXEC(可执行)
    • PROT_NONE(不能被访问)
  • flags:被映射对象的类型
    • MAP_ANON(匿名对象)
    • MAP_PRIVATE(私有的写时复制对象)
    • MAP_SHARED(共享对象)
  • 返回值:指向映射区域开始处的指针

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库基础——3.SQL概述及规范

这篇文章我们来讲一下SQL概述和使用规范 目录 1.SQL概述 1.1SQL背景 1.2 SQL语言排行榜 1.3 SQL分类 2.SQL规则与规范 2.1基本规则 2.2 SQL大小写规范 (建议遵守) 2.3 注 释 2.4 命名规则(暂时了解) 2.5 数据导入指令 1…

Linux 实操篇-网络配置

Linux 实操篇-网络配置 Linux 网络配置原理图 查看网络IP 和网关 查看虚拟网络编辑器和修改IP 地址 查看网关 查看windows 环境的中VMnet8 网络配置(ipconfig 指令) 查看linux 的网络配置ifconfig ping 测试主机之间网络连通性 基本语法 ping 目的主机(功能描述…

交换机安全功能介绍

今天海翎光电的小编来给大家聊聊以太网交换机安全功能。 交换机作为局域网中最常见的设备,在安全上面临着重大威胁,这些威胁有的是针对交换机管理上的漏洞,攻击者试图控制交换机。有的针对的是交换机的功能,攻击者试图扰乱交换机的…

使用curl命令传输数据

文章目录 一、curl命令二、举例和注意事项Reference 一、curl命令 curl是传输数据的命令行工具,可以通过命令行发送HTTP请求和接收HTTP响应。它的名字是“client for URLs”,意为URL的客户端,表示该工具主要用于处理URL相关的任务。curl可以…

vue实现深拷贝的方法

在 vue中,深拷贝是一个很有用的功能,在不改变原来对象状态的情况下,进行对象的复制。 但要实现深拷贝,需要两个对象具有相同的属性。如果两个对象不同,深拷贝也不能实现。 1.我们将变量A的属性赋给变量B,但…

软件测试之自动化测试【webdriver API】

目录 一、webdriver API 1.元素的定位 2.操作测试对象 3.添加等待 3.1 sleep 强制等待 3.2 隐式等待 3.3 显式等待 4.打印信息 5.浏览器的操作 5.1 浏览器的前进和后退 5.2 浏览器滚动条操作 5.3 浏览器最大化及设置浏览器宽、高 6.键盘按键 7. 鼠标事件 8.定位…

12-Vue技术栈之Vuex的使用

目录 1、理解 vuex1.1 vuex 是什么1.2 什么时候使用 Vue1.3 图解两种方式实现数据共享 2、搭建vuex环境2.1 下载vuex2.2 配置文件 3、基本使用3.1 求和案例纯vue写法3.2 求和案例vuex写法 4、getters的使用5、四个map方法的使用5.1 求和案例 6、 模块化命名空间6.1求和案例改造…

linux网络设置

文章目录 一、查看网络配置1.查看网络接口信息——ifconfig1.1查看所有本机的网络的网络设备1.2设置网络接口参数1.3对指定的设备开启或关闭 2.查看主机名称——hostname2.1查看或临时设置当前主机名2.2永久设置主机名 3.查看路由表条目——route3.1查看当前主机路由表3.2添加路…

Redis入门到实战笔记-数据类型

这里写目录标题 SQL与NoSQL关系型数据库:查询方式: 非关联数据库:查询方式: 总结 认识RedisRedis安装远程连接防火墙设置关闭防火墙开启防火墙检查防火墙状态开放指定端口 Redis数据类型和常见命令keysdelEXISTexpired&#xff0c…

C++——多态与虚表

目录 1.多态的实现 2.虚表 2.1虚函数重写是怎么实现的 2.2多态的原理 2.3静态绑定与动态绑定 3.单继承体系中的虚函数表 ​编辑4.多继承体系中的虚函数表 5.菱形继承的虚函数表 6.菱形虚拟继承的虚函数表 1.多态的实现 在C中,要想实现多态,必…

Metasploit超详细安装及使用教程(图文版)

通过本篇文章,我们将会学习以下内容: 1、在Windows上安装Metasploit 2、在Linux和MacOS上安装Metasploit 3、在Kali Linux中使用 Metasploit 4、升级Kali Linux 5、使用虚拟化软件构建渗透测试实验环境 6、配置SSH连接 7、使用SSH连接Kali 8、配…

Ansible基础6——文件模块、jinja2模板

文章目录 一、常用文件模块1.1 blockinfile模块1.2 file模块1.2.1 创建文件并赋予权限1.2.2 创建目录并赋予权限1.2.3 创建软连接1.2.4 删除文件或目录 1.3 fetch模块1.4 lineinfile模块1.5 stat模块1.6 synchronize模块 二、jinja2模板2.1 构建jinja2模板2.2 管理jinja2模板2.…

MAYLAND HOME官网上线 | LTD家居家装行业案例分享

​一、公司介绍 在MAYLAND HOME,我们为我们对质量和服务的承诺感到自豪。我们相信我们的成功与客户的满意度直接相关,这就是为什么我们努力超越您的期望,我们承担的每一个项目。无论您是想升级您的家庭还是企业,我们都会在这里帮助…

冈萨雷斯DIP第5章知识点

图像增强:主要是一种 主观处理,而图像复原很大程度上是一种 客观处理。 5.1 图像退化/复原处理的一个模型 如图5.1 本章把图像退化建模为一个算子 H \mathcal{H} H 该算子 与一个加性噪声项 η ( x , y ) η(x,y) η(x,y) 共同对输入图像 f ( x , y…

MKS SERVO4257D 闭环步进电机_系列2 菜单说明

第1部分 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口和RS485/CAN串行接口,支持MODBUS-RTU通讯协议,内置高效FOC矢量算法,采用高精度编码器,通过位置反馈&am…

开源情报搜集系统的核心技术

随着科技快速发展,科研方向的开源情报搜集系统的应用越来越广泛。为了满足科研工作者的需求,开发人员大力研发了许多功能强大的科研开源情报系统。这些系统不仅可以帮助科研人员更加高效地获取、管理和利用科研信息资源,还能为他们提供全方位…

原来CSS的登录界面可以变得这么好看

个人名片: 😊作者简介:一名大一在校生,web前端开发专业 🤡 个人主页:几何小超 🐼座右铭:懒惰受到的惩罚不仅仅是自己的失败,还有别人的成功。 🎅**学习目…

Sequelize:Node.js 中的强大 ORM 框架

❤️砥砺前行,不负余光,永远在路上❤️ 目录 前言优势:提高效率,不用SQL即可完成数据库操作。 那什么是 Sequelize?主要特性:1、模型定义和映射:2、关联和联接:3、事务管理&#xff…

【网络协议详解】——DNS系统协议(学习笔记)

目录 🕒 1. DNS的作用🕒 2. 域名结构🕒 3. 域名分类🕒 4. 域名空间🕒 5. 域名服务器类型🕘 5.1 根域名服务器🕘 5.2 顶级域名服务器🕘 5.3 权限域名服务器🕘 5.4 本地域名…

英睿达内存条正品鉴别教程(镁光颗粒)

我们打算买一款二手镁光颗粒的英睿达内存条,需要从正面内存标签上的条形码、字串,从背面颗粒上的两行字符一一分析、检查、鉴别,最终确认是否正品,以及内存条等级如何。通过本片文章,您能学会如何进行镁光颗粒的英睿达内存条正品鉴别。 一、标签检查 首先,用百度条形码…