C++ STL:深入探索常见容器

你好呀,欢迎来到 Dong雨 的技术小栈 🌱

在这里,我们一同探索代码的奥秘,感受技术的魅力 ✨。

👉 我的小世界:Dong雨

📌 分享我的学习旅程
🛠️ 提供贴心的实用工具
💡 记录每一个灵感火花

描述

🌟✨ Hello,探索技术的你,这里是本篇的地图指南! ✨🌟

C++ STL:深入探索常见容器

引言:高效编程的核心

C++ 标准模板库(STL)是构建高效程序的强大工具,它提供了多种容器,帮助开发者应对复杂的数据存储和操作需求。STL 容器支持广泛的操作,包括动态内存管理、灵活的元素存储、以及高效的访问与查找能力。本文将深入探讨 STL 中常见的容器,并分析它们的特性、优势和适用场景。


1. vector:动态扩展的数组

概述:

vector 是 STL 中最常用的容器之一,它实现了一个动态数组。vector 具有自动扩容的特性,能够根据实际需求调整内存大小。这使得它特别适合处理需要频繁插入和删除元素的场景,尤其是当元素数量不确定时。

使用场景:

vector 适用于需要频繁访问元素、存储大量数据、并且数据规模动态变化的应用场景,如:

  • 存储大量数字数据或对象。
  • 图像处理中的像素数据。
  • 快速随机访问的应用。

头文件:

#include <vector>
using namespace std;

初始化:

vector<int> vec = {1, 2, 3, 4};  // 使用列表初始化

常用方法:

  • push_back(value):将元素添加到 vector 的末尾。
  • pop_back():移除 vector 末尾的元素。
  • at(index):获取指定位置的元素,提供越界检查。
  • size():返回 vector 中元素的数量。
  • reserve(n):预先为 vector 分配内存,以避免在频繁添加元素时导致多次扩容。

深入分析:

vector 提供了 O(1) 时间复杂度的随机访问,且支持 动态扩容。当 vector 的容量不足以容纳新元素时,它会自动扩容,通常扩展为原来的两倍,这样就能确保每次扩容时的操作成本较低(均摊复杂度为 O(1))。然而,vector 的扩容也有其开销,尤其是当容器中的元素非常大时,内存重新分配和元素拷贝可能会影响性能。

示例代码:

#include <iostream>
#include <vector>
using namespace std;int main() {vector<int> numbers = {1, 2, 3, 4};  // 初始化 vectornumbers.push_back(5);  // 添加元素// 输出 vector 中的所有元素cout << "Vector contents: ";for (const auto& num : numbers) {cout << num << " ";}cout << endl;cout << "Vector size: " << numbers.size() << endl;  // 获取大小return 0;
}

输出:

Vector contents: 1 2 3 4 5
Vector size: 5

2. stack:后进先出(LIFO)容器

概述:

stack 是遵循后进先出(LIFO)原则的容器。stack 只允许从顶端进行插入和删除操作,因此特别适合处理递归问题和需要回溯的任务。

使用场景:

stack 常用于以下场景:

  • 深度优先搜索(DFS)算法。
  • 撤销操作。
  • 表达式求值(如括号匹配问题)。

头文件:

#include <stack>
using namespace std;

初始化:

stack<int> s;

常用方法:

  • push(value):将元素压入栈顶。
  • pop():移除栈顶元素。
  • top():访问栈顶元素。
  • empty():检查栈是否为空。
  • size():返回栈中元素的数量。

深入分析:

stack 底层通常使用 dequevector 来实现,因此它的时间复杂度是 O(1),无论是入栈还是出栈。stack 只提供对栈顶元素的访问,不支持中间元素的访问。适合用来处理先进后出的操作,但若需要频繁查找其他元素时,应考虑其他数据结构。

示例代码:

#include <iostream>
#include <stack>
using namespace std;int main() {stack<int> s;// 压入元素s.push(1);s.push(2);s.push(3);// 输出栈顶元素cout << "Stack top: " << s.top() << endl;// 弹出栈顶元素s.pop();cout << "New stack top: " << s.top() << endl;return 0;
}

