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

30分钟内搭建一个全能轻量级springboot 3.4 + 脚手架 <5> 5分钟集成好caffeine并使用注解操作缓存

快速导航

<1> 5分钟快速创建一个springboot web项目
<2> 5分钟集成好最新版本的开源swagger ui,并使用ui操作调用接口
<3> 5分钟集成好druid并使用druid自带监控工具监控sql请求
<4> 5分钟集成好mybatisplus并使用mybatisplus generator自动生成代码
<5> 5分钟集成好caffeine并使用注解操作缓存
<6> 5分钟集成好前端页面,使用vue开发前端

目录

  • 一、准备工作
    • 1.1 maven 安装caffeine和相关依赖
    • 1.2 配置caffeine
      • 1.2.1 javaconfig配置caffeine
      • 1.2.2 缓存代码编写
    • 1.3 注解说明
  • 二、测试
  • 三、注解操作缓存原理以及一些难点排查
    • 3.1 注解操作缓存原理
    • 3.2 难点排查
  • 总结

在 Spring Boot 中,注解操作缓存的原理基于 Spring 的缓存抽象 (Spring Cache Abstraction)。使用缓存注解时,Spring 会自动处理与缓存相关的逻辑,而开发者只需要专注于业务代码。常用的缓存注解有 @Cacheable、@CachePut 和 @CacheEvict。

一、准备工作

1.1 maven 安装caffeine和相关依赖

<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>3.1.8</version> <!-- 确保版本兼容 -->
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>

1.2 配置caffeine

有两种配置方式

1.2.1 javaconfig配置caffeine

package com.example.demo.config;import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.List;
import java.util.concurrent.TimeUnit;@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic Caffeine<Object, Object> caffeineConfig() {return Caffeine.newBuilder().maximumSize(1000).expireAfterWrite(5, TimeUnit.MINUTES)
//                .weakKeys() // 很坑会,基本上很快就把key清理掉了,缓存再也命中不了.recordStats();}@Beanpublic CacheManager cacheManager(Caffeine<Object, Object> caffeine) {CaffeineCacheManager cacheManager = new CaffeineCacheManager();cacheManager.setCaffeine(caffeine);cacheManager.setCacheNames(List.of(new String[]{"users"}));return cacheManager;}}

1.2.2 缓存代码编写

TestController

package com.example.demo.web;import com.example.demo.entity.User;
import com.example.demo.service.IUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/test")
@Tag(name = "User API", description = "用户管理相关接口")
public class TestController {@Resourceprivate IUserService userService;@GetMapping("")@Operation(method = "test", summary = "测试接口")public String test(){return "test";}@GetMapping("/user")@Operation(method = "allUsers", summary = "获取所有用户")public List<User> allUsers(){return userService.list();}@GetMapping("/user/{id}")@Operation(method = "getUserCache", summary = "获取用户缓存")public void testGetUserCache(@PathVariable String id){User user = userService.getUserById(id);System.out.println(user);}}

UserServiceImpl

package com.example.demo.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.IUserService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;/*** <p>* 测试用户 服务实现类* </p>** @author allens* @since 2025-01-15*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Cacheable(value = "users", key = "'user_' + #id", unless = "#result == null")public User getUserById(String id) {// 模拟数据库查询return this.getBaseMapper().selectById(id);}@CachePut(value = "users", key = "#id")public void updateUser(String id, String name) {// 模拟更新数据库并返回新值User user = this.getBaseMapper().selectById(id);user.setName(name);this.getBaseMapper().updateById(user);}@CacheEvict(value = "users", key = "#id")public void deleteUser(String id) {// 模拟删除数据库记录System.out.println("User with id " + id + " has been deleted from database and cache.");this.getBaseMapper().deleteById(id);}@CacheEvict(value = "users", allEntries = true)public void clearCache() {System.out.println("All user cache has been cleared.");}}

1.3 注解说明

请参考我的这篇文章 Springboot 注解使用详解

二、测试

在这里插入图片描述
点击发送请求,第一次执行了sql,第二次在方法体中打断点,发现没有进入。且日志未输出相关查询数据库操作。

在这里插入图片描述

三、注解操作缓存原理以及一些难点排查

3.1 注解操作缓存原理

在这里插入图片描述

工作原理总结:

1. 代理模式:Spring 使用动态代理或 CGLIB 代理来拦截带有缓存注解的方法调用。代理会在方法调用之前或之后进行缓存操作。

开启注解缓存是靠 @EnableCaching 来实现的,那么我们从这个注解开始入手:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CachingConfigurationSelector.class)
public @interface EnableCaching {/*** Indicate whether subclass-based (CGLIB) proxies are to be created as opposed* to standard Java interface-based proxies. The default is {@code false}. <strong>* Applicable only if {@link #mode()} is set to {@link AdviceMode#PROXY}</strong>.* <p>Note that setting this attribute to {@code true} will affect <em>all</em>* Spring-managed beans requiring proxying, not just those marked with {@code @Cacheable}.* For example, other beans marked with Spring's {@code @Transactional} annotation will* be upgraded to subclass proxying at the same time. This approach has no negative* impact in practice unless one is explicitly expecting one type of proxy vs another,* for example, in tests.*/boolean proxyTargetClass() default false;/*** Indicate how caching advice should be applied.* <p><b>The default is {@link AdviceMode#PROXY}.</b>* Please note that proxy mode allows for interception of calls through the proxy* only. Local calls within the same class cannot get intercepted that way;* a caching annotation on such a method within a local call will be ignored* since Spring's interceptor does not even kick in for such a runtime scenario.* For a more advanced mode of interception, consider switching this to* {@link AdviceMode#ASPECTJ}.*/AdviceMode mode() default AdviceMode.PROXY;/*** Indicate the ordering of the execution of the caching advisor* when multiple advices are applied at a specific joinpoint.* <p>The default is {@link Ordered#LOWEST_PRECEDENCE}.*/int order() default Ordered.LOWEST_PRECEDENCE;}

