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

C++STL剖析(六)—— set和multiset的概念和使用

文章目录

  • 🌟 前言
    • 🍑 树型结构和哈希结构
    • 🍑 键值对
  • 1. set的介绍和使用
    • 🍑 set的模板参数列表
    • 🍑 set的构造
    • 🍑 set的使用
      • 🍅 insert
      • 🍅 find
      • 🍅 erase
      • 🍅 swap
      • 🍅 empty
      • 🍅 size
      • 🍅 count
      • 🍅 lower_bound
      • 🍅 upper_bound
  • 2. multiset的介绍和使用
    • 🍑 multiset的使用
      • 🍅 find
      • 🍅 erase
      • 🍅 count
  • 3. 两个数组的交集

🌟 前言

在 STL 中主要有两种类型的容器:序列式容器关联式容器

  • 序列式容器里面存储的是元素本身,其底层为线性序列的数据结构。比如:vector,list,deque,forward_list 等。
  • 关联式容器里面存储的是 <key, value> 结构的键值对,在数据检索时比序列式容器效率更高。比如:set,map,unordered_set,unordered_map 等。

但是有一点需要注意,STL 当中的 stack,queue 和 priority_queue 属于容器适配器。

stack 和 queue 默认使用的基础容器是 deque,而 priority_queue 使用的基础容器是 vector。

🍑 树型结构和哈希结构

根据应用场景的不同,STL 总共实现了两种不同结构的关联式容器:树型结构哈希结构

在这里插入图片描述

其中,树型结构容器中的元素是一个有序的序列,而哈希结构容器中的元素是一个无序的序列。

🍑 键值对

键值对是用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量 keyvaluekey 代表 键值,value 表示与 key 对应的信息。

比如:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义。

SGI-STL 中关于键值对的定义方式如下:

template <class T1, class T2>
struct pair
{typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair() : first(T1()), second(T2()){}pair(const T1& a, const T2& b) : first(a), second(b){}
};

1. set的介绍和使用

set 的介绍:

  • set 是按照一定顺序存储元素的容器。
  • 在 set 中,元素的 value 也标识它(value 就是 key,类型为 T),并且每个 value 必须是唯一的。set 中的元素不能在容器中修改(元素总是 const 类型),但是可以从容器中插入或删除它们。
  • 在内部,set 中的元素总是按照其内部比较对象(类型为Compare)所指示的特定严格弱排序准则进行排序。
  • set 容器通过 key 访问单个元素的速度通常比 unordered_set 容器慢,但 set 容器允许根据顺序对子集进行直接迭代。
  • set 在底层是用二叉搜索树(红黑树)实现的。

注意:

  • 与 map/multimap 不同,map/multimap 中存储的是真正的键值对 <key, value>,set 中只放 value,但在底层实际存放的是由 <value, value>构成的键值对。
  • set 中插入元素时,只需要插入 value 即可,不需要构造键值对。
  • set 中的元素不可以重复(因此可以使用 set 进行去重)。
  • 使用 set 的迭代器遍历 set 中的元素,可以得到有序序列
  • set 中的元素默认按照小于来比较
  • set 中查找某个元素,时间复杂度为:logNlogNlogN
  • set中的元素不允许修改,因为 set 在底层是用二叉查找树来实现的,若是对二叉查找树当中某个结点的值进行了修改,那么这棵树将不再是二叉查找树。

🍑 set的模板参数列表

如下图所示:

在这里插入图片描述

  • T:set 中存放元素的类型,实际在底层存储 <value, value> 的键值对。
  • Compare:set 中元素默认按照小于来比较。
  • Alloc:set 中元素空间的管理方式,使用 STL 提供的空间配置器管理。

🍑 set的构造

这里主要有 3 种方式:

在这里插入图片描述

(1)无参构造一个空容器

set<int> s1; // 构造一个int类型的空容器

(2)拷贝构造某类型容器

set<int> s2(s1); // 拷贝构造int类型s1容器的复制品

(3)使用迭代器区间进行初始化构造

vector<int> v1 = { 1,2,3,4,5 };
set<int> s3(v1.begin(), v1.end()); // 构造vector对象某段区间的复制品

🍑 set的使用

set 的成员函数主要分为:迭代器,容量操作,修改操作。

