AArch64 内存管理

        本文是对arm developer网站《Learn the architecture - AArch64 memory management Guide》的学习笔记(Documentation – Arm Developer)

一、背景概述

        本文介绍了AArch64中的内存转换,这是内存管理的关键,它解释了虚拟地址如何转换为物理地址、转换表的格式以及软件如何管理TLB。

1. 什么是内存管理

        内存管理描述了如何控制对系统内存的访问。操作系统或应用程序访问内存时,硬件都会执行内存管理。内存管理是一种向应用程序动态分配内存区域的方法。

2. 为什么需要内存管理

        AP旨在运行rich os(如Linux),需要支持虚拟内存系统,AP上运行的软件只能看到虚拟地址,AP将虚拟内存转换为物理地址,物理地址最终指向内存中的实际物理位置。

3. 虚拟地址和物理地址

        使用虚拟地址的好处是它允许管理软件(例如OS)控制呈现给软件的内存视图,OS可以控制哪些内存是可见的、该内存可见的虚拟地址以及允许对该内存进行哪些访问。这允许操作系统对应用程序进行沙箱处理(对另一应用程序隐藏一个应用程序的资源)并提供对底层硬件的抽象。】

        用虚拟地址的另一个好处是操作系统可以将多个碎片物理内存区域作为单个连续的虚拟地址空间呈现给应用程序。

        虚拟地址也有利于软件开发人员,软件开发人员使用虚拟地址,无需关心物理内存。实际上,每个应用程序都可以使用自己的一组虚拟地址,这些地址将映射到物理系统中的不同位置。当操作系统在不同的应用程序之间切换时,需要重新组织物理地址和虚拟地址的映射关系。

        虚拟地址通过映射转换为物理地址。虚拟地址和物理地址之间的映射存储在转换表(有时称为页表)中,如下图所示:

        页表位于内存中,并由软件(通常是OS或hypervisor)管理, 页表不是静态的,并且随着软件需求的变化而刷新。

4. 地址空间

4.1 虚拟地址空间

        AArch64有多个独立的虚拟地址空间,如下(Armv8-A中的地址空间):

        NS.EL0:非安的EL0,在Linux中对应用户态虚拟地址空间,页表基址寄存器TTBR0_EL1

        NS.EL1:非安的EL1,在Linux中对应内核态虚拟地址空间,页表基址寄存器TTBR1_EL1

        NS.EL2:非安的EL2,EL2是可选的

        EL3:EL3也是可选的

        每个虚拟地址空间都是独立的,并且有自己的配置和页表。此外,还有Secure EL0、Secure EL1和Secure EL2的虚拟地址空间,图中没有显示。(Armv8.4-A 中添加了对 Secure EL2 的支持。)

        由于存在多个虚拟地址空间,因此指定地址位于哪个地址空间非常重要。例如,NS.EL2:0x8000指的是非安全 EL2 虚拟地址空间中的地址0x8000

        上图还显示了NS.EL0和NS.EL1中的虚拟地址经过了两步地址转换(2-stage),表示这些表支持虚拟化,虚拟机VM内看到的物理内存还需要经过stage-2的页表才能转换为实际的物理内存。;

        Armv9-A支持上述 Armv8-A 的所有虚拟地址空间。 Armv9-A 引入了可选的领域管理扩展 (RME)。如果实现了RME ,还存在其他转换机制

  • Realm EL1和EL0
  • Realm EL2和EL0
  • Realm EL2

        在虚拟化中,我们将OS控制的一组转换称为stage-1。stage-1页表将虚拟地址转换为中间物理地址 (IPA)。在stage-1,操作系统认为 IPA 是物理地址空间。然而,虚拟机管理程序控制stage-2转换,第二组转换将 IPA 转换为物理地址。下图显示了两组翻译的工作原理:

4.2 物理地址空间

        除了多个虚拟地址空间之外,AArch64 还具有多个物理地址空间(PAS):

  • 非安全 PAS0
  • 安全PAS
  • Realm PAS(仅限 Armv9-A)
  • root PAS(仅限 Armv9-A)

        虚拟地址可以映射到什么物理地址空间取决于处理器当前的安全状态。下表显示了安全状态及其相应的虚拟地址映射

  • 非安全状态:虚拟地址只能映射到非安全物理地址。
  • 安全状态:虚拟地址可以映射到安全或非安全物理地址。
  • Realm状态:虚拟地址可以映射到Realm或非安全物理地址
  • root 状态:虚拟地址可以映射到任意物理地址空间。

note:这些访问权限由页表控制(//todo)

4.3 地址空间大小

        AArch64是64位架构,但这并不意味着所有地址都是64位的。

4.3.1 虚拟地址空间的大小

        虚拟地址以 64 位格式存储。因此,加载指令 (LDR) 和存储指令 (STR) 中的地址始终在通用寄存器中指定。然而,并非通用寄存器中的所有地址都是有效的。

        下图显示了 AArch64 中虚拟地址空间的布局:

        EL0/EL1虚拟地址空间有两个区域:内核空间和应用程序空间。这两个区域显示在图的左侧,内核空间位于顶部,应用程序空间(标记为“用户空间”)位于地址空间的底部。内核空间和用户空间具有单独的页表,这意味着它们的映射可以保持分离。 

        在地址空间的底部有一个区域用于所有其他异常级别。该区域显示在图的右侧。

        如果将 HCR_EL2.E2H 设置为 1,则会host os在 EL2 中运行,host os的应用程序在 EL0 中运行的配置。在这种情况下,EL2也有上部和下部区域。(即type2的虚拟化)

        地址空间的每个区域的大小最多为 52 位。然而,每个区域都可以独立地缩小到更小的尺寸。 TCR_ELx 寄存器中的 TnSZ 字段控制虚拟地址空间的大小。例如,下图显示 TCR_EL1 控制 EL0/EL1 虚拟地址空间:

        

        虚拟地址空间大小为:

virtual address size in bytes = 2^(64-TCR_ELx.TnSZ)

        因此,如果TCR_ELx.T1SZ 设置为32,则EL0/EL1虚拟地址空间中内核区域的大小为2^32字节(0xFFFF_FFFF_0000_0000至0xFFFF_FFFF_FFFF_FFFF)。任何超出配置范围的地址在被访问时都会生成异常作为转换错误。这种配置的优点是我们只需要描述我们想要使用的地址空间,这节省了时间和空间。例如,假设操作系统内核需要 1GB 地址空间(30 位地址大小)作为其内核空间。如果操作系统将 T1SZ 设置为 34,则仅创建描述 1GB 的转换表条目,即 64 - 34 = 30。

        所有 Armv8-A 实现都支持 48 位虚拟地址。对 52 位虚拟地址的支持是可选的,并由 ID_AA64MMFR2_EL1 报告。

4.3.2 物理地址空间的大小

        物理地址的大小由实现定义,最大为 52 位。 ID_AA64MMFR0_EL1 寄存器报告处理器实现的大小。对于 Arm Cortex-A 处理器,通常为 40 位或 44 位。

        在 Armv8.0-A 中,物理地址的最大大小为 48 位。在 Armv8.2-A 中这已扩展到 52 位

4.3.3 IPA地址空间的大小

         如果在转换表条目中指定的输出地址大于实现的最大值,MMU)将产生地址大小错误异常。

        IPA空间的大小可以与虚拟地址空间相同的方式配置。 VTCR_EL2.T0SZ 控制大小。可以配置的最大大小与处理器支持的物理地址大小相同。这意味着您无法配置比支持的物理地址空间更大的 IPA 空间。

