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

B树在数据库中的应用:理论与实践

B树在数据库中的应用:理论与实践

B树(B-tree)是一种自平衡的树数据结构,广泛应用于数据库系统中,特别是用于实现索引和文件系统中的关键字查找。B树的设计目标是保持数据有序并允许高效的查找、插入和删除操作。本文将详细探讨B树的理论基础及其在数据库中的实际应用,并提供具体的代码示例来说明B树的实现和操作。

目录

  1. B树的理论基础
    • B树的定义与性质
    • B树的结构
    • B树的操作
  2. B树在数据库中的应用
    • B树索引的原理
    • B树在MySQL中的应用
    • B+树与B*树的改进
  3. B树的实现与代码示例
    • B树节点的定义
    • 插入操作的实现
    • 删除操作的实现
    • 查找操作的实现
  4. B树的性能分析
    • 查找性能
    • 插入性能
    • 删除性能
  5. B树的优化策略
    • 节点大小优化
    • 磁盘I/O优化
    • 缓存策略
  6. 实战案例:基于B树的简单数据库索引实现
  7. 总结

1. B树的理论基础

B树的定义与性质

B树是一种多路平衡查找树(Multiway Balanced Search Tree),其每个节点可以有多个子节点。B树具有以下性质:

  1. 节点的键值数量:每个节点至少包含t-1个键值,至多包含2t-1个键值,其中t为B树的最小度数(Minimum Degree)。
  2. 子节点数量:每个非叶子节点包含的子节点数量为[t, 2t],根节点的子节点数量为[1, 2t]
  3. 有序性:对于每个节点,键值按升序排列,节点的子树间隔着键值。
  4. 高度平衡性:所有叶子节点在同一层,树的高度最小。
  5. 自平衡:B树通过插入和删除操作自动维持自身的平衡性。

B树的结构

B树的节点结构如下:

struct BTreeNode {int *keys;     // 存储键值的数组int t;         // 最小度数BTreeNode **C; // 子节点指针数组int n;         // 当前键值数量bool leaf;     // 是否为叶子节点BTreeNode(int _t, bool _leaf);
};

B树的操作

B树的主要操作包括查找、插入和删除。

  • 查找:在B树中查找特定键值,返回键值所在节点。
  • 插入:向B树中插入新键值,保持B树的平衡性。
  • 删除:从B树中删除特定键值,保持B树的平衡性。

2. B树在数据库中的应用

B树索引的原理

在数据库中,B树常用于实现索引结构。数据库索引是一种数据结构,能够加快数据的查找速度。B树索引通过保持数据有序,使得查找、插入和删除操作都能在O(log n)时间复杂度内完成,从而大幅提升数据库的性能。

B树在MySQL中的应用

MySQL数据库广泛使用B+树(B-Tree的一种变体)来实现其默认的索引结构。InnoDB存储引擎使用B+树作为聚集索引和二级索引,以提高查询效率。聚集索引将数据存储在叶子节点中,二级索引则存储键值和指向数据行的指针。

B+树与B*树的改进

  • B+树:B+树是B树的一种改进版本,所有数据都存储在叶子节点中,非叶子节点只存储索引。B+树的叶子节点通过链表相连,便于范围查询。
  • B*树:B*树是B+树的进一步改进,增加了内部节点的分裂阈值,通过兄弟节点的重新分配减少分裂次数,提高空间利用率。

3. B树的实现与代码示例

B树节点的定义

以下是B树节点的定义和构造函数:

#include <iostream>
using namespace std;class BTreeNode {
public:int *keys;      // 存储键值的数组int t;          // 最小度数BTreeNode **C;  // 子节点指针数组int n;          // 当前键值数量bool leaf;      // 是否为叶子节点BTreeNode(int _t, bool _leaf);void insertNonFull(int k);void splitChild(int i, BTreeNode *y);void traverse();BTreeNode *search(int k);friend class BTree;
};BTreeNode::BTreeNode(int _t, bool _leaf) {t = _t;leaf = _leaf;keys = new int[2*t-1];C = new BTreeNode *[2*t];n = 0;
}

插入操作的实现

以下是B树的插入操作实现:

