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

学习记录:DAY21

我的开发日志:类路径扫描、DI 容器与动态代理

前言


我失忆了,完全不记得自己早上干了什么。


日程


早上 10 点左右开始,学了一早上,主要是类路径扫描相关的调试。
晚上 8 点了,真不能再摸🐟了。


学习记录


计算机网络:
1. 子网划分与子网掩码


学习内容


省流

  1. 手搓类路径扫描器
  2. 手搓基础 DI 容器
  3. 动态代理

1. 手搓类路径扫描器

1)首先要确定需要扫描的包

String path = packageName.replace('.', '/');

2)然后获取系统类加载器获取路径,并获取该路径下的所有资源

ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Enumeration<URL> resources = classLoader.getResources(path);

注意:系统类加载器 (ClassLoader.getSystemClassLoader()) 的扫描范围包括所有在 JVM 启动时通过 -classpath-cp 指定的路径(包括 Maven/Gradle 依赖)。

3)遍历所有的资源,通过 resource.getProtocol() 获取 URL 对象的协议类型,获取 URL 对象的类文件

while (resources.hasMoreElements()){URL resource = resources.nextElement();if (resource.getProtocol().equals("file")) {classes.addAll(findClasses(new File(resource.getFile()), packageName, classFilter));}
}

->进入 findClasses 方法

4)获取文件列表,遍历文件和子目录,获取 clazz 对象,并返回 List<Class<?>> classes 列表

File[] files = directory.listFiles();          
for (File file : files) {if (file.isDirectory()) {String subPackage = packageName + "." + file.getName();classes.addAll(findClasses(file, subPackage, classFilter));} else if (file.getName().endsWith(".class")) {String className = packageName + '.' +file.getName().substring(0, file.getName().length() - 6); //获取class全类名Class<?> clazz = Class.forName(className, false, Thread.currentThread().getContextClassLoader()); //根据全类名找到clazz对象(不对类进行初始化)if (classFilter.test(clazz)) { //过滤器检查classes.add(clazz);}}
}
return classes;

5)提供了一个扫描含有对应注解的类

public static List<Class<?>> scanClassesWithAnnotation(String packageName,Class<? extends java.lang.annotation.Annotation> annotation) {return scanClasses(packageName, clazz -> clazz.isAnnotationPresent(annotation));
}

Class<? extends java.lang.annotation.Annotation> 表示接收的 Class 对象是 java.lang.annotation.Annotation 的任意子类。

2. 手搓基础 DI 容器

0)用 map 来储存映射,在创建类对象时进行扫描
// 存储类定义的映射(类名 -> 类对象)
private final Map<String, Class<?>> classRegistry = new HashMap<>();
// 存储单例实例的映射(类名 -> 实例)
private final Map<String, Object> singletonInstances = new HashMap<>();
// 正在创建的Bean记录(用于解决循环依赖)
private final Set<String> beansInCreation = new HashSet<>();
//接口到实现类的映射
private final Map<Class<?>, Class<?>> interfaceToImplementation = new HashMap<>();
// 包扫描路径
private final String basePackage;public ContainerFactory(String basePackage) {this.basePackage = basePackage;scanComponents();initializeInterfaceLinks();initializeSingletons();
}
1)组件扫描
private void scanComponents() {List<Class<?>> componentClasses = ClassPathScanner.scanClassesWithAnnotation(basePackage, KatComponent.class);for (Class<?> clazz : componentClasses) {register(clazz);}
}

-> 进入 register 方法

2)注册组件
public void register(Class<?> clazz) {if (clazz.isAnnotationPresent(KatComponent.class)) {String beanName = getBeanName(clazz);classRegistry.put(beanName, clazz);}
}

// 获取Bean名称

