第十三章:Java反射机制
第十三章:Java反射机制
13.1:Java反射机制概述
-
Java Reflection
Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。 加载完类之后,在堆内存的方法区中就产生了一个
Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为: 反射。 -
Java反射机制研究及应用Java反射机制提供的功能- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时获取泛型信息
- 在运行时调用任意一个对象的成员变量和方法
- 在运行时处理注解
- 生成动态代理
- 反射相关的主要
APIjava.lang.Class: 代表一 个类java.lang.reflect.Method: 代表类的方法java.lang.reflect.Field: 代表类的成员变量java.lang.reflect.Constructor: 代表类的构造器
13.2:理解Class类并获取Class实例
-
Class类- 在
Object类中定义了以下的方法,此方法将被所有子类继承:public final Class getClass() - 以上的方法返回值的类型是一个
Class类,此类是Java反射的源头,实际上所谓反射从程序的运行结果来看也很好理解,即:可以通过对象反射求出类的名称。 - 对象照镜子后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,
JRE都为其保留一个不变的Class类型的对象。 - 一个
Class对象包含了特定某个结构(class/interface/enum/annotation/primitive type/void/[])的有关信息Class本身也是一个类Class对象只能由系统建立对象- 一个加载的类在
JVM中只会有一个Class实例 - 一个
Class对象对应的是一个加载到JVM中的一个.class文件 - 每个类的实例都会记得自己是由哪个
Class实例所生成 - 通过
Class可以完整地得到一个类中的所有被加载的结构 Class类是Reflection的根源,针对任何你想动态加载、运行的类,唯有先获得相应的Class对象
- 在
-
Class类的常用方法[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ACzORrcc-1678242636284)(图片\28.png)]
private String name; public int age;public Person(String name, int age) {this.name = name;this.age = age; } private Person(String name) {this.name = name; } public Person() {System.out.println("Person()"); }// 省略get/set方法 // 省略toString方法public void show(){System.out.println("你好,我是一个人"); } private String showNation(String nation){System.out.println("我的国籍是:" + nation);return nation; }Class clazz = Person.class; //1.通过反射,创建Person类的对象 Constructor cons = clazz.getConstructor(String.class,int.class); Object obj = cons.newInstance("Tom", 12); Person p = (Person) obj; System.out.println(p.toString()); //2.通过反射,调用对象指定的属性、方法 Field age = clazz.getDeclaredField("age"); age.set(p,10); System.out.println(p.toString()); //调用方法 Method show = clazz.getDeclaredMethod("show"); show.invoke(p); //通过反射,可以调用Person类的私有结构的 //调用私有的构造器 Constructor cons1 = clazz.getDeclaredConstructor(String.class); cons1.setAccessible(true); Person p1 = (Person) cons1.newInstance("Jerry"); System.out.println(p1); //调用私有的属性 Field name = clazz.getDeclaredField("name"); name.setAccessible(true); name.set(p1,"HanMeimei"); System.out.println(p1); //调用私有的方法 Method showNation = clazz.getDeclaredMethod("showNation", String.class); showNation.setAccessible(true); String nation = (String) showNation.invoke(p1,"中国"); System.out.println(nation); -
获取
Class类的实例//方式一:调用运行时类的属性:.class Class clazz1 = Person.class; System.out.println(clazz1); //方式二:通过运行时类的对象,调用getClass() Person p1 = new Person(); Class clazz2 = p1.getClass(); System.out.println(clazz2); //方式三:调用Class的静态方法:forName(String classPath) Class clazz3 = Class.forName("com.wang.java.Person"); System.out.println(clazz3); //方式四:使用类的加载器:ClassLoader ClassLoader classLoader = ReflectionTest.class.getClassLoader(); Class clazz4 = classLoader.loadClass("com.wang.java.Person"); System.out.println(clazz4);System.out.println(clazz1 == clazz2); // true System.out.println(clazz1 == clazz3); // true System.out.println(clazz1 == clazz4); // true -
哪些类型可以有
Class对象class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类。interface:接口[]:数组enum:枚举annotation:注解@interfaceprimitive type:基本数据类型void
Class c1 = Object.class; Class c2 = Comparable.class; Class c3 = String[].class; Class c4 = int[][].class; Class c5 = ElementType.class; Class c6 = Override.class; Class c7 = int.class; Class c8 = void.class; Class c9 = Class.class;int[] a = new int[10]; int[] b = new int[100]; Class c10 = a.getClass(); Class c11 = b.getClass(); // 只要数组的元素类型与维度一样,就是同一个Class System.out.println(c10 == c11); // true System.out.println(c4 == c11); // false
13.3:类的加载与ClassLoader的理解
-
类的加载过程
当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过如下三个步骤来对该类进行初始化。

