STL容器及其算法

C++ 标准库容器详解:特性、用法与场景选型

容器是 C++ 标准库(STL)的核心组件,用于存储和管理数据。不同容器因底层实现不同,在性能、功能和适用场景上差异显著。本文系统梳理vectorlistsetmap等常用容器,从核心特性、API 用法到场景选型进行全方位解析,帮助开发者精准选择合适的容器。

一、容器分类与核心差异概览

C++ 容器按功能可分为序列式容器(侧重元素顺序)和关联式容器(侧重元素查找),核心差异如下表:

容器类型所属类别底层实现核心特性核心操作复杂度(插入 / 删除 / 查找)
vector序列式动态数组内存连续,支持随机访问,尾部操作高效尾部增删 O (1);中间增删 O (n);查找 O (n)
list序列式双向链表内存不连续,不支持随机访问,任意位置增删高效已知位置增删 O (1);查找 O (n)
set关联式(无序)红黑树元素唯一,自动按 key 排序,支持范围查询增删查 O (log n)
unordered_set关联式(无序)哈希表元素唯一,无序,查找效率高(平均)增删查平均 O (1);最坏 O (n)
map关联式(有序)红黑树键值对存储,key 唯一且排序,支持按 key 索引增删查 O (log n)
unordered_map关联式(无序)哈希表键值对存储,key 唯一,无序,查找效率高(平均)增删查平均 O (1);最坏 O (n)

二、序列式容器详解

1. vector:动态数组(最常用序列容器)

核心特性
  • 底层实现:基于动态数组,内存连续(同数组),但支持自动扩容。
  • 关键优势
    • 支持随机访问(通过[]at()),时间复杂度 O (1);
    • 尾部插入 / 删除(push_back/pop_back)效率极高,O (1);
    • 内存局部性好,缓存命中率高(因内存连续)。
  • 局限性
    • 中间 / 头部插入 / 删除需移动大量元素,O (n);
    • 扩容时可能触发内存重分配(通常扩容为原容量 2 倍),导致性能波动。
常用 API 与示例
#include <vector>
#include <iostream>
using namespace std;int main() {// 1. 初始化(三种常用方式)vector<int> vec1; // 空容器vector<int> vec2(5, 10); // 5个元素,均为10vector<int> vec3 = {1, 2, 3, 4, 5}; // 初始化列表// 2. 插入元素vec1.push_back(6); // 尾部插入(O(1))vec1.insert(vec1.begin() + 1, 8); // 在索引1处插入(O(n),需移动元素)// 3. 访问元素(两种方式)cout << vec3[2] << endl; // 下标访问(无越界检查,快)cout << vec3.at(3) << endl; // at()访问(有越界检查,安全)cout << "首元素:" << vec3.front() << ",尾元素:" << vec3.back() << endl;// 4. 遍历(迭代器/范围for)for (auto it = vec3.begin(); it != vec3.end(); ++it) {cout << *it << " ";}// 范围for更简洁(C++11+)for (int num : vec3) { cout << num << " "; }// 5. 修改与删除vec3[0] = 100; // 直接修改vec1.pop_back(); // 删除尾部元素(O(1))vec3.erase(vec3.begin() + 2); // 删除索引2处元素(O(n))// 6. 容量管理(关键!)cout << "当前大小:" << vec2.size() // 元素个数<< ",容量:" << vec2.capacity() << endl; // 已分配内存可容纳的元素数vec2.reserve(10); // 预分配容量(避免频繁扩容)vec2.resize(3); // 调整大小(多余元素被截断,新增元素为默认值)vec1.clear(); // 清空元素(size=0,但capacity不变)return 0;
}
典型场景
  • 需频繁随机访问元素(如存储数组、矩阵、日志数据);
  • 元素主要在尾部增删(如批量数据收集、缓冲区);
  • 需与 C 语言数组兼容(因内存连续,可通过data()获取原始指针)。

2. list:双向链表(高效增删的序列容器)

核心特性
  • 底层实现双向链表,每个节点包含数据域和前后指针,内存不连续。
  • 关键优势
    • 任意位置(已知迭代器)插入 / 删除效率极高,O (1)(无需移动元素,仅修改指针);
    • 无扩容开销(节点动态分配),内存使用更灵活。
  • 局限性
    • 不支持随机访问(访问第 n 个元素需从头遍历),时间复杂度 O (n);
    • 内存开销大(每个节点额外存储两个指针);
    • 缓存命中率低(内存不连续)。