private String getBeanName(Class<?> clazz) {KatComponent component = clazz.getAnnotation(KatComponent.class);return component.value().isEmpty() ? clazz.getSimpleName() : component.value(); //注解没有指定Bean名称时,以类名作为Bean名称
}
3)对单例 Bean 进行初始化
// 初始化所有单例Bean
private void initializeSingletons() {for (Map.Entry<String, Class<?>> entry : classRegistry.entrySet()) {Class<?> clazz = entry.getValue();if (clazz.isAnnotationPresent(KatSingleton.class)) {getBean(clazz); // 触发单例初始化}}
}

->进入 getBean 方法

4)获取 Bean 实例

这里采用了依赖注入接口模式,所以要从接口索引中获取对应的实现类

// 获取Bean实例(接口映射)
@SuppressWarnings("unchecked") //忽略泛型警告
public <T> T getBean(Class<T> interfaceType) {//接口模式Class<?> implementationClass = interfaceToImplementation.get(interfaceType); if (implementationClass == null) {throw new RuntimeException("No implementation found for " + interfaceType);}return (T) getBean(getBeanName(implementationClass), implementationClass);
}

//初始化接口索引

private void initializeInterfaceLinks() {for (Class<?> clazz : classRegistry.values()) {for (Class<?> intf : clazz.getInterfaces()) {if (!interfaceToImplementation.containsKey(intf)) {interfaceToImplementation.put(intf, clazz);}}}
}

–>进入实现类 Bean 创建

@SuppressWarnings("unchecked") //忽略泛型警告
public <T> T getBean(String beanName, Class<T> clazz) {// 检查单例缓存if (singletonInstances.containsKey(beanName)) {return (T) singletonInstances.get(beanName);}// 检查是否已注册if (!classRegistry.containsKey(beanName)) {throw new RuntimeException("Bean not registered: " + beanName);}// 检查循环依赖if (beansInCreation.contains(beanName)) {throw new RuntimeException("Circular dependency detected for bean: " + beanName);}beansInCreation.add(beanName);try {Class<?> targetClass = classRegistry.get(beanName);Object instance = createInstance(targetClass); //创建实例// 如果是单例则缓存if (targetClass.isAnnotationPresent(KatSingleton.class)) {singletonInstances.put(beanName, instance);}return (T) instance;} catch (Exception e) {throw new RuntimeException("Failed to create bean: " + beanName, e);} finally {beansInCreation.remove(beanName);}
}

—>进入 createInstance 方法

5)创建实例
private Object createInstance(Class<?> clazz) throws Exception {// 1. 优先使用@KatAutowired构造器Constructor<?> autowiredCtor = findAutowiredConstructor(clazz);if (autowiredCtor != null) {return createInstanceWithConstructor(autowiredCtor);}// 2. 使用默认无参构造器try {Object instance = clazz.getDeclaredConstructor().newInstance();injectFields(instance);return instance;} catch (NoSuchMethodException e) {throw new RuntimeException("No suitable constructor found for " + clazz.getName());}
}

---->进入 findAutowiredConstructor 方法

// 查找@KatAutowired构造器
private Constructor<?> findAutowiredConstructor(Class<?> clazz) {Constructor<?>[] ctors = clazz.getConstructors();for (Constructor<?> ctor : ctors) {if (ctor.isAnnotationPresent(KatAutowired.class)) {return ctor;}}return null;
}

---->进入 createInstanceWithConstructor 方法

// 使用构造器创建实例
private Object createInstanceWithConstructor(Constructor<?> ctor) throws Exception {Class<?>[] paramTypes = ctor.getParameterTypes(); //获取参数Object[] args = new Object[paramTypes.length];for (int i = 0; i < paramTypes.length; i++) { //添加参数args[i] = getBean(paramTypes[i]);}Object instance = ctor.newInstance(args); //创建实例injectFields(instance); //注入依赖字段return instance;
}

----->进入 injectFields 方法

// 注入字段依赖
private void injectFields(Object instance) throws IllegalAccessException {Class<?> clazz = instance.getClass();//遍历目标类的所有字段(包括私有字段)for (Field field : clazz.getDeclaredFields()) {// 检查字段是否被@KatAutowired注解标注if (field.isAnnotationPresent(KatAutowired.class)) {Object dependency = getBean(field.getType());field.setAccessible(true); //允许访问私有字段field.set(instance, dependency); //注入目标字段}}
}

目前只是一个非常基础的版本,处理不了复杂的依赖关系,整体效率也比较低。
明天考虑兼容动态代理,多路径扫描(通过配置文件加载)。

3. 动态代理

在运行时动态创建代理类和对象,而不是在编译时静态定义。它对于依赖注入后的事务实现以及 AOP 非常重要。

1)原理分析

InvocationHandler 为例
InvocationHandler 是 Java 动态代理机制中的核心接口,它定义了代理对象方法调用的转发逻辑。