输出:

Stack top: 3
New stack top: 2

3. queue:先进先出(FIFO)队列

概述:

queue 是遵循先进先出(FIFO)规则的容器,常用于需要按顺序处理任务的场景。

使用场景:

queue 常用于:

  • 事件驱动程序。
  • 任务调度(如操作系统中的进程调度)。
  • 异步消息传递。

头文件:

#include <queue>
using namespace std;

初始化:

queue<int> q;

常用方法:

  • push(value):将元素加入队列。
  • pop():移除队列头部元素。
  • front():访问队列头部元素。
  • back():访问队列尾部元素。
  • empty():检查队列是否为空。
  • size():返回队列中元素的数量。

深入分析:

queue 是基于 双端队列deque)实现的,它的操作复杂度为 O(1)。队列的操作仅限于队首和队尾,因此它在需要保持顺序处理任务的场景中非常高效。但在需要从队列中间插入或删除元素时,队列并不是一个好的选择。

示例代码:

#include <iostream>
#include <queue>
using namespace std;int main() {queue<int> q;// 入队q.push(10);q.push(20);q.push(30);// 输出队列头部元素cout << "Queue front: " << q.front() << endl;// 出队q.pop();cout << "New queue front: " << q.front() << endl;return 0;
}

输出:

Queue front: 10
New queue front: 20

4. deque:双端队列

概述:

deque 是一个可以从两端插入和删除元素的容器。与 vector 相比,deque 更适合需要从两端频繁操作元素的场景。

使用场景:

deque 常用于:

  • 滑动窗口问题。
  • 双向任务队列。
  • 游戏中的消息队列。

头文件:

#include <deque>
using namespace std;

初始化:

deque<int> dq = {1, 2, 3, 4};

常用方法:

  • push_front(value):将元素添加到队列前端。
  • push_back(value):将元素添加到队列末端。
  • pop_front():移除队列前端的元素。
  • pop_back():移除队列末端的元素。
  • front():访问队列前端元素。
  • back():访问队列末端元素。
  • size():返回队列中元素的数量。

深入分析:

deque 允许在队列两端进行插入和删除操作,因此它比 vector 更适合双向操作。其底层通常是由多个块构成的结构,这使得它的空间效率较高,但相较于 vector,它的访问元素速度稍慢,尤其是对尾端元素的访问。因此,deque 在某些双端任务中表现优越,但若只在一端操作,vector 可能更高效。

示例代码:

#include  #include  using namespace std;int main() { deque dq = {1, 2, 3, 4};
// 添加元素到队头
dq.push_front(0);
// 添加元素到队尾
dq.push_back(5);// 输出队列元素
cout << "Deque contents: ";
for (const auto& val : dq) {cout << val << " ";
}
cout << endl;return 0;
}

输出:

Deque contents: 0 1 2 3 4 5

5. priority_queue:优先级队列

概述:

priority_queue 是一个根据优先级排序的队列,默认情况下使用最大堆实现。它允许快速访问最大或最小元素,但不像常规队列一样按顺序处理元素。priority_queue 保证每次出队的元素都是当前队列中的最大(或最小)元素。

使用场景:

priority_queue 常用于:

  • 排序问题。
  • 实现 Dijkstra 算法、A* 算法等图搜索算法。
  • 实现事件驱动系统中的优先级任务调度。

头文件:

#include <queue>
using namespace std;

初始化:

priority_queue<int> pq;

常用方法:

  • push(value):将元素加入优先级队列。
  • pop():移除队列中的最大元素。
  • top():访问优先级队列中的最大元素。
  • empty():检查队列是否为空。
  • size():返回队列中元素的数量。

深入分析:

priority_queue 的底层通常使用最大堆或最小堆(通过自定义比较器来改变堆的顺序)。由于堆的性质,pushpop 操作的时间复杂度为 O(log n)。虽然它非常适合用于按优先级处理元素,但它不支持访问中间元素或随机访问,因此如果需要按特定条件查找元素,priority_queue 可能不是最佳选择。

