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

【从零开始入门unity游戏开发之——C#篇39】C#反射使用——Type 类、Assembly 类、Activator 类操作程序集

文章目录

  • 前言
  • 一、前置知识
    • 1、编译器
    • 2、程序集(`Assembly`)
    • 3、元数据(`Metadata`)
  • 二、反射
    • 1、反射的概念
    • 2、反射的作用
    • 3、反射的核心`Type` 类
      • 3.1 `Type` 类介绍
      • 3.2 不同方法获取 `Type`
      • 3.3 获取type类型所在的程序集的相关信息
    • 4、反射的常见用法
      • 4.1 获取 `Type`类型信息
      • 4.2 获取类的公共成员
      • 4.3 获取类的构造函数
      • 4.4 获取类的字段
      • 4.5 获取类的成员方法
      • 4.6 其他反射操作
    • 5、反射访问并操作私有(private)成员(包括字段、属性、方法等)
    • 6、总结
  • 三、关键类Assembly和Activator
    • 1、**反射中的关键类**
      • 1.1 `Type` 类(前面已经介绍过了)
      • 1.2 `Assembly` 类
      • 1.3 `Activator` 类
    • 2、**使用 `Activator` 类实例化对象**
      • 示例 1:无参构造函数
      • 示例 2:带参数的构造函数
    • 3、**使用 `Assembly` 类加载程序集**
      • 3.1 加载程序集:
        • (1)获取当前执行的程序集:
        • (2)从指定路径加载程序集:
      • 3.2 获取指定名称的类型
      • 3.3 获取所有类型:
      • 3.4 获取并调用类型中的方法:
    • 4、综合示例
  • 四、**总结**
  • 专栏推荐
  • 完结

前言

C# 反射 (Reflection) 是一种强大的机制,它允许程序在运行时动态地查看和操作程序的元数据。通过反射,我们可以在不事先知道类型信息的情况下,获取类型信息并操作类型中的成员(如类、方法、属性、字段等)。

一、前置知识

1、编译器

