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

详解list容器

1.list的介绍

list的底层结构是双向带头循环链表,允许随机的插入和删除,但其内存空间不是连续的。随机访问空间能力差,需要从头到尾遍历节点,不像vector一样高效支持

2.list的使用

构造函数

在这里插入图片描述
1.默认构造函数:创建一个空链表

加()会被解析为函数声明而不是对象定义,不会调用默认构造。后面加{}同样可以正确初始化
在这里插入图片描述

2.填充构造函数

用于创建一个包含多个相同值的链表。

3.范围构造函数

用于从其他容器或范围中复制元素到新链表。
在这里插入图片描述

4.拷贝构造函数

用于通过拷贝另一个std::list对象来创建新链表
在这里插入图片描述

5.用数组来构造list

本质上也是利用迭代器来范围构造,数组的指针为原生迭代器
在这里插入图片描述

容量函数

在这里插入图片描述

1.检测list是否为空,是返回true,否则返回false
2.返回list中有效节点的个数,常用于循环,条件判断等
3.用于了解容器的最大容量限制,通常在需要预先分配大量内存或进行容量规划时使用。

元素访问

在这里插入图片描述

1.返回容器中第一个元素的引用。container.front()
2.返回容器中最后一个元素的引用。container.back()

注意:
1.空容器检查:可通过empty检查,否则造成未定义行为
2.常量容器:需要返回常量引用(const T&)
3.适用容器:适用于大多数标准库容器,包括 std::list、std::vector、std::deque 等
在这里插入图片描述
因为是传引用返回,可直接修改返回值

修改操作函数

在这里插入图片描述在这里插入图片描述

重点分析:

splice

翻译为链接,拼接,但理解为转移更好,将原容器中节点重新链接到目标容器中,不是复制元素,原容器中这些节点就相当于删除了,所以“转移”理解更贴切。
在这里插入图片描述

1.整个链表转移:
将整个列表x的内容移动到*this列表中,插入到position迭代器所指的位置之前。操作后,x将变为空列表。
在这里插入图片描述

2.单个元素转移:
将列表x中的单个元素i移动到*this列表中,插入到position迭代器所指的位置之前。操作后,i在x中将不再有效。
在这里插入图片描述

3.元素范围转移:
将列表x中从first到last(不包括last)的元素范围移动到*this列表中,插入到position迭代器所指的位置之前。操作后,first到last范围内的元素在x中将不再存在。
在这里插入图片描述

sort

list底层用的归并算法,vector底层用的快排适合sort算法。

原因:链表不支持随机访问,因此像快速排序这样依赖随机访问的算法效率较低。而合并排序在链表上的性能更优,因为它主要依赖顺序访问和合并操作。

性能测试:

void test_op()
{srand(time(0));const int N = 100000;vector<int> v;v.reserve(N);list<int> lt1;list<int> lt2;for (int i = 0; i < N; ++i){auto e = rand();lt2.push_back(e);lt1.push_back(e);}// 拷贝到vector排序,排完以后再拷贝回来int begin1 = clock();// 先拷贝到vectorfor (auto e : lt1){v.push_back(e);}// 排序sort(v.begin(), v.end());// 拷贝回去size_t i = 0;for (auto& e : lt1){e = v[i++];}int end1 = clock();int begin2 = clock();lt2.sort();int end2 = clock();printf("vector sort:%d\n", end1 - begin1);printf("list sort:%d\n", end2 - begin2);
}

步骤:
1.随机数生成和数据准备
srand(time(0)):用当前时间初始化随机数生成器,定义一个常量N,表示要生成的随机数数量
vector v:创建一个vector,用于存储从list中拷贝出来的元素
v.reserve(N):预先为vector分配足够的内存,避免在后续插入元素时频繁重新分配内存。
list lt1, lt2:创建两个list,lt1和lt2,用于存储相同的随机数序列。
2. 使用vector辅助排序list
begin1 = clock():记录开始时间。
拷贝list到vector:将lt1中的所有元素拷贝到vector中。
排序vector:使用std::sort对vector进行快速排序。
拷贝排序结果回list:将排序后的vector中的元素拷贝回lt1。
end1 = clock():记录结束时间。
3. 直接使用list的sort方法
begin2 = clock():记录开始时间。
lt2.sort():直接对lt2进行排序。
end2 = clock():记录结束时间。
在这里插入图片描述
在这里插入图片描述
可以从结果看出,随着数据量的增大二者效率差别更大,但如果数据量较小的时候用起来差别不大,并且在容器中设计了这样一个函数,在特定情境使用起来也非常方便;如果数据量大的情况下根据需求选择合适的容器比如vector支持随机访问,底层快排实现,比list更好,就不用一定要使用list。