常用 API 与示例
#include <list>
#include <iostream>int main() {// 1. 初始化list<int> list1;list<int> list2(4, 20); // 4个元素,均为20list<int> list3 = {10, 20, 30, 40};// 2. 插入元素(头部/尾部/中间)list1.push_back(5); // 尾部插入(O(1))list1.push_front(3); // 头部插入(O(1))auto it = list3.begin(); ++it; // 指向第二个元素(20)list3.insert(it, 25); // 在20和30之间插入25(O(1),已知位置)// 3. 访问元素(仅支持首尾直接访问)cout << "首元素:" << list3.front() << ",尾元素:" << list3.back() << endl;// 访问中间元素需遍历it = list3.begin();advance(it, 2); // 移动迭代器到第3个元素(25)cout << "第3个元素:" << *it << endl;// 4. 遍历(仅迭代器/范围for)for (int num : list3) { cout << num << " "; }// 5. 特殊操作(链表特有)list3.reverse(); // 反转链表(O(n),仅修改指针)list3.sort(); // 排序(O(n log n),链表自带排序,无需转换为vector)// 6. 删除元素list1.pop_back(); // 尾部删除(O(1))list3.pop_front(); // 头部删除(O(1))it = list3.begin(); ++it;list3.erase(it); // 删除指定位置元素(O(1),已知位置)return 0;
}
典型场景
  • 频繁在中间位置增删元素(如实现链表、队列、栈的变种);
  • 数据量不确定,且需避免扩容开销(如实时数据采集,元素动态增减);
  • 需要高效拆分 / 合并链表(splice()方法,O (1) 实现链表拼接)。

三、关联式容器详解

1. setunordered_set:集合(元素去重与查找)

核心特性对比
特性set(有序集合)unordered_set(无序集合)
底层实现红黑树(平衡二叉搜索树)哈希表(链地址法解决冲突)
有序性元素自动按升序排列(可自定义)无序(按哈希值存储)
唯一性元素不可重复(重复插入被忽略)同左
查找效率O (log n)(稳定)平均 O (1),最坏 O (n)(依赖哈希函数)
迭代器稳定性插入 / 删除不失效(除被删元素)插入可能触发重哈希,迭代器失效
内存开销较低(红黑树结构紧凑)较高(哈希表需预留空间)
常用 API 与示例(以set为例)
#include <set>
#include <iostream>
#include <functional> // 用于自定义排序
using namespace std;
int main() {// 1. 初始化(默认升序)set<int> set1;// 自定义排序(降序)set<int,greater<int>> set2;// 2. 插入元素(自动去重)set1.insert(3);set1.insert(1);set1.insert(2);set1.insert(2); // 重复元素,插入无效set2.insert({5, 3, 7}); // 初始化列表插入// 3. 查找元素(核心操作)auto it1 = set1.find(2); // 查找值为2的元素if (it1 != set1.end()) {cout << "找到元素:" << *it1 << endl;}// 判断元素是否存在(count()返回0或1)if (set1.count(3)) { cout << "元素3存在" << endl; }// 4. 遍历(有序性体现)cout << "set1(升序):";for (int num : set1) { cout << num << " "; } // 输出:1 2 3cout << "\nset2(降序):";for (int num : set2) { cout << num << " "; } // 输出:7 5 3// 5. 删除元素set1.erase(1); // 按值删除(O(log n))set2.erase(set2.begin()); // 按迭代器删除(O(1))return 0;
}
典型场景
  • set:需去重且保持有序(如排行榜、区间统计,支持lower_bound/upper_bound范围查询);
  • unordered_set:仅需去重,追求极致查找效率(如缓存校验、数据去重验证)。

2. mapunordered_map:键值对(关联查询)

核心特性对比
特性map(有序键值对)unordered_map(无序键值对)
底层实现红黑树哈希表
有序性按 key 升序排列(可自定义)无序
键唯一性key 不可重复(重复插入无效)同左
访问方式通过 key 访问 value同左
查找效率O(log n)平均 O (1),最坏 O (n)
典型用途有序关联查询(如字典、配置表)高效键值映射(如缓存、索引)
常用 API 与示例(以unordered_map为例)

