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

基于 Redis 实现一套动态配置中心 DCC 服务与反射基础知识讲解

目录

动态配置中心核心价值

轻量级 Redis 方案与 ZooKeeper 的对比分析

为什么选择自定义 Redis 方案?

1. 技术决策背景

一、活动降级拦截

1. 定义与作用

2. 实现原理

二、活动切量拦截

1. 定义与作用

2. 实现原理

三、两者的核心区别

四、实际应用案例

1. 电商大促场景

2. 金融风控场景

五、技术实现依赖

总结

具体实现

代码核心功能总结

1. 动态配置注入

2. 配置实时更新

3. 业务场景应用

核心原理详解

1. 动态配置存储与读取

2. 实时更新机制

3. 关键技术点

还可以进行的优化

 潜在风险

总结

补充一些关于反射的知识点

1. 概念定义

2. 核心类与操作

3. 核心操作示例

(1) 获取Class对象

(2) 反射操作私有字段

(3) 反射调用方法

4. 应用场景

5. 优缺点对比

6. 优化与避坑指南

7. 高频面试题

总结

学习反射之后再看上面实现的功能

反射相关知识点解释

1. 获取目标 Bean 的类和对象

2. 遍历字段并处理@DCCValue注解

3. Class targetBeanClass = bean.getClass(); 和 Object targetBeanObject = bean; 的作用

4.dccRedisTopicListener 方法

5.postProcessAfterInitialization 方法

总结


欢迎关注我的博客!26届java选手,一起加油💘💦👨‍🎓😄😂

动态配置中心核心价值

动态配置中心是微服务架构中实现「配置热更新」的核心组件,其核心价值在于无需重启服务即可实时调整系统参数。这种能力在灰度发布、流量切换、紧急熔断等场景中至关重要。根据技术选型差异,业界常见方案可分为基于专用中间件(如 ZooKeeper/Nacos)基于通用组件(如 Redis/DB)的自定义方案两类。

轻量级 Redis 方案与 ZooKeeper 的对比分析

维度自定义 Redis 方案ZooKeeper 原生方案技术选型建议
一致性模型最终一致性(依赖 Redis 主从同步)强一致性(ZAB 协议保证)金融/交易类系统选 ZooKeeper
实时性依赖 Pub/Sub 机制,毫秒级延迟Watch 通知机制,通常亚秒级响应实时性要求极高时选 ZooKeeper
运维复杂度无需新增组件,复用现有 Redis 集群需独立部署集群,维护成本较高中小团队优先选 Redis 方案
功能完备性需自行实现版本管理、权限控制等原生支持 ACL、节点历史版本追踪复杂企业级场景选 ZooKeeper
性能影响高频读写可能影响 Redis 主业务写性能受集群规模限制(Raft 协议特性)读多写少场景 ZooKeeper 更优
容灾能力依赖 Redis 集群的持久化和备份策略多副本机制天然支持数据灾备数据安全性要求高时选 ZooKeeper

为什么选择自定义 Redis 方案?

1. 技术决策背景

  • 已有 Redis 基础设施:复用存储组件,避免引入 ZooKeeper 的运维负担 
  • 快速迭代需求:通过注解+反射实现配置注入,开发效率高
  • 中小规模集群:Redis 单机吞吐量可达 10W QPS,满足常规需求

最近在学习使用动态配置中心实现热更新项目中的配置:以活动降级拦截和活动切量拦截举例

一、活动降级拦截

1. 定义与作用
  • 定义:当系统检测到异常(如服务器压力过大、依赖服务故障)时,主动关闭非核心业务功能,仅保留核心服务运行。
  • 代码示例:通过 repository.downgradeSwitch() 判断是否触发降级,若开启则抛出异常阻止用户参与活动。
2. 实现原理
  • 动态配置:通过配置中心(如 Redis/ZooKeeper)实时修改降级开关状态,无需重启服务。

二、活动切量拦截

1. 定义与作用
  • 定义:通过特定规则(如用户ID哈希、设备类型)将流量分配到不同策略组,实现灰度发布、A/B测试或风险控制。
  • 用户代码示例:通过 repository.cutRange(userId) 判断用户是否命中灰度范围,若未命中则拦截请求。
  • 典型场景:新功能上线时仅对10%用户开放,验证功能稳定性
2. 实现原理
  • 流量分割:基于用户特征(如ID取模)或业务标签划分流量,例如:

三、两者的核心区别

维度降级拦截切量拦截
目标保护系统稳定性,避免崩溃控制功能覆盖范围,降低风险
触发条件系统异常(如高负载、依赖故障)预设规则(如用户特征、流量比例)
业务影响完全关闭功能,用户感知明显部分用户受限,整体功能仍可用
技术实现全局开关 + 兜底逻辑流量分桶 + 动态规则

四、实际应用案例

1. 电商大促场景
  • 降级:若库存服务故障,降级拦截下单功能,展示“稍后再试”提示。