unique

在这里插入图片描述

1.无参数版本:
移除链表中所有连续重复的元素,只保留每个连续重复组的第一个元素。只有当一个元素与其前一个元素相等时才会被移除。因此,该函数特别适用于已排序的链表。
在这里插入图片描述

2.带参数版本:
使用自定义的二元谓词来确定元素是否应该被移除。
对于所有元素对(从第二个元素开始),如果二元谓词返回true,则移除该元素。

remove

在这里插入图片描述

移除特定值的元素:std::list::remove会从链表中移除所有等于val的元素。
调用析构函数:被移除的元素的析构函数会被调用。
减少容器大小:容器的大小(size)会减少被移除的元素的数.

与list::erase的区别:

list::erase通过迭代器指定位置来删除元素。
在这里插入图片描述

list::remove通过元素的值来删除元素。
在这里插入图片描述

迭代器失效

迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。
解决办法:
只需要接收erase的返回值就好了,返回值为被删除节点的下一个位置。

3.list的模拟实现

结点定义为公有的,操作方便,成员函数中触碰不到结点,即使定义为公有,别人也不知道具体细节。用struct定义,跟库中保持一致,但此库非C语言中的库,而是类,默认公有。

封装节点

在这里插入图片描述
定义了一个类模板list_node,是一个双向链表节点的结构体,每个节点包含前指针和后指针以及存储值,用它进行传参和访问的时候更高效,包含多种数据信息。

迭代器类模板

//更加通用灵活的类模板迭代器
//typedef _list_iterator<T, T&, T*>iterator;
//typedef _list_iterator<T,const T&,const T*> const_iterator;
template<class T,class ref,class ptr>struct _list_iterator
{typedef list_node<T> Node;//别名,表示链表节点类型typedef _list_iterator<T, ref, ptr> self;//别名,表示当前迭代器类型Node* _node;_list_iterator(Node* node):_node(node){ }//返回当前节点值ref operator*(){return _node->_val;}//返回当前节点值指针ptr operator->(){return &_node->_val;}//前置++self& operator++(){_node = _node->_next;return *this;}//后置++,移动到下一个节点,返回旧状态self operator++(int){self tmp(*this);_node = _node->_next;return tmp;}//前置--self& operator--(){_node = _node->_prev;return *this;}//后置--,移动到前一个节点,返回旧状态self operator--(int){self tmp(*this);_node = _node->_prev;return tmp;}//比较两个迭代器是否不相等bool operator!=(const self& it)const{return _node != it._node;}//比较两个迭代器是否相等bool operator==(const self& it)const{return _node == it._node;}
};

这是一个更通用灵活的模板类,用于实现双向链表的迭代器。
为什么这样设计?
因为list不是一段连续的空间,原生的指针不能完成++或者解引用操作,而C++中对于内置类型无法完成的行为,可以用自定义类型去重载运算符来改变其行为,从而满足自身需求
功能解析:
1.模板参数
T:链表节点中存储的值的类型。
ref:解引用操作符返回的引用类型(例如 T& 或 const T&)。
ptr:箭头操作符返回的指针类型(例如 T* 或 const T*)
2.成员变量
_node:指向当前节点的指针。
3.构造函数
接受一个 Node* 类型的参数,初始化 _node
4.操作符重载:
注意:前置++和后置++重载都需要先拷贝构造一个临时对象,来保存节点当前状态用于返回,再进行操作,返回值不能传引用,因为临时变量具有常性,会造成权限放大的问题。
关于->操作符:
箭头操作符(->)在C++中用于访问指针指向的对象的成员。在迭代器的上下文中,箭头操作符通常被重载,以便能够方便地访问迭代器所指向的节点的值。
在这里插入图片描述
ptr 是模板参数,表示返回的指针类型(例如 T* 或 const T*)。
_node 是指向当前节点的指针。
_node->_val 是当前节点中存储的值。
返回 _node->_val 的地址,这样可以通过箭头操作符访问值的成员。
在这里插入图片描述
编译器会自动处理箭头操作符的链式调用,使得代码更加可读。

