005.精读《B-Tree vs LSM-Tree》

news2024/11/25 10:29:20

文章目录

    • 1. 引言:
    • 2. 精读
      • 2.1 性能指标
      • 2.2 B-tree
      • 2.3 LSM-tree
      • 2.4 性能对比
    • 3. 写在最后

1. 引言:

在本期的技术深度解析中,我们将聚焦于数据领域的两个重要成员——B-TreeLSM-Tree。这两种数据结构在数据管理系统中最为普遍且广泛采用的数据结构。B-Tree以其在磁盘存储系统中的广泛应用而闻名,而LSM-Tree则因其在写入优化方面的表现而受到青睐。随着数据量的不断增长和数据访问模式的多样化,理解这两种数据结构的优势和局限变得尤为重要。本期精读:B-Tree vs LSM-Tree

通过本文,我们将带领读者:

  1. 探讨B-TreeLSM-Tree的起源,它们分别是为了解决什么样的问题而被引入的;
  2. 深入剖析B-TreeLSM-Tree的数据结构特点,以及它们如何在不同的应用场景中发挥作用;
  3. 解析在实际应用中,B-TreeLSM-Tree如何优化存储和检索效率,以及它们在不同数据库系统中的应用案例;
  4. 展望B-TreeLSM-Tree在未来的发展,以及它们在大数据时代中的潜在影响。

欢迎在评论区分享您的观点与见解,期待与您交流讨论!

2. 精读

2.1 性能指标

在评估数据结构的性能时,三个关键指标——写放大、读放大和空间放大——为我们提供了衡量效率和优化程度的量化手段。这些指标不仅帮助我们理解数据结构在实际应用中的表现,还能够指导我们对它们进行针对性的优化。以下是对这些指标重要性的详细阐述:

  1. 写放大(Write Amplification):写放大是指在数据写入过程中,由于数据结构的维护和管理,实际写入存储介质的次数超过了原始数据量的情况。在B树中,每次插入或更新操作可能涉及多次磁盘I/O操作,因为B树需要保持其平衡特性。LSM树虽然通过批量写入减少了磁盘I/O,但在合并过程中也会产生额外的写入。写放大对于理解数据结构的耐久性和性能至关重要,因为它直接关系到存储介质的寿命和系统的能耗。由于闪存的这种工作方式,必须擦除改写的闪存部分比新数据实际需要的大得多。写入放大的主要有以下几个因素:
因素描述类型关系*
垃圾回收用来挑选用于擦除和重写的最佳块的算法的效率变量反面(小为好)
预留空间分配到SSD控制器的物理容量百分比变量反面(小为好)
SATA的TRIM命令 或 SCSI中的UNMAP这些命令必须由操作系统(OS)发送,可以通知存储设备哪些扇区含有无效数据。可以处理这些命令的SSD能在擦除块时,将包含这些扇区的页作为空闲空间回收,而不是复制无效的数据到干净的页中。开关正向(小为好)
空闲用户容量没有实际用户数据的用户容量百分比;需要TRIM,否则SSD不会从任何空闲的用户容量中获得好处变量反面(小为好)
安全擦除擦除所有的用户数据和相关元数据,将SSD的性能重置到最初状态(直至重新开始垃圾回收)开关正向(小为好)
耗损均衡算法的效率,令每块的写入次数与其他的块尽可能相同变量正面(大为坏)
静动数据分离将数据按修改频率分组开关正向(小为好)
顺序写入理论上,顺序写入的写入放大为1,但其他因素仍会影响此值开关正向(小为好)
随机写入写入到非连续的LBA对写入放大的影响最大开关反向(大为坏)
数据压缩,包括重复数据删除数据压缩和重复数据删除能消除更多的冗余数据,降低写入放大,同时提升SSD速度。变量反面(小为好)
以SLC模式使用MLC NAND以每单元1位,而不是以设计的每单元位数(通常为每单元2位)写入数据,以加快读取和写入操作。如果临近SLC模式下的NAND容量限制,SSD必须把旧有用SLC模式写入的数据改写为MLC或TLC模式,才能让SLC模式的NAND空间释放出来,以便容纳更多的数据。然而,通过让经常更改的页面维持在SLC模式,而不是以MLC或TLC模式修改,这种做法也可以降低磨损,因为比用SLC模式,用MLC或TLC模式写入对闪存的伤害确实更大。因此,这种做法提高了写入放大,但当写入模式设为向常写页面上写入时,却可以减少磨损。然而,顺序和随机写入却会加剧磨损,因为这样就没有或少有频繁写入的页是SLC模式,迫使旧数据不断地从SLC模式改写到MLC或TLC。开关反向(大为坏)
  1. 读放大(Read Amplification):读放大是指为了获取所需数据,数据结构需要读取的数据量超过了原始请求的数据量。在B树中,为了找到一个键,可能需要访问多个节点,尤其是当树的高度增加时。LSM树在读取数据时,可能需要检查多个层级的SSTable,以找到最新的数据版本。读放大影响了数据访问的效率,尤其是在读取密集型应用中,它可能导致性能瓶颈。

  2. 空间放大(Space Amplification):空间放大是指数据结构为了维护其性能特性,如B树的平衡性或LSM树的写入优化,而额外占用的存储空间。B树由于其结构特性,通常有较低的空间放大,因为它不需要额外的空间来维护数据的顺序。相反,LSM树为了优化写入性能,可能会保留多个数据版本,从而导致空间放大。空间放大对于存储成本和数据压缩策略有着直接的影响。

