架構設計之自定義延遲雙刪緩存注解(上)

架構設計之自定義延遲雙刪緩存注解(上)

小薛博客官方架構設計之自定義延遲雙刪緩存注解(上)地址

1、業務場景問題

在多線程并發情況下,假設有兩個數據庫修改請求,為保證數據庫與redis的數據一致性,修改請求的實現中需要修改數據庫后,級聯修改Redis中的數據。

  • 請求一:A修改數據庫數據 B修改Redis數據
  • 請求二:C修改數據庫數據 D修改Redis數據
  • 正常情況:A —> B—>C —> D

并發情況下就會存在A —> C —> D —> B的情況,問題在哪里?

要理解線程并發執行多組原子操作執行順序是可能存在交叉現象的

A修改數據庫的數據最終保存到了Redis中,但是在A沒有修改完成是不會同步進mysql的,

C在AB操作之間來查詢,緩存redis數據沒有刪除,那A已經修改新數據了但是沒有同步進B步驟進redis

導致C查看的還是老數據,此時出現了Redis中數據和數據庫數據不一致的情況,從而出現查詢到的數據并不是數據庫中的真實數據的嚴重問題。

2、解決方案

在使用Redis時,需要保持Redis和數據庫數據的一致性,最流行的解決方案之一就是延時雙刪策略。

**注意:**經常修改的數據表不適合使用Redis,因為雙刪策略執行的結果是把Redis中保存的那條數據刪除了,以后的查詢短時間內就都會去查詢數據庫,導致mysql側壓力瞬間增大,所以Redis使用的是讀遠遠大于改的數據緩存。

  • 刪除緩存
  • 更新數據庫
  • 延時500毫秒 (根據具體業務設置延時執行的時間,保證數據庫更新或者刪除業務操作完成即可,看你自己實際情況)
  • 刪除緩存

3、為何要兩次刪除緩存?

如果我們沒有第二次刪除操作,此時有請求訪問數據,有可能是訪問的之前未做修改的Redis數據,刪除操作執行后,Redis為空,有請求進來時,便會去訪問數據庫,此時數據庫中的數據已是更新后的數據,保證了數據的一致性。

因為mysql做了update操作,

導致數據不一致

查都是先查redis,一旦redis和mysql數據不一致,我返回的是redis里面的老數據,導致了這個生產bug

那一不做二不休,直接刪掉redis,沒有redis了,只有唯一的一個底單數據源mysql,數據源現在在唯一了

大家都來自mysql

更新動作完成之前,redis沒有值,都從mysql一個數據源來

4、新建xx-delay-double-del

1、SQL

