Vector 的模拟实现:从基础到高级
文章目录
- 1. 引言
- 2. vector的核心设计
- 3. vector的常用接口介绍
- 3.1 构造函数和析构函数
- 3.1.1 默认构造函数
- 3.1.2 带初始容量的构造函数
- 3.1.3 析构函数
- 3.2 拷贝构造函数和拷贝赋值运算符
- 3.2.1 拷贝构造函数
- 3.2.2 拷贝赋值运算符
- 3.5 数组长度调整和动态扩容
- 3.5.1 调整大小(resize)
- 3.5.2 缩减容量(shrink_to_fit)
- 3.5.3 动态扩容(reserve)
- 3.6 添加元素
- 3.6.1 添加左值元素
- 3.6.2 添加右值元素
- 3.7 删除元素
- 3.7.1 删除指定位置元素
- 3.7.2 尾删
- 3.8 元素访问
- 3.8.1 通过下标访问元素
- 3.9 迭代器支持
- 4. 总结
- 5. 附录
- 5.1 测试用例
1. 引言
std::vector 是 C++ 中最常用的动态数组容器。为了更好地理解其内部机制,我们将从头实现一个功能更完整的 vector,并逐步优化它。本文不仅会实现基本功能,还会深入探讨一些高级特性,例如异常安全性、迭代器支持和自定义分配器。
2. vector的核心设计
根据 STL 中 vector 的设计。一个 vector 的核心是动态数组,它需要以下成员变量:
- _start :指向动态数组当前存储元素的第一个位置。
- _finish :指向动态数组当前存储元素的最后一个位置。
- _end_of_storage :指向动态数组容量的最后一个位置。
具体的代码实现路径如下:
template<class T>
class vector
{
public:typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}//构造函数vector(){}//类模板的成员函数,也可以是一个函数模板template <class InputIterator>vector(InputIterator first,InputIterator last){while (first != last){push_back(*first);++first;}}vector(size_t n, const T& val = T()){reserve(n);for (size_t i = 0;i < n; i++){push_back(val);}}/*vector(int n, const T& val = T()){reserve(n);for (int i = 0; i < n; i++){push_back(val);}}*/vector(std::initializer_list<T> il){reserve(il.size());for (auto& e : il){push_back(e);}}vector(const vector<T>& v){reserve(v.capacity());for (auto& e : v){push_back(e);}}void swap(vector<T>& tmp){// std 需要在上面将 std域展开std::swap(_start, tmp._start);std::swap(_finish, tmp._finish);std::swap(_endofstorage, tmp._endofstorage);}vector<T>& operator=(vector<T> v){swap(v);return *this;}~vector(){if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}T& operator[](size_t i){assert(i < size());return _start[i];}const T& operator[](size_t i) const{assert(i < size());return _start[i];}size_t size() const{return _finish - _start;}size_t capacity() const{return _endofstorage - _start;}void resize(size_t n, T val = T()){if (n <= size()){_finish = _start + n;}else{reserve(n);while (_finish < _start + n){*_finish = val;++_finish;}}}void reserve(size_t n){if (n > capacity()){size_t oldSize = size();T* tmp = new T[n];if (_start){for (size_t i = 0; i < oldSize; i++){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + oldSize;_endofstorage = _start + n;}}void push_back(const T& x){insert(_finish, x);}bool empty(){return _start == _finish;}void pop_back(){assert(!empty());--_finish;}iterator insert(iterator pos,const T& x){assert(pos >= _start && pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _start + len;}iterator i = _finish - 1;while (i >= pos){*(i + 1) = *i;--i;}*pos = x;++_finish;return pos;}iterator erase(iterator pos){assert(pos >= _start && pos < _finish);iterator i = pos + 1;while (i < _finish){*(i - 1) = *i;++i;}_finish--;return pos;}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _endofstorage = nullptr;
};
3. vector的常用接口介绍
3.1 构造函数和析构函数
3.1.1 默认构造函数
初始化一个空的 vector。
template <typename T>
Vector<T>::Vector() : (nullptr), size(0), capacity(0) {}
3.1.2 带初始容量的构造函数
允许用户指定初始容量。
template <typename T>
Vector<T>::Vector(size_t initial_capacity): data(new T[initial_capacity]), size(0), capacity(initial_capacity) {}
3.1.3 析构函数
释放动态分配的内存。
template <typename T>
Vector<T>::~Vector() {delete[] data;
}
3.2 拷贝构造函数和拷贝赋值运算符
3.2.1 拷贝构造函数
深拷贝另一个 vector 的内容。
template <typename T>
Vector<T>::Vector(const Vector& other): data(new T[other.capacity]), size(other.size), capacity(other.capacity) {for (size_t i = 0; i < size; ++i) {data[i] = other.data[i]; // 调用 T 的拷贝构造函数}
}
3.2.2 拷贝赋值运算符
先释放当前资源,再深拷贝另一个 vector 的内容。
template <typename T>
Vector<T>& Vector<T>::operator=(const Vector& other) {if (this != &other) {// 创建一个临时对象Vector temp(other);// 交换当前对象和临时对象的内容std::swap(data, temp.data);std::swap(size, temp.size);std::swap(capacity, temp.capacity);}return *this;
}
3.5 数组长度调整和动态扩容
3.5.1 调整大小(resize)
resize 函数用于调整 vector 的大小。如果新大小大于当前容量,则需要扩容;如果新大小小于当前大小,则只需调整 size 。
template <typename T>
void Vector<T>::resize(size_t new_size) {if (new_size > capacity) {// 如果新大小大于当前容量,需要扩容reserve(new_size);}if (new_size > size) {// 如果新大小大于当前大小,初始化新增元素for (size_t i = size; i < new_size; ++i) {data[i] = T(); // 使用默认构造函数初始化新元素}}size = new_size; // 更新大小
}
3.5.2 缩减容量(shrink_to_fit)
shrink_to_fit 函数用于将 vector 的容量缩减到当前大小,以节省内存。
template <typename T>
void Vector<T>::shrink_to_fit() {if (size < capacity) {// 创建一个临时数组,容量为当前大小T* new_data = new T[size];for (size_t i = 0; i < size; ++i) {new_data[i] = std::move(data[i]); // 移动元素到新数组}// 释放旧数组delete[] data;// 更新指针和容量data = new_data;capacity = size;}
}
注意:这个函数不常用。因为这个函数是请求把多余的内存还给系统,不一定会成功。
3.5.3 动态扩容(reserve)
reserve 函数用于确保 vector 的容量至少为指定值。如果当前容量不足,则扩容。
template <typename T>
void Vector<T>::reserve(size_t new_capacity) {if (new_capacity <= capacity) return; // 如果容量足够,直接返回// 创建新数组T* new_data = new T[new_capacity];for (size_t i = 0; i < size; ++i) {new_data[i] = std::move(data[i]); // 移动元素到新数组}// 释放旧数组delete[] data;// 更新指针和容量data = new_data;capacity = new_capacity;
}
说明:
- 如果 new_capacity <= capacity,直接返回。如果当前数组容量大于新的数组容量,那么就会直接返回。
- 否则,创建一个新数组,容量为 new_capacity。再使用 std::move 将元素从旧数组移动到新数组。释放旧数组,并更新 data和capacity。
3.6 添加元素
3.6.1 添加左值元素
将元素拷贝到 vector 的头部。
template <typename T>
void Vector<T>::insert(const T& value) {if (size >= capacity) {reserve(capacity == 0 ? 4 : capacity * 2);}data[size++] = value;
}
3.6.2 添加右值元素
将元素拷贝到 vector 的末尾。
template <typename T>
void Vector<T>::push_back(const T& value) {if (size >= capacity) {reserve(capacity == 0 ? 1 : capacity * 2);}data[size++] = value;
}
3.7 删除元素
3.7.1 删除指定位置元素
删除指定位置元素。
iterator erase(iterator pos)
{assert(pos >= _start && pos < _finish);iterator i = pos + 1;while (i < _finish){*(i - 1) = *i;++i;}_finish--;return pos;
}
3.7.2 尾删
删除尾部位置的元素。
void pop_back()
{assert(!empty());--_finish;
}
注意:erase尽量少用。由于erase可以删除任意位置的元素,所以会涉及到大量的数组容量更改操作。这会大幅降低程序效率。
3.8 元素访问
3.8.1 通过下标访问元素
T& operator[](size_t i)
{assert(i < size());return _start[i];
}
3.9 迭代器支持
iterator begin()
{return _start;
}iterator end()
{return _finish;
}const_iterator begin() const
{return _start;
}const_iterator end() const
{return _finish;
}
4. 总结
通过这个详细的实现,我们深入了解了 std::vector 的核心机制,包括动态扩容、拷贝/移动语义、迭代器支持等。
希望这篇博客对你有所帮助!如果有任何问题或建议,欢迎留言讨论。
5. 附录
5.1 测试用例
void test_vector01(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto ch : v1){cout << ch << " ";}cout << endl;for (int i = 0; i < v1.size(); i++){cout << v1[i] << " ";}cout << endl;v1.pop_back();for (auto ch : v1){cout << ch << " ";}cout << endl;// pop_back只能尾删,v1.pop_back(1)行不通;int n = *v1.begin();cout << n << endl;vector<int>::iterator it1 = v1.begin();vector<int>::iterator it2 = v1.end();while (it1 != it2){cout << *it1++ << " ";}cout << endl;}void test_vector02(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;// 第一种使用迭代器在指定位置插入数字v1.insert(v1.begin() + 1, 26);for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector03(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);vector<int>::iterator it1 = v1.begin();vector<int>::iterator it2 = v1.end();auto x = 0;cin >> x;// 第二种使用迭代器 在指定位置插入指定倍数的数字auto it = find(it1, it2, x);if (it != it2){it = v1.insert(it, 10 * x);cout << *it << endl;}for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector04(){vector<int> v1;// 这一遍是模拟实现的// 这里必须使用系统自带的vector,不然程序会报错中止//std::vector<int> v1;// 这里就是编译器自带的v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);int x;cin >> x;auto it = find(v1.begin(), v1.end(), x);// 删除指定位置的数while (it != v1.end()){v1.erase(it);}for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector05(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(4);v1.push_back(23);v1.push_back(42);v1.push_back(33);v1.push_back(533);v1.push_back(234);v1.push_back(23454);v1.push_back(534534534);for (auto e : v1){cout << e << " ";}cout << endl;// 要求删除所有的偶数auto it = v1.begin();while (it != v1.end()){if (*it % 2 == 0){// erase返回删除位置下一个位置// 失效的迭代器,更新以后再去访问v1.erase(it);}else {it++;}}for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector06(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;// 将v1的size改为20,自动填充0v1.resize(20);for (auto e : v1){cout << e << " ";}cout << endl;// 也可以指定数字。只是已经填充进去的数字无法更改v1.resize(25, 1);for (auto e : v1){cout << e << " ";}cout << endl;v1.resize(2);for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector07(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;vector<int> v2(v1);for (auto e : v2){cout << e << " ";}cout << endl;vector<int> v3{ 1,2,3,4,5 };v1 = v3;for (auto e : v3){cout << e << " ";}cout << endl; for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector08(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;vector<int> v2(v1.begin(), v1.end());for (auto e : v2){cout << e << " ";}cout << endl;std::string s1("hello world");vector<int> v3(s1.begin(),s1.end());// 打印的是ASSIC码值for (auto e : v3){cout << e << " ";}cout << endl;// 行不通//vector<int> v4(10, 1);//vector<double> v5(10, 1.1);//for (auto e : v4)//{// cout << e << " ";//}//cout << endl;///*for (auto e : v5)//{// cout << e << " ";//}//cout << endl;*/}void test_vector09(){vector<string> v1;v1.push_back("1111111111111111");v1.push_back("1111111111111111");v1.push_back("1111111111111111");v1.push_back("1111111111111111");v1.push_back("1111111111111111");for (auto e : v1){cout << e << " ";}cout << endl;}
}
相关文章:
Vector 的模拟实现:从基础到高级
文章目录 1. 引言2. vector的核心设计3. vector的常用接口介绍3.1 构造函数和析构函数3.1.1 默认构造函数3.1.2 带初始容量的构造函数3.1.3 析构函数 3.2 拷贝构造函数和拷贝赋值运算符3.2.1 拷贝构造函数3.2.2 拷贝赋值运算符 3.5 数组长度调整和动态扩容3.5.1 调整大小&#…...
【大模型科普】大模型:人工智能的前沿(一文读懂大模型)
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈人工智能与大模型应用 ⌋ ⌋ ⌋ 人工智能(AI)通过算法模拟人类智能,利用机器学习、深度学习等技术驱动医疗、金融等领域的智能化。大模型是千亿参数的深度神经网络(如ChatGPT&…...
[漏洞修复]用yum update修openssh漏洞
[漏洞修复]用yum update修openssh漏洞 1. 需求2. 更新Yum仓库2.1 生成本地仓库2.2 生成内网仓库2.3 将Openssh的包更新到仓库 3. 客户端升级3.1 客户端repo文件配置3.2 升级Openssh3.3 升级后的确认 1. 需求 最近经常有朋友问Openssh 漏洞修复的问题,我也在自己的gitee仓库里更…...
[RH342]iscsi配置与排错
[RH342]iscsi配置与排错 1. 服务端配置1.1 安装targetcli1.2 准备磁盘1.3 服务端配置1.4 防火墙配置 2. 客户端配置2.1 安装客户端软件2.2 配置客户端2.3 连接登录服务端2.4 挂载使用 3. 安全验证扩展3.1 服务端3.2 客户端 4. 常见的排错点4.1 服务端常见错误4.2 客户端常见错误…...
Nginx 代理访问一个 Web 界面时缺少内容
1. 资源路径问题 Web 页面中的静态资源(如图片、CSS、JavaScript 文件)可能使用了相对路径或绝对路径,而这些路径在代理后无法正确加载。 解决方法: 检查资源路径:打开浏览器的开发者工具(按 F12…...
HOVER:人形机器人的多功能神经网络全身控制器
编辑:陈萍萍的公主一点人工一点智能 HOVER:人形机器人的多功能神经网络全身控制器HOVER通过策略蒸馏和统一命令空间设计,为人形机器人提供了通用、高效的全身控制框架。https://mp.weixin.qq.com/s/R1cw47I4BOi2UfF_m-KzWg 01 介绍 1.1 摘…...
SEO新手基础优化三步法
内容概要 在网站优化的初始阶段,新手常因缺乏系统性认知而陷入技术细节的误区。本文以“三步法”为核心框架,系统梳理从关键词定位到内容布局、再到外链构建的完整优化链路。通过拆解搜索引擎工作原理,重点阐明基础操作中容易被忽视的底层逻…...
遨游科普:三防平板是哪三防?有哪些应用场景?
在工业智能化与数字化转型的浪潮中,电子设备的耐用性和环境适应性成为关键需求。普通消费级平板电脑虽然功能强大,但在极端环境下往往“水土不服”。而三防平板凭借其独特的防护性能,正逐步成为“危、急、特”场景的核心工具。 AORO P300 Ult…...
Etcd 服务搭建
💢欢迎来到张胤尘的开源技术站 💥开源如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 Etcd 服务搭建预编译的二进制文件安装下载 etcd 的…...
C++《红黑树》
在之前的篇章当中我们已经了解了基于二叉搜索树的AVL树,那么接下来在本篇当中将继续来学习另一种基于二叉搜索树的树状结构——红黑树,在此和之前学习AVL树类似还是通过先了解红黑树是什么以及红黑树的结构特点,接下来在试着实现红黑树的结构…...
Axios 请求取消:从原理到实践
Axios 请求取消:从原理到实践 在现代前端开发中,网络请求是不可或缺的一部分。Axios 是一个基于 Promise 的 HTTP 客户端,广泛应用于浏览器和 Node.js 环境中。然而,在某些场景下,我们可能需要取消正在进行的请求&…...
【css酷炫效果】纯CSS实现照片堆叠效果
【css酷炫效果】纯CSS实现照片堆叠效果 缘创作背景html结构css样式完整代码基础版进阶版(增加鼠标悬停查看) 效果图 想直接拿走的老板,链接放在这里:https://download.csdn.net/download/u011561335/90492022 缘 创作随缘,不定时更新。 创…...
论文精度:Transformers without Normalization
前言 论文题目:Transformers without Normalization 作者:Jiachen Zhu 1,2 , Xinlei Chen 1 , Kaiming He 3 , Yann LeCun 1,2 , Zhuang Liu 1,4,† 论文地址:https://arxiv.org/pdf/2503.10282 摘要 这篇论文探讨了现代神经网络中广泛使用的归一化层是否是必不可少的。…...
基于香橙派 KunpengPro学习CANN(3)——pytorch 模型迁移
通用模型迁移适配可以分为四个阶段:迁移分析、迁移适配、精度调试与性能调优。 迁移分析 迁移支持度分析: 准备NPU环境,获取模型的源码、权重和数据集等文件;使用迁移分析工具采集目标网络中的模型/算子清单,识别第三方…...
微软远程桌面即将下架?Splashtop:更稳、更快、更安全的 RDP 替代方案
近日,Windows 官方博客宣布:将于2025年5月27日起,在 Windows 10 和 Windows 11 应用商店中下架“Microsoft 远程桌面”应用,建议用户迁移至新的 Windows App。这一变动引发了广大用户对远程访问解决方案的关注。作为全球领先的远程…...
【Python】Python与算法有应用关系吗?
李升伟 整理 是的,Python与算法有着密切的应用关系。Python作为一种高级编程语言,因其简洁的语法和强大的库支持,被广泛应用于算法设计、实现和应用中。以下是Python与算法之间的一些主要应用关系: 1. 算法学习与教学࿱…...
js,html,css,vuejs手搓级联单选
<!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>级联选择器</title><script src"h…...
将Django连接到mysql
将Django连接到mysql 文章目录 将Django连接到mysql一.按照我的文章 在Django模型中的Mysql安装 此篇 的步骤完成mysql的基础配置二.Django配置 一.按照我的文章 ‘在Django模型中的Mysql安装’ 此篇 的步骤完成mysql的基础配置 基础配置具体内容 1.打开PowerShell 安装mysql的…...
每天五分钟深度学习框架pytorch:基于pytorch搭建循环神经网络RNN
本文重点 我们前面介绍了循环神经网络RNN,主要分析了它的维度信息,其实它的维度信息是最重要的,一旦我们把维度弄清楚了,一起就很简单了,本文我们正式的来学习一下,如何使用pytorch搭建循环神经网络RNN。 RNN的搭建 在pytorch中我们使用nn.RNN()就可以创建出RNN神经网络…...
【力扣刷题实战】无重复的最长字串
大家好,我是小卡皮巴拉 文章目录 目录 力扣题目: 无重复的最长字串 题目描述 解题思路 问题理解 算法选择 具体思路 解题要点 完整代码(C) 兄弟们共勉 !!! 每篇前言 博客主页&#x…...
vulhub/joker 靶机----练习攻略
1. 靶机下载地址 https://download.vulnhub.com/ha/joker.zip 下载下来是ova文件,直接双击,在VMware打开,选择保存位置,点击导入。 2. 设置网卡模式为NAT,打开靶机 3.老规矩,打开kali,扫同C…...
Nuxt2 vue 给特定的页面 body 设置 background 不影响其他页面
首先认识一下 BODY_ATTRS 他可以在页面单独设置 head () {return {bodyAttrs: {form: form-body}};},设置完效果是只有这个页面会加上 接下来在APP.vue中添加样式...
【Go】运算符笔记
基本数学运算 Go 语言支持常见的 算术运算符,用于执行数学计算。 运算符说明加法-减法*乘法/除法%取余自增--自减 整数运算只能得到整数部分 package mainimport ("fmt""math" )func main() {go_math() }func go_math() {x, y : 8, 5fmt.Pr…...
常见的前端安全问题
前端安全是 Web 开发中至关重要的一环,以下是常见的前端安全问题及对应的防御措施: 1. XSS(跨站脚本攻击) 攻击原理 攻击者向页面注入恶意脚本(如 JavaScript),在用户浏览器中执行,…...
基于Spring Boot的项目申报系统的设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
SPI驱动(九) -- SPI_Master驱动程序
文章目录 参考资料:一、SPI传输概述二、SPI传输的两种方法2.1 旧方法2.2 新方法 参考资料: 参考资料: 参考内核源码: drivers\spi\spi.c 一、SPI传输概述 SPI控制器的作用是发起与它下面挂接的SPI设备之间的数据传输,那么控制…...
Transformer网络发展概述2025.3.18
一.Transformer概述 1.1 定义与原理 Transformer是一种基于自注意力机制的深度学习模型,在处理序列数据时表现卓越。其核心原理包括: 自注意力机制 :允许模型同时考虑输入序列中的所有位置,捕捉语义关系多头注意力 :…...
3.4 二分查找专题:LeetCode 69. x 的平方根
1. 题目链接 LeetCode 69. x 的平方根 2. 题目描述 给定一个非负整数 x,计算并返回 x 的平方根的整数部分(向下取整)。 示例: 输入:x 4 → 输出:2输入:x 8 → 输出:2࿰…...
机器人曲面跟踪Surface-Tracking
定义 机器人曲面跟踪(Surface-Tracking)是指机器人通过实时感知工件曲面的三维形貌,动态调整运动轨迹和位姿,以精确跟随曲面进行加工(如打磨、抛光、喷涂等)的技术。 力 - 位姿协同控制 力控模式ÿ…...
opencv中stitch图像融合
openv版本: opencv249 vs :2010 qt : 4.85 #include "quanjing.h"#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <open…...
深入解析ES6+新语法:复杂的迭代器与生成器
一、迭代器(Iterator):数据遍历的统一协议 1. 迭代器协议的本质 **迭代器协议(Iterator Protocol)** 是一种标准化的数据访问接口,它要求对象实现一个 next() 方法,每次调用返回包含 { valu…...
【C语言】自定义类型:结构体
一、结构体类型的声明 我们前面学习操作符的时候已经接触过结构体了,下面我们回顾一下结构体的基本内容。 创建结构体的语法如上所示: struct是创建结构体的关键字,然后tag就是我们结构体的名称,member-list是结构体的成员列表&…...
微服务即时通信系统---(五)框架学习
目录 ODB 介绍 安装 build2安装 odb-compiler安装 ODB运行时库安装 mysql和客户端开发包安装 boost profile库安装 总体打包安装 总体卸载 总体升级 头文件包含和编译时指明库 ODB常见操作介绍 类型映射 ODB编程 类与接口介绍 mysql连接池对象类 mysql客户端…...
蓝桥杯练习day1:自除数
前言 自除数 是指可以被它包含的每一位数整除的数。 例如,128 是一个 自除数 ,因为 128 % 1 0,128 % 2 0,128 % 8 0。 自除数 不允许包含 0 。 给定两个整数 left 和 right ,返回一个列表,列表的元素…...
0基础 | 上下拉电阻典型应用场景
三极管典型运用: 上拉电阻 下拉电阻 限流电阻 此处开关为三极管 左侧电阻:驱动电阻【限流电阻】 (控制mos管) 下面电阻:下拉电阻【关断电阻】 %%作用1: (因为IO口输出信号分为低电平&…...
MySQL数据高效同步到Elasticsearch的四大方案
目录 引言 一、为什么需要MySQL到ES的同步? 二、四大同步方案对比 三、方案详解与代码实战 1. 应用层双写:简单但强耦合 2. 定时任务同步:可控的准实时 3. Logstash JDBC:离线迁移利器 4. Binlog监听:生产级实…...
Docker详解
云是一种服务理念。在云里docker是业务的最小载体 doker是管理容器的引擎,为应用打包、部署平台、而非单纯的虚拟化技术 1.轻量级虚拟化 2.一致性 4.高效的资源利用 5.易于部署和扩展 docker和虚拟机的区别: 虚拟机:真机需要一个操作系…...
清晰易懂的Maven安装教程(含自定义依赖包位置)
初学者也能看懂的 Maven 安装教程(含自定义依赖包位置) Maven 是一个强大的项目管理和构建工具,广泛用于 Java 项目的依赖管理和构建自动化。本教程将手把手教你如何在 Windows 系统上安装 Maven,并配置环境变量,同时…...
王道数据结构6.3
顶点x的第一个邻接点以及下一个邻接点 int first_neighbor(Algraph G, int x){if(G.vertices[x].firstarc! nullptr){return G.vertices[x].firstarc->adjvex;}else return -1; }int next_neighbor(Algraph G,int x,int y){ArcNode *pG.vertices[x].firstarc;while(p! null…...
【Linux操作系统——学习笔记二】Linux简单导航命令操作
一、前言 学习Linux,本质上是学习在命令行下熟练使用Linux的各类命令。 命令行:是一种通过输入命令和参数与计算机系统进行交互的方式,可以使用各种字符化命令对系统发出操作指令,打开Linux终端,进入命令行界面。 …...
贪心算法——c#
贪心算法通俗解释 贪心算法是一种"每一步都选择当前最优解"的算法策略。它不关心全局是否最优,而是通过局部最优的累积来逼近最终解。优点是简单高效,缺点是可能无法得到全局最优解。 一句话秒懂 自动售货机找零钱:用最少数量的…...
SPI 总线协议
1、协议介绍 SPI,是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口。是 Motorola 首先在其 MC68HCXX 系列处理器上定义的。 SPI,是一种高速的,全双工,同步的通信总线。主节点或子节点的数据在…...
单片机开发资源分析的实战——以STM32G431RBT6为例子的单片机资源分析
目录 第一点:为什么叫STM32G431RBT6 从资源手册拿到我们的对STM32G431RBT6的资源描述 第二件事情,关心我们的GPIO引脚输出 第三件事情:去找对应外设的说明部分 第一点:为什么叫STM32G431RBT6 对于命名规则不太熟悉的朋友看这里…...
物联网(IoT)架构中,平台层的应用与技术
在物联网(IoT)架构中,平台层是连接物理设备(感知层)和应用服务(应用层)的核心部分。它负责数据的采集、处理、存储、分析以及设备管理等功能,是物联网系统的“大脑”。以下是平台层的主要功能及其技术实现手段: 平台层的主要功能 设备管理: 功能:管理物联网设备的注…...
大语言模型的压缩技术
尽管人们对越来越大的语言模型一直很感兴趣,但MistralAI 向我们表明,规模只是相对而言的,而对边缘计算日益增长的兴趣促使我们使用小型语言获得不错的结果。压缩技术提供了一种替代方法。在本文中,我将解释这些技术,并…...
JVM 2015/3/15
定义:Java Virtual Machine -java程序的运行环境(java二进制字节码的运行环境) 好处: 一次编写,到处运行 自动内存管理,垃圾回收 数组下标越界检测 多态 比较:jvm/jre/jdk 常见的JVM&…...
DeepSeek辅助学术写作中期能力及提示词分享
目录 确立三论 收集资料 选取论据 展开论证 大家好这里是AIWritePaper官方账号!更多内容👉AIWritePaper~在如今这个学术圈的“快车道”上,时间就像是一场永不停歇的赛跑,而论文质量则是那颗我们拼命追逐的“金苹果”。最近一款…...
Git 实战指南:本地客户端连接 Gitee 全流程
本文将以 Gitee(码云)、系统Windows 11 为例,详细介绍从本地仓库初始化到远程协作的全流程操作 目录 1. 前期准备1.1 注册与配置 Gitee1.2 下载、安装、配置客户端1.3 配置公钥到 Gitee2. 本地仓库操作(PowerShell/Git Bash)2.1 初始化本地仓库2.2 关联 Gitee 远程仓库3. …...
汇编基础知识
机器语言 1、机器语言是机器指令的集合,机器指令就是机器可以正确执行的命令,由二进制数组成 2、当今我们常用的是pc机,由一个芯片完成上述功能,即CPU是一种微处理器,每一种微处理器由于自身硬件设计和内部构造不同都…...
线程池的拒绝策略适用场景思考
ThreadPoolExecutor有四种拒绝策略。刚开始学习线程池的时候我就觉得,就是应该当任务饱和(达到拒绝策略)时,就应该拒绝任务,抛出异常。最近仔细思考了下,既然线程池这么设计,也应该有一定的道理…...