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

拦截指定注解(FeignClient),补偿重试

拦截指定注解(FeignClient),补偿重试;对代码无入侵
避免正常调用和重试逻辑调用重复插入;
根据自己的业务需求 插入新数据时 是否需要删除之前的旧数据,防止数据覆盖


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.ev.edge.computility.domain.dto.BaseResult;
import com.ev.edge.retryFail.domain.RetryFailLog;
import com.ev.edge.retryFail.service.RetryFailLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.Arrays;
import java.util.Date;import static com.ev.edge.constants.Constants.CONSTANT_ZERO;@Aspect
@Component
@Slf4j
public class RetryFailureAop {@Autowiredprivate RetryFailLogService retryFailLogService;@Around("@within(org.springframework.cloud.openfeign.FeignClient)")public Object handleFeignClientResponse(ProceedingJoinPoint joinPoint) throws Throwable {// 执行目标方法Object result = joinPoint.proceed();// 如果是重试调用,则跳过日志插入逻辑if (RetryFailureAopScheduled.isRetryCall()) {return result;}if (result instanceof BaseResult<?>) {BaseResult<?> sesResult = (BaseResult<?>) result;// 只对特定状态码做处理if (!ObjectUtil.equal(sesResult.getCode(), CONSTANT_ZERO)) {logFailedRequest(joinPoint, sesResult);}}return result;}/*** 记录失败请求到数据库*/private void logFailedRequest(ProceedingJoinPoint joinPoint, BaseResult<?> sesResult) {try {MethodSignature signature = (MethodSignature) joinPoint.getSignature();String targetClass = signature.getDeclaringTypeName(); // 获取目标类名String targetMethod = signature.getName(); // 获取方法名Object[] args = joinPoint.getArgs();RetryFailLog log = new RetryFailLog();log.setTargetClass(targetClass);log.setTargetMethod(targetMethod);// 序列化请求参数为 JSON 字符串log.setRequestArgs(JSONUtil.toJsonStr(args));// 在 logFailedRequest 方法中Class<?>[] parameterTypes = signature.getParameterTypes();// 将 Class 数组转换为包含全限定类名的字符串数组String[] parameterTypeNames = Arrays.stream(parameterTypes).map(Class::getName).toArray(String[]::new);log.setParameterTypeList(Arrays.asList(parameterTypeNames));log.setErrorMessage("Feign 调用失败: " + sesResult.getMsg());log.setStatus("pending");log.setRetryCount(0);log.setMaxRetryTimes(5); // 可以从配置文件读取log.setNextRetryTime(calculateNextRetryTime(0));log.setCreateTime(new Date());log.setUpdateTime(new Date());// 保存到数据库retryFailLogService.save(log);} catch (Exception e) {// 防止日志记录失败导致业务异常log.error("记录失败日志时发生异常", e);}}private Date calculateNextRetryTime(int retryCount) {long delay = (long) Math.pow(2, retryCount) * 1000 * 60; // 指数退避,分钟级return new Date(System.currentTimeMillis() + delay);}
}

