突破编程_C++_C++11新特性(unordered_multimap)
1 概述
std::unordered_multimap 是一个哈希表实现的无序容器,它存储的元素是键值对,并且允许键的重复。这意味着同一个键可以关联多个值。在 std::unordered_multimap 中,元素的插入顺序是不确定的,并且不会因为元素的插入、删除或查找而改变。
std::unordered_multimap 与 std::multimap 的主要区别如下:
- std::multimap 也是一个关联容器,它存储的元素也是键值对,并且同样允许键的重复。但是,std::multimap 的内部实现是基于红黑树这种有序数据结构,因此它存储的元素是按键的升序(或降序,取决于比较函数的定义)排列的。而 std::unordered_multimap 则不保证元素的任何顺序,它主要关注的是高效的查找、插入和删除操作。
- 在性能上,std::unordered_multimap 的查找、插入和删除操作的时间复杂度通常接近 O(1),这是因为它使用了哈希表这种数据结构。而 std::multimap 的这些操作的时间复杂度则是 O(log n),因为它基于红黑树实现。因此,当对性能有较高要求,且不需要元素有序时,std::unordered_multimap 可能会是一个更好的选择。
std::unordered_multimap 的实现基于哈希表。哈希表是一种数据结构,它使用哈希函数将键映射到数组的索引,从而可以在常数时间内找到键对应的值。在 std::unordered_multimap 中,由于允许键的重复,所以每个哈希表槽位可能对应一个链表或其他动态数组结构,用于存储具有相同哈希值的键值对。
当插入一个元素时,首先计算键的哈希值,然后使用该哈希值找到数组中的对应槽位。如果槽位为空,则直接在该槽位插入新的键值对。如果槽位已有元素,则将新的键值对添加到对应的链表或动态数组中。
查找和删除操作也类似,首先计算键的哈希值找到对应的槽位,然后在槽位对应的链表或动态数组中查找或删除指定的键值对。
需要注意的是,哈希表的性能在很大程度上取决于哈希函数的质量。一个好的哈希函数应该能够将键均匀地映射到数组的各个槽位,以减少哈希冲突的发生。
2 声明与初始化
2.1 声明
首先,需要包含 <unordered_map> 头文件,然后声明一个 std::unordered_multimap 变量,并指定键和值的类型。
#include <unordered_map> std::unordered_multimap<KeyType, ValueType> mapName;
其中 KeyType 是键的类型,ValueType 是值的类型,mapName 是你为该 unordered_multimap 变量选择的名称。
2.2 初始化
初始化 std::unordered_multimap 可以通过多种方式进行,包括默认初始化、使用列表初始化器初始化、复制初始化、移动初始化等。
(1)默认初始化
如果没有提供任何初始化器,std::unordered_multimap 将被默认初始化,这意味着它将不包含任何元素,并且会使用默认的哈希函数和键相等性比较对象。
std::unordered_multimap<std::string, int> myMultimap; // 默认初始化
(2)使用列表初始化器初始化
可以使用列表初始化器(大括号 {})来初始化 std::unordered_multimap,并直接添加一些元素。
std::unordered_multimap<std::string, int> myMultimap = { {"apple", 1}, {"banana", 2}, {"apple", 3} // 注意:允许相同的键
};
在这个例子中,myMultimap 初始时包含三个元素,其中有两个元素具有相同的键 “apple”。
(3)注意事项
- std::unordered_multimap 不保证元素的顺序,因此不应该依赖特定的插入顺序。
- 插入到 std::unordered_multimap 中的键可以重复。
- 如果键类型没有提供默认的哈希函数和相等性比较对象,则需要提供自定义的实现(后面会详细讲解)。
3 插入元素
3.1 插入方法
(1)使用 insert 成员函数
std::unordered_multimap 提供了一个 insert 成员函数,用于向容器中插入元素。该函数接受一个键值对,并将其添加到容器中。如果容器中已经存在具有相同键的元素,insert 函数仍然会插入新的键值对,因为 std::unordered_multimap 允许键的重复。
插入单个键值对
可以使用 insert 函数插入单个键值对。这通常通过创建一个 std::pair 对象来实现,其中第一个元素是键,第二个元素是值。
#include <unordered_map>
#include <string> int main()
{ std::unordered_multimap<std::string, int> myMultimap; // 插入单个键值对 myMultimap.insert(std::make_pair("apple", 10)); // 也可以直接使用花括号初始化列表来构造 pair 对象 myMultimap.insert({"banana", 20}); return 0;
}
这个例子创建了一个 std::unordered_multimap 对象 myMultimap,并使用 insert 函数插入了两个键值对。第一个键值对是 (“apple”, 10),第二个键值对是 (“banana”, 20)。
插入多个键值对
也可以使用初始化列表一次性插入多个键值对。
#include <unordered_map>
#include <string> int main()
{ std::unordered_multimap<std::string, int> myMultimap; // 插入多个键值对 myMultimap.insert({ {"apple", 10}, {"banana", 20}, {"orange", 30} }); return 0;
}
在这个例子中,使用初始化列表一次性插入了三个键值对。
(2)使用迭代器插入
insert 函数还有一个重载版本,它接受一个迭代器和一个键值对,尝试在迭代器指向的位置插入元素。如果插入成功,函数返回一个指向新插入元素的迭代器;如果插入失败(例如,由于内存不足),则返回一个指向容器中下一个有效位置的迭代器。
#include <unordered_map>
#include <string> int main()
{ std::unordered_multimap<std::string, int> myMultimap; // 插入一个键值对,并获取指向它的迭代器 auto it = myMultimap.insert(myMultimap.begin(), std::make_pair("apple", 10)); return 0;
}
这个例子使用 insert 函数的迭代器版本在容器的开始位置尝试插入一个键值对。返回的迭代器 it 指向新插入的元素。
(3)使用 emplace 成员函数
除了 insert 函数外,std::unordered_multimap 还提供了 emplace 成员函数,它可以在容器内直接构造元素,避免了不必要的复制或移动操作。这对于大型对象或那些复制/移动成本较高的对象特别有用。
#include <unordered_map>
#include <string> struct LargeObject { std::string data; // ... 其他成员和数据 ... LargeObject(const std::string& d) : data(d) { // 构造函数实现 }
}; int main()
{ std::unordered_multimap<std::string, LargeObject> myMultimap; // 使用 emplace 插入元素,直接在容器内构造 LargeObject 对象 myMultimap.emplace("key", "large data"); return 0;
}
这个例子定义了一个名为 LargeObject 的结构,它有一个接受 std::string 的构造函数。我们使用 emplace 函数直接向 myMultimap 中插入一个 LargeObject 对象,避免了先构造对象再复制的额外开销。
3.2 注意事项
- 插入操作的时间复杂度在平均情况下是 O(1),但由于哈希冲突的存在,最坏情况下的时间复杂度可能较高。因此,为了获得最佳性能,应确保键的哈希函数分布均匀,并尽量减少哈希冲突。
- 插入操作可能会导致容器的重新哈希(rehashing),这是一个相对昂贵的操作,因为它涉及到重新分配内存和重新计算所有元素的哈希值。
4 访问元素
4.1 使用迭代器遍历元素
由于 std::unordered_multimap 是一种容器,因此可以使用迭代器来遍历并访问其中的元素。迭代器类似于指针,可以用来访问容器中的元素。
(1)遍历所有元素
可以使用 begin() 和 end() 成员函数来获取指向容器第一个元素和最后一个元素之后位置的迭代器,然后使用这些迭代器遍历容器中的所有元素。
#include <iostream>
#include <unordered_map>
#include <string> int main()
{ std::unordered_multimap<std::string, int> myMultimap = { {"apple", 10}, {"banana", 20}, {"apple", 30}, {"orange", 40} }; // 使用迭代器遍历所有元素 for (auto it = myMultimap.begin(); it != myMultimap.end(); ++it) { std::cout << it->first << ": " << it->second << std::endl; } return 0;
}
这个例子创建了一个 std::unordered_multimap 对象 myMultimap,并使用 begin() 和 end() 获取迭代器来遍历容器中的所有元素。it->first 访问键,it->second 访问值。
(2)遍历具有特定键的所有元素
由于 std::unordered_multimap 允许键的重复,可能需要遍历具有特定键的所有元素。这可以通过结合 equal_range 函数和迭代器来实现。
#include <iostream>
#include <unordered_map>
#include <string> int main() { std::unordered_multimap<std::string, int> myMultimap = { {"apple", 10}, {"banana", 20}, {"apple", 30}, {"orange", 40} }; // 查找键为 "apple" 的所有元素 auto range = myMultimap.equal_range("apple"); for (auto it = range.first; it != range.second; ++it) { std::cout << it->second << std::endl; // 输出值 } return 0;
}
上面代码的输出为:
10
30
在这个例子中,equal_range 返回一个包含两个迭代器的 pair,第一个迭代器指向第一个键为 “apple” 的元素,第二个迭代器指向第一个键不为 “apple” 的元素。通过遍历这个范围来访问所有键为 “apple” 的元素。
4.2 使用 find 函数查找元素
如果只需要查找具有特定键的第一个元素,可以使用 find 函数。如果找到了匹配的元素,find 会返回一个指向该元素的迭代器;如果没有找到,则返回 end() 迭代器。
#include <iostream>
#include <unordered_map>
#include <string> int main() { std::unordered_multimap<std::string, int> myMultimap = { {"apple", 10}, {"banana", 20}, {"apple", 30}, {"orange", 40} }; // 查找键为 "apple" 的第一个元素 auto it = myMultimap.find("apple"); if (it != myMultimap.end()) { std::cout << "Found apple with value: " << it->second << std::endl; } else { std::cout << "Apple not found." << std::endl; } return 0;
}
这个例子使用 find 函数来查找键为 “apple” 的第一个元素。如果找到了,就输出它的值;否则,输出 “Apple not found.”。
5 删除元素
5.1 使用 erase 成员函数删除单个元素
erase 成员函数可以用于删除容器中的单个元素。可以通过传递一个指向要删除元素的迭代器来调用它。
#include <iostream>
#include <unordered_map>
#include <string> int main() { std::unordered_multimap<std::string, int> myMultimap = { {"apple", 10}, {"banana", 20}, {"apple", 30}, {"orange", 40} }; // 假设我们有一个指向要删除元素的迭代器 auto it = myMultimap.find("apple"); // 查找键为 "apple" 的一个元素 if (it != myMultimap.end()) { // 使用 erase 删除找到的元素 myMultimap.erase(it); } // 输出容器内容以验证元素已被删除 for (const auto& pair : myMultimap) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0;
}
上面代码的输出为:
apple: 30
banana: 20
orange: 40
在这个例子中,首先使用 find 函数找到一个键为 “apple” 的元素的迭代器。然后,检查找到的迭代器是否不等于 end(),以确保找到了有效的元素。最后,调用 erase 并传入迭代器来删除该元素。
5.2 使用 erase 成员函数删除删除一系列元素
erase 成员函数还有一个重载版本,它接受两个迭代器作为参数,用于删除一个范围内的所有元素。这在你想要删除具有特定键的所有元素时非常有用。
#include <iostream>
#include <unordered_map>
#include <string> int main()
{ std::unordered_multimap<std::string, int> myMultimap = { {"apple", 10}, {"banana", 20}, {"apple", 30}, {"orange", 40} }; // 查找键为 "apple" 的元素范围 auto range = myMultimap.equal_range("apple"); // 删除范围内的所有元素 myMultimap.erase(range.first, range.second); // 输出容器内容以验证元素已被删除 for (const auto& pair : myMultimap) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0;
}
上面代码的输出为:
banana: 20
orange: 40
这个例子使用 equal_range 函数来获取一个包含所有键为 “apple” 的元素的范围。然后,调用 erase 并传入这个范围的开始和结束迭代器来删除所有这些元素。
5.3 使用 clear 成员函数删除所有元素
如果想要删除 std::unordered_multimap 中的所有元素,可以使用 clear 成员函数。这将移除容器中的所有键值对,并将容器的大小变为 0。
std::unordered_multimap<int, std::string> myMap;
// 假设 myMap 中已经填充了一些元素 myMap.clear(); // 删除所有元素,myMap 现在为空
5.4 遍历删除
在 std::unordered_multimap 中遍历并删除元素时,需要特别小心,因为删除操作会使指向已删除元素的迭代器失效。如果试图使用一个已经失效的迭代器,程序可能会崩溃或产生不可预测的行为。
一种常见的策略是使用迭代器从 begin() 到 end() 遍历容器,并在遍历过程中删除满足特定条件的元素。但是,由于直接删除当前迭代器指向的元素会使迭代器失效,需要在删除前获取下一个迭代器的位置。这可以通过递增当前迭代器来完成,然后在递增之前检查它是否指向要删除的元素。
以下是一个示例,展示如何在遍历 std::unordered_multimap 时删除所有键为 “apple” 的元素:
#include <iostream>
#include <unordered_map>
#include <string> int main()
{ std::unordered_multimap<std::string, int> myMultimap = { {"apple", 10}, {"banana", 20}, {"apple", 30}, {"orange", 40}, {"apple", 50} }; // 使用迭代器遍历并删除键为 "apple" 的所有元素 for (auto it = myMultimap.begin(); it != myMultimap.end(); ) { if (it->first == "apple") { // 删除元素,并使迭代器指向下一个有效元素 it = myMultimap.erase(it); } else { // 如果不删除,则递增迭代器 ++it; } } // 输出容器内容以验证元素已被删除 for (const auto& pair : myMultimap) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0;
}
上面代码的输出为:
banana: 20
orange: 40
这个例子使用了一个 for 循环来遍历 myMultimap。在循环内部,首先检查当前迭代器的键是否为 “apple”。如果是,则调用 erase 来删除该元素,并更新迭代器 it 为 erase 返回的下一个有效迭代器。如果不删除当前元素,就递增迭代器以继续遍历。
注意:erase 成员函数返回指向被删除元素之后的那个元素的迭代器。如果 erase 被调用在最后一个元素上,它将返回 end()。这就是为什么循环条件仍然是 it != myMultimap.end(),因为即使删除了当前元素,it 在更新后仍然可能不是 end()。
这种遍历并删除元素的方法在大多数情况下都是安全的,因为它避免了使用已经失效的迭代器。然而,如果容器在遍历过程中被其他线程修改,那么可能会出现数据竞争。在多线程环境中,应确保适当的同步机制来避免这种情况。
6 使用自定义键类型
std::unordered_multimap 也可以使用自定义键类型。当使用自定义键类型时,需要为该类型定义哈希函数和键相等性比较函数。哈希函数用于将键映射到哈希表中的位置,而键相等性比较函数则用于确定两个键是否相等。
下面是一个示例,展示了如何使用自定义键类型 Person 作为 std::unordered_multimap 的键:
#include <iostream>
#include <unordered_map>
#include <string>
#include <functional> // 用于 std::hash 和 std::equal_to // 自定义键类型
struct Person { Person(const std::string& name, int age) : name(name), age(age) {} // 为了简化示例,这里只根据name字段进行比较和哈希 bool operator==(const Person& other) const { return name == other.name; } std::string name; int age;
}; // 为Person定义哈希函数
struct PersonHash { std::size_t operator()(const Person& p) const { std::size_t h1 = std::hash<std::string>()(p.name); // 可以在这里添加更多字段的哈希计算,如果需要的话 return h1; }
}; // 为Person定义键相等性比较函数
struct PersonEqual { bool operator()(const Person& lhs, const Person& rhs) const { return lhs.name == rhs.name; }
}; int main()
{ // 使用自定义键类型的unordered_multimap std::unordered_multimap<Person, int, PersonHash, PersonEqual> peopleMap; // 插入元素 peopleMap.emplace(Person("Alice", 30), 1); peopleMap.emplace(Person("Bob", 25), 2); peopleMap.emplace(Person("Alice", 30), 3); // 相同的Person对象可以插入多次 // 遍历并打印元素 for (const auto& pair : peopleMap) { std::cout << pair.first.name << ": " << pair.first.age << " -> " << pair.second << std::endl; } return 0;
}
上面代码的输出为:
Alice: 30 -> 1
Alice: 30 -> 3
Bob: 25 -> 2
这个例子定义了一个 Person 结构体,它包含 name 和 age 两个字段。此外还为 Person 定义了哈希函数 PersonHash 和键相等性比较函数 PersonEqual。
在创建 std::unordered_multimap 时,将 Person 作为键类型,并将 PersonHash 和 PersonEqual 作为模板参数传递给 std::unordered_multimap。这样,unordered_multimap 就知道如何为 Person 对象计算哈希值以及如何比较两个 Person 对象是否相等。
注意:在哈希函数和键相等性比较函数中,只考虑了 Person 的 name 字段。在实际情况中,可能需要根据 Person 的所有字段来计算哈希值和比较相等性,以确保正确的行为。特别是当两个 Person 对象具有相同的 name 但不同的 age 时,只根据 name 进行哈希和比较可能会导致意外的行为。
相关文章:
突破编程_C++_C++11新特性(unordered_multimap)
1 概述 std::unordered_multimap 是一个哈希表实现的无序容器,它存储的元素是键值对,并且允许键的重复。这意味着同一个键可以关联多个值。在 std::unordered_multimap 中,元素的插入顺序是不确定的,并且不会因为元素的插入、删除…...
15.WEB渗透测试--Kali Linux(三)
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于: 易锦网校会员专享课 上一个内容:14.WEB渗透测试--Kali Linux(二)-CSDN博客 Kali工具使用 3389远…...
Android-Framework pm list packages和pm install返回指定应用信息
一、环境 高通 Android 13 注:Android10 和Android13有些差异,代码位置不变,参照修改即可 二、pm简单介绍 pm工具为包管理(package manager)的简称 可以使用pm工具来执行应用的安装和查询应用宝的信息、系统权限、…...
CSS
什么是CSS? CSS是一门语言,用于控制网页表现 CSS(Cascading Style Sheet):层叠样式表 W3C标准:网页主要由三部分组成 结构:HTML表现:CSS行为:JavaScript CSS导入方式…...
算法详解——选择排序和冒泡排序
一、选择排序 选择排序算法的执行过程是这样的:首先,算法遍历整个列表以确定最小的元素,接着,这个最小的元素被置换到列表的开头,确保它被放置在其应有的有序位置上。接下来,从列表的第二个元素开始&#x…...
图论(蓝桥杯 C++ 题目 代码 注解)
目录 迪杰斯特拉模板(用来求一个点出发到其它点的最短距离): 克鲁斯卡尔模板(用来求最小生成树): 题目一(蓝桥王国): 题目二(随机数据下的最短路径&#…...
矩阵起源新一年喜报连连!
新春伊始 矩阵起源向大家分享 一连串好消息 首先,公司创始人兼CEO王龙先生获评“2023深圳创新突出贡献人物“。这一荣誉是对其在推动数据库行业技术创新和产品开发方面所做出的卓越贡献的认可。他的领导力和创新精神不仅引领我司取得了显著的成就,也为…...
牛客——紫魔法师(并查集)
链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 “サーヴァント、キャスター、Medea。”--紫魔法师 给出一棵仙人掌(每条边最多被包含于一个环,无自环,无重边,保证连通),要求用最少的…...
最新WooCommerce教程指南-如何搭建B2C外贸独立站
WooCommerce是全球最受欢迎的开源电子商务平台之一。它基于WordPress建站,只需一键安装即可使用。该平台提供了丰富的功能,包括产品发布、库存管理、支付网关和运输发货等,可以帮助搭建各种类型的电子商务网站。相比其他竞争对手,…...
一文教会你SpringBoot是如何启动的
SpringBoot启动流程分析 流程图 源码剖析 运行Application.run()方法 我们在创建好一个 SpringBoot 程序之后,肯定会包含一个类:xxxApplication,我们也是通过这个类来启动我们的程序的(梦开始的地方),而…...
车载测试面试:各大车企面试题汇总
本博主可协助大家成功进军车载测试行业 TBOX 深圳 涉及过T-BOX测试吗Ota升级涉及的台架环境是什么样的?上车实测之前有没有一个仿真环境台架环境都什么零部件T-BOX了解多少Linux和shell有接触吗 单片机uds诊断是在实车上座的吗 uds在实车上插的那口 诊断仪器是哪…...
Qt散文一
Qt的事件分为普通事件和系统事件,普通事件比如用户按下键盘,系统事件比如定时器事件。事件循环的开始是从main函数的QApplication,然后调用exec()开始的,在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件…...
MySQL学习Day32——数据库备份与恢复
在任何数据库环境中,总会有不确定的意外情况发生,比如例外的停电、计算机系统中的各种软硬件故障、人为破坏、管理员误操作等是不可避免的,这些情况可能会导致数据的丢失、 服务器瘫痪等严重的后果。存在多个服务器时,会出现主从服…...
阅读基础知识
一 网络 1. 三次握手四次挥手 三次握手:为了建立长链接进行交互即建立一个会话,使用 http/https 协议 ① 客户端产生初始化序列号 Seqx ,向服务端发送建立连接的请求报文,将 SYN1 同步序列号; ② 服务端接收建立连接…...
【NestJS 编程艺术】1. NestJS设计模式深度解析:构建高效、可维护的服务端应用
在当今快速发展的软件开发领域,Node.js凭借其轻量级和高性能的特点,已经成为了构建服务端应用的首选技术之一。然而,随着应用规模的扩大,传统的Node.js框架如Express和Koa可能在架构设计和代码组织上显得力不从心。这时࿰…...
QT中connect()的参数5:Qt::DirectConnection、Qt::QueuedConnection区别
原文链接:https://blog.csdn.net/Dasis/article/details/120916993 connect用于连接QT的信号和槽,在qt编程过程中不可或缺。它其实有第5个参数,只是一般使用默认值,在满足某些特殊需求的时候可能需要手动设置。 Qt::AutoConnect…...
VXLAN学习笔记
声明:该博客内容大部分参考参考链接整理 什么是VXLAN? VXLAN(Virtual Extensible LAN)即虚拟扩展局域网,是大二层网络中广泛使用的网络虚拟化技术。在源网络设备与目的网络设备之间建立一条逻辑VXLAN隧道,采用MAC in UDP的封装方…...
全排列的不同写法(茴字的不同写法)及对应的时间开销
资源课件: CS106B-recursion-pptstanford library-timer.hstanford library-set.h 不同的方法 1------ Set<string> permutations1Rec(string remaining) {Set<string> res;if(remaining.size() 0) {res "";}else {for(int i 0; i <…...
权衡后台数据库设计中是否使用外键
目录 引言 外键简介 对比 真实后台项目中的权衡 结论 引言 在大学学习数据库课程时,我们会早早的接触到外键这一概念,同时我相信大部分人在懂了外键的概念后都会觉得外键很重要,在涉及多表一定要用,但后来在我接触到真实项目…...
ChatGPT提示词方法的原理
关于提示词,我之前的一些文章可以参考: 【AIGC】AI作图最全提示词prompt集合(收藏级)https://giszz.blog.csdn.net/article/details/134815245?ydrefereraHR0cHM6Ly9tcC5jc2RuLm5ldC9tcF9ibG9nL21hbmFnZS9hcnRpY2xlP3NwbT0xMDExL…...
计算机网络 谢希仁(001-1)
计算机网络-方老师 总时长 24:45:00 共50个视频,6个模块 此文章包含1.1到1.4的内容 简介 1.1计算机网络的作用 三网融合(三网合一) 模拟信号就是连续信号 数字信号是离散信号 1.2互联网概述 以前2兆带宽就要98 现在几百兆带宽也就几百块 …...
Windows,MacOS,Linux下载python并配置环境图文讲解
Windows 打开python官网 点击download 点击黄色按钮 另存为 打开文件 全选 配置安装路径 安装中 关闭路径长度限制 完成 验证 同时按住winr(win就是空格键左边的东西) 输入cmd 键入python,如果出现版本(红框)即安装成功 MacOS 同理打开python官网 点击最新版本 拖…...
汽车网络基础知识 要点
在以太网开发中,常常会听到一些专业名词,例如PHY,MAC,MII,switch,下面是解释 PHY PHY 是物理接口收发器,它实现物理层。包括 MII/GMII (介质独立接口) 子层、PCS (物理编码子层) 、PMA (物理介…...
ClickHouse中的设置的分类
ClickHouse中的各种设置 ClickHouse中的设置有几百个,下面对这些设置做了一个简单的分类。...
香港空间服务器带宽和流量限制:原因和解决方法
香港空间服务器,也被称作香港虚拟服务器。一般情况下,香港空间服务器所提供的流量或者带宽,是足以满足99%的普通中小网站用户使用的,但也不排除,网站访问量大,租香港空间不能够满足要求的情况。 在本…...
echarts实践总结(常用一):柱状图(特点:渐变色、点击缩放、左右滑动、悬浮展示样式)
目录 第一章 echarts基本使用 第二章 echarts实践——柱状图 效果展示 第一章 echarts基本使用 Echarts常用配置项(详细入门)_echarts配置项手册-CSDN博客 第二章 echarts实践——柱状图 最近接到这么一个需求,需要画页面,然后有这么几个echarts的图需…...
CVE-2020-6418:Incorrect side effect modelling for JSCreate
文章目录 环境搭建漏洞分析漏洞利用漏洞触发链RCE 总结参考 环境搭建 sudo apt install python git reset --hard cecaa443ec29784ee26e31e678a333a3c1e71136 gclient sync -D// 手动引入漏洞,参考下面的 patch,把相关修改注释掉即可// debug version t…...
STM32信息安全 1.2 课程架构介绍:芯片生命周期管理与安全调试
STM32信息安全 1.2 课程架构介绍:STM32H5 芯片生命周期管理与安全调试 下面开始学习课程的第二节,简单介绍下STM32H5芯片的生命周期和安全调试,具体课程大家可以观看STM32官方录制的课程,链接:1.2. 课程架构介绍&…...
springboot278基于JavaWeb的鲜牛奶订购系统的设计与实现
鲜牛奶订购系统的设计与实现 摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统鲜牛奶订购信息管理难度大&…...
SSH介绍及检测规则思路分析
一、SSH 1、定义 SSH是安全的加密协议,用于远程连接linux服务器。 2、ssh服务的主要功能: 1)提供远程链接服务器的功能; 2)对远程链接传输的数据进行加密 3、ssh与telnet的区别: 服务链接方式 服务数据…...
政府网站集约化建设完成情况/站长工具查询seo
Java面试题之:基于 Redis 分布式锁一二三一 获取锁的时候,使用 setnx(SETNX key val:当且仅当 key 不存在时,set 一个 key为 val 的字符串,返回 1;若 key 存在,则什么都不做…...
网站备案快速备案/针对大学生推广引流
客户服务管理技巧 上文为您介绍了需要客户服务管理的重要性,以下是为你提供一些可以直接借鉴客户服务管理技巧,这些技巧肯定会提高客户满意度: 1:雇用具有符合您业务需求的技能和素质的人员 流程和系统很重要,但您提…...
浦东新区中国建设银行官网站/文军seo
今天对数据库做异机恢复,我们知道在恢复过程中是不对临时表空间进行恢复的,所以在进行resetlogs打开数据库之后,需要对临时表空间进行处理,处理方式如下: 1 添加新的临时表空间文件。 2 删除旧的临时表空间文件。 al…...
找作文做读书笔记去什么网站/网推什么意思
链接:https://ac.nowcoder.com/acm/contest/188/C?&headNavwww 来源:牛客网 题目描述 小w不会离散数学,所以她van的图论游戏是送分的 小w有一张n个点n-1条边的无向联通图,每个点编号为1~n,每条边都有一个长度 小w现在在点x上 她想知…...
wordpress标题数据表/建站平台哪个比较权威
Mahout版本:0.7,hadoop版本:1.0.4,jdk:1.7.0_25 64bit。 本篇是ItemBased Collaborative Filtering的算法综述,即总结前面几篇blog,分析该算法的数据流,主要使用的数据是《mahout i…...
做软件公司网站/人力资源短期培训班
mybatis入门(一)什么是mybatis 1.JDBC Java Data Base Connectivity :Java数据库连接 由SUN公司提出的一系列规范 -- 只定义了接口的规范,具体实现是交给各个数据库厂商去实现的,JDBC是一种典型的桥接模式 …...