示例代码:

#include <iostream>
#include <queue>
using namespace std;int main() {priority_queue<int> pq;// 向优先级队列中添加元素pq.push(10);pq.push(20);pq.push(15);// 输出优先级队列中的最大元素cout << "Top element: " << pq.top() << endl;// 移除最大元素pq.pop();cout << "New top element: " << pq.top() << endl;return 0;
}

输出:

Top element: 20
New top element: 15

6. map:键值对存储(红黑树)

概述:

map 是一种关联容器,用于存储键值对。map 中的每个元素都由一个唯一的键和一个与之关联的值组成,且元素按键的顺序自动排序。map 默认使用 红黑树 实现,保证了插入、查找、删除操作的时间复杂度为 O(log n)

使用场景:

map 常用于:

  • 需要根据键高效查找值的场景。
  • 实现频率计数、符号表等数据结构。
  • 数据按键排序的场景。

头文件:

#include <map>
using namespace std;

初始化:

map<int, string> m;

常用方法:

  • insert({key, value}):向 map 插入键值对。
  • erase(key):删除指定键的元素。
  • find(key):查找指定键的元素。
  • at(key):访问指定键的值,若键不存在抛出异常。
  • size():返回 map 中的元素数量。

深入分析:

map 是一个基于红黑树实现的排序容器,因此所有的键值对都保持按键排序的状态。这使得 map 在需要排序数据或进行键查找时非常高效。然而,由于其底层结构的特性,map 中的元素不能像 unordered_map 那样以 O(1) 时间复杂度进行查找。

示例代码:

#include <iostream>
#include <map>
using namespace std;int main() {map<int, string> m;// 向 map 中插入元素m.insert({1, "Apple"});m.insert({2, "Banana"});m[3] = "Cherry";// 输出所有键值对for (const auto& p : m) {cout << p.first << ": " << p.second << endl;}return 0;
}

输出:

1: Apple
2: Banana
3: Cherry

7. set:无重复的有序集合

概述:

set 是一个集合类型的容器,存储的是唯一元素,并且按照升序(或自定义顺序)排列。set 的实现通常基于 红黑树,所以它的插入、删除和查找操作都具有 O(log n) 的时间复杂度。

使用场景:

set 适用于:

  • 需要无重复元素的场景。
  • 元素按特定顺序进行排序的需求。
  • 需要高效查找、插入和删除的场景。

头文件:

#include <set>
using namespace std;

初始化:

set<int> s;

常用方法:

  • insert(value):将元素插入集合。
  • erase(value):删除指定的元素。
  • find(value):查找元素。
  • size():返回集合中元素的数量。
  • empty():检查集合是否为空。

深入分析:

set 内部使用红黑树保持元素有序,支持自动排序,因此其插入、查找、删除操作的时间复杂度为 O(log n)。但是,set 不允许重复元素,因此在插入元素时,如果元素已经存在,它不会再次插入。

示例代码:

#include <iostream>
#include <set>
using namespace std;int main() {set<int> s;// 插入元素s.insert(1);s.insert(2);s.insert(3);// 输出所有元素cout << "Set contents: ";for (const auto& elem : s) {cout << elem << " ";}cout << endl;return 0;
}

输出:

Set contents: 1 2 3

8. pair:存储两个元素的组合

概述:

pair 是一个简单的容器,用于存储两个相关联的元素。pair 是一个模板类,可以用来存储任何两种类型的值。

使用场景:

pair 常用于:

  • 关联两个不同类型的数据。
  • 作为返回值,尤其是函数需要返回多个相关的值时。
  • mapset 一起使用来存储键值对。

头文件:

#include <utility>
using namespace std;

初始化:

pair<int, string> p = {1, "Apple"};

常用方法:

  • first:访问 pair 的第一个元素。
  • second:访问 pair 的第二个元素。