public interface InvocationHandler {public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
}
  • proxy:动态生成的代理对象实例
  • method:被调用的方法对象
  • args:方法调用时传入的参数数组

使用示例:

class DebugInvocationHandler implements InvocationHandler {private final Object target;public DebugInvocationHandler(Object target) {this.target = target;}   @Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 方法调用前逻辑System.out.printf("调用方法: %s,参数: %s%n", method.getName(), Arrays.toString(args));// 调用真实对象的方法Object result = method.invoke(target, args);// 方法调用后逻辑System.out.printf("方法 %s 调用完成,结果: %s%n", method.getName(), result);return result;}
}public static void main(String[] args) {RealSubject real = new RealSubject(); //真实的对象//创建一个代理对象Subject proxy = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),new Class[]{Subject.class},new DebugInvocationHandler(real));//代理对象.method() → InvocationHandler.invoke() → 真实对象.method()proxy.request();
}

结语


大脑已经宕机。


相关文章:

学习记录:DAY21

我的开发日志&#xff1a;类路径扫描、DI 容器与动态代理 前言 我失忆了&#xff0c;完全不记得自己早上干了什么。 日程 早上 10 点左右开始&#xff0c;学了一早上&#xff0c;主要是类路径扫描相关的调试。 晚上 8 点了&#xff0c;真不能再摸&#x1f41f;了。 学习记录 计…...

服务器频繁重启日志分析与诊断

从你提供的日志来看&#xff0c;系统确实经历了多次重启。这个日志行显示的是&#xff1a; reboot system boot 6.8.0-58-generic Tue Apr 29 17:54 - 14:26 (20:31)这表示系统在4月29日17:54启动&#xff0c;运行了约20小时31分钟后&#xff0c;于次日14:26结束&#xff08;可…...

阿里云服务迁移实战: 07-其他服务迁移

概述 当完成了服务器、数据库、IP、OSS等迁移后&#xff0c;剩下的就是其他服务了。 短信网关 短信模板只能一个个创建&#xff0c;不能批量操作。但是可以使用以下方式优化操作。 在原账号导出模板列表 概述 当完成了服务器、数据库、IP、OSS等迁移后&#xff0c;剩下的…...

第六章 QT基础:9、Qt中数据库的操作

Qt数据库模块概述与使用详解 软件安装教程&#xff1a;https://subingwen.cn/qt/sql-driver/ 1. 概述 Qt框架中对数据库操作提供了很好的支持&#xff0c;我们可以通过Qt提供的类非常方便地和本地或者远程数据库进行连接。 众所周知&#xff0c;数据库是 C-S&#xff08;cl…...

DINOv2 - 无监督学习鲁棒视觉特征

本文翻译整理自&#xff1a;https://github.com/facebookresearch/dinov2 文章目录 一、关于 DINOv2相关链接资源关键功能特性 二、预训练模型预训练骨架网络通过 PyTorch Hub 加载预训练模型预训练分类头 - ImageNet预训练头 - 深度估计预训练头 - 语义分割 三、安装1、推荐安…...

AI与无人零售:如何通过智能化技术提升消费者体验和运营效率?

引言&#xff1a;无人零售不只是无人值守 你走进一家无人便利店&#xff0c;没有迎宾、没有收银员&#xff0c;甚至没有一个人在场&#xff0c;但你刚拿起商品&#xff0c;货架旁的摄像头就悄悄“看懂”了你的动作&#xff0c;系统已经在后台为你记账。你以为只是没人管&#x…...

STM32F10X OLED屏幕点亮

本节实现点亮OLED屏 首先去原理图中查找对应引脚 配置上述的IO口 查看对应的原理图 ​​​​​​​ OLED_CS 和 OLED_RES&#xff08;PB6&#xff0c;PB7&#xff09;就是配置为推挽输出OLED_SCLK 和 OLED_SDIN &#xff08;PB13 PB15&#xff09;OLED_D/C (PE12) 推挽输出就…...

Nginx核心功能02

目录 一&#xff1a;正向代理 1.编译安装nginx 2.配置正向代理 二&#xff1a;反向代理 1.配置nginx七层代理 2.配置nginx四层代理&#xff08;传输层&#xff0c;TCP/UDP&#xff09; 三&#xff1a;nginx缓存 1.缓存功能的核心原理和缓存类型 2.代理缓存功能设置 四…...

