C++修炼:map和set的使用
Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路!
我的博客:<但凡.
我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C++修炼之路》
欢迎点赞,关注!
这一期我们来讲讲map和set的使用,之后的红黑树模拟实现以及map和set的封装做铺垫
1、引言
在C++标准模板库(STL)中,map和set是两种非常重要的关联容器,它们基于红黑树实现,提供了高效的查找、插入和删除操作。
关联容器是C++标准模板库(STL)中的一类重要容器,它们与序列容器(如vector、list等)不同,不是通过位置来存储和访问元素,而是通过键(key)来高效地组织和管理数据。
关联式容器逻辑结构通常是非线性结构, 两个位置有紧密的关联关系,交换⼀下,他的存储结构就被破坏了。这类容器查找效率一般都很高,可以达O(logN)或以上。本期的set和map都是关联容器,我们通过键值key来排序,访问内容。其中set存储的是单独的键值,而map存储的是键值对。键值和键值对就分别对应我们之前提到的key和key_value。
2、set系列的使用
之所以叫set系列,是因为这部分包含set和multiset两个容器,他们的不同是set允许重复值,而multiset不支持重复值。在学习之前,我们可以把set理解为可以自动排序的容器,对于容器内的值,我们使用迭代器遍历它总是成升序的。
2.1、set的主要特性
-
唯一性:set中的元素都是唯一的,不允许重复
-
自动排序:元素插入后会自动排序
-
不可修改元素:set中的元素是const的,不能直接修改
-
高效的查找操作:基于红黑树实现,查找时间复杂度为O(log n)
2.2、 set容器的插入
我们包一下set的头文件,然后新建一个set容器,接着在set容器中插入三个元素:
#include<iostream>
#include<set>
using namespace std;
int main()
{set<int> s;s.insert(10);s.insert(15);s.insert(20);return 0;
}
当然set在C++11之后支持范围插入和初始化列表了:
vector<int> vec = {2, 4, 6, 8};
set<int> mySet;
mySet.insert(vec.begin(), vec.end());//范围插入
set<int> s={1,2,3,4};//初始化列表
尖括号里是我们想要存储的值的类型,对于这个值类型,他必须支持<的比较。基础的编译器自带的int,char,double等类型以及常用的string类型编译器都支持<比较。但是对于我们自定义类型,必须自己实现仿函数对他进行比较。
#include<iostream>
#include<set>
using namespace std;
struct node
{node(int a,int b):x(a),y(b){}int x;int y;
};
template<class node>
struct A
{bool operator()(node a, node b) const{return a.y< b.y;}
};
int main()
{set<pair<int,int>> s;s.insert({ 4,2 });s.insert({ 2,2 });s.insert({ 3,2 });s.insert({ 5,6 });s.insert({ 6,8 });s.insert({ 7,9 });for (auto e : s){cout << e.first << " ";}cout << endl;set<node,A<node>> s1;s1.insert({1,2});s1.insert({ 1,1 });s1.insert({ 1,6 });s1.insert({ 1,4 });s1.insert({ 1,3 });for (auto e : s1){cout << e.y << " ";}return 0;
}
pair类型自带的有<类型比较,pair类型的比较是按照字典序来的,首先按照first的值进行排序,如果first的值相等再按照second的值进行比较。上面的代码我们就支持了自定义类型的比较。
把仿函数里面的<改成>他就变成升序了。
输出结果:
2.3、set的删除
我们使用一下删除接口:
#include<iostream>
#include<set>
using namespace std;int main()
{set<int> s;s.insert(1);s.insert(2);s.insert(3);s.insert(4);s.insert(5);s.insert(6);for (auto e : s){cout << e << " ";}cout << endl;s.erase(2);s.erase(s.begin());//删除接口支持迭代器for (auto e : s){cout << e << " ";}return 0;
}
输出结果:
2.4、set的查找
set的查找返回的是迭代器:
#include<iostream>
#include<set>
using namespace std;int main()
{set<int> s;s.insert(1);s.insert(2);s.insert(3);s.insert(4);s.insert(5);s.insert(6);auto it = s.find(5);cout << *it << endl;return 0;
}
2.5、遍历set
set支持迭代器遍历和范围for遍历。
#include<iostream>
#include<set>
using namespace std;int main()
{set<int> s;s.insert(1);s.insert(2);s.insert(3);s.insert(4);s.insert(5);s.insert(6);for (auto e : s){cout << e << " ";}cout << endl;auto it = s.begin();while (it != s.end()){cout << *it << " ";it++;}return 0;
}
到目前位置我们应该可以感受到set使用这一块很“无聊”。和之前的容器在使用上区别不大。
接下来我们看个稍微有那么一点点意思的代码:
#include<iostream>
#include<set>
using namespace std;int main()
{set<int> s;s.insert(1);s.insert(2);s.insert(3);s.insert(4);s.insert(5);s.insert(6);for (auto e : s){e += 1;cout << e << " ";}cout << endl;auto it = s.begin();while (it != s.end()){*it += 1;cout << *it << " ";it++;}return 0;
}
首先告诉大家这串代码会编译报错,*it+=1会编译报错,因为我们之前说过set里面的值不支持更改。我们迭代器返回的是const迭代器,所以说不支持更改值。 但问题是为什么范围for中e可以+=1,并且打印结果确实达到我们的目的了呢?
不卖关子了直接告诉大家,其实这也很无聊没什么意思,就是我们范围for写的是auto e:s,那么对于这个e其实是拷贝了set中的每一个值,然后我们再对这个拷贝下来的值进行+=1.看似更改了set中的值,实际上set中的值并没有改变。
2.6、set的容量查询
这个和之前容器也没什么区别。
#include<iostream>
#include<set>
using namespace std;int main()
{set<int> s;s.insert(1);s.insert(2);s.insert(3);s.insert(4);s.insert(5);s.insert(6);cout<<s.empty()<<endl;//0cout << s.size() << endl;//6return 0;
}
3、multiset
首先说明,multiset和set在同一个头文件中,所以我们不需要包其他的头文件。multiset和set主要的区别就是multiset支持重复元素:
#include<iostream>
#include<set>
using namespace std;int main()
{multiset<int> s;s.insert(1);s.insert(2);s.insert(2);//重复元素s.insert(3);s.insert(4);s.insert(4);s.insert(5);for (auto e : s){cout << e << " ";}cout << endl;return 0;
}
输出结果:
那么基于set不支持重复元素的特性,我们经常使用set进行去重的操作。当然去重也可以用算法库的unique,但是我个人感觉不如set用着顺手。
除此之外还有一些区别:
3.1、insert返回值不同
set的insert返回值为pair<iterator,bool>,如果一个元素已经存在了就会插入失败,返回已经存在的元素的迭代器和false。
而由于multiset允许重复元素的特性,他不会插入失败,他一直会返回新插入元素位置的迭代器。
auto it = ms.insert(2); // 总是成功
3.2、count和find不同
在set中,count只能返回0或1,find返回查找元素位置的迭代器,如果没有该元素返回end(),而multiset中count可能是任意非负整数,而find返回的是正向遍历第一次出现的位置的迭代器。
set<int> s = {1,2,3};
cout << s.count(2); // 输出1multiset<int> ms = {1,2,2,3};
cout << ms.count(2); // 输出2
3.3、erase不同
multiset一次性会删除所有符合元素,而set只会删除一个元素(如果存在)。如果存在该元素返回true,如果不存在该元素(删除失败)返回false。
4、map
map是一种关联容器,存储键值对(key-value pairs),其中键是唯一的,且元素按照键的顺序进行排序。
4.1、map的主要特性
-
键值对存储:每个元素都是一个pair<const Key, T>
-
键的唯一性:每个键只能在map中出现一次
-
自动排序:元素按键的顺序自动排序
-
高效的查找操作:基于红黑树实现,查找时间复杂度为O(log n)
4.2、map的基本操作
4.2.1、map的插入
首先由于map插入的时候需要插入两个值,key和value,所以说有很多种插入方式,我来介绍一下主流的几个插入方法:
map<string, int> mp;mp.insert(pair<string,int>("apple",5));//临时对象插入法mp.insert({ "pear",4 });//C++11花括号插入法mp.emplace("orange", 6);//C++11emplace直接构建,避免构建临时对象mp["banana"] = 6;//下标访问插入,后面会详细介绍
除了这四个以外,我们还可以在构建是初始化:
map<string, int> mp = {{"apple",5},{"pear",4}};
4.2.2、map元素的访问
访问元素的方式有很多种,我们可以使用find来找到特定的元素(key),然后通过返回的迭代器访问其value,也可以改变value值,但注意不能改变key值:
#include<iostream>
#include<map>
#include<string>
using namespace std;int main()
{map<string, int> mp = {{"apple",5},{"pear",4}};auto it=mp.find("apple");//如果apple不存在,则返回end(),解引用会报错。cout << it->second << endl;//5it->second = 10;cout << it->second << endl;//10//it->first += "x";报错return 0;
}
其次我们可以使用方括号访问:
#include<iostream>
#include<map>
#include<string>
using namespace std;int main()
{map<string, int> mp = {{"apple",5},{"pear",4}};cout << mp["pear"] << endl;//4return 0;
}
同时方括号也可以进行插入值。如果方括号中的元素不存在,则会向mp中插入该值,并返回插入的默认value值0:
#include<iostream>
#include<map>
#include<string>
using namespace std;int main()
{map<string, int> mp = {{"apple",5},{"pear",4}};cout << mp["p"] << endl;//0return 0;
}
4.2.3、删除元素
删除元素可以传迭代器,也可以传key值。
myMap.erase("Bob"); // 删除键为"Bob"的元素
myMap.erase(myMap.begin()); // 删除第一个元素
4.2.4、容量查询
和set没什么不同。
if (myMap.empty()) {cout << "Map is empty" << endl;
}
cout << "Map size: " << myMap.size() << endl;
map同样要求插入元素类型至少支持<比较,和set同理,在这我就不重复写了。
4.2.5、find和count
首先说find,有一点需要特别注意,就是我们的find只能根据key值进行查找:
#include<iostream>
#include<map>
#include<string>
using namespace std;int main()
{map<string, int> mp = {{"apple",5},{"pear",4}};auto it=mp.find("pear");cout << it->second << endl;mp.find({ "pear",4 });cout << it->second<< endl;mp.find({ "pear",5 });cout << it->second << endl;return 0;
}
以上代码输出结果都是4,因为我们无论传什么进去他都是根据key值找的,对于value并不关心。
其次count统计的是符合key值的元素个数。 只能返回0或1。
我们来看下面这串代码,虽然输出结果是0和1,但是这不代表map中的count不是只按照key值进行比较的。第一个之所以是0,是因为我们花括号里的值隐式类型转换成了pair,而pair对象和我们的string是对应不上的,所以找不到,返回0。
#include<iostream>
#include<map>
#include<string>
using namespace std;int main()
{map<string, int> mp = {{"apple",5},{"pear",4},};int num1 = mp.count({ "pear" ,2});int num2 = mp.count("pear");cout << num1 << endl;//0cout << num2 << endl;//1return 0;
}
5、multimap
同样,他也是支持重复key元素版本的map。这一特点我不再多说了,说说其他的不同。
5.1、元素访问方式
multimap不支持[]访问,必须使用迭代器进行访问:
multimap<int, string> mm;
// mm[1] = "Apple"; // 错误!不能这样使用
mm.insert({1, "Apple"});
5.2、查找和计数
multimap的count会返回符合key值的值的数量。
map<int, string> m = {{1,"A"}, {2,"B"}};
cout << m.count(1); // 输出1multimap<int, string> mm = {{1,"A"}, {1,"B"}, {2,"C"}};
cout << mm.count(1); // 输出2
multimap的count也是只按照key进行统计:
#include<iostream>
#include<map>
#include<string>
using namespace std;int main()
{multimap<string, int> mp = {{"apple",5},{"pear",4},{"pear",5},{"pear",6}};int num1 = mp.count({ "pear" ,4});int num2 = mp.count("pear");cout << num1 << endl;//3cout << num2 << endl;//3return 0;
}
multimap的find会返回第一个符合key值的元素的迭代器。
#include<iostream>
#include<map>
#include<string>
using namespace std;int main()
{map<string, int> mp = {{"apple",5},{"pear",4},{"pear",5},{"pear",6}};auto it = mp.find("pear");cout << it->second << endl;//4return 0;
}
5.3、获取范围
multimap
特有的equal_range()
方法可以获取所有相同键的元素范围:
multimap<int, string> mm = {{1,"A"}, {1,"B"}, {2,"C"}};
auto range = mm.equal_range(1);
for (auto it = range.first; it != range.second; ++it) {cout << it->second << " "; // 输出A B
}
5.4、删除操作
相比map,multimap删除的是所有符合key值的元素。erase接口中只能传key值,如果传key_value的pair临时对象会显示读取无效数据。达不到删除元素的目的。
好了,到这里map和set的使用我们就讲完了,下一期我们开始模拟实现map和set底层的红黑树,更进一步理解map和set的工作机制,我们下期再见!
相关文章:
C++修炼:map和set的使用
Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路! 我的博客:<但凡. 我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 欢迎点赞,关注&am…...
ABC 355
D. Intersecting Intervals 首先思考两个区间相交会有哪些情况:有两种左右端点包含,一种大区间包含小区间。 但是反过来思考,两个区间不相交只会有两种情况:Ri < Lj 和 Rj < Li。非常典型的逆向思考 对左右端点升序排序后&a…...
正则表达式进阶(三):递归模式与条件匹配的艺术
在正则表达式的高级应用中,递归模式和条件匹配是处理复杂嵌套结构和动态模式的利器。它们突破了传统正则表达式的线性匹配局限,能够应对嵌套括号、HTML标签、上下文依赖等复杂场景。本文将详细介绍递归模式((?>...)、 (?R) 等࿰…...
芯片分享之AD5542性能介绍
产品特征: AD5541/AD5542均为单通道、16位、串行输入、电压输出数模转换器(DAC),采用2.7 V至5.5 V单电源供电。DAC输出范围为0 V至VREF DAC输出范围为0 V至VREF,保证单调性,提供1 LSB INL精度(16位)&…...
从零开始:Python 从0到1轻松入门
你是否曾好奇,那些能自动处理数据、搭建网站、甚至预测未来趋势的神奇程序是如何诞生的?答案或许就藏在 Python 这门简洁而强大的编程语言中!Python以其“代码即可读性”的设计哲学,成为全球开发者的心头好——无论是初学者入门&a…...
Linux线程互斥与同步(上)(29)
文章目录 前言一、资源共享问题多线程并发访问临界区与临界资源“锁”概念引入 二、多线程抢票并发抢票引发问题 三、线程互斥互斥锁相关操作解决抢票问题互斥锁的原理多线程封装互斥锁的封装 总结 前言 马上要结束了!!! 我们在学习 多线…...
深入解析 hping3网络探测与测试利器
一、什么是 hping3? 体量轻巧:安装包仅约 255 KB。协议多样:支持 TCP、UDP、ICMP、RAW IP 四种模式。灵活定制:可设置任意报文头、分片、Payload 长度;还支持伪造源地址、随机目标等高级操作。脚本化:集成…...
SPA模式下的es6如何加快宿主页的显示速度
SPA的模式下,宿主页是首先加载的页面,会需要一些主要的组件,如element-plus,easyui,devextreme,ant-design等,这些组件及其依赖组件,文件多,代码量大,可能导致…...
环境配置!
1.下载openEuler虚拟机和rocky虚拟机 下载好后,ping一下看一下手动配置的网络ok不,再把复杂密码改成自己能记住的简单密码 2.安装软件 下载yum源 也可以用阿里云的yum源 把里面的:%d全删了,然后把 #generic-repos is licensed …...
【VS Code】Qt程序的调试与性能分析
要对 Qt 程序进行性能分析和调试,尤其是使用像 Valgrind、Perf 或 GDB 这类工具时,通常需要结合开发环境(如 VS Code)与相关插件或命令行工具。 以下是一些常用的方法和步骤: 1. VS Code 调试 Qt 程序 所需配置&…...
记录学习的第三十六天
很久没写过博客了,今天又开始了。 今天很不错,了解了查分数组的实质。 还是做了一道滑动窗口的题,我什么时候才能刷完滑动窗口啊。...
ANSI V 级对夹球阀控制阀:高性价比零泄漏流体控制新选择-耀圣
ANSI V 级对夹球阀控制阀:高性价比零泄漏流体控制新选择 在化工、食品、给排水等工业领域,流体控制的精准性与密封性直接关乎生产安全与效率。ANSI V 级对夹球阀控制阀凭借零泄漏密封性能(ANSI VI 级标准)、紧凑的对夹式结构、亲…...
pcdn核心要素
开展PCDN业务最核心的是明确业务定位、保障网络与硬件基础、确保合规运营,并选择合适的盈利模式。以下是具体要点: 1. 明确业务定位与目标 内容类型适配:PCDN适合高并发、大流量的内容分发场景,如视频直播、点播、大文件下载等。…...
数据分析_主播考核指标体系搭建
作为一名合格的数据分析师,要同时具备逻辑框架搭建能力以及解决实际问题的经验。通过指标量化问题、监控业务健康度并驱动决策。以下是我搭建抖音电商主播考核指标体系时的一些经验,希望对大家有些帮助。 搭建主播能力考核指标体系需要结合直播业务的核心…...
联合索引失效情况分析
一.模拟表结构: 背景: MySQL版本——8.0.37 表结构DDL: CREATE TABLE unite_index_table (id bigint NOT NULL AUTO_INCREMENT COMMENT 主键,clomn_first varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMEN…...
ZYNQ Cache一致性问题解析与实战:从原理到创新优化
一、Cache一致性:多核系统的"记忆迷宫" 1.1 为什么需要关注Cache一致性? 在Zynq-7000系列SoC的双核ARM Cortex-A9架构中,每个CPU核心拥有32KB L1数据Cache和512KB共享L2 Cache。当两个核心同时操作共享内存时,可能会出现: #mermaid-svg-RD2USaYdR7mMPPIA {fon…...
vtkPiecewiseFunction
1. 定义分段函数映射。 2.允许添加控制点,并允许用户控制控制点之间的功能。 3.基于锐度和中点参数,在控制点之间使用分段hermite曲线。 4.锐度为0产生分段线性函数,锐度为1产生分段常数函数。 5.中点是曲线达到Y中值的控制点之间的归一化距离…...
HarmonyOS NEXT~鸿蒙系统与mPaaS三方框架集成指南
HarmonyOS NEXT~鸿蒙系统与mPaaS三方框架集成指南 1. 概述 1.1 鸿蒙系统简介 鸿蒙系统(HarmonyOS)是华为开发的分布式操作系统,具备以下核心特性: 分布式架构:支持跨设备无缝协同微内核设计:提高安全性和性能一次开…...
【老马】流程引擎(Process Engine)概览
前言 大家好,我是老马。 最近想设计一款审批系统,于是了解一下关于流程引擎的知识。 下面是一些的流程引擎相关资料。 工作流引擎系列 工作流引擎-00-流程引擎概览 工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎&#x…...
基于ROS2/Gazebo的室内送餐机器人系统开发实战教程
1. 系统架构设计 1.1 功能需求分析 #mermaid-svg-Yht1n03rcf5MP4du {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Yht1n03rcf5MP4du .error-icon{fill:#552222;}#mermaid-svg-Yht1n03rcf5MP4du .error-text{fill:…...
msq基础
一、检索数据 SELECT语句 1.检索单个列 SELECT prod_name FROM products 上述语句用SELECT语句从products表中检索一个名prod_name的列,所需列名在SELECT关键字之后给出,FROM关键字指出从其中检索数据的表名 (返回数据的顺序可能是数据…...
威纶通触摸屏IP地址设定步骤及程序下载指南
在使用威纶通触摸屏时,正确设定IP地址以及完成程序下载是确保其正常运行和实现功能的关键步骤。本文将详细介绍威纶通触摸屏IP地址设定步骤及程序下载的方法。 一、IP地址设定步骤 (一)前期准备 确保威纶通触摸屏已经通电并启动࿰…...
全排列问题深度解析:为何无需index参数且循环从i=0开始?
文章目录 问题背景一、为何回溯函数不需要 index 参数?1. 全排列问题的核心特性2. index 的作用与局限性3. 正确设计:用 used[] 替代 index 二、为何循环从 i0 开始而非 index?1. 排列问题的顺序敏感性2. 对比组合问题的循环设计3. 关键区别总…...
计算机网络通信技术与协议(七)———关于ACL的详细解释
今日学习状态: 关于ACL,我们在之前的博文中有简要的提及到,今天我们将ACL作为一个专题进行讲解: 目录 ACL成立背景: ACL(Access Control List,访问控制列表): 五元组…...
《算法笔记》11.8小节——动态规划专题->总结 问题 D: Coincidence
题目描述 Find a longest common subsequence of two strings. 输入 First and second line of each input case contain two strings of lowercase character a…z. There are no spaces before, inside or after the strings. Lengths of strings do not exceed 100. 输出…...
power BI 倒计时+插件HTML Content,实现更新倒计时看板!
直接拿去玩吧,花了我两个小时。 搜了b站和百度都没找到像样的,就决定自己干一个了。 先看效果: 起个度量值,然后去power bi 插件那边搜索html Content,把这个放进html content插件的字段values即可。 HTML倒计时每周…...
镜像管理(2)Dockerfile总结
一、docker镜像构建方法 commoit :使用 docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑 箱镜像,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根 本无从得知。而且,即使是这个制作镜像的人,过一段时间后也无法记清具…...
【Tools】neovim操作指南
Neovim 中最常见、最实用的操作, 主要针对C 开发需求: 🚀 基础操作 操作快捷键说明保存:w 或 ZZ保存当前文件退出:q 或 ZQ退出当前窗口保存并退出:wq 或 ZZ保存并退出强制退出:q!不保存直接退出撤销u撤销上一步重做<C-r>重做撤销搜索/xxx向下搜索…...
docker 安装 Nacos
下载镜像 docker pull nacos/nacos-server创建本地目录 mkdir -p /home/nacos/conf /home/nacos/logs运行镜像 docker run -d -p 8848:8848 -e MODEstandalone -e PREFER_HOST_MODEhostname -v /home/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties …...
【嵌入式】【ESP32】ADF框架
推荐阅读: [005] [ESP32开发笔记] ADF基本框架...
Redisson分布式集合原理及应用
Redisson是一个用于Redis的Java客户端,它简化了复杂的数据结构和分布式服务的使用。 适用场景对比 数据结构适用场景优点RList消息队列、任务队列、历史记录分布式共享、阻塞操作、分页查询RMap缓存、配置中心、键值关联数据支持键值对、分布式事务、TTLRSet去重集…...
一种新兴的网络安全技术:XDR(Extended Detection and Response,扩展检测与响应)(Grok3 DeepSearch模式下回答)
直接回答 XDR(扩展检测与响应)是一种网络安全技术,整合多层数据(如端点、网络、云)以检测和响应威胁。研究表明,它通过AI和自动化提高安全团队效率,减少数据泄露成本。存在原生XDR(…...
使用 Qt Designer 开发
Qt Designer 是属于 Qt Creator 的 一个功能而已,Qt Designer 也叫 UI 设计师或者 UI 设计器,这都是指的同一 个东西而已。 一、在ui文件添加一个按钮 1、新建一个项目 项目名为 02_designer_example 构建系统可选择 CMake , qmake, Qbs 对…...
第7天-Python+PyEcharts实现股票分时图实战教程
分时图是金融领域常用的可视化形式,能够清晰展示价格随时间变化的趋势。本教程将手把手教你用PyEcharts库实现专业级分时图效果。 一、环境准备 bash 复制 下载 pip install pyecharts # 核心可视化库 pip install pandas # 数据处理支持 二、基础分时图实现 1. 模拟…...
Zenmap代理情况下无法扫描ip
原因是开了代理会报错 error “only ethernet devices can be used for raw scans on Windows” 在扫描参数后加 -sT -Pn,但会导致结果太多 例如:nmap -sT -T4 -A -v -Pn 10.44.2.0/24 如果你只是想找没人用的IP,你不需要搞复杂的原始层扫描&…...
JAVA打飞机游戏设计与实现(论文+源代码)【源码+文档+部署】
1 绪论 1.1 手机软件现状 在信息社会中,手机及其他无线设备越来越多的走进普通百姓的工作和生活,随着信息网络化的不断进展,手机及其他无线设备上网络势在必行。但是传统手机存在以下弊端: 1. 传统手机出厂时均由硬件厂商固化…...
C++学习:六个月从基础到就业——多线程编程:std::thread基础
C学习:六个月从基础到就业——多线程编程:std::thread基础 本文是我C学习之旅系列的第五十四篇技术文章,也是第四阶段"并发与高级主题"的第一篇,介绍C11引入的多线程编程基础知识。查看完整系列目录了解更多内容。 引言…...
深入理解指针(一)
1.内存和地址 2.指针变量和地址 3.指针变量类型的意义 4.指针运算 1. 内存和地址 1.1 内存 在讲内存和地址之前,为了大家更好的理解举了这么个例子: 假如有一栋教学楼,刚好你今天在这栋楼的某一个课室上课,已知这栋楼有50个…...
添加currentSchema后,该模式下表报不存在(APP)
文章目录 环境文档用途详细信息相关文档 环境 系统平台:Linux x86-64 Red Hat Enterprise Linux 7 版本:4.5.7 文档用途 解决程序URL添加currentSchema后,访问该模式下的表,报错信息com.highgo.jdbc.util.PSQLException: ERROR…...
Python数据整合与转换全攻略
在大数据时代,企业平均使用16个不同数据源,但数据利用率不足30%。数据整合与转换能力已成为数据工程师的核心竞争力。本文将通过电商订单数据整合实战,系统讲解Python数据整合与转换的核心技术栈。 一、数据整合的三大挑战与应对策略 1. 数…...
ArcGIS操作16:添加经纬网
1、单击视图 > 数据框属性 2、单击格网选项卡 > 新建格网按钮 3、创建经纬网 4、经纬网标注间隔需要自己多次尝试,选择一个合适的值,这里江苏省选择50 5、继续设置合适的参数 6、点击应用,预览是否合适(不合适再新建一个经…...
BioID技术:探索蛋白质相互作用的新方法
在细胞的复杂环境中,蛋白质并非孤立地执行其功能,而是通过与其他蛋白质相互协作来完成各种生物学过程。理解蛋白质相互作用网络对于揭示细胞机制和疾病发生发展具有至关重要的意义。近年来,一种名为BioID(Biotin Identification&a…...
Java 大视界——Java大数据在智慧交通智能停车诱导系统中的数据融合与实时更新
智慧交通的快速发展对城市停车资源的高效利用提出了更高要求,而智能停车诱导系统作为缓解“停车难”问题的核心手段,亟需解决多源数据融合、实时状态更新及高并发访问等挑战。Java凭借其稳定的大数据生态、卓越的实时计算能力及跨平台兼容性,…...
【Redisson】快速实现分布式锁
大家好,我是jstart千语。之前给大家分享过使用redis的set nx ex命令实现分布式锁。但手动的实现方式不仅麻烦,而且不好管理。实现出来的锁也是不可重入的,不可重试的。那么在要求比较高的系统中,就不太适用了。虽然说重入问题可以…...
内核常见面试问题汇总
1、Linux 中主要有哪几种内核锁?它们各自的特点和适用场景是什么? 自旋锁 自旋锁是一种忙等待锁,当一个线程试图获取一个被占用的自旋锁时,他会一直循环在那里,不断地检查锁是否可用,而不会进入睡眠状态。 自旋锁的优点这是在锁被持有的时间很短的情况下,性能非常高,…...
laravel中如何使用Validator::make定义一个变量是 ,必传的,json格式字符串
在 Laravel 中,使用 Validator::make 定义一个变量为必传且为JSON 格式字符串时,可以通过以下方式实现: use Illuminate\Support\Facades\Validator;$validator Validator::make($request->all(), [your_field > required|json, // 必…...
【全解析】EN18031标准下的NMM网络监控机制
上一篇文章我们了解了RLM机制如何为设备抵御DoS攻击保驾护航,今天我们将目光转向 EN18031 标准中的另一个重要防线——NMM(Network Monitoring Mechanism)网络监控机制。 NMM - 1规定,如果设备是网络设备,应提供网络监…...
浏览器开发随笔
浏览器多进程架构(Chrome) ----------------------------- | Browser Process | |-----------------------------| | UI 线程、主控、导航、安全策略 | -----------------------------| | |↓ ↓ ↓ -------…...
漏洞类型与攻击技术
1.1 SQL注入 1.1.1 SQL注入简介与原理 SQL注入是通过用户输入的数据中插入恶意SQL代码,绕过应用程序对数据库的合法操作,进而窃取、篡改或删除数据的攻击方式。核心原理是应用程序未对用户输入进行严格过滤,导致攻击者可以操控SQL语句逻辑。 1.1.2 联合查询注入与报…...
day018-磁盘管理-案例
文章目录 1. 磁盘分区1.1 手动磁盘分区1.2 重装系统,保留分区1.2.1 选择从光盘启动1.2.2 保留系统盘分区1.2.3 挂载数据盘 2. 物理服务器使用流程3. swap3.1 增加swap3.2 关闭swap 4. 故障案例(红帽类系统)4.1 root密码忘记,重新设…...