class BTree {
public:BTreeNode *root;int t;BTree(int _t) {root = nullptr;t = _t;}void traverse() {if (root != nullptr) root->traverse();}BTreeNode* search(int k) {return (root == nullptr) ? nullptr : root->search(k);}void insert(int k);
};void BTreeNode::insertNonFull(int k) {int i = n-1;if (leaf) {while (i >= 0 && keys[i] > k) {keys[i+1] = keys[i];i--;}keys[i+1] = k;n = n+1;} else {while (i >= 0 && keys[i] > k) i--;if (C[i+1]->n == 2*t-1) {splitChild(i+1, C[i+1]);if (keys[i+1] < k) i++;}C[i+1]->insertNonFull(k);}
}void BTreeNode::splitChild(int i, BTreeNode *y) {BTreeNode *z = new BTreeNode(y->t, y->leaf);z->n = t - 1;for (int j = 0; j < t-1; j++) z->keys[j] = y->keys[j+t];if (!y->leaf) {for (int j = 0; j < t; j++) z->C[j] = y->C[j+t];}y->n = t - 1;for (int j = n; j >= i+1; j--) C[j+1] = C[j];C[i+1] = z;for (int j = n-1; j >= i; j--) keys[j+1] = keys[j];keys[i] = y->keys[t-1];n = n + 1;
}void BTree::insert(int k) {if (root == nullptr) {root = new BTreeNode(t, true);root->keys[0] = k;root->n = 1;} else {if (root->n == 2*t-1) {BTreeNode *s = new BTreeNode(t, false);s->C[0] = root;s->splitChild(0, root);int i = 0;if (s->keys[0] < k) i++;s->C[i]->insertNonFull(k);root = s;} else {root->insertNonFull(k);}}
}

删除操作的实现

以下是B树的删除操作实现:

void BTreeNode::remove(int k) {int idx = findKey(k);if (idx < n && keys[idx] == k) {if (leaf) removeFromLeaf(idx);else removeFromNonLeaf(idx);} else {if (leaf) {cout << "The key " << k << " is does not exist in the tree\n";return;}bool flag = (idx == n);if (C[idx]->n < t) fill(idx);if (flag && idx > n) C[idx-1]->remove(k);else C[idx]->remove(k);}
}void BTreeNode::removeFromLeaf(int idx) {for (int i = idx+1; i< n; ++i) keys[i-1] = keys[i];n--;
}void BTreeNode::removeFromNonLeaf(int idx) {int k = keys[idx];if (C[idx]->n >= t) {int pred = getPred(idx);keys[idx] = pred;C[idx]->remove(pred);} else if (C[idx+1]->n >= t) {int succ = getSucc(idx);keys[idx] = succ;C[idx+1]->remove(succ);} else {merge(idx);C[idx]->remove(k);}
}int BTreeNode::getPred(int idx) {BTreeNode *cur = C[idx];while (!cur->leaf) cur = cur->C[cur->n];return cur->keys[cur->n-1];
}int BTreeNode::getSucc(int idx) {BTreeNode *cur = C[idx+1];while (!cur->leaf) cur = cur->C[0];return cur->keys[0];
}void BTreeNode::fill(int idx) {if (idx != 0 && C[idx-1]->n >= t) borrowFromPrev(idx);else if (idx != n && C[idx+1]->n >= t) borrowFromNext(idx);else {if (idx != n) merge(idx);else merge(idx-1);}
}void BTreeNode::borrowFromPrev(int idx) {BTreeNode *child = C[idx];BTreeNode *sibling = C[idx-1];for (int i = child->n-1; i >= 0; --i) child->keys[i+1] = child->keys[i];if (!child->leaf) {for (int i = child->n; i >= 0; --i) child->C[i+1] = child->C[i];}child->keys[0] = keys[idx-1];if (!child->leaf) child->C[0] = sibling->C[sibling->n];keys[idx-1] = sibling->keys[sibling->n-1];child->n += 1;sibling->n -= 1;
}void BTreeNode::borrowFromNext(int idx) {BTreeNode *child = C[idx];BTreeNode *sibling = C[idx+1];child->keys[child->n] = keys[idx];if (!child->leaf) child->C[child->n+1] = sibling->C[0];keys[idx] = sibling->keys[0];for (int i = 1; i < sibling->n; ++i) sibling->keys[i-1] = sibling->keys[i];if (!sibling->leaf) {for (int i = 1; i <= sibling->n; ++i) sibling->C[i-1] = sibling->C[i];}child->n += 1;sibling->n -= 1;
}void BTreeNode::merge(int idx) {BTreeNode *child = C[idx];BTreeNode *sibling = C[idx+1];child->keys[t-1] = keys[idx];for (int i = 0; i < sibling->n; ++i) child->keys[i+t] = sibling->keys[i];if (!child->leaf) {for (int i = 0; i <= sibling->n; ++i) child->C[i+t] = sibling->C[i];}for (int i = idx+1; i < n; ++i) keys[i-1] = keys[i];for (int i = idx+2; i <= n; ++i) C[i-1] = C[i];child->n += sibling->n + 1;n--;delete sibling;
}