通过引入这些指标,我们能够更全面地评估和比较不同的数据结构,这意味着一种数据结构不太可能在所有三个方面都比另一种好。例如,B树的读放大比LSM树少,而LSM树的写放大比B树少。这些指标不仅帮助我们理解数据结构的工作原理,还能够指导我们如何针对特定的应用场景进行优化,以达到性能与资源利用之间的最佳平衡。从而在实际应用中做出更明智的选择。

2.2 B-tree

B树是一种自平衡的多路搜索树,它通过有序存储数据,确保查找、插入、删除和顺序访问操作的高效性,其时间复杂度为对数级别。B树节点分为内部节点和叶子节点,内部节点存储数据和子节点指针,而叶子节点仅存储数据。与二叉树不同,B树的每个节点可以拥有多个子节点,这使得它在处理大量数据时更为高效,特别是在磁盘存储系统中。AVL树作为自平衡二叉树的先驱,通过保持树的高度平衡,优化了二叉搜索树的性能。B树继承了这些优点,并在数据库和文件系统中得到广泛应用。

一棵m阶的B树是一种自平衡的树形数据结构,具有以下关键特性:

  1. 节点子节点限制:每个节点最多可以有m个子节点。
  2. 非叶子节点子节点最小值:除了根节点外,每个非叶子节点至少有m/2个子节点,如果m是偶数,则取m/2的上界,确保树的平衡性。
  3. 根节点子节点要求:如果根节点不是叶子节点,它至少需要有两个子节点,以维持树的结构。
  4. 键的有序性:在非叶子节点中,如果有k个子节点,则存在k-1个键,这些键按升序排列,即对于任意的i,都有 k[i] < k[i+1]
  5. 键的数量限制:每个节点包含的键的数量最多为2k-1,这是由子节点数量和键的有序性共同决定的。
  6. 叶子节点的同层性:所有的叶子节点都位于树的同一层,这有助于保持树的平衡和提高访问效率。

如上图展示了树的根节点位于顶部,在本例中恰好包含一个pivot(20),这表明键k满足k ≤ 20的记录存储在第一个子节点中,而键k满足k > 20的记录存储在第二个子节点中。第一个子节点包含两个pivot键(11和15),这表明键k满足k ≤ 11的记录存储在第一个子节点中,11 < k ≤ 15的记录存储在第二个子节点中,而k > 15的记录存储在第三个子节点中。最左边的叶子节点包含三个值(3, 5, 和 7)。