2. 金融风控场景
  • 降级:支付通道异常时,关闭快捷支付,引导使用银行卡支付。

五、技术实现依赖

  1. 动态配置中心:如 Redis/ZooKeeper 管理开关和规则,支持实时生效 
  2. 流量标识:通过用户ID、设备指纹等特征实现精准切量。
  3. 监控告警:结合 Prometheus/Grafana 监控降级和切量状态,及时人工干预。

总结

降级拦截是系统异常的“紧急刹车”,切量拦截是可控的“流量导航”。两者结合可构建多层次的容错体系,在保障用户体验的同时降低运维风险。实际开发中需根据业务需求选择合适的触发阈值和策略

具体实现

定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
public @interface DCCValue {String value() default "";}

代码核心功能总结

实现了一个轻量级动态配置中心(DCC),核心功能是通过Redis实时更新应用配置,无需重启服务。具体功能如下:

1. 动态配置注入
  • 注解标记配置字段 使用@DCCValue("key:default")标记需要动态管理的字段,如降级开关、切量比例:

    @DCCValue("downgradeSwitch:0") 
    // 降级开关,默认关闭 private String downgradeSwitch;
  • 启动时初始化配置 DCCValueBeanFactory在Spring Bean初始化后,从Redis读取配置值(若无则写入默认值),并通过反射注入字段:

    // 示例:若Redis无downgradeSwitch,则设置默认值0 
    field.set(bean, "0");
2. 配置实时更新
  • 发布/订阅机制 通过Redis的group_buy_market_dcc主题监听配置变更消息(如downgradeSwitch,1):

    dccTopic.publish(key + "," + value); // 发布配置变更
  • 动态刷新字段值 监听器收到消息后,更新Redis中的值,并通过反射修改Bean字段值,实现实时生效

    field.set(objBean, "1"); // 将降级开关更新为开启
3. 业务场景应用
  • 降级开关 isDowngradeSwitch()方法根据配置值决定是否开启降级策略(如返回兜底数据)。
  • 切量控制 isCutRange(userId)通过用户ID哈希值决定是否命中灰度发布范围。
  • 渠道拦截 isSCBlackIntercept(source, channel)检查黑名单配置,拦截指定渠道请求。

核心原理详解

1. 动态配置存储与读取
  • 存储结构 每个配置项在Redis中对应一个键(group_buy_market_dcc_downgradeSwitch),值为字符串:

    SET group_buy_market_dcc_downgradeSwitch "0"
  • 初始化流程

    • 应用启动时,BeanPostProcessor扫描所有Bean的@DCCValue字段。
    • 若Redis中不存在配置键,写入默认值(如downgradeSwitch:0)。
    • 将配置值通过反射注入字段,完成初始化。
