计算虚拟化3——I/O设备虚拟化

news2025/1/19 2:43:05

目录

I/O基本概念

I/O设备与CPU连接图

CPU与I/O设备的交互

访问I/O设备(IO Access)

数据传输(Data Tronhsfer)

I/O设备虚拟化技术

软件辅助全虚拟化

半虚拟化

Virtio协议基本概念

Virtqueue讲解

硬件辅助全虚拟化

I/O直通方式

SR-IOV方式


I/O基本概念

什么是I/O设备

I/O就是输入输出,而I/O设备就是可以将数据输入到计算机,或者将计算机的数据输出到其他设备,属于计算机的硬件设备

I/O设备具体使用什么类型的数据、做什么事情取决于I/O设备本身的功能,不同功能的I/O设备传输数据可能不同(例如:磁盘会将数据持久化、网卡会将数据转发到其它主机)

I/O设备的分类

存储I/O设备(块设备-可以寻址)

也称外存,用来存储设信息

例如:硬盘、光盘、U盘等

人机交互设备(字符设备-不可寻址)

主要就是实现用户与计算机系统之间的通信

在输入输出时通常采用中断驱动的方式

例如:打印机、键盘鼠标等

网络通信设备

主要用于与远程设备进行通信

例如:网卡、调制解调器等

I/O设备与CPU连接图

通常I/O设备并不会直接与CPU进行通信,而是依靠设备控制器通信来实现通信(设备控制器位于计算机本身内部,集成在主板上,包含一些寄存器)

设备控制器的作用

接收设备的CPU指令(CPU的读写指令和参数存储在控制寄存器中)

向CPU报告设备的状态(状态寄存器记录I/O设备的当前状态)

进行数据交换(通过数据寄存器暂存CPU发来的数据和IO设备发来的数据,之后将数据发送给控制寄存器或CPU)

地址识别(通过可寻址存储或队列根据CPU提供的地址来判断CPU要读取的是哪个IO设备)


CPU与I/O设备的交互

在一次完整的CPU与IO设备的交互中,有三个重要的部分

CPU访问I/O设备,CPU与I/O设备进行数据交换,I/O设备将结果返回给CPU

访问I/O设备(IO Access)

访问I/O设备目前主要有两种方式PMIO和MMIO

设备控制器上有一组IO寄存器, CPU通过访问IO寄存器就可以对IO设备进行相应的操作

两种不同的方式其区别就是找到IO寄存器的方式不同

PMIO端口映射IO(Port Mapped IO)

将I/O设备独立看待,使用CPU提供的专用I/O指令访问I/O设备

设备控制器的寄存器上映射了一组IO端口(这些IO端口存储在设备控制器中,不占用内存地址),CPU就可以通过一些特殊的指令来访问这些端口,从而达到访问IO寄存器的效果,最后达到对IO设备进行操作的目的

优点:使用专门的IO指令对端口进行操作,IO指令短,执行速度快

缺点:CPU需要设计单独的指令,实现复杂;不能使用通用的内存访问指令操作

MIMI内存映射IO(Memory Mapped IO)

物理内存和I/O设备共享物理内存地址空间,直接访问内存地址访问I/O设备

将设备控制器上寄存器映射的一组IO端口映射为一些特殊的内存地址,CPU只需要访问这些特殊的内存地址的话则可以达到访问IO端口的效果,也就对设备进行了操作(操作系统内部也不需要执行特殊的指令,而只需要像正常的操作一样访问特殊的内存地址即可对IO设备进行操作)

后续衍生出了PCI设备

PCI设备及其衍生的接口(如PCIE)主要服务于高速I/O设备-网卡和显卡等

计算机既要访问设备管理器的寄存器,也要访问它们的内存

数据传输(Data Tronhsfer)

数据传输目前主要有三种实现方式:传统的标准传输、引入中断的传输、DMA传输

传统的标准交互(程序直接控制的方式)

CPU通过发送IO指令来进行数据传输(以读取数据为例)

CPU通过PMIO或MMIO获得IO设备对应的状态寄存器,然后读取I/O设备的状态,如果是忙碌状态就继续轮询检查状态,如果是空闲状态,则从中数据寄存器中读取数据到CPU中;读到CPU后CPU还需要往内存中写入数据,写完后在执行下一套指令