cpp

运行

#include <unordered_map>
#include <iostream>int main() {// 1. 初始化(键为int,值为string)unordered_map<int, string> umap;// 2. 插入键值对(三种方式)umap.insert({1, "one"}); // 插入pair(重复key无效)umap[2] = "two"; // []运算符(重复key会覆盖)umap.emplace(3, "three"); // 直接构造(效率更高)// 3. 访问value(两种方式)cout << umap[2] <<endl; // []访问(无key则插入默认值)try {cout << umap.at(3) << endl; // at()访问(无key抛异常,更安全)} catch (const out_of_range& e) {cout << "key不存在" << endl;}// 4. 查找key(核心操作)auto it = umap.find(1); // 查找key=1if (it != umap.end()) {cout << "key:" << it->first << ",value:" << it->second << endl;}// 5. 遍历for (const auto& pair : umap) {cout << pair.first << " → " << pair.second << " ";}// 6. 删除元素umap.erase(2); // 按key删除it = umap.find(3);if (it != umap.end()) {umap.erase(it); // 按迭代器删除}return 0;
}
典型场景
  • map:需按 key 排序的键值对(如按 ID 排序的用户信息、区间查询配置);
  • unordered_map:高频键值查询(如数据库索引、缓存映射,优先考虑查找速度)。

四、容器选型决策指南

选择容器时需结合操作类型(增删查为主?随机访问?)、数据特性(是否有序?是否重复?)和性能需求(时间 / 内存优先),决策流程如下:

  1. 是否需要键值对关联?

    • 是 → 选map(有序)或unordered_map(无序);
    • 否 → 进入下一步。
  2. 是否需要去重?

    • 是 → 选set(有序)或unordered_set(无序);
    • 否 → 进入下一步(序列容器)。
  3. 序列容器核心需求?

    • 频繁随机访问 → vector
    • 频繁中间增删 → list
    • 头尾增删频繁且需随机访问 → deque(双端队列,未详细展开)。

五、容器算法

C++ 标准库的 <algorithm> 头文件提供了大量实用算法,涵盖排序、查找、修改、数值计算等场景。以下是常用算法的分类总结及例程:

5.1 排序与顺序相关算法

1. sort - 快速排序(不稳定)

对范围元素排序,平均复杂度 O (n log n)

#include <algorithm>
#include <vector>
#include <iostream>int main() {std::vector<int> v = {3, 1, 4, 1, 5};std::sort(v.begin(), v.end()); // 升序// 输出:1 1 3 4 5// 自定义降序std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });// 输出:5 4 3 1 1return 0;
}
2. stable_sort - 稳定排序

保持相等元素的原始相对顺序

std::vector<std::pair<int, int>> v = {{2,1}, {1,2}, {2,3}};
std::stable_sort(v.begin(), v.end()); 
// 结果:{1,2}, {2,1}, {2,3}(两个2的相对顺序不变)
3. partial_sort - 部分排序

只保证前 k 个元素有序(最小的 k 个)

std::vector<int> v = {5, 3, 1, 4, 2};
std::partial_sort(v.begin(), v.begin()+3, v.end());
// 结果:1 2 3 5 4(前3个为最小且有序)
4. nth_element - 定位第 n 大元素

使第 n 个元素处于排序后的正确位置

std::vector<int> v = {5, 3, 1, 4, 2};
std::nth_element(v.begin(), v.begin()+2, v.end());
// 结果:2 1 3 5 4(3是第3小元素,左侧≤3,右侧≥3)

5.2  查找算法

1. find - 查找元素

返回首个匹配元素的迭代器

std::vector<int> v = {1, 2, 3, 4, 5};
auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {std::cout << "找到元素:" << *it; // 输出:3
}
2. find_if - 条件查找

通过谓词查找元素

// 查找第一个偶数
auto it = std::find_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
3. binary_search - 二分查找

已排序范围中查找(返回 bool)

std::vector<int> v = {1, 3, 5, 7};
bool exists = std::binary_search(v.begin(), v.end(), 5); // true
4. lower_bound / upper_bound
  • lower_bound:返回首个 ≥ 目标值的迭代器
  • upper_bound:返回首个 > 目标值的迭代器