4.4 ASID-地址空间标识符

        许多现代操作系统的应用程序都在同一地址空间运行,但不同的应用程序有自己的虚拟地址空间。这意味着 VA 0x8000的地址转换取决于当前正在运行的应用程序。    

        理想情况下,我们希望不同应用程序的翻译能够在翻译后备缓冲区 (TLB) 中共存,以防止 TLB 在上下文切换时失效。但是处理器怎么知道要使用哪个版本的 VA 0x8000转换呢?在 AArch64 中,答案是地址空间标识符 (ASID)     

        对于 EL0/EL1 虚拟地址空间,可以使用转换表条目的属性字段中的 nG 位将转换标记为全局 (G) 或非全局 (nG)。例如,内核映射是全局翻译,应用程序映射是非全局翻译。全局翻译适用于当前正在运行的任意应用程序。非全局翻译仅适用于特定应用程序。

        非全局映射在 TLB 中用 ASID 进行标记。在 TLB 查找中,TLB 条目中的 ASID 与当前选择的 ASID 进行比较。如果它们不匹配,则不使用 TLB 条目。下图显示了内核空间中没有 ASID 标记的全局映射和用户空间中带有 ASID 标记的非全局映射:

        该图显示,多个应用程序的 TLB 条目可以在缓存中共存,ASID 决定使用哪个条目。 

        ASID 存储在两个 TTBRn_EL1 寄存器之一中。通常TTBR0_EL1用于用户空间。因此,更新TTBRn_EL1寄存器可以更改 ASID 及其指向的转换表。

        HCR_EL2.E2H为1时(type2的虚拟化),ASID标记也可以在EL2中使用

4.5 VMID-虚拟机标识符

        EL0/EL1 转换还可以使用虚拟机标识符 (VMID) 进行标记。 VMID 允许来自不同 VM 的转换在缓存中共存。这类似于 ASID 用于来自不同应用程序的翻译的方式。实际上,这意味着某些翻译将同时标记有 VMID 和 ASID,并且两者都必须与要使用的 TLB 条目匹配。

        当安全状态支持虚拟化时,EL0/EL1 转换始终标记有 VMID,即使未启用stage-2转换。这意味着,如果您正在编写初始化代码并且不使用hypervisor,则在设置stage-1 MMU 之前设置已知的 VMID 值非常重要。

4.6 Common not Private

        如果一个系统包括多个PE,在一个PE上使用的ASIDs和VMIDs在其他PE上是否有相同的意义?对于 Armv8.0-A,答案是它们不必表示相同的意思。不要求软件在多个PE上以相同的方式使用给定的 ASID。例如,ASID 5 可能由一个处理器上的计算器使用,并由另一处理器上的 Web 浏览器使用。这意味着由一个处理器创建的 TLB 条目不能被另一处理器使用。

        实际上,软件不太可能在不同的PE上以不同的方式使用 ASID。对于软件来说,更常见的是在给定系统中的所有PE上以相同的方式使用 ASID 和 VMID。因此,Armv8.2-A 在转换表基址寄存器 (TTBR) 中引入了 Common not Private (CnP) 位。当 CnP 位被设置时,软件承诺在所有处理器上以相同的方式使用 ASID 和 VMID,这允许一个处理器创建的 TLB 条目可以由另一个处理器使用。

        note:处理单元Processing Element (PE),PE是任何实现 Arm 架构的处理单元。这一点在这里很重要,因为微架构方面的原因导致处理器之间共享 TLB 会很困难。但在多线程处理器中,每个硬件线程都是一个 PE,因此更需要共享 TLB 条目。

5. MMU(内存管理单元)

        内存管理单元 (MMU) 负责将软件使用的虚拟地址转换为内存系统中使用的物理地址。

        MMU 包含以下内容:

  • The table walk unit:从内存中读取转换表的逻辑
  • Translation Lookaside Buffers (TLBs):缓存最近使用的翻译

        软件分配的所有内存地址都是虚拟的。这些内存地址被传递到 MMU,MMU 检查 TLB 中是否有最近使用的缓存翻译。如果 MMU 没有找到最近缓存的翻译,表遍历单元会从内存中读取相应的表条目,如下所示:        

        在进行内存访问之前,必须将虚拟地址转换为物理地址(因为我们必须知道正在访问哪个物理内存位置)。这种转换需求也适用于缓存数据(cached data),因为在 Armv6 及更高版本的处理器上,数据缓存使用物理地址(物理标记的地址)存储数据。因此,在完成高速缓存查找之前必须转换地址。 