迭代器的职责

没有自定义实现调用默认生成的拷贝构造函数,发生浅拷贝,这是我们期望的,返回值也指向该结点
为什么没崩溃?因为没有自定义实现析构函数
为什么不析构?因为迭代器作用只是去访问结点而不是去管理,不需要自定义析构函数来释放节点的内存。当迭代器对象被销毁时,只是销毁指针本身,而不会影响节点的内存。容器类(如 list)负责管理节点的内存,包括分配和释放。
通过封装可以使stl中各容器的迭代器的使用方法都类似,而底层却千差万别,这就是魅力所在,对于内置类型指针是否需要深拷贝取决于实际需求,由自己控制

辨析
const迭代器设计思想

我们期望迭代器本身是能被修改的,进行重载之后的解引用,访问,自增和自减的操作。期望迭代器指向的内容不被修改。
按照之前的经验以及实现过的vector,会习惯于在类名前加一个const来修饰,但vector内存连续布局,原生指针就能很好满足迭代器需求,可以这么写;但list内存非连续,需要自定义迭代器来重载一些操作。

typedef const __list_iterator<> const_iterator;
这样设计const迭代器是不行的,因为const迭代器期望指向内容不能修改这样设计是迭代器本身不能修改
typedef __list_const_iterator<> const_iterator;
这么设计在简单场景下有效,复杂场景下存在局限性,
1.无法处理 const 元素:
如果容器中的元素本身是 const 类型,_list_const_iterator<> 无法正确处理,因为它假设元素是可以修改的。
在这里插入图片描述

2.无法保证真正的不可修改性:
如果容器中的元素是复杂对象(例如包含指针或引用的类),_list_const_iterator<> 无法确保这些对象的内部状态不被修改。
在这里插入图片描述

所以需要使用上述模板类来解决

双向链表类模板list

迭代器定义

在这里插入图片描述
用一个模板类来定义节点,内部封装了实现细节。iterator:普通迭代器,用于读写操作。const_iterator:常量迭代器,用于只读操作。多个模板参数满足不同情况下的参数需求

构造函数

在这里插入图片描述
_size初始化为 0,表示链表为空。

拷贝构造

在这里插入图片描述
创建一个新的哨兵节点。深拷贝源链表的每个元素。

赋值运算符重载

在这里插入图片描述
参数 it 是一个 list<> 类型的对象,调用拷贝构造函数生成一个临时拷贝。
交换资源:通过 swap 函数交换当前对象和临时拷贝的资源。可以看作是深拷贝
返回引用:返回当前对象的引用,以便支持链式赋值。

插入和删除操作

//pos位置之前插入
iterator insert(iterator pos, const T& x)
{Node* cur = pos._node;Node* newnode = new Node(x);Node* prev = cur->_prev;//改变链接cur->_prev = newnode;newnode->_next = cur;newnode->_prev = prev;prev->_next = newnode;_size++;return newnode;
}
iterator erase(iterator pos)
{assert(pos != end());Node* cur = pos._node;Node* next = cur->_next;Node* prev = cur->_prev;next->_prev = prev;prev->_next = next;delete cur;_size--;return next;
}

注意提前保存节点,这样不用担心链接顺序。插入函数中pos是一个模板类对象,创建指针cur来保存该对象中封装的节点,再通过箭头操作符来访问其中成员变量。

push和pop操作

void push_back(const T& x)
{Node* newnode = new Node(x);//提前记录尾节点可以不用在意链接顺序Node* tail = _head->_prev;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;//复用insert函数//insert(end(), x);
}void push_front(const T& x)
{insert(begin(), x);
}void pop_back()
{erase(--end());
}void pop_front()
{erase(begin());
}