深入分析:

pair 提供了一个简单而有效的方式来将两个不同类型的数据捆绑在一起。它的访问非常方便,直接通过 firstsecond 成员进行访问。pair 在处理关联数据(如键值对)时非常有用。

示例代码:

#include <iostream>
#include <utility>
using namespace std;int main() {pair<int, string> p = {1, "Apple"};// 输出 pair 中的元素cout << "First: " << p.first << ", Second: " << p.second << endl;return 0;
}

输出:

First: 1, Second: Apple

9. string:动态字符数组

概述:

string 是 C++ 标准库中用于处理文本数据的类。它支持动态调整大小,能够灵活处理字符串的插入、删除、查找和替换等操作。

使用场景:

string 常用于:

  • 处理动态长度的文本数据。
  • 文件操作、网络协议解析、用户输入等。

头文件:

#include <string>
using namespace std;

初始化:

string s = "Hello, world!";

常用方法:

  • length():返回字符串的长度。
  • empty():检查字符串是否为空。
  • append(str):向字符串末尾追加内容。
  • find(substr):查找子字符串的位置。
  • substr(start, length):返回子字符串。

深入分析:

string 类是一个非常强大且灵活的容器,提供了大量处理文本数据的函数。string 内部使用动态数组,因此能够自动扩展其容量。字符串操作通常涉及到字符的复制、移动或插入,所以操作时需要特别注意效率和内存管理。

示例代码:

#include <iostream>
#include <string>
using namespace std;int main() {string s = "Hello, world!";// 查找字符串中的字符位置cout << "Found 'world' at position: " << s.find("world") << endl;// 取子字符串string sub = s.substr(7, 5);cout << "Sub-string: " << sub << endl;return 0;
}

输出:

Found 'world' at position: 7
Sub-string: world

10. bitset:固定大小的位集合

概述:

bitset 是一个用于处理固定数量位的容器,提供对位的操作。bitset 可以用来进行二进制操作、实现位掩码等应用。它的大小在编译时就已确定,因此非常高效。

使用场景:

bitset 常用于:

  • 位掩码和位操作。
  • 存储和操作二进制状态数据。
  • 实现某些低级算法(如布尔运算)。

头文件:

#include <bitset>
using namespace std;

初始化:

bitset<8> b1;  // 默认值为 00000000
bitset<8> b2("10101010");  // 初始化为二进制字符串

常用方法:

  • set(pos):将指定位置的位设为 1。
  • reset(pos):将指定位置的位设为 0。
  • flip(pos):翻转指定位置的位。
  • size():返回 bitset 的大小。
  • count():返回 1 的位数。

深入分析:

bitset 是一个非常高效的位操作工具。它使用固定大小的数组来存储位,并提供直接的位操作方法。由于其大小在编译时就已确定,因此对于存储较小二进制数据非常合适。不过,bitset 不适合动态大小的位集合,且无法像 vector 那样随时扩展。

示例代码:

#include <iostream>
#include <bitset>
using namespace std;int main() {bitset<8> b1("10101010");// 输出 bitset 的内容cout << "Initial bitset: " << b1 << endl;// 翻转第 2 位b1.flip(2);cout << "After flipping 2nd bit: " << b1 << endl;// 获取 1 的位数cout << "Number of 1s: " << b1.count() << endl;return 0;
}

输出:

Initial bitset: 10101010
After flipping 2nd bit: 10100010
Number of 1s: 3

11. array:固定大小的数组

概述:

array 是 C++11 引入的一个容器,它是一个固定大小的数组容器。与 C 风格数组不同,array 是一个模板类,它支持 STL 容器的所有常用操作(如迭代器、排序等),但大小在编译时就已经确定。

使用场景:

array 适用于:

  • 需要固定大小数组的场景。
  • 需要类似于传统数组的性能,且希望获得更强大的 STL 操作支持时。

头文件:

#include <array>
using namespace std;

初始化:

array<int, 5> arr = {1, 2, 3, 4, 5};