B+树是B树的增强版本,它在实际应用中,特别是在操作系统的文件索引和数据库索引方面,展现出比B树更高的适用性和效率。在现代关系型数据库中,B+树被广泛采用作为其索引结构的核心,这得益于其优化的数据存储和访问机制,使其成为处理大规模数据检索的首选数据结构。以下是B树和B+树的区别

特性B树B+树
数据存储位置内部节点和叶子节点都存储数据只有叶子节点存储数据,内部节点仅存储索引键
叶子节点链接叶子节点之间没有链接叶子节点之间通过指针相连,形成链表
查询效率适合随机访问,但范围查询和顺序访问效率较低适合范围查询和顺序访问,效率较高
磁盘I/O操作可能需要多次磁盘I/O操作来访问数据由于叶子节点形成链表,可以减少磁盘I/O操作次数
内部节点结构内部节点存储数据和子节点指针内部节点仅存储索引键和子节点指针
适用场景适用于需要随机访问和更新的场景适用于数据库和文件系统中的索引结构,特别是范围查询和顺序访问
节点分裂和合并当节点达到最大容量时分裂,容量过低时合并同样在节点达到最大容量时分裂,容量过低时合并
平衡性保持自平衡,通过旋转和重新分配节点来保持平衡同样自平衡,通过旋转和重新分配节点来保持平衡

2.3 LSM-tree

LSM树(Log-Structured Merge Tree)是一种高效的数据结构,专为优化数据的存储和检索而设计。它通过创新的数据组织方式,实现了高吞吐量的写入操作和高效的读取性能。LSM树的诞生旨在解决传统B树在面对大量写入操作时的性能限制,尤其适用于高写入负载的环境,如分布式数据库系统、日志记录系统和缓存机制等。

LSM树的核心理念是将随机写入操作转换为顺序写入,这一策略显著提升了写入效率。在LSM树中,所有新的数据首先被写入内存中的写入缓冲区,随后定期批量写入到一个有序的日志文件中。由于这些写入操作主要在内存中完成,因此大大减少了对磁盘的随机写入需求,从而极大提高了整体写入性能。随着时间的积累,内存中的数据会通过合并过程逐步迁移到磁盘上的多个层级,这样做不仅保持了数据的有序性,也确保了数据的持久化存储。

内存中的数据结构

  1. Memtable
  • 描述:内存中的可变数据结构,存储最新的写入数据。
  • 实现:常用跳表、红黑树或AVL树,以支持快速的插入、删除和查找操作。
  1. Immutable Memtable
  • 描述:当Memtable达到设定的大小限制后,转变为不可变状态,等待刷写到磁盘的SSTable中。
  • 特点:不再接受新的写入,保持数据的稳定性。

磁盘上的数据结构

  1. SSTable
  • 描述:Sorted String Table,磁盘上的持久化数据结构,存储有序的键值对。
  • 特点:一旦写入,SSTable是只读的,按时间顺序组织。
  1. 布隆过滤器(Bloom Filter)
  • 描述:一种概率性数据结构,用于快速判断某个键是否可能存在于SSTable中。
  • 特点:高效减少不必要的磁盘I/O操作。
  1. 写前日志(WAL,Write-Ahead Log)
  • 描述:用于故障恢复的日志结构,记录所有写入操作。
  • 特点:提供持久性保障,以确保数据在崩溃后可恢复。

LSM-tree 写操作

在写入数据到 LSM 树时,主要流程包括 MemtableImmutable MemtableSSTable 的生成以及 Compaction 操作。

  1. Memtable:内存中的可变部分,用于快速写入新的键值对。
  2. Immutable Memtable:当 Memtable 达到大小限制后,转换为不可变状态,用于后续的持久化操作。
  3. SSTable:磁盘上的持久化文件,存储有序的键值对,通常伴随索引和布隆过滤器等辅助数据结构。
  4. Compaction:定期将多个 SSTable 合并,以优化存储和查询性能。
  1. 写入数据到 Memtable

    • 新的键值对首先写入内存中的可变 Memtable
    • Memtable 通常是一个有序的数据结构,例如跳表或红黑树。