 定时任务 补偿处理

@Configuration
@Slf4j
@AllArgsConstructor
public class RetryFailureAopScheduled {// 缓存 <methodKey, Method> 提升反射效率private static final Map<String, Method> METHOD_CACHE = new ConcurrentHashMap<>();private final RetryFailLogService retryFailLogService;/*** 定时任务:每分钟执行一次,检查并重试失败的日志记录*/@Scheduled(fixedRate = 60_000)public void retryFailedRequests() {List<RetryFailLog> logs = retryFailLogService.findPendingAndDue();for (RetryFailLog logEntry : logs) {try {boolean success = invoke(logEntry);if (success) {logEntry.setStatus("success");log.info("重试成功: {}, method={}", logEntry.getTargetClass(), logEntry.getTargetMethod());} else {updateRetryInfo(logEntry);log.warn("重试未完成: {}, method={}, 当前重试次数: {}",logEntry.getTargetClass(), logEntry.getTargetMethod(), logEntry.getRetryCount());}} catch (Exception e) {log.error("重试失败: {}, method={}, error={}",logEntry.getTargetClass(), logEntry.getTargetMethod(), e.getMessage(), e);updateRetryInfo(logEntry);} finally {retryFailLogService.updateById(logEntry);}}}public boolean invoke(RetryFailLog logEntry) {try {markAsRetryCall();String targetClass = logEntry.getTargetClass();String targetMethod = logEntry.getTargetMethod();String requestArgsJson = logEntry.getRequestArgs();List<String> parameterTypeNames = logEntry.getParameterTypeList();Class<?>[] paramTypes = loadParameterTypes(parameterTypeNames);// 获取目标类和 Bean 实例Class<?> clazz = Class.forName(targetClass);Object bean = SpringUtils.getBean(clazz);// 构建唯一方法 KeyString methodKey = buildMethodKey(clazz, targetMethod, paramTypes);// 已经从缓存或首次加载中获取了 Method 对象Method method = METHOD_CACHE.computeIfAbsent(methodKey, k -> {try {return clazz.getDeclaredMethod(targetMethod, paramTypes);} catch (NoSuchMethodException e) {log.error("找不到目标方法: {}.{}", targetClass, targetMethod, e);return null;}});if (method == null) {throw new NoSuchMethodException("未找到方法: " + targetMethod + " 在类: " + targetClass);}// 反序列化请求参数Object[] args = deserializeArgs(requestArgsJson, paramTypes);// 获取目标对象(绕过 AOP)Object target = AopUtils.getTargetObject(bean);// 设置可访问性为 true(以防方法不是 public)method.setAccessible(true);
 // 直接使用已有的 method 对象调用目标对象上的方法Object result = method.invoke(target, args);// 调用方法
// Object result1 = ReflectUtil.invoke(bean, method, args);
            // 判断是否调用成功(注意类型安全)return isSuccessResult(result);} catch (InvocationTargetException e) {Throwable cause = e.getCause();log.error("调用目标方法失败", cause);return false;} catch (Exception e) {log.error("invoke 方法出现异常", e);return false;} finally {clear(); // 清除标记,确保不会影响其他调用}}/*** 动态调用 Feign Client 方法*/
//    public boolean invoke(RetryFailLog logEntry) throws Exception {
//        String targetClass = logEntry.getTargetClass();
//        String targetMethod = logEntry.getTargetMethod();
//        String requestArgsJson = logEntry.getRequestArgs();
//
//        List<String> parameterTypeNames = logEntry.getParameterTypeList();
//        Class<?>[] paramTypes = loadParameterTypes(parameterTypeNames);
//
//        // 获取目标类和 Bean 实例
//        Class<?> clazz = Class.forName(targetClass);
//        Object bean = SpringUtils.getBean(clazz);
//
//        // 构建唯一方法 Key
//        String methodKey = buildMethodKey(clazz, targetMethod, paramTypes);
//
//        // 从缓存中获取 Method 或首次加载
//        Method method = METHOD_CACHE.computeIfAbsent(methodKey, k -> {
//            try {
//                return clazz.getDeclaredMethod(targetMethod, paramTypes);
//            } catch (NoSuchMethodException e) {
//                log.error("找不到目标方法: {}.{}", targetClass, targetMethod, e);
//                return null;
//            }
//        });
//
//        if (method == null) {
//            throw new NoSuchMethodException("未找到方法: " + targetMethod + " 在类: " + targetClass);
//        }
//
//        // 反序列化请求参数
//        Object[] args = deserializeArgs(requestArgsJson, paramTypes);
//        // 调用方法
//        Object result = ReflectUtil.invoke(bean, method, args);
//
//        // 判断是否调用成功(根据业务返回值判断)
//        return isSuccessResult(result);
//    }/*** 将参数类型字符串转换为 Class[]*/private Class<?>[] loadParameterTypes(List<String> typeNames) throws ClassNotFoundException {Class<?>[] types = new Class<?>[typeNames.size()];for (int i = 0; i < typeNames.size(); i++) {types[i] = getClassForName(typeNames.get(i));}return types;}/*** 根据类名字符串获取 Class 对象(支持泛型截断)*/private Class<?> getClassForName(String className) throws ClassNotFoundException {if (className.contains("<")) {className = className.substring(0, className.indexOf('<'));}return Class.forName(className);}/*** 构建方法唯一标识 Key*/private String buildMethodKey(Class<?> clazz, String methodName, Class<?>... paramTypes) {StringBuilder sb = new StringBuilder(clazz.getName()).append("#").append(methodName);for (Class<?> t : paramTypes) {sb.append("$").append(t.getName());}return sb.toString();}/*** 反序列化 JSON 字符串为参数数组*/private Object[] deserializeArgs(String json, Class<?>... paramTypes) {Object[] array = JSONUtil.parseArray(json).toArray();Object[] args = new Object[paramTypes.length];for (int i = 0; i < paramTypes.length; i++) {args[i] = Convert.convert(paramTypes[i], array[i]);}//        // 解析 JSON 字符串为数组
//        Object[] jsonArray = JSONUtil.parseArray(json).toArray();
//        Object[] args = new Object[paramTypes.length];
//        for (int i = 0; i < paramTypes.length; i++) {
//            Class<?> paramType = paramTypes[i];
//            Object jsonElement = jsonArray[i];
//
//            if (jsonElement == null) {
//                args[i] = null;
//                continue;
//            }
//
//            // 如果目标类型是 String,则直接使用 JSONUtil.toStr()
//            if (paramType == String.class) {
//                args[i] = JSONUtil.toJsonStr(jsonElement);
//            }
//            // 如果目标类型是 Long 或 long,则尝试将 JSON 元素转换为 Long
//            else if (paramType == Long.class || paramType == long.class) {
//                if (jsonElement instanceof Number) {
//                    args[i] = ((Number) jsonElement).longValue();
//                } else {
//                    try {
//                        args[i] = Long.parseLong(JSONUtil.toJsonStr(jsonElement));
//                    } catch (NumberFormatException e) {
//                        throw new IllegalArgumentException("无法将参数 '" + JSONUtil.toJsonStr(jsonElement) + "' 转换为 Long 类型", e);
//                    }
//                }
//            }
//            // 如果目标类型是 Integer 或 int,则尝试将 JSON 元素转换为 Integer
//            else if (paramType == Integer.class || paramType == int.class) {
//                if (jsonElement instanceof Number) {
//                    args[i] = ((Number) jsonElement).intValue();
//                } else {
//                    try {
//                        args[i] = Integer.parseInt(JSONUtil.toJsonStr(jsonElement));
//                    } catch (NumberFormatException e) {
//                        throw new IllegalArgumentException("无法将参数 '" + JSONUtil.toJsonStr(jsonElement) + "' 转换为 Integer 类型", e);
//                    }
//                }
//            }
//            // 对于其他复杂对象类型,使用 JSONUtil.toBean()
//            else {
//                args[i] = JSONUtil.toBean(JSONUtil.toJsonStr(jsonElement), paramType);
//            }
//        }return args;}/*** 更新重试次数、下次重试时间等信息*/private void updateRetryInfo(RetryFailLog logEntry) {int maxRetryTimes = logEntry.getMaxRetryTimes();int retryCount = logEntry.getRetryCount() + 1;if (retryCount >= maxRetryTimes) {logEntry.setStatus("failed");log.warn("已达最大重试次数({}), 请求失败: {}.{}", maxRetryTimes,logEntry.getTargetClass(), logEntry.getTargetMethod());} else {logEntry.setRetryCount(retryCount);logEntry.setNextRetryTime(calculateNextRetryTime(retryCount));}}/*** 计算下一次重试时间(指数退避策略)*/private Date calculateNextRetryTime(int retryCount) {long baseDelay = 30_000L; // 基础延迟 30slong delay = baseDelay * (1L << retryCount); // 指数增长return new Date(System.currentTimeMillis() + delay);}/*** 简单判断调用结果是否成功(可按实际业务逻辑扩展)*/private boolean isSuccessResult(Object result) {if (result instanceof BaseResult) {BaseResult ses = (BaseResult) result;String msg = ses.getMsg();return ObjectUtil.equal(ses.getCode(), SUCCESS.getCode());}return false;}private static final ThreadLocal<Boolean> isRetryCall = new ThreadLocal<>();public static void markAsRetryCall() {isRetryCall.set(true);}public static boolean isRetryCall() {return Boolean.TRUE.equals(isRetryCall.get());}public static void clear() {isRetryCall.remove();}
}        


@TableName(value = "retry_fail_log")
@Data
public class RetryFailLog {private Long id;private String targetClass;private String targetMethod;private String errorMessage;private Integer retryCount;private Integer maxRetryTimes;private Date nextRetryTime;private String status;private Date createTime;private Date updateTime;private String requestArgs; // 原始请求参数的 JSON 字符串private String parameterTypes; // 参数类型的字符串数组public List<String> getParameterTypeList() {return JSONUtil.toList(parameterTypes, String.class);}public void setParameterTypeList(List<String> parameterTypeList) {this.parameterTypes = JSONUtil.toJsonStr(parameterTypeList);}
}

@Data
public abstract class  BaseResult<T> {private String code;private String msg;private T data;
}

-- inference_platform.retry_fail_log definition

CREATE TABLE `retry_fail_log` (

`id` bigint NOT NULL AUTO_INCREMENT,

`target_class` varchar(255) COLLATE utf8mb4_bin NOT NULL,

`target_method` varchar(255) COLLATE utf8mb4_bin NOT NULL,

`request_args` text COLLATE utf8mb4_bin NOT NULL,

`parameter_types` text COLLATE utf8mb4_bin NOT NULL,

`error_message` text COLLATE utf8mb4_bin,

`retry_count` int DEFAULT '0',

`max_retry_times` int DEFAULT '5',

`next_retry_time` datetime DEFAULT NULL,

`status` varchar(50) COLLATE utf8mb4_bin DEFAULT 'pending',

`create_time` datetime DEFAULT CURRENT_TIMESTAMP,

`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

PRIMARY KEY (`id`),

KEY `idx_status` (`status`),

KEY `idx_next_retry_time` (`next_retry_time`)

) ENGINE=InnoDB AUTO_INCREMENT=70 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

@Select("SELECT * FROM retry_fail_log WHERE status = 'pending' AND next_retry_time <= NOW()")
List<RetryFailLog> findPendingAndDue();

 


<dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.9.19</version> <!-- 确保使用最新版本,这里以1.9.19为例 -->
</dependency>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.19</version> <!-- 确保使用最新版本,这里以1.9.19为例 -->
</dependency>

相关文章:

拦截指定注解(FeignClient),补偿重试

拦截指定注解&#xff08;FeignClient&#xff09;&#xff0c;补偿重试&#xff1b;对代码无入侵 避免正常调用和重试逻辑调用重复插入&#xff1b; 根据自己的业务需求 插入新数据时 是否需要删除之前的旧数据&#xff0c;防止数据覆盖 import cn.hutool.core.util.ObjectUti…...

使用 GitHub Pages 部署单页面应用教程

## 简介 GitHub Pages 是 GitHub 提供的一个静态网站托管服务&#xff0c;可以免费托管个人、项目或组织页面。本教程将指导您如何部署一个单页面应用到 GitHub Pages。 ## 前提条件 - 拥有 GitHub 账号 - 已安装 Git - 已安装 Node.js&#xff08;如果使用前端框架&#x…...

day16-17-磁盘管理

1. 磁盘分类 磁盘接口 硬盘 大小 sata接口 机械硬盘、固态硬盘 机械&#xff1a;4tb 10k性能要求不高 sas接口 机械硬盘、固态硬盘 机械&#xff1a;900G 15k性能好&#xff0c;容量低 pcie-e接口 固态硬盘 tb级别 4tb 8tb 性能要求高&#xff0c;数据库&#xff0c…...

【神经网络与深度学习】扩散模型之通俗易懂的解释

引言&#xff1a; 扩散模型&#xff08;Diffusion Models&#xff09;是近年来深度学习领域的一项重要突破&#xff0c;尤其在生成式人工智能&#xff08;Generative AI&#xff09;中展现了惊人的能力。它的核心思想类似于一个孩子学习搭建乐高城堡的过程——先拆散&#xff0…...

Linux Bash 中 $? 的详细用法

Bash (Bourne Again SHell) 是使用最广泛的 SHell 脚本语言之一&#xff0c;因为它与 Unix 和 Linux 系统兼容。它提供了许多内置函数和变量&#xff0c;使脚本编写更高效&#xff0c;更不容易出错。其中一个变量是 $?&#xff0c; 它是 Bash 脚本错误处理的一个组成部分。这个…...

嵌入式培训之系统编程(一)标准IO、文件操作

目录 一、系统编程概述 二、标准IO &#xff08;一&#xff09;&#xff08;以计算机为中心&#xff09;标准IO &#xff08;二&#xff09;io的分类 &#xff08;三&#xff09;man命令 三、文件读写操作 &#xff08;一&#xff09;文件操作步骤 &#xff08;二&#…...

NVIDIA Earth-2 AI 天气模型 DLI 课程:解锁全球风云的未来之匙

电影闲聊引发思索之言&#xff1a; 曾几何时&#xff0c;当我们闲聊起那些描绘美国气候的大电影时&#xff08;龙卷风-后天等美国大片&#xff09;&#xff0c;仿佛被带入了一个个奇幻而真实的气象世界。从狂风暴雨到烈日炎炎最后到冰天雪地&#xff0c;电影里的场景让我们对气…...

至此(day1-day4)代码详解(ai辅助整理)

至此&#xff08;day1-day4&#xff09;代码详解 ipl10.nas ; 第一阶段引导程序 ; 功能&#xff1a;读取磁盘数据并跳转到第二阶段加载程序 ; 编译参数&#xff1a;nask -o ipl10.bin ipl10.nasCYLS EQU 10 ; 预设读取柱面数&#xff08;实际值由BIOS决定&#xff09;ORG…...

STM32F103_LL库+寄存器学习笔记12.2 - 串口DMA高效收发实战2:进一步提高串口接收的效率

导言 通过优化代码算法&#xff0c;在串口空闲中断回调里不需要暂时关闭DMA接收&#xff0c;达到提高串口接收的效率。在IDLE接收中断里关闭DMA接收会导致接收过程中有数据丢失风险&#xff08;关DMA的瞬间如果有数据到来&#xff0c;会丢帧&#xff01;&#xff09;。 回顾一…...

conda 设置env后,环境还是安装在c盘的解决方式:

1|设置 envs 文件夹权限 右键【envs】文件夹&#xff0c;选择【属性】 选择【安全】&#xff0c;点击【编辑】 选中【Users(用户名\Users)】&#xff0c;选中运行所有权限&#xff0c;如图所示 点击【确认】&#xff0c;确保修改被保存 2、环境变量path设置 选择【高级系统设置…...

设计模式 - 工厂模式

简单工厂模式 public class CoffeeFactory {public Coffee get(string coffeeType) {Coffee coffee null;if ("American".equals(coffeeType)) {coffee new AmericanCoffee();} else if ("Latte".equals(coffeeType)) {coffee new LatteCoffee();}retur…...

动态规划-LCR 090.打家劫舍II-力扣(LeetCode)

一、题目解析 本题与打家劫舍的最大区别在于房子不是线性分布的了&#xff0c;而是首尾相连的环形分布&#xff0c;即如果偷了第一间房子&#xff0c;那么最后一间房子就不能偷了&#xff0c;因为它们是相连的。 二、算法原理 在分析之前我们可以先讨论上面提到的第一间房子偷…...

2025 年暑假 LBE 大空间市场火爆程度预测:技术驱动与消费升级下的增长引擎

一、市场爆发的底层逻辑 根据 DeepSeek 行业报告显示&#xff0c;2025 年 LBE 大空间市场将呈现结构性爆发&#xff0c;核心驱动力来自三大技术突破&#xff1a; 空间计算能力跃迁&#xff1a;上海移动已开通全球最大规模商用 5G-A 3CC 网络&#xff0c;主城区及十大重点场景…...

【AI 大模型】盘古大模型简介 ( 创建空间 | 体验模型 | 部署模型 )

文章目录 一、盘古大模型简介1、创建空间2、体验模型3、部署模型 总结 : 盘古大模型 是 开发部署 盘古基础模型 , 或 在 盘古模型 基础上进行 微调训练 的 大模型 的平台 , 是 开发训练 大模型的平台 ; 不适合 中小企业 和 个人开发者 开发 大模型应用 ; 一、盘古大模型简介 1、…...

2025年护网行动蓝队防御全解析:构建智能动态防御体系

2025年&#xff0c;随着网络攻击手段的智能化、混合化升级&#xff0c;护网行动中的蓝队防御已从传统的被动防护转向“动态感知、智能研判、主动反制”的立体化模式。如何在攻防不对称的对抗中实现“看得见、防得住、溯得清”&#xff1f;本文将结合前沿技术与实战经验&#xf…...

【Java高阶面经:微服务篇】3.熔断机制深度优化:从抖动治理到微服务高可用架构实战

一、熔断抖动的本质剖析与核心成因 1.1 熔断机制的核心价值与抖动危害 熔断机制作为微服务弹性架构的核心组件,通过模拟电路断路器逻辑,在服务出现异常时自动阻断请求链,防止故障扩散引发雪崩。但频繁的“熔断-恢复-熔断”抖动会导致: 用户体验恶化:请求成功率波动大,响…...

HTML回顾

html全称:HyperText Markup Language(超文本标记语言) 注重标签语义,而不是默认效果 规则 块级元素包括: marquee、div等 行内元素包括: span、input等 规则1:块级元素中能写:行内元素、块级元素(几乎什么都能写) 规则2:行级元素中能写:行内元素,但不能写:块…...

Leetcode百题斩-字典树

208. Implement Trie (Prefix Tree)[medium] 做完了哈希&#xff0c;来看看数据结构&#xff0c;做做字典树。字典树在搜索方面的作用还是蛮大的&#xff0c;主要是能实现前缀联想以及正确性匹配相关的功能。 字典树又名前缀树&#xff0c;顾名思义就是维护字符串的前缀。这个…...

大数据Spark(五十九):Standalone集群部署

文章目录 Standalone集群部署 一、节点划分 二、搭建Standalone集群 1、将下载好的Spark安装包上传解压 2、配饰spark-env.sh 3、配置workers 4、将配置好的安装包发送到node2、node3节点上 5、启动Standalone集群 三、提交任务测试 Standalone集群部署 Standalone 模…...

Vue 3 ~ 3.5 版本useTemplateRef使用

注意&#xff0c;useTemplateRef版本要在 3.5 以后才可使用&#xff0c;版本低的 ref 替代问题也不大&#xff5e; 2024 年 9 月 1 日发布的 组合式 API&#xff1a;辅助 | Vue.js&#xff0c;引入一个小小的新 API useTemplateRef()&#xff0c;它用于访问实际的 DOM 节点。 …...

使用F5-tts复刻音色

最近第一人称视角的视频很火&#xff0c;想试试看复刻一下电视剧中某个角色的音色。看了下字节的API&#xff0c;嗯。。。138元一个音色&#xff0c;还不包括合成语音的费用&#xff0c;算了还是看看开源项目吧。 随便搜了搜&#xff0c;发现了两个项目一个是openvoice&#x…...

使用亮数据代理IP+Python爬虫批量爬取招聘信息训练面试类AI智能体(附完整源码)

文章目录 一、为什么要用代理IP&#xff1f;(重要&#xff01;)二、环境准备&#xff08;5分钟搞定&#xff09;三、爬虫核心代码解析&#xff08;含反反爬技巧&#xff09;四、数据清洗的3个关键步骤五、训练AI智能体的实战技巧六、法律风险防范&#xff08;必须看&#xff01…...

[软件工程]第二章题目汇总

1 [单选题] 原型化模型是&#xff08; &#xff09;。 A、适用于客户需求被明确定义的情况 B、很难产生有意义产品的一种冒险模型 C、提供一个精确表述的形式化规格说明 D、适用于客户需求难以清楚定义的情况 2 [单选题] 下列关于增量模型的说法正确的是&#xff08; &…...

Java EE进阶1:导读

1.发展历程 2.学习内容 前⾯的课程中,学习的是Java基础,JavaEE主要学习Java的应用,也就是学习Java在企业中是如何应用的 Java更多场景是业务开发,更狭义点可以理解为web开发.所以咱们的学习也是围绕着如何使用Java来做web开发 2.1 什么是Web开发&#xff1f; web&#xff08…...

Unity自定义shader打包SpriteAtlas图集问题

Unity打包图集还是有一些坑的&#xff0c;至于图集SpriteAtlas是什么请参考我之前写的文章&#xff1a;【Sprite Atlas】Unity新图集系统SpriteAtlas超详细使用教程_spriteatlas 使用-CSDN博客 问题&#xff1a; 今天碰到的问题是&#xff0c;shader绘制的时候&#xff0c;因…...

系统集成项目管理工程师学习笔记之启动过程组

第十章 启动过程组 制定项目章程 定义 制定项目章程是编写一份正式批准项目并授权项目经理在项目活动中使用组织资源的文件的过程。 正式批准的项目文件 作用 1、明确项目与组织战略目标之间的直接联系 2、确立项目的正式地位 3、展示组织对项目的承诺 本过程仅开展一…...

vscode 常用调试

一、文件执行 python script.py {"name": "Python 调试程序: 当前文件","type": "debugpy","request": "launch","program": "${file}","console": "integratedTerminal"…...

Java 07异常

异常 指的是程序在编译和执行的过程中&#xff0c;出现的非正常的情况&#xff1b; 当然语法错误并不属于错误异常体系 最大的Throwable; 分为两个&#xff1a;Error ExceptionError 严重级别问题 常见的 堆内存溢出 栈内存溢出Exception 分为两个子类 RuntimeException 运…...

2025年PMP 学习二十三 16章 高级项目管理

2025年PMP 学习二十三 16章 高级项目管理 文章目录 2025年PMP 学习二十三 16章 高级项目管理高级项目管理战略管理战略管理的组成要素&#xff1a;企业战略转化为战略行动的阶段&#xff1a; 组织战略类型战略组织类型组织级项目管理OPM&#xff08;公司项目管理&#xff09; 组…...

【Java高阶面经:微服务篇】1.微服务架构核心:服务注册与发现之AP vs CP选型全攻略

一、CAP理论在服务注册与发现中的落地实践 1.1 CAP三要素的技术权衡 要素AP模型实现CP模型实现一致性最终一致性(Eureka通过异步复制实现)强一致性(ZooKeeper通过ZAB协议保证)可用性服务节点可独立响应(支持分区存活)分区期间无法保证写操作(需多数节点可用)分区容错性…...

ISCC 2025决赛 wp

PWN Dilemma 64位程序没有开启PIE&#xff0c;并且过滤了execve&#xff0c;不能使用system这些的了&#xff0c;所以要考虑ORW来做 进入main函数分析&#xff0c;这里有两个函数一个func_1一个func_2。 这两个函数都有漏洞&#xff0c;以下是详细分析&#xff1a; 对于func…...

C++(5)switch语句 循环while

这是一个电影评分的程序 default 就是 如果上述的都没有执行 就统一的执行default的内容。 然后记得break ___________________________________ 循环 &#xff08;while&#xff09; while的使用方式 输出 0-9的while循环...

操作系统----软考中级软件工程师(自用学习笔记)

目录 1、计算机系统层次结构 2、程序顺序执行的特征 3、程序并发执行的特征 4、三态模型 5、同步与互斥 6、信号量机制 7、PV操作 8、死锁 9、进程资源图 10、死锁避免 11、线程 12、程序局部性原理 13、分页存储管理 14、单缓冲器 15、双缓冲区 16、磁盘调度算…...

利用Spring Boot和Redis构建高性能缓存系统

利用Spring Boot和Redis构建高性能缓存系统 引言 在现代Web应用中&#xff0c;缓存是提升系统性能的关键技术之一。Redis作为一种高性能的内存数据库&#xff0c;广泛应用于缓存场景。本文将介绍如何利用Spring Boot和Redis构建一个高性能的缓存系统&#xff0c;涵盖Redis的基…...

每日一题:1、虚拟IPv4地址转换为32位整数(JS)

题目背景 我们需要处理一种特殊的虚拟IPv4地址&#xff0c;这种地址由4个小节组成&#xff0c;每节之间用#分隔。与标准IPv4地址不同&#xff0c;虚拟IPv4地址的第一节范围是1~128&#xff0c;后三节的范围是0~255。我们需要将这种虚拟IPv4地址转换为一个唯一的32位整数。如果…...

[Vue]组件介绍和父子组件间传值

组件介绍 Vue3的 .vue文件中的主要部分分别分为三个&#xff1a;<template>、<script>、<style> <template>&#xff1a; 结构&#xff0c;相当于原html中的<head><body><footer>部分。原本的index.html现在只做一个容器&#xff0…...

Vue3 中使用 provide/inject 实现跨层级组件传值失败的原因及解决方案

1、基础用法 父组件&#xff1a; <script setup> import { ref, provide } from vue; import ChildComponent from ./ChildComponent.vue; const parentData ref(初始数据); // 提供数据 provide(parentData, parentData); </script>子组件&#xff1a; <sc…...

Git Hooks 和 自动生成 Commit Message

前言&#xff1a; 企业编程必须始终依赖流程&#xff0c;而不是个人。个人能力很重要&#xff0c;应该鼓励&#xff0c;但不能指望它&#xff0c;否则软件质量将不一致&#xff0c;没有可持续性。一旦顶级程序员跳槽&#xff0c;公司就会陷入困境。企业应该努力改进工作流程&am…...

【小明剑魔视频Viggle AI模仿的核心算法组成】

Viggle AI 作为一款先进的生成式视频AI工具&#xff0c;其核心技术栈融合了多项前沿算法。以下是深度解析其核心算法架构及实现原理&#xff1a; 一、核心算法组成 1. 运动控制生成&#xff08;Motion Control Generation&#xff09; 算法框架&#xff1a;基于扩散模型&…...

Linux学习心得问题整理(二)

day05 Linux基础入门 Linux语法解析 如何理解ssh远程连接?如何使用ssh使用远程连接服务&#xff1f; ssh进也称远程服务终端&#xff0c;常见连接方式可以包括windows和Linux两种方式 首先咱们使用windows窗口进行连接&#xff0c;这里就采用xshell连接工具来给大家做演示吧…...

百度网盘加速补丁v7.14.1.6使用指南|PC不限速下载实操教程

软件介绍 本加速补丁可突破百度网盘限速限制&#xff0c;无需会员、无次数限制&#xff0c;实测下载速度可达带宽峰值。 三步极速配置教程 1. 环境准备 → 卸载电脑原有百度网盘客户端&#xff08;避免冲突&#xff09; → 关闭杀毒软件/安全卫士&#xff08;防止误删补丁&am…...

RocketMQ消息拉取模式详解

RocketMQ提供了两种消息拉取模式&#xff0c;Pull模式&#xff08;主动拉取&#xff09;和 Push模式&#xff08;长轮询&#xff09;。 一、消息拉取模式分类 1. Pull模式&#xff08;主动拉取&#xff09; 特点&#xff1a;消费者主动向Broker发送请求拉取消息实现类&#…...

C++23 容器从其他兼容范围的可构造性与可赋值性 (P1206R7)

文章目录 背景与动机提案内容与实现细节提案 P1206R7实现细节编译器支持 对开发者的影响提高灵活性简化代码向后兼容性 总结 C23标准引入了对容器构造和赋值的新特性&#xff0c;这些特性使得容器能够更灵活地从其他兼容范围初始化&#xff0c;并支持从范围赋值。这些改进由提案…...

深入解析 HTTP 中的 GET 请求与 POST 请求​

在互联网的世界里&#xff0c;数据的传输与交互无时无刻不在发生。HTTP&#xff08;超文本传输协议&#xff09;作为 Web 应用的基石&#xff0c;承载着浏览器与服务器之间的通信重任。而 GET 请求和 POST 请求&#xff0c;作为 HTTP 协议中最为常用的两种请求方法&#xff0c;…...

华三(H3C)IRF堆叠心跳的LACP MAD、BFD MAD和ARP MAD差异

华三&#xff08;H3C&#xff09;IRF堆叠心跳的三种MAD&#xff08;多主检测&#xff09;机制——LACP MAD、BFD MAD和ARP MAD在实现原理、组网要求及适用场景上存在显著差异。以下是三者的对比分析&#xff1a; 一、核心区别对比 特性LACP MADBFD MADARP MAD检测原理扩展LAC…...

thread 的mutex优化

std::mutex mtx; int shared_data 0;void increment() {std::lock_guard<std::mutex> lock(mtx); // 自动加锁shared_data; // 临界区 } // 离开作用域时自动解锁std::lock_guard 在离开作用域时自动解锁的行为是基于 C 的 RAII (Resource Acquisition Is Initializa…...

深入解析前端 JSBridge:现代混合开发的通信基石与架构艺术

引言&#xff1a;被低估的通信革命 在移动互联网爆发式增长的十年间&#xff0c;Hybrid App&#xff08;混合应用&#xff09;始终占据着不可替代的地位。作为连接 Web 与 Native 的神经中枢&#xff0c;JSBridge 的设计质量直接决定了应用的性能上限与开发效率。本文将突破传…...

打破次元壁,VR 气象站开启气象学习新姿势​

在教育领域&#xff0c;VR 气象站同样发挥着巨大的作用&#xff0c;为气象教学带来了全新的模式&#xff0c;打破了传统教学的次元壁&#xff0c;让学生们以全新的姿势学习气象知识。​ 在传统的气象教学中&#xff0c;学生们主要通过课本、图片和老师的讲解来学习气象知识。这…...

python八股文汇总(持续更新版)

python装饰器 一、装饰器是什么&#xff1f; 装饰器是Python中一种"化妆师"&#xff0c;它能在不修改原函数代码的前提下&#xff0c;给函数动态添加新功能。 本质&#xff1a;一个接收函数作为参数&#xff0c;并返回新函数的工具。作用&#xff1a;像给手机贴膜…...

C#入门系列【基础类型大冒险】从0到1,解锁编程世界的“元素周期表”

C#入门系列【基础类型大冒险】从0到1&#xff0c;解锁编程世界的“元素周期表” 嘿&#xff0c;欢迎来到C#的奇妙世界&#xff01;如果把编程比作建造一座大厦&#xff0c;那么基础类型就是我们手中的“砖块”和“水泥”。它们看似普通&#xff0c;却构成了所有复杂程序的基石…...