微格式:为Web内容赋予语义的力量

一、什么是微格式? 微格式是一种建立在已有 Web 标准基础上的简单、开放的数据格式。它的核心思想是通过在 HTML 标签中添加特定的属性和类名,为网页内容添加语义注解,从而兼顾 HTML 文档的人机可读性。 简单来说,微格式就是一套约定俗成的 HTML 标记方式,让我们能够在不…...

Linux基础 -- Generic Netlink 框架详解与开发实践

Generic Netlink 框架详解与开发实践 本文旨在系统性介绍 Linux 内核中的 Generic Netlink 框架&#xff0c;包括其设计背景、结构设计、核心数据结构 genl_ops 的使用&#xff0c;以及完整的内核与用户态通信示例&#xff0c;适合用于驱动开发、用户空间控制接口构建及系统通信…...

CMake解析参数用法示例

cmake_parse_arguments 是 CMake 中用于解析函数或宏参数的工具&#xff0c;特别适合处理带有选项&#xff08;OPTIONS&#xff09;、单值参数&#xff08;SINGLE_ARGS&#xff09;和多值参数&#xff08;MULTI_ARGS&#xff09;的复杂参数列表。以下是用法说明和一个示例&…...

开源项目实战学习之YOLO11:ultralytics-cfg-models-fastsam(九)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 1. __init__.py2. model.py3. predict.py4. utils.py5. val.py FastSAM 是一种目标检测和图像分割模型&#xff0c;Ultralytics 是一个在计算机视觉领域广泛使用的库&#x…...

使用frpc链接内网的mysql

以下是配置 frpc 连接内网 MySQL 服务的详细步骤&#xff1a; 1. 准备工作 frps 服务器&#xff1a;已部署在公网 IP 11.117.11.245&#xff0c;假设 frps 的默认端口为 7000。 内网 MySQL 服务&#xff1a;运行在内网机器的 3306 端口。 目标&#xff1a;通过公网 IP 11.117…...

分享:VTK版本的选择 - WPF空域问题

在早期版本中&#xff0c;ActiViz 对 Windows Presentation Foundation (WPF) 框架的支持是通过 WindowsFormHost 组件实现的&#xff0c;这种方式依赖于 WindowsForm 和 WPF 的互操作性。然而&#xff0c;这种方法存在一个众所周知的“空域问题”&#xff08;airspace issue&a…...

MIPS架构详解:定义、应用与其他架构对比

一、MIPS架构的定义 MIPS&#xff08;Microprocessor without Interlocked Pipeline Stages&#xff09; 是一种经典的精简指令集&#xff08;RISC&#xff09;处理器架构&#xff0c;由斯坦福大学John Hennessy团队于1981年提出&#xff0c;强调高效流水线设计和硬件简化。 核…...

项目剖析:基于Agent的个人知识管理系统如何设计

为什么写这篇文章?最近在思考如果想要构建一个个人知识管理的Agent应该怎样设计才好,然后最近看到这样一个项目,就想剖析一下它的架构,看一下它的设计思想。然后一些剖析得过程就沉淀到本文当中。本文档主要从整体架构、dataflow的视角剖析khoj项目,分析应该一个知识管理A…...

Python魔法函数深度解析

一、魔法函数是什么&#xff1f; 魔法函数&#xff08;Magic Methods&#xff09;是Python中以双下划线&#xff08;__xx__&#xff09;包裹的特殊方法&#xff0c;它们为类提供了一种与Python内置语法深度集成的能力。这些方法由解释器自动调用&#xff0c;无需显式调用&…...

PCB设计工艺规范(一)概述

PCB设计工艺规范&#xff08;一&#xff09; 1.概述2.关键词及引用标准3.PCB板材要求3.1 确定PCB使用板材以及TG值3.2 确定 PCB 的表面处理镀层 4.热设计要求5.器件库选项要求 资料来自网络&#xff0c;仅供学习使用。 1.概述 规范产品的 PCB 工艺设计&#xff0c;规定 PCB 工…...

Github开通第三方平台OAuth登录及Java对接步骤