5.1 Table entry(表项)

        转换表的工作原理是将虚拟地址空间划分为大小相等的块,并为每个块提供表中的一个条目(表项)

        表中的条目 0 提供块 0 的映射,条目 1 提供块 1 的映射,依此类推。每个条目包含相应物理内存块的地址以及访问物理地址时要使用的属性。

        

5.2 查表

        翻译时会进行查表,当转换发生时,软件发出的虚拟地址被分成两部分,如下图所示:

        上图是单级查找表,高位在图中标记为“which entry”,低位被标记为"offset in block"。

5.3 多级页表

        在单级查找中,虚拟地址空间被分割成大小相等的块。在实践中,使用多级页表。一级表将虚拟地址空间划分为大块,表中的每个表项指向大小相同的物理内存块,也可以指向将该块细分为更小的块的另一个表。下图是三个级别的多级页表示例。

        

        在 Armv8-A 中,最大级别数为 4,级别编号为 0 到 3。这种多级方法允许描述较大的块和较小的块。大块和小块的特点如下: 

  • 大块比小块需要更少的读取级别来转换。另外,大块在 TLB 中缓存的效率更高
  • 小块使软件可以对内存分配进行细粒度控制。然而,小块在 TLB 中缓存的效率较低。缓存效率较低,因为小块需要多次读取各个级别才能进行转换。

当处理器开始查表时,它不知道翻译的大小。处理器通过执行查表来计算出正在转换的块的大小。

5.4 控制地址转换表格式

        在这里我们可以看到转换表条目允许的不同格式:

        

        每个表项都是 64 位,底部两个bit位确定表项的类型。请注意,某些table entry仅在特定级别有效。table的最大级别数是四级,这就是为什么没有level3(或第四级)表的Table Descriptor的原因(即level 3不可能再指向下级表项)。同样地,第0级也没有块描述符或页描述符。因为第0级 entry覆盖了很大的虚拟地址空间区域,因此在level0允许块是没有意义的,即level0永远都会指向下级表。

5.5 转换粒度

        转换粒度是可以描述的最小的内存块。AArch64 支持三种不同的粒度大小:4KB、16KB 和 64KB。处理器支持的粒度是自定义的,由 ID_AA64MMFR0_EL1 保存。所有Arm Cortex-A处理器都支持4KB和64KB。选择的粒度是最高level table中描述的大小。

        一个处理器所支持的粒度大小是ID_AA64MMFR0_EL1定义的,所有Arm Cortex-A处理器都支持4KB和64KB。选择的颗粒是可以在最新级别表中描述的最小块。也可以描述更大的块。此表显示了基于所选粒度的每个级别表的不同块的尺寸:

        在推出 Armv9.2-A 和 Armv8.7-A 之前,使用 52 位地址存在限制。当选择的颗粒为4KB或16KB时,最大虚拟地址区域大小为48位。同样,输出物理地址限制为 48 位。只有当使用64KB颗粒时才能使用完整的52位。 

5.6 地址转换的起始级别

        虚拟地址空间的粒度和大小共同控制地址转换的起始级别。上表总结了每个级别表中每个粒度的块大小(单个entry覆盖的虚拟地址范围的大小)。从块的大小,你可以算出虚拟地址的哪些位是用来索引每一级表的。

        我们以4KB的粒度为例。这张图显示了用于索引4KB粒度的 不同级别表的索引。

        由于是4K的页表,0:11的低12位是4K的块内偏移,4K的页表一共有512个表项(每个表项8个字节),所以需要9个bit来表示每一级页表的索引。

        如图所示,将TCR_EL1.T0SZ设置为32,以地址为单位的虚拟地址空间的大小计算方式如下:64 - T0SZ = 32 bit

        从之前的4KB配置的粒度图中可以看出,level0是47:39位索引的。这些在32位地址空间是不存在的。因此,地址翻译是从level1开始的。接着,假设设置T0SZ为34:64 - T0SZ = 30, 这一次,不存在level0 和level1的索引。因此,该配置的转译起始级别是level2。

        当虚拟地址空间的大小减少时,您需要更少级别的表来描述它。这些示例基于使用 4KB 粒度。当使用 16KB 和 64KB 颗粒时,同样的原理也适用,但地址位会发生变化