常用方法:

  • at(index):返回指定位置的元素。
  • size():返回数组的大小。
  • fill(value):将所有元素初始化为相同的值。
  • front():返回第一个元素。
  • back():返回最后一个元素。

深入分析:

array 使得 C 风格数组拥有了 STL 容器的一些优势。它的大小固定,因此可以在栈上高效分配。相比于 vectorarray 不支持动态扩展,但它提供了更强大的 STL 接口和更高的类型安全性。适合存储大小固定的数据。

示例代码:

#include <iostream>
#include <array>
using namespace std;int main() {array<int, 5> arr = {1, 2, 3, 4, 5};// 输出数组的元素cout << "Array elements: ";for (const auto& elem : arr) {cout << elem << " ";}cout << endl;// 修改第一个元素arr[0] = 10;cout << "After modifying first element: " << arr[0] << endl;return 0;
}

输出:

Array elements: 1 2 3 4 5 
After modifying first element: 10

12. tuple:异构容器

概述:

tuple 是一个可以存储多个不同类型元素的容器。与 pair 类似,tuple 可以包含多个不同类型的元素,并且支持访问每个元素。tuple 提供了一种灵活的方式来捆绑多种类型的数据。

使用场景:

tuple 适用于:

  • 返回多个不同类型的值的函数。
  • 存储多个不同类型的参数或数据。
  • 元素数量在编译时已知的场景。

头文件:

#include <tuple>
using namespace std;

初始化:

tuple<int, string, float> t = {1, "Apple", 3.14};

常用方法:

  • get<index>(tuple):访问指定索引的元素。
  • tuple_size<tuple>::value:返回 tuple 的大小。
  • make_tuple():创建一个 tuple

深入分析:

tuple 是 C++ 中的一个非常灵活的容器,能够存储不同类型的数据。虽然它不如 vectormap 那样高频使用,但在需要处理多种类型的函数返回值或数据组合时非常有用。tuple 支持通过索引和类型访问元素。

示例代码:

#include <iostream>
#include <tuple>
using namespace std;int main() {tuple<int, string, float> t = {1, "Apple", 3.14};// 访问 tuple 中的元素cout << "First: " << get<0>(t) << ", Second: " << get<1>(t) << ", Third: " << get<2>(t) << endl;// 修改 tuple 中的元素get<1>(t) = "Banana";cout << "Modified tuple: " << get<0>(t) << ", " << get<1>(t) << ", " << get<2>(t) << endl;return 0;
}

输出:

First: 1, Second: Apple, Third: 3.14
Modified tuple: 1, Banana, 3.14

总结:

在这篇博客中,我们深入分析了 C++ STL 中的常用容器。每个容器都有其特定的使用场景和优缺点。在实际开发中,选择合适的容器是编写高效和易于维护代码的关键。了解每个容器的工作原理、常用方法以及深入分析将帮助你在复杂的应用中做出更好的选择。

通过对以下容器的详细讲解和示例,你可以清晰地了解每个容器的特性和应用场景:

  1. vector:动态数组,适用于需要快速随机访问的场景。
  2. stack:栈,适用于后进先出(LIFO)的场景。
  3. queue:队列,适用于先进先出(FIFO)的场景。
  4. deque:双端队列,适用于两端操作都频繁的场景。
  5. priority_queue:优先级队列,适用于按优先级排序的场景。
  6. map:键值对容器,适用于根据键查找值的场景。
  7. set:无重复元素的有序集合,适用于去重和排序的场景。
  8. pair:存储两个相关元素的组合,常用于 map 中。
  9. string:动态字符串,适用于文本处理的场景。
  10. bitset:固定大小的位集合,适用于位运算的场景。
  11. array:固定大小的数组,适用于大小已知且不变的场景。
  12. tuple:存储多个不同类型元素的容器,适用于函数返回多个不同类型值的场景。

每个容器的底层实现和时间复杂度有所不同,选择正确的容器能显著提高程序的性能和可维护性。希望这篇文章能帮助你更好地理解 C++ STL 容器的使用和选择。