调研起因&#xff1a; 准备搞AI Agent海外项目&#xff0c;有相当一部分用户群体是程序员&#xff0c;所以当然要接入Github这个全球最大的同性交友网站了&#xff0c;让用户使用Github账号一键完成注册或登录。 本教程基于Web H5界面进行对接&#xff0c;同时也提供了spring-…...

DeepSeek V1:初代模型的架构与性能

DeepSeek V1(又称DeepSeek-MoE)是DeepSeek系列的首代大规模语言模型,它采用Transformer结合稀疏混合专家(MoE)的创新架构,实现了在受控算力下的大容量模型。本文将深入解析DeepSeek V1的架构设计与技术细节,包括其关键机制、训练优化策略,以及在各类NLP任务上的表现。 …...

Java ResourceBundle 资源绑定详解

Java ResourceBundle 资源绑定详解 ResourceBundle 是 Java 提供的国际化(i18n)资源管理工具,位于 java.util 包。它专门用于加载本地化的 .properties 资源文件,支持多语言切换,是国际化和本地化开发的核心类。 1. 核心特性 (1)基本特点 基于 .properties 文件管理键…...

flutter 专题 六十一 支持上拉加载更多的自定义横向滑动表格

在股票软件中&#xff0c;经常会看到如下所示的效果&#xff08;ps&#xff1a;由于公司数据敏感&#xff0c;所以使用另一个朋友的一个图&#xff09;。 分析需要后&#xff0c;我先在网上找了下支持横向滑动的组件&#xff0c;最后找到了这个&#xff1a;flutter_horizontal…...

暗夜模式续

之前写过一篇笨拙的方式实现暗夜模式&#xff0c;但是当真正去适配的时候发现简直恶心至极&#xff1b;然后想通过一些方式可以把笨拙的方式变得优雅&#xff1b; 之前实现暗夜模式的快速通道&#xff0c;这篇文章在基于这个基础上优化而来 目录 背景 优化步骤 OK&#xf…...

[吾爱出品] 文件夹迁移工具(DirMapper)

文件夹迁移工具&#xff08;DirMapper&#xff09; 链接&#xff1a;https://pan.xunlei.com/s/VOP4Uf6vu3dalYLaZ1iZUhJ1A1?pwdfhzi# 文件夹迁移工具&#xff08;DirMapper&#xff09; 智能识别源文件夹分类 复制/移动两种迁移模式 冲突解决方案&#xff08;覆盖/跳过/合…...

DeepSeek 4月30日发布新模型:DeepSeek-Prover-V2-671B 可进一步降低数学AI应用门槛,推动教育、科研领域的智能化升级

DeepSeek-Prover-V2-671B模型特点&#xff1a; 一、超大参数规模与数学推理能力 参数规模跃升 模型参数量高达6710亿&#xff0c;是前代数学推理模型Prover-V1.5&#xff08;70亿参数&#xff09;的近100倍&#xff0c;表明其具备更强的复杂问题处理能力。 前代Prover-V1.5在高…...

GitHub修炼法则:第一次提交代码教学(Liunx系统)

前言 github是广大程序员们必须要掌握的一个技能&#xff0c;万事开头难&#xff0c;如果成功提交了第一次代码&#xff0c;那么后来就会简单很多。网上的相关资料往往都不是从第一次开始&#xff0c;导致很多新手们会在过程中遇到很多权限认证相关的问题&#xff0c;进而被卡…...

百家号等新媒体私信入口是否可以聚合到企业微信的客服,如何实现

一、技术实现路径 1. 百家号 API 对接 接口权限申请&#xff1a; 登录百度开发者平台&#xff0c;创建应用并获取 API 密钥&#xff08;app_id和app_token&#xff09;。申请私信相关接口权限&#xff08;如消息通知、粉丝查询&#xff09;&#xff0c;需满足百家号的审核要求…...

【来自AI】RS485,Rs232,Modbus的区别和联系是什么

RS485、RS232 和 Modbus 是常用于工业自动化和通信中的技术标准&#xff0c;它们有不同的特点和应用。下面是它们的区别和联系&#xff1a; RS232 (Recommended Standard 232) 定义&#xff1a;RS232 是一种串行通信标准&#xff0c;通常用于短距离&#xff08;一般最多15米&…...

java实现序列化与反序列化

