【C++初阶】vector容器

在这里插入图片描述

👦个人主页:@Weraphael
✍🏻作者简介:目前学习C++和算法
✈️专栏:C++航路
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨


目录

  • 一、什么是vector
  • 二、vector初始化
      • 2.1 默认构造函数(常见)
      • 2.2 构造函数将n个元素拷贝给本身
      • 2.3 拷贝构造函数(常见)
      • 2.4 区间拷贝
      • 2.5 数组方式
  • 三、迭代器的使用
      • 3.1 begin + end(常见)
      • 3.2 rbegin + rend
  • 四、遍历
      • 4.1 operator[]
      • 4.2 迭代器遍历
      • 4.3 范围for
  • 五、空间增长问题
      • 5.1 size
      • 5.2 empty
      • 5.3 resize
      • 5.4 reserve
      • 5.5 swap
  • 六、vector的插入与删除
      • 6.1 push_back - 尾插
      • 6.2 pop_back - 尾删
      • 6.3 insert - 插入
      • 6.4 erase - 删除pos位置的数据
      • 6.5 clear - 清空所有数据
  • 七、几个常用算法
      • 7.1 sort - 排序
      • 7.2 reverse
      • 7.3 find
  • 八、迭代器失效问题
      • 8.1 什么是迭代器失效
      • 8.2 为什么string不存在迭代器失效问题
      • 8.3 几个常见的迭代器失效样例
      • 8.4 如何解决迭代器失效问题

一、什么是vector

  • vector容器和数组非常相似,与普通数组的区别:数组是静态空间,而vector可以动态扩展
  • 动态扩展并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间
  • 使用vector容器需要包含头文件:#include <vector>
  • vector可以存储多种不同的数据类型,是因为它是一个模板容器
    在这里插入图片描述
    通过使用模板参数,我们可以在vector中指定要存储的数据类型,例如:
vector<int> vi // 整型容器
vector<char> vc // 字符型容器
vector<double> vd // 浮点型容器
vector<string> vs // string类型容器
vector<vector<int>> // 本质是二维数组
// 等等...

类模板实例化与普通类的实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,而普通类的类名就是类型。

注意:需要注意数据类型的统一性。例如,如果创建了一个存储整数的vector,就应该只向其中存储整数类型的数据,否则可能会出现类型错误或数据损坏的问题。

二、vector初始化

2.1 默认构造函数(常见)

#include <iostream>
#include <vector>
using namespace std;
int main()
{// 默认构造函数vector<int> v;return 0;
}

默认构造的对象,sizecapacity都为0。

在这里插入图片描述

2.2 构造函数将n个元素拷贝给本身

【函数原型】