🎉🌈 陪伴至此,感谢有你 🌈🎉

感谢你能坚持看到这里!如果这篇文章对你有一点点帮助,希望能收获你的:
👍 一个赞,⭐ 一个收藏,💬 一条评论 或 🔗 一键分享!
你的支持是我持续输出的最大动力!✨

有问题?有灵感?
别犹豫,直接留言和我交流~让我们一起成长、一起突破 💡。

最后,祝你:

🍯 生活美满如蜜香
🌞 心情灿烂似朝阳
🌱 成长如树渐成章
🚀 未来闪耀梦飞翔!

再次感谢你的阅读!🌟 下次再见~ 🎉

感谢

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

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

相关文章

ShenNiusModularity项目源码学习(7:数据库结构)

ShenNiusModularity项目默认使用mysql数据库&#xff0c;数据库连接字符串放到了ShenNius.Admin. Mvc、ShenNius.Admin.Hosting的appsettings.json文件内。   ShenNiusModularity项目为自媒体内容管理系统&#xff0c;支持常规管理、CMS管理、商城管理等功能&#xff0c;其数…

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(五)

Understanding Diffusion Models: A Unified Perspective&#xff08;五&#xff09; 文章概括基于得分的生成模型&#xff08;Score-based Generative Models&#xff09; 文章概括 引用&#xff1a; article{luo2022understanding,title{Understanding diffusion models: A…

服务器上安装Nginx详细步骤

第一步&#xff1a;上传nginx压缩包到指定目录。 第二步&#xff1a;解压nginx压缩包。 第三步&#xff1a;配置编译nginx 配置编译方法&#xff1a; ./configure 配置编译后结果信息&#xff1a; 第四步&#xff1a;编译nginx 在nginx源文件目录中直接运行make命令 第五步&…

C++初阶—string类

第一章&#xff1a;为什么要学习string类 1.1 C语言中的字符串 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP的思想&…

基于Django的豆瓣影视剧推荐系统的设计与实现

【Django】基于Django的豆瓣影视剧推荐系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用了Python作为后端开发语言&#xff0c;采用Django作为后端架构&#xff0c;结…

【miniconda】:langraph的windows构建

langraph需要python3.11 langraph强烈建议使用py3.11 默认是3.12 官方 下载仓库 下载老版本的python (后续发现新版miniconda也能安装老版本的python) 在这里

使用Python和Qt6创建GUI应用程序--关于Qt的一点介绍

关于Qt的一点介绍 Qt是一个免费的开源部件工具包&#xff0c;用于创建跨平台GUI应用程序&#xff0c;允许应用程序从Windows瞄准多个平台&#xff0c;macOS&#xff0c; Linux和Android的单一代码库。但是Qt不仅仅是一个Widget工具箱和功能内置支持多媒体&#xff0c;数据库&am…

Web3.0时代的挑战与机遇:以开源2+1链动模式AI智能名片S2B2C商城小程序为例的深度探讨

摘要&#xff1a;Web3.0作为互联网的下一代形态&#xff0c;承载着去中心化、开放性和安全性的重要愿景。然而&#xff0c;其高门槛、用户体验差等问题阻碍了Web3.0的主流化进程。本文旨在深入探讨Web3.0面临的挑战&#xff0c;并提出利用开源21链动模式、AI智能名片及S2B2C商城…

NoteGen:记录、写作与AI融合的跨端笔记应用

在信息爆炸的时代,如何高效地捕捉灵感、整理知识并进行创作成为了许多人关注的问题。为此,我们开发了 NoteGen,一款专注于记录和写作的跨端 AI 笔记应用。它基于 Tauri 开发,利用其强大的跨平台能力支持 Mac、Windows 和 Linux 系统,并计划未来扩展到 iOS 和 Android 平台…

八股——Java基础(四)