优点:实现简单

缺点:CPU和I/O设备只能串行化工作,CPU要一直轮巡检查,长期处于忙等的低效状态中

中断驱动的方式

通过允许I/O设备主动打断CPU的运行并请求服务来解放CPU(以读取数据为例)

CPU通过PMIO或MMIO获得IO设备对应的状态寄存器,然后读取I/O设备的状态,如果是忙碌状态则CPU先做自己的任务,当IO设备空闲时便发出中断请求信号,CPU感知到中断后就会把当前正在进行任务的相关计算数据保存下来,优先完成对I/O设备的处理,然后CPU将读取的数据在存入到内存中

优点:CPU和I/O设备可以并行工作,CPU利用率得到提升

缺点:数据在硬件中的移动是通过CPU完成的,仍然会消耗较多的CPU时间

直接存储方式DMA(Direct Memory Access)

以上两种方式,数据在硬件中的移动是通过CPU完成的(CPU读取数据时先得到数据,然后再由CPU存入内存;I/O设备读取数据时也是由CPU作为中间人)

DMA的数据流向是从IO设备直接放入内存,或从内存直接到IO设备,不需要使用CPU作为中间者,直接将CPU从I/O任务中解脱出来

多了DMA控制器模块,CPU将需要读取数据告诉DMA控制器(想要读取数据的那一块,然后把数据读到哪个内存的哪个地址),然后DMA控制器就代替CPU和设备控制器进行交互完成读取的工作,并将读取的数据写入到内存中去,此时CPU就可以去做其他的事情

当DMA控制器得操作执行完成后,将产生中断请求信号,通知CPU读取任务完成

优点:仅在开始和结束需要CPU干涉,CPU和利用率进一步提升

缺点:CPU发出一条指令只能读或写一个或多个连续的数据块;如果读写的数据块不是连续存放的则CPU需要分别发送多条I/O指令,进行多次中断处理

还有一种方式:通道控制方式

通道值得是一种硬件,可以理解为低配版的CPU

通道根据CPU的指令执行响应程序,只有完成一组数据块的读写后才会发出中断信号让CPU干预(也是直接有设备→内存或内存→设备)

CPU的干预频率最低

实现方式

CPU干预频率

每次I/O传输的单位

数据流向

程序直接控制方式

极高

设备→CPU→内存
内存→CPU→设备

中断驱动方式

设备→CPU→内存
内存→CPU→设备

DMA方式

设备→内存
内存→设备

通道控制方式

一组块

设备→内存
内存→设备


I/O设备虚拟化技术

虚拟化架构:虚拟化的基础知识-CSDN博客

软件辅助全虚拟化

核心思想

将I/O设备以一个虚拟设备的形式暴露给虚拟机,虚拟机操作系统内部看来他正在使用一个真实的物理设备

VMM截获虚拟机驱动程序对设备的访问,并进行设备模拟;VMM的设备模拟器需要仔细研究现实设备的接口定义和内部设计规范,然后通过软件的方式完全模拟I/O设备,显示设备具有哪些资源,设备模拟器就需要呈现出同样的资源

访问设备

CPU通过PCI总线与I/O设备连接,在CPU的视角下,每个设备就是一个PCI设备,而每一个PCI设备都有一组重要的寄存器,叫做基址寄存器,软件虚拟化是通过VMM模拟基地址寄存器给虚拟机使得虚拟机能够找到I/O设备

访问拦截

虚拟机CPU访问虚拟I/O设备的两种形式PMIO和MMIO

PMIO和MMIO找到设备对应的IO端口或内存地址都是通过基址寄存器完成的

PMIO访问拦截

CPU通过特殊指令访问IO端口,这些端口可以由VMM来屏蔽掉,一旦CPU要访问这些端口,CPU就会触发异常,退出虚拟机,由VMM接管,此时VMM就可以截获到这次IO请求

MIMO访问拦截

CPU通过内存特殊地址来访问IO端口,该内存特殊地址为GPA,我们需要将其映射为HPA;而GPA→HPA的映射是由VMM建立的,当虚拟机触发MMIO来访问这些IO特殊地址时,触发异常产生VM exit交给VMM处理,这时VMM就可以感知到虚拟机对IO设备的访问了,并拦截了此次访问请求