va 实现序列化与反序列化 序列化&#xff08;Serialization&#xff09; 是将 Java 对象转换为字节流&#xff08;二进制数据&#xff09;&#xff0c;以便存储或网络传输。 反序列化&#xff08;Deserialization&#xff09; 则是将字节流恢复为 Java 对象。 Java 提供了 ja…...

harmonyOS 手机,双折叠,平板,PC端屏幕适配

由于HarmonyOS设备的屏幕尺寸和分辨率各不相同&#xff0c;开发者需要采取适当的措施来适配不同的屏幕。 1.EntryAbility.ets文件里&#xff1a;onWindowStageCreate方法里判断设备类型&#xff0c; 如果是pad&#xff0c;需全屏展示&#xff08;按客户需求来&#xff0c;本次…...

Qt Creator环境编译的Release软件放在其他电脑上使用方法

本文解决的问题&#xff1a;将Qt Creator环境编译的exe可执行程序放到其他电脑上不可用情况 1、寻找windeployqt工具所在路径" D:\Qt5.12.10\5.12.10\msvc2015_64\bin" &#xff0c;将此路径配置到环境变量&#xff1b; 2、用Qt Creator环境编译出Release版本可执行…...

electron+vite+vue3 快速入门教程

Electron、Vite 和 Vue 3 结合使用可以创建强大的跨平台桌面应用程序&#xff0c;下面是一个快速入门教程&#xff0c;帮助你搭建一个基于 Electron Vite Vue 3 的项目。 环境准备 Node.js: 首先确保你的机器上已经安装了 Node.js。你可以通过以下命令来检查是否已安装&…...

添加了addResourceHandlers 但没用

