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

空闲列表:回收和再利用

空闲列表:回收和再利用

在这里插入图片描述

手动与自动内存管理

  • 手动管理:程序员需要明确地分配和释放内存。
  • 自动管理:例如使用垃圾收集器(GC),它能够自动检测并回收未使用的对象,不需要程序员干预。

对于某些数据结构如B树,通过实现删除回调函数可以手动管理未使用的节点,从而可能避免使用GC。

未使用对象列表

为了有效地重复利用被释放的空间(如磁盘上的页面),通常会维护一个未使用空间的列表,称为自由列表(free list)或对象池(object pool)。这种机制简化了内存管理,因为它处理的是相同大小的块,而不是像malloc那样需要处理任意大小的请求。

嵌入式链表

一种简单的策略是使用嵌入式(侵入式)链表,其中指向下一个对象的指针直接存放在对象内部。这种方式的优点是不需要额外的空间来存储链表结构,但是它不兼容写时复制机制,因为更新时可能会覆盖原数据。

外部链表

另一种方法是将未使用页面的指针存储在一个外部的数据结构中。虽然这种方法需要额外的空间来维持这个数据结构本身,但它避免了嵌入式链表的一些问题。

自由列表作为日志

当自由列表只是未使用页面编号的日志时,添加新项仅需追加到列表末尾。然而,如何有效移除条目以防止列表无限增长是一个挑战。

解决这个问题的一种方法可能是周期性地整理自由列表,合并连续的空闲段,或者采用更复杂的数据结构如平衡树来高效管理这些信息。这有助于确保即使频繁地分配和释放页面,系统的性能也不会受到显著影响。

在磁盘上实现链表(如自由列表)需要仔细设计,以确保其高效性、可靠性和与写时复制(copy-on-write, COW)机制的兼容性。以下是对该问题的详细分析和解决方案。


自由列表的设计要求

自由列表是一个存储未使用页面编号的日志式数据结构。由于在写时复制树中,每次更新都会生成新节点并删除旧节点,因此自由列表需要同时支持添加和移除操作:

  1. 从末尾移除:如果从末尾移除条目,新增加的条目会覆盖旧数据。这需要额外的崩溃恢复机制(如第3章讨论的内容)。
  2. 从开头移除:如果从开头移除条目,则面临如何回收这些被移除条目占用的空间的问题。

为了解决这些问题,自由列表应基于页面进行管理,这样它就可以自我维护。这种基于页面的链表本质上是一个“展开的链表”(unrolled linked list),其中每个页面可以存储多个条目。


自由列表的核心特性

  1. 独立的数据结构

    • 自由列表是一个基于页面的链表。
    • 当需要扩展新节点时,它会尝试从自身获取一个空闲页面。
    • 被移除的节点会被重新添加到自由列表中以供重用。
  2. 每个页面的多条目存储

    • 每个页面包含多个条目(例如页面编号)。
    • 页面是原地更新的,但在页面内部仍然是追加写入(append-only)。
  3. 条目的追加与消费

    • 条目被追加到尾节点(tail node)。
    • 条目从头节点(head node)消费。
    • 这种设计使得尾节点更容易保持追加写入的特性。

自由列表的磁盘布局

每个节点的格式如下:

| next | pointers | unused |
| 8B   | n*8B     | ...    |
  • next 是指向下一个节点的指针,占 8 字节。
  • pointers 是存储页面编号的数组,每个编号占 8 字节。
  • unused 是未使用的空间。

定义如下常量和方法:

type LNode []byteconst FREE_LIST_HEADER = 8                   // "next" 指针大小
const FREE_LIST_CAP = (BTREE_PAGE_SIZE - FREE_LIST_HEADER) / 8 // 每页能存储的条目数// 获取和设置方法
func (node LNode) getNext() uint64 { /* 返回 next 指针 */ }
func (node LNode) setNext(next uint64) { /* 设置 next 指针 */ }
func (node LNode) getPtr(idx int) uint64 { /* 获取第 idx 个条目 */ }
func (node LNode) setPtr(idx int, ptr uint64) { /* 设置第 idx 个条目 */ }

元页面(meta page)中存储了指向头节点和尾节点的指针。尾节点指针的存在是为了实现 O(1) 的插入操作。

磁盘布局示例:

                        first_item↓
head_page -> [ next | xxxxx ]↓[ next | xxxxxxxx ]↓
tail_page -> [ NULL | xxxxxx    ]↑last_item