Memtable:
key1 -> value1
key2 -> value2
key3 -> value3
  1. Memtable 达到大小限制并转换为 Immutable Memtable

    • Memtable 达到预设的大小限制(如 1MB),会被转换为 Immutable Memtable
    • 当前的 Memtable 被清空,并创建一个新的可变 Memtable,以接收新的写入。
Memtable 达到大小限制:
- 当前 Memtable 被转换为 Immutable Memtable:
  Immutable Memtable:
  key1 -> value1
  key2 -> value2
  key3 -> value3
- 创建一个新的空的 Memtable:
  Memtable: (空)
  1. Immutable Memtable 数据写入到 SSTable

    • Immutable Memtable 的数据会被刷新到磁盘,生成新的 SSTable
    • 数据从内存中按顺序写入 SSTable 文件,同时生成元数据(如索引和布隆过滤器)。
Immutable Memtable 数据被写入到新的 SSTable:
- 从 Immutable Memtable 读取数据
- 将数据以有序方式写入 SSTable 文件:
  SSTable 0:
  key1 -> value1
  key2 -> value2
  key3 -> value3
  1. 继续写入新数据到新的 Memtable

    • 清空后的 Memtable 继续接收新的数据写入。
    • 上一个 Immutable Memtable 已经开始持久化为 SSTable
写入操作:
应用程序 -> Memtable:(key4, value4)
应用程序 -> Memtable:(key5, value5)

Memtable:
key4 -> value4
key5 -> value5
  1. 定期执行 Compaction 操作

    • 随着 SSTable 文件的增加,系统定期执行 Compaction 操作,以合并多个 SSTable 文件。
    • Compaction 有助于移除重复或过期的数据,提升查询效率。
Compaction 之前:
SSTable 0:
key1 -> value1
key2 -> value2
key3 -> value3

SSTable 1:
key4 -> value4
key5 -> value5

Compaction 操作:
1. 选择 SSTables 0 和 1 进行合并。
2. 读取数据进行合并:
   合并后的数据:
   key1 -> value1
   key2 -> value2
   key3 -> value3
   key4 -> value4
   key5 -> value5
3. 写入合并后的数据到新的 SSTable:
   SSTable 2:
   key1 -> value1
   key2 -> value2
   key3 -> value3
   key4 -> value4
   key5 -> value5
4. 删除旧的 SSTables 0 和 1。

LSM-tree 读操作

LSM树的读操作依赖于有序查找和布隆过滤器的结合,逐级递进以提高查找效率并减少I/O操作。在读取某个键对应的值时,LSM树会从最新的数据开始查找,以确保返回最新的值。这个过程通常包括以下几个步骤:

  1. 检查 Memtable(C0)

首先,查找内存中的 Memtable(C0),因为它包含所有最新的写入。

value = C0.get(key)
if (value exists):
    return value
  1. 检查 Immutable Memtable

如果在 Memtable 中未找到对应的键,接着检查 Immutable Memtable。该 Memtable 是在最近写操作后达到一定大小而转为不可变状态,等待刷入磁盘。

value = ImmutableMemtable.get(key)
if (value exists):
    return value
  1. 检查 SSTables

如果上述步骤均未找到所需的值,则依次检查存储在磁盘上的多个层级 SSTables(C1, C2, …)。采用按时间顺序从最早到最近的方式进行搜索,以确保最新的更新覆盖旧值。

  • 布隆过滤器(Bloom Filter):在每个 SSTable 上使用布隆过滤器,可以快速判断一个值是否不在该文件中,从而减少不必要的磁盘 I/O 操作。
for level in SSTable_levels:
    for sstable in level:
        if sstable.BloomFilter.mightContain(key):
            value = sstable.get(key)
            if (value exists and not tombstoned(value)):
                return value
  1. 数据合并与删除标记

    • 删除标记(Tombstone):如果有删除操作,某些值会带有特殊标记。继续检查以下层级以确保数据删除的幂等性与正确性。
    • 合并读取(Merge Read):当查询经过多个 SSTable 文件时,需要实时合并以确保返回的值是最新的更新。