学会复用插入和删除操作

迭代器范围

iterator begin()
{//return iterator(_head->next);//可直接返回的原因是单参数构造函数支持隐式类型转换return _head->_next;
}iterator end()
{//end指向尾结点下一个位置,即哨兵位头结点//return iterator(_head);return _head;
}const_iterator begin()const
{return _head->_next;
}const_iterator end()const
{return _head;
}

清空和析构

在这里插入图片描述
clear:删除链表中的所有元素。
析构函数:调用 clear 并释放哨兵节点

完整代码

#pragma once
#include<iostream>
#include<assert.h>
namespace ee
{template<class T>struct list_node{list_node<T>* _next;list_node<T>* _prev;T _val;list_node(const T& val = T()):_next(nullptr), _prev(nullptr), _val(val){}};//template<class T>//struct _list_iterator//{//	typedef list_node<T> Node;//	Node* _node;//	//构造函数//	_list_iterator(Node* node)//		:_node(node)//	{}//	T& operator*()//	{//		return _node->_val;//	}//	//前置++//	_list_iterator<T>& operator++()//	{//		_node = _node->_next;//		return *this;//	}//	//后置++//	_list_iterator<T>& operator++(int)//	{//		_list_iterator<T> tmp(*this);//		_node = _node->_next;//		return tmp;//	}//	bool operator!=(const _list_iterator<T>& it)//	{//		return _node != it._node;//	}//	bool operator==(const _list_iterator<T>& it)//	{//		return _node == it._node;//	}//};//更加通用灵活的模板类迭代器//typedef _list_iterator<T, T&, T*>iterator;//typedef _list_iterator<T,const T&,const T*> const_iterator;template<class T,class ref,class ptr>struct _list_iterator{typedef list_node<T> Node;typedef _list_iterator<T, ref, ptr> self;Node* _node;_list_iterator(Node* node):_node(node){ }//返回当前节点值ref operator*(){return _node->_val;}//返回当前节点值指针ptr operator->(){return &_node->_val;}//前置++self& operator++(){_node = _node->_next;return *this;}//后置++,移动到下一个节点,返回旧状态self operator++(int){self tmp(*this);_node = _node->_next;return tmp;}//前置--self& operator--(){_node = _node->_prev;return *this;}//后置--,移动到前一个节点,返回旧状态self operator--(int){self tmp(*this);_node = _node->_prev;return tmp;}//比较两个迭代器是否不相等bool operator!=(const self& it)const{return _node != it._node;}//比较两个迭代器是否相等bool operator==(const self& it)const{return _node == it._node;}};template<class T>class list{typedef list_node<T> Node;public:typedef _list_iterator<T,T&,T*> iterator;typedef _list_iterator<T, const T&, const T*> const_iterator;iterator begin(){//return iterator(_head->next);//可直接返回的原因是单参数构造函数支持隐式类型转换return _head->_next;}iterator end(){//end指向尾结点下一个位置,即哨兵位头结点//return iterator(_head);return _head;}const_iterator begin()const{return _head->_next;}const_iterator end()const{return _head;}//构造函数list(){_head = new Node;//将前后指针链接自己,可明确初始状态_head->_prev = _head;_head->_next = _head;_size = 0;}//拷贝构造list(const list<T>& lt){_head = new Node;_head->_prev = _head;_head->_next = _head;_size = 0;//深拷贝for (auto& e : lt){push_back(e);}}void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}//赋值运算符重载list<T>& operator=(list<T> it)//传参过程调用拷贝构造{swap(it);return *this;}void clear(){iterator it = begin();while (it != end()){it = erase(it);}_size = 0;}~list(){clear();delete[] _head;_head = nullptr;}void push_back(const T& x){Node* newnode = new Node(x);//提前记录尾节点可以不用在意链接顺序Node* tail = _head->_prev;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;//复用insert函数//insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}//pos位置之前插入iterator insert(iterator pos, const T& x){Node* cur = pos._node;Node* newnode = new Node(x);Node* prev = cur->_prev;//改变链接cur->_prev = newnode;newnode->_next = cur;newnode->_prev = prev;prev->_next = newnode;_size++;return newnode;}iterator erase(iterator pos){assert(pos != end());Node* cur = pos._node;Node* next = cur->_next;Node* prev = cur->_prev;next->_prev = prev;prev->_next = next;delete cur;_size--;return next;}size_t size(){return _size;}private:Node* _head;//哨兵位节点size_t _size;};}

相关文章:

详解list容器

1.list的介绍 list的底层结构是双向带头循环链表&#xff0c;允许随机的插入和删除&#xff0c;但其内存空间不是连续的。随机访问空间能力差&#xff0c;需要从头到尾遍历节点&#xff0c;不像vector一样高效支持 2.list的使用 构造函数 1.默认构造函数&#xff1a;创建一个…...

leetcode_977. 有序数组的平方_java

977. 有序数组的平方https://leetcode.cn/problems/squares-of-a-sorted-array/ 1.题目 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1…...

Spring Boot 3.4.3 基于 SpringDoc 2 和 Swagger 3 实现项目接口文档管理

在现代企业级应用开发中&#xff0c;前后端分离已成为主流模式&#xff0c;前端负责界面呈现&#xff0c;后端专注提供 RESTful API 接口。然而&#xff0c;接口文档的编写和维护往往是开发过程中的痛点。Spring Boot 3.4.3 结合 SpringDoc 2 和 Swagger 3&#xff0c;为开发者…...

前端面经分享(25/03/26)

北京一家做AI解决方案的公司&#xff0c;技术一面&#xff0c;15k-20k&#xff0c;要求3-5年 你们React项目里路由模式用的什么React里class组件和function组件都用过吗常用Hook&#xff0c;解释一下他们的作用useEffect第二个参数填空数组和不填有什么区别React组件通信的常用…...

Matlab基础知识与常见操作【无痛入门】

【1】Matlab基本概念 【2】Matlab程序设计 【3】Matlab图形绘制 以上三篇文章为Matlab主要的应用场景&#xff0c;我在学习的过程中做一下记录&#xff0c;方便以后回顾。 接下来介绍下Matlab的工作界面&#xff0c;以及如何高效率的应用Matlab的帮助手册。在我看来&#x…...

HTTP协议手写服务器

目录 一、请求的是Web根目录 二、GET方法通过URL传参 三、根据资源类型对应出Content-Type值 四、Http代码 项目完整源代码&#xff1a;Http 周不才/cpp_linux study - 码云 - 开源中国 一、请求的是Web根目录 如果URL中请求的资源是Web根目录&#xff0c;则自动跳转到主…...

网络探索之旅:网络原理(第二弹)

上篇文章&#xff0c;小编分享了应用层和传输层深入的一点的知识&#xff0c;那么接下来&#xff0c;这篇文章&#xff0c;继续分享网络层和数据链路层。 网络层 了解这个网络层&#xff0c;那么其实就是重点来了解下IP这个协议 对于这个协议呢&#xff0c;其实也是和前面的…...

深入剖析 JVM:从组成原理到调优实践

深入剖析 JVM&#xff1a;从组成原理到调优实践 深入剖析 JVM&#xff1a;从组成原理到调优实践一、JVM 组成架构&#xff1a;运行 Java 程序的 “幕后引擎”1.1 内存结构&#xff1a;数据存储的 “分区管理”1.2 执行引擎&#xff1a;字节码的 “翻译官”1.3 本地方法接口&…...

阿里云下一代可观测时序引擎-MetricStore 2.0

作者&#xff1a;徐昊&#xff08;博澍&#xff09; 背景 作为可观测场景使用频度最高的数据类型&#xff0c;Metrics 时序数据在可观测领域一直占有着重要地位&#xff0c;无论是从全局视角来观测系统整体状态&#xff0c;还是从大范围数据中定位某一个异常的位置&#xff0…...

从入门到精通【 MySQL】 数据库约束与设计

文章目录 &#x1f4d5;1. 数据库约束✏️1.1 NOT NULL 非空约束✏️1.2 DEFAULT 默认值约束✏️1.3 UNIQUE 唯一约束✏️1.4 PRIMARY KEY 主键约束✏️1.5 FOREIGN KEY 外键约束✏️1.6 CHECK 约束 &#x1f4d5;2. 数据库设计✏️2.1 第一范式✏️2.2 第二范式✏️2.3 第三范…...

使用LLaMAFactory微调Qwen大模型

一、环境配置与工具安装 1. 硬件要求 GPU:至少1块NVIDIA GPU(推荐RTX 4090/A100/H100,显存≥16GB)。内存:≥64GB系统内存。存储:≥100GB硬盘空间用于模型与数据集存储。2. 软件依赖 Python 3.8+:需安装CUDA支持的PyTorch版本(如torch==2.0.1+cu117)。 依赖库:通过以…...

Dubbo 通信流程 - 服务的调用

Dubbo 客户端的使用 在 Dubbo 应用中&#xff0c;往类成员注解 DubboReference&#xff0c;服务启动后便可以调用到远端&#xff1a; Component public class InvokeDemoFacade {AutowiredDubboReferenceprivate DemoFacade demoFacade;public String hello(String name){// …...

【数据结构】哈夫曼树

哈夫曼树 在学习哈夫曼树之前&#xff0c;先了解以下几个概念&#xff1a; 一&#xff1a;**路径长度&#xff1a;**在一棵树中&#xff0c;从一个节点到另一个节点所经过的“边”的数量&#xff0c;被我们称为两个节点之间的路径长度。 二&#xff1a;**树的路径长度&#xf…...

HCIP(TCP)(2)

1. TCP三次握手 SYN (同步序列编号) 报文: 客户端发送 SYN 报文&#xff0c;开始建立连接&#xff0c;并初始化序列号。 SYN-ACK (同步序列编号-确认) 报文: 服务器收到 SYN 报文后&#xff0c;回复 SYN-ACK 报文&#xff0c;确认连接请求&#xff0c;并初始化自己的序列号和确…...

VMware Ubuntu 网络配置全攻略:从断网到畅通无阻

一、网络连接模式选择&#xff08;先搞懂原理&#xff09; VMware提供三种网络模式&#xff0c;就像手机的不同网络套餐&#xff1a; 模式适用场景特点类比NAT个人上网/新手首选虚拟机共享主机IP&#xff0c;能上网但隐身家用WiFi桥接服务器/需要被局域网访问虚拟机会获得独立…...

基于Web的交互式智能成绩管理系统设计

目录 摘要 绪论 一、应用背景 二、行业发展现状 三、程序开发的重要意义 四、结语 1 代码 2 数据初始化模块 3 界面布局模块 4 核心功能模块 5 可视化子系统 6 扩展功能模块 7 架构设计亮点 功能总结 一、核心数据管理 二、智能分析体系 三、可视化系统 四、扩…...

第 12 章(番外)| Solidity 安全前沿趋势 × 审计生态 × 职业路径规划

&#x1f310; 第 12 章&#xff08;番外&#xff09;| Solidity 安全前沿趋势 审计生态 职业路径规划 ——做得了审计&#xff0c;也接得了项目&#xff0c;走进 Web3 安全工程师的职业实战地图 ✅ 本章导读 Solidity 安全&#xff0c;不只是代码安全、业务安全、审计安全…...

输出3行3列矩阵的鞍点

【问题描述】在矩阵中&#xff0c;一个数在所在行中是最大值&#xff0c;在所在列中是最小值&#xff0c;则被称为鞍点。任意输入一个3行3列矩阵&#xff0c;请设计程序输出其鞍点。 【输入形式】每行3个数&#xff0c;输入3列 【输出形式】输出所有鞍点&#xff1b;如果没有…...

k8s日志管理

k8s日志管理 k8s查看日志查看集群中不是完全运行状态的pod查看deployment日志查看service日志进入pod的容器内查看日志 管理k8s组件日志kubectl logs查看日志原理 管理k8s应用日志收集k8s日志思路收集标准输出收集容器中日志文件 k8s查看节点状态失败k8s部署prometheus监控 k8s…...

【数据结构】顺序表-元素去重

数据元素 结点定义&#xff0c;复杂数据类型&#xff0c;可用作整体性的管理系统。如果单独研究某些数据&#xff0c;比如只看学号或成绩&#xff0c;那么直接使用int之类的简单数据类型亦可。对应修改&#xff1a;typedef int Elemtype; typedef struct student{ //定义学生…...

物理安全——问答

目录 1、计算机的物理安全包含哪些内容 1. 设备保护 2. 访问控制 3. 电力与环境安全 4. 数据存储保护 5. 硬件防护 6. 监控与审计 7. 灾难恢复与应急响应 8. 拆卸与维修安全 2、物理安全有哪些需要关注的问题 1、计算机的物理安全包含哪些内容 1. 设备保护 防止盗窃&…...

element-plus中,Loading 加载组件的使用

一.基本使用 给一个组件&#xff0c;如&#xff1a;table表格&#xff0c;加上v-loading"true"即可。 举例&#xff1a;复制如下代码。 <template><el-table v-loading"loading" :data"tableData" style"width: 100%"><…...

Mybatis_Plus中的常用注解

目录 1、TableName TableId TableId的type属性 TableField 1、TableName 经过以上的测试&#xff0c;在使用MyBatis-Plus实现基本的CRUD时&#xff0c;我们并没有指定要操作的表&#xff0c;只是在 Mapper接口继承BaseMapper时&#xff0c;设置了泛型User&#xff0c;而操…...

云数据库概念

1.云数据库概念 云数据库是部署和虚拟化在云计算环境中的数据库。云数据库是在云计算的大背景下发展起来的一种新兴的共享基础架构的方法&#xff0c;它极大地增强了数据库的存储能力&#xff0c;消除了人员、硬件、软件的重复配置&#xff0c;让软、硬件升级变得更加容易。云…...

高并发金融系统,“可观测-可追溯-可回滚“的闭环审计体系

一句话总结 在高并发金融系统中&#xff0c;审计方案设计需平衡"观测粒度"与"系统损耗"&#xff0c;通过双AOP实现非侵入式采集&#xff0c;三表机制保障操作原子性&#xff0c;最终形成"可观测-可追溯-可回滚"的闭环体系。 业务痛点与需求 在…...

UDP视频传输中的丢包和播放花屏处理方法

在处理UDP视频传输中的丢包和花屏问题时,需要结合编码优化、网络传输策略和接收端纠错技术。以下是分步骤的解决方案: 1. 前向纠错(FEC,Forward Error Correction) 原理:在发送数据时附加冗余包,接收方通过冗余信息恢复丢失的数据包。 实现方法: 使用Reed-Solomon、XO…...

企业内训|DeepSeek技术革命、算力范式重构与场景落地洞察-某头部券商

3月19日北京&#xff0c;TsingtaoAI公司负责人汶生受邀为某证券公司管理层和投资者举办专题培训&#xff0c;围绕《DeepSeek技术革命、算力范式重构与场景落地洞察》主题&#xff0c;系统阐述了当前AI技术演进的核心趋势、算力需求的结构性变革&#xff0c;以及行业应用落地的关…...

K8S学习之基础五十二:k8s配置jenkins

k8s配置jenkins...

VS Code C/C++项目设置launch.json中的environment参数解决支持库路径问题

问题描述 Windows 11 VS Code C/C 开发环境搭建分别写了c和cpp两个示例代码&#xff0c;在运行过程中c代码没有发现问题&#xff08;可能简单&#xff0c;没有用到太多支持&#xff09;&#xff0c;但使用了stl的cpp代码并没有运行出来&#xff0c;如下图&#xff1a; 出问题…...

怎样解决 Windows 11 上的 DirectX 错误,最新DX 问题解决方法

在使用 Windows 11 操作系统的过程中&#xff0c;大家可能会遇到 DirectX 错误的情况&#xff0c;这可能会给游戏体验、多媒体应用甚至是系统的整体性能带来负面影响。不过别担心&#xff0c;本文将为大家详细介绍如何解决 Windows 11 上的 DirectX 错误&#xff0c;让您的系统…...