设备模拟

需要VMM来模拟设备的真实行为了,不同的IO设备类型模拟不同的行为

在VMM层面,这些模拟的设备是一个基于本地文件系统的一个文件,而虚拟机对于整个磁盘的读写在经过VMM层就转化为了对这个文件某一位置的读写,在此过程中就涉及到数据传输(DMA为例子)

VMM内部需要模拟DMA的功能,虚拟机的设备驱动会告诉该DMA要读取数据的信息(虚拟机告知DMA的是GPA地址,需要通过内存虚拟化将该GPA转为HPA地址),然后由VMM来模拟这个行为将数据从文件中读取出来写入到目标地址中

当DMA数据传输完成之后,VMM产生中断(通过为虚拟机的vCPU注入一个中断),告知虚拟机内部这次IO请求的完成;然后由虚拟机内部的中断机制来完成IO请求剩余的中断处理

此方式的特点

虚拟机操作系统原有的驱动程序无需修改就可以驱动虚拟设备

对虚拟机来说非常透明,无需考虑底层硬件的情况

软件模拟效率较低,并且虚拟机发送出来的I/O请求需要虚拟机和VMM之间进行多次交互,产生巨大开销

以KVM架构实现软件辅助全虚拟化的架构

虚拟机发送I/O请求到虚拟机的设备驱动

设备驱动发送的I/O设备操作请求被KVM模块中的I/O操作捕获代码捕获(不会直接发到物理设备上)

KVM的I/O操作模块捕获到I/O请求后,把请求进行处理,将请求信息存放到I/O共享页

QEMU程序从I/O共享页读取信息后,交由硬件模拟代码来模拟出本次I/O操作,然后将其转发给硬件,硬件将结果返回给QEMU程序

QEMU程序将将结果放回到I/O共享页,并通知KVM模块中的I/O操作捕获代码

KVM模块的捕获代码读取I/O共享页中的操作结果,将结果返回给虚拟机

半虚拟化

Virtio协议基本概念

为什么提出Virtio协议

Virtio很好的定义了一套半虚拟化的架构,但并不是唯一的半虚拟化IO的技术,它的主要意义是简化和统一半虚拟化I/O的标准

Virtio半虚拟化作为当前KVM平台上主流的半虚拟化IO协议,在设备的资源高效利用和保持性能之间做到了一个较好的平衡;,既能够利用半虚拟化的特点,在数据传输层面极大的提高IO的效率,又能够保持前后端的良好兼容

其他半虚拟化协议

Xen有自己的一套完整的半虚拟化IO的实现方案、VMware也有自己的一套半虚拟化实现方案

Virtio协议的概念

virtio定义了一套典型的前后端架构,通过在虚拟机安装前端驱动(Front-end driver),在VMM安装后端驱动(Back-end);前端将请求通过VMM提供的通信机制直接发给后端,后端处理完请求后再发回通知给前者,使得前后端直接通信

前后端之间的通信可以分为两个层面

控制层面

通过控制层面使得前后端在通信之前在某方面达成一致,还会做一些对于数据层面的配置(例如CPU发现设备、配置IO设备、管理IO设备等相关操作)

例如:由于软件不断更新,前后端之间的版本可能不一致,在新的版本中可能会有新的特性;为了达成一致,后端会将自己的特性集合发给前端,前端也会将这些特性与自己的特性进行对比,最后返回两者的交集,这样就可以确保在特性上达成一致

数据层面

数据层面是为虚拟机和IO设备进行数据传输所服务的;可以对虚拟机和设备之间IO数据传输的相关数据与传输方式进行设定

在数据层面中定义了一个virtqueue数据传输结构来供前端和后端进行数据上的通信

Virtqueue讲解

什么是Virtqueue

Virtqueue是一个队列的抽象模型,前端驱动负责向virtqueue中插入一个个数据buffer,后端则负责处理这些buffer;每个buffer可以由一段或多段不连续的数据空间链接而成,每段数据空间可以由不同的读写权限用于不同的用途(即buffer的具体结构与IO设备类型相关)

virtqueue模型如何实现前后端通信