查找操作的实现

以下是B树的查找操作实现:

BTreeNode* BTreeNode::search(int k) {int i = 0;while (i < n && k > keys[i]) i++;if (keys[i] == k) return this;if (leaf) return nullptr;return C[i]->search(k);
}void BTreeNode::traverse() {int i;for (i = 0; i < n; i++) {if (!leaf) C[i]->traverse();cout << " " << keys[i];}if (!leaf) C[i]->traverse();
}

4. B树的性能分析

查找性能

B树的查找操作时间复杂度为O(log n),其中n为树中的节点数量。由于B树的高度较低,查找操作通常非常高效。

插入性能

B树的插入操作同样具有O(log n)的时间复杂度。在最坏情况下,插入操作可能需要进行节点分裂,但总体效率仍然较高。

删除性能

B树的删除操作时间复杂度为O(log n)。删除操作可能需要进行节点合并和重新分配,但整体性能仍然优于大多数其他数据结构。

5. B树的优化策略

节点大小优化

选择合适的节点大小可以显著提高B树的性能。通常,节点大小应与磁盘块大小相匹配,以便在每次I/O操作中尽可能多地读取和写入数据。

磁盘I/O优化

通过缓存最近访问的节点,可以减少磁盘I/O操作的次数,提高B树的性能。此外,可以使用批量读取和写入技术,进一步优化磁盘I/O性能。

缓存策略

使用内存缓存策略(如LRU缓存)可以提高B树的访问速度。将经常访问的节点保存在内存中,可以显著减少磁盘访问次数。

6. 实战案例:基于B树的简单数据库索引实现

下面是一个基于B树实现的简单数据库索引的示例代码:

#include <iostream>
#include <vector>
using namespace std;class BTreeNode {
public:vector<int> keys;vector<BTreeNode*> children;bool leaf;BTreeNode(bool _leaf);void insertNonFull(int k);void splitChild(int i, BTreeNode *y);void traverse();BTreeNode* search(int k);friend class BTree;
};class BTree {
public:BTreeNode *root;int t;BTree(int _t) {root = new BTreeNode(true);t = _t;}void insert(int k);void traverse() {if (root != nullptr) root->traverse();}BTreeNode* search(int k) {return (root == nullptr) ? nullptr : root->search(k);}
};BTreeNode::BTreeNode(bool _leaf) {leaf = _leaf;
}void BTreeNode::insertNonFull(int k) {int i = keys.size() - 1;if (leaf) {keys.push_back(0);while (i >= 0 && keys[i] > k) {keys[i + 1] = keys[i];i--;}keys[i + 1] = k;} else {while (i >= 0 && keys[i] > k) i--;if (children[i + 1]->keys.size() == 2 * t - 1) {splitChild(i + 1, children[i + 1]);if (keys[i + 1] < k) i++;}children[i + 1]->insertNonFull(k);}
}void BTreeNode::splitChild(int i, BTreeNode *y) {BTreeNode *z = new BTreeNode(y->leaf);z->keys.insert(z->keys.end(), y->keys.begin() + t, y->keys.end());y->keys.resize(t - 1);if (!y->leaf) {z->children.insert(z->children.end(), y->children.begin() + t, y->children.end());y->children.resize(t);}children.insert(children.begin() + i + 1, z);keys.insert(keys.begin() + i, y->keys[t - 1]);
}void BTree::insert(int k) {if (root->keys.size() == 2 * t - 1) {BTreeNode *s = new BTreeNode(false);s->children.push_back(root);s->splitChild(0, root);int i = 0;if (s->keys[0] < k) i++;s->children[i]->insertNonFull(k);root = s;} else {root->insertNonFull(k);}
}void BTreeNode::traverse() {int i;for (i = 0; i < keys.size(); i++) {if (!leaf) children[i]->traverse();cout << " " << keys[i];}if (!leaf) children[i]->traverse();
}BTreeNode* BTreeNode::search(int k) {int i = 0;while (i < keys.size() && k > keys[i]) i++;if (keys[i] == k) return this;if (leaf) return nullptr;return children[i]->search(k);
}int main() {BTree t(3);t.insert(10);t.insert(20);t.insert(5);t.insert(6);t.insert(12);t.insert(30);t.insert(7);t.insert(17);cout << "Traversal of the constructed tree is ";t.traverse();int k = 6;(t.search(k) != nullptr) ? cout << "\nPresent" : cout << "\nNot Present";k = 15;(t.search(k) != nullptr) ? cout << "\nPresent" : cout << "\nNot Present";return 0;
}