需要注意的是,对于 set 而言,它的普通迭代器和 const 迭代器都不支持修改。

在这里插入图片描述

我这里只列举几个常用的,其它的可以看文档学习。

🍅 insert

在 set 中插入元素 val,实际插入的是 <val, val> 构成的键值对

  • 如果插入成功,返回 <val在set中的位置, true>
  • 如果插入失败,说明 val 在 set 中已经存在,返回 <val在set中的位置, false>

在这里插入图片描述

代码示例

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(2);s.insert(1);s.insert(3);s.insert(3);// 遍历for (auto e : s){cout << e << " ";}
}

可以看到当插入重复元素时,set 的去掉了的,并且还进行了升序的排序

在这里插入图片描述

🍅 find

在容器中搜索查找 val 元素,如果找到,则返回一个迭代器,否则返回 set::end 的迭代器。

在这里插入图片描述

代码示例

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(2);s.insert(1);s.insert(3);s.insert(3);auto pos = s.find(5);if (pos != s.end()){cout << "找到了" << endl;}
}

运行结果

在这里插入图片描述

🍅 erase

删除 set 中的元素,这里有 3 种删除方式。

在这里插入图片描述

(1)从 set 容器中删除单个元素(搭配 find 使用)

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(1);s.insert(6);s.insert(3);s.insert(8);s.insert(7);auto pos = s.find(5);if (pos != s.end()){s.erase(pos); // 删除元素5cout << "删除成功" << endl;}else{cout << "删除失败" << endl;}// 遍历for (auto e : s){cout << e << " ";}
}

可以看到元素 5 已经被删除了

在这里插入图片描述

(2)从 set 容器中删除单个元素(直接传要删除的元素)

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(1);s.insert(6);s.insert(3);s.insert(8);s.insert(7);s.erase(5);// 遍历for (auto e : s){cout << e << " ";}
}

可以看到 5 已经被删除

在这里插入图片描述

那么它和第 1 种的区别是什么呢?

  • erase(x):如果 x 存在就删除;如果不存在,不做任何改变
  • erase(pos):如果 x 存在就删除;如果不存在,此时 pos 位置指向 set::end 的迭代器,那么程序运行就会报错。

其实这种方式本质上可以理解为 erase 去调用了迭代器和 find

(3)从 set 容器中删除一组元素(传的是迭代器区间 [first,last)

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(1);s.insert(6);s.insert(3);s.insert(8);s.insert(7);auto pos = s.find(5);if (pos != s.end()){s.erase(pos, s.end()); // 从5开始所有的元素全部删除cout << "删除成功" << endl;}else{cout << "删除失败" << endl;}// 遍历for (auto e : s){cout << e << " ";}
}

可以看到从 5 开始所有的元素都已经被删除

在这里插入图片描述

🍅 swap

交换 set 容器中的元素

在这里插入图片描述

代码示例

void testset()
{set<int> s1;s1.insert(4);s1.insert(5);s1.insert(2);s1.insert(1);set<int> s2;s2.insert(6);s2.insert(3);s2.insert(8);s2.insert(7);s1.swap(s2);cout << "s1:";// 遍历for (auto e1 : s1){cout << e1 << " ";}cout << "s2:";// 遍历for (auto e2 : s2){cout << e2 << " ";}
}

可以看到 s1 和 s2 的元素已经被交换了

在这里插入图片描述

🍅 empty

判断 set 容器是否为空,空返回 true,非空返回 false。

在这里插入图片描述

代码示例

void testset()
{set<int> s1;s1.insert(4);s1.insert(5);s1.insert(2);s1.insert(1);set<int> s2;cout << s1.empty() << endl; // s1容器不为空,输出0cout << s2.empty() << endl; // s2容器为空,输出1
}

运行结果

在这里插入图片描述

🍅 size

返回 set 中有效元素的个数

在这里插入图片描述

代码示例

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(1);s.insert(6);s.insert(3);s.insert(8);s.insert(7);// 打印元素个数cout << s.size() << endl;
}

运行结果

在这里插入图片描述

🍅 count

返回 set 中值为 x 的元素的个数。

在这里插入图片描述

代码示例

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(1);s.insert(6);s.insert(3);s.insert(8);s.insert(7);// 元素3的个数cout << s.count(3) << endl;// 元素7的个数cout << s.count(10) << endl;
}