virtqueue需要支持5个接口来实现数据在虚拟机和宿主机之间的传输

add_buf接口:向virtqueue中插入一个待处理的buffer

kick接口:    通知宿主机由新的buffer加入

get_buf接口: 从virtqueue中获取一个宿主机处理完成的buffer

disable_cb和enable_cp接口:IO设备驱动中的关中断和开中断,用于设置在宿主机处理完一个buffer后是否会被调用

virtio_ring的作用以及组成

Virtqueue是数据传输的抽象模型,而virtio_ving(也称为ving)是这个模型的一种高效实现方式,而ving主要由以下三个部分组成

描述符表项

首先virtqueue会给每个buffer分配一个描述符(描述buffer的地址、长度等),并且也会维护一个全局的表来记录这些描述符,这个表中包含描述符所描述的特性(也有可能多个buffer连成一个链表)

Available ring队列

这个队列主要就是来表示在描述表里面有哪些请求是需要被处理的,需要将其在描述表中对应的序列号放入此队列(如果序号之间存在链接,则只放第一个序号)

Used ring队列

后端处理完成后会将处理好的请求放到该队列中,这个队列的格式和Available Ring是差不多的,也是把相应的描述符在描述表中对应的序号填写进去(如果后端往buffer里面写过数据,它同样会带上她在buffer里面写入数据的长度)

工作流程

假如前端发送了一个IO读取的请求,则前端通过add_buf接口在virtqueue中插入一个buffer,并且接下来会往描述符表项中写入关于这一个buffer的描述符(包含地址、长度、序号等信息)

然后此buffer描述符对应的序列号加入到Available Ring队列,此时前端就会通过virtqueue提供的kick接口来告知后端设备这些请求是需要处理的

然后后端设备将会从Available Ring队列里面读取请求来处理(当然这个kick也会涉及到一次vm-exit)

后端处理完成后会将处理好的请求放到Used Ring队列(也是把相应的描述符在描述表项中的对应序号填写进去),然后会以一个正常的中断形式注入给虚拟机,告知其内部I/O操作完成

然后前端通过get_buf接口从virtqueue中的Used Ring队列获取宿主机处理完成的buffer

特点

需要修改虚拟机和宿主机操作系统内核相应的代码来满足相应要求,兼容性较低

省略了我们在发送I/O前先进行VMM捕获的过程,使用效率提升

支持前端在Available Ring中设置让后端知道什么时候能够触发一个中断,也可以在后端Used Ring中设置前端的下一次Kick是什么时候

以KVM架构实现半虚拟化的架构

不过常用的半虚拟化架构为Xen架构

硬件辅助全虚拟化

目前常用的有两种方式

I/O直通方式(设备透传方式)、SR-IOV方式

I/O直通方式

核心思想

虚拟机真正直接使用到了物理设备,给物理服务器安装多个I/O设备,将一个物理I/O设备直通给虚拟机使用,使得虚拟机操作系统可以直接操作这个I/O设备,尽量避免触发VM exit来让VMM介入(最常用的就是网卡--直通网卡)

I/O直通技术需要硬件支持才可以完成,首选的是Inter的VT-d技术

设备访问

我们要知道PMIO和MMIO找到设备对应的IO端口或内存地址都是通过PCI设备的基址寄存器完成的

因此在直通的情况下,虽然物理设备直接存在,但是不能直接把物理设备的基址寄存器暴露给虚拟机,因为在设备透传给虚拟机之前,该I/O设备还需要挂载给物理主机,因此该I/O设备的基址寄存器实际上是宿主机配置的而不是虚拟机,如果直接将I/O的基址寄存器直接暴露给虚拟机,可能会存在基址寄存器冲突,因此在物理设备透传的情况下,我们也需要模拟寄存器给虚拟机

访问拦截

PMIO方式的访问拦截

虚拟机的基址寄存器是不同于物理机的基址寄存器的,因此他们的IO端口可能就是不同的,所以当虚拟机访问自己的IO端口时VMM需要将其截获,并且将这个IO请求转发给物理设备真实的IO端口,此时就会涉及到依次VM exit

MMIO方式的访问拦截