自由列表节点的更新

在没有自由列表的情况下,元页面是唯一需要原地更新的页面。这是写时复制机制使得崩溃恢复变得简单的原因之一。

引入自由列表后,会有两种额外的原地更新操作:

  1. 更新链表节点的 next 指针。
  2. 在链表节点中追加条目。

尽管链表节点是原地更新的,但在页面内部不会覆盖已有数据。因此,即使更新中断,元页面仍然指向相同的数据,不需要额外的崩溃恢复机制。此外,与元页面不同,链表节点的原子性不是必需的。


嵌入式链表的可行性

嵌入式链表也可以工作,但前提是 B+ 树节点中需要预留 next 指针的空间。这种方法虽然可行,但会导致写放大效应加倍(write amplification doubles)。具体来说:

  • 写放大效应是指为了完成一次逻辑写操作而实际写入的物理数据量。
  • 如果在 B+ 树节点中嵌入 next 指针,则每次更新不仅需要更新节点本身,还需要更新链表结构,从而增加了写入量。

总结

通过将自由列表设计为基于页面的链表,我们实现了以下目标:

  1. 高效的内存管理:自由列表能够自我维护,并且支持快速分配和释放页面。
  2. 与写时复制的兼容性:通过追加写入的方式避免覆盖数据,减少了崩溃恢复的复杂性。
  3. 灵活性:可以选择外部链表或嵌入式链表,根据性能和存储需求进行权衡。

这种设计为数据库系统中的磁盘空间管理提供了一种优雅的解决方案。

在这一节中,我们详细讨论了自由列表(Free List)的实现方法。自由列表是一种用于管理未使用页面的数据结构,它通过链表的形式组织页面编号,并支持高效的分配和回收操作。以下是对自由列表实现的逐步分析和总结。


自由列表接口设计

核心数据结构

自由列表是 KV 数据库中的一个额外组件:

type KV struct {Path string// 内部字段fd   inttree BTreefree FreeList // 自由列表// ...
}

FreeList 是自由列表的核心结构,包含以下内容:

  1. 回调函数:用于管理磁盘上的页面。
    • get:读取页面。
    • new:追加新页面。
    • set:更新现有页面。
  2. 持久化数据:存储在元页面中。
    • headPagetailPage:分别指向链表头节点和尾节点。
    • headSeqtailSeq:单调递增的序列号,用于索引头节点和尾节点中的条目。
  3. 内存状态
    • maxSeq:保存上一次的 tailSeq,以防止消费刚刚添加的条目。
type FreeList struct {// 回调函数get func(uint64) []byte // 读取页面new func([]byte) uint64 // 追加新页面set func(uint64) []byte // 更新现有页面// 持久化数据headPage uint64 // 头节点指针headSeq  uint64 // 头节点序列号tailPage uint64 // 尾节点指针tailSeq  uint64 // 尾节点序列号// 内存状态maxSeq uint64 // 上一次的 tailSeq
}
接口方法
  • PopHead():从链表头部移除一个条目。
  • PushTail(ptr uint64):向链表尾部添加一个条目。
  • SetMaxSeq():将 maxSeq 更新为当前的 tailSeq,以允许消费新添加的条目。

自由列表的操作

1. 从头部消费

从自由列表中移除条目时,只需递增 headSeq。如果当前头节点为空,则移动到下一个节点,并将空节点回收到自由列表中。