7. 总结

B树作为一种高效的自平衡多路查找树,在数据库系统中具有广泛的应用。它能够高效地支持查找、插入和删除操作,显著提升数据库的性能。通过优化节点大小、磁盘I/O和缓存策略,可以进一步提高B树的性能。本文详细介绍了B树的理论基础、操作实现、性能分析和优化策略,并通过实战案例展示了如何基于B树实现简单的数据库索引。希望本文能够帮助读者深入理解B树在数据库中的应用,并在实际开发中灵活应用B树提高系统性能。

相关文章:

B树在数据库中的应用:理论与实践

B树在数据库中的应用&#xff1a;理论与实践 B树&#xff08;B-tree&#xff09;是一种自平衡的树数据结构&#xff0c;广泛应用于数据库系统中&#xff0c;特别是用于实现索引和文件系统中的关键字查找。B树的设计目标是保持数据有序并允许高效的查找、插入和删除操作。本文将…...

网络编程 -------- 3、TCP_UDP_UNIX

1、基于TCP的套接字编程流程 Server.c socket bind &#xff08;服务器的ip端口&#xff09; listen accept recv / send close Client.c socket connect &#xff08;服务器的ip端口&#xff09; …...

口袋奇兵:游戏辅助教程!陆军搭配阵容推荐,平民必备!

《口袋奇兵》是一款策略类手游&#xff0c;玩家需要在游戏中组建和指挥自己的军队&#xff0c;进行各种战斗和任务。为了在游戏中取得更好的成绩&#xff0c;合理搭配英雄和使用辅助工具是非常重要的。本攻略将为大家介绍一种强力的陆军搭配阵容&#xff0c;以及如何利用VMOS云…...

Spring Boot 集成参数效验 Validator

为什么需要参数效验? 在业务开发中,为了防止非法参数对业务造成影响,所以需要对用户输入的正确性、数据完整性、安全性、业务规则的执行做效验,靠代码对接口参数做if判断的话就太繁琐了,代码冗余且可读性差(主要是不够优雅)。 Validator效验框架遵循了JSR-303验证规范…...

63、ELK安装和部署

一、ELK日志系统 1.1、ELK平台的定义 ELK平台是一套完整的日志集中处理解决方案&#xff0c;将ElasticSearch、Logstash和Kiabana 三个开源工具配合使用&#xff0c;完成更强大的用户对日志的查询、排序、统计需求 E:elasticsearch ES分布式索引型非关系数据库&#xff0c;存…...

【Dash】简单的直方图

一、Visualizing Data The Plotly graphing library has more than 50 chart types to choose from. In this example, we will make use of the histogram chart. # Import packages from dash import Dash, html, dash_table, dcc import pandas as pd import plotly.expre…...

【CTF-Crypto】格密码基础(例题较多,非常适合入门!)

格密码相关 文章目录 格密码相关格密码基本概念&#xff08;属于后量子密码&#xff09;基础的格运算&#xff08;行列式运算&#xff09;SVP&#xff08;shortest Vector Problem&#xff09;最短向量问题CVP&#xff08;Closet Vector Problem&#xff09;最近向量问题 做题要…...

Java对象流

对象流 对象输入流 java.io.ObjectInputStream使用对象流可以进行对象反序列化 构造器 ObjectInputStream(InputStream in) 将当前创建的对象输入流链接在指定的输入流上 方法 Object readObject() 进行对象反序列化并返回。该方法会从当前对象输入流链接的流中读取若干…...

问界M7是不是换壳东风ix7? 这下有答案了

文 | AUTO芯 作者 | 谦行 终于真相大白了 黑子们出来挨打啊 问界M7是换壳的东风ix7&#xff1f; 你们没想到&#xff0c;余大嘴会亲自出来正面回应吧 瞧瞧黑子当时乐的 问界你可以啊&#xff01;靠改名字造车呢&#xff1f; 还有更过分的&#xff0c;说M7是东风小康ix7…...