故障处理与缓存优化

  • WAL(Write-Ahead Log):用于故障恢复,保证数据在崩溃后的正确恢复。
  • 缓存机制:频繁访问的键会缓存在内存中,提高查询性能。有效的缓存策略有助于减少读取操作的延迟。

LSM-tree 更新和删除操作

LSM树的更新和删除操作实质上是写入操作的特例。在LSM树中,更新一个键值对意味着添加一个新的键值对,而删除则是添加一个带有删除标记的键值对

更新操作

  1. 写入Memtable:新的键值对首先被写入内存中的Memtable。如果键已经存在,旧的键值对会被新的键值对替换。
C0.put(key, newValue)
  1. 触发Compaction:当Memtable达到一定大小后,它会被转换为Immutable Memtable,并最终被写入磁盘上的SSTableCompaction过程会合并包含相同键的SSTable,确保最新的值被保留。

删除操作

  1. 标记删除:删除操作不是从MemtableSSTable中物理移除键值对,而是在Memtable中添加一个带有删除标记的键值对。
C0.put(key, tombstone)
  1. Compaction过程中的处理:在Compaction过程中,带有删除标记的键值对会被识别并忽略,从而实现数据的逻辑删除。

更新和删除的Compaction过程

Compaction过程中,LSM树会合并多个SSTable,包括MemtableImmutable Memtable。这个过程会处理所有的更新和删除标记:

  1. 合并数据Compaction会合并所有包含特定键的键值对,确保最新的更新被保留,删除标记的键值对会被忽略。

  2. 生成新的SSTable:合并后的数据会生成新的SSTable,旧的SSTable会被标记为可以被删除。

  3. 优化存储:通过CompactionLSM树可以优化存储空间的使用,移除过时的数据和删除标记,同时保持数据的有序性。

2.4 性能对比

为了解释如何得出B+树和基于级别的LSM树的写放大和读放大的具体计算过程,我们需要考虑它们的数据结构和操作特性。

B+树的读写放大

写放大(Write Amplification):
B+树的写放大主要来自于节点分裂和合并操作。当一个节点达到其最大容量时,它需要分裂成两个节点,这涉及到写入两个新节点的数据。因此,写放大与节点的大小B有关,即每次写入操作可能涉及到多个块的写入。在最坏的情况下,写放大可以达到Θ(B),即每个写入操作都需要写入整个节点的数据。

读放大(Read Amplification):
B+树的读放大取决于树的高度。在最坏的情况下,读取一个数据项可能需要从根节点遍历到叶节点,这涉及到树的高度的磁盘I/O操作。如果每个内部节点包含Θ(B)个孩子,那么树的高度是O(log_B N / B),其中N是数据库的大小。因此,读放大是树的高度,即O(log_B N / B)

LSM树的读写放大

写放大(Write Amplification):
LSM树的写放大较高,因为数据首先写入内存中的Memtable,然后定期刷新到磁盘上的SSTable。随着时间的推移,SSTable会经历多次合并(Compaction)操作,以优化存储和查询性能。每次合并操作都会涉及到写入多个SSTable的数据。如果每个级别的数据大小是前一个级别的k倍,那么写放大包括将数据从每个级别移动到下一个级别,以及在每个级别中重复合并数据。因此,写放大是Θ(k log_k N / B),其中k是每个级别的增长因子,N是数据库的大小。

读放大(Read Amplification):
LSM树的读放大涉及到从多个SSTable中读取数据,以确保获取到最新的数据项。在最坏的情况下,可能需要从所有级别中读取数据。对于最高级别,数据大小是O(N),因此需要O(log N / B)次磁盘I/O操作。对于前一个级别,数据大小是O(N/k),因此需要O(log (N/kB))次磁盘I/O操作。以此类推,对于第i个级别,需要O(log (N/k^i B))次磁盘I/O操作。将所有级别的磁盘I/O操作相加,总的读放大是Θ((log^2 N / B) / log_k)

综上所述可以得到:

Data StructureWrite AmplificationRead Amplification
B+ treeΘ(B)O(log_B N / B)
Level-Based LSM-treeΘ(k log_k N / B)Θ((log^2 N / B) / log_k)