std::vector<int> v = {1, 3, 3, 5};
auto lb = std::lower_bound(v.begin(), v.end(), 3); // 指向第一个3
auto ub = std::upper_bound(v.begin(), v.end(), 3); // 指向5
int count = ub - lb; // 3的个数:2

5.3 容器修改算法

1. copy - 复制元素
std::vector<int> src = {1, 2, 3};
std::vector<int> dest(3);
std::copy(src.begin(), src.end(), dest.begin()); // dest = {1,2,3}
2. swap - 交换元素
int a = 1, b = 2;
std::swap(a, b); // a=2, b=1std::vector<int> v1 = {1,2}, v2 = {3,4};
std::swap(v1, v2); // 交换整个容器
3. reverse - 反转范围
std::vector<int> v = {1, 2, 3};
std::reverse(v.begin(), v.end()); // {3,2,1}
4. remove - 移除元素(逻辑删除)
std::vector<int> v = {1, 2, 3, 2, 4};
// 逻辑删除所有2(返回新结尾迭代器)
auto last = std::remove(v.begin(), v.end(), 2);
v.erase(last, v.end()); // 物理删除,结果:{1,3,4}
5. unique - 移除连续重复元素
std::vector<int> v = {1, 2, 2, 3, 3, 3};
std::sort(v.begin(), v.end()); // 先排序
auto last = std::unique(v.begin(), v.end());
v.erase(last, v.end()); // 结果:{1,2,3}

5.4 数值与集合算法

1. accumulate - 累加(需 <numeric> 头文件)
#include <numeric>
std::vector<int> v = {1, 2, 3, 4};
int sum = std::accumulate(v.begin(), v.end(), 0); // 0+1+2+3+4=10// 计算乘积
int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());
2. count / count_if - 计数
std::vector<int> v = {1, 2, 2, 3};
int cnt = std::count(v.begin(), v.end(), 2); // 2的个数:2// 计数偶数
int even_cnt = std::count_if(v.begin(), v.end(), [](int x) { return x%2==0; });
3. min_element / max_element - 查找最值
std::vector<int> v = {3, 1, 4};
auto min_it = std::min_element(v.begin(), v.end()); // 指向1
auto max_it = std::max_element(v.begin(), v.end()); // 指向4
4. set_intersection - 求交集(需已排序)
std::vector<int> a = {1, 2, 3, 4};
std::vector<int> b = {3, 4, 5, 6};
std::vector<int> res;
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(res));
// res = {3,4}

5.5  编程练习