@Import(CachingConfigurationSelector.class) 我们进入CachingConfigurationSelector 看下:

在这里插入图片描述
点击进入ProxyCachingConfiguration

@Bean(name = CacheManagementConfigUtils.CACHE_ADVISOR_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public BeanFactoryCacheOperationSourceAdvisor cacheAdvisor(CacheOperationSource cacheOperationSource, CacheInterceptor cacheInterceptor) {BeanFactoryCacheOperationSourceAdvisor advisor = new BeanFactoryCacheOperationSourceAdvisor();advisor.setCacheOperationSource(cacheOperationSource);advisor.setAdvice(cacheInterceptor);if (this.enableCaching != null) {advisor.setOrder(this.enableCaching.<Integer>getNumber("order"));}return advisor;
}@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public CacheOperationSource cacheOperationSource() {// Accept protected @Cacheable etc methods on CGLIB proxies, as of 6.0.return new AnnotationCacheOperationSource(false);
}@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public CacheInterceptor cacheInterceptor(CacheOperationSource cacheOperationSource) {CacheInterceptor interceptor = new CacheInterceptor();interceptor.configure(this.errorHandler, this.keyGenerator, this.cacheResolver, this.cacheManager);interceptor.setCacheOperationSource(cacheOperationSource);return interceptor;
}

我们可以看到动态代理注入了一个interceptor,我们这个时候就可以猜测,所有的缓存操作都是在这个interceptor里边进行操作的(不熟悉动态代理原理的可以先去看下)。

public class CacheInterceptor extends CacheAspectSupport implements MethodInterceptor, Serializable {@Override@Nullablepublic Object invoke(final MethodInvocation invocation) throws Throwable {Method method = invocation.getMethod();CacheOperationInvoker aopAllianceInvoker = () -> {try {return invocation.proceed();}catch (Throwable ex) {throw new CacheOperationInvoker.ThrowableWrapper(ex);}};Object target = invocation.getThis();Assert.state(target != null, "Target must not be null");try {return execute(aopAllianceInvoker, target, method, invocation.getArguments());}catch (CacheOperationInvoker.ThrowableWrapper th) {throw th.getOriginal();}}
}

再点击进入 CacheAspectSupport 发现有个方法叫execute,礼拜呢有一个findCachedValue方法,这个就是查询缓存有没有命中,如果有命中直接返回缓存,如果没命中那么就会执行员原服务方法获取数据。

@Nullable
private Object execute(CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {if (contexts.isSynchronized()) {// Special handling of synchronized invocationreturn executeSynchronized(invoker, method, contexts);}// Process any early evictionsprocessCacheEvicts(contexts.get(CacheEvictOperation.class), true,CacheOperationExpressionEvaluator.NO_RESULT);// Check if we have a cached value matching the conditionsObject cacheHit = findCachedValue(invoker, method, contexts); // 查询缓存if (cacheHit == null || cacheHit instanceof Cache.ValueWrapper) { // 判断是否命中缓存return evaluate(cacheHit, invoker, method, contexts);}return cacheHit;
}

CacheAspectSupport.findCachedValue

@Nullable
private Object findCachedValue(CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {for (CacheOperationContext context : contexts.get(CacheableOperation.class)) {if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);Object cached = findInCaches(context, key, invoker, method, contexts); // 查找缓存if (cached != null) {if (logger.isTraceEnabled()) {logger.trace("Cache entry for key '" + key + "' found in cache(s) " + context.getCacheNames());}return cached;}else {if (logger.isTraceEnabled()) {logger.trace("No cache entry for key '" + key + "' in cache(s) " + context.getCacheNames());}}}}return null;
}

CacheAspectSupport.findInCaches

@Nullable
private Object findInCaches(CacheOperationContext context, Object key,CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {for (Cache cache : context.getCaches()) {if (CompletableFuture.class.isAssignableFrom(context.getMethod().getReturnType())) {CompletableFuture<?> result = doRetrieve(cache, key);  // 重试策略if (result != null) {return result.exceptionally(ex -> {getErrorHandler().handleCacheGetError((RuntimeException) ex, cache, key);return null;}).thenCompose(value -> (CompletableFuture<?>) evaluate((value != null ? CompletableFuture.completedFuture(unwrapCacheValue(value)) : null),invoker, method, contexts));}else {continue;}}if (this.reactiveCachingHandler != null) {Object returnValue = this.reactiveCachingHandler.findInCaches(context, cache, key, invoker, method, contexts);if (returnValue != ReactiveCachingHandler.NOT_HANDLED) {return returnValue;}}Cache.ValueWrapper result = doGet(cache, key);if (result != null) {return result;}}return null;
}

CacheAspectSupport.doGet 可以看到最终拿的就是我们在cache manager 里边配置的cache

@Nullable
protected Cache.ValueWrapper doGet(Cache cache, Object key) {try {return cache.get(key); }catch (RuntimeException ex) {getErrorHandler().handleCacheGetError(ex, cache, key);return null;  // If the exception is handled, return a cache miss}
}

2. 缓存管理:缓存的存储和取用是通过 Spring 的缓存抽象来管理的。缓存的实现可以是简单的内存缓存,也可以是分布式缓存,如 Redis 等。
3. 缓存策略:开发者可以通过注解设置不同的缓存策略,例如缓存的键、值、过期时间、条件等。

这种基于注解的缓存方式极大地简化了缓存操作,让开发者专注于业务逻辑的实现,而缓存的管理由 Spring 自动处理。

3.2 难点排查

在做demo的时候发现配置也没错,也没有说是通过本文件的方法去调用提供缓存的方法(这样不走代理,无法执行命中缓存操作),后来发现是weakkey导致的。假如说内存不够的情况下,key就会被直接清楚掉,而我电脑可分配内存很少。可能会频繁触发GC,导致cache key被清除掉了。不清楚weakReference作用的同学可以去看下我写的另一篇文章:
WeakReference浅析

@Bean
public Caffeine<Object, Object> caffeineConfig() {return Caffeine.newBuilder().maximumSize(1000).expireAfterWrite(5, TimeUnit.MINUTES)
//                .weakKeys() // 很坑会,基本上很快就把key清理掉了,缓存再也命中不了.recordStats();
}

总结

散会

相关文章:

30分钟内搭建一个全能轻量级springboot 3.4 + 脚手架 <5> 5分钟集成好caffeine并使用注解操作缓存

快速导航 <1> 5分钟快速创建一个springboot web项目 <2> 5分钟集成好最新版本的开源swagger ui&#xff0c;并使用ui操作调用接口 <3> 5分钟集成好druid并使用druid自带监控工具监控sql请求 <4> 5分钟集成好mybatisplus并使用mybatisplus generator自…...

STM32 FreeRTOS中断管理

目录 FreeRTOS的中断管理 1、STM32中断优先级管理 2、FreeRTOS任务优先级管理 3、寄存器和内存映射寄存器 4、BASEPRI寄存器 5、FreeRTOS与STM32中断管理结合使用 vPortRaiseBASEPRI vPortSetBASEPRI 6、FromISR后缀 7、在中断服务函数中调用FreeRTOS的API函数需注意 F…...

第10章:Python TDD优化货币类方法与引入工厂方法

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

嵌入式硬件篇---基本组合逻辑电路

文章目录 前言基本逻辑门电路1.与门&#xff08;AND Gate&#xff09;2.或门&#xff08;OR Gate&#xff09;3.非门&#xff08;NOT Gate&#xff09;4.与非门&#xff08;NAND Gate&#xff09;5.或非门&#xff08;NOR Gate&#xff09;6.异或门&#xff08;XOR Gate&#x…...

回归人文主义,探寻情感本质:从文艺复兴到AI时代,我的情感探索之旅

回归人文主义&#xff0c;探寻情感本质&#xff1a;从文艺复兴到AI时代&#xff0c;我们的情感探索之旅 多年来&#xff0c;我们的团队一直关注人工智能&#xff0c;尤其是AI在音乐领域的应用研究。随着技术的不断演进&#xff0c;我们也不断反思&#xff1a;在“算法、代码、…...

接上回--综合AIDemo测试

一&#xff0c;前言 上回外挂了知识库之后&#xff0c;我们需要使用知识库中的信息&#xff0c;让AI为我们实际处理业务上的需求。 这里我们让AI扮演公司的人事助手&#xff0c;帮我们处理员工请假的业务。 具体流程如下 感知用户需要请假提取用户请假信息获取用户数据库中…...

几何数据结构之四叉树与八叉树

几何数据结构之四叉树与八叉树 四叉树的定义四叉树深度的计算公式推导假设&#xff1a;计算过程&#xff1a;1. 划分空间&#xff1a;2. 节点容纳的最小距离&#xff1a;3. 解出深度&#xff1a;4. 考虑常数项&#xff1a; 总结&#xff1a; 八叉树 四叉树的定义 四叉树&#…...

postman请求参数化

postman界面介绍 一、使用环境变量(Environment Variables)进行参数化 1、在请求中使用环境变量 在请求的url、请求头(Headers)、请求体(Body)等部分都可以使用环境变量。 URL 部分示例 点击 Postman 界面右上角的 “眼睛” 图标(Environment Quick Look)打开环境管理…...

java实现word转html(支持docx及doc文件)

private final static String tempPath "C:\\Users\\xxx\\Desktop\\Word2Html\\src\\test\\";//图片及相关文件保存的路径public static void main(String argv[]) {try {JFileChooser fileChooser new JFileChooser();fileChooser.setDialogTitle("Select a …...

<电子幽灵>开发笔记:BAT基础笔记(一)

BAT脚本基础笔记(一) 介绍 费曼学习法最重要的部分&#xff0c;即把知识教给一个完全不懂的孩子——或者小白。 为了更好的自我学习&#xff0c;也为了让第一次接触某个知识范畴的同学快速入门&#xff0c;我会把我的学习笔记整理成电子幽灵系列。 提示&#xff1a;作为低代码…...

Leetcode::3427.变长子数组求和

给你一个长度为 n 的整数数组 nums 。对于 每个 下标 i&#xff08;0 < i < n&#xff09;&#xff0c;定义对应的子数组 nums[start ... i]&#xff08;start max(0, i - nums[i])&#xff09;。 返回为数组中每个下标定义的子数组中所有元素的总和。 子数组 是数组中…...

通过以太网加载linux内核、设备树、根文件系统方法(以stm32MP135为例)

0 硬件平台 正点原子stm32MP135开发板 1 通过以太网加载linux内核、设备树、根文件系统方法&#xff08;以stm32MP135为例&#xff09; 在产品正式发布前&#xff0c;为了调试方便&#xff0c;我们可以使用以太网加载linux内核、设备树、根文件系统以加快调试速度。本文以stm3…...

mac配置stable diffusion以及模型出图优化

1. 基础stable diffusion webui安装 使用的工程是stable-diffusion-webui&#xff0c;直接clone下来即可。 然后创建一个conda环境&#xff0c;python为3.9 激活conda环境后&#xff0c;执行./webui.sh即可。脚本会自动安装必要的包&#xff0c;然后启动网页。 默认有一个sd…...

LeetCode热题100(子串篇)

LeetCode热题100 说是子串&#xff0c;其实是子区间~ 560. 和为 K 的子数组 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 思路 思路&#xff1a; 和为k的子数组&#xff0c;看到…...

从密码学原理与应用新方向到移动身份认证与实践

相关学习资料放下面啦&#xff01; 记得关注❤️&#xff5e;后续分享更多资料 通过百度网盘分享的文件&#xff1a;从密码学原理与应... 链接https://pan.baidu.com/s/1mHpHkvPuf8DUwReQkoYQlw?pwdGza7 提取码&#xff1a;Gza7 复制这段内容打开「百度网盘APP 即可获取」 记…...

【Flink系列】9. Flink容错机制

9. 容错机制 在Flink中&#xff0c;有一套完整的容错机制来保证故障后的恢复&#xff0c;其中最重要的就是检查点。 9.1 检查点&#xff08;Checkpoint&#xff09; 9.1.1 检查点的保存 1&#xff09;周期性的触发保存 “随时存档”确实恢复起来方便&#xff0c;可是需要我…...

【物联网】ARM核介绍

文章目录 一、芯片产业链1. CPU核(1)ARM(2)MIPS(3)PowerPc(4)Intel(5)RISC-V 2. SOC芯片(1)主流厂家(2)产品解决方案 3. 产品 二、ARM核发展1. 不同架构的特点分析(1)VFP(2)Jazelle(3)Thumb(4)TrustZone(5)SIMD(6)NEON 三、ARM核(ARMv7)工作模式1. 权限级别(privilege level)2.…...

spring的事物管理的认知

事物 它是一个原子操作要么全部不执行&#xff0c;要么全部执行成功&#xff0c;如果有一个失败也会撤销&#xff0c;它保证用户每一次的操作都是可靠的&#xff0c;即使时出现了错误也不至于破坏数据的完整性 它包含了四种特性&#xff1a; 原子性&#xff1a;保证事物要么…...

QT跨平台应用程序开发框架(3)—— 信号和槽

目录 一&#xff0c;基本概念 二&#xff0c;connect函数使用 2.1 connect 2.2 Qt内置信号和槽 2.3 一些细节 三&#xff0c;自定义信号和槽 3.1 自定义槽函数 3.2 自定义信号 3.3 带参数的信号槽 四&#xff0c;信号和槽的意义 五&#xff0c;信号和槽断开连接 六&…...

技术面试中的软素质技巧性答复集锦

1、请你自我介绍一下你自己&#xff1f; 回答提示&#xff1a;一般人回答这个问题过于平常&#xff0c;只说姓名、年龄、爱好、工作经验&#xff0c;这些在简历上都有。其实&#xff0c;企业最希望知道的是求职者能否胜任工作&#xff0c;包括&#xff1a;最强的技能、最深入研…...

JavaWeb项目——如何处理管理员登录和退出——笔记

一、知识点 1、WebServlet注解的使用 WebServlet注解是Servlet 3.0引入的一个特性&#xff0c;它允许开发者在Servlet类上使用注解来声明Servlet的一些属性&#xff0c;从而避免在web.xml文件中进行配置。这种方式简化了Servlet的配置过程&#xff0c;使得代码更加简洁&#…...

函数递归的介绍

1.递归的定义 在C语言中&#xff0c;递归就是函数自己调用自己 上面的代码就是 main 函数在函数主体内 自己调用自己 但是&#xff0c;上面的代码存在问题&#xff1a;main 函数反复地 自己调用自己 &#xff0c;不受限制&#xff0c;停不下来。 最终形成死递归&#xff0c;…...

昇腾环境ppstreuct部署问题记录

测试代码 我是在华为昇腾910B3上测试的PPStructure。 import os import cv2 from PIL import Image #from paddleocr import PPStructure,draw_structure_result,save_structure_res from paddleocr_asyncio import PPStructuretable_engine PPStructure(show_logTrue, imag…...

《知识图谱:鸿蒙NEXT中人工智能的智慧基石》

在鸿蒙NEXT系统的人工智能应用中&#xff0c;知识图谱技术犹如一座智慧基石&#xff0c;为系统的智能化提供了强大的知识支撑&#xff0c;开启了更智能、更高效、更个性化的交互新时代。 提升语义理解能力 知识图谱以其结构化的知识表示方式&#xff0c;将各种实体和它们之间…...

Springboot项目Jackson支持多种接收多种时间格式

前言 在springboot项目中经常会使用Jackson框架,当前端给后端传输时间类型时,我们一般需要先配置好时间格式,否则后端无法接收。以下是一些配置方法 统一配置 spring:jackson:time-zone: GMT+8date-format: yyyy-MM-dd HH:mm:ss这种配置就是要求前端统一传输的格式是yyyy-…...

go语言zero框架通过chromedp实现网页在线截图的设计与功能实现

在 GoZero 框架中实现网页在线截图的功能&#xff0c;可以通过集成 chromedp 库来控制 Chrome 浏览器进行截图。chromedp 是一个基于 Chrome DevTools 协议的 Go 包&#xff0c;可以用来在 Go 程序中模拟浏览器操作&#xff0c;如页面截图、DOM 操作、表单提交等。 下面是一个…...

基于深度学习的视觉检测小项目(十四) 用SQLite数据库进行用户管理

在开始做用户管理之前&#xff0c;先要了解一下SQLite数据库的基础知识&#xff1a;https://blog.csdn.net/xulibo5828/category_12785993.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12785993&sharereferPC&sharesourcexulibo5828&sharefrom…...

【2024年华为OD机试】 (B卷,100分)- 敏感字段加密(Java JS PythonC/C++)

一、问题描述 题目描述 给定一个由多个命令字组成的命令字符串: 字符串长度小于等于 127 字节,只包含大小写字母、数字、下划线和偶数个双引号;命令字之间以一个或多个下划线 _ 进行分割;可以通过两个双引号 "" 来标识包含下划线 _ 的命令字或空命令字(仅包含…...

图像去雾数据集的下载和预处理操作

前言 目前&#xff0c;因为要做对比实验&#xff0c;收集了一下去雾数据集&#xff0c;并且建立了一个数据集的预处理工程。 这是以前我写的一个小仓库&#xff0c;我决定还是把它用起来&#xff0c;下面将展示下载的路径和数据处理的方法。 下面的代码均可以在此找到。Auo…...

Vue3数据响应式原理

什么是数据响应式 当数据变化时&#xff0c;引用数据的函数&#xff08;副作用函数&#xff09;自动重新执行。 即数据触发了函数的响应&#xff0c;如&#xff1a;视图渲染中使用了某数据&#xff0c;数据改变后&#xff0c;视图跟着自动更新。 触发者&#xff1a;数据 响应者…...

5.最长回文子串--力扣

给你一个字符串 s&#xff0c;找到 s 中最长的 回文子串。 示例 1&#xff1a; 输入&#xff1a;s “babad” 输出&#xff1a;“bab” 解释&#xff1a;“aba” 同样是符合题意的答案。 示例 2&#xff1a; 输入&#xff1a;s “cbbd” 输出&#xff1a;“bb” 原题如上&…...

ChatGPT大模型极简应用开发-CH1-初识 GPT-4 和 ChatGPT

文章目录 1.1 LLM 概述1.1.1 语言模型和NLP基础1.1.2 Transformer及在LLM中的作用1.1.3 解密 GPT 模型的标记化和预测步骤 1.2 GPT 模型简史&#xff1a;从 GPT-1 到 GPT-41.2.1 GPT11.2.2 GPT21.2.3 GPT-31.2.4 从 GPT-3 到 InstructGPT1.2.5 GPT-3.5、Codex 和 ChatGPT1.2.6 …...

python学opencv|读取图像(三十九 )阈值处理Otsu方法

【1】引言 前序学习了5种阈值处理方法&#xff0c;包括(反)阈值处理、(反)零值处理和截断处理&#xff0c;还学习了一种自适应处理方法&#xff0c;相关文章链接为&#xff1a; python学opencv|读取图像&#xff08;三十三&#xff09;阈值处理-灰度图像-CSDN博客 python学o…...

统信V20 1070e X86系统编译安装mysql-5.7.44版本以及主从构建

设备信息 操作系统版本架构CPU内存备注统信UOS V20 1070eX864C8G此配置仅做编译安装验证&#xff0c;持续运行或数据量增长大请自行评估资源配置。统信UOS V20 1070eX864C8G 资源包 该包包含mysql-5.7.44源码包、boost资源包、统信编译mysql-5.7.44安装包 通过网盘分享的文件…...

麒麟LINUX V10SP3 2401安装ORACLE 12.2.1 runInstaller直接报UNZIP格式不对

好久没有安装ORACLE了&#xff0c;一般都是RHEL上安装得比较多&#xff0c;这不&#xff0c;现在大家都是选择国产操作系统来安装数据库了&#xff0c;以前在龙蜥&#xff0c;欧拉&#xff0c;麒麟上也安装过&#xff0c;都没有问题&#xff0c;想来在麒麟LINUX v10sp3 2401上面…...

10 为什么系统需要引入分布式、微服务架构

java技术的发展 在java开始流行起来之后&#xff0c;主要服务于企业家应用&#xff0c;例如ERP,CRM等等&#xff0c;这些项目是为企业内部员工使用&#xff0c;我们的思维是怎么用设计模式&#xff0c;如何封装代码。让开发人员关注到业务上去&#xff0c;系统也就那么几十几百…...

【Web】2025西湖论剑·中国杭州网络安全安全技能大赛题解(全)

目录 Rank-l Rank-U sqli or not Rank-l username存在报错回显&#xff0c;发现可以打SSTI 本地起一个服务&#xff0c;折半查找fuzz黑名单&#xff0c;不断扔给fenjing去迭代改payload from flask import Flask, request, render_template_stringapp Flask(__name__)app…...

openharmony应用开发快速入门

开发准备 本文档适用于OpenHarmony应用开发的初学者。通过构建一个简单的具有页面跳转/返回功能的应用&#xff08;如下图所示&#xff09;&#xff0c;快速了解工程目录的主要文件&#xff0c;熟悉OpenHarmony应用开发流程。 在开始之前&#xff0c;您需要了解有关OpenHarmon…...

解决npm install安装出现packages are looking for funding run `npm fund` for details问题

当我们运行npm install时&#xff0c;可能会收到类似以下的提示信息&#xff1a;“x packages are looking for funding.” 这并不是错误提示&#xff0c;也不会影响项目的正常运行。其实实在提醒有一些软件包正在寻求资金支持。 根据提示输入npm fund可以查看详细的信息&#…...

python助力WRF自动化运行

对大部分人而言&#xff0c;特别是新用户&#xff0c;WRF模式的安装繁琐且不必要&#xff0c;可以作为后续进阶掌握的技能&#xff0c;本学习跳过繁琐的安装步骤&#xff0c;直接聚焦模式的运行部分&#xff0c;通过短平快的教学&#xff0c;快速掌握模式运行。进一步将python语…...

Go-知识 版本演进

Go-知识 版本演进 Go release notesr56(2011/03/16)r57(2011/05/03)Gofix 工具语言包工具小修订 r58(2011/06/29)语言包工具小修订 r59(2011/08/01)语言包工具 r60(2011/09/07)语言包工具 [go1 2012-03-28](https://golang.google.cn/doc/devel/release#go1)[go1.1 2013-05-13]…...

企业级NoSQL数据库Redis

1.浏览器缓存过期机制 1.1 最后修改时间 last-modified 浏览器缓存机制是优化网页加载速度和减少服务器负载的重要手段。以下是关于浏览器缓存过期机制、Last-Modified 和 ETag 的详细讲解&#xff1a; 一、Last-Modified 头部 定义&#xff1a;Last-Modified 表示服务器上资源…...

Android渲染Latex公式的开源框架比较

对比主流框架&#xff0c;介绍如下几款 1、AndroidMath 官网&#xff1a;https://github.com/gregcockroft/AndroidMath/tree/master 基于android原生view方式渲染 优点&#xff1a;速度快&#xff0c;开源协议 MIT license 缺点&#xff1a;不支持文字公式混合渲染 2、Ma…...

ARM学习(42)CortexM3/M4 MPU配置

笔者之前学习过CortexR5的MPU配置,现在学习一下CortexM3/M4 MPU配置 1、背景介绍 笔者在工作中遇到NXP MPU在访问异常地址时,就会出现总线挂死,所以需要MPU抓住异常,就需要配置MPU。具体背景情况可以参考ARM学习(41)NXP MCU总线挂死,CPU could not be halted以及无法连…...

Sam Altman亲自确认:o3-mini即将上线!GPT和o系列模型合并!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…...

数据结构-队列

目录 前言一、队列及其抽象数据类型1.1 队列的基本概念1.2 队列的抽象数据类型 二、队列的实现2.1 顺序表示2.1.1 结构定义2.1.2 基本操作的实现 2.2 链式表示2.2.1 结构定义2.2.2 基本操作的实现 总结 前言 本篇文章介绍队列的基础知识&#xff0c;包括队列的抽象数据类型以及…...

Go Map 源码分析(一)

Go语言中的map是通过哈希表实现的&#xff0c;其底层结构和实现机制如下&#xff1a; 一、hash 结构 hmap结构体&#xff1a;是map的头部结构&#xff0c;主要字段及含义如下&#xff1a; count&#xff1a;表示当前哈希表中的元素数量&#xff0c;与len()函数相对应。flags…...

天机学堂5-XxlJobRedis

文章目录 梳理前面的实现&#xff1a;Feign点赞改进 day07-积分系统bitmap相关命令签到增加签到记录计算本月已连续签到的天数查询签到记录 积分表设计签到-->发送RabbitMQ消息&#xff0c;保存积分对应的消费者&#xff1a;**消费消息 用于保存积分**增加积分查询个人今日积…...

SpringBoot整合junit

SpringBoot 整合 junit 特别简单&#xff0c;分为以下三步完成: 1在测试类上添加 SpringBootTest 注解2使用 Autowired 注入要测试的资源3定义测试方法进行测试 1.实验准备&#xff1a; 创建一个名为 springboot_junit_test 的 SpringBoot 工程&#xff0c;工程目录结构如下…...

Jenkins-pipeline Jenkinsfile说明

一. 简介&#xff1a; Jenkinsfile 是一个文本文件&#xff0c;通常保存在项目的源代码仓库中&#xff0c;用于定义 Jenkins Pipeline 的行为。使用 Jenkinsfile 可以使 CI/CD 流程版本化&#xff0c;并且易于共享和审核。 二. 关于jenkinsfile&#xff1a; jenkins的pipeline…...