B站黑马的视频 public class WebMvcConfig extends WebMvcConfigurationSupport { /** * 设置静态资源映射 * param registry */ Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { log.info("开始进…...

uniapp如何获取安卓原生的Intent对象

通过第三方app唤起&#xff0c;并且获取第三方app唤起时携带的参数 因为应用a唤起应用b时&#xff0c;应用b第一时间就要拿到参数token&#xff0c;所以需要将获取参数的方法写在APP.vue中的onLaunch钩子里,如果其他地方要用可以选择vuex或者采用本地缓存。 uniapp中plus.run…...

国标GB28181视频平台EasyGBS在物业视频安防管理服务中的应用方案​

一、方案背景​ 在现代物业服务中&#xff0c;高效的安全管理与便捷的服务运营至关重要。随着科技的不断发展&#xff0c;物业行业对智能化、集成化管理系统的需求日益增长。EasyGBS作为一款基于国标GB28181协议的视频监控平台&#xff0c;具备强大的视频管理与集成能力&#…...

Linux容器大师:K8s集群部署入门指南

引言 在云原生时代&#xff0c;Kubernetes就像一位"集群调度大师"&#x1f3ae;&#xff0c;轻松管理成千上万的容器化应用&#xff01;本文将带你从零开始搭建生产级K8s集群&#xff0c;从基础概念到实战部署&#xff0c;从核心组件到安全运维。无论你是要搭建开发…...

Vue 3 中纯 template 标签

发现 Vue 3 中纯 template 标签不会被渲染。 可以加 v-if"1" 即可 https://andi.cn/page/622155.html...

极光PDF编辑器:高效编辑,轻松管理PDF文档

在日常工作和学习中&#xff0c;PDF文件的使用越来越普遍。无论是学术论文、工作报告还是电子书籍&#xff0c;PDF格式因其稳定性和兼容性而被广泛采用。然而&#xff0c;编辑PDF文件往往比编辑Word文档更加复杂。今天&#xff0c;我们要介绍的 极光PDF编辑器&#xff0c;就是这…...

《可信数据空间 技术架构》技术文件正式发布

可信数据空间 技术架构发布了 国家数据基础设施技术文件发布有几个月了&#xff0c;成为数据要素圈内必读的白皮书&#xff0c;接着今日国家数据局正式发布了《可信数据空间 技术架构》&#xff0c;笔者有幸见证了该文件出炉的过程&#xff0c;在这两个文件重&#xff0c;对数…...

OpenCV 图形API(74)图像与通道拼接函数-----合并三个单通道图像(GMat)为一个多通道图像的函数merge3()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 从3个单通道矩阵创建一个3通道矩阵。 此函数将多个矩阵合并以生成一个单一的多通道矩阵。即&#xff0c;输出矩阵的每个元素将是输入矩阵元素的…...

Redis应用场景实战:穿透/雪崩/击穿解决方案与分布式锁深度剖析

一、缓存异常场景全解与工业级解决方案 1.1 缓存穿透&#xff1a;穿透防御的三重门 典型场景 恶意爬虫持续扫描不存在的用户ID 参数注入攻击&#xff08;如SQL注入式查询&#xff09; 业务设计缺陷导致无效查询泛滥 解决方案进化论 第一层防护&#xff1a;布隆过滤器&am…...

负载均衡技术全景指南:架构、算法与发展趋势

负载均衡技术全景指南&#xff1a;架构、算法与发展趋势 一、负载均衡技术概述二、应用层负载均衡&#xff08;一&#xff09;HTTP 重定向&#xff08;二&#xff09;反向代理服务器 三、传输层负载均衡&#xff08;一&#xff09;DNS 域名解析负载均衡&#xff08;二&#xff…...

DeepSeek-V3 解析第二篇:DeepSeekMoE

这篇文章是我们 DeepSeek-V3 系列的第二篇&#xff0c;聚焦于 DeepSeek 模型 [1, 2, 3] 的一个关键架构突破&#xff1a;DeepSeekMoE。 &#x1f4da; 本文也是我们【LLM 架构演化系列】的第二篇&#xff0c;聚焦 DeepSeek-V3 的 MoE 架构创新。如果你正研究大模型性能优化或架…...

【ArcGISPro学习笔记】布局输出时图例总是有省略号怎么办?

在用ArcGISPro制图时&#xff0c;发现布局输出时图例总是有省略号&#xff0c;例如下图&#xff1a; 调整半天都搞不定&#xff0c;必须把图例框拉很宽才没有省略号&#xff0c;非常影响布局体验 后来发现只需调整一个地方就把省略号弄没了&#xff0c;就是在图例排列这里&…...

驱散养生伪识阴霾,重铸科学养生晴空

在健康意识日益觉醒的当下&#xff0c;养生已然成为人们生活中备受瞩目的焦点。然而&#xff0c;各类养生伪知识如同阴霾&#xff0c;遮蔽了科学养生的光芒&#xff0c;误导着人们的养生实践。只有彻底驱散这些伪识阴霾&#xff0c;才能重铸科学养生的朗朗晴空&#xff0c;让健…...

【补题】Codeforces Round 664 (Div. 1) A. Boboniu Chats with Du

题意&#xff1a;给出n&#xff0c;d&#xff0c;m三个值&#xff0c;分别代表&#xff0c;有多少个值ai&#xff0c;使用超过m的ai&#xff0c;需要禁言d天&#xff0c;如果不足也能使用&#xff0c;m代表区分点&#xff0c;问能得到最大的值有多少。 思路&#xff1a; …...

大语言模型 06 - 从0开始训练GPT 0.25B参数量 - MiniMind 实机配置 GPT训练基本流程概念

写在前面 GPT&#xff08;Generative Pre-trained Transformer&#xff09;是目前最广泛应用的大语言模型架构之一&#xff0c;其强大的自然语言理解与生成能力背后&#xff0c;是一个庞大而精细的训练流程。本文将从宏观到微观&#xff0c;系统讲解GPT的训练过程&#xff0c;…...

Java进阶--设计模式

设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编制真正工程化&#xff0c;设计模式是软件工程的基石&#xff0c;如同大厦的一块块砖石一样&#xff0…...

同时启动俩个tomcat压缩版

下载解压tomcat压缩版 复制一份&#xff0c;换个名字 更改任意一个tomcat的配置文件用记事本打开 修改三个位置 1.<Server port"8005" shutdown"SHUTDOWN"> 2. <Connector port"8080" protocol"HTTP/1.1" …...

ZYNQ MPSOC之PL与PS数据交互DMA方式

ZYNQ MPSOC之PL与PS数据交互DMA方式 1 摘要 XILINX ZYNQ 以及 ZYNQ MPSOC主要优势在于异构 ARM+FPGA。其中非常关键的一点使用了 AXI 总线进行高速互联。而且这个 AXI 总线是开放给我们用户使用的。在前面的文章中我们详解了使用了AXI-HP方式PL到PS端进行数据交互。本文主要涉…...