#include <algorithm>
#include <vector>
#include <iostream>
#include <numeric>  // 用于accumulateusing namespace std;int main() {// 一、排序与顺序相关算法{// 1. sort - 快速排序(不稳定)vector<int> v1 = {3, 1, 4, 1, 5};sort(v1.begin(), v1.end());  // 升序cout << "sort升序: ";for (int num : v1) cout << num << " ";  // 1 1 3 4 5cout << endl;// 自定义降序sort(v1.begin(), v1.end(), [](int a, int b) { return a > b; });cout << "sort降序: ";for (int num : v1) cout << num << " ";  // 5 4 3 1 1cout << endl;// 2. stable_sort - 稳定排序(保留相等元素相对顺序)vector<pair<int, int>> v2 = {{2,1}, {1,2}, {2,3}};stable_sort(v2.begin(), v2.end());cout << "stable_sort结果: ";for (auto p : v2) cout << "{" << p.first << "," << p.second << "} ";  // {1,2} {2,1} {2,3}cout << endl;// 3. partial_sort - 部分排序(前k个元素有序)vector<int> v3 = {5, 3, 1, 4, 2};partial_sort(v3.begin(), v3.begin()+3, v3.end());cout << "partial_sort前3个: ";for (int num : v3) cout << num << " ";  // 1 2 3 5 4cout << endl;// 4. nth_element - 定位第n个元素vector<int> v4 = {5, 3, 1, 4, 2};nth_element(v4.begin(), v4.begin()+2, v4.end());  // 第3小元素cout << "nth_element结果: ";for (int num : v4) cout << num << " ";  // 2 1 3 5 4(3在正确位置)cout << endl;}// 二、查找算法{vector<int> v = {1, 2, 3, 4, 5};// 1. find - 查找元素auto it1 = find(v.begin(), v.end(), 3);if (it1 != v.end()) cout << "find找到: " << *it1 << endl;  // 3// 2. find_if - 条件查找auto it2 = find_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });if (it2 != v.end()) cout << "find_if找到首个偶数: " << *it2 << endl;  // 2// 3. binary_search - 二分查找(需已排序)bool exists = binary_search(v.begin(), v.end(), 5);cout << "binary_search查找5: " << (exists ? "存在" : "不存在") << endl;  // 存在// 4. lower_bound/upper_boundvector<int> v_sorted = {1, 3, 3, 5};auto lb = lower_bound(v_sorted.begin(), v_sorted.end(), 3);  // 首个>=3auto ub = upper_bound(v_sorted.begin(), v_sorted.end(), 3);  // 首个>3cout << "3的个数: " << (ub - lb) << endl;  // 2}// 三、容器修改算法{// 1. copy - 复制元素vector<int> src = {1, 2, 3};vector<int> dest(3);copy(src.begin(), src.end(), dest.begin());cout << "copy结果: ";for (int num : dest) cout << num << " ";  // 1 2 3cout << endl;// 2. swap - 交换int a = 1, b = 2;swap(a, b);cout << "swap后: a=" << a << ", b=" << b << endl;  // a=2, b=1// 3. reverse - 反转vector<int> v_rev = {1, 2, 3};reverse(v_rev.begin(), v_rev.end());cout << "reverse结果: ";for (int num : v_rev) cout << num << " ";  // 3 2 1cout << endl;// 4. remove - 移除元素(需配合erase)vector<int> v_rem = {1, 2, 3, 2, 4};auto last = remove(v_rem.begin(), v_rem.end(), 2);  // 逻辑删除v_rem.erase(last, v_rem.end());  // 物理删除cout << "remove后: ";for (int num : v_rem) cout << num << " ";  // 1 3 4cout << endl;// 5. unique - 去重(需先排序)vector<int> v_uni = {1, 2, 2, 3, 3, 3};sort(v_uni.begin(), v_uni.end());auto last_uni = unique(v_uni.begin(), v_uni.end());v_uni.erase(last_uni, v_uni.end());cout << "unique后: ";for (int num : v_uni) cout << num << " ";  // 1 2 3cout << endl;}// 四、数值与集合算法{vector<int> v = {1, 2, 3, 4};// 1. accumulate - 累加/累乘int sum = accumulate(v.begin(), v.end(), 0);  // 初始值0cout << "累加和: " << sum << endl;  // 10int product = accumulate(v.begin(), v.end(), 1, multiplies<int>());cout << "累乘积: " << product << endl;  // 24// 2. count/count_if - 计数vector<int> v_cnt = {1, 2, 2, 3};int cnt = count(v_cnt.begin(), v_cnt.end(), 2);cout << "数字2的个数: " << cnt << endl;  // 2int even_cnt = count_if(v_cnt.begin(), v_cnt.end(), [](int x) { return x%2 == 0; });cout << "偶数个数: " << even_cnt << endl;  // 2// 3. min_element/max_element - 最值vector<int> v_minmax = {3, 1, 4};auto min_it = min_element(v_minmax.begin(), v_minmax.end());auto max_it = max_element(v_minmax.begin(), v_minmax.end());cout << "最小值: " << *min_it << ", 最大值: " << *max_it << endl;  // 1,4// 4. set_intersection - 交集(需已排序)vector<int> a = {1, 2, 3, 4};vector<int> b = {3, 4, 5, 6};vector<int> res;set_intersection(a.begin(), a.end(), b.begin(), b.end(), back_inserter(res));cout << "交集: ";for (int num : res) cout << num << " ";  // 3 4cout << endl;}return 0;
}