USE
`xx_db2025`;DROP TABLE IF EXISTS `user_db`;CREATE TABLE `user_db`
(`id`       int                                                    NOT NULL AUTO_INCREMENT,`username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;insert into `user_db`(`id`, `username`)
values (1, 'Version1');

2、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.0</version><relativePath/></parent><artifactId>xx-delay-double-del</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- spring boot的web開發所需要的起步依賴 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><!-- mybatis-plus-boot3-starter --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.7</version></dependency><!-- mybatis-plus-extension --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-extension</artifactId><version>3.5.7</version></dependency><!--pagehelper--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>2.1.0</version></dependency><!--SpringBoot集成druid連接池druid-spring-boot-starter --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.21</version></dependency><!-- mysql-connector-j --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.3.0</version></dependency><!--boot-redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- aop --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>com.xx</groupId><artifactId>xx-common-core</artifactId><version>1.6.1</version></dependency><!-- md5 加密包 --><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.2</version></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId></dependency><!-- commons --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

3、application.yml

server:port: 8001spring:data:redis:database: 0host: 127.0.0.1password: 123456port: 6379datasource:driver-class-name: com.mysql.cj.jdbc.Driver#    url: jdbc:mysql://127.0.0.1:3306/xx_db2023?connectTimeout=6000&socketTimeout=6000&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaiurl: jdbc:mysql://127.0.0.1:3306/xx_db2025?connectTimeout=6000&socketTimeout=6000&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=trueusername: rootpassword: mac_root# mybatis-plus相關配置
mybatis-plus:#  global-config:#    db-config:#      id-type: auto# xml掃描,多個目錄用逗號或者分號分隔(告訴 Mapper 所對應的 XML 文件位置)mapper-locations: classpath:mapper/*Mapper.xml# type-enums-package: com.xx.enumsconfiguration:# 是否開啟自動駝峰命名規則映射:從數據庫列名到Java屬性駝峰命名的類似映射map-underscore-to-camel-case: true# 如果查詢結果中包含空值的列,則 MyBatis 在映射的時候,不會映射這個字段call-setters-on-nulls: true# 這個配置會將執行的sql打印出來,在開發或測試的時候可以用log-impl: org.apache.ibatis.logging.stdout.StdOutImplcache-enabled: truedb-config:logic-delete-field: del_flag  # 全局邏輯刪除的實體字段名(since 3.3.0,配置后可以忽略不配置步驟2)logic-delete-value: 1 # 邏輯已刪除值(默認為 1)logic-not-delete-value: 0 # 邏輯未刪除值(默認為 0)---
spring:sql:init:mode: always  # 總是初始化數據庫schema-locations: classpath:db/init.sql  # 初始化SQL文件位置#Mybatis輸出sql日志
logging:level:com.xx.mapper: info

4、啟動類

package com.xx;import com.xx.utils.LocalIpUtil;
import com.xx.utils.ValidationUtil;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.util.StopWatch;import java.net.UnknownHostException;/*** @Author: xueqimiao* @Date: 2025/3/17 14:22*/
@SpringBootApplication
@MapperScan("com.xx.mapper")
@Slf4j
public class DelayDoubleDelApplication {public static void main(String[] args) throws UnknownHostException {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext application = SpringApplication.run(DelayDoubleDelApplication.class, args);stopWatch.stop();Environment env = application.getEnvironment();String ip = LocalIpUtil.getLocalIp();String port = env.getProperty("server.port");String path = env.getProperty("server.servlet.context-path");path = ValidationUtil.isEmpty(path) ? "" : path;log.info("\n--------------------------------------------------------\n\t" +"Application Manager is running! Access URLs:\n\t" +"Local: \t\thttp://127.0.0.1:" + port + path + "/\n\t" +"External: \thttp://" + ip + ":" + port + path + "/\n\t" +"Swagger文檔: \thttp://" + ip + ":" + port + path + "/doc.html\n\t" +"服務啟動完成,耗時: \t" + stopWatch.getTotalTimeSeconds() + "S\n" +"----------------------------------------------------------");}}

5、RedisUtils

package com.xx.utils;import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;import java.util.Set;
import java.util.concurrent.TimeUnit;/*** @Author: xueqimiao* @Date: 2025/3/17 14:19*/
@Service
public class RedisUtils {@Resourceprivate RedisTemplate<String, String> redisTemplate;/*** RedisAutoConfiguration* 寫入緩存+過期時間** @param key* @param value* @param expireTime* @param timeUnit* @return*/public boolean set(String key, String value, Long expireTime, TimeUnit timeUnit) {ValueOperations<String, String> operations = redisTemplate.opsForValue();operations.set(key, value);redisTemplate.expire(key, expireTime, timeUnit);return true;}/*** 通過key獲取value** @param key* @return*/public String get(String key) {ValueOperations<String, String> operations = redisTemplate.opsForValue();return operations.get(key);}/*** 批量刪除 k-v** @param keys* @return*/public boolean del(final String... keys) {for (String key : keys) {if (redisTemplate.hasKey(key)) { //key存在就刪除redisTemplate.delete(key);}}return true;}public boolean del(final Set<String> keys) {for (String key : keys) {if (redisTemplate.hasKey(key)) { //key存在就刪除redisTemplate.delete(key);}}return true;}/*** 獲取key集合* @param key* @return*/public Set<String> keys(final String key) {Set<String> keys = redisTemplate.keys(key);return keys;}
}

6、RedisConfig

package com.xx.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;/*** @Author: xueqimiao* @Date: 2025/3/17 14:19*/
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<Integer,Integer> redisTemplate(RedisConnectionFactory factory){RedisTemplate<Integer,Integer> redisTemplate = new RedisTemplate<>();// 設置連接工廠類redisTemplate.setConnectionFactory(factory);// 設置k-v的序列化方式// Jackson2JsonRedisSerializer 實現了 RedisSerializer接口Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.setKeySerializer(new StringRedisSerializer());return redisTemplate;}
}

7、User

package com.xx.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;/*** @Author: xueqimiao* @Date: 2025/3/17 14:13*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user_db")
public class User implements Serializable {@TableId(type = IdType.AUTO)private Integer id;private String username;}

8、UserMapper

package com.xx.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xx.entity.User;/*** @Author: xueqimiao* @Date: 2025/3/17 14:14*/
public interface UserMapper extends BaseMapper<User> {
}

9、UserService

package com.xx.service;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xx.common.Result;
import com.xx.entity.User;
import com.xx.mapper.UserMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;/*** @Author: xueqimiao* @Date: 2025/3/17 14:17*/
@Service
public class UserService {@Resourceprivate UserMapper userMapper;public Result update(User user) {int i = userMapper.updateById(user);if (i > 0) {return Result.ok(i);}return Result.error(500, "操作數據庫失敗");}public Result get(Integer id) {LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.eq(User::getId, id);User user = userMapper.selectOne(wrapper);return Result.ok(user);}
}

5、自定義緩存注解@Cache

package com.xx.cache;import java.lang.annotation.*;/*** @Author: xueqimiao* @Date: 2025/3/17 14:24*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Cache {/*** 過期時間,默認60s* @return*/long expire() default 5 * 60 * 1000;/*** 緩存標識name* @return*/String name() default "";}

6、CacheAspect

package com.xx.cache;import com.alibaba.fastjson.JSON;
import com.xx.common.Result;
import com.xx.utils.RedisUtils;
import com.xx.utils.ValidationUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;/*** @Author: xueqimiao* @Date: 2025/3/17 14:25*/
@Component
@Aspect
@Slf4j
public class CacheAspect {@Resourceprivate RedisUtils redisUtils;/*** aop切點* 攔截被指定注解修飾的方法*/@Pointcut("@annotation(com.xx.cache.Cache)")public void cache() {}/*** 緩存操作** @param pjp* @return*/@Around("cache()")public Object toCache(ProceedingJoinPoint pjp) {try {// 思路: 設置存儲的格式,獲取即可Signature signature = pjp.getSignature();// 類名String className = pjp.getTarget().getClass().getSimpleName();// 方法名String methodName = signature.getName();// 參數處理Object[] args = pjp.getArgs();Class[] parameterTypes = new Class[args.length];String params = "";for (int i = 0; i < args.length; i++) {if (args[i] != null) {parameterTypes[i] = args[i].getClass();params += JSON.toJSONString(args[i]);}}if (!ValidationUtil.isEmpty(params)) {//加密 以防出現key過長以及字符轉義獲取不到的情況params = DigestUtils.md5Hex(params);}// 獲取controller中對應的方法Method method = signature.getDeclaringType().getMethod(methodName, parameterTypes);// 獲取Cache注解Cache annotation = method.getAnnotation(Cache.class);long expire = annotation.expire();String name = annotation.name();// 訪問redis(先嘗試獲取,沒有則訪問數據庫)String redisKey = name + "::" + className + "::" + methodName + "::" + params;String redisValue = redisUtils.get(redisKey);if (!ValidationUtil.isEmpty(redisValue)) {// 不為空返回數據Result result = JSON.parseObject(redisValue, Result.class);log.info("數據從redis緩存中獲取,key: {}", redisKey);return result; // 跳出方法}Object proceed = pjp.proceed();// 放行redisUtils.set(redisKey, JSON.toJSONString(proceed), expire, TimeUnit.MILLISECONDS);log.info("數據存入redis緩存,key: {}", redisKey);return proceed;} catch (Throwable throwable) {return Result.error(500, "系統錯誤");}}}

7、自定義延遲雙刪注解@ClearAndReloadCache

package com.xx.cache;import java.lang.annotation.*;/*** @Author: xueqimiao* @Date: 2025/3/17 14:26*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.METHOD)
public @interface ClearAndReloadCache {String name() default "";
}

8、ClearAndReloadCacheAspect

package com.xx.cache;import com.xx.utils.RedisUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
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.springframework.stereotype.Component;import java.lang.reflect.Method;
import java.util.Set;/*** @Author: xueqimiao* @Date: 2025/3/17 14:26*/
@Aspect
@Component
@Slf4j
public class ClearAndReloadCacheAspect {@Resourceprivate RedisUtils redisUtils;/*** 切入點* 切入點,基于注解實現的切入點  加上該注解的都是Aop切面的切入點*/@Pointcut("@annotation(com.xx.cache.ClearAndReloadCache)")public void pointCut() {}/*** 環繞通知第一個參數必須是org.aspectj.lang.ProceedingJoinPoint類型** @param proceedingJoinPoint*/@Around("pointCut()")public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {log.info("----------- 環繞通知 -----------");log.info("環繞通知的目標方法名:" + proceedingJoinPoint.getSignature().getName());Signature signature = proceedingJoinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method targetMethod = methodSignature.getMethod();//方法對象ClearAndReloadCache annotation = targetMethod.getAnnotation(ClearAndReloadCache.class);//反射得到自定義注解的方法對象String name = annotation.name();//獲取自定義注解的方法對象的參數即nameSet<String> keys = redisUtils.keys("*" + name + "*");//模糊定義keyredisUtils.del(keys);//模糊刪除redis的key值//執行加入雙刪注解的改動數據庫的業務 即controller中的方法業務Object proceed = null;try {proceed = proceedingJoinPoint.proceed();//放行} catch (Throwable throwable) {throwable.printStackTrace();}//新開開一個線程延遲0.5秒(時間可以改成自己的業務需求),等著mysql那邊業務操作完成//在線程中延遲刪除  同時將業務代碼的結果返回 這樣不影響業務代碼的執行new Thread(() -> {try {Thread.sleep(500);Set<String> keys1 = redisUtils.keys("*" + name + "*");//模糊刪除redisUtils.del(keys1);log.info("-----------0.5秒后,在線程中延遲刪除完畢 -----------");} catch (InterruptedException e) {e.printStackTrace();}}).start();return proceed;//返回業務代碼的值}}

9、UserController

可以在 redisUtils.del(keys)的時候打斷點調試

package com.xx.controller;import com.xx.cache.Cache;
import com.xx.cache.ClearAndReloadCache;
import com.xx.common.Result;
import com.xx.entity.User;
import com.xx.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;/*** @Author: xueqimiao* @Date: 2025/3/17 14:27*/
@RestController
@RequestMapping("/user")
public class UserController {@Resourceprivate UserService userService;@PostMapping("/updateData")@ClearAndReloadCache(name = "get_user")public Result updateData(@RequestBody User user) {return userService.update(user);}@GetMapping("/get")@Cache(name = "get_user")public Result get(@RequestParam Integer id) {return userService.get(id);}
}

寫在最后

Java是一種強大的語言,它賦予了我們創造無限可能的力量。無論你是在開發企業級應用、移動應用還是大數據處理系統,Java都在背后默默支持著你。在這個瞬息萬變的技術時代,保持學習的熱情和對新技術的敏感度是至關重要的。每一個新的Java版本發布,都帶來了新的特性和改進,這是我們提升自己的絕佳機會。讓我們一起在Java的道路上勇往直前,用代碼構建更加美好的數字世界,因為你手中的代碼,有可能成為下一個改變世界的偉大發明。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/898957.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/898957.shtml
英文地址,請注明出處:http://en.pswp.cn/news/898957.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Windows桌面采集技術

在進入具體的方式討論前&#xff0c;我們先看看 Windows 桌面圖形界面的簡化架構&#xff0c;如下圖&#xff1a; 在 Windows Vista 之前&#xff0c;Windows 界面的復合畫面經由 Graphics Device Interface&#xff08;以下簡稱 GDI&#xff09;技術直接渲染到桌面上。 在 Wi…

ElementPlus 快速入門

目錄 前言 為什么要學習 ElementPlus&#xff1f; 正文 步驟 1 創建 一個工程化的vue 項目 ?2 安裝 element-Plus :Form 表單 | Element Plus 1 點擊 當前界面的指南 2 點擊左邊菜單欄上的安裝&#xff0c;選擇包管理器 3 運行該命令 demo(案例1 &#xff09; 步驟 …

TypeScript語言的設備管理

TypeScript 設備管理系統的設計與實現 引言 在現代社會&#xff0c;設備管理已成為企業和組織運營中不可或缺的一部分。無論是IT設備、辦公家具還是生產機器&#xff0c;企業都需要一種有效的方式來管理、追蹤和維護這些資產。隨著前端技術的不斷發展&#xff0c;TypeScript作…

Ubuntu20.04.6系統根目錄擴容

文章目錄 方法一&#xff1a;**1. 檢查磁盤和分區情況****2. 擴展 vda3 分區****3. 擴展 LVM 物理卷****4. 擴展 LVM 邏輯卷****5. 擴展文件系統** 方法二:1. 查看當前磁盤分區情況2. 創建新分區3. 重新加載分區表4. 擴展物理卷&#xff08;PV&#xff09;5. 擴展邏輯卷&#x…

[藍橋杯 2023 省 A] 異或和之和

題目來自洛谷網站&#xff1a; 暴力思路&#xff1a; 先進性預處理&#xff0c;找到每個點位置的前綴異或和&#xff0c;在枚舉區間。 暴力代碼&#xff1a; #include<bits/stdc.h> #define int long long using namespace std; const int N 1e520;int n; int arr[N…

python學習筆記--實現簡單的爬蟲(二)

任務&#xff1a;爬取B站上最愛歡迎的編程課程 網址&#xff1a;編程-嗶哩嗶哩_bilibili 打開網頁的代碼模塊&#xff0c;如下圖&#xff1a; 標題均位于class_"bili-video-card__info--tit"的h3標簽中&#xff0c;下面通過代碼來實現&#xff0c;需要說明的是URL中…

微服務分層架構詳解:表示層、應用層與基礎設施層的協同工作

微服務分層架構詳解&#xff1a;表示層、應用層與基礎設施層的協同工作 文章目錄 微服務分層架構詳解&#xff1a;表示層、應用層與基礎設施層的協同工作1. 表示層&#xff08;Presentation Layer&#xff09;1.1 表示層的作用1.2 技術選型1.3 表示層的挑戰 2. 應用層&#xff…

[C++面試] 你了解transform嗎?

層級核心知識點入門基本語法、與for_each對比、單/雙范圍操作進階動態擴展、原地轉換、類型兼容性、異常安全高階性能優化、C20 Ranges、transform_if模擬 一、入門 1、描述std::transform的基本功能&#xff0c;并寫出兩種版本的函數原型 std::transform函數是 C 標準庫<…

windows清除電腦開機密碼,可保留原本的系統和資料,不重裝系統

前言 很久的一臺電腦沒有使用了&#xff0c;開機密碼忘了&#xff0c;進不去系統 方法 1.將一個閑置u盤設置成pe盤&#xff08;注意&#xff0c;這個操作會清空原來u盤的數據&#xff0c;需要在配置前將重要數據轉移走&#xff0c;數據無價&#xff0c;別因為配置這個丟了重…

5.4 位運算專題:LeetCode 137. 只出現一次的數字 II

1. 題目鏈接 LeetCode 137. 只出現一次的數字 II 2. 題目描述 給定一個整數數組 nums&#xff0c;其中每個元素均出現 三次&#xff0c;除了一個元素只出現 一次。請找出這個只出現一次的元素。 要求&#xff1a; 時間復雜度為 O(n)&#xff0c;空間復雜度為 O(1)。 示例&a…

C語言:掃雷

在編程的世界里&#xff0c;掃雷游戲是一個經典的實踐項目。它不僅能幫助我們鞏固編程知識&#xff0c;還能鍛煉邏輯思維和解決問題的能力。今天&#xff0c;就讓我們一起用 C 語言來實現這個有趣的游戲&#xff0c;并且通過圖文并茂的方式&#xff0c;讓每一步都清晰易懂 1. 游…

【論文#目標檢測】YOLO9000: Better, Faster, Stronger

目錄 摘要1.引言2.更好&#xff08;Better&#xff09;3.更快&#xff08;Faster&#xff09;4.更健壯&#xff08;Stronger&#xff09;使用 WordTree 組合數據集聯合分類和檢測評估 YOLO9000 5.結論 Author: Joseph Redmon; Ali Farhadi Published in: 2017 IEEE Conference …

數據庫誤更新操作 如何回滾

1.未提交 直接 rollback 2.已提交 步驟 查詢指定時間內修改前數據庫數據&#xff1a; -- 查詢誤操作前的數據&#xff08;例如 10 分鐘前&#xff09; SELECT * FROM 表名 AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL 10 MINUTE) WHERE 條件;-- 將數據恢復&#xff08;需確保有…

大數據運維實戰之YARN任務內存泄露排查實戰:從節點掉線到精準定位的完整指南

1.問題背景&#xff1a;集群內存風暴引發的危機 最近某大數據集群頻繁出現節點掉線事故&#xff0c;物理內存監控持續爆紅。運維人員發現當節點內存使用率達到95%以上時&#xff0c;機器會進入不可響應狀態&#xff0c;最終導致服務中斷。這種"內存雪崩"現象往往由單…

AI+金融 應用 使用DeepSeek、Qwen等大模型輸入自然語言,得到通達信等行情軟件公式代碼,導入后使用

AI金融 應用 使用DeepSeek、Qwen等大模型輸入自然語言&#xff0c;得到通達信等行情軟件公式代碼&#xff0c;導入后使用。不會編程&#xff0c;也能行情軟件中實現個性化條件選股&#xff0c;個性化技術指標。 AIbxm低估值趨勢選股策略&#xff0c;參考提示詞&#xff1a; 編…

[Xilinx]工具篇_PetaLinux自動編譯

[Xilinx]工具篇_PetaLinux自動編譯 若該文為原創文章&#xff0c;未經允許不得轉載風釋雪QQ:627833006E-mail:hn.cyfoxmail.comCSDN博客: https://blog.csdn.net/weixin_46718879知乎&#xff1a;https://www.zhihu.com/people/abner-80-4 1.版本 日期作者版本說明2025XXXX風釋…

多語言語料庫萬卷·絲路2.0開源,數據模態全面升級,搭建文化交流互鑒AI橋梁

3月22日&#xff0c;上海人工智能實驗室&#xff08;上海AI實驗室&#xff09;聯合新華社新聞信息中心、上海外國語大學、外研在線等&#xff0c;發布全新升級的“萬卷絲路2.0”多語言語料庫&#xff0c;通過構建多語言開源數據底座&#xff0c;以人工智能賦能“一帶一路”高質…

多語言生成語言模型的少樣本學習

摘要 大規模生成語言模型&#xff0c;如GPT-3&#xff0c;是極具競爭力的少樣本學習模型。盡管這些模型能夠共同表示多種語言&#xff0c;但其訓練數據以英語為主&#xff0c;這可能限制了它們的跨語言泛化能力。在本研究中&#xff0c;我們在一個涵蓋多種語言的語料庫上訓練了…

Linux運維篇-系統io調優

目錄 磁盤文件系統虛擬文件系統 文件系統的工作原理文件系統 I/OI/O 的分類緩沖與非緩沖 I/O直接與非直接 I/O阻塞與非阻塞 I/O同步與異步 I/O 查看文件系統容量目錄項和索引節點緩存 通用塊層I/O 棧磁盤性能指標磁盤 I/O 觀測進程 I/O 觀測I/O瓶頸的排查思路思路一思路二 I/O優…

C語言筆記(鵬哥)上課板書+課件匯總(動態內存管理)--數據結構常用

動態內存管理 引言&#xff1a;將內存升起一段空間存放數據有幾種手段 創建變量&#xff1a;存放一個值創建數組&#xff1a;存放多個連續的一組值 以上開辟的內存空間是固定的&#xff0c;創建大了&#xff0c;空間浪費&#xff0c;創建小了&#xff0c;空間不夠。并且一旦…