MMIO下虚拟机访问IO设备直接访问的就是一个内存地址,这个内存地址为GPA,然后通过内存虚拟化将GPA转为HPA;对于IO设备也是需要在VMM上建立IO GPA到IO HPA的映射关系,使得虚拟机访问IO设备就可以直接通过映射表来完成

数据传输

DMA重映射

虚拟机内部的设备驱动是期待这个设备支持DMA功能的

在DMA的视角下,它只知道虚拟内存的地址空间,它就会往虚拟地址中读写数据,但是实际上这个内存地址是错误的,应该写入的地址是物理机内存地址

因此就需要做到DMA的重映射,这个功能是由介于设备控制器和内存之间的一个模块(叫做IOMMU实现的,该模块属于CPU的功能)

IOMMU介绍

IOMMU是一个内存管理单元,主要针对外设访问系统内存时进行内存管理

IOMMU的主要功能包括DMA Remapping(地址重映射)和Interrupt Remapping(中断重映射)

对于DMA Remapping,IOMMU可以将一个设备访问地址转换为存储器地址(对于虚拟机的情况来说就是可以实现GPA与HPA的转换)

即:在IOMMU中会有一个表项,这个表是通过一个一个的PCI设备来作为索引的,并且能够导向虚拟机的信息(包含IO GPA到IO HPA的映射信息),这个索引到虚拟机信息的映射是由负责分配虚拟机内存的VMM建立的

具体IOMMU工作原理

在整个PCI架构中,每个设备都是有自己的一个唯一的标识符,类似于身份证,我们叫做Src ID,当设备通过这个PCI总线进行通信的时候,会携带上自己的Src ID,而I/O设备和内存之间通信也一样

当DMA发送请求时会被IOMMU给截获并找到对应PCI设备的Src id,然后通过IOMMU的映射就可以将这个DMA控制器所访问的GPA内存地址转换为HPA,从而DMA的操作也就可以访问到一个正确的内存地址了

当DMA完成操作之后会产生中断信息,告诉虚拟机IO操作完成

特点

这种方式从性能上来说是最优先的,但这种方式需要比较多的硬件资源

这种方式一旦一个设备被虚拟机占用了,其他虚拟机就无法使用该设备

SR-IOV方式

设备透传无法达到单个设备共享给多个虚拟机使用的目的,因为IO设备是依据挂载给单个主机使用而设计的;于是可以在IO设备设计时就考虑到将其运行在虚拟化环境中的,使得一个I/O设备支持共享给多个虚拟机来使用,这就是SR-IOV技术

SR-IOV的基本概念

在宿主机上挂载一个支持SR-IOV的高性能网络设备,需要CPU支持IOMMU

SR-IOV是将设备的虚拟化放到了硬件层面来实现,从而减少了软件层面的开销

SR-IOV单独引入了两种软件实体功能

Physical Function(PF)

PF包含轻量级的PCIE功能, 一个PF能够作为一个PCIE设备来供这个宿主机所配置

一个SR-IOV设备上可能会有多个PF,本次只考虑单个PF的情况

作用:为虚拟机提供设备访问功能和全局贡献资源配置的功能

VF(Virtual Function)

VF也包含轻量级的PCIE功能,我们可以将这个VF透传给一个虚拟机所使用,因此多个VF便可以拓展给不同的虚拟机,这样就可以达到将整个SR-IOV设备共享给多个虚拟机的目的

在一个PF上可以衍生出来多个VF,一个PE最多有64000个与其相关联的VF

作用:为虚拟机提供接口、进行数据的发送与接收功能、与PE通信完成全局相关配置

具体的工作流程

虚拟机和VF设备的交互与IO直通的交互类似,只不过SR-IOV是多个虚拟机共享同一个I/O设备

既然VF可以作为一个正常的PCIE设备透传给虚拟机使用,那是否会遇到在使用一个正常的物理设备透传给这个虚拟机所需要的问题(也就是IO直通所遇到的问题)?

答案是会遇到

我们知道IO直通场景下有一个重要的阶段IO数据的传输,当DMA请求时,需要通过IOMMU模块将GPA翻译为HPA来完成内存的读写

VF也是一样的,它支持DMA功能,也会通过IOMMU将GPA转为HPA,从而找到宿主机上正确的HPA,将IO相关的数据写入到目标内存地址中