- 加载:将
class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口(即引用地址)。所有需要访问和使用类数据只能通过这个Class对象。这个加载的过程需要类加载器参与。 - 链接:将
Java类的二进制代码合并到JVM的运行状态之中的过程。- 验证:确保加载的类信息符合JVM规范,例如:以
cafe开头,没有安全方面的问题 - 准备:正式为类变量(
static)分配内存并 设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配 - 解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程
- 验证:确保加载的类信息符合JVM规范,例如:以
- 初始化:
- 执行类构造器
<clinit>()方法的过程。类构造器<clinit>()方法是由编译期自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的。(类构造器是构造类信息的,不是构造该类对象的构造器)。 - 当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化
- 虚拟机会保证一个类的
<clinit>()方法在多线程环境中被正确加锁和同步
- 执行类构造器
- 加载:将
-
什么时候会发生类初始化
- 类 的主动引用 ( 一定会发生类的初始化 )
- 当虚拟机启动,先初始化main方法所在的类
- new一个类的对象
- 调用类的静态成员(除了final常量)和静态方法
- 使用java.lang.reflect包的方法对类进行反射调用
- 当初始化一个类,如果其父类没有被初始化,则先会初始化它的父类
- 类的被动引用 ( 不会发生类的初始化 )
- 当访问一个静态域时,只有真正声明这个域的类才会被初始化
- 当通过子类引用父类的静态变量,不会导致子类初始化
- 通过数组定义类引用,不会触发此类的初始化
- 引用常量不会触发此类的初始化(常量在链接阶段就存入调用类的常量池中了
- 当访问一个静态域时,只有真正声明这个域的类才会被初始化
- 类 的主动引用 ( 一定会发生类的初始化 )
-
类加载器的作用:
-
类加载的作用:将
class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口。 -
类缓存:标准的
JavaSE类加载器可以按要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间。不过JVM垃圾回收机制可以回收这些Class对象 -
类加载器作用是用来把类(class)装载进内存的。JVM 规范定义了如下类型的类的加载器。

//对于自定义类,使用系统类加载器进行加载 ClassLoader classLoader = ClassLoaderTest.class.getClassLoader(); System.out.println(classLoader); //调用系统类加载器的getParent():获取扩展类加载器 ClassLoader classLoader1 = classLoader.getParent(); System.out.println(classLoader1); //调用扩展类加载器的getParent():无法获取引导类加载器 //引导类加载器主要负责加载java的核心类库,无法加载自定义类的。 ClassLoader classLoader2 = classLoader1.getParent(); System.out.println(classLoader2);ClassLoader classLoader3 = String.class.getClassLoader(); System.out.println(classLoader3);
-
13.4:创建运行时类的对象
-
调用
Class对象的newInstance()方法- 类必须有一个无参数的构造器。
- 类的构造器的访问权限需要足够。
Class<Person> clazz = Person.class; Person obj = clazz.newInstance(); System.out.println(obj); -
**调用
Class类的getDeclaredConstructor(Class ...parameterTypes)**方法Class clazz = Person.class; Constructor con = clazz.getConstructor(String.class,Integer.class); Person p2 = (Person) con.newInstance("Peter",20); System.out.println(p2);
13.5:获取运行时类的完整结构
-
实现的全部接口
public Class<?>[] getInterfaces()
Class clazz = Person.class; Class[] interfaces = clazz.getInterfaces(); for(Class c : interfaces){System.out.println(c); } System.out.println(); //获取运行时类的父类实现的接口 Class[] interfaces1 = clazz.getSuperclass().getInterfaces(); for(Class c : interfaces1){System.out.println(c); } -
所继承的父类
public Class<? Super T> getSuperclass()
Class clazz = Person.class; Class superclass = clazz.getSuperclass(); System.out.println(superclass); -
全部构造器
public Constructor<T>[] getConstructors():返回Class对象所表示的类的所有public构造方法。public Constructor<T>[] getDeclaredConstructors():返回Class对象表示的类声明的所有构造方法。public int getModifiers(): 取得修饰符public String getName():取得方法名称public Class<?>[] getParameterTypes(): 取得参数的类型
Class clazz = Person.class; // getConstructors():获取当前运行时类中声明为public的构造器 Constructor[] constructors = clazz.getConstructors(); for(Constructor c : constructors){System.out.println(c); } System.out.println(); // getDeclaredConstructors():获取当前运行时类中声明的所有的构造器 Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); for(Constructor c : declaredConstructors){System.out.println(c); } -
全部的方法
public Method[] getDeclaredMethods():返回此Class对象所表示的类或接口的全部方法public Method[] getMethods():返回此Class对象所表示的类或接口的public的方法
Class clazz = Person.class; //getMethods():获取当前运行时类及其所有父类中声明为public权限的方法 Method[] methods = clazz.getMethods(); for(Method m : methods){System.out.println(m); } System.out.println(); //getDeclaredMethods():获取当前运行时类中声明的所有方法。(不包含父类中声明的方法) Method[] declaredMethods = clazz.getDeclaredMethods(); for(Method m : declaredMethods){System.out.println(m); }public Class<?> getReturnType():取得全部的返回值public Class<?>[] getParameterTypes():取得全部的参数public int getModifiers():取得修饰符public Class<?>[] getExceptionTypes():取得异常信息
Class clazz = Person.class; Method[] declaredMethods = clazz.getDeclaredMethods(); for(Method m : declaredMethods){//1.获取方法声明的注解Annotation[] annos = m.getAnnotations();for(Annotation a : annos){System.out.println(a);}//2.权限修饰符System.out.print(Modifier.toString(m.getModifiers()) + "\t");//3.返回值类型System.out.print(m.getReturnType().getName() + "\t");//4.方法名System.out.print(m.getName());System.out.print("(");//5.形参列表Class[] parameterTypes = m.getParameterTypes();if(!(parameterTypes == null && parameterTypes.length == 0)){for(int i = 0;i < parameterTypes.length;i++){if(i == parameterTypes.length - 1){System.out.print(parameterTypes[i].getName() + " args_" + i);break;}System.out.print(parameterTypes[i].getName() + " args_" + i + ",");}}System.out.print(")");//6.抛出的异常Class[] exceptionTypes = m.getExceptionTypes();if(exceptionTypes.length > 0){System.out.print("throws ");for(int i = 0;i < exceptionTypes.length;i++){if(i == exceptionTypes.length - 1){System.out.print(exceptionTypes[i].getName());break;}System.out.print(exceptionTypes[i].getName() + ",");}}System.out.println(); } -
全部的
Fieldpublic Field[] getFields():返回此Class对象所表示的类或接口的public的Field。public Field[] getDeclaredFields():返回此Class对象所表示的类或接口的全部Field。
Class clazz = Person.class; //获取属性结构 //getFields():获取当前运行时类及其父类中声明为public访问权限的属性 Field[] fields = clazz.getFields(); for(Field f : fields){System.out.println(f); } System.out.println(); //getDeclaredFields():获取当前运行时类中声明的所有属性。(不包含父类中声明的属性) Field[] declaredFields = clazz.getDeclaredFields(); for(Field f : declaredFields){System.out.println(f); }public int getModifiers(): 以整数形式返回此Field的修饰符public Class<?> getType(): 得到Field的属性类型public String getName(): 返回Field的名称
Class clazz = Person.class; Field[] declaredFields = clazz.getDeclaredFields(); for(Field f : declaredFields){//1.权限修饰符int modifier = f.getModifiers();System.out.print(Modifier.toString(modifier) + "\t");//2.数据类型Class type = f.getType();System.out.print(type.getName() + "\t");//3.变量名String fName = f.getName();System.out.print(fName);System.out.println(); } -
泛型相关
Type getGenericSuperclass():获取父类泛型类型
Class clazz = Person.class; Type genericSuperclass = clazz.getGenericSuperclass(); System.out.println(genericSuperclass);ParameterizedType:泛型类型getActualTypeArguments():获取实际的泛型类型参数数组
Class clazz = Person.class; Type genericSuperclass = clazz.getGenericSuperclass(); ParameterizedType paramType = (ParameterizedType) genericSuperclass; //获取泛型类型 Type[] actualTypeArguments = paramType.getActualTypeArguments(); // System.out.println(actualTypeArguments[0].getTypeName()); System.out.println(((Class)actualTypeArguments[0]).getName()); -
类所在的包
Package getPackage()
Class clazz = Person.class; Package pack = clazz.getPackage(); System.out.println(pack);
13.6:调用运行时类的指定结构
-
调用指定方法
通过反射,调用类中的方法,通过Method类完成。步骤:
- 通过
Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。 - 之后使用
Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。
Class clazz = Person.class; //创建运行时类的对象 Person p = (Person) clazz.newInstance(); Method show = clazz.getDeclaredMethod("show", String.class); //保证当前方法是可访问的 show.setAccessible(true); Object returnValue = show.invoke(p,"CHN"); System.out.println(returnValue); System.out.println("*************如何调用静态方法*****************"); Method showDesc = clazz.getDeclaredMethod("showDesc"); showDesc.setAccessible(true); //如果调用的运行时类中的方法没有返回值,则此invoke()返回null //Object returnVal = showDesc.invoke(null); Object returnVal = showDesc.invoke(Person.class); System.out.println(returnVal); - 通过
-
Object invoke(Object obj, Object … args)Object对应原方法的返回值,若原方法无返回值,此时返回null。- 若原方法若为静态方法,此时形参
Object obj可为null - 若原方法形参列表为空,则
Object[] args为null - 若原方法声明为private,则需要在调用此invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法。
-
调用指定属性
- 在反射机制中,可以直接通过
Field类操作类中的属性,通过Field类提供的set()和get()方法就可以完成设置和取得属性内容的操作 public Field getField(String name):返回此Class对象表示的类或接口的指定的public的Field。public Field getDeclaredField(String name):返回此Class对象表示的类或接口的指定的Field。public Object get(Object obj): 取得指定对象obj上此Field的属性内容public void set(Object obj,Object value):设置指定对象obj上此Field的属性内容
Class clazz = Person.class; //创建运行时类的对象 Person p = (Person) clazz.newInstance(); //1. getDeclaredField(String fieldName):获取运行时类中指定变量名的属性 Field name = clazz.getDeclaredField("name"); //2.保证当前属性是可访问的 name.setAccessible(true); //3.获取、设置指定对象的此属性值 name.set(p,"Tom"); System.out.println(name.get(p)); - 在反射机制中,可以直接通过
-
关于
setAccessible方法的使用-
Method和Field、Constructor对象都有setAccessible()方法。 -
setAccessible启动和禁用访问安全检查的开关。 -
参数值为
true则指示反射的对象在使用时应该取消Java语言访问检查。-
提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为
true。 -
使得原本无法访问的私有成员也可以访问
-
-
参数值为
false则指示反射的对象应该实施Java语言访问检查
-
13.7:动态代理
-
代理设计模式的原理
- 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
- 动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象
- 动态代理使用场合
- 调试
- 远程方法调用
- 动态代理相比于静态代理的优点
抽象角色中(接口)声明的所有方法都被转移到调用处理器一个集中的方法中处理,这样,我们可以更加灵活和统一的处理众多的方法
-
Java动态关代理相关API- Proxy :专门完成代理的操作类,是所有动态代理类的父类。通过此类为一个或多个接口动态地生成实现类。
- 提供用于创建动态代理类和动态代理对象的静态方法
static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces):创建一个动态代理类所对应的Class对象static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h):直接创建一个动态代理对象
-
静态代理
interface ClothFactory{void produceCloth(); }//代理类 class ProxyClothFactory implements ClothFactory{private ClothFactory factory;//用被代理类对象进行实例化public ProxyClothFactory(ClothFactory factory){this.factory = factory;}@Overridepublic void produceCloth() {System.out.println("代理工厂做一些准备工作");factory.produceCloth();System.out.println("代理工厂做一些后续的收尾工作");} }//被代理类 class NikeClothFactory implements ClothFactory{@Overridepublic void produceCloth() {System.out.println("Nike工厂生产一批运动服");} }public class StaticProxyTest {public static void main(String[] args) {//创建被代理类的对象ClothFactory nike = new NikeClothFactory();//创建代理类的对象ClothFactory proxyClothFactory = new ProxyClothFactory(nike);proxyClothFactory.produceCloth();} } -
动态代理
interface Human{String getBelief();void eat(String food); }//被代理类 class SuperMan implements Human{@Overridepublic String getBelief() {return "I believe I can fly!";}@Overridepublic void eat(String food) {System.out.println("我喜欢吃" + food);} }class HumanUtil{public void method1(){System.out.println("====================通用方法一====================");}public void method2(){System.out.println("====================通用方法二====================");} }class ProxyFactory{//调用此方法,返回一个代理类的对象。解决问题一public static Object getProxyInstance(Object obj){//obj:被代理类的对象MyInvocationHandler handler = new MyInvocationHandler();handler.bind(obj);return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler);} }class MyInvocationHandler implements InvocationHandler{private Object obj;//需要使用被代理类的对象进行赋值public void bind(Object obj){this.obj = obj;}//当我们通过代理类的对象,调用方法a时,就会自动的调用如下的方法:invoke()//将被代理类要执行的方法a的功能就声明在invoke()中@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {HumanUtil util = new HumanUtil();util.method1();//method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法//obj:被代理类的对象Object returnValue = method.invoke(obj,args);util.method2();//上述方法的返回值就作为当前类中的invoke()的返回值。return returnValue;} }public class ProxyTest {public static void main(String[] args) {SuperMan superMan = new SuperMan();//proxyInstance:代理类的对象Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);//当通过代理类对象调用方法时,会自动的调用被代理类中同名的方法String belief = proxyInstance.getBelief();System.out.println(belief);proxyInstance.eat("四川麻辣烫");System.out.println("*****************************");NikeClothFactory nikeClothFactory = new NikeClothFactory(); ClothFactory proxyClothFactory = (ClothFactory)ProxyFactory.getProxyInstance(nikeClothFactory);proxyClothFactory.produceCloth();} }
相关文章:
第十三章:Java反射机制
第十三章:Java反射机制 13.1:Java反射机制概述 Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。 加…...
iLok USB不识别怎么办?
我的iLok USB坏了吗? 我的iLok USB没有被系统或软件识别。 如果您的iLok USB未被识别,问题可能出在iLok USB、iLok软件或受保护的软件。 提示如果您使用USB集线器,请确保您使用正确的集线器电源适配器。排除硬件:将iLok USB直接插…...
【LeetCode与《代码随想录》】二叉树篇:做题笔记与总结-JavaScript版
文章目录代码随想录144. 二叉树的前序遍历94. 二叉树的中序遍历145. 二叉树的后序遍历102.二叉树的层序遍历226.翻转二叉树101. 对称二叉树104.二叉树的最大深度111.二叉树的最小深度222.完全二叉树的节点个数110.平衡二叉树257. 二叉树的所有路径404.左叶子之和513.找树左下角…...
机器人运动|浅谈Time Elastic Band算法
前言在自主移动机器人路径规划的学习与开发过程中,我接触到Time Elastic Band算法,并将该算法应用于实际机器人,用于机器人的局部路径规划。在此期间,我也阅读了部分论文、官方文档以及多位大佬的文章,在此对各位大佬的…...
【Linux】网络基础(1)
前言 相信没有网络就没有现在丰富的世界。本篇笔记记录我在Linux系统下学习网络基础部分知识,从关于网络的各种概念和关系开始讲起,逐步架构起对网络的认识,对网络编程相关的认知。 我的上一篇Linux文章呀~ 【Linux】网络套接字编程_柒海啦的…...
限流算法详解
限流是我们经常会碰到的东西,顾名思义就是限制流量。它能保证我们的系统不会被突然的流量打爆,保证系统的稳定运行。像我们生活中,地铁就会有很多护栏,弯弯绕绕的,这个就是一种限流。像我们抢茅台,肯定大部…...
Spark/Hive
Spark/HiveHive 原理Spark with HiveSparkSession Hive Metastorespark-sql CLI Hive MetastoreBeeline Spark Thrift ServerHive on SparkHive 擅长元数据管理Spark 擅长高效的分布式计算 Spark Hive 集成 : Hive on Spark : Hive 用 Spark 作为底层的计算引擎时Spark w…...
HashMap底层的实现原理(JDK8)
目录一、知识点回顾二、HashMap 的 put() 和 get() 的实现2.1 map.put(k, v) 实现原理2.2 map.get(k) 实现原理三、HashMap 的常见面试题3.1 为何随机增删、查询效率都很高?3.2 为什么放在 HashMap 集合 key 部分的元素需要重写 equals 方法?3.3 HashMap 的 key 为…...
操作系统-整理
进程 介绍 进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大&#…...
系统换行符的思考
各系统换行符 换行符,也即是回车换行,因为表示为Carriage-Return和Line-Feed。 回车用Return-Carrige表示,简写为CR,字符表示为\r。 换行用Line-Feed表示,简写为LF,字符表示为\n。 由于历史原因…...
Wwise集成到unreal
1、Wwise集成到Unreal 1.1 安装必要的软件 安装unreal 5.1;安装Audiokinetic Launcher;集成版本是Wwise 2021.1.12.7973。Audiokinetic Launcher下载地址: https://www.audiokinetic.com/zh/thank-you/launcher/windows/?refdownload&pl…...
前端秘籍之=>八股文经卷=>(原生Js篇)【持续更新中...】
大家好,最近想了想,打算总结归纳一版前端八股文经卷,给大家提供学习参考,如果帮助到大家,请大家,一键三连支持一下,你们的支持会激励我更加努力的更新更多有用的知识,博主先在这里谢…...
【Python安装配置教程】
Python由荷兰数学和计算机科学研究学会的吉多范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台…...
Spring-Retry失败重试
文章目录 重试的场景引入依赖启动类serviceController@Retryable参数@Recover注意事项重试的场景 1、网络波动需要,导致请求失败,需要重发。 2、发送消息失败,需要重发,重发失败要记录日志 … 引入依赖 <!-- spring-retry--> <dependency><groupId>or…...
【目标检测 DETR】通俗理解 End-to-End Object Detection with Transformers,值得一品。
文章目录DETR1. 亮点工作1.1 E to E1.2 self-attention1.3 引入位置嵌入向量1.4 消除了候选框生成阶段2. Set Prediction2.1 N个对象2.2 Hungarian algorithm3. 实例剖析4. 代码4.1 配置文件4.1.1 数据集的类别数4.1.2 训练集和验证集的路径4.1.3 图片的大小4.1.4 训练时的批量…...
项目ER图和资料
常用的数据类型 模型类 一对多 from app import db import datetimeclass BaseModel(db.Model):__abstract__ Truecreate_time db.Column(db.DateTime,defaultdatetime.datetime.now())update_time db.Column(db.DateTime,defaultdatetime.datetime.now())class Role(db.M…...
剑指 Offer 20. 表示数值的字符串(java+python)
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。 数值(按顺序)可以分成以下几个部分: 若干空格 一个 小数 或者 整数 (可选)一个 ‘e’ 或 ‘E’ ,后面跟着一个 整数…...
程序员的逆向思维
前要: 为什么你读不懂面试官提问的真实意图,导致很难把问题回答到面试官心坎上? 为什么在面试结束时,你只知道问薪资待遇,不知道如何高质量反问? 作为一名程序员,思维和技能是我们职场生涯中最重要的两个方面。有时候…...
吐血整理学习方法,2年多功能测试成功进阶自动化测试,月薪23k+......
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 测试进阶方向 测试进…...
mysql慢查询:pt-query-digest 分析
"某些SQL语句执行效率慢",这个问题总体上分为两类: 出现了慢查询语句某些查询语句没有使用索引 由于数据的写入量非常大,所以要想直接打开慢查询日志来查看到底哪些语句有问题几乎是不可能的,因为日志的刷新速度太快了…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