可以看到 3 出现了一次,10 不存在

在这里插入图片描述

这个接口对于 set 容器其实没有太大用处,因为 set 当中的每个 value 都是唯一的。

🍅 lower_bound

返回一个指向容器中第一个元素的迭代器,该迭代器不被认为在val之前(它是等于或在val之后)

其实就是,返回大于等于 val 位置的迭代器。

在这里插入图片描述

代码示例一

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(1);s.insert(3);s.insert(8);s.insert(7);// 如果3存在就返回3位置的迭代器auto lowIt = s.lower_bound(3);cout << *lowIt << endl;// 如果6不存在就返回比6大的位置的迭代器lowIt = s.lower_bound(6);cout << *lowIt << endl;
}

运行结果

在这里插入图片描述

代码示例二

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(1);s.insert(3);s.insert(8);s.insert(7);// 删除大于等于4的所有值auto lowIt = s.lower_bound(4);s.erase(lowIt, s.end());// 遍历for (auto e : s){cout << e << " ";}
}

可以看到大于等于 4 的所有值都被删除了

在这里插入图片描述

🍅 upper_bound

返回指向容器中第一个元素的迭代器,该元素被认为是 val 之后的元素。

也就是说,不管 val 存在还是不存在,都返回比 val 大的那个值。

在这里插入图片描述

代码示例

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(1);s.insert(3);s.insert(8);s.insert(7);// 如果3存在就返回大于3位置的迭代器auto lowIt = s.upper_bound(3);cout << *lowIt << endl;// 如果6不存在就返回比6大的位置的迭代器lowIt = s.upper_bound(6);cout << *lowIt << endl;
}

运行结果

在这里插入图片描述

其实 lower_boundupper_bound 可以搭配使用,删除元素中间的一段区间。

void testset()
{set<int> s;// 插入元素s.insert(4);s.insert(5);s.insert(2);s.insert(6);s.insert(1);s.insert(3);s.insert(8);s.insert(7);// 删除 [3, 7] 这段区间中的所有数auto leftIt = s.lower_bound(3); // 返回3位置的迭代器auto rightIt = s.upper_bound(7); // 返回8位置的迭代器s.erase(leftIt, rightIt);// 遍历for (auto e : s){cout << e << " ";}
}

注意,erase 删除的迭代器区间是左闭右开,也就是说 rightIt 是 8 位置的迭代器,但是 erase 只会删除到 7。

[3, 8)[3, 7]

在这里插入图片描述

2. multiset的介绍和使用

multiset 的介绍:

  • multiset 是按照特定顺序存储元素的容器,其中元素是可以重复的。
  • 在 multiset 中,元素的 value 也会识别它(因为 multiset 中本身存储的就是 <value, value> 组成的键值对,因此 value 本身就是 key,key 就是 value,类型为 T),multiset 元素的值不能在容器中进行修改(因为元素总是 const 的),但可以从容器中插入或删除。
  • 在内部,multiset 中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则进行排序。
  • multiset 容器通过 key 访问单个元素的速度通常比 unordered_multiset 容器慢,但当使用迭代器遍历时会得到一个有序序列。
  • multiset 底层结构为二叉搜索树(红黑树)。

注意:

  • multiset 中再底层中存储的是 <value, value> 的键值对
  • mtltiset 的插入接口中只需要插入即可
  • 与 set 的区别是,multiset 中的元素可以重复,set 是中 value 是唯一的
  • 使用迭代器对 multiset 中的元素进行遍历,可以得到有序的序列
  • multiset 中的元素不能修改
  • 在 multiset 中找某个元素,时间复杂度为O(logN)O(logN)O(logN)
  • multiset 的作用:可以对元素进行排序

multiset的模板参数列表如下:

在这里插入图片描述

🍑 multiset的使用

当我们插入多个元素时,multiset 允许键值冗余,也就说 multiset 容器当中存储的元素是可以重复的。

代码示例

void testmultiset()
{multiset<int> ms;ms.insert(4);ms.insert(5);ms.insert(2);ms.insert(2);ms.insert(1);ms.insert(3);ms.insert(3);// 遍历for (auto e : ms){cout << e << " ";}
}

可以看到是存在多个相同元素的。

在这里插入图片描述