vector<T> v(n,elem);

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{// 构造函数将n个元素拷贝给本身// 将3个100拷贝给本身vector<int> v(3, 100);for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

2.3 拷贝构造函数(常见)

【函数原型】

vector (const vector& x);

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{// 构造函数将3个100拷贝给本身vector<int> v1(3, 100);cout << "v1:";for (int i = 0; i < v1.size(); i++){cout << v1[i] << ' ';}cout << endl;// 拷贝构造函数// v2是v1的副本vector<int> v2(v1);cout << "v2:";for (int i = 0; i < v2.size(); i++){cout << v2[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

2.4 区间拷贝

【函数原型】

vector(v.begin(),v.end());

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{// 构造函数将n个元素拷贝给本身// 将5个100拷贝给本身vector<int> v1;// 写入1 2 3 4 5v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);// 区间拷贝// 拷贝v1对象中的2、3、4、5vector<int> v2(v1.begin() + 1, v1.end());cout << "v2:";for (int i = 0; i < v2.size(); i++){cout << v2[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

2.5 数组方式

#include <iostream>
#include <vector>
#include <string>
using namespace std;int main()
{vector<int> v1{ 1,2,3,4,5,6 };vector<char> v2{ 'h','e','l','l','o' };vector<string> v3{ "hello", "vector" };return 0;
}

【输出结果】

在这里插入图片描述

三、迭代器的使用

3.1 begin + end(常见)

大家可以认为迭代器是指针。begin指向第一个数据的位置,end指向最后一个数据的下一个位置

在这里插入图片描述

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');vector<char>::iterator begin = v.begin();// begin指向第一个元素,对齐解引用就能得到cout << "第一个元素为:" << *begin << endl;vector<char>::iterator end = v.end();// end指向最后一个元素的下一个位置cout << "最后一个元素为:" << *(end - 1) << endl;return 0;
}

【输出结果】

在这里插入图片描述

3.2 rbegin + rend

rbeginrend是反着来的。rbegin指向的是最后一个元素,rend指向的是第一个元素的前一个位置
在这里插入图片描述

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// vector<char>::iterator 如果认为太长// 可用autoauto vci = v.rbegin();// vci指向最后一个元素cout << "最后一个元素:" << *vci << endl;auto vcc = v.rend();// vcc指向第一个元素的前一个位置// 对其-1。就指向第一个元素cout << "第一个元素" << *(vcc - 1) << endl;return 0;
}

【输出结果】

在这里插入图片描述

四、遍历

4.1 operator[]

在这里插入图片描述

vector底层重载了下标访问操作符[],因此可以像数组一样变量

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// operator[]for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

4.2 迭代器遍历

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// 迭代器vector<char>::iterator begin = v.begin();while (begin != v.end()){cout << *begin << ' ';begin++;}cout << endl;// 以上用for循环也是可以的for (vector<char>::iterator begin = v.begin(); begin != v.end(); begin++){cout << *begin << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

4.3 范围for

string类时,我们讲过 范围for的底层是迭代器。

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// 范围forfor (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

五、空间增长问题

5.1 size

功能:获取数据的有效个数

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v{ 1,2,3,4 };cout << "个数为:" << v.size() << endl;for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

5.2 empty

功能:判断容器是否为空。如果为空返回1,否则返回0

#include <iostream>
#include <vector>
using namespace std;int main()
{// 默认构造默认有效个数size为0vector<int> vi;cout << "vi:" << vi.empty() << endl;vector<char> vc{ 'h', 'e', 'l', 'l','o' };cout << "vc:" << vc.empty() << endl;return 0;
}

【输出结果】

在这里插入图片描述

5.3 resize

【函数原型1】

resize(int num);

功能:重新指定容器的长度为num

情况1:若有效数据size > num,则会保留前num个,剩下的删除

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v{ 1,2,3,4,5,6 };cout << "改变之前的长度:" << v.size() << endl;// 重新指定容器长度// 保留前3个v.resize(3);cout << "改变后的长度:" << v.size() << endl;cout << "改变后的内容为:";for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【程序结果】

在这里插入图片描述

【函数原型2】

resize(int num, elem);

情况2:若num > size,则会增加有效长度。如果不指定第二个参数,默认增加的内容是0

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v1{ 1,2,3,4 };v1.resize(6);// 增加了2个,不指定第二个参数默认是0for (auto x : v1){cout << x << ' ';}cout << endl;vector<char> v2{ 'h','i' };v2.resize(6, 'x');for (auto x : v2){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

5.4 reserve

功能:改变vector容器的容量。一般都是扩容。

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;int capacity = v.capacity();for (int i = 0; i < 100; i++){// 插入100个数据v.push_back(i);// v.capacity是输出当前容量的if (capacity != v.capacity()){capacity = v.capacity();cout << "容量改变:" << capacity << '\n';}}return 0;
}

【输出结果】

在这里插入图片描述

通过以上代码我们发现:vs下的容量是按1.5倍增长的g++是按2倍增长的。

然后我们再把以上代码拿到Linux环境下测试:

在这里插入图片描述

我们发现:Linux下使用的vector是按照2倍方式扩容。

因此,如果已经确定vector中要存储元素大概个数,可以提前将空间设置足够就可以避免边插入边扩容导致效率低下的问题了。

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;int capacity = v.capacity();// 提前开好大小为100的容量v.reserve(100);for (int i = 0; i < 100; i++){// 插入100个数据v.push_back(i);// v.capacity是输出当前容量的if (capacity != v.capacity()){capacity = v.capacity();cout << "容量改变:" << capacity << '\n';}}return 0;
}

【输出结果】

在这里插入图片描述

或者还能这样开空间:

在这里插入图片描述

5.5 swap

【函数原型】

swap(vec); // 将vec与本身的元素互换

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v1{1,2,3,4,5,6};v1.reserve(100);cout << "交换前:" << endl;cout << "v1:";for (auto x : v1){cout << x << ' ';}cout << endl;vector<int> v2{ 7,8,9,10,11, 12 };cout << "v2:";for (auto x : v1){cout << x << ' ';}cout << endl;cout << "v1的容量" << v1.capacity() << endl;cout << "v2的容量" << v2.capacity() << endl;// 交换v1.swap(v2);cout << "交换后:" << endl;cout << "v1:";for (auto x : v1){cout << x << ' ';}cout << endl;cout << "v2:";for (auto x : v1){cout << x << ' ';}cout << endl;cout << "v1的容量" << v1.capacity() << endl;cout << "v2的容量" << v2.capacity() << endl;return 0;
}