其中,Θ表示大O记号中的紧确界(Theta notation),O表示大O记号,用于描述算法的渐进上界,log_B N表示以B为底N的对数,log_k N表示以k为底N的对数。

3. 写在最后

通过比较B+树和基于级别的LSM树在各种性能方面的表现,我们可以得出结论:基于级别的LSM树在写入性能上优于B+树,而在读取性能上则不如B+树。但是大多数组件选择使用LSM树而不是B树作为其底层存储引擎的主要原因是,利用缓存技术来提升读取性能要比提升写入性能容易得多

如果你想参与讨论,请 点击这里👉https://github.com/hiszm/BigDataWeekly,每周都有新的主题,周末或周一发布。

大数据精读,探索知识的深度。

关注 大数据精读周刊

版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证)

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

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

相关文章

关于 el-table 的合计行问题

目录 一.自定义合计行 二.合计行不展示&#xff0c;只有缩放/变大窗口或者F12弹出后台时才展示 三.合计行出现了表格滚动条下方 四.合计行整体样式的修改 五.合计行单元格样式修改 1.css 2.jsx方式 六.合计行单元格合并 一.自定义合计行 通过 show-summary 属性开启合计…

C++ | Leetcode C++题解之第554题砖墙

题目&#xff1a; 题解&#xff1a; class Solution { public:int leastBricks(vector<vector<int>>& wall) {unordered_map<int, int> cnt;for (auto& widths : wall) {int n widths.size();int sum 0;for (int i 0; i < n - 1; i) {sum wi…

如何使用 C# 编写一个修改文件时间属性的小工具?

下面是简鹿办公一个用 C# 编写的简单工具&#xff0c;它可以批量修改文件的创建时间、最后访问时间和最后修改时间。我们将使用 .NET Framework 或 .NET Core 来实现这个功能。 完整示例代码 1. 创建一个新的 C# 控制台应用程序 您可以使用 Visual Studio 或 .NET CLI 创建一个…

使用FTP与多个合作伙伴传文件,如何处理运维管理和数据安全问题

许多行业的企业使用FTP与外部客户、供应商等合作伙伴进行文件交换&#xff0c;如大型保险公司、研究所、IC设计企业、汽车制造厂商等。基于FTP可以满足企业与外部合作伙伴文件收发的基础需求&#xff0c;但在IT运维管理、数据安全保障及业务便利性上仍存在不同程度的缺陷和不足…

Simulink中Matlab function使用全局变量

目录 一. 引言二. 普通Matlab function使用全局变量三. Simulink中的Matlab function使用全局变量四. 如何利用Matlab function的全局变量施加随机噪声 一. 引言 最近发现了之前仿真中的一个问题&#xff0c;记录一下备忘。 Matlab function中有时候需要用到全局变量&#xf…

Jmeter的安装,设置中文,解决乱码问题

1.Jmeter安装 1-Jmeter如何下载 1---我这里提供一个下载快的方式 https://www.123684.com/s/lWZKVv-4jiav?提取码:4x4y 2---Jmeter官网下载地址 Apache JMeter - Download Apache JMeter 2-配置java环境 1---下载javaJDK 官方下载地址 https://www.oracle.com/java/techno…

深 度 学 习

神经网络基础 一、逻辑回归( Logic Regression ) 1 问题的模型 模型&#xff1a; 其中xx为输入量&#xff0c;y^​预测量&#xff0c;σ()激活函数。   逻辑回归主要用于二分类问题的拟合&#xff1a;0≤y^P(y1∣x)≤1&#xff0c;σ(z)如图&#xff1a; ​ 问题&#xff…