5.7 控制地址转换的寄存器
  • SCTLR_ELx

        M:使能MMU

        C:使能Dcache

  • TTBR0_ELx and TTBR1_ELx

         BADDR:转译表物理地址/中间物理地址的起点

        ASID:非全局转译的标识符

  • TCR_ELx

        PS/IPS:PA 或 IPA 空间的大小

        TnSZ:转译表能表示的地址空间的大小

        TGn:粒度大小

        SH/IRGN/ORGN:缓存能力共享能力的使能

        TBIn:禁止搜索table中的某一行

  • MAIR_ELx

        Attr:statge1 的类型和缓存能力控制

5.8 禁用MMU

        MMU被禁用时,所有地址都是平行映射,即输入和输出地址相同

5.9 维护TLB

        Translation Lookaside Buffers (TLB) 缓存最近使用的转译项。此缓存允许后续查找重复使用转译,而无需重新读取table。

                如果要更改转换表entry或控制entry的解释方式,则需要使 TLB 中受影响的entry无效。如果不使这些entry无效,则处理器可能会继续使用旧的转译。

        处理器不允许导致以下任何故障的翻译缓存到 TLB:

  • 翻译错误(未映射的地址)
  • 地址大小错误(超出地址范围)
  • 非法访问

因此,在第一次映射地址时,你不需要让TLB 无效。然而,如果要做以下操作,需要让TLB失效:

  • Unmap an address:将有效的地址标记为无效
  • 改变映射关系:将地址权限从只读改为读写。
  • 改变table 的转译方式:修改粒度大小时,table的转译方式也会改变。
5.10 操作TLB的方式

        TLBI 指令用于使 TLB 中的条目无效。该指令的语法为:

TLBI < type >< level >{IS|OS} {, < xt >}

< type >:指定无效的entries

        All - 所有entries

        VA - Entry matching VA and ASID in Xt

        VAA - Entry matching VA in Xt, for any ASID

        ASID - Any entry matching the ASID in Xt

< level >: 操作哪一个地址空间

        E1 = EL0/1 virtual address space

        E2 = EL2 virtual address space

        E3 = EL3 virtual address space

 < IS|OS >内部共享还是外部共享

< Xt >:操作那个地址或者ASID

        例如,考虑一个正在更新其内核转换表中的条目的操作系统 (OS)。典型的 TLB 无效序列如下所示:        

STR  X1, [X5]        // Write to translation table entry
DSB  ISH             // Barrier instructions - not covered in this guide
TLBI VAAE1IS  , X0   // Invalidate VA specified by X0, in EL0/1// virtual address space for all ASIDs
DSB  ISH             // Barrier instructions - not covered in this guide
ISB                  // Synchronize context on this processor
5.11 地址转换说明

        地址转换指令(AT)可以查询特定地址的转换。地址翻译的结果,属性会写入物理寄存器PAR_EL1。

        AT指令的语法具有优先级。例如,EL2指令可以查询EL0/EL1的翻译表,但是EL1指令不能查询EL2的。

6. check

Q:地址翻译中,statge和level有什么区别?

A:statge 指的是把输入地址转换为输出地址的过程。对于stage1,就是从VA到IPA的过程。stage2 从IPA到PA的过程。level指的是翻译给定阶段的table,将一个大块划分为小块的过程。

Q:物理地址最大是多少?

A:物理地址大小由IMPLEMENTATION DEFINED定义,在ARMV8.2-A后为52位。

Q:虚拟地址大小由哪些寄存器控制?

A:stage2的TCR_ELx.TnSZ, or VTCR_EL2.T0SZ

Q:翻译粒度是什么?支持的大小是多少?

A:翻译粒度指的是内存可以描述的最小的块。支持4KB, 16KB, and 64KB.

Q:TLBI ALLE3 作用是什么?

A:EL3虚拟地址中使所有的TLB entries无效。

Q:发生翻译错误时的翻译表项能缓存在TLB中吗?

A:不能