编译器是将源语言程序(如 C#、Java、C 等)翻译为目标语言程序(如机器代码或伪机器代码)的工具。源代码经过编译器的处理后,可以生成可执行文件 (.exe) 或库文件 (.dll) ,供程序运行时使用。

2、程序集(Assembly

程序集是经过编译器编译得到的中间产物,可以是一个库文件 (.dll) 或可执行文件 (.exe)。它是 .NET 程序中的代码集合,包含了类型、方法、属性等元数据,是程序执行的基础。

程序集就是我们写的一个代码集合,我们现在写的所有代码,最终都会被编译器翻译为一个程序集供别人使用。比如一个代码库文件(dll)或者一个可执行文件(exe)

我们新建一个C#项目,运行一次后,系统就会自动在bin目录里生成对应的程序集文件
在这里插入图片描述

3、元数据(Metadata

在C#中,元数据(Metadata)指的是描述程序及其组成部分(如类、方法、属性、字段等)的信息。它是关于代码的“数据”,但并不是实际执行的代码。可以将元数据视为程序代码的“数据字典”,它提供了有关类型、成员和引用等的信息,使得程序在运行时可以进行动态操作。

元数据是随代码一起编译成程序集(Assembly)的一部分,并且可以在运行时通过反射机制进行访问。

元数据是指有关程序结构和组成部分的描述信息,它不仅有助于程序的运行时类型检查,还为反射、动态加载等功能提供了支持。在C#中,元数据通常存储在程序集文件中,并可以通过反射机制访问和操作。

二、反射

1、反射的概念

反射允许程序在运行时查看其他程序集或自身的元数据,动态获取类型信息并对其进行操作。例如,通过反射可以查看类的构造函数、方法、字段、属性等,甚至可以在运行时动态创建对象并调用方法。

2、反射的作用

  • 程序运行时获取类型信息:反射可以帮助我们动态获取类、方法、字段等的元数据信息。
  • 动态操作对象:反射使得我们可以动态实例化对象,调用方法,修改字段值等。
  • 增强灵活性:反射使得代码更加灵活,尤其在插件机制、依赖注入等场景下尤为重要。

3、反射的核心Type

3.1 Type 类介绍

Type 类是反射的基础,它提供了关于类的所有信息,例如类的名称、构造函数、方法、字段、属性等。它是访问元数据的主要方式。

3.2 不同方法获取 Type

  • 通过对象的 GetType() 方法获取:

    int a = 42;
    Type type = a.GetType();
    Console.WriteLine(type);  // 输出: System.Int32
    
  • 通过 typeof 关键字获取:

    Type type = typeof(int);
    Console.WriteLine(type);  // 输出: System.Int32
    
  • 通过类的全名获取:

    Type type = Type.GetType("System.Int32");
    Console.WriteLine(type);  // 输出: System.Int32
    

    其实就是命名空间.类名
    在这里插入图片描述

3.3 获取type类型所在的程序集的相关信息

Console.WriteLine(type.Assembly);

打印

System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
  • System.Private.CoreLib 是程序集的名称。(通常是 .exe 或 .dll 文件的名称)
  • Version=9.0.0.0 是程序集的版本。
  • Culture=neutral 表示它是通用区域设置的。(如果是通用语言程序集,则为 neutral)。
  • PublicKeyToken=7cec85d7bea7798e 是公共密钥标识符。(用于区分同名的不同程序集版本)。

4、反射的常见用法

为了方便测试反射的常见用法,这里我先新增一个简单的类,里面包含基本的构造函数、方法、字段、属性。

ps:这里只是测试探究,实际开发肯定不需要通过反射来操作自己的类。

class Test
{private int i = 1;public int j = 2;public int k { get; set; }public string str = "向宇的客栈";public Test() { }public Test(int i){this.i = i;}public Test(int i, string str) : this(i){this.str = str;}public void Log(){Console.WriteLine("学习C#");}
}

4.1 获取 Type类型信息

Type t = typeof(Test);// 获取类型信息

4.2 获取类的公共成员

使用 GetMembers() 方法获取类中的所有公共成员:

MemberInfo[] infos = t.GetMembers();
foreach (var info in infos)
{Console.WriteLine(info);
}

打印结果
在这里插入图片描述

可以看到,除了万物之父(object)中的方法,打印出来的都是我们前面Test类中定义的公共成员信息(构造函数、方法、字段、属性)。

4.3 获取类的构造函数

  • 获取所有构造函数:
ConstructorInfo[] ctors = t.GetConstructors();
foreach (var ctor in ctors)
{Console.WriteLine(ctor);
}

结果
在这里插入图片描述

  • 获取无参构造函数并调用:
ConstructorInfo ctor = t.GetConstructor(Type.EmptyTypes);
Test obj = (Test)ctor.Invoke(null);
Console.WriteLine(obj);
  • 获取有参构造函数并调用:
ConstructorInfo ctor = t.GetConstructor(new Type[] { typeof(int), typeof(string) });
Test obj = (Test)ctor.Invoke(new object[] { 10, "Hello" });
Console.WriteLine(obj);

4.4 获取类的字段

  • 获取所有公共字段:
FieldInfo[] fieldInfos = t.GetFields();
foreach (var field in fieldInfos)
{Console.WriteLine(field);
}

结果
在这里插入图片描述

  • 获取指定字段:
FieldInfo fieldInfo = t.GetField("j");
Console.WriteLine(fieldInfo);

结果
在这里插入图片描述

  • 使用反射获取和设置字段的值:
FieldInfo fieldInfo = t.GetField("j");
Test test = new Test();
test.j = 99;
fieldInfo.SetValue(test, 100);
Console.WriteLine(fieldInfo.GetValue(test));  // 输出: 100

4.5 获取类的成员方法

  • 获取所有公共方法(记得引入using System.Reflection;反射命名空间):
using System.Reflection;MethodInfo[] methods = t.GetMethods();
foreach (var method in methods)
{Console.WriteLine(method);
}
  • 获取指定方法并调用:
MethodInfo method = t.GetMethod("ToString");
object result = method.Invoke(test, null);
Console.WriteLine(result);
  • 对于方法重载,需要提供方法的参数类型:
MethodInfo method = t.GetMethod("Substring", new Type[] { typeof(int), typeof(int) });
object result = method.Invoke("Hello, World!", new object[] { 7, 5 });
Console.WriteLine(result);  // 输出: World

4.6 其他反射操作

  • 枚举
    获取枚举类型的名称:

    Enum.GetEnumName(typeof(DayOfWeek), 1);  // 输出: Monday
    
  • 事件
    获取类的事件:

    EventInfo eventInfo = t.GetEvent("MyEvent");
    Console.WriteLine(eventInfo);
    
  • 接口
    获取类实现的接口:

    Type[] interfaces = t.GetInterfaces();
    foreach (var iface in interfaces)
    {Console.WriteLine(iface);
    }
    
  • 属性
    获取类的属性:

    PropertyInfo[] properties = t.GetProperties();
    foreach (var property in properties)
    {Console.WriteLine(property);
    }
    

5、反射访问并操作私有(private)成员(包括字段、属性、方法等)

在默认情况下,反射是可以访问私有成员的,但你必须明确告诉 .NET 你要访问它们。具体来说,你需要使用 BindingFlags 来指定访问私有成员。

例如,默认情况下,反射会忽略私有字段和方法,但你可以通过显式地指定 BindingFlags.NonPublicBindingFlags.Instance 来让反射能够访问这些私有成员。

示例

// 创建 MyClass 的实例
MyClass myObject = new MyClass();// 获取 MyClass 类型的信息
Type type = typeof(MyClass);// 使用反射访问私有字段 secretValue
FieldInfo fieldInfo = type.GetField("secretValue", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo != null)
{// 获取字段的值var value = fieldInfo.GetValue(myObject);Console.WriteLine("Private Field 'secretValue' Value: " + value);
}// 使用反射访问私有方法 PrintSecret
MethodInfo methodInfo = type.GetMethod("PrintSecret", BindingFlags.NonPublic | BindingFlags.Instance);
if (methodInfo != null)
{// 调用私有方法methodInfo.Invoke(myObject, null);
}

这种机制虽然强大,但应谨慎使用,避免破坏封装性,尤其是在生产环境中。这种做法通常用于调试、测试、动态代理等特殊场景。

6、总结

C# 中的反射为程序提供了强大的动态能力,通过 Type 类及其提供的方法,我们可以在运行时获取类型的元数据,动态创建对象,调用方法,甚至修改字段值。

虽然反射提供了灵活性,但是反射的性能较差,因为它是动态查找和操作的。如果频繁使用反射,可能会影响程序性能,尤其是在处理大量数据时。因此应该在合适的场合使用反射,并考虑到性能和可维护性。

三、关键类Assembly和Activator

反射(Reflection)是 C# 中一个非常强大的机制,它允许在运行时访问和操作程序中的类型信息。通过反射,程序可以在运行时动态地获取类、方法、属性等信息,并实例化对象、调用方法、访问字段等。下面是对 AssemblyActivator 这两个关键类的详细介绍和相关用法。

1、反射中的关键类

1.1 Type 类(前面已经介绍过了)

Type 类提供了对类型信息的访问,它是所有类型的元数据的基础。通过 Type 对象,你可以获取类的构造函数、属性、字段、方法等信息。

1.2 Assembly

Assembly 类用于加载和操作程序集。程序集包含了类、接口、枚举等信息,反射可以用来加载程序集,并且在程序运行时查找类型和操作它们。

1.3 Activator

Activator 类位于 System 命名空间下,提供了一组静态方法来创建类型的实例。它常用于在运行时通过反射动态创建对象,特别是在我们事先不知道具体类型的情况下。例如,依赖注入、插件加载、对象池等场景中,可以使用 Activator 来动态实例化对象。

2、使用 Activator 类实例化对象

Activator 提供了几种创建对象的方法,最常用的是 CreateInstance,它可以用来根据 Type 对象动态创建实例。

示例 1:无参构造函数

假设有一个类 Test,它有一个无参构造函数。你可以使用 Activator.CreateInstance 来创建该类的实例。

using System;public class Test
{public string str = "Hello, World!";
}class Program
{static void Main(){// 获取 Test 类的 Type 对象Type testType = typeof(Test);// 使用 Activator 创建对象实例Test testobj = Activator.CreateInstance(testType) as Test;// 输出结果Console.WriteLine(testobj.str);  // Output: Hello, World!}
}

示例 2:带参数的构造函数

如果类有带参数的构造函数,可以使用 Activator.CreateInstance 方法传递参数来创建实例。

using System;public class Test
{public int j;public string str;// 构造函数public Test(int j, string str){this.j = j;this.str = str;}
}class Program
{static void Main(){Type testType = typeof(Test);// 使用带参数的构造函数Test testobj1 = Activator.CreateInstance(testType, 99, "Hello") as Test;Console.WriteLine(testobj1.j);  // Output: 99Console.WriteLine(testobj1.str);  // Output: HelloTest testobj2 = Activator.CreateInstance(testType, 55, "World") as Test;Console.WriteLine(testobj2.j);  // Output: 55Console.WriteLine(testobj2.str);  // Output: World}
}

3、使用 Assembly 类加载程序集

前面我们一直都是对当前程序的操作,实际开发肯定是操作外部程序集。Assembly 类使得我们可以在运行时加载、查询、获取外部程序集的类型信息等。

常用方法:

  • GetExecutingAssembly():获取当前执行的程序集。
  • LoadFrom(string path):从指定路径加载程序集。
  • GetTypes():获取程序集中的所有类型。
  • GetType(string typeName):获取指定名称的类型。
  • GetManifestResourceNames():获取程序集中的所有嵌入式资源名称。

3.1 加载程序集:

(1)获取当前执行的程序集:
Assembly assembly = Assembly.GetExecutingAssembly();
Console.WriteLine("当前程序集: " + assembly.FullName);
(2)从指定路径加载程序集:
Assembly assembly = Assembly.LoadFrom("path/to/your/assembly.dll");
Console.WriteLine("加载程序集: " + assembly.FullName);

3.2 获取指定名称的类型

Assembly assembly = Assembly.LoadFrom("path/to/your/assembly.dll");
Type type = assembly.GetType("Namespace.ClassName"); // 获取程序集中的某个类型
Console.WriteLine("类型名称: " + type.FullName);

3.3 获取所有类型:

Assembly assembly = Assembly.LoadFrom("path/to/your/assembly.dll");
Type[] types = assembly.GetTypes();
foreach (Type t in types)
{Console.WriteLine(t.FullName); // 输出程序集中的所有类型
}

3.4 获取并调用类型中的方法:

其实就是结合前面Type知识配合使用

Assembly assembly = Assembly.LoadFrom("path/to/your/assembly.dll");
Type type = assembly.GetType("Namespace.ClassName");
MethodInfo methodInfo = type.GetMethod("MethodName");
object result = methodInfo.Invoke(null, null); // 调用静态方法
Console.WriteLine(result);

4、综合示例

我这里项目的程序集文件路径为:C:\Users\zw\Desktop\C#\bin\Debug\net9.0\C#.dll
在这里插入图片描述
程序集文件里主要的代码是,我自定义了一个Test类
在这里插入图片描述

代码

using System;
using System.Reflection;class Program
{static void Main(){// 加载程序集(因为是反斜杠,所以加个@不希望它转义)Assembly assembly = Assembly.LoadFrom(@"C:\Users\zw\Desktop\C#\bin\Debug\net9.0\C#.dll");// 获取程序集中的所有类型Type[] types = assembly.GetTypes();foreach (var type in types){Console.WriteLine(type.Name);}// 获取程序集中的一个具体类型Type testType = assembly.GetType("Test");// 使用反射实例化对象object myClassObj = Activator.CreateInstance(testType);// 获取并调用方法MethodInfo method = testType.GetMethod("Log");method.Invoke(myClassObj, null);// 获取指定字段并打印值FieldInfo field1 = testType.GetField("str");Console.WriteLine(field1.GetValue(myClassObj));// 获取指定字段,先修改值,在打印值FieldInfo field2 = testType.GetField("j");field2.SetValue(myClassObj, 100);Console.WriteLine(field2.GetValue(myClassObj));}
}

结果,程序集里的方法被执行,字段也被打印了(Program类和E_Days枚举是定义的其他两个测试数据,不用管即可)
在这里插入图片描述

四、总结

  • Type:提供关于类、接口、枚举等类型的信息。
  • Assembly:用于加载程序集,可以获取程序集中的所有类型和类型成员信息。
  • Activator:用于在运行时动态创建对象实例,支持无参数和带参数构造函数。
  • 反射虽然非常强大,但会影响性能,因此在需要时使用,避免过度依赖。

专栏推荐

地址
【从零开始入门unity游戏开发之——C#篇】
【从零开始入门unity游戏开发之——unity篇】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架开发】

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

相关文章:

【从零开始入门unity游戏开发之——C#篇39】C#反射使用——Type 类、Assembly 类、Activator 类操作程序集

文章目录 前言一、前置知识1、编译器2、程序集(Assembly)3、元数据(Metadata) 二、反射1、反射的概念2、反射的作用3、反射的核心Type 类3.1 Type 类介绍3.2 不同方法获取 Type3.3 获取type类型所在的程序集的相关信息 4、反射的常…...

安卓触摸事件的传递

setOnTouchListener()返回值的副作用(触摸事件是否继续往下或往后传递)如下: 返回值效果是否往下层view传递是否往当前view的后续监听传递true该pointer离开屏幕前的后续所有触摸事件都会传递给该TouchListener否否false该pointer离开屏幕前…...

idea项目导入gitee 码云

1、安装gitee插件 IDEA 码云插件已由 gitosc 更名为 gitee。 1 在码云平台帮助文档http://git.mydoc.io/?t153739上介绍的很清楚,推荐前两种方法, 搜索码云插件的时候记得名字是gitee,gitosc已经搜不到了。 2、使用码云托管项目 如果之…...

典型常见的基于知识蒸馏的目标检测方法总结三

来源:Google学术2023-2024的顶会顶刊论文 NeurIPS 2022:Towards Efficient 3D Object Detection with Knowledge Distillation 为3D目标检测提出了一种知识蒸馏的Benchmark范式,包含feature的KD,Logit的cls和reg的KD&#xff0c…...

端口被占用

端口8080被占用 哈哈哈,我是因为后端项目跑错了,两个项目后端名称太像了; (1)netstat -aon | findstr 8080,找到占用8080端口的进程号,获取对应的进程号pid; (2&#…...

Javascript知识框架图(待完善)

以下是一个清晰且详细的 JavaScript 知识框架,涵盖基础知识到高级概念,适合学习和参考: JavaScript 知识框架 1. 基础知识 数据类型 原始类型:Number,String,Boolean,Null,Undefin…...

清华大学Python包镜像站点

清华大学提供了一个Python包镜像站点,其中包括了许多常用的Python包。使用这个镜像站点可以提高下载Python包时的速度,因为包已经存储在国内的服务器上,从而减少了网络延迟。 要使用清华的pip镜像,你可以在pip命令中指定-i参数来…...

逆境清醒文章总目录表

逆境清醒文章总目录表 零、时光宝盒🌻 (https://blog.csdn.net/weixin_69553582 逆境清醒) 《你的答案》歌曲原唱:阿冗,填 词:林晨阳、刘涛,谱曲:刘涛 也许世界就这样&#xff0c…...

LeetCode算法题——移除元素

题目描述 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作&#xff1…...

常见的中间件漏洞

1.Tomcat Tomcat介绍 tomcat是⼀个开源而且免费的jsp服务器,默认端口 : 8080,属于轻量级应⽤服务器。它可以实现 JavaWeb程序的装载,是配置JSP(Java Server Page)和JAVA系统必备的⼀款环境。 在历史上也披露出来了很…...

IPv6的过度技术

如何界定手动与自动?  主要是隧道目标地址能否自动获取 👯1. 双栈 必须支持IPv4和IPv6协议  链接双栈网络的接口必须同时配置v4和v6地址  路由器能够根据二层标记识别协议,type:0x0800代表IPV4,type:0x…...

Python用K-Means均值聚类、LRFMC模型对航空公司客户数据价值可视化分析指标应用|数据分享...

全文链接:https://tecdat.cn/?p38708 分析师:Yuling Fang 信息时代的来临使得企业营销焦点从产品中心转向客户中心,客户关系管理成为企业的核心问题(点击文末“阅读原文”获取完整代码数据)。 客户关系管理的关键是客…...

WebRTC的三大线程

WebRTC中的三个主要线程: signaling_thread,信号线程:用于与应用层交互worker_thread,工作线程(最核心):负责内部逻辑处理network_thread,网络线程:负责网络数据包的收发…...

Spring SpEL表达式由浅入深

标题 前言概述功能使用字面值对象属性和方法变量引用#this 和 #root变量获取类的类型调用对象(类)的方法调用类构造器类型转换运算符赋值运算符条件(关系)表达式三元表达式Elvis 操作符逻辑运算instanceof 和 正则表达式的匹配操作符 安全导航操作员数组集合(Array 、List、Map…...

数据设计规范

目录 一、数据库设计的原则 二、表设计原则 三、其他设计规范 四、最佳实践 数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据&#…...

基于SpringBoot的宠物寄养系统的设计与实现(源码+SQL+LW+部署讲解)

文章目录 摘 要1. 第1章 选题背景及研究意义1.1 选题背景1.2 研究意义1.3 论文结构安排 2. 第2章 相关开发技术2.1 前端技术2.2 后端技术2.3 数据库技术 3. 第3章 可行性及需求分析3.1 可行性分析3.2 系统需求分析 4. 第4章 系统概要设计4.1 系统功能模块设计4.2 数据库设计 5.…...

深度学习中的HTTP:从请求到响应的计算机网络交互

在现代深度学习应用中,HTTP(超文本传输协议)不仅仅是网页浏览的基础协议,它也在机器学习和人工智能的服务架构中扮演着至关重要的角色。本文将深入探讨HTTP在深度学习中的应用,并阐明它如何支持模型的训练、推理及API服…...

Agent系列:AppAgent v2-屏幕智能Agent(详解版)

引言 简介 方法 Agent 框架 Agent 交互 探索阶段 部署阶段 文档生成 高级功能 实验结果 总结 局限性 未来工作 1. 引言 大语言模型(LLM)如 ChatGPT 和 GPT-4 显著提升了自然语言处理能力,并且推动了智能体在自主决策中的应用。…...

艾体宝方案丨全面提升API安全:AccuKnox 接口漏洞预防与修复

一、API 安全:现代企业的必修课 在现代技术生态中,应用程序编程接口(API)扮演着不可或缺的角色。从数据共享到跨平台集成,API 成为连接企业系统与外部服务的桥梁。然而,伴随云计算的普及与微服务架构的流行…...

开源的Vue低代码表单设计器 form-create-designer v3.2.9 版本发布,新增10多种功能

form-create-designer 是一款开源的低代码表单设计器,通过数据驱动表单渲染。可以通过拖拽的方式快速创建表单,提高开发者对表单的开发效率,节省开发者的时间。并广泛应用于在政务系统、OA系统、ERP系统、电商系统、流程管理等领域。 项目采…...

Android Killer 无法调用jd-gui.exe

在Android Killer 时,点击图标转换为java代码时,调用jd-gui.exe 弹窗无法验证发布者,点击运行没反应 第一种方案:开启组策略(网上找的,没有效果) 键盘WinR ,在弹出窗口中输入gped…...

24.01.01 MyBatis

对sql拆分简化之后,更适合使用MyBatisPlus 搭建项目 引入依赖 <!--Mysql 驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--Druid数据库连接池--><dependenc…...

游戏引擎学习第70天

这一节没讲什么主要是关于接下来要干的任务 开发过程概览 我们正在进行最后的总结&#xff0c;并计划接下来的步骤。目前的目标是创建一个包含所有必要组件的游戏引擎原型版本&#xff0c;目的是让这些部分能够协同工作并展现预期效果。通过这一过程&#xff0c;可以实验和探…...

深入理解 Spring Cloud 中的 Eureka、Ribbon 和 Feign

1.eureka自我保护机制是什么? Eureka的自我保护机制是一种针对网络异常情况的安全保护措施&#xff0c;旨在防止因为网络问题导致的服务注册中心&#xff08;Eureka Server&#xff09;与微服务实例之间的通信故障。当网络分区或其他形式的网络故障发生时&#xff0c;即使微服…...

DVWA靶场Brute Force (暴力破解) 漏洞low(低),medium(中等),high(高),impossible(不可能的)所有级别通关教程

目录 暴力破解low方法1方法2 mediumhighimpossible 暴力破解 暴力破解是一种尝试通过穷尽所有可能的选项来获取密码、密钥或其他安全凭证的攻击方法。它是一种简单但通常无效率的破解技术&#xff0c;适用于密码强度较弱的环境或当攻击者没有其他信息可供利用时。暴力破解的基…...

山高路陡,无人机代替滑轨吊运物资极大提高做作业效率降低成本

在山高路陡的地区&#xff0c;无人机代替传统的滑轨吊运物资&#xff0c;极大地提高了作业效率并降低了成本。以下是对这一现象的详细分析&#xff1a; 一、无人机吊运的优势 1. 提高作业效率&#xff1a; 无人机能够快速响应并执行吊运任务&#xff0c;尤其在高山、陡峭或交…...

数据的高级处理——pandas模块进阶——数据的统计运算

今天的学习用有好几处与书上的内容有出入&#xff0c;不只是因为pycharm中函数更新、弃用的问题&#xff0c;还是作者有些疏忽。不过影响不大&#xff0c;运行报错&#xff0c;GPT分析一下&#xff0c;原因很简单。这里不进行详细书名&#xff0c;在下边的代码上已经进行详细的…...

【Leetcode】3280. 将日期转换为二进制表示

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个字符串 date&#xff0c;它的格式为 yyyy-mm-dd&#xff0c;表示一个公历日期。 date 可以重写为二进制表示&#xff0c;只需要将年、月、日分别转换为对应的二进制表示&a…...

Vue3 中自定义hook

什么是hook&#xff1f;—— 本质是一个函数&#xff0c;把setup函数中使用的Composition API进行了封装&#xff0c;类似于vue2.x中的mixin。 自定义hook的优势&#xff1a;复用代码, 让setup中的逻辑更清楚易懂。 场景需求&#xff1a;现在我需要获取当前鼠标所点击的地方的…...

嵌入式系统 第七讲 ARM-Linux内核

• 7.1 ARM-Linux内核简介 • 内核&#xff1a;是一个操作系统的核心。是基于硬件的第一层软件扩充&#xff0c; 提供操作系统的最基本的功能&#xff0c;是操作系统工作的基础&#xff0c;它负责管理系统的进程、内存、设备驱动程序、文件和网络系统&#xff0c; 决定着系统的…...