mybatis多条件in查询拓展

背景 最近碰上有个业务&#xff0c;查询的sql如下&#xff1a; select * from table where (sku_id,batch_no) in ((#{skuId},#{batchNo}),...); 本来也没什么&#xff0c;很简单常见的一种sql。问题是我们使用的是mybatis-plus&#xff0c;然后写的时候又没有考虑到后面的查…...

<Rust><iced>基于rust使用iced构建GUI实例:一个CRC16校验码生成工具

前言 本专栏是Rust实例应用。 环境配置 平台:windows 软件:vscode 语言:rust 库:iced、iced_aw 概述 本文是专栏第五篇实例,是一个CRC16校验码转换程序。 本篇内容: 1、CRC16校验码生成 代码介绍 本文的crc16校验码生成工具,主要设计两个方面,一个是crc16 modbus…...

动态规划与0/1背包问题:深入解析

目录 一、动态规划简介 二、0/1背包问题概述 三、动态规划解决0/1背包问题 1. 定义子问题 2. 确定状态 3. 初始条件和边界情况 4. 计算最终结果 5. 代码实现 6. 空间优化 四、例题讲解 例题1&#xff1a;基础例题 例题2&#xff1a;路径恢复 例题3&#xff1a;扩展…...

Python爬虫:下载人生格言

Python爬虫:下载人生格言 爬取网页 将这些格言下载存储到本地 代码: import requests #导入requests库&#xff0c;用于提取网页 from lxml import etree#导入lxml库&#xff0c;用于Xpath数据解析#请求头 header{ user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) A…...

使用注意力机制的seq2seq

一、背景 1、机器翻译中&#xff0c;每个生成的词可能相关于源句子中不同的词&#xff0c;但是之前用的是最后一个RNN层出来的context。 2、加入注意力 &#xff08;1&#xff09;假设输入序列中有&#x1d447;个词元&#xff0c; 解码时间步&#x1d461;′的上下文变量是…...

我们的前端开发逆天了!1 小时搞定了新网站,还跟我说 “不要钱”

大家好&#xff0c;我是程序员鱼皮。前段时间我们上线了一个新软件 剪切助手 &#xff0c;并且针对该项目做了一个官网&#xff1a; 很多同学表示官网很好看&#xff0c;还好奇是怎么做的&#xff0c;其实这个网站的背后还有个有趣的小故事。。。 鱼皮&#xff1a;我们要做个官…...

.NET 相关概念

.NET 和 .NET SDK .NET 介绍 .NET 是一个由 Microsoft 开发和维护的广泛用于构建各种类型应用程序的开发框架。它是一个跨平台、跨语言的开发平台&#xff0c;提供了丰富的类库、API和开发工具&#xff0c;支持开发者使用多种编程语言&#xff08;如C#、VB.NET、F#等&#xf…...

Kubernetes 从集群中移除一个节点(Node)

目录 1. 移除工作节点(Worker Node)1.1 确定工作节点名称1.2 驱逐工作节点上的Pod1.3 删除工作节点1.4 重置该工作节点 2. 移除控制平面节点(Control Plane Node)2.1 确定控制平面节点名称2.2 驱逐控制平面节点上的Pod2.3 更新 etcd 集群2.4 从集群中删除控制平面节点2.5 重置移…...

高德地图离线版 使用高德地图api的方法

高德离线包我已经存至Gitee&#xff08;自行下载即可&#xff09;&#xff1a;高德地图离线解决方案: 高德地图离线解决方案 然因为高德地图的瓦片地图太大&#xff0c;所以要让后端部署下 前端直接调用 如果本地 直接找到瓦片图路径就可以 initMap () {const base_url "…...

springboot 集成私有化Ollama大模型开源框架,搭建AI智能平台

Ollama是一个用于大数据和机器学习的平台&#xff0c;它可以帮助企业进行数据处理、分析和决策制定。 &#xff11;、在Spring Boot项目pom.xml中添加Ollama客户端库依赖 <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-a…...

6.key的层级结构

redis的key允许多个单词形成层级结构&#xff0c;多个单词之间用:隔开&#xff0c;格式如下&#xff1a; 项目名:业务名:类型:id 这个格式并非固定的&#xff0c;可以根据自己的需求来删除或添加词条。 例如&#xff1a; taobao:user:1 taobao:product:1 如果value是一个java对…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...