Java泛型类型解析
解析泛型类型
获取字段泛型类型
**java.lang.reflect.Field#getGenericType**:- 作用:返回字段的泛型类型。
- 返回类型:
Type。 - 如果字段是一个泛型类型,这个方法将返回一个表示这个泛型类型的
Type对象,比如ParameterizedType,TypeVariable等等。如果字段不是泛型类型,这个方法将返回字段的具体类型,即Class对象。 - 示例:
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;public class MyClass<K, V> {private K key;private V value;private List<String> list;public static void main(String[] args) throws Exception {Field field = MyClass.class.getDeclaredField("list");Type fieldType = field.getGenericType();System.out.println(fieldType + ": class " + fieldType.getClass());if (fieldType instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType) fieldType;System.out.println("ActualType: "+parameterizedType.getActualTypeArguments()[0]);}}
}
输出结果
java.util.List<java.lang.String>: class class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
ActualType: class java.lang.String
获取对象泛型类型
**java.lang.Class#getTypeParameters**:- 作用:返回类或接口的类型参数。
- 返回类型:
TypeVariable<?>[]。 - 如果类或接口没有定义类型参数,这个方法将返回一个空数组。如果类或接口有类型参数,这个方法将返回这些类型参数的数组。
- 示例:
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;public class MyClass<K, V> {private K key;private V value;private List<String> list;public static void main(String[] args) throws Exception {TypeVariable<?>[] typeParameters = MyClass.class.getTypeParameters();for (TypeVariable<?> typeParameter : typeParameters) {System.out.println(typeParameter.getName() + ": class" + typeParameter.getClass());System.out.println("Bounds:");for (Type bound : typeParameter.getBounds()) {System.out.println(bound);}}}
}
输出结果,此处的范型被擦除了,后续会讲解具体的解决方案
K: classclass sun.reflect.generics.reflectiveObjects.TypeVariableImpl
Bounds:
class java.lang.Object
V: classclass sun.reflect.generics.reflectiveObjects.TypeVariableImpl
Bounds:
class java.lang.Object
总结
Field#getGenericType是针对类的字段,返回字段的泛型类型或具体类型。Class#getTypeParameters是针对类或接口,返回定义在类或接口上的类型参数。
如果你想获取一个类中字段的实际类型,Field#getGenericType 是合适的方法。如果你想获取类本身定义的类型参数,Class#getTypeParameters 是正确的方法。
ParameterizedType与TypeVariable区别
ParameterizedType 和 TypeVariable 是 Java 反射 API 中的两个接口,用于表示不同类型的泛型类型信息。它们之间的区别在于它们表示的泛型类型的不同方面。
ParameterizedType
ParameterizedType 表示的是一个参数化的类型,即:使用具体类型参数化的泛型类型。它包含了泛型类型的完整信息,包括原始类型和实际类型参数。例如,对于 List<String>,ParameterizedType 会表示 List<String> 这个具体的类型。
主要方法:
Type[] getActualTypeArguments():返回实际的类型参数数组。Type getRawType():返回原始类型(即未参数化的类型,例如List)。Type getOwnerType():返回拥有者类型,如果类型是一个内部类,这个方法返回其外部类;否则返回null。
示例:
import java.lang.reflect.*;public class ParameterizedTypeExample {public static void main(String[] args) throws NoSuchFieldException {Field field = MyClass.class.getDeclaredField("list");Type type = field.getGenericType();if (type instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType) type;System.out.println("Raw type: " + parameterizedType.getRawType());System.out.println("Actual type arguments:");for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {System.out.println(actualTypeArgument);}}}static class MyClass {List<String> list;}
}
输出结果
Raw type: interface java.util.List
Actual type arguments:
class java.lang.String
TypeVariable
TypeVariable 表示的是一个类型变量(泛型类型参数),通常在泛型类、接口或方法的定义中使用。例如,对于 T 在 class MyClass<T> 中,TypeVariable 就表示 T。
主要方法:
Type[] getBounds():返回类型变量的上边界(可能有多个),默认为Object。D getGenericDeclaration():返回声明这个类型变量的泛型声明(通常是Class、Method或Constructor)。String getName():返回类型变量的名称。
示例:
import java.lang.reflect.*;public class TypeVariableExample {public static void main(String[] args) {TypeVariable<Class<MyClass>>[] typeParameters = MyClass.class.getTypeParameters();for (TypeVariable<Class<MyClass>> typeParameter : typeParameters) {System.out.println("Name: " + typeParameter.getName());System.out.println("Bounds:");for (Type bound : typeParameter.getBounds()) {System.out.println(bound);}}}static class MyClass<T extends Number> {T value;}
}
输出结果
Name: T
Bounds:
class java.lang.Number
区别总结
**ParameterizedType**表示的是已经用实际类型参数化的泛型类型。例如,List<String>是一个ParameterizedType。**TypeVariable**表示的是泛型类型参数本身。例如,T在class MyClass<T>中是一个TypeVariable。
这两个接口的主要区别在于它们表示的类型信息的不同:ParameterizedType 表示完整的参数化类型,而 TypeVariable 表示泛型类型参数。
泛型擦除
有时候为了扩展,需要动态的根据泛型获取对应的处理类,此时涉及到类型擦除时需要强制转换支持
- List<Pipeline<?, MyOutput>>无法直接强转为List<Pipeline<T, MyOutput>>
解决方法
- (List<?>)将List<Pipeline<?, MyOutput>>中的类型擦除,然后再次强转为List<Pipeline<T, MyOutput>>
- 遍历列表将元素强转为目标类型之后添加到列表
private static final Map<Object, List<Pipeline<?, MyOutput>>> PIPELINE = Maps.newHashMap();@SuppressWarnings("unchecked")
public <T> List<Pipeline<T, MyOutput>> get(T input) {return (List<Pipeline<T, MyOutput>>) (List<?>) PIPELINE.get(input);
}@SuppressWarnings("unchecked")
public <T> List<Pipeline<T, MyOutput>> getCanBuyPipeLine(T input) {List<Pipeline<T, MyOutput>> result = Lists.newArrayList();for (Pipeline<?, MyOutput> pipeline : PIPELINE.get(input)) {result.add((Pipeline<T, MyOutput>) pipeline);}return result;
}
第一种方式
GenericTypeDemo<Integer> demo = new GenericTypeDemo<>();
Type t = new TypeToken<T>(demo.getClass()) {}.getType();
- 创建实例:
GenericTypeDemo<Integer> demo = new GenericTypeDemo<>();
创建了一个 GenericTypeDemo<Integer> 的实例。
- 使用 TypeToken 获取类型:
Type t = new TypeToken<T>(demo.getClass()) {}.getType();
这段代码试图通过 TypeToken 获取 demo 的泛型类型。这里的 TypeToken<T> 依赖于 demo.getClass(),但是 demo.getClass() 返回的是 GenericTypeDemo 的运行时类信息,其中的泛型类型已经被擦除。因此,TypeToken<T> 无法捕获到实际的泛型类型 Integer。
第二种方式
import com.google.common.reflect.TypeToken;public class GenericTypeDemo<T> {private final TypeToken<T> typeToken;public GenericTypeDemo() {this.typeToken = new TypeToken<T>(getClass()) {};}public TypeToken<T> getTypeToken() {return this.typeToken;}public static void main(String[] args) {GenericTypeDemo<Integer> demo = new GenericTypeDemo<>() {};System.out.println("泛型类型是: " + demo.getTypeToken().getType());}
}
- 定义类和构造函数:
public class GenericTypeDemo<T> {private final TypeToken<T> typeToken;public GenericTypeDemo() {this.typeToken = new TypeToken<T>(getClass()) {};}public TypeToken<T> getTypeToken() {return this.typeToken;}
}
在这个类中,TypeToken<T> 被用来捕获 GenericTypeDemo 的泛型类型。关键在于 new TypeToken<T>(getClass()) {},这是在匿名子类中使用 TypeToken 捕获泛型类型信息。
- 使用泛型类型实例化对象:
public static void main(String[] args) {GenericTypeDemo<Integer> demo = new GenericTypeDemo<>() {};System.out.println("泛型类型是: " + demo.getTypeToken().getType());
}
在 main 方法中,GenericTypeDemo<Integer> 被实例化为匿名子类,因此 TypeToken 可以捕获到实际的泛型类型 Integer。当调用 demo.getTypeToken().getType() 时,会正确输出 Integer 的类型。
总结
- 第一种方式:
- 直接通过
demo.getClass()获取类型,类型信息在运行时已经被擦除,TypeToken<T>无法获取到实际的泛型类型。 - 最终得到的
Type t只是一个原始的类型GenericTypeDemo,没有泛型信息。
- 直接通过
- 第二种方式:
- 在
GenericTypeDemo类的构造函数中,通过匿名子类和TypeToken<T>捕获泛型类型信息。 - 实例化
GenericTypeDemo<Integer>时,匿名子类保留了泛型类型信息,TypeToken<T>成功捕获到实际的泛型类型Integer。 - 结果是
demo.getTypeToken().getType()能够正确输出泛型类型Integer。
- 在
因此,第二种方式能够正确捕获和输出泛型类型信息,而第一种方式由于泛型类型擦除问题无法正确捕获泛型类型。
spring中获取泛型
抽象类与泛型捕获
假设我们有一个抽象类 AbstractComponent:
import com.google.common.reflect.TypeToken;public abstract class AbstractComponent<T> {private final Class<T> type = (Class<T>) new TypeToken<T>(getClass()) {}.getType();public AbstractComponent() {}public Class<T> getType() {return this.type;}
}
关键点
**TypeToken**** 的使用**:
new TypeToken<T>(getClass()) {}
- `TypeToken` 是 Guava 库中的一个工具类,它用于在运行时捕获和处理泛型类型信息。
- `TypeToken` 的构造函数接收一个 `Class` 对象,这里是 `getClass()`,它在这个上下文中返回 `AbstractComponent` 的运行时类。
- 为什么能够捕获泛型类型:
- 在
AbstractComponent<T>类中,getClass()返回的是AbstractComponent的运行时类,而不是具体的子类。 - 当创建具体子类(例如
ConcreteComponent)时,AbstractComponent的构造函数会执行,并且TypeToken实例会使用当前运行时类(即ConcreteComponent)来初始化。
- 在
- 类型擦除与泛型捕获:
- 类型擦除:Java 的泛型在编译时会进行类型擦除,这意味着在运行时,泛型类型
T的具体信息会丢失。但在创建子类时,匿名子类的TypeToken实例会捕获并保留泛型类型信息。 - 具体子类的影响:当具体子类(例如
ConcreteComponent)被实例化时,它会调用父类的构造函数。在这种情况下,TypeToken能够通过匿名子类的方式捕获实际的泛型类型。
- 类型擦除:Java 的泛型在编译时会进行类型擦除,这意味着在运行时,泛型类型
示例
假设我们有以下具体子类:
import org.springframework.stereotype.Component;@Component
public class ConcreteComponent extends AbstractComponent<String> {// Concrete implementation
}
执行流程
- 创建子类实例:
ConcreteComponent component = new ConcreteComponent();
- 这会调用 `ConcreteComponent` 的构造函数,而 `ConcreteComponent` 的构造函数会调用 `AbstractComponent` 的构造函数。
**AbstractComponent**** 的构造函数**:
public AbstractComponent() {// Initializer of the final field 'type'
}
- 在这个构造函数中,`TypeToken` 实例使用 `getClass()` 返回 `ConcreteComponent` 的运行时类。这是由于在 `AbstractComponent` 的 `type` 字段初始化时,`new TypeToken<T>(getClass()) {}` 被调用。
- 捕获泛型类型:
new TypeToken<T>(getClass()) {}创建了一个匿名子类,并且这个匿名子类通过反射机制获取到了泛型类型String。- 因此,
type字段被正确初始化为String的Class对象。
总结
- 运行时类信息:在
AbstractComponent中,通过getClass()返回具体子类(如ConcreteComponent)的运行时类信息。 - 匿名子类和泛型捕获:
TypeToken的匿名子类能够在创建时捕获并保留泛型类型信息,即使在运行时泛型信息被擦除。 - 实例化时的行为:当具体子类被实例化时,它会调用父类的构造函数,
TypeToken实例通过具体子类的运行时类信息正确捕获泛型类型。
因此,在你的抽象类 AbstractComponent<T> 中,final 字段 type 能够正确保存具体泛型类型信息,是因为匿名子类机制允许 TypeToken 捕获到实际的泛型类型 T。
spring能够获取到泛型,是因为spring使用了代理超类,bean对于spring来说是子类化了,所以可以通过反射或者TypeToken方式获取到具体的泛型
Spring 能够获取到泛型类型信息,主要是因为它在处理 bean 时会使用一些技巧来保持泛型的类型信息。具体来说:
- 代理超类:Spring 在创建代理对象时,通常会使用自定义的代理超类,这样可以在运行时通过反射获取到泛型参数的信息。
- TypeToken:Spring 通过使用
TypeToken(类似于 Google Guava 的TypeToken类)来保持泛型信息。在类型擦除的情况下,TypeToken提供了一个获取具体泛型类型的方法。 - 反射:Spring 使用反射机制来获取泛型参数的类型信息。例如,Spring 的
@Autowired注解可以自动注入泛型类型的 Bean,Spring 在进行注入时会解析泛型参数的信息。 - 自定义 Bean 实现:在一些情况下,Spring 可能会使用自定义的 Bean 实现来保持泛型类型信息。这种方法通常是通过在 Bean 定义中显式声明泛型类型。
总之,Spring 通过这些机制确保了泛型类型信息可以在运行时被正确地获取和使用。
普通对象获取泛型
new Pipeline<>() 创建实例时,Java 的类型擦除特性会导致你无法直接获取泛型的具体类型。类型擦除是指在编译时,Java 泛型信息会被移除,导致在运行时无法直接获取泛型参数的实际类型。
Spring 在处理泛型时,能够获取到泛型类型参数,是因为 Spring 在实例化 bean 的时候,通常使用了代理或其他机制来保存泛型信息。以下是一些解决方法,可以帮助你获取泛型参数的实际类型:
使用 TypeToken 获取泛型类型
你可以使用 TypeToken(Guava 库中的一个工具类)来获取泛型类型信息,但要注意,TypeToken 需要在 Pipeline 子类中使用才能正确地获得泛型类型。示例如下:
import com.google.common.reflect.TypeToken;public class Pipeline<I, O> {private final Class<I> inputClass;@SuppressWarnings("unchecked")public Pipeline() {TypeToken<Pipeline<I, O>> typeToken = new TypeToken<Pipeline<I, O>>(getClass()) {};this.inputClass = (Class<I>) typeToken.resolveType(typeToken.getType().getActualTypeArguments()[0]).getRawType();}public Class<I> getInputClass() {return inputClass;}// Other methods...
}
使用反射获取泛型类型
如果你不想使用 Guava 库,你可以在 Pipeline 的子类中获取泛型类型信息。示例如下:
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;public class Pipeline<I, O> {private final Class<I> inputClass;@SuppressWarnings("unchecked")public Pipeline() {this.inputClass = (Class<I>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];}public Class<I> getInputClass() {return inputClass;}// Other methods...
}
确保子类化 Pipeline
确保 Pipeline 是通过子类化的方式实例化的,这样可以保留泛型信息。例如:
public class StringPipeline extends Pipeline<String, Integer> {// Implementation details...
}
在 StringPipeline 中,你可以通过反射或者 TypeToken 来获取 String 类型信息。
结论
Java 的类型擦除特性使得泛型类型信息在运行时不可用。使用 TypeToken 或者在子类中通过反射获取泛型类型是解决这个问题的常用方法。如果你使用 Spring 或其他框架,它们通常会在创建 bean 时保留泛型信息,这样你可以在运行时访问这些信息。
相关文章:
Java泛型类型解析
解析泛型类型 获取字段泛型类型 **java.lang.reflect.Field#getGenericType**: 作用:返回字段的泛型类型。返回类型:Type。如果字段是一个泛型类型,这个方法将返回一个表示这个泛型类型的 Type 对象,比如 ParameterizedType&…...
EasyExcel 学习之 导出 “类型及精度问题”
目录 现象缘由类型问题精度/格式问题精度问题格式问题 解决 现象 Excel 导出时,可能面临几个问题: 类型问题:常见类型转换、URL 转图片等精度/格式问题:数字、日期转换 缘由 类型问题 Excel 常见的 API 有两种,Ea…...
从视频中每隔10帧截取一帧并保存为图片
要从视频中每隔10帧截取一帧并保存为图片,可以使用 OpenCV 库。 import cv2# 视频文件的路径 video_path path/to/your/video.mp4# 创建一个 VideoCapture 对象 cap cv2.VideoCapture(video_path)# 检查是否成功打开视频文件 if not cap.isOpened():print("E…...
防火墙、firewalld指令、更改yum源为阿里云的yum源及常见问题
一、防火墙分类 1、硬件防火墙 2、软件防火墙(咱们昨天学的就属于这个) 3、waf 4、下一代防火墙 二、工作原理 1、通过对进出口数据的(数据、端口、IP等)进行过滤,达到对内网数据的保护。 2、防护危险的一堵墙、…...
5G Multicast/Broadcast Services(MBS) (二) Multicast
这篇是Multicast handling的overview,正文开始。 值得注意的是,对于5MBS multicast,UE只有处于 RRC connected和Inactive时,网络侧才可以 通过MRB将MBS multicast数据传输到 UE;处于Idle态只能进行MBS broadcast过程。 对于multicast涉及的RN...
【计算机方向】中科院二区潜力刊!最快14天accept,还是非OA ,不能错过!
期刊解析 🚩本 期 期 刊 看 点 🚩 非OA 审稿友好,审稿速度快 自引率7.9% 今天小编带来计算机领域SCI快刊的解读! 如有相关领域作者有意投稿,可作为重点关注! 01 期刊信息✦ 期刊名称:Inter…...
合适做项目交付的物联网平台:ThingsKit
ThingsKit,作为一个专为项目交付设计的物联网平台,凭借其强大的功能和灵活性,成为了众多企业的首选。 一、ThingsKit的核心优势 模块化设计:ThingsKit采用模块化设计,使得用户可以根据自己的需求灵活选择和组合不同的…...
python绘制3D瀑布图
成品: 代码: def line_3d(x, y, z, x_label_indexs):"""在y轴的每个点,向x轴的方向延伸出一个折线面:展示每个变量的时序变化。x: x轴,时间维,右边。y: y轴,变量维,…...
ArcGIS中怎么合并多个点图层并删除重复点?
最近,我接到了一个怎么合并多个点图层并删除其中的重复点的咨询。 下面是我对这个问题的解决思路: 1、合并图层 在地理处理工具里面 选择合并 并设置好要合并的图层即可 2、接下来在 数据管理工具→常规→删除相同项 即可 希望这些建议能对大家有所帮…...
【vue、UI】使用 Vue2 和 Element UI 封装 CSV 文件上传组件,实现csv回显
文章目录 前言组件功能概述实现效果组件模板结构组件的核心逻辑1.数据属性定义2.方法拆解3.CSV 文件解析方法4. 错误处理方法 组件样式完整组件代码总结待优化的地方 前言 在 Vue2 项目中,我们经常需要封装一些可重用的组件来提升开发效率。本文将介绍如何使用 Vue…...
erlang学习: Mnesia Erlang数据库2
Mnesia数据库增加与查询学习 -module(test_mnesia).-record(shop, {item, quantity, cost}). -record(cost, {name, price}). -record(design, {info, plan}). %% API -export([insert/3,select/1,start/0]). start() ->mnesia:start().insert(Name, Quantity, Cost) ->…...
电脑文件怎么备份?推荐6个高效便捷的文件备份的方法
在日常使用电脑的过程中,数据备份是一项至关重要的任务。无论是个人用户还是企业用户,都需要确保重要文件的安全性和可恢复性。 以下是推荐的六个高效便捷的文件备份方法,帮助你轻松守住你的文档安全。 1. 使用USB存储设备 USB存储设备如U盘…...
Procdump抓ToDesk密码
目录 前言 1.工具教程 2.转储数据 3.密码获取 4.总结 前言 本文是因为在公众号上看到一篇文章随想着实战中利用ToDesk秀操作失败后,实验环境成功复现后写下。ProcDump[1] 是一个命令行实用工具,其主要用途是监视应用程序的 CPU 峰值,并在…...
ESP8266下载固件→连接阿里云
一、工具准备 1、ESP8266Wifi模块 2、ESP8266下载器 ESP8266-01模块 二、固件配置 CH340串口工具-烧录ESP8266-01固件_esp8266 ch340烧录-CSDN博客文章浏览阅读444次,点赞6次,收藏3次。CH340会有供电不足的问题,因此需要外部供电_esp…...
20240911软考架构-------软考156-160答案解析
每日打卡题156-160答案 156、NoSQL整体框架分为4层,由下至上分为数据持久层、数据分布层、数据逻辑模型层和(1)。(2)定义了数据的存储形式。(3)定义了数据是如何分布的。(4…...
工厂模式与策略模式(golang示例)
一、工厂模式简介 工厂模式是一种创建型设计模式,主要用于封装对象的创建过程。通过使用工厂模式,客户端代码无需直接实例化对象,而是通过工厂类来创建对象。这样可以将对象的创建与使用分离,从而提高代码的灵活性。 1.1 工厂模…...
批量视频如何做成一个二维码(分步骤教程)
原创教程,阿酷TONY,2024.9.11,湖南长沙 批量视频如何做成一个二维码(分步骤教程),场景应用: 1. 一批视频需要按组分类,生成一个二维码,实现扫一个二维码,观看…...
OpengGL教程(三)---使用VAO和VBO方式绘制三角形
本章参考官方教程:learnopengl-cn VertexShader.glsl #version 330 core layout(location 0) in vec3 position; layout(location 1) in vec3 color; uniform mat4 projection; // 投影矩阵 out vec4 ourColor; void main() {gl_Position projection * vec4(p…...
【单片机开发】单片机常用开发工具
【前言】 在嵌入式系统领域,单片机(Microcontroller, MCU)作为核心组件,广泛应用于智能家居、工业控制、汽车电子等众多领域。而单片机开发工具,则是开发者们实现创意、解决问题的重要助手。本文主要讲述目前主流的单…...
一、计算机网络的体系结构
1.1 计算机网络的组成 1)从组成部分上分为:硬件、软件、协议。硬件是指主机、通信链路、交换设备和通信处理机组曾。软件包括各种实现资源共享的软件以及各种软件工具(如网络操作系统、邮件收发程序、FTP程序、聊天软件)。 2&…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
GraphRAG优化新思路-开源的ROGRAG框架
目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...