目录 一、泛型 1. Java中的泛型是什么 ? 2. 使用泛型的好处是什么? 3. Java泛型的原理是什么 ? 什么是类型擦除 ? 4.什么是泛型中的限定通配符和非限定通配符 ? 5. List和List 之间有什么区别 ? 6. 可以把List传递给一个接受List参数的方法吗&#xff1f; 7. Arra…

字节iOS面试经验分享:HTTP与网络编程

字节iOS面试经验分享&#xff1a;HTTP与网络编程 &#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 目录 字节iOS面试经验分享&#xff1a;HTT…

Jenkins上生成的allure report打不开怎么处理

目录 问题背景&#xff1a; 原因&#xff1a; 解决方案&#xff1a; Jenkins上修改配置 通过Groovy脚本在Script Console中设置和修改系统属性 步骤 验证是否清空成功 进一步的定制 也可以使用Nginx去解决 使用逆向代理服务器Nginx&#xff1a; 通过合理调整CSP配置&a…

【16届蓝桥杯寒假刷题营】第2期DAY5

2.最大公因数 - 蓝桥云课 问题描述 给你2个正整数N&#xff0c;M。 你需要构造一个有N个数的正整数序列a&#xff0c;满足以下条件&#xff1a; ∑i1N​ai​M。 求gcd(a)&#xff0c;可能的最大值。 输入描述 输入一行两个正整数N&#xff0c;M&#xff0c;表示数组的长…

【Linux系统】计算机世界的基石:冯诺依曼架构与操作系统设计

文章目录 一.冯诺依曼体系结构1.1 为什么体系结构中要存在内存&#xff1f;1.2 冯诺依曼瓶颈 二.操作系统2.1 设计目的2.2 系统调用与库函数 一.冯诺依曼体系结构 冯诺依曼体系结构&#xff08;Von Neumann Architecture&#xff09;是计算机的基本设计理念之一&#xff0c;由…

顶刊JFR|ROLO-SLAM:首个针对不平坦路面的车载Lidar SLAM系统

摘要 基于激光雷达&#xff08;LiDAR&#xff09;的同步定位与地图构建&#xff08;SLAM&#xff09;被认为是在恶劣环境中提供定位指导的一种有效方法。然而&#xff0c;现成的基于激光雷达的SLAM方法在经过不平坦地形时&#xff0c;尤其是在垂直方向相关的部分&#xff0c;会…

深度学习探索:ChatGPT数据分析精髓 梯度下降优化方法深度剖析

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

docker安装elk6.7.1-搜集java日志

docker安装elk6.7.1-搜集java日志 如果对运维课程感兴趣&#xff0c;可以在b站上、A站或csdn上搜索我的账号&#xff1a; 运维实战课程&#xff0c;可以关注我&#xff0c;学习更多免费的运维实战技术视频 0.规划 192.168.171.130 tomcat日志filebeat 192.168.171.131 …

网络工程师 (3)指令系统基础

一、寻址方式 &#xff08;一&#xff09;指令寻址 顺序寻址&#xff1a;通过程序计数器&#xff08;PC&#xff09;加1&#xff0c;自动形成下一条指令的地址。这是计算机中最基本、最常用的寻址方式。 跳跃寻址&#xff1a;通过转移类指令直接或间接给出下一条指令的地址。跳…

思科交换机telnet配置案例

目录 1.telnet简述2.网络拓扑3.设备说明4.网络配置4.1 电脑PC ip设置4.2 网络交换机telnet配置 5.小结 1.telnet简述 Telnet是远程登录服务的一个协议&#xff0c;该协议定义了远程登录用户与服务器交互的方式。它允许用户在一台联网的计算机上登录到一个远程分时系统中&#…

Spring MVC(二)

介绍 Cookie 与 Session Session 类似哈希表&#xff0c;存储了一些键值对结构&#xff0c;Key 就是 SessionID&#xff0c;Vaule 就是用户信息&#xff0c;客户端发起会话的时候&#xff0c;服务器一旦接收&#xff0c;就会创建会话【也就是 Session】&#xff0c;通过 Sessi…