因此一个VF设备也会需要有一个自己全局唯一的设备标识符(Src ID);IOMMU就是通过这个Src ID找到这个VF挂载的虚拟机,找到这个虚拟机的IO内存地址的映射,从而找到这个GPA所映射的HPA

特点

只是SR-IOV设备本身是基于虚拟化环境设计的,因此他可以做一些专门针对虚拟化环境的优化(例如可以增加一个本地的高速缓存存放GPA到HPA的映射,从而在某些场景下就省去了查询IOMMU的功夫)

建立了基于PF&VF的标准

性能最高,几乎和直接使用硬件I/O设备没有区别

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

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

相关文章

美国航空公司飞行员工会遭受勒索软件攻击

导语:近日,美国航空公司的飞行员工会遭受了一次勒索软件攻击。这次攻击对于全球最大的独立飞行员工会——美国航空公司飞行员协会(APA)造成了一定影响。让我们一起来了解详情。 背景介绍 美国航空公司飞行员协会成立于1963年&…

Bytedance揭秘OpenAI大模型: GPT-3到GPT-4进化路径

文章目录 探秘GPT-3到GPT-4进化之路1、SFT:早期GPT进化的推动者2、RLHF和SFT:编码能力提升的功臣3、代码加入预训练,对推理帮助最大4、“跷跷板”现象 论文地址项目链接Reference GPT-Fathom: Benchmarking Large Language Models to Deciphe…

Python入门:6个好用的Python代码,快来收藏!

文章目录 1.类有两个方法,一个是 new,一个是 init,有什么区别,哪个会先执行呢?2.map 函数返回的对象3.正则表达式中 compile 是否多此一举?4.[[1,2],[3,4],[5,6]]一行代码展开该列表,得出[1,2,3,4,5,6]5.一行代码将字符…

物理内存的关系及分配模式

在分配缓存块的时候,要分两种路径,fast path 和 slow path,也就是快速通道和普通通道。其中 kmem_cache_cpu 就是快速通道,kmem_cache_node 是普通通道。每次分配的时候,要先从 kmem_cache_cpu 进行分配。如果 kmem_ca…

shell脚本代码混淆

文章目录 起因安装 Bashfuscator安装BashfuscatorBashfuscator的使用 起因 很多时候我并不希望自己的shell脚本被别人看到,于是我在想有没有什么玩意可以把代码加密而又正常执行,于是我想到了代码混淆,简单来看一下: 现在我的目…

WSL 下载

可以使用单个命令安装运行 WSL 所需的一切内容。 在管理员模式下打开 PowerShell 或 Windows 命令提示符,方法是右键单击并选择“以管理员身份运行”,输入 wsl --install 命令,然后重启计算机。 首先查看可以下载的版本 最后再运行wsl --ins…

新手入门Python一定要看的八个超实用建议!

文章目录 前言一、项目文件事先做好归档二、永远不要手动修改源数据并且做好备份三、做好路径的正确配置四、代码必要的地方做好备注与说明五、加速你的Python循环代码六、可视化你的循环代码进度七、使用高效的异常捕获工具八、要多考虑代码健壮性关于Python技术储备一、Pytho…

代理模式(静态代理、JDK代理、CGLIB代理)

简介 代理模式有三种不同的形式:静态代理、动态代理(JDK代理、接口代理)、CGLIB代理 目标:在不修改目标对象的前提下,对目标对象进行扩展。 静态代理 需要定义接口或父类对象,被代理对象和代理对象通过实…

Go 方法介绍,理解“方法”的本质

Go 方法介绍,理解“方法”的本质 文章目录 Go 方法介绍,理解“方法”的本质一、认识 Go 方法1.1 基本介绍1.2 声明1.2.1 引入1.2.2 一般声明形式1.2.3 receiver 参数作用域1.2.4 receiver 参数的基类型约束1.2.5 方法声明的位置约束1.2.6 如何使用方法 二…

uniapp: 前端利用百度云OCR实现文字识别(身份证识别功能,别的功能类似)