Q:当MMU关闭时,地址是如何映射的?

A:平行映射,即输入地址和输出地址相同。

Q:什么是ASID?什么时候TLB entry会包含ASID?

A:ASID是地址空间标识符,它标识了翻译与那个应用相关联。非全局映射(nG=1)在在TLB中被标记为一个ASID。

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

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

相关文章

第3章 WebServer重构

3.1 重构原生Web服务框架 3.1.1 分析原生Web服务框架 在服务端代码的 ClientHandler 中&#xff0c;请求解析、处理请求、返回响应的代码混杂在一起&#xff0c;这样的设计会导致代码难以维护和理解。为了提高代码的可读性、可维护性和可扩展性&#xff0c;我们需要对这些代码…

ComfyUI搭建和注意事项for WIN[笔记]

下载ComfyUI(GitHub - comfyanonymous/ComfyUI: The most powerful and modular stable diffusion GUI, api and backend with a graph/nodes interface.) 从源码上搭建比较麻烦&#xff0c;一般不推荐&#xff0c;所以跑到release里面找一个下载。我的显卡是GeFore GTX 1050 …

飞腾E2000运行Zephyr操作系统

Phytium-Zephyr-SDK 1. 仓库介绍 1.1 本仓库特色 此项目是一个开源软件&#xff0c;专为物联网领域设计&#xff0c;基于Zephyr实时操作系统&#xff0c;针对Phytium系列CPU进行了专门的适配和应用开发。我们的目标是降低开发者的使用门槛&#xff0c;提供了部署文档和使用指…

同向双指针(滑动窗口)算法

