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

Redis的BitMap实现分布式布隆过滤器

布隆过滤器(Bloom Filter)是一种高效的概率型数据结构,用于判断一个元素是否属于一个集合。它通过使用哈希函数和位数组来存储和查询数据,具有较快的插入和查询速度,并且占用空间相对较少。

引入依赖

<!--切面-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><!-- 数据库-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version>
</dependency>

properties配置

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/itcast?serverTimezone=GMT%2B8&useUnicode=true&logger=Slf4JLogger&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root123
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.pool-name=HikariCPDatasource
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=180000
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
mybatis-plus.configuration.log-impl= org.apache.ibatis.logging.stdout.StdOutImpl
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.timeout=10s
spring.redis.password=123

自定义注解


import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 此注解可作用于控制器方法,或者服务类方法** 使用示例,在目标方法上添加如下注解* <pre>*     BitMap(key = "user", id = "#id")* </pre>**/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface BitMap {/*** <p>同一类集合的唯一标识符 商品表、订单表分别设置不同key</p>*/String key();/*** 支持{@code SPEL}表达式* 含义是以被调用方法参数<code>id</code>的值作为主键ID*/String id() default "#id";
}

切面

import com.example.demo.annotation.BitMap;
import com.example.demo.util.ParserUtils;
import com.example.demo.util.RedisBitMapUtils;
import com.example.demo.util.ResponseResult;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.TreeMap;/*** Redis BitMap AOP**/
@Aspect
@Component
public class BitMapAspect {private static final Logger logger = LoggerFactory.getLogger(BitMapAspect.class);@Resourceprivate RedisBitMapUtils redisBitMapUtils;@Pointcut("@annotation(com.example.demo.annotation.BitMap)")public void aspect() {}@Around("aspect()")public Object doAround(ProceedingJoinPoint point) throws Throwable {// 通过 point 对象获取方法签名信息。MethodSignature signature = (MethodSignature) point.getSignature();// 通过方法签名获取当前方法对象。Method method = signature.getMethod();// 获取当前方法上的 BitMap 注解。BitMap annotation = method.getAnnotation(BitMap.class);// 获取方法参数名和参数值的映射关系,并将结果保存到TreeMap中。TreeMap<String, Object> map = ParserUtils.createTreeMap(point, signature);// 从参数映射中获取 id 参数对应的值。String idString = ParserUtils.parse(annotation.id(), map);if (idString != null) {long id = Long.parseLong(idString);if (redisBitMapUtils.isPresent(annotation.key(), id)) {return point.proceed();} else {logger.info(String.format("当前主键ID{%d}不存在", id));return method.getReturnType().equals(ResponseResult.class) ? ResponseResult.okResult() : null;}}throw new RuntimeException("主键ID解析不正确,请按照参考格式书写");}}

RedisBitMap工具类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;/*** {@link RedisBitMapUtils}工具类*/
@Component
public class RedisBitMapUtils {private static final Logger logger = LoggerFactory.getLogger(RedisBitMapUtils.class);@Resourceprivate   StringRedisTemplate stringRedisTemplate ;ValueOperations<String, String> opsForValue;@PostConstructpublic  void init() {opsForValue= stringRedisTemplate.opsForValue();}/*** 该方法可以方便地将一个集合中的每个元素根据给定的映射函数进行转换,* 并返回一个新的列表。如果集合为空或为null,则返回一个空列表。* @param list* @param action* @return* @param <T>* @param <R>*/public  <T, R> List<R> toList(final Collection<T> list, final Function<? super T, ? extends R> action) {Objects.requireNonNull(action);if (Objects.nonNull(list)) {return list.stream().map(action).collect(Collectors.toList());}return Collections.emptyList();}/*** <p>本方法在首次初始化以{@code key}为参数的BitMap时执行</p>* <p>首先删除Key 然后重新构建BitMap</p>** @param <T> 主键类型* @param key 每种业务分别对应不同的Key名称* @param ids 主键ID*/public  <T extends Serializable> void init(String key, Collection<T> ids) {remove(key);setBit(key, ids);}/*** <p>本方法在首次初始化以{@code key}为参数的BitMap时执行</p>* <p>首先删除Key 然后重新构建BitMap</p>** @param key    每种业务分别对应不同的Key名称* @param list   实体类对象集合* @param action 主键列(方法引用表示)* @param <T>    实体类泛型* @param <R>    主键列泛型*/public  <T, R extends Serializable> void init(String key, Collection<T> list, Function<T, R> action) {List<R> ids = toList(list, action);init(key, ids);}/*** 检查当前主键ID在Redis BitMap中是否存在 如果存在则执行函数式回调** @param key 每种业务分别对应不同的Key名称* @param id  主键ID* @return {@code R}实例*/public  <T extends Serializable, R> R ifPresent(String key, T id, Function<T, R> action) {if (getBit(key, id)) {return action.apply(id);}return null;}/*** 检查当前主键ID在Redis BitMap中是否存在 如果存在则执行函数式回调** @param key 每种业务分别对应不同的Key名称* @param id  主键ID* @return {@code R}实例*/public  <T extends Serializable, R> R ifPresent(String key, T id, Supplier<R> supplier) {if (getBit(key, id)) {return supplier.get();}return null;}/*** 检查当前主键ID在Redis BitMap中是否存在 如果存在则返回<code>true</code>** @param key 每种业务分别对应不同的Key名称* @param id  主键ID* @return 如果存在则返回<code>true</code>*/public  <T extends Serializable> boolean isPresent(String key, T id) {return getBit(key, id);}/*** 检查当前主键ID在Redis BitMap中是否存在 如果存在则返回<code>true</code>* 本方法是{@link RedisBitMapUtils#getBit(String, Serializable)}的别名方法 方便对外调用** @param key 每种业务分别对应不同的Key名称* @param id  主键ID* @return 如果存在则返回<code>true</code>*/public  <T extends Serializable> boolean checkId(String key, T id) {return getBit(key, id);}/*** 检查当前主键ID(集合)在Redis BitMap中是否存在 只返回存在的主键ID* 本方法是{@link RedisBitMapUtils#getBit(String, Serializable)}的别名方法 方便对外调用** @param key 每种业务分别对应不同的Key名称* @param ids 主键ID* @return 返回存在的主键ID*/public  <T extends Serializable> List<T> checkIds(String key, Collection<T> ids) {return ids.stream().filter(e -> checkId(key, e)).collect(Collectors.toList());}/*** 向Redis BitMap中保存主键ID** @param key 每种业务分别对应不同的Key名称* @param id  主键ID*/public  <T extends Serializable> void setBit(String key, T id) {ifOffsetValid(Objects.hash(id), e -> opsForValue.setBit(key, e, true));}/*** 向Redis BitMap中批量保存主键ID** @param <T> 主键类型* @param key 每种业务分别对应不同的Key名称* @param ids 主键ID*/public  <T extends Serializable> void setBit(String key, Collection<T> ids) {ids.forEach(id -> ifOffsetValid(Objects.hash(id), e -> opsForValue.setBit(key, e, true)));}/*** 检查当前主键ID在Redis BitMap中是否存在 如果存在则返回<code>true</code>** @param key 每种业务分别对应不同的Key名称* @param id  主键ID* @return 如果存在则返回<code>true</code>*/public  <T extends Serializable> boolean getBit(String key, T id) {return ifOffsetValid(Objects.hash(id), e -> opsForValue.getBit(key, e));}/*** 从Redis BitMap中删除当前主键ID** @param key 每种业务分别对应不同的Key名称* @param id  主键ID*/public  <T extends Serializable> void removeBit(String key, T id) {ifOffsetValid(Objects.hash(id), e -> opsForValue.setBit(key, e, false));}/*** 从Redis BitMap中批量删除主键ID** @param key 每种业务分别对应不同的Key名称* @param ids 主键ID* @param <T> 主键类型*/public  <T extends Serializable> void removeBit(String key, Collection<T> ids) {ids.forEach(id -> ifOffsetValid(Objects.hash(id), e -> opsForValue.setBit(key, e, false)));}/*** 将当前分类下的BitMap Key删除* 清空该Key下所有数据*/public  void remove(String key) {stringRedisTemplate.delete(key);}/*** <p>检查偏移量是否合法</p>* <p>Redis字符串支持字符串最大长度512M,因此支持offset的最大值为(2^32)-1</p>** @param offset 偏移量* @param action 映射规则*/private static <N extends Number> Boolean ifOffsetValid(N offset, Function<N, Boolean> action) {Objects.requireNonNull(action);//如果ID用整型表示 那么正整数范围内所有的ID均有效 最大正整数值为2147483647 约为20亿long max = (1L << 32) - 1;if (offset.intValue() >= 0 && offset.intValue() < Integer.MAX_VALUE) {return action.apply(offset);} else {// 如果偏移量类型为长整型,或者整型范围内的最大值小于0且 offset 的值小于等于 maxif (Integer.MAX_VALUE >= 0 && offset.longValue() <= max) {return action.apply(offset);} else {logger.info(String.format("偏移量{%d}越界[0,%s],本次操作不成功!", offset.longValue(), max));return false;}}}
}

response工具类


import lombok.Data;import java.io.Serializable;
@Data
public class ResponseResult<T> implements Serializable {private Boolean success;private Integer code;private String msg;private T data;public ResponseResult() {this.success=true;this.code = HttpCodeEnum.SUCCESS.getCode();this.msg = HttpCodeEnum.SUCCESS.getMsg();}public ResponseResult(Integer code, T data) {this.code = code;this.data = data;}public ResponseResult(Integer code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}public ResponseResult(Integer code, String msg) {this.code = code;this.msg = msg;}public static ResponseResult errorResult(int code, String msg) {ResponseResult result = new ResponseResult();return result.error(code, msg);}public static ResponseResult okResult() {ResponseResult result = new ResponseResult();return result;}public static ResponseResult okResult(int code, String msg) {ResponseResult result = new ResponseResult();return result.ok(code, null, msg);}public static ResponseResult setHttpCodeEnum(HttpCodeEnum enums) {return okResult(enums.getCode(), enums.getMsg());}public static <T> ResponseResult<T> error(String message) {return new ResponseResult<T>(HttpCodeEnum.SYSTEM_ERROR.getCode(),  message);}public ResponseResult<?> error(Integer code, String msg) {this.success=false;this.code = code;this.msg = msg;return this;}public ResponseResult<?> ok(Integer code, T data) {this.success=true;this.code = code;this.data = data;return this;}public ResponseResult<?> ok(Integer code, T data, String msg) {this.success=true;this.code = code;this.data = data;this.msg = msg;return this;}public static ResponseResult ok(Object data) {ResponseResult result = new ResponseResult();result.setData(data);return result;}}

controller


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.annotation.BitMap;
import com.example.demo.annotation.PreventRepeatSubmit;
import com.example.demo.mapper.StuMapper;
import com.example.demo.model.ResponseResult;
import com.example.demo.model.Student;
import com.example.demo.util.RedisBitMapUtils;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;@RestController
@RequestMapping("/test")
@Validated
public class TestController {@Resourceprivate StuMapper stuMapper;@Resourceprivate StringRedisTemplate stringRedisTemplate;private static final String BITMAP_STU="bitmap_stu";@Resourceprivate RedisBitMapUtils redisBitMapUtils;@GetMapping("init")public com.example.demo.util.ResponseResult init(){List<Student> studentList = stuMapper.selectList(new QueryWrapper<Student>());redisBitMapUtils.init(BITMAP_STU,studentList,Student::getId);return com.example.demo.util.ResponseResult.okResult();}/*** 编程式*/@GetMapping("selectStu1/{id}")@BitMap(key = BITMAP_STU,id = "#id")public com.example.demo.util.ResponseResult selectStu1(@PathVariable Integer id){return com.example.demo.util.ResponseResult.ok(stuMapper.selectById(id));}/*** 注解式*/@GetMapping("selectStu2/{id}")public com.example.demo.util.ResponseResult selectStu2(@PathVariable Integer id){if (redisBitMapUtils.getBit(BITMAP_STU,id)){return com.example.demo.util.ResponseResult.ok(stuMapper.selectById(id));}return com.example.demo.util.ResponseResult.okResult();}}

测试

初始化biemap数据,从数据库种获取所有id并导入redis的key为bitmap_stu的数据

测试数据库存在的数据id:1,走数据库获取数据 

测试数据库的数据id:200,因为id为200不存在在数据库中,所以没有走数据库,减少了数据库压力 