2. 实时更新机制
  • 消息格式 配置变更消息格式为属性名,新值(如downgradeSwitch,1

  • 更新流程

    1. 调用updateConfig接口发布消息。
    2. Redis通知所有订阅该主题的服务实例。
    3. 服务实例收到消息后,更新Redis中的值并修改Bean字段。
3. 关键技术点
  • Spring扩展机制(BeanPostProcessor) 在Bean初始化后拦截,通过反射修改字段值,实现配置注入。

  • AOP代理处理 使用AopUtils识别并获取代理对象的原始类,避免因AOP增强导致反射失效:

    if (AopUtils.isAopProxy(bean)) { targetBeanClass = AopUtils.getTargetClass(bean); }
  • 反射性能与安全 通过setAccessible(true)突破私有字段访问限制,需注意线程安全问题(如并发修改字段值)。

还可以进行的优化

  • 线程安全 将dccObjGroup改用ConcurrentHashMap,避免多线程并发修改问题。
  • 配置版本管理 增加配置版本号,支持回滚和历史记录查询。
  • 异常降级 Redis不可用时,降级为本地缓存或默认值。

 潜在风险

  • 反射滥用 频繁反射修改字段可能影响性能,建议限制动态字段范围。
  • 配置覆盖 多服务实例同时更新配置时,需考虑分布式锁避免竞态条件。

总结

通过注解驱动+Redis发布订阅,实现了配置的实时动态管理,具备以下优势:

  1. 无侵入:通过注解标记配置字段,不改动业务代码。
  2. 实时生效:配置变更秒级同步到所有服务实例。
  3. 轻量灵活:无需引入ZooKeeper/Nacos等重型组件,适合中小项目。

适用场景:灰度发布、功能开关、参数热调整等需动态控制的业务场景。

@Bean("dccTopic")
public RTopic dccRedisTopicListener(RedissonClient redissonClient) {// 1. 创建Redis主题监听器:订阅名为"group_buy_market_dcc"的频道RTopic topic = redissonClient.getTopic("group_buy_market_dcc");// 2. 添加消息监听器(监听String类型消息)topic.addListener(String.class, (charSequence, s) -> {// 3. 拆分消息内容(格式:属性名,新值)String[] split = s.split(Constants.SPLIT); // 假设SPLIT为","String attribute = split[0]; // 属性名(如downgradeSwitch)String key = BASE_CONFIG_PATH + attribute; // 构造Redis键(group_buy_market_dcc_属性名)String value = split[1]; // 新值(如1)// 4. 更新Redis中的配置值RBucket<String> bucket = redissonClient.getBucket(key);if (!bucket.isExists()) return; // 若键不存在则忽略(防误操作)bucket.set(value); // 写入新值// 5. 获取关联的Bean对象(从内存缓存dccObjGroup中查找)Object objBean = dccObjGroup.get(key);if (objBean == null) return;// 6. 处理AOP代理对象(获取原始类)Class<?> objBeanClass = objBean.getClass();if (AopUtils.isAopProxy(objBean)) {objBeanClass = AopUtils.getTargetClass(objBean); // 获取目标类}// 7. 反射更新字段值try {Field field = objBeanClass.getDeclaredField(attribute); // 获取字段field.setAccessible(true); // 突破私有权限field.set(objBean, value); // 设置新值(如downgradeSwitch=1)field.setAccessible(false);log.info("DCC 节点监听,动态设置值 {} {}", key, value);} catch (Exception e) { ... }});return topic;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {// 1. 处理AOP代理对象(确保获取原始类)Class<?> targetBeanClass = bean.getClass();Object targetBeanObject = bean;if (AopUtils.isAopProxy(bean)) {targetBeanClass = AopUtils.getTargetClass(bean); // 目标类targetBeanObject = AopProxyUtils.getSingletonTarget(bean); // 目标对象}// 2. 遍历Bean的所有字段,寻找@DCCValue注解Field[] fields = targetBeanClass.getDeclaredFields();for (Field field : fields) {if (!field.isAnnotationPresent(DCCValue.class)) continue;// 3. 解析注解值(格式:key:defaultValue)DCCValue dccValue = field.getAnnotation(DCCValue.class);String value = dccValue.value(); // 如"downgradeSwitch:0"String[] splits = value.split(":"); String key = BASE_CONFIG_PATH.concat(splits[0]); // 构造Redis键String defaultValue = splits.length == 2 ? splits[1] : null;// 4. 初始化配置值(优先从Redis读取,无则写入默认值)try {RBucket<String> bucket = redissonClient.getBucket(key);if (!bucket.isExists()) {bucket.set(defaultValue); // 设置默认值到Redis}String setValue = bucket.get() != null ? bucket.get() : defaultValue;// 5. 反射注入字段值field.setAccessible(true);field.set(targetBeanObject, setValue); // 如downgradeSwitch=0field.setAccessible(false);// 6. 缓存对象(用于后续动态更新)dccObjGroup.put(key, targetBeanObject);} catch (Exception e) { ... }}return bean;
}

补充一些关于反射的知识点

1. 概念定义

反射(Reflection) 是Java的运行时自省机制,允许程序在运行时动态获取类的元数据(如字段、方法、构造器),并操作对象的属性或方法,实现灵活的动态编程。

2. 核心类与操作
类名作用常用方法
Class表示类的元数据,是反射的入口forName("全类名")getDeclaredFields()newInstance()
Field描述类的字段(成员变量)get(Object obj)set(Object obj, Object value)setAccessible(true)
Method描述类的方法invoke(Object obj, Object... args)
Constructor描述类的构造器,用于实例化对象newInstance(Object... args)
3. 核心操作示例
(1) 获取Class对象

Java

// 方式1:通过对象获取 
Class<?> clazz = obj.getClass(); 
// 方式2:通过类名.
class Class<?> clazz = String.class; 
// 方式3:通过全类名加载(需处理异常) 
Class<?> clazz = Class.forName("java.lang.String");
(2) 反射操作私有字段
Field field = clazz.getDeclaredField("privateField"); 
field.setAccessible(true);// 突破私有权限 
field.set(obj, "newValue"); // 修改值
(3) 反射调用方法
Method method = clazz.getDeclaredMethod("methodName", int.class);Object result = method.invoke(obj, 123);
4. 应用场景
  1. 框架开发
    • Spring依赖注入:通过反射创建Bean并注入属性。
    • MyBatis结果映射:反射将SQL结果映射到Java对象字段。
  2. 动态代理
    • 结合Proxy类生成接口代理,AOP切面拦截方法调用。
  3. 插件化系统
    • 动态加载外部JAR包,反射实例化插件类并调用功能。
  4. 配置化编程
    • 根据配置文件(如className=com.example.ServiceImpl)反射创建对象。
5. 优缺点对比
优点缺点
灵活性高:运行时动态处理任意类性能差:反射调用比直接操作慢约10-100倍
扩展性强:支撑框架底层实现(如Spring)破坏封装:可访问私有字段,降低安全性
通用性佳:编写通用工具类(如JSON解析)维护困难:代码可读性差,调试复杂
6. 优化与避坑指南
  1. 性能优化
    • 缓存Class对象:避免重复调用Class.forName()
    • 减少反射调用:高频操作改用字节码工具(如ASM)或LambdaMetafactory。
  2. 安全控制
    • 安全管理器:通过SecurityManager限制反射访问敏感字段。
  3. 替代方案
    • MethodHandle:Java 7+ 提供更高效的动态方法调用。
    • 字节码增强:使用CGLIB、Javassist生成代理类。
7. 高频面试题
  1. 反射能修改final字段吗?
    • :通过field.setAccessible(true)后强制修改(但可能导致不可预期行为)。
  2. 反射如何破坏单例模式?
    • 反射调用私有构造器创建新实例,需通过枚举或构造器抛出异常防御。
  3. 反射的典型应用?
    • 框架(Spring)、序列化工具(Jackson)、单元测试(Mockito)。

总结

反射是Java动态能力的核心,用好了是神器,用错了是灾难

学习反射之后再看上面实现的功能

定义了一个名为DCCValueBeanFactory的配置类,它实现了BeanPostProcessor接口。其主要功能是在 Spring Bean 初始化之后,处理带有@DCCValue注解的字段,并从 Redis 中获取或设置这些字段的值。同时,它还监听 Redis 的一个主题,当主题接收到消息时,动态更新对应的 Bean 字段值。

反射相关知识点解释

1. 获取目标 Bean 的类和对象
Class<?> targetBeanClass = bean.getClass();
Object targetBeanObject = bean;
if (AopUtils.isAopProxy(bean)) {targetBeanClass = AopUtils.getTargetClass(bean);targetBeanObject = AopProxyUtils.getSingletonTarget(bean);
}
  • 为什么要这样做:在 Spring 中,为了实现 AOP(面向切面编程),会对 Bean 进行代理。代理对象和原始对象的类结构是不同的,如果直接使用bean.getClass()获取类信息,可能会得到代理类而不是原始类。使用AopUtils.isAopProxy(bean)判断当前 Bean 是否为代理对象,如果是,则使用AopUtils.getTargetClass(bean)获取原始类,使用AopProxyUtils.getSingletonTarget(bean)获取原始对象。这样做的目的是为了能够正确获取到原始类的注解和字段信息。
2. 遍历字段并处理@DCCValue注解
Field[] fields = targetBeanClass.getDeclaredFields();
for (Field field : fields) {if (!field.isAnnotationPresent(DCCValue.class)) {continue;}// 处理带有 @DCCValue 注解的字段// ...
}
  • 有和没有for循环的区别
    • for循环:会遍历目标 Bean 类的所有声明字段,检查每个字段是否带有@DCCValue注解。如果有,则进行相应的处理,如从 Redis 中获取或设置字段的值。
    • 没有for循环:就无法遍历所有字段,也就不能处理带有@DCCValue注解的字段,代码的核心功能就无法实现。
3. Class<?> targetBeanClass = bean.getClass(); 和 Object targetBeanObject = bean; 的作用
  • Class<?> targetBeanClass = bean.getClass();获取当前 Bean 对象的类信息。类信息包含了类的所有元数据,如字段、方法、注解等。在后续的反射操作中,需要使用类信息来获取字段和设置字段的值。
  • Object targetBeanObject = bean;:将当前 Bean 对象赋值给targetBeanObject,以便在后续的反射操作中使用。通过反射设置字段的值时,需要一个具体的对象实例作为目标。
4.dccRedisTopicListener 方法

该方法创建了一个 Redis 主题监听器,监听名为group_buy_market_dcc的主题。当接收到消息时,会解析消息内容,更新 Redis 中的值,并使用反射动态更新 Bean 对象的字段值。

5.postProcessAfterInitialization 方法

该方法是BeanPostProcessor接口的实现方法,会在每个 Bean 初始化之后调用。它会遍历 Bean 对象的所有字段,处理带有@DCCValue注解的字段。从 Redis 中获取或设置字段的值,并将 Bean 对象和对应的 Redis 键存储在dccObjGroup中,以便后续动态更新。

总结

使用反射机制实现了在 Spring Bean 初始化之后动态设置字段值的功能,并通过 Redis 主题监听实现了字段值的动态更新。反射机制允许在运行时获取和操作类的元数据和对象的字段,从而实现了代码的灵活性和可扩展性。

相关文章:

基于 Redis 实现一套动态配置中心 DCC 服务与反射基础知识讲解

目录 动态配置中心核心价值 轻量级 Redis 方案与 ZooKeeper 的对比分析 为什么选择自定义 Redis 方案&#xff1f; 1. 技术决策背景 一、活动降级拦截 1. 定义与作用 2. 实现原理 二、活动切量拦截 1. 定义与作用 2. 实现原理 三、两者的核心区别 四、实际应用案例 1. 电商大促…...

vue 前端遇到问题 样式不展示

vue 前端遇到问题 样式不展示 先看接口返回有数据没 如果有数据看下 是不是 输入赋值给其他 字段 没有赋值上导致报错 所以页面没展示数据...

基于 Spring Boot + Vue 的 [业务场景] 管理系统设计与实现

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

2025蓝桥杯JavaB组

说明 博主自己水平有限&#xff0c;而且答案也不一定对&#xff0c;下面代码和思路仅作分享。我只把我考场上做了的写出来了&#xff0c;有什么问题欢迎评论区交流。 A&#xff1a;逃离高塔 思路&#xff1a; 由于有了去年的经验&#xff0c;所以一上来我就是找规律&#xf…...

HDF5文件格式:数据类型与读写功能详解

HDF5文件格式&#xff1a;数据类型与读写功能详解 HDF5简介 HDF5&#xff08;Hierarchical Data Format version 5&#xff09;是一种用于存储和管理大量科学数据的文件格式和库。它由美国国家高级计算应用中心&#xff08;NCSA&#xff09;开发&#xff0c;具有以下特点&…...

探索 Python 的 functools 模块:缓存、属性缓存与 LRU 缓存

李升伟 编译 Python 的 functools 模块是函数式编程爱好者的宝库&#xff0c;提供了许多工具来提升代码的效率和优雅性。本文将深入探讨三个强大的函数——cache、cached_property 和 lru_cache&#xff0c;它们通过存储昂贵计算的结果来优化性能。无论是加速递归算法还是简化…...

缓存与数据库一致性:从问题到解决方案全解析

一、⼀致性问题的由来&#xff1a;为什么会不一致&#xff1f; 我们先从现实例子出发&#xff0c;来看为什么会出现一致性问题&#xff1a; &#x1f4e6; 场景举例&#xff1a;电商下单业务 用户提交订单 → 服务写入数据库订单表&#xff1b;同时更新缓存&#xff08;比如用…...

【android bluetooth 框架分析 02】【Module详解 2】【gd_shim_module 模块介绍】

1. 背景 上一章节 我们介绍了 module_t 的 大体框架 &#xff0c;本节内容我们就选择 我们的 gd_shim_module 模块为例子&#xff0c;具体剖析一下&#xff0c;它里面的逻辑。 static const char GD_SHIM_MODULE[] "gd_shim_module";// system/main/shim/shim.cc …...

dbt:新一代数据转换工具

dbt&#xff08;Data Build Tool&#xff09;一款专为数据分析和工程师设计的开源工具&#xff0c;专注于 ETL/ELT 流程的数据转换&#xff08;Transform&#xff09;环节&#xff0c;帮助用户以高效、可维护的方式将原始数据转换为适合分析的数据模型。 用户只需要编写查询&am…...

Linux-内核驱动-makemenu,make modules,make uImage,杂项

动态生成设备节点设备号...

linux 内存踩踏导致的空指针问题分析纪要

1&#xff0c;查看日志信息打印 我们看到日志发现发包的skb模块有NULL pointer情况&#xff0c;我们看代码分析skb指针不可能出现是空指针&#xff0c;这个时候我们怀疑可能是出现了踩内存导致的空指针情况&#xff0c;所以我们首先需要找到系统PANIC的条件&#xff0c;也就是…...

【C++】 —— 笔试刷题day_14

一、乒乓球筐 题目解析 题目输入两个字符串A和B&#xff0c;分别代表A和B中的乒乓球&#xff0c;不同的大写字母就表示不同的乒乓球&#xff1b; 如果判断B中的所有乒乓球在A中都有&#xff0c;且A中每种乒乓球的数量大于等于B中的。&#xff08;简单来说就是B是A的子集&#…...

在WPS中通过JavaScript宏(JSA)调用DeepSeek官方API自动识别标题级别和目录

我们希望通过AI&#xff0c;能够自动识别像“一”、“&#xff08;一&#xff09;”、“1”、“&#xff08;1&#xff09;” 这类常见标题序号。做一个规则&#xff0c;如果存在“一”时&#xff0c;则“一”、“&#xff08;一&#xff09;”、“1”分别识别为H1、H2、H3&…...

修复 WPS 编译错误:缺少:Sub或Function 且出现两个MathType加载项

问题首次出现于2025.4.12。 同时使用了Word和WPS&#xff0c;在里面都使用了MathType&#xff0c;在Microsoft的Word中&#xff0c;加载项能正常加载且显示&#xff0c;这也是我们要的效果。 而在WPS中&#xff0c;却出现了两个MathType&#xff0c;且在启动时会弹窗报错&…...

HTTP协议

目录 1 Fiddler工具 2 HTTP协议 2.1 HTTP请求和响应格式 2.2 URL 2.3 方法method 2.3.1 GET 2.3.2 POST 2.4 请求报头Header 2.5 请求正文body 2.6 http响应状态码 2.7 响应报头header HTTP协议是应用层的协议&#xff0c;基于传输层的TCP协议来传输&#xff0c;数据…...

拓扑排序 —— 2. 力扣刷题207. 课程表

题目链接&#xff1a;https://leetcode.cn/problems/course-schedule/description/ 题目难度&#xff1a;中等 相关标签&#xff1a;拓扑排序 / 广度优先搜搜 BFS / 深度优先搜索 DFS 2.1 问题与分析 2.1.1 原题截图 2.1.2 题目分析 首先&#xff0c;理解题目后必须马上意识到…...

寻找峰值 --- 二分查找

目录 一&#xff1a;题目 二&#xff1a;算法原理 三&#xff1a;代码实现 一&#xff1a;题目 题目链接&#xff1a;162. 寻找峰值 - 力扣&#xff08;LeetCode&#xff09; 二&#xff1a;算法原理 三&#xff1a;代码实现 class Solution { public:int findPeakElemen…...

SAP系统客户可回收包材库存管理

问题&#xff1a;客户可回收包材库存管理 现象&#xff1a;回收瓶无库存管理&#xff0c;在库数量以及在客户的库存数量没有统计&#xff0c;管理混乱。 解决方法&#xff1a; 客户可回收包装材料在SAP有标准的解决方案&#xff0c;在集团尚未启用该业务&#xff0c;首先…...

C++标识符:检查是否和保留字冲突

1. 基础知识 最基本的要求&#xff1a; 字母、数字、下划线组成&#xff0c; 并且不能是数字开头。 禁忌1&#xff1a; C 关键字不能用做标识符。 它们是&#xff1a; alignas alignof asm auto bool break case catch char char16_t char32_t class const constexpr const_…...

【Java多线程】告别线程混乱!深度解析Java多线程4大实现方式(附实战案例)

一、继承Thread类 实现步骤&#xff1a; 1.继承Thread类 2.重写run()方法 3.创建线程对象并调用start()方法 示例&#xff1a; class MyThread extends Thread {Overridepublic void run() {for (int i 0; i < 5; i) {System.out.println(Thread.currentThread().getNam…...

Linux安装yum和python

一、安装yum(CentOS) 查看yum版本 yum --version 如果未安装&#xff0c;执行以下部分&#xff1a; 1. 确保你的系统中已经安装了epel仓库&#xff0c;如果没有安装可以通过以下命令安装&#xff1a; sudo yum install epel-release 2.yum安装 – CentOS/RHEL系统&#…...

【数据结构】HashMap源码 —— 简单介绍

HashMap源码介绍 下面并非完整的源码&#xff0c;主要简单了解其流程。 1. 基本成员变量 哈希桶/开散列&#xff0c;链地址法/开链法是由&#xff1a;数组 链表(单链表) 红黑树&#xff08;当数组长度>64 && 链表长度>8以后&#xff0c;链表变成红黑树&#xf…...

149页研读——华为基于IPD全过程研发质量管理【附全文阅读】

本文介绍了IPD(集成产品开发)的全过程研发质量管理,强调了以客户需求为导向,通过跨部门协同、资源整合、快速响应等方式提高研发效率和成功率。文章详细阐述了IPD研发管理体系的精要,包括其核心思想、优势、框架以及核心理念。 其中,跨领域平台与技术研发、端到端流程与项…...

深入理解 v-for 指令及其使用方法

在 Vue.js 中&#xff0c;v-for 是用于渲染列表的核心指令&#xff0c;它允许你通过循环渲染数据源中的每一项。通过 v-for&#xff0c;你可以轻松地将数组、对象或其他可迭代的数据渲染成 HTML 元素。本文将详细介绍 v-for 的基本用法、常见的应用场景、最佳实践及性能优化&am…...

swift菜鸟教程24-25(可选链,自动引用计数)

一个朴实无华的目录 今日学习内容&#xff1a;1.Swift 可选链1.1定义1.2通过可选链调用方法1.3使用可选链调用下标脚本1.4通过可选链接调用来访问下标1.4访问可选类型的下标 2.Swift 自动引用计数&#xff08;ARC&#xff09;2.1实例之间的循环强引用会造成内存泄露2.2弱引用&a…...

使用 Visual Studio 2022 (VS2022) 编译 FreeCAD 1.0.0 的详细教程

一、环境准备 官方教程&#xff1a;在 Windows 上编译 - FreeCAD Documentation Windows 10/11&#xff08;推荐&#xff09; git vs2022 cmake 3.26.4 Doxygen1.12 二、获取源码与依赖 版本关系 打开Git Bash或CMD&#xff0c;执行以下命令 git clone --recurse-sub…...

机械臂只有位置信息是否可以进行手眼标定?

平常我在做手眼标定时&#xff0c;一般都是通过OpenCV的cv::calibrateHandEye函数进行求解&#xff0c;需要输入多组不同的机械臂位姿。今天遇到了一款舵机机器人&#xff0c;只能获取位置&#xff0c;得不到姿态信息&#xff0c;想着那就把姿态都设为0&#xff0c;结果求不出来…...

Unity入门

文章目录 Unity脚本基础大基础生命周期函数Inspector窗口显示常用特性辅助特性 MnonBehaviour基类成员变量成员方法 组件GameObject成员变量gameObject静态方法成员方法 组件Time静态成员变量 组件TransformVector3结构体基础基本概念常用向量表示常用方法 位置与位移位置posit…...

《汽车制造技术基础》第一次作业

作业内容 查阅相关资料&#xff0c;谈谈对汽车制造技术的发展的理解。 可以是关于汽车的先进制造技术 或 汽车先进制造技术 与 制造理念的发展趋势 或 汽车先进制造技术对环境与可持续发展的影响等。 以下从技术突破、制造理念转型及环境影响三个维度展开对汽车制造技…...

烟花爆竹储存作业安全要求

烟花爆竹储存作业证是从事相关作业的法定凭证&#xff0c;旨在确保操作人员具备专业知识和安全技能&#xff0c;防止因违规操作引发火灾、爆炸等事故。根据《烟花爆竹安全管理条例》及相关法规&#xff0c;未取得作业证的人员不得从事烟花爆竹储存、搬运、管理等作业。 仓库选址…...

Flask+Plotly结合动态加载图形页面实践

1. DeepSeek帮我实践 1.1. 我的提问既设计方案 原有如下主页:dashboard.html,现增加“预测模型学习”,对感知机神经网络描述如下: 1、输入与输出为固定值,例如输入层215,输出层48; 2、模型为回归神经网络; 3、中层是可动态调整的,例如定义如下:第二层,200,第三层…...

leetcode每日一题:统计好整数的数目

题目 给你两个 正 整数 n 和 k 。 如果一个整数 x 满足以下条件&#xff0c;那么它被称为 k 回文 整数 。 x 是一个 回文整数 。 x 能被 k 整除。 如果一个整数的数位重新排列后能得到一个 k 回文整数 &#xff0c;那么我们称这个整数为 好 整数。比方说&#xff0c;k 2 …...

《2025蓝桥杯C++B组:D:产值调整》

**作者的个人gitee**​​ 作者的算法讲解主页▶️ 每日一言&#xff1a;“泪眼问花花不语&#xff0c;乱红飞过秋千去&#x1f338;&#x1f338;” 题目 二.解题策略 本题比较简单&#xff0c;我的思路是写三个函数分别计算黄金白银铜一次新产值&#xff0c;通过k次循环即可获…...

【模块化拆解与多视角信息1】基础信息:隐藏的筛选规则——那些简历上没说出口的暗号

写在最前 作为一个中古程序猿,我有很多自己想做的事情,比如埋头苦干手搓一个低代码数据库设计平台(目前只针对写java的朋友),比如很喜欢帮身边的朋友看看简历,讲讲面试技巧,毕竟工作这么多年,也做到过高管,有很多面人经历,意见还算有用,大家基本都能拿到想要的offe…...

当Browser Use遇见A2A:浏览器自动化与智能体协作的“冰与火之歌“

——一场正在改写数字文明的技术奇遇 第一章 浏览器革命&#xff1a;从"手动挡"到"自动驾驶" 1.1 传统自动化工具的"中年危机" 还记得2023年那个抓狂的凌晨吗&#xff1f;你蹲守演唱会门票时&#xff0c;Selenium脚本因为验证码识别失败第108次…...

Python:开启自动化办公与游戏开发的无限可能

重要的事情放在前面 Python自动化办公和游戏 Python&#xff1a;开启自动化办公与游戏开发的无限可能 在数字化时代的浪潮中&#xff0c;Python以其强大的功能和简洁的语法&#xff0c;成为了众多开发者手中的得力工具&#xff0c;尤其在自动化办公与游戏开发领域&#xff0…...

腾讯后台开发 一面

一、手撕 合并升序链表 合并两个排序的链表_牛客题霸_牛客网 顺时针翻转矩阵 顺时针旋转矩阵_牛客题霸_牛客网 二、八股 1、静态变量和实例变量 public class House {public static String buildDate "2024-10-27"; // 静态变量public String color; // 实…...

基于生成对抗网络(GAN)的手写数字生成实践

基于生成对抗网络&#xff08;GAN&#xff09;的手写数字生成实践 一、图像生成的技术演进 在人工智能领域&#xff0c;图像生成技术经历了从传统算法到深度学习的革命性发展。其中&#xff0c;生成对抗网络&#xff08;Generative Adversarial Networks, GANs&#xff09;作…...

网络互连与互联网

1.在路由表中找不到目标网络时使用默认路由&#xff0c;默认路由通常指本地网关的地址。 2.OSPF最主要的特征是使用分布式链路状态协议&#xff0c;而RIP使用的是距离向量协议。 3.OSPF使用链路状态公告LSA扩散路由信息 4.内部网关路由协议IGRP是一种动态距离矢量路由协议&a…...

大模型常见面试题

大模型常见面试题 大模型相关的面试问题通常涉及模型的原理、应用、优化以及面试者对于该领域的理解和经验。以下是一些常见的 大模型面试问题以及建议的回答方式&#xff1a; 请简述什么是大模型&#xff0c;以及它与传统模型的主要区别是什么&#xff1f; 回答&#xff1a…...

python高级编程一(生成器与高级编程)

@TOC 生成器 生成器使用 通过列表⽣成式,我们可以直接创建⼀个列表。但是,受到内存限制,列表容量肯定是有限的。⽽且,创建⼀个包含100万个元素的列表,不仅占⽤很⼤的存储空间,如果我们仅仅需要访问前⾯⼏个元素,那后⾯绝⼤多数元素占 ⽤的空间都⽩⽩浪费了。所以,如果…...

Linux线程属性与多线程开发:API详解与实战代码解析

Linux 线程的属性 线程池 多线程的创建 线程的属性 引入 我们设想一个场景&#xff0c;使用pthread_detach时&#xff0c;发现线程早就已经结束了&#xff0c;这时候pthread_detach还能正常发挥清理线程的 独有空间 的作用吗&#xff1f; 答案是可以的&#xff0c;但是这难…...

Inkscape安装教程

Inkscape 是一款开源的矢量图形编辑软件&#xff0c;功能强大且免费&#xff0c;适用于 Windows、macOS 和 Linux 系统。以下是在不同操作系统上安装 Inkscape 的详细教程&#xff1a; 一、Windows 系统安装 Inkscape 1. 下载安装包 打开浏览器&#xff0c;访问 Inkscape 官方…...

危化品安全员岗位注意事项有哪些?

危化品安全员肩负着保障危化品生产、储存、运输和使用等环节安全的重要职责&#xff0c;其岗位注意事项涉及多个方面&#xff0c;以下是一些主要内容&#xff1a; 法规标准与制度执行 必须熟悉并严格遵守国家和地方有关危化品安全管理的法律法规、标准规范&#xff0c;如《危险…...

1、从零搭建魔法工坊:React 19 新手村生存指南

一、开篇&#xff1a;新世界的入场券 "你好&#xff0c;年轻的魔法学徒&#xff01;欢迎来到React魔法世界。我是你的向导赫敏韦斯莱&#xff0c;今天我们将用React 19这根全新魔杖&#xff0c;搭建属于你的第一座魔法工坊。" ——以对话形式开场&#xff0c;消除技…...

链表代码实现(C++)

数据结构第三篇 一、几个注意点 1、同时持有头尾结点的引用 双链表一般同时持有头尾结点的引用 因为在工程应用中&#xff0c;通常在容器尾插入元素&#xff0c;双链表持有尾部节点的引用&#xff0c;就可以在O&#xff08;1&#xff09;时间复杂度的情况下在尾部添加元素。…...

【学习笔记】两个类之间的数据交互方式

在面向对象编程中&#xff0c;两个类之间的数据交互可以通过以下几种方式实现&#xff0c;具体选择取决于需求和设计模式&#xff1a; 1. 通过方法调用 一个类通过调用另一个类的公共方法来获取或传递数据。这是最常见的方式&#xff0c;符合封装原则。 class ClassA:def __…...

【Docker基础】深入解析 Docker 存储卷:管理、绑定与实战应用

文章目录 一、什么是存储卷二、为什么需要存储卷三、存储卷分类四、管理卷 Volume方式一&#xff1a;Volume 命令操作方式二&#xff1a;使用 -v 或 --mount 参数指定卷方式三&#xff1a;Dockerfile 匿名卷 五、操作案例Docker 命令创建管理卷Docker -v 创建管理卷Docker 卷生…...

Python生成exe

其中的 -w 参数是 PyInstaller 用于窗口模式&#xff08;Windowed mode&#xff09;&#xff0c;它会关闭命令行窗口的输出&#xff0c;这通常用于 图形界面程序&#xff08;GUI&#xff09;&#xff0c;比如使用 PyQt6, Tkinter, PySide6 等。 所以&#xff1a; 如果你在没有…...

SpringBoot原理

配置优先级 SpringBoot项目当中支持的三类配置文件&#xff1a; 在SpringBoot项目当中&#xff0c;我们要想配置一个属性&#xff0c;可以通过这三种方式当中的任意一种来配置都可以&#xff0c;那么如果项目中同时存在这三种配置文件&#xff0c;且都配置了同一个属性&#x…...