209. 长度最小的子数组 这里的更新结果就题来定 class Solution {public int minSubArrayLen(int target, int[] nums) {int sum 0;int len 0;int f 0;for(int left 0, right 0; right < nums.length;){//求和sum nums[right];while(sum > target){//lenint t ri…

MLP实现fashion_mnist数据集分类(1)-模型构建、训练、保存与加载(tensorflow)

1、查看tensorflow版本 import tensorflow as tfprint(Tensorflow Version:{}.format(tf.__version__)) print(tf.config.list_physical_devices())2、fashion_mnist数据集下载与展示 (train_image,train_label),(test_image,test_label) tf.keras.datasets.fashion_mnist.l…

张大哥笔记:卖盗版网课,获利 100 万被抓

这几天刷视频&#xff0c;看到一个新闻&#xff0c;某大学生卖盗版网课&#xff0c;把别人2000多正版网课&#xff0c;以做活动名义售卖20元&#xff0c;获利100多万被抓。 下方图片来自&#xff1a;极目新闻 卖这种盗版网课&#xff0c;门槛低&#xff0c;成本低&#xff0c;…

解决3D模型只显示线框材质的方法---模大狮模型网

在3D建模和渲染过程中&#xff0c;正确的材质和纹理是呈现逼真效果的关键。然而&#xff0c;有时候用户可能会遇到一个常见问题&#xff0c;即3D模型在渲染或查看时只显示线框材质&#xff0c;而没有正确的表面纹理和颜色。本文将介绍解决这一问题的几种方法&#xff0c;帮助用…

7 人赚 960 亿美元,数字天才的首次独舞

巴菲特股东大会 一年一度的巴菲特股东大会如常召开&#xff0c;只不过这次坐在老爷子左手边的不再是老搭档查理芒格&#xff0c;而是钦点的未来继任者&#xff0c;格雷格阿贝尔。 随着芒格&#xff08;99岁&#xff09;的离开&#xff0c;巴菲特&#xff08;93岁&#xff09;也…

【.sh】Shell 脚本文件的基础内容

目录 &#x1f30a;1. 基础知识 &#x1f30a;2. 简单示例 &#x1f30d;2.1 示例一 输出"Hello, World!" &#x1f30d;2.2 示例二 输入输出创建 &#x1f30a;1. 基础知识 .sh文件是什么&#xff1f; .sh文件即 Shell 脚本文件&#xff0c;通常用来执行一系列…

Ranni: Taming Text-to-Image Diffusion for Accurate Instruction Following

Ranni: Taming Text-to-Image Diffusion for Accurate Instruction Following abstract 我们引入了一个语义面板作为解码文本到图像的中间件&#xff0c;支持生成器更好地遵循指令 Related work 最近的工作还通过包含额外的条件&#xff08;如补全掩码[15&#xff0c;45]、…

10 华三vlan技术介绍

AI 解析 -Kimi-ai Kimi.ai - 帮你看更大的世界 (moonshot.cn) 虚拟局域网&#xff08;VLAN&#xff09;技术是一种在物理网络基础上创建多个逻辑网络的技术。它允许网络管理员将一个物理网络分割成多个虚拟的局域网&#xff0c;这些局域网在逻辑上是隔离的&#xff0c;但实际…

【LeetCode刷题记录】105. 从前序与中序遍历序列构造二叉树 106. 从中序与后序遍历序列构造二叉树

105 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,1…

Pandas入门篇(三)-------数据可视化篇2(pandas-plot篇)

目录 概述一、格式1. 生成pandas.plotting对象来生成图表2. 调用plot()函数来生成图表3.支持的图表类型 二、单变量绘图常用图表1. 柱状图&#xff08;bar&#xff09;使用场景代码实现 2. 折线图&#xff08;line&#xff09;&#xff08;默认即为折线图&#xff09;适用场景代…

计算机毕业设计 | vue+springboot 在线花店后台管理系统(附源码)

1&#xff0c;绪论 1.1 项目背景 随着社会发展&#xff0c;网上购物已经成为我们日常生活的一部分。但是&#xff0c;至今为止大部分电商平台都是从人们日常生活出发&#xff0c;出售都是一些日常用品比如&#xff1a;食物、服装等等&#xff0c;并未发现一个专注于鲜花的电商…

从一到无穷大 #25 DataFusion:可嵌入,可扩展的模块化工业级计算引擎实现

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言架构总览与可扩展性Catalog and Data SourcesFront End逻辑计划与逻辑计划优化器…

使用台式机打开腾讯会议后打开麦克风提示:未检测到可用的麦克风,请插入设备后重试

解决方法如下&#xff1a; 台式机是不带输入设备的&#xff0c;也就是不自带麦克风的&#xff0c;而笔记本电脑是带的。这时候在台式机上可以通过插入有线耳机充当输入设备&#xff0c;就可以正常使用麦克风功能了。 插入之后&#xff0c;可以看到设置里面声音界面包含了一个…

new mars3d.control.MapSplit({实现点击卷帘两侧添加不同图层弹出不同的popup

new mars3d.control.MapSplit({实现点击卷帘两侧添加不同图层弹出不同的popup效果&#xff1a; 左侧&#xff1a; 右侧&#xff1a; 说明&#xff1a;mars3d的3.7.12以上版本才支持该效果。 示例链接&#xff1a; 功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 相关代…

关于视频号小店,常见问题解答,开店做店各方面详解

大家好&#xff0c;我是电商笨笨熊 视频号小店作为今年风口&#xff0c;一个新推出的项目&#xff0c;凭借着自身流量加用户群体的优势吸引了不少的电商玩家。 但对于很多玩家来说&#xff0c;视频号小店完全是一个新的项目、新的领域&#xff0c;因此也会存在很多的疑问&…

数据分析从入门到精通 2.pandas修真之前戏基础

从爱上自己那天起&#xff0c;人生才真正开始 —— 24.5.6 为什么学习pandas numpy已经可以帮助我们进行数据的处理了&#xff0c;那么学习pandas的目的是什么呢? numpy能够帮助我们处理的是数值型的数据&#xff0c;当然在数据分析中除了数值型的数据还有好多其他类型…

接口自动化测试之-requests模块详解

一、requests背景 Requests 继承了urllib2的所有特性。Requests支持HTTP连接保持和连接池&#xff0c;支持使用cookie保持会话&#xff0c;支持文件上传&#xff0c;支持自动确定响应内容的编码&#xff0c;支持国际化的 URL 和 POST 数据自动编码。 二、requests安装 利用p…