六 、算法使用要点

  1. 算法通常接受迭代器范围 [first, last)(左闭右开)
  2. 排序相关算法要求容器支持随机访问迭代器(如 vectorarray
  3. 二分查找类算法要求范围已排序
  4. 自定义谓词需满足 "严格弱序" 规则,避免逻辑错误

这些算法大幅简化了常见操作,合理使用可提高代码效率和可读性。

总结

C++ 容器的设计各有侧重:vector以连续内存和随机访问为核心,list以高效增删为优势,set/map提供有序性和稳定查找,unordered_*系列则追求极致查询效率。理解底层实现是掌握容器的关键 —— 红黑树带来有序性和稳定性能,哈希表带来平均 O (1) 的效率,动态数组平衡了访问与增删成本。实际开发中,需根据具体场景的操作频率和性能需求,选择最适合的容器,才能写出高效、易维护的代码。

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

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

相关文章

MySQL ZIP安装教程:从解压到启动

金金金上线&#xff01; 话不多&#xff0c;只讲你能听懂的前端知识 前言 我这里不能下载安装程序的mysql&#xff0c;由于电脑安全限制&#xff0c;安装时会弹出需要管理员账号密码权限&#xff0c;此路行不通&#xff0c;所以琢磨着免安装版本怎么个流程&#xff0c;好&#…

p2p打洞

p2p网络穿透库,它的C++版本目前只支持linux,不支持win,它最新版本的穿透用的tcp,老版本支持tcp/udp: https://libp2p.io/ P2P-udp的穿透教程: https://edu.51cto.com/lesson/731596.html 目前打洞机制最好的库是webrtc,其次是libnice,它是轻量级的专门打洞的库。 libni…

『“无恙心宽”,梗痛不常』——爱上古中医(12)(健康生活是coder抒写优质代码的前提条件——《黄帝内经》伴读学习纪要)

养心护心气血通&#xff0c;无痛无梗全身松。 笔记模板由python脚本于2025-08-10 15:54:46创建&#xff0c;本篇笔记适合至少通晓一门语言&#xff0c;熟悉基本编程范式的coder翻阅。 学习的细节是欢悦的历程 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅仅…

Spark 运行流程核心组件(一)作业提交

1、Job启动流程1、Client触发 SparkContext 初始化 2、SparkContext 向 Master 注册应用 3、Master 调度 Worker 启动 Executor 4、Worker 进程启动 Executor 5、DAGScheduler 将作业分解为 Stage&#xff1a; 6、TaskScheduler 分配 Task 到 Executor 2、核心组件组件职责Spar…

MySQL 临时表与复制表

一、MySQL 临时表临时表是会话级别的临时数据载体&#xff0c;其设计初衷是为了满足短期数据处理需求&#xff0c;以下从技术细节展开说明。&#xff08;一&#xff09;核心特性拓展1.生命周期与会话绑定会话结束的判定&#xff1a;包括正常断开连接&#xff08;exit/quit&…

从配置到调试:WinCC与S7-1200/200SMT无线Modbus TCP通讯方案

测试设备与参数l 西门子PLC型号&#xff1a;S7-1200 1台l 西门子PLC型号&#xff1a;S7-200Smart 1台l 上位机&#xff1a;WinCC7.4 1台l 无线通讯终端——DTD418MB 3块l 主从关系&#xff1a;1主2从l 通讯接口&#xff1a;RJ45接口l 供电&#xff1a;12-24VDCl 通讯协议&a…

Android沉浸式全屏显示与隐藏导航栏的实现

1. 总体流程以下是实现沉浸式全屏显示和隐藏导航栏的流程&#xff1a;步骤描述步骤1创建一个新的Android项目步骤2在布局文件中定义需要展示的界面步骤3在Activity中设置沉浸式全屏显示步骤4处理系统UI的显示与隐藏步骤5运行应用并测试效果2. 详细步骤步骤1&#xff1a;创建一个…

EN 62368消费电子、信息技术设备和办公设备安全要求标准

EN 62368认证标准是一项全球性的电子产品安全标准&#xff0c;用于评估和认证消费电子、信息技术设备和办公设备的安全性。该标准由国际电工委员会(IEC)制定&#xff0c;取代了传统的EN60065和EN 60950两个标准&#xff0c;成为国际电子产品安全领域的新指导。IEC /EN 62368-1是…

【unity实战】使用Splines+DOTween制作弯曲手牌和抽牌动画效果

最终效果 文章目录最终效果前言实战1、Splines的使用2、绘制样条线3、DOTween安装和使用4、基于样条曲线&#xff08;Spline&#xff09;的手牌管理系统4.1 代码实现4.2 解释&#xff1a;&#xff08;1&#xff09;计算第一张卡牌的位置&#xff08;居中排列&#xff09;&#…

Flask模板注入梳理

从模板开始介绍&#xff1a;Flask中有许多不同功能的模板&#xff0c;他们之间是相互隔离的地带&#xff0c;可供引入和使用。Flask中的模块&#xff1a;flask 主模块&#xff1a;包含框架的核心类和函数&#xff0c;如 Flask&#xff08;应用实例&#xff09;、request&#x…

企业级的即时通讯平台怎么保护敏感行业通讯安全?

聊天记录存在第三方服务器、敏感文件被误发至外部群组、离职员工仍能查看历史消息.对于金融、医疗、政务等对数据安全高度敏感的行业而言&#xff0c;“沟通效率与”信息安全”的矛盾&#xff0c;从未像今天这样尖锐。企业即时通讯怎么保护敏感行业通讯安全&#xff1f;这个问题…

Java Spring框架最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡

Java Spring框架最新版本及发展史详解&#xff08;截至2025年8月&#xff09;-优雅草卓伊凡引言今天有个新项目 客户问我为什么不用spring 4版本&#xff0c;卓伊凡我今天刚做完项目方案&#xff0c;我被客户这一句问了有点愣住&#xff0c;Java Spring框架最新版本及发展史详解…

Android实现Glide/Coil样式图/视频加载框架,Kotlin

Android实现Glide/Coil样式图/视频加载框架&#xff0c;Kotlin <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permiss…

【k8s】pvc 配置的两种方式volumeClaimTemplates 和 PersistentVolumeClaim

pvc配置实例 实例1在Deployment中配置 template:xxxxxxvolumeClaimTemplates:- metadata:name: dataspec:accessModes:- ReadWriteOnceresources:requests:storage: 1GistorageClassName: nfsdev-storageclass (创建好的storageClassName)实例2#先创建一个pvc 然后在 Deploym…

Logistic Loss Function|逻辑回归代价函数

----------------------------------------------------------------------------------------------- 这是我在我的网站中截取的文章&#xff0c;有更多的文章欢迎来访问我自己的博客网站rn.berlinlian.cn&#xff0c;这里还有很多有关计算机的知识&#xff0c;欢迎进行留言或…

计算机网络技术-知识篇(Day.1)

一、网络概述 1、网络的概念 两个不在同一地理位置的主机&#xff0c;通过传输介质和通信协议&#xff0c;实现通信和资源共享。 2、网络发展史 第一阶段&#xff08;20世纪60年代&#xff09; 标志性事件&#xff1a;ARPANET的诞生关键技术&#xff1a;分组交换技术 第二…

工业元宇宙:迈向星辰大海的“玄奘之路”

一、从认知革命到工业革命&#xff1a;文明跃迁的底层逻辑1.1 认知革命&#xff1a;人类协作的基石时间线&#xff1a;约7万年前&#xff0c;智人通过语言和想象力构建共同虚拟现实&#xff0c;形成部落协作模式。核心突破&#xff1a;虚构能力&#xff1a;创造神、国家、法律等…

9. React组件生命周期

2. React组件生命周期 2.1. 认识生命周期 2.1.1. 很多事物都有从创建到销毁的整个过程&#xff0c;这个过程称之为生命周期&#xff1b;2.1.2. React组件也有自己的生命周期&#xff0c;了解生命周期可以让我们在最合适的地方完成想要的功能2.1.3. 生命周期和生命周期函数的关系…

【单板硬件开发】关于复位电路的理解

阅读紫光同创供应商提供的FPGA单板硬件开发手册&#xff0c;发现复位电路他们家解释的很通俗易懂&#xff0c;所以分享一下。如下图&#xff0c;RST_N 是低有效的异步全芯片复位信号&#xff0c;一般外部连接电路有 3 种形式如图 3–2&#xff0c;可根据实际需要选择合适的电路…

《Unity Shader入门精要》学习笔记一

1、本书的源代码 https://github.com/candycat1992/Unity_Shaders_Book 2、第1章 Shader是面向GPU的工作方式 3、第2章 渲染流水线 Shader&#xff1a;着色器 渲染流水线&#xff1a;目标是渲染一张二维纹理&#xff0c;输入是一个虚拟摄像机、一些光源、一些Shader以及纹…