另外,它和 set 容器所提供的成员函数的接口都是基本一致的,所以就不全部列举了,只列举几个稍微有点小差别的函数接口。

🍅 find

在容器中搜索 val 元素,如果找到,则返回中序位置的第一个迭代器,否则返回 multiset::end 的迭代器。

在这里插入图片描述

代码示例

void testmultiset()
{multiset<int> ms;ms.insert(4);ms.insert(5);ms.insert(2);ms.insert(2);ms.insert(5);ms.insert(7);ms.insert(1);ms.insert(5);ms.insert(6);ms.insert(5);ms.insert(3);ms.insert(3);for (auto e : ms){cout << e << " ";}cout << endl;auto pos = ms.find(5); // 多个5的话,返回中序第一个5// 打印pos位置后面的所有元素while (pos != ms.end()){cout << *pos << " ";++pos;}
}

可以看到确实是从第一个 5 开始打印的

在这里插入图片描述

🍅 erase

从容器中删除单个元素,直接传要删除的话,erase 是的返回值是 size_type

它会把容器中所有的 val 全部删除,并且返回删除的 val 的个数。

在这里插入图片描述

代码示例

void testmultiset()
{multiset<int> ms;ms.insert(4);ms.insert(5);ms.insert(2);ms.insert(2);ms.insert(5);ms.insert(7);ms.insert(1);ms.insert(5);ms.insert(6);ms.insert(5);ms.insert(3);ms.insert(3);// 删除容器中所有的5,并返回5的个数cout << ms.erase(5) << endl;for (auto e : ms){cout << e << " ";}
}

可以看到元素 5 已经被删除了,并且元素个数是 4。

在这里插入图片描述

🍅 count

在容器中搜索等同于 val 的元素,并返回匹配的个数。

在这里插入图片描述

代码示例

void testmultiset()
{multiset<int> ms;ms.insert(4);ms.insert(3);ms.insert(2);ms.insert(2);ms.insert(5);ms.insert(7);ms.insert(1);ms.insert(3);ms.insert(6);ms.insert(5);ms.insert(3);// 统计3的个数cout << ms.count(3) << endl;// 遍历for (auto e : ms){cout << e << " ";}
}

运行结果

在这里插入图片描述

3. 两个数组的交集

题目描述

在这里插入图片描述

解题思路

对于求并集、交集、差集,其实有一种特定的方法,如下图所示:

在这里插入图片描述

代码实现

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {// 去掉num1当中重复的元素并排序set<int> s1;for (auto e1 : nums1){s1.insert(e1);}// 去掉num2当中重复的元素并排序set<int> s2;for (auto e2 : nums2){s2.insert(e2);}vector<int> ret; // 存放交集auto it1 = s1.begin(); // 指向s1的起始位置auto it2 = s2.begin(); // 指向s2的起始位置while (it1 != s1.end() && it2 != s2.end()) // 当s1和s2都没有遍历完时{if (*it1 < *it2) {it1++;}else if (*it2 < *it1){it2++;}else // 当it1和it2指向的元素相等时,就是交集{ret.push_back(*it1); // 把元素尾插到ret中,然后同时向后挪动it1++;it2++;}}return ret; // 返回交集}
};

相关文章:

C++STL剖析(六)—— set和multiset的概念和使用

文章目录&#x1f31f; 前言&#x1f351; 树型结构和哈希结构&#x1f351; 键值对1. set的介绍和使用&#x1f351; set的模板参数列表&#x1f351; set的构造&#x1f351; set的使用&#x1f345; insert&#x1f345; find&#x1f345; erase&#x1f345; swap&#x1…...

SpringColud第四讲 Nacos的Windows安装方式和Linux的安装方式

在Nacos的GitHub页面&#xff0c;提供有下载链接&#xff0c;可以下载编译好的Nacos服务端或者源代码&#xff1a; 目录 1.Windows安装Nacos 1.1.下载 1.2.解压 1.3.修改相关配置&#xff1a; 1.4.启动&#xff1a; 1.5.登录&#xff1a; 2.Linux的安装方式Nacos 2.1.…...

微服务项目【网关服务限流熔断降级分布式事务】

网关服务限流熔断降级 第1步&#xff1a;启动sentinel-dashboard控制台和Nacos注册中心服务 第2步&#xff1a;在网关服务中引入sentinel依赖 <!-- sentinel --> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-…...