第一章 前言 介绍如何使用百度智能云实现我们想要的效果,需要在下面这个网址注册账号: 百度智能云-云智一体深入产业 使用文档在该网址上: 简介 - 文字识别OCR 请求成功的效果,如下图: 搜索产品(例如文字…

数据结构--前缀树(Trie)

1. 简介 前缀树是一种数据结构&#xff0c;常用来字符搜索。 2. 实现 包含的操作主要是: 加入串搜索串 代码实现&#xff0c;直接用leetcode_208的题解咯。 代码 class Trie { public:Trie():isEnd(false){for ( int i 0; i < 26;i)child[i] nullptr;}~Trie() {fo…

零基础搭建Nextcloud私有云盘并通过内网穿透实现远程访问

文章目录 摘要1. 环境搭建2. 测试局域网访问3. 内网穿透3.1 ubuntu本地安装cpolar3.2 创建隧道3.3 测试公网访问 4 配置固定http公网地址4.1 保留一个二级子域名4.1 配置固定二级子域名4.3 测试访问公网固定二级子域名 摘要 Nextcloud,它是ownCloud的一个分支,是一个文件共享服…

Vue 条件渲染 与 列表渲染

目录 一、条件渲染 1.简介 : 2.v-if实例 : 3.v-show实例 : 4.v-if与v-show的区别 : 二、列表渲染 1.基本用法 : 1.1 v-for遍历数组 1.2 v-for遍历对象 2.应用实例 : 一、条件渲染 1.简介 : (1) Vue提供了v-if 和 v-show条件指令来完成条件渲染/控制。 v-if指令用于条…

​C++内存模型

c语言分区:栈、堆、全局/静态存储区、常量存储区、代码区(.text段)、自由存储区 1、栈区&#xff08;stack&#xff09;— 由编译器自动分配释放&#xff0c;存放函数的参数值&#xff0c;局部变量的值等。其操作方式类似于数据结构中的栈。向下生长 2、堆区&#xff08;heap&…

iSlide2024一款基于PPT的插件工具包含38个设计辅助功能

根据使用者情况表明iSlide 是一款拥有30W素材的PPT高效设计软件&#xff0c;可提高90%工作效率&#xff0c;现全球已有超过1400万使用者&#xff0c;智能排版原创高品模板可商用图形&#xff0c;真正摆脱PPT的束缚&#xff0c;把精力用在该用的地方。我们都明白islide插件功能特…

Linux背景介绍与环境搭建

本章内容 认识 Linux, 了解 Linux 的相关背景学会如何使用云服务器掌握使用远程终端工具 xshell 登陆 Linux 服务器 Linux 背景介绍 发展史 本门课程学习Linux系统编程&#xff0c;你可能要问Linux从哪里来&#xff1f;它是怎么发展的&#xff1f;在这里简要介绍Linux的发展…

pytorch 中 nn.Conv2d 解释

1. pytorch nn.Con2d 中填充模式 torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride1, padding0, dilation1, groups1, biasTrue, padding_mode‘zeros’, deviceNone, dtypeNone) 1.1 padding 参数的含义 首先 &#xff0c;padd N, 代表的是 分别在 上下&…

阿里云安全恶意程序检测

阿里云安全恶意程序检测 赛题理解赛题介绍赛题说明数据说明评测指标 赛题分析数据特征解题思路 数据探索数据特征类型数据分布箱型图 变量取值分布缺失值异常值分析训练集的tid特征标签分布测试集数据探索同上 数据集联合分析file_id分析API分析 特征工程与基线模型构造特征与特…

driver.find_element()用法

driver.find_element()用于在Web页面中定位单个元素。它是Selenium WebDriver库中的 一种方法。该方法接受一个定位器&#xff08;locator&#xff09;和一个值作为参数&#xff0c;用于指定要查找的元素 位置。下面是具体的用法和一些例子&#xff1a; 通过ID定位元素&#x…

AI神助攻,购物更省心:我即将上线一套企业数据高度契合的智能导购APP来开创这一新纪元

将要做什么事的介绍 近期博客写了少了&#xff0c;是因为近小半年来我正在打造一款可私布在企业内部并结合企业自有领域&#xff08;零售商超先行&#xff09;数据的智能导购引擎。截止目前为止还算顺利&#xff0c;并且我将很快将在中国本土的一家生鲜百货超市上线这一款生成…