【输出结果】

在这里插入图片描述

通过以上发现:swap不仅可以交换容器内容,同时还达到实用的收缩内存效果

六、vector的插入与删除

6.1 push_back - 尾插

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

6.2 pop_back - 尾删

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;// 删掉4v.pop_back();for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

6.3 insert - 插入

【函数原型1】

iterator insert (iterator position, const value_type& val);

注意:insert是要配合迭代器使用的!

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;// 头插一个6v.insert(v.begin(), 6);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

【函数原型2】

void insert (iterator position, size_type n, const value_type& val);

【代码样例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;// 尾插4个6v.insert(v.end(), 4, 6);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

6.4 erase - 删除pos位置的数据

【函数原型1】

erase(const iterator pos);

注意:erase也是要配合迭代器使用的

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);// 删除最后一个数据v.erase(v.end() - 1);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

【函数原型2】

erase(const iterator start,const iterator end)

功能:删除某个区间的数据

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);// 清空数据v.erase(v.begin(), v.end());for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

除了以上方式可以清空数据,clear同样也行

6.5 clear - 清空所有数据

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.clear();for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

七、几个常用算法

注意:使用库里的算法需要加上头文件#include <algorithm>

7.1 sort - 排序

#include <iostream>
#include <vector>
using namespace std;
#include<algorithm>int main()
{vector<int> a{ 4,7,1,0,5,3, 2 };// 从小到大sort(a.begin(), a.end());for (auto x : a){cout << x << ' ';}cout << endl;// 从大到小sort(a.rbegin(), a.rend());for (auto x : a){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

7.2 reverse

#include <iostream>
#include <vector>
using namespace std;
#include<algorithm>int main()
{vector<int> a{ 1,2,3,4,5,6 };//逆置reversereverse(a.begin(), a.end());for (auto x : a){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

7.3 find

注意:vector是没有提供find接口的。而我们知道vector是一个类似于数组的容器,因此如果想找一个数据,直接遍历即可。但是算法库提供了find

#include <iostream>
#include <vector>
using namespace std;
#include<algorithm>int main()
{vector<int> a{ 1,2,3,4,5,6 };// 查找4vector<int>::iterator pos = find(a.begin(), a.end(), 4);if (pos != a.end()){// 找到4就删掉a.erase(pos);}for (auto x : a){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

八、迭代器失效问题

8.1 什么是迭代器失效

迭代器失效实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃。即如果继续使用已经失效的迭代器,程序可能会崩溃。

8.2 为什么string不存在迭代器失效问题

string是一个特殊的容器,它是由字符组成的连续序列,类似于C语言的字符串。string类会动态地管理内部存储区域,确保足够的容量容纳字符串。当我们向string中插入或删除字符时,并不会导致整个字符串被复制到新的内存位置,因此迭代器不会失效。

对比vector,它是一个动态数组,它使用连续的内存存储元素。当我们向vector中插入元素时,如果导致当前内存不足以容纳所有元素,vector会重新分配更大的内存空间,并将所有元素复制到新的内存中。这样一来,原来指向旧内存中的元素的迭代器就会失效,因为它们指向的位置已经改变了。

8.3 几个常见的迭代器失效样例

当涉及到插入或删除操作时,我们需要注意vector迭代器的失效问题

  • 会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resizereserveinsertpush_back
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v{ 1, 2, 3 };// 1. 将有效元素个数增加到100个//   多出的位置使用6填充,操作期间底层会扩容v.resize(100, 6);// 2. reserve的作用就是改变扩容大小但不改变有效元素个数,// 操作期间可能会引起底层容量改变v.reserve(100);// 3. insert和尾插期间// 可能会引起扩容,而导致原空间被释放v.insert(v.begin(), 0);v.push_back(10);return 0;
}

以上操作可能会导致vector扩容,扩容就会导致旧空间被释放掉,而返回的迭代器是指向被释放的空间,如果再对迭代器进行使用,会引起代码崩溃。

  • 指定位置元素的删除操作
#include <iostream>
#include <vector>
using namespace std;int main()
{int a[] = { 1, 2, 3, 4, 5 };vector<int> v(a, a + sizeof(a) / sizeof(int));// 使用find查找4所在位置auto pos = find(v.begin(), v.end(), 4);// 删除pos位置的数据,v.erase(pos);// 预测打印5cout << *pos << endl;return 0;
}

【输出结果】

理论上删除了4*pos应该是5,可是为什么没有打印出来呢?

我们可以通过调试来观察:

在这里插入图片描述

当我再按F10,发现pos的地址变了:

在这里插入图片描述

理论上删除4后,5应该占据4的空间,然而地址却变了。因此导致了迭代器失效了。

那如果是删除最后一个数据,那么结果更加明显:

在这里插入图片描述

8.4 如何解决迭代器失效问题

在使用前,对迭代器重新赋值即可。

#include <vector>
#include <iostream>
using namespace std;
int main()
{vector<int> v{ 1,2,3,4,5,6,7,8,9,10};// 保留1 2 3// 剩下全删除vector<int>::iterator it = v.begin() + 3;while (it != v.end()){// 在使用之前重新赋值it = v.erase(it);}for (auto& x : v){cout << x << ' ';}cout << endl;return 0;
}

在这里插入图片描述

【输出结果】

在这里插入图片描述

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

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

相关文章

C++day1(笔记整理)

一、Xmind整理&#xff1a; 二、上课笔记整理&#xff1a; 1.第一个c程序&#xff1a;hello world #include <iostream> //#:预处理标识符 //<iostream>:输入输出流类所在的头文件 //istream:输入流类 //ostream:输出流类using namespace std; //std&#x…

编写一个俄罗斯方块

编写俄罗斯方块 思路。 1、创建容器数组&#xff0c;方块&#xff0c; 2、下落&#xff0c;左右移动&#xff0c;旋转&#xff0c;判断结束&#xff0c;消除。 定义一个20行10列的数组表示游戏区。初始这个数组里用0填充&#xff0c;1表示有一个方块&#xff0c;2表示该方块固…

基于Java SpringBoot+vue+html 的地方美食系统(2.0版本)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,csdn、博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 1 简介2 技术栈3 系统流程的分析3.1 用户管理的流程3.2个人中心管理流程3.3登录流程 4系统设计…

【BASH】回顾与知识点梳理(三十六)

【BASH】回顾与知识点梳理 三十六 三十六. 认识与分析登录档36.1 什么是登录档CentOS 7 登录档简易说明登录档的重要性Linux 常见的登录档档名登录档所需相关服务 (daemon) 与程序CentOS 7.x 使用 systemd 提供的 journalctl 日志管理 登录档内容的一般格式 36.2 rsyslog.servi…

从 Ansible Galaxy 使用角色

从 Ansible Galaxy 使用角色 根据下列要求&#xff0c;创建一个名为 /home/curtis/ansible/roles.yml 的 playbook &#xff1a; playbook 中包含一个 play&#xff0c; 该 play 在 balancers 主机组中的主机上运行并将使用 balancer 角色。 此角色配置一项服务&#xff0c;以…

桌面软件开发框架 Electron、Qt、WPF 和 WinForms 怎么选?

一、Electron Electron 是一个基于 Web 技术的跨平台桌面应用程序开发框架。它使用 HTML、CSS 和 JavaScript 来构建应用程序界面,并借助 Chromium 渲染引擎提供强大的页面渲染能力。Electron 的主要特点包括: 跨平台:Electron 可以在 Windows、macOS 和 Linux 等多个主流操…

蓝蓝设计UI设计公司-界面设计与开发案例

天津航天中为项目 中国南方电网十二个软件交互优化和界面设计 图标设计 | 交互设计 | 界面设计 天津航天中为数据系统科技有限公司是航天503所控股的专业化公司&#xff0c;坐落于天津滨海新区航天技术产业园&#xff0c;是航天五院家入住天津未来科技城的军民融合型企业&…

回归预测 | MATLAB实现FA-BP萤火虫算法优化BP神经网络多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现FA-BP萤火虫算法优化BP神经网络多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现FA-BP萤火虫算法优化BP神经网络多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览基本介绍程…

JSON的处理

1、JSON JSON(JavaScript Object Notation)&#xff1a;是一种轻量级的数据交换格式。 它是基于 ECMAScript 规范的一个子集&#xff0c;采用完全独立于编程语言的文本格式来存储和表示数据。 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写&#…

Mybatis的学习笔记(IDEA快捷键,参数占位符,转义符)

一、IDEA快捷键&#xff1a; IDEA多行注释&#xff1a;ctrlShift/ 单行注释&#xff1a;ctrl/ 导入包&#xff0c;自动修正代码&#xff1a;altenter 自动生成代码&#xff1a;altinsert 二、Mybatis重要知识点&#xff1a; 2.1 参数占位符 一共分为2种&#xff1a;#{}和…

基于百度文心大模型创作的实践与谈论

文心概念 百度文心大模型源于产业、服务于产业&#xff0c;是产业级知识增强大模型。百度通过大模型与国产深度学习框架融合发展&#xff0c;打造了自主创新的AI底座&#xff0c;大幅降低了AI开发和应用的门槛&#xff0c;满足真实场景中的应用需求&#xff0c;真正发挥大模型…

5.7.webrtc线程的启动与运行

那在上一节课中呢&#xff1f;我向你介绍了web rtc的三大线程&#xff0c;包括了信令线程&#xff0c;工作线程以及网络线程。那同时呢&#xff0c;我们知道了web rtc 3大线程创建的位置以及运行的时机。 对吧&#xff0c;那么今天呢&#xff1f;我们再继续深入了解一下&#…

k8s v1.27.4 部署metrics-serverv:0.6.4,kube-prometheus

只有一个问题&#xff0c;原来的httpGet存活、就绪检测一直不通过&#xff0c;于是改为tcpSocket后pod正常。 wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml修改后的yaml文件&#xff0c;镜像修改为阿里云 apiVersion: …

窗口函数大揭秘!轻松计算数据累计占比,玩转数据分析的绝佳利器

上一篇文章《如何用窗口函数实现排名计算》中小编为大家介绍了窗口函数在排名计算场景中的应用&#xff0c;但实际上窗口函数除了可以进行单行计算&#xff0c;还可以在每行上打开一个指定大小的计算窗口&#xff0c;这个计算窗口可以由SQL中的语句具体指定&#xff0c;大到整个…

S05-巧用单元格格式转换数据

视频教程 文章目录 S05-巧用单元格格式转换数据 S05-巧用单元格格式转换数据 格式类型默认格式&#xff08;常规&#xff09;转换格式数值1.21.200货币1.2&#xffe5;1.20会计专用1.2&#xffe5;1.20日期43567四月十二日时间0.3333333338:00 AM百分比1.2120.00%分数0.21/5科…

工作纪实37-mybatis-plus关闭结果集输出log

1.springbootmybatis-pluslogback.xml组合&#xff0c;运行mapper会把sql查询会把结果也打印出来&#xff09;&#xff0c;但是就是不想让它输出到控制台&#xff0c;今天就来记录一下如何操作才能不把sql结果集打印出来&#xff0c;当然sql语句还是会打印的。 2、修改配置 …

响应式编程

响应式编程 响应式编程打破了传统的同步阻塞式编程模型&#xff0c;基于响应式数据流和背压机制实现了异步非阻塞式的网络通信、数据访问和事件驱动架构&#xff0c;能够减轻服务器资源之间的竞争关系&#xff0c;从而提高服务的响应能力。 一、Reactive Stream 要了解什么是响…

从零实战SLAM-第九课(后端优化)

在七月算法报的班&#xff0c;老师讲的蛮好。好记性不如烂笔头&#xff0c;关键内容还是记录一下吧&#xff0c;课程入口&#xff0c;感兴趣的同学可以学习一下。 --------------------------------------------------------------------------------------------------------…

【STM32CubeMX】低功耗模式

前言 本文讲解STM32F10X的低功耗模式&#xff0c;部分资料参考自STM32手册。STM32F10X提供了三种低功耗模式&#xff1a;睡眠模式&#xff08;Sleep mode&#xff09;、停机模式&#xff08;Stop mode&#xff09;和待机模式&#xff08;Standby mode&#xff09;。这些低功耗模…

mysql通过binlog日志恢复误删数据

1、先查看binlog功能是否开启 show variables like %log_bin%;log_bin为ON说明可以使用binlog恢复&#xff0c;如果为OFF说明没有开启binlog。 2、删除部分数据做测试 3、查找binlog文件位置 show variables like %datadir%;cd /var/lib/mysqlls -l删除数据时间是在文件154与…