【情人节用Compose给女神写个爱心动画APP】

情人节用Compose给女神写个爱心动画APP前言涉及知识点实现思路实现过程绘制爱心创建动画效果Preview预览效果完整源码彩蛋前言 前一阵子看电视里的学霸用代码写了个炫酷的爱心&#xff0c;网上有很多js和python的源码&#xff0c;复制粘贴就能拥有&#xff0c;但是Android的好…...

GUI swing和awt

GUI&#xff08;Graphical User Interface&#xff0c;简称 GUI&#xff0c;图形用户界面&#xff09;是指采用图形方式显示的计算机操作用户界面&#xff0c;与早期计算机使用的命令行界面相比&#xff0c;图形界面对于用户来说在视觉上更易于接受。Java GUI主要有两个核心库&…...

速通Spring

尚硅谷2023最新版Spring6课程_bilibili 1 Spring 【强制】Spring是什么&#xff1f; 1) Spring是一款主流的Java EE轻量级开源框架。 轻量级&#xff1a;体积很小&#xff0c;且不需要依赖于其他组件。 2) 狭义的Spring。 Spring Framework。 3) 广义的Spring。 以Spring F…...

【C++】C++入门

一、 C关键字&#xff08;C98&#xff09; C有63个关键字&#xff08;C语言有32个&#xff09;&#xff0c;如下&#xff1a; asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutabl…...

Linux网络技术学习(五)—— 网络设备初始化(I)

文章目录什么时候进行的设备初始化&#xff1f;设备注册和初始化NIC&#xff08;网卡 Network Interface Card&#xff09;初始化的基本目标设备与内核之间的交互硬件中断中断类型传送节流方式为了改善效率中断共享IRQ处理函数映射的组织irqaction结构体存储方式什么时候进行的…...

[技术选型] ClickHouse和StarRocks的介绍

文章目录1.ClickHouse介绍2.StarRocks介绍1.ClickHouse介绍 ClickHouse是面向联机分析处理&#xff08;OLAP&#xff09;的开源分析引擎。最初由俄罗斯第一搜索引擎Yandex开发&#xff0c;于2016年开源&#xff0c;开发语言为C。由于其优良的查询性能&#xff0c;PB级的数据规…...

算法刷题打卡第90天:表现良好的最长时间段

表现良好的最长时间段 难度&#xff1a;中等 给你一份工作时间表 hours&#xff0c;上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候&#xff0c;那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」&#xff0c;意味在这…...

Python语言零基础入门教程(十七)

Python 文件I/O 本章只讲述所有基本的 I/O 函数&#xff0c;更多函数请参考Python标准文档。 #### 打印到屏幕 最简单的输出方法是用print语句&#xff0c;你可以给它传递零个或多个用逗号隔开的表达式。此函数把你传递的表达式转换成一个字符串表达式&#xff0c;并将结果写…...

C语言中大小端问题

目录 一、什么是大小端 二、 举个例子 三、大小端演示 四、解释"二"中举例的问题 ​五、怎么判断是大端还是小端 六、一个题目 一、什么是大小端 大端模式&#xff08;大端字节序存储&#xff09;&#xff1a;就是高位字节数据存放在内存的低地址端&#xff…...

vue2+微前端qiankun从搭建到部署的实践(主子应用切换;集成vue3+vite3子应用)

一、最终效果 二、微前端&#xff08;qiankun&#xff09;介绍及为什么选择用微前端&#xff0c;可以看官网 三、目录结构如下 四、具体配置 一、主应用配置 1、主应用技术栈 Vue-cli4搭建项目Vue2Element-Uiqiankun&#xff1b;Vue2Element-Uiqiankun 2、搭建好主项目&…...

怎么代理微信小程序创业?

随着微信的兴起&#xff0c;小程序已经成为了人们生活中不可或缺的一部分。如果你想要创业的话&#xff0c;那么代理微信小程序是一个不错的选择。本文将为大家介绍怎么代理微信小程序创业。 一、什么是微信小程序 微信小程序是一款专为移动设备使用者而设计的应用。它通过扫…...

今天是情人节呐,我利用Python制作了好多表白的东西,快来吧~

