[Collection与数据结构] 位图与布隆过滤器
🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (93平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
🎃Redis(97平均质量分)https://blog.csdn.net/2301_80050796/category_12777129.html?spm=1001.2014.3001.5482
🐰RabbitMQ(97平均质量分) https://blog.csdn.net/2301_80050796/category_12792900.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
目录
- 1. 常见位运算总结
- 2. 位图
- 2.1 位图的概念
- 2.2 位图的实现
- 2.3 位图的应用
- 2.4 对应java中的类
- 3. 布隆过滤器
- 3.1 布隆过滤器的提出
- 3.2 布隆过滤器的概念
- 3.3 布隆过滤器的插入
- 3.4 布隆过滤器的查找
- 3.5 布隆过滤器的模拟实现
- 3.6 布隆过滤器的缺陷
- 3.7 布隆过滤器的优点
- 3.8 布隆过滤器的常见使用场景
- 4. 海量数据处理
- 4.1 哈希切割
- 4.2 位图应用
- 4.3 布隆过滤器的应用
1. 常见位运算总结
- 基础位运算
<<
: 二进制左移.
>>
:二进制右移.
~
:二进制取反.
&
: 有0就是0,全1才是1.
|
: 有1就是1,全0才是0.
^
: 相同为0,相异位1.其实也可以看做是一种无进位相加. - 给定一个数n,确定他的二进制表示的第x位是0还是1
可以把这个数字n进行左移x位,之后&
上一个二进制1,如果结果是1,说明该位是1,如果结果是0,说明该位是0. - 将一个数n的二进制表示的第x位修改为1.
可以把二进制1左移x位,之后n|=
左移x位之后的这个数字. - 将一个数n的二进制表示的第x位修改成0.
首先把一个二进制1取反,之后再左移x位,之后n&=
左移x位之后的这个数字. - 提取一个数n二进制表示中最右侧的1.
n&(~n+1)
- 干掉一个数n二进制表示中最右侧的1.
n&(n-1)
- 异或
^
运算的运算律
消消乐运算律- a^0 = a
- a^a = 0
- a ^ b ^ c = a ^ (b ^ c)
2. 位图
2.1 位图的概念
所谓位图,就是用每一个bit位来存放某种状态,1表示一种状态,0表示另一种状态.适用于海量数据,整数,数据无重复的场景.通常用来判断某个数据是否存在.
位图之所以可以存储海量的数据,是由于位图对空间的利用率非常高.下面我们来举个例子:
给定40亿个不重复的无符号整数,没有经过排序,给一个无符号整数,如何快速判断这个数是否在这40亿个数据中存在.
我们如果使用遍历数据的方法的话,存在两个问题,第一个问题就是内存空间有限,我们不可能把数据全部都从硬盘中读取到内存中来寻找,其次就是查找效率太低,时间复杂度为O(N).如果我们进行排序之后利用二分查找算法来查找,只能一定程度上解决时间效率上的问题,不可解决空间效率上的问题.
所以我们可以使用位图来解决:
数据是否给定的整形数据中,结果是在或者是不在,刚好是两种状态,那么可以使用一个二进制位来表示数据是否存在的信息,如果二进制比特位为1,代表的是存在,为0则代表的是不存在.
2.2 位图的实现
- 首先位图需要有存储数据的空间,我们使用byte[]数组来存储数据.
- 其次需要有空间使用大小.
- 使用构造方法初始化byte[]数组的空间.默认是1字节,如果指定了空间大小,那么就是
n/8+1
字节.比如n=12,除8之后就是1余4,也就是我们需要存储在第二个字节的第4个比特位,此时我们就需要2个byte.如果正好是在第8个bit位的时候,可能会多出来一个字节,但是也没有关系. - 插入数据,首先/8计算在那个字节,之后判断有没有越界的情况,如果越界,使用
copyof
方法进行扩容,之后%8,计算在那个bit位存储这个数据,之后使用我们上面提到的常用的位运算来把指定的bit为改为1. - 查找数据,首先还是把数据/8之后%8,之后还是使用我们上面的常用位运算验证对应的bit位是否是1.
- 删除某个数据,还是先把数据/8之后%8,之后还是使用我们上面的常用位运算把对应的bit为改为0.
代码实现:
import java.util.Arrays;public class MyBitSet {private byte[] elem;public int usedSize;public MyBitSet(){this.elem = new byte[1];}public MyBitSet(int size){this.elem = new byte[size/8+1];}/*** 添加指定元素* @param val 指定元素* @return 返回是否添加成功*/public boolean add(int val){if (val < 0){//不支持负数throw new RuntimeException("val not support lower than 0");}int byteSet = val / 8;int bitSet = val % 8;if (byteSet > elem.length-1){//容量不够,扩容elem = Arrays.copyOf(elem,elem.length*2);}elem[byteSet] |= (byte) (1 << bitSet);usedSize++;return true;}/*** 是否包含指定元素* @param val 指定元素* @return 返回是否存在*/public boolean contains(int val){if (val < 0){throw new RuntimeException("val not support lower than 0");}int byteSet = val / 8;int bitSet = val % 8;if ((elem[byteSet] & (byte) (1 << bitSet)) != 0){return true;}return false;}/*** 删除指定元素* @param val 指定元素*/public void del(int val){if (val < 0){throw new RuntimeException("val not support lower than 0");}int byteSet = val / 8;int bitSet = val % 8;elem[byteSet] &= (byte) ~(1 << bitSet);usedSize--;}
}
2.3 位图的应用
- 去重+排序
位图这种数据结构本身就是一个萝卜一个坑,一个数据在位图中只能存在一次,其次,位图本身就是从小到大存储数据,只要把位图中的元素遍历一遍,就可以从小到大输出数据.下面是遍历位图的实现:
/*** 输出位图中的数据*/
public void display(){for (int i = 0;i < elem.length;i++){for (int j = 0;j < 8;j++){if ((elem[i] & (1<<j)) != 0){System.out.print(i*8+j+" ");}}}
}
- 求两个交集的交集,并集.
把两个位图进行&
运算,就可以求出交集,把连个位图进行|
就可以求出并集.
对位图进行测试进行测试:
public class Main {public static void main(String[] args) {MyBitSet bitSet = new MyBitSet();bitSet.add(3);bitSet.add(7);bitSet.add(10);bitSet.add(9);bitSet.add(5);System.out.println(bitSet.contains(5));bitSet.del(10);bitSet.display();}
}
测试结果符合预期:
3. 操作系统重磁盘块的标记
2.4 对应java中的类
位图在java中被封装为了BitSet
这个类,不同的一点就是,我们自己实现的这个位图是用byte数组来保存数据的,在除和取模的时候是以8为单位来计算的,而java封装的这个位图是使用long数组来保存数据的,在除和取模的时候是使用64为单位来计算的,下面是常用的一些方法:
返回值 | 方法名 | 描述 |
---|---|---|
void | clear(int bitIndex) | 将指定的bit为设置为0 |
boolean | get(int bitIndex) | 查看指定的值是否在位图中 |
void | set(int bitIndex) | 将指定位置的值设置为1 |
String | toString() | 将这个位图按照字符串的形式表示出来 |
下面是使用实例
public static void main(String[] args) {BitSet bitSet = new BitSet();bitSet.set(1);bitSet.set(2);bitSet.set(3);bitSet.set(4);bitSet.set(5);bitSet.set(6);System.out.println(bitSet.toString());System.out.println(bitSet.get(1));bitSet.clear(2);System.out.println(bitSet.get(2));System.out.println(bitSet.toString());
}
测试结果:
3. 布隆过滤器
3.1 布隆过滤器的提出
日常生活中,包括在设计计算机软件时,我们经常要判断一个元素是否在一个集合中。比如在字处理软件
中,需要检查一个英语单词是否拼写正确(也就是要判断它是否在已知的字典中);在 FBI,一个嫌疑人的
名字是否已经在嫌疑名单上;在网络爬虫里,一个网址是否被访问过等等。最直接的方法就是将集合中全部
的元素存在计算机中,遇到一个新元素时,将它和集合中的元素直接比较即可。
一般来讲,计算机中的集合是用哈希表(hash table)来存储的。它的好处是快速准确,缺点是费存储空
间。当集合比较小时,这个问题不显著,但是当集合巨大时,哈希表存储效率低的问题就显现出来了。
比如说,一个像 Yahoo,Hotmail 和 Gmai 那样的公众电子邮件(email)提供商,总是需要过滤来自发送垃
圾邮件的人(spamer)的垃圾邮件。一个办法就是记录下那些发垃圾邮件的 email 地址。由于那些发送者
不停地在注册新的地址,全世界少说也有几十亿个发垃圾邮件的地址,将他们都存起来则需要大量的网络服
务器。
如果用哈希表,每存储一亿个 email 地址, 就需要 1.6GB 的内存(用哈希表实现的具体办法是将每一个
email 地址对应成一个八字节的信息指纹,然后将这些信息指纹存入哈希表,由于哈希表的存储效率一般只有
50%,因此一个 email 地址需要占用十六个字节。一亿个地址大约要 1.6GB, 即十六亿字节的内存)。因此
存贮几十亿个邮件地址可能需要上百 GB 的内存。除非是超级计算机,一般服务器是无法存储的。
- 用哈希表存储用户记录,缺点:浪费空间
- 用位图存储用户记录,缺点:位图一般只能处理整形,如果内容编号是字符串,就无法处理了。
- 将哈希与位图结合,即布隆过滤器.
3.2 布隆过滤器的概念
布隆过滤器是一种紧凑的,比较巧妙的概率型数据结构,特点是高效的插入和查询,可以用来告诉你某样东西一定不存在或者可能存在,不可以判断某样东西一定存在,他是用多个哈希函数,将一个数据映射到位图的结构中.此种方式不仅仅可以提升查询的效率,也可以节省大量的内存空间.
布隆过滤器与位图最大的区别就是,位图适合处理大量的整数.适合对这些整数进行查找/排序/去重,但如果不是整数,但是依然还是想在位图中存储数据,那么就需要使用到布隆过滤器.
3.3 布隆过滤器的插入
比如我们要向布隆过滤器中插入"baidu"和"tencent".
我们首先需要把这个字符经过不同的哈希函数进行映射,得到一个值之后,把他映射到位图之上.
我们看到在插入不同的数据的时候,经过不同的哈希函数映射之后的值是有可能产生重合的值的.如果这些值全部重合的话,在查找的时候就有可能产生误判.下面我们就来解释查找操作.
3.4 布隆过滤器的查找
布隆过滤器的思想是将一个元素用多个哈希函数映射到一个位图中,因此被映射到的位置的bit位一定为1.所以可以按照一下的方式进行查找:分别计算每个哈希值对应的比特位置存储的是否为0,只要有一个为0,代表该元素一定不在位图中,否则可能在哈希表中.
注意:布隆过滤器如果判断某个元素一定不存在时,该元素一定不存在,如果该元素存在时,则该元素可能存在,因为哈希函数映射之后存在一定的误判概率.
比如:在不同过滤器中查找alibaba时,假设经过哈希函数计算出的哈希值为1,3,7,刚好和其他元素的比特位重叠,此时布隆过滤器告诉该元素存在,但实际上元素是不存在的.
3.5 布隆过滤器的模拟实现
- 首先我们需要定义一个hash函数类,其中包含容积和随机种子.
- 之后我们需要在定义一个hash方法,使用这个hash函数求出对应的hash值.
- 实现布隆过滤器,布隆过滤器中存在若干个随机种子和默认容积.
- 存在hash函数数组,在为位图中设置值的时候,需要经过hash数组中每一个hash函数的计算,数组中每一个hash函数都会计算出一个hash值,最后我们需要把这些hash值全部设置到位图当中去.
import java.util.BitSet;/*** 创建Hash函数*/
class SimpleHash{private int cap;//容量private int seed;//随机种子public SimpleHash(int cap, int seed) {this.cap = cap;this.seed = seed;}/*** 根据容量和随机数种子计算得到val的Hash值* @param val 传入的值* @return 返回Hash值*/public int hash(String val){int ret = 0;int len = val.length();for (int i = 0;i < len;i++){ret = ret * seed + val.charAt(i);}return (cap-1) & ret;}
}/*** 布隆过滤器*/
public class MyBloomFilter {private static final int DEFAULT_SIZE = 1 << 24;//默认容积private static final int[] seeds = {1,6,3,5,10};//一共5个随机种子,在映射到位图中就需要把一个值映射到5个bit位.public int size;//过滤器存储元素的个数private SimpleHash[] simpleHashes;//不同种子的哈希函数private BitSet bitSet;//存储元素的位图public MyBloomFilter(){bitSet = new BitSet();//初始化位图//初始化哈希函数数组simpleHashes = new SimpleHash[seeds.length];for (int i = 0;i < seeds.length;i++){SimpleHash simpleHash = new SimpleHash(DEFAULT_SIZE,seeds[i]);simpleHashes[i] = simpleHash;}}/*** 为布隆过滤器中设置指定的值* @param val 指定的值*/public void set(String val){if (val == null){return;}for (SimpleHash simpleHash : simpleHashes) {bitSet.set(simpleHash.hash(val));}size++;}/*** 获取指定的值是否在布隆过滤器中存在* @param val 需要获取的值* @return 返回是否在布隆过滤器中存在*/public boolean get(String val){if (val == null){return false;}for (SimpleHash simpleHash : simpleHashes) {if (!bitSet.get(simpleHash.hash(val))) {//如果有一个不存在,就返回falsereturn false;}}return true;//如果全部存在,则可能存在}
}
3.6 布隆过滤器的缺陷
- 布隆过滤器不能直接支持删除操作,因为在删除一个元素的时候,可能会影响到其他的元素.
比如我们上面"baidu"和"tencent"的例子,想要在布隆过滤器中删除"tencent"元素,如果直接将该元素所对应的二进制位置为0,"tencent"元素和"baidu"元素刚好有一个重叠的位置,那么"baidu"元素也被删除了. - 有误判率,即不能准确判断元素是否在集合中存在.
- 不能获取元素本身
3.7 布隆过滤器的优点
- 增加和查询元素的时间复杂度为:O(K), (K为哈希函数的个数,一般比较小),与数据量大小无关,所以化简之后时间复杂度为O(1).
- 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势
- 在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势,数据量很大的时候,布隆过滤器可以表示全集,而其他数据结构不可以.
3.8 布隆过滤器的常见使用场景
- 网页爬虫对URL的去重,避免爬取相同的URL地址.
- 垃圾邮件的过滤,从数十亿个垃圾邮件列表中判断某邮件是否为垃圾邮件.
- 解决数据库缓存击穿问题,当黑客攻击服务器的时候,会构建大量不存在于缓存中的key向服务器发起请求,在数据量足够大的时候,频繁的数据库查询会导致数据库服务器宕机.
- 秒杀系统,查看用户是否存在重复购买.
4. 海量数据处理
4.1 哈希切割
给一个超过100G大小的log file.log中保存着IP地址,设计算法找到出现次数最多的IP地址.
- IP本身是一个字符串,先把使用哈希函数把一个字符串变为一个hash值,
hash(IP)
- 我们需要把这些地址存入不同的文件中,首先计算出IP地址需要在那个文件中存放,即存放文件的下标.
index = hash(IP)%文件数
- 把每个小文件都加载到内存中,统计每个文件中出现IP的次数(使用Map统计).
4.2 位图应用
- 给定100亿个整数,设计算法找到只出现一次的整数.
我们可以使用位图来解决,其中有两个位图,我们针对没有出现的数据在两个位图中分别使用0 0
来表示,针对只出现一次数据在两个位图中分别用1 0
表示,针对出现两次的数据分别使用0 1
来表示,针对出现两次以上的数据使用1 1
来表示.
- 给定两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件的交集.
- 第一种方法使用哈希切割的方法
首先我们把一个文件拆分为多个小文件,之后比较每个小文件中的交集((1,1)文件,(2,2)文件依次比较). - 第二种方法是使用位图的算法.
遍历第一个文件,把存在的数据存放到位图中,之后遍历第二个文件,看读取到的数据是否在位图中存在,如果存在,就是交集.
- 第一种方法使用哈希切割的方法
4.3 布隆过滤器的应用
- 给定两个文件,分别有100亿个query,我们只有1G内存,如果找到两个文件的交集,分别给出精确的算法和近似的算法.
- 精确算法: 利用哈希切割,把两个大文件利用hash函数分为若干个小文件,之后比较小文件之间的交集((1,1)文件,(2,2)文件以此类推).
- 近似算法: 把第一个文件中的query使用hash函数映射到布隆过滤器中,之后再把第二个文件中的query使用hash函数映射出对应的值.之后再从布隆过滤器中查找,如果存在,就是交集.如果不存在就不是.
相关文章:

[Collection与数据结构] 位图与布隆过滤器
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...

idea中新建一个空项目
目的,为了在同一个目录下有多个小的项目:使用IDE为idea2022。 步骤: 点击新建项目,点击创建空项目,这里选择空项目是将其作为其他项目的一个容器,如图所示: 然后点击文件->项目结构…...
【Python】【Conda 】Conda 与 venv 虚拟环境优缺点全解:如何做出明智选择
目录 引言一、基本概念1.1 Conda 虚拟环境1.2 Python venv 虚拟环境 二、主要区别对比三、优缺点分析3.1 Conda 虚拟环境的优缺点3.2 Python venv 虚拟环境的优缺点 四、使用场景推荐4.1 使用 Conda 虚拟环境的场景4.2 使用 Python venv 虚拟环境的场景 五、虚拟环境管理工具对…...
深度学习在故障检测中的应用:从理论到实践
随着工业设备和信息系统的复杂性增加,故障检测成为企业运维的重要任务。然而,传统的基于规则或统计学的故障检测方法难以应对复杂多变的故障模式。深度学习作为一种强大的数据分析工具,为故障检测提供了新的解决思路。本文将介绍深度学习模型…...
自然语言处理与人工智能
自然语言处理(NLP)与人工智能(AI) 自然语言处理(NLP)是人工智能(AI)领域的一个重要分支,旨在使计算机能够理解、解释和生成自然语言。随着深度学习技术的进步࿰…...
量化交易系统开发-实时行情自动化交易-8.15.Ptrade/恒生平台
19年创业做过一年的量化交易但没有成功,作为交易系统的开发人员积累了一些经验,最近想重新研究交易系统,一边整理一边写出来一些思考供大家参考,也希望跟做量化的朋友有更多的交流和合作。 接下来会对于Ptrade/恒生平台介绍。 P…...

非常简单实用的前后端分离项目-仓库管理系统(Springboot+Vue)part 4
三十三、出入库管理 Header.vue导一下,RecordController加一个 //将入库数据和原有数据相加吧//新增PostMapping("/save")public Result save(RequestBody Record record) {return recordService.save(record) ? Result.success() : Result.fail();} GoodsManage.v…...

基于MATLAB的信号处理工具:信号分析器
信号(或时间序列)是与特定时间相关的一系列数字或测量值,不同的行业和学科将这一与时间相关的数字序列称为信号或时间序列。生物医学或电气工程师会将其称为信号,而统计学家或金融定量分析师会使用时间序列这一术语。例如…...

Codeforces Round 784 (Div. 4)
题目链接 A. Division? 题意 思路 模拟即可 示例代码 void solve() {int n;cin >> n;int ans;if(n > 1900) ans 1;else if(n > 1600) ans 2;else if(n > 1400) ans 3;else ans 4;cout << "Division " << ans << \n;}B. T…...

OpenNebula 开源虚拟平台,对标 VMware
Beeks Group 主要为金融服务提供商提供虚拟专用服务器和裸机服务器。该公司表示,转向 OpenNebula 不仅大幅降低了成本,还使其虚拟机效率提升了 200%,并将更多裸机服务器资源用于客户端负载,而非像以往使用 VMware 时那样用于虚拟机…...

软件项目标书参考,合同拟制,开发合同制定,开发协议,标书整体技术方案,实施方案,通用套用方案,业务流程,技术架构,数据库架构全资料下载(原件)
1、终止合同协议书 2、项目合作协议 3、合同交底纪要 4、合同管理台账 软件资料清单列表部分文档清单:工作安排任务书,可行性分析报告,立项申请审批表,产品需求规格说明书,需求调研计划,用户需求调查单&…...

Jenkins环境一站式教程:从安装到配置,打造高效CI/CD流水线环境-Ubuntu 22.04.5 环境离线安装配置 Jenkins 2.479.1
文章目录 Jenkins环境一站式教程:从安装到配置,打造高效CI/CD流水线环境-Ubuntu 22.04.5 环境离线安装配置 Jenkins 2.479.1一、环境准备1.1 机器规划1.2 环境配置1.2.1 设置主机名1.2.2 停止和禁用防火墙1.2.3 更新系统 二、安装配置Jenkins2.1 安装JDK…...
【Android】ARouter源码解析
本篇文章主要讲解了 ARouter 框架的源码分析,包括其初始化过程、核心方法等。 初始化 在使用ARouter的时候我们都会先进行初始化: ARouter.init(this);我们看下 init() 源码: public static void init(Application application) {// 检查…...

计算直线的交点数
主要实现思路 整体流程思路: 程序旨在解决给定平面上不同数量的直线(无三线共点),求出每种直线数量下所有可能的交点数量,并按要求格式输出的问题。整体通过初始化一个二维数组来存储不同直线数量与交点数量对应的存在…...
STM32基于HAL库的串口接收中断触发机制和适用场景
1. HAL_UART_Receive_DMA函数 基本功能 作用:启动一个固定长度的 DMA 数据接收。特点: 需要预先指定接收数据的长度(Size 参数)。DMA 会一直工作直到接收到指定数量的数据,接收完成后触发 HAL_UART_RxCpltCallback 回…...

java面试宝典
本文只摘抄部分宝典内容,完整宝典可以在打开下方链接,在网盘获取 ^ _ ^ 链接:java面试宝典 提取码: wxy1 复制这段内容后打开百度网盘手机App,操作更方便哦 链接: java前端面试宝典 提取码: wxy1 复制这段内容后打开百度网盘手机Appÿ…...

Scala—Slice(提取子序列)方法详解
Scala—Slice(提取子序列)方法详解 在 Scala 中,slice 方法用于从集合中提取一个连续的子序列(切片)。可以应用于多种集合类型,如 List、Array、Seq 等。 一、slice 方法的定义 slice 根据提供的起始索引…...

【电子通识】案例:USB Type-C USB 3.0线缆做直通连接器TX/RX反向
【电子通识】案例:连接器接线顺序评估为什么新人总是评估不到位?-CSDN博客这个文章的后续。最近在做一个工装项目,需要用到USB Type-C线缆做连接。 此前已经做好了线序规划,结果新人做成实物后发现有的USB Type-C线缆可用,有的不行。其中发现USB3.0的TX-RX信号与自己的板卡…...

【SKFramework框架核心模块】3-5、函数扩展模块
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享QQ群:398291828小红书小破站 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 【Unity3D框架】SKFramework框架完全教程《全…...

使用 EasyExcel 提升 Excel 处理效率
目录 前言1. EasyExcel 的优点2. EasyExcel 的功能3. 在项目中使用 EasyExcel3.1 引入依赖3.2 实体类的定义与注解3.3 工具类方法的实现3.4 在 Controller 中使用 4. 总结5. 参考地址 前言 在日常开发中,Excel 文件的处理是不可避免的一项任务,特别是在…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...