c++ 位图和布隆过滤器
位图(bitmap)
定义
位图是一种使用位数组存储数据的结构。每一位表示一个状态,通常用于快速判断某个值是否存在,或者用来表示布尔类型的集合。
特点
- 节省空间:一个字节可以表示8个状态。
- 高效操作:位操作(如按位与、或、非)速度极快。
- 不支持重复元素:每个值只能映射到唯一的位。
应用
集合操作
-
判断某个用户 ID 是否存在。
-
插入一个用户 ID。
-
删除一个用户 ID。
-
计算两个用户 ID 集合的交集、并集和差集。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;class Bitmap {
private:vector<unsigned char> bitmap; // 位图存储size_t size; // 位图大小(支持的最大值)public:// 构造函数Bitmap(size_t size) : size(size) {bitmap.resize((size + 7) / 8, 0); // 每8个数占1字节}// 设置某个位为1(插入操作)void set(int num) {if (num >= size) return; // 越界检查bitmap[num / 8] |= (1 << (num % 8));}// 重置某个位为0(删除操作)void reset(int num) {if (num >= size) return; // 越界检查bitmap[num / 8] &= ~(1 << (num % 8));}// 检查某个位是否为1(查询操作)bool get(int num) const {if (num >= size) return false; // 越界检查return bitmap[num / 8] & (1 << (num % 8));}// 求交集Bitmap intersection(const Bitmap& other) const {Bitmap result(size);for (size_t i = 0; i < bitmap.size(); ++i) {result.bitmap[i] = bitmap[i] & other.bitmap[i];}return result;}// 求并集Bitmap unionSet(const Bitmap& other) const {Bitmap result(size);for (size_t i = 0; i < bitmap.size(); ++i) {result.bitmap[i] = bitmap[i] | other.bitmap[i];}return result;}// 求差集Bitmap difference(const Bitmap& other) const {Bitmap result(size);for (size_t i = 0; i < bitmap.size(); ++i) {result.bitmap[i] = bitmap[i] & ~other.bitmap[i];}return result;}// 打印位图内容void print() const {for (size_t i = 0; i < size; ++i) {if (get(i)) cout << i << " ";}cout << endl;}
};// 测试用例
int main() {Bitmap bm1(100); // 位图1,范围为0到99Bitmap bm2(100); // 位图2,范围为0到99// 插入一些IDbm1.set(10);bm1.set(20);bm1.set(30);bm2.set(20);bm2.set(30);bm2.set(40);cout << "Bitmap 1: ";bm1.print(); // 输出:10 20 30cout << "Bitmap 2: ";bm2.print(); // 输出:20 30 40// 求交集cout << "Intersection: ";Bitmap intersect = bm1.intersection(bm2);intersect.print(); // 输出:20 30// 求并集cout << "Union: ";Bitmap unionResult = bm1.unionSet(bm2);unionResult.print(); // 输出:10 20 30 40// 求差集cout << "Difference (bm1 - bm2): ";Bitmap difference = bm1.difference(bm2);difference.print(); // 输出:10return 0;
}
代码说明
- 位图核心操作:
set(num)
:将数字num
对应的位置为1。reset(num)
:将数字num
对应的位置清零。get(num)
:查询数字num
是否存在。
- 集合运算:
- 交集:
result.bitmap[i] = bitmap[i] & other.bitmap[i];
- 并集:
result.bitmap[i] = bitmap[i] | other.bitmap[i];
- 差集:
result.bitmap[i] = bitmap[i] & ~other.bitmap[i];
- 交集:
- 空间效率:
- 位图将整数范围映射到位数组,节省了大量存储空间。比如范围为 0 到 1,000,000 的位图只需约 125 KB 内存。
- 时间效率:
- 插入、删除、查询的时间复杂度为 O(1)。
- 集合运算的时间复杂度为 O(n),其中 n是位数组的大小。
数据去重
#include <iostream>
#include <vector>
using namespace std;class Bitmap {
private:vector<unsigned char> bitmap; // 位图存储size_t size; // 位图支持的最大值public:Bitmap(size_t size) : size(size) {bitmap.resize((size + 7) / 8, 0); // 每8个数占1字节}// 设置某个位为1void set(int num) {if (num >= size) return; // 超出范围检查bitmap[num / 8] |= (1 << (num % 8));}// 检查某个位是否为1bool get(int num) const {if (num >= size) return false; // 超出范围检查return bitmap[num / 8] & (1 << (num % 8));}
};// 使用位图实现数据去重
void removeDuplicates(const vector<int>& input) {const int MAX_VALUE = 1000000; // 数据范围:0到999999Bitmap bitmap(MAX_VALUE);vector<int> uniqueNumbers;for (int num : input) {if (!bitmap.get(num)) { // 如果位未被设置,说明是新数据uniqueNumbers.push_back(num);bitmap.set(num); // 标记该数据已存在}}// 输出去重后的数据cout << "Unique numbers: ";for (int num : uniqueNumbers) {cout << num << " ";}cout << endl;
}int main() {// 测试数据vector<int> input = {10, 20, 30, 10, 20, 40, 50, 40, 30};removeDuplicates(input); // 输出:10 20 30 40 50return 0;
}
代码说明
Bitmap
类:set(int num)
:将数字num
对应的位设置为1,表示该数字已存在。get(int num)
:检查数字num
是否已经存在。
removeDuplicates
函数:- 输入一个整数数组
input
。 - 使用位图记录已出现的数字,跳过重复数字,将未重复数字加入结果集。
- 输入一个整数数组
- 空间效率:
- 如果数据范围为0到999999,则需要约125 KB内存(1000000/8字节)。
- 时间效率:
- 遍历输入数组的时间复杂度为 O(n),其中 n是数组的大小。
- 设置和查询位图的复杂度为 O(1)。
布尔状态管理
#include <iostream>
#include <vector>
using namespace std;class Bitmap {
private:vector<unsigned char> bitmap; // 位图存储size_t size; // 位图支持的最大位数public:Bitmap(size_t size) : size(size) {bitmap.resize((size + 7) / 8, 0); // 每8个布尔状态占用1字节}// 设置某个位为1(开)void setOn(int num) {if (num >= size) return; // 越界检查bitmap[num / 8] |= (1 << (num % 8));}// 设置某个位为0(关)void setOff(int num) {if (num >= size) return; // 越界检查bitmap[num / 8] &= ~(1 << (num % 8));}// 查询某个位的状态bool isOn(int num) const {if (num >= size) return false; // 越界检查return bitmap[num / 8] & (1 << (num % 8));}// 打印所有状态void printStatus() const {for (size_t i = 0; i < size; ++i) {cout << "Device " << i << ": " << (isOn(i) ? "ON" : "OFF") << endl;}}
};int main() {const int NUM_DEVICES = 10000; // 管理10000个设备Bitmap devices(NUM_DEVICES);// 设置一些设备为开devices.setOn(1);devices.setOn(100);devices.setOn(9999);// 查询设备状态cout << "Device 1: " << (devices.isOn(1) ? "ON" : "OFF") << endl; // 输出:ONcout << "Device 2: " << (devices.isOn(2) ? "ON" : "OFF") << endl; // 输出:OFF// 设置设备100为关devices.setOff(100);// 查询状态cout << "Device 100: " << (devices.isOn(100) ? "ON" : "OFF") << endl; // 输出:OFF// 打印前10个设备状态for (int i = 0; i < 10; ++i) {cout << "Device " << i << ": " << (devices.isOn(i) ? "ON" : "OFF") << endl;}return 0;
}
代码说明
- 位图操作:
setOn(int num)
:将设备编号对应的位设置为1(设备开)。setOff(int num)
:将设备编号对应的位清零(设备关)。isOn(int num)
:检查设备编号对应的位是否为1。
- 存储空间效率:
- 如果管理10,000个设备,每个设备1位,需要10,000/8=1250字节(约1.25 KB)。
- 相比直接用布尔数组(10,000字节),空间节省了约8倍。
- 时间效率:
- 查询、设置的时间复杂度为 O(1)。
布隆过滤器
定义
布隆过滤器是一种基于位图的概率性数据结构,用于判断某个元素是否在集合中。它可能存在假阳性(误判元素存在),但不会有假阴性(漏判元素不存在)。
特点
- 高效存储:用较小的空间表示大数据集。
- 高效查询:查询时间复杂度 O(k),k为哈希函数的数量。
- 不可删除元素:经典布隆过滤器不支持删除。
应用
- 初始化一个大小为 m 的位数组,将所有位初始化为0。
- 对于一个元素 x,通过 k 个哈希函数计算其哈希值,并将对应位置的位设为1。
- 查询时,用同样的 k 个哈希函数检查这些位是否都为1,若全为1,则判断元素可能存在,否则不存在。
#include <iostream>
#include <vector>
#include <functional>
using namespace std;class BloomFilter {
private:vector<bool> bitArray; // 位数组vector<hash<int>> hashFuncs; // 哈希函数集合size_t size;public:BloomFilter(size_t size, int numHashFuncs) : size(size), bitArray(size, false) {for (int i = 0; i < numHashFuncs; ++i) {hashFuncs.push_back(hash<int>()); // 简单使用std::hash}}void insert(int key) {for (auto& hashFunc : hashFuncs) {size_t index = hashFunc(key) % size;bitArray[index] = true;}}bool contains(int key) {for (auto& hashFunc : hashFuncs) {size_t index = hashFunc(key) % size;if (!bitArray[index]) return false;}return true;}
};int main() {BloomFilter bf(100, 3); // 位数组大小为100,使用3个哈希函数bf.insert(10);bf.insert(20);cout << bf.contains(10) << endl; // 输出1cout << bf.contains(30) << endl; // 输出0(一定不存在)cout << bf.contains(20) << endl; // 输出1(可能存在)return 0;
}
位图和布隆过滤器对比
特性 | 位图 | 布隆过滤器 |
---|---|---|
存储效率 | 高 | 更高 |
查询效率 | 快速 | 快速 |
误判率 | 无误判 | 存在假阳性 |
数据删除 | 支持 | 不支持(需要Counting Bloom) |
典型应用 | 离散集合、计数 | 大规模数据集查询过滤 |
应用场景
- 位图:数据去重、位标记、快速布尔状态存储。
- 布隆过滤器:URL去重、缓存预加载、推荐系统中的快速判别过滤。
源码解读(redis中的bitmap)
存储结构
Redis 使用字符串类型存储 Bitmap。
- 每个字符串可以存储多个字节(最多 512MB),而位操作直接基于字符串的二进制位进行。
- 因为 Bitmap 是字符串的扩展功能,其底层存储依赖
sds
(Simple Dynamic String)。
sds 源码文件:
sds.h
sds.c
Bitmap 数据存储: Bitmap 数据实际上以字符串形式存储在 robj
结构体中,定义在 object.c
:
struct redisObject {unsigned type : 4; /* 数据类型(如 String、Hash) */unsigned encoding : 4; /* 编码方式(如 RAW、INT 等) */void *ptr; /* 实际数据的指针 */
};
对于 Bitmap,type
是字符串类型 (REDIS_STRING
),而 encoding
通常为 RAW
或 EMBSTR
,表示底层是动态字符串。
核心命令实现
(1)SETBIT key offset value
设置指定位的值。
- 命令格式:
SETBIT key offset value
key
是存储 Bitmap 的 Redis 键。offset
是位的偏移量。value
是要设置的值(0 或 1)。
- 实现逻辑:
- 计算
offset
所属的字节位置:byte = offset / 8
。 - 计算在字节中的位偏移量:
bit = offset % 8
。 - 如果
key
的值不足以存储该位,Redis 会自动扩展字符串长度。 - 使用位运算修改指定位。
- 计算
- 源码位置:
t_string.c
void setbitCommand(client *c) {long long offset, byte, bit;robj *o;size_t bitoffset;int byteval;/* 获取 offset 参数并校验范围 */if (getLongLongFromObjectOrReply(c, c->argv[2], &offset, NULL) != C_OK)return;if (offset < 0 || ((unsigned long long)offset >> 3) >= 512*1024*1024) {addReplyError(c, "bit offset is not an integer or out of range");return;}/* 获取 value 参数并校验 */if (strcmp(c->argv[3]->ptr, "0") && strcmp(c->argv[3]->ptr, "1")) {addReplyError(c, "bit value is not 0 or 1");return;}/* 获取或创建字符串对象 */o = lookupKeyWrite(c->db, c->argv[1]);if (o == NULL) {if (strcmp(c->argv[3]->ptr, "0") == 0) {addReply(c, shared.czero);return; /* 位是0,无需修改 */}o = createObject(OBJ_STRING, sdsnewlen(NULL, byte + 1));dbAdd(c->db, c->argv[1], o);}/* 修改指定位 */byte = offset / 8;bit = 7 - (offset % 8);byteval = ((unsigned char *)o->ptr)[byte];byteval &= ~(1 << bit); /* 清零 */byteval |= (bitval << bit); /* 置位 */((unsigned char *)o->ptr)[byte] = byteval;addReply(c, shared.cone);
}
(2)GETBIT key offset
获取指定位的值。
- 命令格式:
GETBIT key offset
- 实现逻辑:
- 计算
offset
对应的字节和位位置。 - 如果
offset
超出字符串的长度,返回 0。 - 读取目标字节并通过位运算提取目标位。
- 计算
- 源码实现:
void getbitCommand(client *c) {robj *o;long long offset;unsigned char *bitmap;size_t byte, bit;int bitval = 0;/* 获取 offset 参数 */if (getLongLongFromObjectOrReply(c, c->argv[2], &offset, NULL) != C_OK)return;/* 计算字节和位位置 */byte = offset / 8;bit = 7 - (offset % 8);/* 获取字符串对象 */o = lookupKeyRead(c->db, c->argv[1]);if (o != NULL && o->type == OBJ_STRING) {bitmap = o->ptr;if (byte < sdslen(bitmap)) {bitval = bitmap[byte] & (1 << bit);}}addReplyLongLong(c, bitval ? 1 : 0);
}
(3)BITCOUNT key [start end]
统计 Bitmap 中设置为 1 的位数。
- 命令格式:
BITCOUNT key [start end]
- 实现逻辑:
- 读取字符串中每个字节,逐字节统计 1 的数量。
- 如果指定了范围
[start, end]
,只计算范围内的位。
- 源码实现:
void bitcountCommand(client *c) {robj *o;long start, end;size_t bitcount = 0;/* 获取并校验范围 */if (getRangeFromObjectOrReply(c, c->argv[2], c->argv[3], &start, &end) != C_OK)return;/* 获取字符串对象 */o = lookupKeyRead(c->db, c->argv[1]);if (o && o->type == OBJ_STRING) {unsigned char *bitmap = o->ptr;size_t len = sdslen(bitmap);/* 遍历字节统计 1 的数量 */for (size_t i = start; i <= end && i < len; i++) {bitcount += __builtin_popcount(bitmap[i]);}}addReplyLongLong(c, bitcount);
}
Redis Bitmap 的常见优化
- 延迟创建字符串: 如果设置的位是 0,Redis 不会立即分配内存存储字符串。
- 按需扩展: 设置位时,如果超过当前字符串长度,Redis 会自动扩展存储。
- 低层优化: Redis 利用 CPU 指令,如
__builtin_popcount
快速统计 1 的数量。
应用场景
- 用户签到:记录每天用户是否签到。
- 状态管理:如设备是否可用。
- 去重与快速过滤:记录某项操作是否完成。
相关文章:
c++ 位图和布隆过滤器
位图(bitmap) 定义 位图是一种使用位数组存储数据的结构。每一位表示一个状态,通常用于快速判断某个值是否存在,或者用来表示布尔类型的集合。 特点 节省空间:一个字节可以表示8个状态。高效操作:位操作…...
基于Springboot开发的云野旅游平台
一、功能介绍 云野旅游平台包含管理员、用户两个角色以及前后台系统。 前台系统功能 用户登录成功后,可以进行查看旅游路线、最新线路、旅游资讯、个人中心、后台管理、购物车、客服等功能模块。进行相对应操作。 后台系统功能 管理员或用户登录成功后…...
微服务即时通讯系统(5)用户管理子服务,网关子服务
用户管理子服务(user文件) 用户管理子服务也是这个项目中的一个业务最多的子服务,接口多,但是主要涉及的数据表只有user表,Redis的键值对和ES的一个搜索引擎,主要功能是对用户的个人信息进行修改管理&#…...
docker.io连接超时的处理,用代理网站
docker pull的时候会超时: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) 这时可以找一些代理网站,比如…...
【测试工具JMeter篇】JMeter性能测试入门级教程(四):JMeter中BeanShell内置方法使用
一、什么是BeanShell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;BeanShell是一种松散类型的脚本语言(这点和JS类似);BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精简…...
JavaScript 键盘控制移动
如果你想通过 JavaScript 实现键盘控制对象(比如一个方块)的移动,下面是一个简单的示例,展示如何监听键盘事件并根据按下的键来移动一个元素。 HTML 和 CSS: <!DOCTYPE html> <html lang"en">…...
如何预防服务器后台爆破攻击
服务器后台爆破(Brute Force Attack)是一种通过反复尝试用户名和密码组合,以非法获取系统访问权限的攻击方式。这种攻击不仅会消耗服务器资源,还可能导致合法用户被锁定或敏感数据泄露。为了有效预防服务器后台爆破攻击࿰…...
AI 写作(一):开启创作新纪元(1/10)
一、AI 写作:重塑创作格局 在当今数字化高速发展的时代,AI 写作正以惊人的速度重塑着创作格局。AI 写作在现代社会中占据着举足轻重的地位,发挥着不可替代的作用。 随着信息的爆炸式增长,人们对于内容的需求日益旺盛。AI 写作能够…...
【HarmonyOS】鸿蒙应用使用lottie动画
【HarmonyOS】鸿蒙应用使用lottie动画 一、lottie动画是什么? https://airbnb.design/lottie Lottie是由Airbnb团队开发的一个适用于iOS、Android、React Native、Web和Windows的开源动画库,用于解析使用Bodymovin导出为JSON的Adobe After Effects动…...
SQL面试题——腾讯SQL面试题 合并连续支付订单
合并连续支付订单 现有一张用户支付表:user_pay包含字段订单ID,用户ID,商户ID,支付时间,支付金额。如果同一用户在同一商户存在多笔订单,且中间该用户没有其他商户的支付记录,则认为是连续订单,请把连续订单进行合并,时间取最早支付时间,金额求和。 +----------+------…...
【docker】10. 容器操作案例
容器操作案例 容器基本操作 • 通过 nginx 镜像文件创建容器 • 容器的列举(包含正在运行的容器) # 发现此时 e7c33d9f5c61 这个容器运行的状态为 Up,即运行状态 rootLAPTOP-H2EI4I6A:~# docker container ls CONTAINER ID IMAGE COMMAND CREATED …...
postman测试
当然,以下是针对你提供的API层和Service层代码中涉及到的各个接口,如何使用 Postman 进行详细测试的指南。这个指南将帮助你理解如何配置 Postman 来测试这些接口,包括请求的构造、认证的处理、以及如何解读响应。 目录 准备工作接口测试指…...
【攻防实验】溯源与取证分析实验
溯源与取证分析实验 溯源取证分析作为网络攻防过程中重要环节,准确找到攻击者的入侵线索(尤其是攻击突破口、攻击IP地址、域名、工具等信息),对于企业或者团队安全运营团队来说都是必备技能。常规攻击取证过程中往往会结合流量、Web访问日志、终端系统或…...
【测试工具JMeter篇】JMeter性能测试入门级教程(七):JMeter断言
一、前言 在 JMeter 中,断言元件(Assertion)用于验证测试结果是否符合预期。断言元件可以检查服务器的响应数据,以确保它们符合期望的模式或值,从而验证性能测试脚本的正确性。断言元件通常在每个请求的响应中添加&am…...
Linux 常用命令
目录 一、ls 指令 二、pwd命令 三、cd 指令 1、cd 目录名 2、cd .. 返回上级目录 3、cd ~ 进入用户家目 4、cd - 返回最近访问目录 5、cd相对路径&&cd绝对路径 四、touch指令 五、mkdir指令 1、mkdir 目录名 创建一个目录 2、mkdir -p 递归创建多…...
汽车IVI中控OS Linux driver开发实操(二十八):回声消除echo cancellation和噪声消除Noise reduction
概述: 在当今高度互联的世界中,清晰的实时通信比以往任何时候都更重要。在远程团队会议期间,没有什么能像回声一样打断对话。当说话者听到他们的声音回响时,可能会分散注意力,甚至无法理解对话。即使是很小的回声也会产生很大的影响,仅仅25毫秒的振幅就足以造成声音干扰…...
003-SpringBoot整合Pagehelper
SpringBoot整合Pagehelper 一、引入依赖二、配置 application.yml三、配置 MybatisPlusConfig四、Controller五、ServiceImpl 一、引入依赖 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</ar…...
零基础学安全--shell练习
目录 用shell写一个计算器 测试 一些小问题 n阶乘数 测试 拓展 写⼀个Shell脚本去筛选出eth0⽹卡的ipv4地址,并赋值⼀个变量输出 测试 无限重启 用shell写一个计算器 read -p "请输入数字a: " number1 read -p "请输入操作符…...
【专题】计算机网络之运输层(传输层)
1. 运输层协议概述 1.1 进程之间的通信 (1) 运输层的作用 运输层提供进程间的逻辑通信。 运输层的屏蔽作用: 运输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用的路由选择协议等),使应用进程看见的就是好像在两个运…...
【leetcode100】旋转图像
1、题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1: 输入:matrix [[1,2,3],[4,5,6],…...
软件工程——期末复习(1)
名词解释: 名词解释--人月 答案:人月是软件开发工作量的单位,1人月表示1个程序员1个月的工作时间所开发的代码量。 请解释软件缺陷、错误和失败,并简单举例说明。 答案:缺陷(defect)指系统代…...
HTML5系列(3)--多媒体标签详解
前端技术探索系列:HTML5 多媒体标签详解 🎥 开篇寄语 👋 前端开发者们, 在前三篇文章中,我们探讨了 HTML5 的语义化和表单特性。今天,让我们深入了解 HTML5 的多媒体能力,看看如何构建强大的…...
Spring Boot 3.4.0 发布:功能概览与示例
Spring Boot 3.4.0 带来了许多增强功能,使现代应用开发更加高效、便捷和强大。以下是最新功能的完整概述,以及一些帮助您快速入门的代码示例。 1. 应用程序版本管理 Spring Boot 引入了 spring.application.version 属性,方便开发者设置和访…...
【Vue3】【Naive UI】<n-upload>标签
【Vue3】【Naive UI】标签 基本设置 【VUE3】【Naive UI】<NCard> 标签 【VUE3】【Naive UI】<n-button> 标签 【VUE3】【Naive UI】<a> 标签 【VUE3】【Naive UI】<NDropdown> 标签…...
7.代理模式(Proxy Pattern)
古朗月行 代理模式JDK动态代理代码示例原码分析 cglib动态代理代码示例源码分析 JDK cglib动态代理对比ClassLoader类的生命周期: 参考资料 唐 李白 小时不识月,呼作白玉盘。 又疑瑶台镜,飞在青云端。 仙人垂两足,桂树何团团。…...
【效果】回到顶部功能实现
实现效果: 相关代码: <template><div class"cats" :style"{ top: catsTop }" ref"cats" click"catTop"></div> </template> 样式: /* 回到顶部 - 小猫咪 */ .cats {posi…...
项目搭建+修改
一 : 在列表成功回调函数,追加数据中,添加修改的按钮 for (let x of res) {//追加数据$("#table").append(<tr><td><input type"checkbox" class"ck" value"\${x.uid}"></td><td>\${x.uid}</td>…...
GD库如何根据颜色生成纯色背景图
GD库是一个用于图像处理的PHP扩展模块,它提供了一系列函数来创建、编辑和操作图像。要使用GD库根据颜色生成纯色背景图,可以按照以下步骤进行: 一、检查并安装GD库 检查GD库是否已安装: 可以通过运行phpinfo();或在命令行中使用p…...
Python 网络爬虫入门全知道
一、引言 在当今数字化时代,网络上的数据量呈爆炸式增长。无论是进行数据分析、市场调研,还是开发智能应用,获取网络数据都变得极为重要。而 Python 网络爬虫就是一把打开网络数据宝库的利器。它能够自动地从网页中抓取我们需要的信息&#…...
MATLAB期末复习笔记(下)
目录 五、数据和函数的可视化 1.MATLAB的可视化对象 2.二维图形的绘制 3.图形标识 4.多子图绘图 5.直方图的绘制 (1)分类 (2)垂直累计式 (3)垂直分组式 (4)水平分组式 &…...
基于大数据爬虫数据挖掘技术+Python的网络用户购物行为分析与可视化平台(源码+论文+PPT+部署文档教程等)
#1024程序员节|征文# 博主介绍:CSDN毕设辅导第一人、全网粉丝50W,csdn特邀作者、博客专家、腾讯云社区合作讲师、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老…...
【go】只读通道和只写通道
文章目录 概述1. 通道的方向2. 为什么会有只读通道和只写通道?3. 总结 概述 在 Go 中,只读通道和只写通道的概念通过通道的方向来实现。Go 语言允许你在函数参数中指定通道的方向,从而限制通道的使用方式,这样可以确保代码的清晰…...
带Burst AOT Settings移植问题
报错 burst问题 Burst AOT Settings 是 Unity 的 Burst Compiler 的一部分,用于预编译程序集(AOT,Ahead-Of-Time Compilation),以便在不支持 JIT(即时编译)的平台上运行,例如 iOS 和…...
Debezium日常分享系列之:Debezium Engine
Debezium日常分享系列之:Debezium Engine 依赖打包项目在代码中输出消息格式消息转换消息转换谓词高级记录使用引擎属性异步引擎属性数据库模式历史属性处理故障 Debezium连接器通常通过部署到Kafka Connect服务来运行,并配置一个或多个连接器来监视上游…...
运行 GreatSQL 时为什么要求关闭透明大页
在大部分运维规范中,一般都会要求在运行 GreatSQL/MySQL 的环境中要关闭透明大页,那么到底什么是透明大页,为什么要关闭,打开有什么风险吗? 在此之前,我也是有点懵的,本文试着回答这个疑问&…...
【Rive】Rive在Android上的简单应用
1 前言 Rive 是一款强大的矢量图编辑器,可以设计图形、也可以制作动画。Rive 提供了矩形、圆形、三角形、多边形、星形、钢笔、文字等工具来绘制各式各样的矢量图形;提供了平移、旋转、缩放等工具对矢量图形进行各种变换;提供了骨骼、约束、时…...
Base 崛起,SynFutures 或成生态系统中最具潜力应用
10月份的 Unchained Crypto 采访中,Solana 联合创始人 Anatoly 表示,通过观察活跃地址数、TVL、DeFi 版块、Meme 热潮和开发者生态等多个关键指标,察觉到 Base 势头正猛,成为以太坊生态最强劲的 L2。 11月下旬,小狐狸创…...
探索Go语言中的循环双向链表
简介 循环双向链表将双向链表的灵活性与循环结构相结合,使得每个节点都有一个指向前一个节点和后一个节点的指针,并且最后一个节点的Next指针指向头节点,形成一个闭环。本文将深入探讨如何在Go语言中实现和操作这种数据结构。 循环双向链表…...
Leetcode617.合并二叉树(HOT100)+Leetcode79. 单词搜索(HOT100)
链接 代码: class Solution { public:TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {if(!root1)return root2;if(!root2)return root1;root1->valroot2->val;root1->left mergeTrees(root1->left,root2->left);root1->right merg…...
亚马逊云(AWS)使用root用户登录
最近在AWS新开了服务器(EC2),用于学习,遇到一个问题就是默认是用ec2-user用户登录,也需要密钥对。 既然是学习用的服务器,还是想直接用root登录,下面开始修改: 操作系统是࿱…...
使用Docker在Ubuntu 22.04上部署MySQL数据库的完整指南
使用Docker在Ubuntu 22.04上部署MySQL数据库的完整指南 在现代应用开发中,使用Docker来部署数据库已成为一种流行的做法。本文将详细介绍如何在Ubuntu 22.04系统上使用Docker部署最新版本的MySQL数据库,包括关键注意事项、详细步骤、闭坑指南以及总结。…...
算法笔记:力扣15、三数之和
思路: 实现代码 class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> result new ArrayList<>(); Arrays.sort(nums); // 先对数组进行排序 for (int i 0; i < nums.length - 2; i) { /…...
perf list PMU 缓存事件
事件标识事件解释PMU事件路径l1d_cacheL1数据缓存的访问次数,L1缓存是CPU内部最快的缓存,位于距离CPU核心非常近的位置。armv8_pmuv3/l1d_cache/l1d_cache_lmiss_rd表示从L1数据缓存读取数据时发生缓存未命中的次数。armv8_pmuv3/l1d_cache_lmiss_rd/l1d…...
使用C#开发VTK笔记(一)-VTK开发环境搭建
一.使用C#开发VTK的背景 因为C#开发的友好性,一直都比较习惯于从C#开发程序。而长期以来,都希望有一个稳定可靠的三位工程数模的开发演示平台,经过多次对比之后,感觉VTK和OpenCasCade这两个开源项目是比较好的,但它们都是用C++编写的,我用C#形式开发,只能找到发布的C#组…...
2024Selenium自动化常见问题!
"NoSuchElementException"异常: 确保使用了正确的选择器来定位元素。可以使用id、class、XPath或CSS选择器等。 可以尝试使用find_elements方法来查找元素列表,并检查列表的长度来判断元素是否存在。 使用显式等待(WebDriverWait…...
考研英语翻译与大小作文
名词动化词 1 持有 harbor2 2 反映 mirror 3 缩短 bridge 4 使用 harness 5 掩饰 mask/veil 6 修改 tailor 7 汇集 pool 8 控制 curb 9 想象 picture 10 激发 trigger 拉丁…...
详解Rust异步编程
文章目录 多线程编程与异步编程对比并发模型对比分析异步编程基础概念及用法 Rust的异步编程通过async/await语法和Future特性提供了一种高效的方式来处理并发任务,尤其在I/O密集型操作中表现出色。async/await异步编程模型性能高,还能支持底层编程&…...
Vue + Element UI 实战技巧:如何实现 el-table 重新加载数据后折叠所有展开行
在 Vue 中使用 Element UI 的 el-table 组件时,如果你想要在数据重新加载后折叠所有行的展开状态,你可以通过维护一个数据属性来追踪哪些行是展开的,并在数据更新时重置这个属性。 以下是一个简单的示例来说明如何实现这个功能: …...
linux静态链接和动态链接
静态链接的特点 程序独立性高 静态链接是在程序编译时,将所有需要的目标文件以及它们所依赖的库文件中的代码和数据链接成一个可执行文件。一旦链接完成,这个可执行文件就包含了运行所需的全部内容,不依赖外部的库文件。例如,一个…...
计算机网络学习资料全攻略
计算机网络是计算机科学中一个非常重要的分支,它涉及到数据在计算机系统之间的传输和通信。随着互联网的快速发展,对计算机网络知识的掌握变得越来越重要。本文将为您提供一份全面的计算机网络学习资料指南,帮助您从基础到高级逐步深入学习。…...