func (fl *FreeList) PopHead() uint64 {ptr, head := flPop(fl)if head != 0 { // 回收空的头节点fl.PushTail(head)}return ptr
}func flPop(fl *FreeList) (ptr uint64, head uint64) {if fl.headSeq == fl.maxSeq {return 0, 0 // 无法继续消费}node := LNode(fl.get(fl.headPage))ptr = node.getPtr(seq2idx(fl.headSeq)) // 获取条目fl.headSeq++// 如果当前头节点已空,移动到下一个节点if seq2idx(fl.headSeq) == 0 {head, fl.headPage = fl.headPage, node.getNext()assert(fl.headPage != 0) // 确保链表至少有一个节点}return
}
2. 向尾部追加

向自由列表尾部添加条目时,递增 tailSeq。如果当前尾节点已满,则创建一个新的尾节点,并确保链表始终至少有一个节点。

func (fl *FreeList) PushTail(ptr uint64) {// 将条目添加到尾节点LNode(fl.set(fl.tailPage)).setPtr(seq2idx(fl.tailSeq), ptr)fl.tailSeq++// 如果尾节点已满,添加新的尾节点if seq2idx(fl.tailSeq) == 0 {next, head := flPop(fl) // 尝试从头节点回收空节点if next == 0 {// 如果没有可回收的节点,则分配新节点next = fl.new(make([]byte, BTREE_PAGE_SIZE))}// 链接到新尾节点LNode(fl.set(fl.tailPage)).setNext(next)fl.tailPage = next// 如果头节点被移除,则将其添加到新尾节点if head != 0 {LNode(fl.set(fl.tailPage)).setPtr(0, head)fl.tailSeq++}}
}

关键点分析

1. 序列号的设计
  • headSeqtailSeq 是单调递增的序列号,用于唯一标识链表中的位置。
  • 通过 seq2idx(seq) 将序列号映射到节点内的索引,避免直接操作环形缓冲区的复杂性。
func seq2idx(seq uint64) int {return int(seq % FREE_LIST_CAP)
}
2. 自我管理

自由列表是自我管理的:

  • 被移除的头节点会被重新添加到尾部。
  • 在需要新节点时,优先尝试从头节点回收空节点,而不是直接分配新节点。
3. 崩溃恢复

由于自由列表的更新是基于追加写入的,即使中断也不会覆盖已有数据。因此,崩溃恢复机制与写时复制树一致,无需额外处理。


总结

自由列表的实现通过以下几个关键特性,确保了其高效性和可靠性:

  1. 基于页面的链表:每个页面可以存储多个条目,减少了节点数量,提高了空间利用率。
  2. 自我管理能力:被移除的节点会自动回收,避免了外部干预。
  3. 崩溃安全性:通过追加写入的方式,保证了崩溃后的一致性。
  4. 灵活性:支持动态扩展和收缩,能够适应不同的工作负载。

这种设计使得自由列表成为数据库系统中管理未使用页面的理想选择。

在这一节中,我们详细讨论了如何将自由列表(Free List)集成到键值存储(KV)数据库中,并分析了页面管理的实现细节。通过引入自由列表,数据库能够高效地重用未使用的页面,从而减少磁盘空间的浪费。


1. 页面管理

核心数据结构

为了支持页面的重用和原地更新,KV 数据库新增了一个 page 结构,用于管理页面的状态:

type KV struct {// ...page struct {flushed  uint64            // 已刷新的页面数量nappend  uint64            // 待追加的页面数量updates  map[uint64][]byte // 待处理的页面更新,包括追加的页面}
}
  • updates:一个映射表,用于捕获待处理的页面更新。当页面被修改时,其新内容会先存储在这里,而不是直接写入磁盘。
  • flushednappend:分别记录已刷新的页面数量和待追加的页面数量。

2. 页面分配与更新

2.1 分配新页面

BTree.new 方法现在由 KV.pageAlloc 替代。在分配页面时,优先从自由列表中获取空闲页面,只有在自由列表为空时才追加新页面。

func (db *KV) pageAlloc(node []byte) uint64 {if ptr := db.free.PopHead(); ptr != 0 { // 尝试从自由列表获取页面db.page.updates[ptr] = nodereturn ptr}return db.pageAppend(node) // 追加新页面
}
2.2 更新现有页面

KV.pageWrite 方法返回一个可写的页面副本,用于捕获原地更新。如果页面已经有待处理的更新,则直接返回该副本;否则从磁盘读取页面内容并创建一个新副本。

func (db *KV) pageWrite(ptr uint64) []byte {if node, ok := db.page.updates[ptr]; ok {return node // 返回待处理的更新}node := make([]byte, BTREE_PAGE_SIZE)copy(node, db.pageReadFile(ptr)) // 从磁盘初始化db.page.updates[ptr] = nodereturn node
}
2.3 读取页面

由于页面可能已经被更新,KV.pageRead 方法需要优先检查 updates 映射表。如果页面有未提交的更新,则直接返回更新后的内容;否则从磁盘读取。

func (db *KV) pageRead(ptr uint64) []byte {if node, ok := db.page.updates[ptr]; ok {return node // 返回待处理的更新}return db.pageReadFile(ptr) // 从磁盘读取
}

3. 元页面更新

元页面(meta page)是数据库的核心元数据,包含了树根指针、自由列表指针等信息。引入自由列表后,元页面的格式如下:

| sig | root_ptr | page_used | head_page | head_seq | tail_page | tail_seq |
| 16B |    8B    |    8B     |    8B     |    8B    |    8B     |    8B    |
  • head_pagetail_page:分别指向自由列表的头节点和尾节点。
  • head_seqtail_seq:用于索引自由列表中的条目。
  • page_used:记录当前数据库中已使用的页面数量。
3.1 初始化空数据库

在初始化一个空数据库时,需要为元页面和自由列表预留至少两个页面:

  • 第一页是元页面。
  • 第二页是自由列表的初始节点。
func readRoot(db *KV, fileSize int64) error {if fileSize == 0 { // 空文件// 预留两个页面:元页面和自由列表节点db.page.flushed = 2// 添加一个初始节点到自由列表,确保它永远不会为空db.free.headPage = 1 // 第二个页面db.free.tailPage = 1return nil // 元页面将在第一次更新时写入}// ...
}
3.2 准备下一次更新

在每次更新之间,调用 SetMaxSeq() 方法以允许重用上一版本的页面。

func updateFile(db *KV) error {// ...// 为下一次更新准备自由列表db.free.SetMaxSeq()return nil
}

4. 关键点分析

4.1 自由列表的作用
  • 自由列表使得未使用的页面可以被重用,减少了磁盘空间的浪费。
  • 在分配新页面时,优先从自由列表中获取空闲页面,只有在自由列表为空时才追加新页面。
4.2 原地更新的安全性
  • 页面更新被捕获在 updates 映射表中,直到提交时才会写入磁盘。
  • 由于页面更新是基于追加写入的,即使中断也不会覆盖已有数据,因此崩溃恢复机制仍然有效。
4.3 元页面的一致性
  • 元页面包含自由列表的指针和序列号,这些信息与树根指针一起原子性地更新,确保了一致性。

5. 并发支持的展望

目前的实现假设页面访问是顺序的。在后续引入并发支持时,headSeq 的推进将受到最老的读取操作的限制,而不是简单的 maxSeq


总结

通过引入自由列表,KV 数据库实现了以下目标:

  1. 高效的页面重用:通过自由列表管理未使用的页面,减少了磁盘空间的浪费。
  2. 安全的原地更新:通过 updates 映射表捕获页面更新,确保了崩溃恢复的安全性。
  3. 一致的元数据管理:元页面包含自由列表的指针和序列号,与树根指针一起原子性地更新。

这种设计为数据库系统提供了一种高效且可靠的页面管理机制,同时为后续引入并发支持奠定了基础。

相关文章:

空闲列表:回收和再利用

空闲列表:回收和再利用 手动与自动内存管理 手动管理:程序员需要明确地分配和释放内存。自动管理:例如使用垃圾收集器(GC),它能够自动检测并回收未使用的对象,不需要程序员干预。 对于某些数据结构如B树,…...

功能脑网络较新的方法[和ai讨论的方向和学习资源]

文章目录 前言和回顾代码实现ai 提问大脑连通性分析方法扩展与分类指南一、现有方法的补充与分类1. 补充的其他连通性方法2. 分类框架 二、近年来的新方法(2019年后)1. 相位动力学扩展2. 信息论与复杂度3. 基于图论与网络科学4. 动态系统与因果推断 三、…...

【MongoDB + Spark】 技术问题汇总与解决方案笔记

场景背景 最近练手项目:Spark 结合 MongoDB 构建商品推荐系统的过程中,过程中出现多种环境配置与兼容性问题,主要涉及 MongoDB 连接、版本兼容性、Casbah 驱动使用问题等。汇总调试过程中遇到的常见错误及其解决方案,供参考复用。…...

给git配置SSH(github,gitee)

更多个人笔记:(仅供参考,非盈利) gitee: https://gitee.com/harryhack/it_note github: https://github.com/ZHLOVEYY/IT_note 本文基于mac,linux和win可以参考 个人同时配置gitee和github的ss…...

Linux基础使用-笔记

1. 文件和目录操作 查看当前目录:pwd 命令用于显示当前工作目录的完整路径。 pwd切换目录:cd 命令用于切换工作目录。 # 切换到指定目录 cd /home/user/Documents # 切换到上一级目录 cd .. # 切换到用户主目录 cd ~列出目录内容:ls 命令用…...

什么是Maven

Maven的概念 Maven是一个一键式的自动化的构建工具。Maven 是 Apache 软件基金会组织维护的一款自动化构建工具,专注服务于Java 平台的项目构建和依赖管理。Maven 这个单词的本意是:专家,内行。Maven 是目前最流行的自动化构建工具&#xff0…...

DNS主从同步及解析

DNS 域名解析原理 域名系统的层次结构 :DNS 采用分层树状结构,顶级域名(如.com、.org、.net 等)位于顶层,下面是二级域名、三级域名等。例如,在域名 “www.example.com” 中,“com” 是顶级域名…...

Git 的基本概念和使用方式

Git 是一种分布式版本控制系统,广泛用于跟踪文件的变化和协作开发项目。以下是 Git 的基本概念和使用方式: 仓库(Repository):Git 用来存储项目文件和历史记录的地方。可以是本地仓库(Local Repository)或远程仓库(Remote Repository)。 工作区(Working Directory):…...

【C++】二叉树进阶面试题

根据二叉树创建字符串 重点是要注意括号省略问题,分为以下情况: 1.左字树为空,右子树不为空,左边括号保留 2.左右子树都为空,括号都不保留 3。左子树不为空,右子树为空,右边括号不保留 如果根节…...

时序数据库IoTDB构建的能源电力解决方案

随着能源格局的快速变化与“双碳”战略的逐步践行,电力系统的绿色低碳转型已成为重要发展趋势。在这一背景下,数字化、智能化技术正逐步扩大在新型电力系统发电侧、电网侧、储能侧的应用,以推动传统电力发输配用向全面感知、双向互动、智能高…...

【KWDB 创作者计划】_上位机知识篇---Github

文章目录 前言1. GitHub 核心功能(1) 代码托管(Git 仓库)存储代码版本控制代码浏览(2) 协作开发Pull RequestlssuesProjectsDiscussions(3) 自动化与 CI/CDGitHub ActionsGitHub PagesDependabot(4) 社区与开源ForkStarWatchSponsor2. GitHub 基本使用方法(1) 创建仓库(Repo…...

vxe-table封装表头

待补充使用说明,但是可以用 一.效果二.封装MyTable.vue1.封装index.vue2.日期选择筛选3.输入筛选4.下拉筛选5.多选筛选6.远程多选筛选7.远程单选筛选 三、页面使用1.具体页面使用2./utils/filter.js 注意:需要使用jsx、vxe-table、element-plus 一.效果 …...

力扣hot100 91-100记录

91-100 &#xff08;动态规划&#xff09; class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> f(m, vector<int>(n, 1));for(int i 1; i < m; i){for(int j 1; j < n; j){f[i][j] f[i-1][j] f[i][j-1];} }return f[…...

SpringMVC处理请求映射路径和接收参数

目录 springmvc处理请求映射路径 案例&#xff1a;访问 OrderController类的pirntUser方法报错&#xff1a;java.lang.IllegalStateException&#xff1a;映射不明确 核心错误信息 springmvc接收参数 一 &#xff0c;常见的字符串和数字类型的参数接收方式 1.1 请求路径的…...

ESP32上C语言实现JSON对象的创建和解析

在ESP32上使用C语言实现JSON对象的创建和解析&#xff0c;同样可以借助cJSON库。ESP-IDF&#xff08;Espressif IoT Development Framework&#xff09;本身已经集成了cJSON库&#xff0c;你可以直接使用。以下是详细的步骤和示例代码。 1. 创建一个新的ESP-IDF项目 首先&…...

关于Qt对Html/CSS的支持

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、原生控件二、QtWebEngine总结 前言 最近遇到了一些问题需要使用Qt加载Html发现一些特性不能使用&#xff0c;估计很多人也和我一样遇到这种情况。需要说明…...

Python 读取 txt 文件详解 with ... open()

文章目录 1 概述1.1 注意事项1.2 模式说明1.3 文件准备 2 读文件2.1 读取整个文件2.2 逐行读取2.3 读取所有行到列表 3 写文件3.1 覆盖写入3.2 追加写入3.3 写入多行 4 实用技巧4.1 检查文件是否存在4.2 异常处理 1 概述 1.1 注意事项 文件编码&#xff1a;建议指定编码&…...

[Mac] 使用homebrew安装miniconda

使用虚拟环境可以对不同项目的依赖进行隔离。可以使用venv或者conda来创建和使用虚拟环境。 venv是Python内置的虚拟环境管理模块&#xff0c;适合纯Python项目以及快速轻量级的开发和部署。conda具备更强大的版本管理能力&#xff0c;但是占用较大的磁盘空间。 考虑到我基本不…...

如何获取适用于广告过滤增强的Chrome浏览器版本【广告净化】

不少人使用浏览器时&#xff0c;会遇到广告弹窗、视频前贴广告或页面跳转。这些情况会影响上网体验。想要改善&#xff0c;可以从选择合适版本的谷歌浏览器开始&#xff0c;并加上合理设置。 先打开电脑上的浏览器&#xff0c;在搜索栏中输入“谷歌浏览器官方下载页面”。找到带…...

JVM(Java虚拟机)详解

目录 1 JVM执行流程 2 JVM运行时数据区&#xff08;内存布局&#xff09; 2.1 堆 2.2 栈 2.3 方法区 2.4 程序计数器 2.5 Java和运行时数据区相关的异常 3 JVM类加载&#xff08;Class Loading&#xff09; 3.1 加载Loading 3.2 连接Linking 3.2.1 验证Verification…...

Vue3 + TypeScript,使用provide提供只读的响应式数据的详细分析与解决方法

原始无类型写法&#xff08;不报错&#xff09; typescript const applySampleTableData ref<ApplySample[]>([]); const applySampleListSymbol Symbol("applySampleList"); provide(applySampleListSymbol, readonly(applySampleTableData)); 类型推断&a…...

深入理解 BLE PHY 模式:1M、2M 与 Coded 的演进与应用

随着蓝牙技术不断演进,BLE(Bluetooth Low Energy)在物联网、可穿戴设备、智能家居等领域的应用愈发广泛。BLE 中的 PHY(Physical Layer,物理层)是决定无线传输速率、覆盖范围和功耗的核心因素。本文将以浅显易懂的语言,结合示意图和代码示例,系统梳理 BLE 三种 PHY 模式…...

人工智能与机器学习:二元分类决策树构建指南

引言 在人工智能与机器学习的领域里&#xff0c;算法犹如智慧的钥匙&#xff0c;开启着数据洞察的大门。决策树作为其中一颗璀璨的明珠&#xff0c;以其独特的非线性处理能力和可解释性备受瞩目。今天&#xff0c;让我们跟随作者的脚步&#xff0c;深入探究如何构建一个用于二…...

Ubuntu下软件运行常见异常退出问题汇总分析

软件在Ubuntu下运行时&#xff0c;可能会遇到各种异常退出情况&#xff0c;常见可分为以下几点&#xff1a; 目录 一、系统资源耗尽导致退出 二、权限导致无法运行 三、找不到依赖的动态库 四、编译可执行文件时&#xff0c;动态库所引用的头文件与动态库不匹配 一、系统资…...

机器学习漏洞大汇总——利用机器学习服务

在本节中,我们将展示机器学习框架中存在的漏洞,这些漏洞会直接处理模型工件,或者通过工件存储或模型注册表的凭证来处理。利用此类漏洞,攻击者可以在企业系统内部进行非常强大的横向移动,从而劫持被利用的模型注册表中的机器学习模型。 WANDB Weave 目录遍历 - CVE-2024-…...

类的六个默认成员函数

如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会生成的成员函数称为默认…...

精益数据分析(21/126):剖析创业增长引擎与精益画布指标

精益数据分析&#xff08;21/126&#xff09;&#xff1a;剖析创业增长引擎与精益画布指标 大家好&#xff01;在创业和数据分析的探索道路上&#xff0c;我一直希望能和大家携手共进&#xff0c;共同学习。今天&#xff0c;我们继续深入研读《精益数据分析》&#xff0c;剖析…...

SAIL-RK3588协作机器人运动控制器技术方案

一、核心能力与政策适配‌ ‌政策合规性‌ 满足工信部《智能机器人重点技术攻关指南》要求&#xff0c;支持 ‌EtherCAT主站协议&#xff08;符合IEC 61158标准&#xff09;‌&#xff0c;助力企业申报工业机器人研发专项补贴&#xff08;最高300万元/项目&#xff09;‌核心板…...

手搓箱图并输出异常值(MATLAB)

看下需求 想要复刻这种箱图&#xff0c;咱们直接开始手搓 %% 可修改 % 生成模拟数据&#xff08;假设5个用户群体的发帖数&#xff09; data {randn(100,1)*10 30, ... % 核心用户randn(200,1)*5 10, ... % 边缘用户randn(150,1)*8 20, ... % 积极社交用户randn(8…...

Java:XML被自动转义

在Java中处理XML响应被自动转义的问题时&#xff0c;需结合XML规范及工具特性进行针对性处理。以下是常见原因及解决方案的总结&#xff1a; ‌一、XML自动转义的原因‌ ‌字符安全性处理‌ XML中的保留字符&#xff08;如 <、>、&&#xff09;会被自动转义为实体&a…...

Day-3 应急响应实战

应急响应实战一&#xff1a;Web入侵与数据泄露分析 1. Web入侵核心原理 ​​漏洞利用路径​​ 未授权访问&#xff1a;弱口令&#xff08;如空密码/默认口令&#xff09;、目录遍历漏洞代码注入攻击&#xff1a;JSP/ASP木马、PHP一句话木马&#xff08;利用eval($_POST[cmd])&…...

【软件设计师】模拟题一

以下是 ​​10道软考-软件设计师模拟试题​​&#xff0c;涵盖高频考点和易错点&#xff0c;附带答案和解析&#xff1a; ​​一、软件工程​​ ​​1. 在软件开发生命周期中&#xff0c;瀑布模型的主要特点是&#xff08; &#xff09;​​ A. 强调快速原型迭代 B. 阶段间有明…...

每日一练(4~24):互质的数【省模拟赛】

算法&#xff1a;暴力枚举 问题描述 如果两个整数 a, b 除了 1 以外&#xff0c;没有其它的公约数&#xff0c;则称整数 a 与 b 互质。 请问&#xff0c;与 2024 互质的数&#xff08;包括 1&#xff09;中&#xff0c;第 2024 小的是多少&#xff1f; 答案提交 这是一道结…...

金融软件测试有哪些注意事项?专业第三方软件测试服务机构分享

在现代金融行业中&#xff0c;软件系统的稳定性和安全性直接关系到资金的安全和业务的正常运转。金融软件因涉及庞大的资金流和敏感的个人及交易信息&#xff0c;对软件测试提出了更高的要求&#xff0c;那么金融软件在进行测试时有哪些注意事项呢?卓码软件测评作为专业的第三…...

关于QT信号、槽、槽函数的讲解

也是好久没有发帖子了&#xff0c;最近博主主要还是在边学QT边完成任务&#xff0c;所以进度很慢&#xff0c;但确实在这几天对于QT自身槽和信号这类特殊的机制有了一定简单的理解&#xff0c;所以还是想记录下来&#xff0c;如果有初学者看到帖子对他有一定的帮助&#xff0c;…...

算法训练营第三十天 | 动态规划 (三)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、01背包问题理论基础&#xff08;一&#xff09;动态规划五部曲确定dp数组以及下标的含义确定递推公式初始化dp数组确定遍历顺序 二、01背包问题理论基础&#…...

Vue开发网站会有“#”原因是前端路由使用了 Hash 模式

前言 网站链接中出现 #&#xff08;井号&#xff09;是因为你的前端路由使用了 Hash 模式&#xff08;hash mode&#xff09;&#xff0c;这是一种前端框架&#xff08;如 Vue.js、React 等&#xff09;中常用的路由策略。 为什么有 # 比如 https://www.zimeinew.com/#/order…...

SpringBootTest报错

Unable to find a SpringBootConfiguration, you need to use ContextConfiguration or … 解决方案&#xff1a;在SpringTest注解中添加属性&#xff08;classes &#xff09;填写启动类 如我的启动类是MainApplication.class javax.websocket.server.ServerContainer no…...

【质量管理】现代TRIZ(萃智)理论概述

一、什么是TRIZ理论 TRIZ理论,即发明问题解决理论(Teoriya Resheniya Izobreatatelskikh Zadatch),是由前苏联发明家根里奇阿奇舒勒(Genrich S. Altshuller)于1946年创立的。它是一门基于知识的、面向人的发明问题解决系统化方法学。TRIZ理论通过研究大量的专利,总结出技…...

前端面经-JS篇(四)--回调地狱、promise异步编程、Proxy 与 Reflect 、模块化

一、回调地狱 回调地狱&#xff08;Callback Hell&#xff09;&#xff0c;也称为回调地狱&#xff0c;是指在 JavaScript 中处理多个嵌套的异步回调函数时&#xff0c;代码结构变得非常难以阅读和维护的现象。 为什么会出现回调地狱&#xff1f; 回调地狱通常出现在需要执行…...

【oql】spark thriftserver内存溢出,使用oql查询导致oom的sql

eclipse memory analyzer (mat)软件内的OQL实现查询内促信息。 帮助信息&#xff1a;软件Help/Help Contents/Querying Heap Objects (OQL) 就是查询SparkExecuteStatementOperation 的statement 字段。 select objects s.statement from org.apache.spark.sql.hive.thriftser…...

算法设计与分析(基础)

问题列表 一、 算法的定义与特征&#xff0c;算法设计的基本步骤二、 算法分析的目的是什么&#xff1f;如何评价算法&#xff0c;如何度量算法的复杂性&#xff1f;三、 递归算法、分治法、贪婪法、动态规划法、回溯法的基本思想方法。四、 同一个问题&#xff0c;如TSP&#…...

爬虫学习——使用HTTP服务代理、redis使用、通过Scrapy实现分布式爬取

一、使用HTTP服务代理 由于网络环境、网站对用户的访问速度的限制等原因&#xff0c;使得爬取过程会出现IP被封禁&#xff0c;故使用代理可提高爬取速度。在Scrapy中提供了一个HttpProxyMiddleware专门用于进行爬虫代理设置。在使用该代理进行爬取操作时&#xff0c;需要先在ba…...

机器学习中的特征存储是什么?我需要一个吗?

本质上,特征存储是一个专用存储库,用于系统地存储和排列特征,主要用于数据科学家训练模型,并帮助已训练模型的应用程序进行预测。它是一个关键的聚合点,人们可以在此构建或修改从各种数据源提取的特征集合。此外,它还支持从这些特征组中创建和增强新的数据集,以满足处于…...

【C语言】C语言中的联合体与枚举类型

前言 在C语言中&#xff0c;联合体&#xff08;union&#xff09;和枚举&#xff08;enum&#xff09;是两种非常实用但又常被忽视的自定义数据类型。它们在内存管理、代码可读性以及程序设计的灵活性方面都有着独特的优势。今天&#xff0c;我们就来深入探讨一下联合体和枚举…...

Golang编程拒绝类型不安全

button-chen/containertypesafe-go: 使用泛型包装标准库的容器 list、ring、heap、sync.Pool 和 sync.Map&#xff0c;实现类型安全 简介 在 Go 中&#xff0c;标准库提供了多种容器类型&#xff0c;如 list、ring、heap、sync.Pool 和 sync.Map。然而&#xff0c;这些容器默认…...

炼锌废渣提取钴工艺流程

炼锌废渣中提取钴的工艺流程通常结合湿法冶金技术&#xff0c;针对废渣中钴与锌、铁、铜等金属的复杂共生特性&#xff0c;通过预处理、浸出、除杂、钴富集及提纯等步骤实现钴的高效回收。以下是典型工艺流程的详细说明&#xff1a; 一、预处理 炼锌废渣&#xff08;如锌浸出…...

Restful接口学习

一、为什么RESTful接口是数据开发的核心枢纽&#xff1f; 在数据驱动的时代&#xff0c;RESTful接口如同数据高速公路上的收费站&#xff0c;承担着数据交换的核心职责。数据工程师每天需要面对&#xff1a; 异构系统间的数据交互&#xff08;Hadoop集群 ↔ 业务系统&#xf…...

仿真每日一练 | ABAQUS应力松弛

应力松弛是弹性材料在应力作用下产生微塑性变形&#xff0c;并且逐渐积累&#xff0c;在保持应变或者位移不变的前提下&#xff0c;表现为应力逐渐下降的现象。今天介绍一个ABAQUS中应力松弛的相关案例&#xff0c;模型如下所示&#xff1a; 图1 模型认识 回顾一下ABAQUS的有限…...

智能电网第4期 | 电力设备全连接组网方案:从有线到无线无缝融合

随着新型电力系统建设的加速推进&#xff0c;电力设备通信网络正面临前所未有的挑战与机遇。在变电站自动化、输电线路监测、配电房智能化等场景中&#xff0c;传统通信方案已难以满足日益增长的连接需求&#xff1a; 环境复杂性&#xff1a;变电站强电磁干扰环境下需保障微秒级…...