今天是情人节那&#xff0c;有没有现在没有对象的宝子&#xff0c;评论里扣个111哈哈 目录 玫瑰 爱心树 丘比特 多彩气球 阿玥的小课堂 一、情人节的由来 二、情人节的来历和意义 玫瑰 局部代码实现如下&#xff1a; # 花瓣1 turtle.left(150) turtle.circle(-90, 70) …...

【Linux】-- 进程信号(处理、内核)

上篇&#xff1a;【Linux】-- 进程信号&#xff08;认识、应用&#xff09;_川入的博客-CSDN博客 目录 信号其他相关常见概念 pending handler block 信号处理的过程 sigset_t sigset_t使用 系统接口 sigpending sigprocmask 捕捉方法 sigaction struct sigactio …...

C/【静态通讯录】

&#x1f331;博客主页&#xff1a;大寄一场. &#x1f331;系列专栏&#xff1a;C语言学习笔记 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 前言 往期回顾&#xff1a; C/扫雷 C/N子棋 通讯录作为通讯录地址的书本&#xff0c;当今的通讯录可以涵盖多项…...

万卷书 - 让孩子对自己负责 [The Self-Driven Child]

让孩子对自己负责 The Self-Driven Child - 让你的孩子更加科学合理的掌控自己的生活 简介 《The Self-Driven Child》(2018)解释了我们对孩子的习惯性控制欲,它导致了孩子压力过大、难以合作,以及主观能动性差。本书不提倡这种做法,而是认为我们应该帮助孩子自己做出合适…...

Postman中cookie的操作

在接口测试中&#xff0c;某些接口的调用&#xff0c;需要带入已有Cookie&#xff0c;比如有些接口需要登陆后才能访问。 Postman接口请求使用Cookie有如下两种方式&#xff1a; 1、直接在头域中添加Cookie头域&#xff0c;适用于已经知道请求所用Cookie数据的情况。 2、使用…...

torch.grid_sample

参考&#xff1a; 双线性插值的理论Pytorch grid_sample解析PyTorch中grid_sample的使用方法pytorch中的grid_sample()使用 查阅官方文档&#xff0c;TORCH.NN.FUNCTIONAL.GRID_SAMPLE grid_sample的函数签名如下所示&#xff0c;torch.nn.functional.grid_sample(input, gr…...

前端基于 Docker 的 SSR 持续开发集成环境实践

项目收益 整体开发效率提升20%。加快首屏渲染速度&#xff0c;减少白屏时间&#xff0c;弱网环境下页面打开速度提升40%。 权衡 在选择使用SSR之前&#xff0c;需要考虑以下事项&#xff01; SSR需要可以运行Node.js的服务器&#xff0c;学习成本相对较高。对于服务器而言&a…...

ARM交叉编译入门及交叉编译第三方库常见问题解析

1. 交叉编译是什么&#xff1f; 交叉编译简单说来&#xff0c;就是编译成果物的地儿不是你运行这个成果物的地儿。最常见的场景&#xff0c;就是我们要编译一个 ARM版本 的可执行程序&#xff0c;但我们编译这个 ARM版本 可执行程序的地方&#xff0c;是在一个 x86_x64 的平台…...

Ruby Web Service 应用 - SOAP4R

什么是 SOAP&#xff1f; 简单对象访问协议(SOAP,全写为Simple Object Access Protocol)是交换数据的一种协议规范。 SOAP 是一种简单的基于 XML 的协议&#xff0c;它使应用程序通过 HTTP 来交换信息。 简单对象访问协议是交换数据的一种协议规范&#xff0c;是一种轻量的、…...

HashMap底层实现原理概述

原文https://blog.csdn.net/fedorafrog/article/details/115478407 hashMap结构 常见问题 在理解了HashMap的整体架构的基础上&#xff0c;我们可以试着回答一下下面的几个问题&#xff0c;如果对其中的某几个问题还有疑惑&#xff0c;那就说明我们还需要深入代码&#xff0c…...

Linux驱动学习环境搭建

背景常识 一、程序分类 程序按其运行环境分为&#xff1a; 1. 裸机程序&#xff1a;直接运行在对应硬件上的程序 2. 应用程序&#xff1a;只能运行在对应操作系统上的程序 二、计算机系统的层次结构 所有智能设备其实都是计算机&#xff0c;机顶盒、路由器、冰箱、洗衣机、汽…...

Java基础之异常