 注解式也生效

达到了使用redis的bitmap实现分布式的布隆过滤器,过滤掉bitmap不存在的数据 

相关文章:

Redis的BitMap实现分布式布隆过滤器

布隆过滤器&#xff08;Bloom Filter&#xff09;是一种高效的概率型数据结构&#xff0c;用于判断一个元素是否属于一个集合。它通过使用哈希函数和位数组来存储和查询数据&#xff0c;具有较快的插入和查询速度&#xff0c;并且占用空间相对较少。 引入依赖 <!--切面--&…...

【linux API分析】module_init

linux版本&#xff1a;4.19 module_init()与module_exit()用于驱动的加载&#xff0c;分别是驱动的入口与退出函数 module_init()&#xff1a;内核启动时或动态插入模块时调用module_exit()&#xff1a;驱动移除时调用 本篇文章介绍module_init() module_init() module_init…...

NSDT孪生编辑器助力智慧城市

技术有能力改变城市的运作方式&#xff0c;提高效率&#xff0c;为游客和居民提供更好的体验&#xff0c;实现更可持续的运营和更好的决策。 当今城市面临的主要挑战是什么&#xff0c;成为智慧城市如何帮助克服这些挑战&#xff1f; 我们生活在一个日益城市化的世界&#xf…...

如何优雅的实现接口统一调用

耦合问题 有些时候我们在进行接口调用的时候&#xff0c;比如说一个push推送接口&#xff0c;有可能会涉及到不同渠道的推送&#xff0c;以我目前业务场景为例&#xff0c;我做结算后端服务的&#xff0c;会与金蝶财务系统进行交互&#xff0c;那么我结算后端会涉及到多个结算…...

tomcat、nginx实现四层转发+七层代理+动静分离实验

实验环境&#xff1a; nginx1——20.0.0.11——客户端 静态页面&#xff1a; nginx2——20.0.0.21——代理服务器1 nginx3——20.0.0.31——代理服务器2 动态页面&#xff1a; tomcat1——20.0.0.12——后端服务器1 tomcat2——20.0.0.22——后端服务器2 实验步骤&…...

交通目标检测-行人车辆检测流量计数 - 计算机竞赛

文章目录 0 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 毕业设计…...

Java Excel转PDF,支持xlsx和xls两种格式, itextpdf【即取即用】

Java Excel转PDF itextpdf&#xff0c;即取即用 工具方法一、使用方式1、本地转换2、网络下载 二、pom依赖引入三、工具方法三、引文 本篇主要为工具方法整理&#xff0c;参考学习其他博主文章做了整理&#xff0c;方便使用。 工具方法 一、使用方式 1、本地转换 导入依赖创…...

重生奇迹mu宠物带来不一样的体验

重生奇迹mu宠物有什么作用&#xff1f; 全新版本中更是推出了各种宠物&#xff0c;在玩游戏时还可以带着宠物&#xff0c;一起疯狂的刷怪等等&#xff0c;可以为玩家带来非常不错的游戏体验&#xff0c;那么下面就来给大家说说各种宠物适合做什么事情。 1、强化恶魔适合刷怪 …...

【C++笔记】多态的原理、单继承和多继承关系的虚函数表、 override 和 final、抽象类、重载、覆盖(重写)、隐藏(重定义)的对比

1.final关键字 引出&#xff1a;设计一个不能被继承的类。有如下方法&#xff1a; class A { private:A(int a0):_a(a){} public:static A CreateOBj(int a0){return A(a);} protected:int _a; } //简介限制&#xff0c;子类构成函数无法调用父类构造函数初始化 //子类的构造…...

安装thinkphp6并使用多应用模式,解决提示路由不存在解决办法

1. 安装稳定版tp框架 composer create-project topthink/think tptp是安装完成的目录名称 &#xff0c;可以根据自己需要修改。 如果你之前已经安装过&#xff0c;那么切换到你的应用根目录下面&#xff0c;然后执行下面的命令进行更新&#xff1a; composer update topthin…...

FPGA笔试

1、FPGA结构一般分为三部分&#xff1a;可编程逻辑块&#xff08;CLB&#xff09;、可编程I/O模块和可编程内部连线。 2 CPLD的内部连线为连续式布线互连结构&#xff0c;任意一对输入、输出端之间的延时是固定 &#xff1b;FPGA的内部连线为分段式布线互连结构&#xff0c;各…...

Pytorch:cat、stack、squeeze、unsqueeze的用法

Pytorch&#xff1a;cat、stack、squeeze、unsqueeze的用法 torch.cat 在指定原有维度上链接传入的张量&#xff0c;所有传入的张量都必须是相同形状 torch.cat(tensors, dim0, *, outNone) → Tensor tensor:相同形状的tensor dim:链接张量的维度&#xff0c;不能超过传入张…...

聊聊HttpClient的RedirectStrategy

序 本文主要研究一下HttpClient的RedirectStrategy RedirectStrategy org/apache/http/client/RedirectStrategy.java public interface RedirectStrategy {/*** Determines if a request should be redirected to a new location* given the response from the target ser…...

【1day】复现宏景OA KhFieldTree接口 SQL注入漏洞

注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、资产测绘 三、漏洞复现 四、漏洞修复 一、漏洞描述 宏景OA是一款基于...

同为科技TOWE智能PDU引领数据中心机房远控用电安全高效

随着数据中心的环境变得更加动态和复杂&#xff0c;许多数据中心都在对数据中心管理人员施加压力&#xff0c;要求提高可用性&#xff0c;同时降低成本&#xff0c;提升效率。新一代高密度服务器和网络设备的投入使用&#xff0c;增加了对更高密度机架的需求&#xff0c;并对整…...

支付成功后给指定人员发送微信公众号消息

支付成功后给指定人员&#xff08;导购&#xff09;发送微信公众号消息 微信openid已录入数据库表 调用后台接口发送消息接口调用代码如下&#xff1a; //----add by grj 20231017 start //订单支付成功发送微信公众号消息$.ajax({url:http://www.menggu100.com:7077/strutsJsp…...

漏洞复现--安恒明御安全网关文件上传

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…...

简单的对称加密

异或 异或算法的好处便是数A和数B异或后&#xff0c;把结果再和数A异或便可得到B&#xff0c;或者和数B异或可重新得到数据A。利用异或的这个特性可简单实现数据的加密和解密算法。 恺撒密码 恺撒密码的替换方法是通过排列明文和密文字母表&#xff0c;密文字母表示通过将明…...

vue源码笔记之——响应系统

vue是一种声明式范式编程&#xff0c;使用vue者只需要告诉其想要什么结果&#xff0c;无需关心具体实现&#xff08;vue内部做了&#xff0c;底层是利用命令式范式&#xff09; 1. reactive为什么只能操作对象&#xff0c;对于基本数据类型&#xff0c;需要用ref&#xff1f; …...

Android Studio Giraffe | 2022.3.1

Android Gradle 插件和 Android Studio 兼容性 Android Studio 构建系统以 Gradle 为基础&#xff0c;并且 Android Gradle 插件 (AGP) 添加了几项专用于构建 Android 应用的功能。下表列出了各个 Android Studio 版本所需的 AGP 版本。 如果您的项目不受某个特定版本的 Andr…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space

问题&#xff1a;IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案&#xff1a;将编译的堆内存增加一点 位置&#xff1a;设置setting-》构建菜单build-》编译器Complier...