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

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;
}

代码说明

  1. 位图核心操作
    • set(num):将数字 num 对应的位置为1。
    • reset(num):将数字 num 对应的位置清零。
    • get(num):查询数字 num 是否存在。
  2. 集合运算
    • 交集result.bitmap[i] = bitmap[i] & other.bitmap[i];
    • 并集result.bitmap[i] = bitmap[i] | other.bitmap[i];
    • 差集result.bitmap[i] = bitmap[i] & ~other.bitmap[i];
  3. 空间效率
    • 位图将整数范围映射到位数组,节省了大量存储空间。比如范围为 0 到 1,000,000 的位图只需约 125 KB 内存。
  4. 时间效率
    • 插入、删除、查询的时间复杂度为 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;
}

代码说明

  1. Bitmap
    • set(int num):将数字 num 对应的位设置为1,表示该数字已存在。
    • get(int num):检查数字 num 是否已经存在。
  2. removeDuplicates函数
    • 输入一个整数数组 input
    • 使用位图记录已出现的数字,跳过重复数字,将未重复数字加入结果集。
  3. 空间效率
    • 如果数据范围为0到999999,则需要约125 KB内存(1000000/8字节)。
  4. 时间效率
    • 遍历输入数组的时间复杂度为 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;
}

代码说明

  1. 位图操作
    • setOn(int num):将设备编号对应的位设置为1(设备开)。
    • setOff(int num):将设备编号对应的位清零(设备关)。
    • isOn(int num):检查设备编号对应的位是否为1。
  2. 存储空间效率
    • 如果管理10,000个设备,每个设备1位,需要10,000/8=1250字节(约1.25 KB)。
    • 相比直接用布尔数组(10,000字节),空间节省了约8倍。
  3. 时间效率
    • 查询设置的时间复杂度为 O(1)。

布隆过滤器

定义

布隆过滤器是一种基于位图的概率性数据结构,用于判断某个元素是否在集合中。它可能存在假阳性(误判元素存在),但不会有假阴性(漏判元素不存在)。

特点

  • 高效存储:用较小的空间表示大数据集。
  • 高效查询:查询时间复杂度 O(k),k为哈希函数的数量。
  • 不可删除元素:经典布隆过滤器不支持删除。

应用

  1. 初始化一个大小为 m 的位数组,将所有位初始化为0。
  2. 对于一个元素 x,通过 k 个哈希函数计算其哈希值,并将对应位置的位设为1。
  3. 查询时,用同样的 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 通常为 RAWEMBSTR,表示底层是动态字符串。

核心命令实现

(1)SETBIT key offset value