目录1 异常1.1 异常的概述1.2 常见异常类型1.3 JVM的默认处理方案1.4 编译时异常的处理方式1.4.1 异常处理之 try ... catch ... [ktʃ]&#xff08;捕获异常&#xff09;1.4.2 异常处理之 throws&#xff08;抛出异常&#xff09;1.5 Throwable 的成员方法1.6 编译时异常和运行…...

感慨:大三了,未来该何去何从呢

笔者曾在十一月份通过了字节跳动的三次面试&#xff0c; 但是最终因为疫情原因不能满足公司的入职时间要求&#xff0c; 没有拿到offer。近期也是投递了大量大厂的实习岗&#xff0c; 但是要么已读不回&#xff0c; 要么明确告诉我学历至少要985硕士(天天被阿里cpu)。 说实话一…...

分账系统逻辑

一、说明 主体与业务关系方进行相关利益和支出的分配过程 使用场景&#xff1a; 在分销业务中&#xff0c;主营商户收到用户购买分销商品所支付的款项后&#xff0c;可以通过分账逻辑&#xff0c;与分销商进行佣金结算。在零售、餐饮等行业中&#xff0c;当销售人员完零售等…...

SpringCloud篇——什么是SpringCloud、有什么优缺点、学习顺序是什么

文章目录一、首先看官方解释二、Spring Cloud 的项目的位置三、Spring Cloud的子项目四、Spring Cloud 现状五、spring cloud 优缺点六、Spring Cloud 和 Dubbo 对比七、Spring Cloud 学习路线一、首先看官方解释 Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式…...

TCP核心机制之连接管理详解(三次握手,四次挥手)

目录 前言&#xff1a; 建立连接 建立连接主要两个TCP状态&#xff1a; 断开连接 断开连接的两个重要状态 小结&#xff1a; 前言&#xff1a; TCP是如何建立对端连接&#xff0c;如何断开连接&#xff0c;这篇文章会详细介绍。 建立连接 首先明确连接的概念&#xff1a…...

福安做网站/微信群拉人的营销方法

本公众号 的系列文章《跟热饭一起学习vue吧》&#xff0c;本文会采用非常土&#xff0c;非常low的语言&#xff0c;让读者学习并立即上手即可使用vue去写前端页面。简单生动&#xff0c;由浅入深。那么&#xff0c;就一起开始学习吧&#xff0c;体验一把又土又油腻的教程吧~ 别…...

微信平台的微网站怎么做的/移动营销

本部分理解原理就好 Spring入门1 Spring引入1.1 原生web开发中存在的问题2 Spring2.1 Spring的概念2.2 Spring 作用2.3 Spring的组成2.4 spring的IOC底层实现原理3 Spring快速入门3.1 引入spring依赖3.2 spring的配置文件3.3 测试四、Spring的开发细节4.1 BeanFactory的类间关系…...

深圳市门户网站建设/如何做网站赚钱

近年来&#xff0c;为顺应新一轮科技革命和产业变革发展趋势&#xff0c;国家提出加快新型基础设施建设并做出一系列决策部署&#xff0c;同时首次将“新基建”写入政府工作报告。新型基础设施更侧重于以信息网络为基础&#xff0c;综合集成新一代信息技术&#xff0c;围绕数据…...

phpwind 做企业网站/彩虹云商城网站搭建

题目描述 给出一个字符串s&#xff0c;分割s使得分割出的每一个子串都是回文串 计算将字符串s分割成回文分割结果的最小切割数 例如:给定字符串s"aab", 返回1&#xff0c;因为回文分割结果["aa","b"]是切割一次生成的。 思路&#xff1a; 动…...

怀来住房和城乡建设委员会网站/最近一周新闻

转载自 http://blog.csdn.net/edricbjtu/article/details/41082597 转载于:https://www.cnblogs.com/minesweeper/p/5937474.html...

什么叫网站建设四网合一/重庆seo网络优化咨询热线

前面一篇《NoSQL架构实践&#xff08;一&#xff09;——以NoSQL为辅》主要介绍了以NoSQL为辅助的架构&#xff0c;这种架构实施起来比较简单&#xff0c;易于理解&#xff0c;由于其中也使用了传统的关系数据库&#xff0c;让开发者更容易控制NoSQL带来的风险。接下来我们继续…...