华为OD机试 - 最低位排序 - 数组(Java 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…

C语言:文件操作2(又一万字?)

关于文件操作这章内容&#xff0c;因为知道内容较多所以我分两篇发了&#xff0c;但是还是没料到第二篇还是这么多&#xff0c;达到了一万多字&#xff01;&#xff01;&#xff01;作者本人真的将知识点进行了超级详解分析并且举了很多例子来帮助读者理解&#xff0c;本文章较…

RabbitMQ队列详细属性(重要)

RabbitMQ队列详细属性 1、队列的属性介绍1.1、Type&#xff1a;队列类型1.2、Name&#xff1a;队列名称1.3、Durability&#xff1a;声明队列是否持久化1.4、Auto delete&#xff1a; 是否自动删除1.5、Exclusive&#xff1a;1.6、Arguments&#xff1a;队列的其他属性&#xf…

【大模型】相比现有智能体(Agent)系统,微软新推出的 Magnetic-One 值得一看吗?

微软最近发布的Magnetic-One智能体系统在开源社区引发了广泛关注&#xff0c;因其在性能、灵活性和扩展性方面表现出色&#xff0c;被誉为目前开源社区最强的智能体解决方案。本文将从评测结果、工作原理、与现有智能体系统的比较三个方面&#xff0c;全面解析Magnetic-One的独…

C++——左值和右值的本质区别

左值和右值好干嘛&#xff1f; 深入理解左值和右值可以帮助我们对代码进行优化 一、什么是左值和右值 左值&#xff1a;有某种存储支持的变量 右值&#xff1a;临时值&#xff08;字面量、函数的结果&#xff09; Ⅰ右值是字面量 int yy 22;22本身就是一个临时的&#xf…

Rust-AOP编程实战

文章本天成,妙手偶得之。粹然无疵瑕,岂复须人为?君看古彝器,巧拙两无施。汉最近先秦,固已殊淳漓。胡部何为者,豪竹杂哀丝。后夔不复作,千载谁与期? ——《文章》宋陆游 【哲理】文章本是不加人工,天然而成的,是技艺高超的人在偶然间所得到的。其实作者所说的“天成”…

深入了解支持向量机:机器学习中的经典算法

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

第01章 Linux概述及系统环境搭建

目标: ◆ 知道 Linux 是什么&#xff1f;有什么特点&#xff1f; ◆ 知道 Linux 内核及发行版的区别 ◆ 知道 Linux 的应用领域 ◆ 能够在虚拟机软件上新建虚拟机 ◆ 能够在虚拟机中挂载CentOS6.7光盘镜像 ◆ 能够根据需求安装CentOS6.7的操作系统 ◆ 能够对系统进行登录和关闭…

【题解】—— LeetCode一周小结45

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结44 4.平方数之和 题目链接&#xff1a;633. 平方数之和 给定一…

Python爬虫基础-正则表达式!

前言 正则表达式是对字符串的一种逻辑公式&#xff0c;用事先定义好的一些特定字符、及这些特定字符的组合&#xff0c;组成一个“规则的字符串”&#xff0c;此字符串用来表示对字符串的一种“过滤”逻辑。正在在很多开发语言中都存在&#xff0c;而非python独有。对其知识点…

kdump 应该怎么安装 linux-crashdump kdump-tools

sudo apt install linux-crashdump sudo apt install crash sudo apt install kdump-tools 1. 两个工具的关系 linux-crashdump kdump-tools 在 Ubuntu 上安装 kdump 功能&#xff0c;这两个包都是相关的&#xff0c;但有不同的作用. linux-crashdump 是一个元包&#xff08;…

STM32F405RGT6单片机原理图、PCB免费分享

大学时机创比赛时画的板子&#xff0c;比到一半因为疫情回家&#xff0c;无后续&#xff0c;&#xff0c;&#xff0c;已打板验证过&#xff0c;使用stm32f405rgt6做主控 下载文件资源如下 原理图文件 pcb文件 外壳模型文件 stm32f405例程 功能 以下功能全部验证通过 4路…

2024-11-01 - 统一身份认证 - OpenLdap - 中间件 - 流雨声

摘要 2024-11-01 周五 杭州 暴雨 调查问卷: https://www.wjx.cn/vm/exIBFDM.aspx# 2024年转瞬即逝&#xff0c;可是生活还在继续&#xff0c;这里有一项关于人工智能和项目管理对于效能关系的调研问卷&#xff0c;AI 对工作的作用和影响。问卷不采集个人信息&#xff0c;在此…