设置指定位的值。

  • 命令格式: SETBIT key offset value
    • key 是存储 Bitmap 的 Redis 键。
    • offset 是位的偏移量。
    • value 是要设置的值(0 或 1)。
  • 实现逻辑:
    1. 计算 offset 所属的字节位置:byte = offset / 8
    2. 计算在字节中的位偏移量:bit = offset % 8
    3. 如果 key 的值不足以存储该位,Redis 会自动扩展字符串长度。
    4. 使用位运算修改指定位。
  • 源码位置: 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
  • 实现逻辑:
    1. 计算 offset 对应的字节和位位置。
    2. 如果 offset 超出字符串的长度,返回 0。
    3. 读取目标字节并通过位运算提取目标位。
  • 源码实现:
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. 读取字符串中每个字节,逐字节统计 1 的数量。
    2. 如果指定了范围 [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 的常见优化

  1. 延迟创建字符串: 如果设置的位是 0,Redis 不会立即分配内存存储字符串。
  2. 按需扩展: 设置位时,如果超过当前字符串长度,Redis 会自动扩展存储。
  3. 低层优化: Redis 利用 CPU 指令,如 __builtin_popcount 快速统计 1 的数量。

应用场景

  1. 用户签到:记录每天用户是否签到。
  2. 状态管理:如设备是否可用。
  3. 去重与快速过滤:记录某项操作是否完成。

相关文章:

c++ 位图和布隆过滤器

位图&#xff08;bitmap&#xff09; 定义 位图是一种使用位数组存储数据的结构。每一位表示一个状态&#xff0c;通常用于快速判断某个值是否存在&#xff0c;或者用来表示布尔类型的集合。 特点 节省空间&#xff1a;一个字节可以表示8个状态。高效操作&#xff1a;位操作…...

阿里云CPU过载的一点思考

现象&#xff1a;阿里云ECS服务器连续5个周期CPU超90%告警 分析&#xff1a; max_connections和max_user_connections都做了限制&#xff0c;但是依然告警&#xff0c;服务器上有四个子服务&#xff0c;查看了每个服务的配置文件&#xff0c;发现使用同一个数据库账号&#x…...

单片机学习笔记 15. 串口通信(理论)

更多单片机学习笔记&#xff1a;单片机学习笔记 1. 点亮一个LED灯单片机学习笔记 2. LED灯闪烁单片机学习笔记 3. LED灯流水灯单片机学习笔记 4. 蜂鸣器滴~滴~滴~单片机学习笔记 5. 数码管静态显示单片机学习笔记 6. 数码管动态显示单片机学习笔记 7. 独立键盘单片机学习笔记 8…...

算法训练营day22(二叉树08:二叉搜索树的最近公共祖先,插入,删除)

第六章 二叉树part08 今日内容&#xff1a; ● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点 详细布置 235. 二叉搜索树的最近公共祖先 相对于 二叉树的最近公共祖先 本题就简单一些了&#xff0c;因为 可以利用二叉搜索树的…...

Linux history 命令详解

简介 history 命令显示当前 shell 会话中以前执行过的命令列表。这对于无需重新输入命令即可重新调用或重新执行命令特别有用。 示例用法 显示命令历史列表 history# 示例输出如下&#xff1a;1 ls -l 2 cd /var/log 3 cat syslog执行历史记录中的命令 !<number>…...

Kafka知识体系

一、认识Kafka 1. kafka适用场景 消息系统&#xff1a;kafka不仅具备传统的系统解耦、流量削峰、缓冲、异步通信、可扩展性、可恢复性等功能&#xff0c;还有其他消息系统难以实现的消息顺序消费及消息回溯功能。 存储系统&#xff1a;kafka把消息持久化到磁盘上&#xff0c…...

【Android】EventBus的使用及源码分析

文章目录 介绍优点基本用法线程模式POSTINGMAINMAIN_ORDEREDBACKGROUNDASYNC 黏性事件 源码注册getDefault()registerfindSubscriberMethods小结 postpostStickyunregister 介绍 优点 简化组件之间的通信 解耦事件发送者和接收者在 Activity、Fragment 和后台线程中表现良好避…...

【大数据学习 | Spark调优篇】Spark之内存调优

1. 内存的花费 1&#xff09;每个Java对象&#xff0c;都有一个对象头&#xff0c;会占用16个字节&#xff0c;主要是包括了一些对象的元信息&#xff0c;比如指向它的类的指针。如果一个对象本身很小&#xff0c;比如就包括了一个int类型的field&#xff0c;那么它的对象头实…...

Linux:文件系统inode

早期&#xff0c;存储文件的设备是磁盘&#xff08;当下的市场几乎都是SSD&#xff09;&#xff0c;但大家习惯的把它们都称为磁盘&#xff0c;磁盘是用来表示区分内存的存储设备。而在操作系统看来&#xff0c;这个存储设备的结构就是一个线性结构&#xff0c;这一点很重要。 …...

力扣难题解析

滑动窗口问题 76.最小覆盖子串 题目链接&#xff1a;76. 最小覆盖子串 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空…...

4.5-Channel 和 Flow:SharedFlow 和 StateFlow

文章目录 SharedFlow数据流的收集和事件订阅的区别launchIn() 和 shareIn() 的区别SharedFlow 与 Flow、Channel 的区别shareIn() 适用场景 shareIn() 的具体参数说明shareIn() 的 replay 参数shareIn() 的 started 参数WhileSubscribed() 的参数及适用场景 MutableSharedFlow、…...

Qt | TCP服务器实现QTcpServer,使用线程管理客户端套接字

点击上方"蓝字"关注我们 01、QTcpServer >>> QTcpServer 是 Qt 网络模块中的一个类,用于实现TCP服务器。它允许创建一个服务器,可以接受来自客户端的连接。QTcpServer 是事件驱动的,这意味着它将通过信号和槽机制处理网络事件。 常用函数 构造函数: QT…...

【提高篇】3.6 GPIO(六,寄存器介绍,下)

目录 2.3 输出速度寄存器OSPEEDR(GPIOx_OSPEEDR) (x = A..I) 2.4 上拉/下拉寄存器 (GPIOx_PUPDR) (x = A..I) 2.5 输入数据寄存器(IDR) 2.6 输出数据寄存器(ODR) 2.7 置位/复位寄存器(BSRR) 2.8 BSRR与ODR寄存器的区别 2.3 输出速度寄存器OSPEEDR(GPIOx_OSPEEDR) (…...

【AI】数据,算力,算法和应用(3)

三、算法 算法这个词&#xff0c;我们都不陌生。 从接触计算机&#xff0c;就知道有“算法”这样一个神秘的名词存在。象征着专业、权威、神秘、高难等等。 算法是一组有序的解决问题的规则和指令&#xff0c;用于解决特定问题的一系列步骤。算法可以被看作是解决问题的方法…...

深度学习笔记——生成对抗网络GAN

本文详细介绍早期生成式AI的代表性模型&#xff1a;生成对抗网络GAN。 文章目录 一、基本结构生成器判别器 二、损失函数判别器生成器交替优化目标函数 三、GAN 的训练过程训练流程概述训练流程步骤1. 初始化参数和超参数2. 定义损失函数3. 训练过程的迭代判别器训练步骤生成器…...

网络安全开源组件

本文只是针对开源项目进行收集&#xff0c;如果后期在工作中碰到其他开源项目将进行更新。欢迎大家在评论区留言&#xff0c;您在工作碰到的开源项目。 祝您工作顺利&#xff0c;鹏程万里&#xff01; 一、FW&#xff08;防火墙&#xff09; 1.1 pfSense pfSense项目是一个免费…...

Python毕业设计选题:基于django+vue的智慧社区可视化平台的设计与实现+spider

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 养老机构管理 业主管理 社区安防管理 社区设施管理 车位…...

Oracle LinuxR7安装Oracle 12.2 RAC集群实施(DNS解析)

oracleLinuxR7-U6系统Oracle 12.2 RAC集群实施&#xff08;DNS服务器&#xff09; 环境 RAC1RAC2DNS服务器操作系统Oracle LinuxR7Oracle LinuxR7windows server 2008R2IP地址172.30.21.101172.30.21.102172.30.21.112主机名称hefei1hefei2hefei数据库名hefeidbhefeidb实例名…...

M2芯片安装es的步骤

背景&#xff1a;因为最近经常用到es&#xff0c;但是测试环境没有es&#xff0c;自己本地也没安装&#xff0c;为了方便测试&#xff0c;然后安装一下&#xff0c;但是刚开始安装就报错&#xff0c;记录一下&#xff0c;安装的版本为8.16.1 第一步&#xff1a;去官网下载maco…...

macos下brew安装redis

首先确保已安装brew&#xff0c;接下来搜索资源&#xff0c;在终端输入如下命令&#xff1a; brew search redis 演示如下&#xff1a; 如上看到有redis资源&#xff0c;下面进行安装&#xff0c;执行下面的命令&#xff1a; brew install redis 演示效果如下&#xff1a; …...

第六届金盾信安杯-SSRF

操作内容&#xff1a; 进入环境 可以查询网站信息 查询环境url https://114.55.67.167:52263/flag.php 返回 flag 就在这 https://114.55.67.167:52263/flag.php 把这个转换成短连接&#xff0c;然后再提交 得出 flag...

【论文投稿】国产游戏技术:迈向全球引领者的征途

【IEEE出版南方科技大学】第十一届电气工程与自动化国际会议&#xff08;IFEEA 2024)_艾思科蓝_学术一站式服务平台 更多学术会议论文投稿请看&#xff1a;https://ais.cn/u/nuyAF3 目录 国产游戏技术能否引领全球&#xff1f; 一、国产游戏技术的崛起之路 1.1 初期探索与积…...

腾讯微众银行大数据面试题(包含数据分析/挖掘方向)面试题及参考答案

为什么喜欢使用 XGBoost,XGBoost 的主要优势有哪些? XGBoost 是一个优化的分布式梯度增强库,在数据科学和机器学习领域应用广泛,深受喜爱,原因主要在于其众多突出优势。 首先,它的精度高,在许多机器学习竞赛和实际应用中,XGBoost 都展现出卓越的预测准确性。其基于决策…...

【Linux】死锁、读写锁、自旋锁

文章目录 1. 死锁1.1 概念1.2 死锁形成的四个必要条件1.3 避免死锁 2. 读者写者问题与读写锁2.1 读者写者问题2.2 读写锁的使用2.3 读写策略 3. 自旋锁3.1 概念3.2 原理3.3 自旋锁的使用3.4 优点与缺点 1. 死锁 1.1 概念 死锁是指在⼀组进程中的各个进程均占有不会释放的资源…...

Spring Web开发(请求)获取JOSN对象| 获取数据(Header)

大家好&#xff0c;我叫小帅今天我们来继续Spring Boot的内容。 文章目录 1. 获取JSON对象2. 获取URL中参数PathVariable3.上传⽂件RequestPart3. 获取Cookie/Session3.1 获取和设置Cookie3.1.1传统获取Cookie3.1.2简洁获取Cookie 3. 2 获取和存储Session3.2.1获取Session&…...

用c语言完成俄罗斯方块小游戏

用c语言完成俄罗斯方块小游戏 这估计是你在编程学习过程中的第一个小游戏开发&#xff0c;怎么说呢&#xff0c;在这里只针对刚学程序设计的学生&#xff0c;就是说刚接触C语言没多久&#xff0c;有一点功底的学生看看&#xff0c;简陋的代码&#xff0c;简陋的实现&#xff0…...

SpringBoot整合Retry详细教程

问题背景 在现代的分布式系统中&#xff0c;服务间的调用往往需要处理各种网络异常、超时等问题。重试机制是一种常见的解决策略&#xff0c;它允许应用程序在网络故障或临时性错误后自动重新尝试失败的操作。Spring Boot 提供了灵活的方式来集成重试机制&#xff0c;这可以通过…...

JS API事件监听(绑定)

事件监听 语法 元素对象.addEventListener(事件监听,要执行的函数) 事件监听三要素 事件源&#xff1a;那个dom元素被事件触发了&#xff0c;要获取dom元素 事件类型&#xff1a;用说明方式触发&#xff0c;比如鼠标单击click、鼠标经过mouseover等 事件调用的函数&#x…...

ceph手动部署

ceph手动部署 一、 节点规划 主机名IP地址角色ceph01.example.com172.18.0.10/24mon、mgr、osd、mds、rgwceph02.example.com172.18.0.20/24mon、mgr、osd、mds、rgwceph03.example.com172.18.0.30/24mon、mgr、osd、mds、rgw 操作系统版本&#xff1a; Rocky Linux release …...

superset load_examples加载失败解决方法

如果在执行load_examples命令后,出现上方图片情况,或是相似报错(url error\connection error),大概率原因是python程序请求github数据,无法访问. 因此我们可以将数据下载在本地来解决. 1.下载zip压缩文件,存放到本地 官方示例地址:GitHub - apache-superset/examples-data …...

佛山市建设小学网站/网络营销优化培训

IIS最近有个别客户反映购买的在线人数(IIS连接数)和实际不符合&#xff0c;现在特说明如下首先了解什么是IIS连接数。IIS连接数指并发连接数&#xff0c;什么意思呢&#xff1f;要分几种情况&#xff1a;(以100M空间50人在线为例)A 用户单点下载你的文件&#xff0c;结束后正常…...

深圳做网站的好公司有哪些/关键词文案生成器

在工作中遇到需要进行批量装机的情况下&#xff0c;我们可以部署PXEKickstart无人值守安装操作系统&#xff0c;它可以批量自动安装操作系统&#xff0c;提高效率。 操作环境&#xff1a;一台VMware 12 虚拟机和REHL6.5系统的虚拟机可互联互通REHL6.5系统虚拟机为服务器&#x…...

上海浦东做网站/网站优化排名服务

在给 MySQL 数据库访问层增加新功能时遇到了这样的错误&#xff1a;1 ProgrammingError: (2014, "Commands out of sync; you cant run this comnd now")之前零星地见到过几次&#xff0c;因为发生频度很低&#xff0c;就没有太在意&#xff0c;这次找了一下原因&…...

做电影网站解决版权问题/网页设计论文

测试和开发过程中&#xff0c;有时候需要修改接口的返回状态&#xff0c;或是返回值。在Charles中可以通过远程映射&#xff0c;将另一个接口的响应返回给原接口&#xff0c;从而达到修改接口响应的目的。这个功能还能在正式线域名和测试线域名切换上。 文章目录一、原理二、操…...

石家庄便宜做网站/seo关键词排名优化要多少钱

问题如图所示&#xff1a; 解决办法&#xff1a;这种情况只需要全选该段落&#xff0c;然后点击右键选择【段落】-【中文版式】-【允许西文在单词中间换行】即可&#xff0c;不要忘了给换行时被分隔的单词中间加一个连词符“-”。...

英国做电商网站有哪些/seo快速排名案例

普通用户 -> root mac打开终端默认是当前登录用户&#xff0c;若要切换到root用户&#xff0c;使用命令&#xff1a; 方法1 输入 sudo -i 或者 su - 或者 su - root 然后回车 输入密码&#xff0c;就可以进入root用户 这种方法的终端显示形式为&#xff1a;usernamedeM…...