反射、枚举以及lambda表达式

1. 反射

1.1 定义

java的.class文件在运行时会被编译为一个Class对象,既然是对象,那么我们就可以通过一定的方式取到这个对象,然后对于这个对象进行一系列操作(改变原本类的属性、方法)。

这个操作就是反射,反射会像一面照妖镜一样,将所有的类“照”出来,不管它是否是private的还是protected,都可以进行访问、创建、修改。

反射的一系列操作都是动态的。

1.2 用途(了解)

  1. 在日常的第三方应用开发中,经常有某个属性或者方法只对于系统进行开放,这时可以利用反射进行获取。
  2. 开发各种通用框架也可以用到。

1.3 反射出的基本信息

java程序中许多对象在运行时会出现两种类型:运行时类型(RTTI)和编译时类型,例如Person p = new Student();这句代码中p在编译时类型为Person,运行时类型为Student。程序需要在运行时发现对象和类的真实 信息。而通过使用反射程序就能判断出该对象和类属于哪些类。

1.4 反射相关的类(重要)

说明
Class类代表类的实体,在运行的java程序中表示类和接口
Field类代表类的成员变量
Constructor类代表类的构造方法
Method类代表类的方法

1.5 获得Class对象的三种方式

package ReflectDemo;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class ReflectDemo {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, ClassNotFoundException {// 方式1Class<?> student1 = Student.class;// 方式2Class<?> student2 = Class.forName("ReflectDemo.Student");// 方式3Student studentTmp = new Student("",1);Class<?> student3 = studentTmp.getClass();// 验证是不是同一个Class对象System.out.println(student1 == student2);System.out.println(student1 == student3);}
}

三种方式:

  1. 使用 “对象名.class” 进行获得
  2. 使用 "Class.forName(“类的路径”)"进行获得
  3. 使用 “已经构造出来的对象.getClass()” 进行获得

只有一个Class对象的原因:
在这里插入图片描述

所以通过反射只能得到同一个Class对象。

1.6 反射的使用——Class类中的相关方法(重要)

出现Declared就能够获取私有变量/方法。

1.6.1 常用获得类相关的方法

方法说明
getClassLoader()获得类的加载器
getDeclaredClass()返回一个数组,数组中包含该类中所有类和接口类的对象(包括私有的
forName(String className)根据类名返回类的对象
getName()获得类的完整路径名字

创建的Person测试类(包含public、private内部类,接口,各种属性):

package ReflectDemo;public class Person implements Comparable<Person>{public String name;private int id;private int age;@Overridepublic int compareTo(Person o) {return o.age - this.age;}interface interfaceTest{};public class PublicInnerClass {}private class PrivateInnerClass {}public Person(String name, int id) {this.name = name;this.id = id;}}

测试代码:

package ReflectDemo;import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;public class ReflectTest {public static void main(String[] args) {Class<?> cls;try {cls = Class.forName("ReflectDemo.Person");/*// 获取Person类内部的public类、接口,返回一个数组Class<?>[] classes = cls.getClasses();*/// 获取Person类内部的包括private的类、接口,返回一个数组Class<?>[] classes = cls.getDeclaredClasses();System.out.println(Arrays.toString(classes));System.out.println(Person.class.getName());}catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.6.2 (重要)常用获得类属性的方法(以下与Field相关)

方法说明
getField(String name)获得某个公有属性(参数为属性名称)
getFields()获得所有公共属性(返回值为Fields数组)
getDeclaredField(String name)获得某个属性(参数为属性名称、不分权限)
getDeclaredFields()获得某个属性(返回值为Fields数组、不分权限)

示例代码:

package ReflectDemo;import java.lang.reflect.Field;
import java.util.Arrays;public class ReflectDemo3 {public static void main(String[] args) throws NoSuchFieldException {Class<?> personClass = Person.class;// 获得公有属性Field name = personClass.getField("name");Field[] fields = personClass.getFields();System.out.println("获得某个公有属性");System.out.println(name);System.out.println("获得所有公有属性");for (Field field : fields) {System.out.println(field);}System.out.println("获得某个属性(不分权限)");//获得某个属性(不分权限)System.out.println(personClass.getDeclaredField("id"));System.out.println("获得所有属性(不分权限)");// 获得所有属性(不分权限)System.out.println(Arrays.toString(personClass.getDeclaredFields()));}
}

运行结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.6.3 (了解)获得类中注解相关的方法

方法说明
getAnnotation(Class annotationClass)返回该类中与参数类型匹配的公有注解对象
getAnnotations()返回该类所有的公有注解对象
getDeclaredAnnotation(Class annotationClass)返回该类中与参数类型匹配的所有注解对象
getDeclaredAnnotations()返回该类所有的注解对象

1.6.4 (重要)获得类中构造器相关的方法(以下方法返回值为Constructor相关)

方法说明
getConstructor(Class… parameterTypes)获得该类中与参数类型匹配的公有构造方法
getConstructors()得该类的所有公有构造方法
getDeclaredConstructor(Class… parameterTypes)获得该类中与参数类型匹配的构造方法
getDeclaredConstructors()获得该类所有构造方法

代码:

package ReflectDemo;import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;public class ReflectDemo4 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class<?> personClass = Person.class;System.out.println("获得类中特定参数的公有构造方法");Constructor<?> personConstructor = personClass.getConstructor(String.class, int.class);System.out.println(personConstructor);System.out.println("使用特定参数的公有构造方法");System.out.println(personConstructor.newInstance("王五", 2023).toString());System.out.println("获得类中所有的公有构造方法");Constructor<?>[] personConstructors = personClass.getConstructors();System.out.println(Arrays.toString(personConstructors));System.out.println("获得类中所有的公有构造方法");Constructor<?>[] personConstructors2 = personClass.getDeclaredConstructors();System.out.println(Arrays.toString(personConstructors2));System.out.println("获得类中特定参数的、不分权限的构造方法");Constructor<?> personConstructor2 = personClass.getDeclaredConstructor(String.class);personConstructor2.setAccessible(true);// 必须设置为true,确认对这个私有方法进行操作System.out.println(personConstructor2);System.out.println(personConstructor2.newInstance("老六").toString());}
}

运行结果:
在这里插入图片描述

1.6.5 (重要)获得类中方法相关的方法(以下方法返回值为Method相关)

方法获取到后,需要使用invoke进行调用,第一个参数是这个方法作用的对象,后面的参数是要传到函数中的参数。

方法说明
getMethod(String name, Class… parameterTypes)获得该类某个公有的方法
getMethods()获得该类所有公有的方法
getDeclaredMethod(String name, Class… parameterTypes)获得该类某个方法
getDeclaredMethods()获得该类所有方法
package ReflectDemo;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class ReflectDemo5 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class<?> personClass = Person.class;Constructor<?> perspnConstructor = personClass.getConstructor(String.class, int.class);Person p = (Person) perspnConstructor.newInstance("老七", 2023001);System.out.println(p.toString());Method setName = personClass.getMethod("setName", String.class);p.setName("老八");System.out.println(p.toString());Method eat = personClass.getMethod("eat");eat.invoke(p);// 无参函数调用Method swim = personClass.getDeclaredMethod("swim");swim.setAccessible(true);// 确认修改访问权限swim.invoke(p);}
}

运行结果:
在这里插入图片描述

1.5 反射优点和缺点

优点:

  1. 能够获取本来访问受限的属性、方法。
  2. 增强了程序的灵活性,降低耦合度
  3. 已经运用在了很多流行的框架上,如:Struts、Hibernate、Spring 等等。

缺点:

  1. 使用反射的代码效率较低。
  2. 破坏程序封装性。
  3. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 。

1.6 重要总结

  1. 反射的意义

意义在于获取一些只对于系统开放的、不让外界看到的方法、属性。

  1. 反射的重要类:

Field类,Constructor类,Method类,Class类。

  1. 合理利用反射,不要轻易使用。

2. 枚举

将一组常量组织起来,同c语言的枚举相同,已经定义好的枚举中,常量就代表这个符号,这个符号也代表常量。

场景:错误状态码,消息类型,颜色的划分,状态机等等。

本质:继承自Enum这个类。(如同所有的对象都继承自Object类一样,都是隐式继承)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.1 常用方法

方法说明
values()获得枚举类中所有的成员
ordinal()获得成员在枚举类中的索引位置
name()获得枚举成员的名称
valueOf()将普通字符串转换为枚举实例
compareTo()返回成员在定义时的顺序(将索引位置进行相减)

代码:

package EnumDemo;public class Demo2 {public static void main(String[] args) {Color[] color = Color.values();for (Color color1 : color) {// ordinal的编号改变不了,这是枚举成员在类中的索引位置System.out.println(color1.ordinal() +" "+ color1.name());}// 将编号与name联系起来System.out.println(Color.getEnumKey(4));Color red = Color.RED;Color blue = Color.BLUE;System.out.println(red.compareTo(blue));// 索引位置相减}
}

运行结果:
在这里插入图片描述

枚举的构造方法默认是私有的!所以还可以在枚举类中加上自己定义的构造函数,直接在成员后面进行初始化。

package EnumDemo;public enum Color {RED(4,"红色"),GREEN(5,"绿色"),BLUE(6,"蓝色");private int key;private String name;Color(int key, String name) {this.key = key;this.name = name;}public static Color getEnumKey(int key) {// 遍历整个枚举类看有没有keyfor (Color e : Color.values()) {if (key == e.key) {return e;}}return null;}// err,默认是私有的
//    public Color(int num, String color) {}
//    RED,GREEN,BLUE;
}

2.2 枚举的优缺点

优点:

  1. 统一组织,便于管理常量,优于final
  2. 简单安全
  3. 枚举类有内置方法,书写更优雅

缺点:

  1. 不可被继承,无法扩展

但是为单例模式提供了很好的思路。

2.3 枚举与反射

枚举既然安全性这么高,那么能不能通过反射获取到枚举类呢?做个实验验证一下。

package EnumDemo;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class Demo3 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class<?> enumClass = Color.class;Constructor<?> enumClassConstructor = enumClass.getDeclaredConstructor(int.class, String.class);enumClassConstructor.setAccessible(true);Color o = (Color) enumClassConstructor.newInstance(1, "黑色");System.out.println(o);}
}

运行结果:
在这里插入图片描述

报错提示我们并没有这个构造方法,但是我们的构造方法就是两个参数:

Color(int key, String name) {this.key = key;this.name = name;
}

是不是由于隐藏的super()?还需要参数给父类Enum进行初始化?

Enum类构造方法:

/*** Sole constructor.  Programmers cannot invoke this constructor.* It is for use by code emitted by the compiler in response to* enum type declarations.** @param name - The name of this enum constant, which is the identifier*               used to declare it.* @param ordinal - The ordinal of this enumeration constant (its position*         in the enum declaration, where the initial constant is assigned*         an ordinal of zero).*/
protected Enum(String name, int ordinal) {this.name = name;this.ordinal = ordinal;
}

插播:(在给出源码的时候,源码上的注解已经能够说明不能进行invoke构造了。)

确实,看来父类还需要两个参数进行构造,修改代码如下:

package EnumDemo;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class Demo3 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class<?> enumClass = Color.class;// 函数的参数需要有四个,前两个是父类进行使用,后两个才是自己写的本身的参数Constructor<?> enumClassConstructor = enumClass.getDeclaredConstructor(String.class, int.class,int.class, String.class);enumClassConstructor.setAccessible(true);Color o = (Color) enumClassConstructor.newInstance(1, "黑色");System.out.println(o);}
}

运行结果:
在这里插入图片描述

看来参数传正确也不能够调用,报错指出不能够使用反射进行获取。

然后再返回来看源码中的注释部分:

枚举的源码注释:

** Sole constructor. Programmers can not invoke this constructor.* ** It is for use by code emitted by the compiler in response to* *** enum type declarations.

唯一的构造器,程序员不能够激活这个构造器,它它供编译器在响应 enum类型声明时发出的代码使用。

newInstance()的源码

在这里插入图片描述

结论:

  1. 枚举类不能够使用反射获取实例。
  2. 枚举可以避免反射和序列化。
  3. 枚举简单安全、有内置函数、能够组织常量,便于管理,优于final

2.4 枚举与单例模式

package EnumDemo;enum SingleEnum {INSTANCE;public SingleEnum getInstance() {return INSTANCE;}
}
public class Demo4 {public static void main(String[] args) {SingleEnum singleEnum1 = SingleEnum.INSTANCE;SingleEnum singleEnum2 = SingleEnum.INSTANCE;System.out.println(singleEnum2 == singleEnum1);}
}

用枚举实现单例模式简单优雅。

3. lambda表达式

3.1 背景

Lambda表达式是java SE 8中一个重要的新特性。它能够简化匿名内部类(函数式接口)的代码量,只关注怎么执行这个代码,而不是无用的创建过程。

3.2 语法

基本原则要遵循:

  1. (parameters)->expresstion
  2. (parameters)->{statements;}

lambda表达式由三部分组成:

  1. parameters:参数部分,类似于普通方法当中的形参部分。

这里的参数可以明确声明,也可以省略,原则是:能推导出来,就能省略。

  1. 比如参数只有一个,那么可以省略类型,同时也可以省略小括号()
  2. 比如参数有多个,但是类型都一样,那么也可省略类型
  1. ->:lambda表达式的标志性语法结构,可以理解为,“被用于”

  2. 方法体:相当于普通方法的方法体,可以是表达式,也可以是代码块,同样,也可以省略。

可推导即可省略:

  1. 如果这个方法只有一个return语句,那么就可以省略return,省略{}

3.2.1 函数式接口

是一个内部仅含一个抽象方法的接口。

注解:@FunctionalInterface

3.3 使用

package LambdaDemo;public class demo1 {// 无返回值无参数@FunctionalInterfacepublic interface NoParameterNoReturn {void test();}//无返回值一个参数@FunctionalInterfaceinterface OneParameterNoReturn {void test(int a);}//无返回值多个参数@FunctionalInterfaceinterface MoreParameterNoReturn {void test(int a,int b);}//有返回值无参数@FunctionalInterfaceinterface NoParameterReturn {int test();}//有返回值一个参数@FunctionalInterfaceinterface OneParameterReturn {int test(int a);}//有返回值多参数@FunctionalInterfaceinterface MoreParameterReturn {int test(int a,int b);}public static void main(String[] args) {// 相当于已经覆写了这个接口的test方法NoParameterNoReturn a1 = ()-> System.out.println("无参数无返回值");a1.test();OneParameterNoReturn a2 = ((a)->{System.out.println("无返回值一个参数,参数为:" + a);});a2.test(1);MoreParameterNoReturn a3 = ((a,b) -> {System.out.println("无返回值多个参数,参数有:" + a + " "+ b);});a3.test(1,2);NoParameterReturn a4 = ()->{System.out.print("有返回值无参数,返回值为:");return 4;};System.out.println(a4.test());OneParameterReturn a5 = ((a)->{System.out.print("有返回值一个参数,参数为:" + a + "返回值为平方:");return a*a;});System.out.println(a5.test(5));MoreParameterReturn a6 = ((a,b)-> {System.out.print("有返回值多参数, 参数为:" + a +" "+ b+ "返回值为和:");return a+b;});System.out.println(a6.test(6, 7));}
}

运行结果:

在这里插入图片描述

3.3.1 精简规则

在这里插入图片描述

3.4 变量捕获

3.4.1 匿名内部类

匿名内部类就是没有名字的类,用过一次就用不了的类。比如创建线程的时候可以创建匿名内部类进行创建线程。举个例子:

package LambdaDemo;class Test{public void func() {System.out.println("未被重写的func()方法");}
}
public class Demo2 {public static void main(String[] args) {Test t = new Test(){public void func() {System.out.println("重写func()");}};t.func();Test t2 = new Test();t2.func();}
}

运行结果:
在这里插入图片描述

这里就是创建了一个匿名的Test类,直接对类中的func()方法进行重写。因为只想要利用一下Test类中的func()方法。

3.4.2 匿名内部类的变量捕获

package LambdaDemo;import javax.smartcardio.TerminalFactory;class Test{public void func() {System.out.println("未被重写的func()方法");}
}
public class Demo2 {public static void main(String[] args) {int a = 100;Test t = new Test(){public void func() {System.out.println("重写func()");
//                a = 99;// err, 不允许改变变量System.out.println("捕获到变量,值为:"+ a);}};t.func();}
}

结论:

  1. 匿名内部类中的捕获的变量必须是final,或者与final等价(未经修改的变量)。

3.4.4 Lambda的变量捕获

package LambdaDemo;@FunctionalInterface
interface Test2{abstract void func();
}public class Demo3 {public static void main(String[] args) {int a = 100;Test2 t = (()->{
//            a = 99;// errSystem.out.println("重写func()");System.out.println(a);});t.func();}
}

结论与匿名内部类相同,方法体中只能由final或者等价于final 的变量存在。

4. Lambda在集合当中的使用

4.1 Collection接口

forEach**() 方法源码:**

default void forEach(Consumer action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } 
}

该方法表示:对容器中的每个元素执行action指定的动作 。

使用示例:

package LambdaDemo;import java.util.ArrayList;
import java.util.function.Consumer;public class Demo4 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("a");list.add("b");list.add("c");list.add("d");list.forEach(new Consumer<String>() {@Overridepublic void accept(String s) {// 使用accept方法对 list 中每个元素执行相同的操作System.out.print(s + " ");}});System.out.println("\r\n使用lambda表达式改写后:");list.forEach((s)-> System.out.print(s + " "));}
}

运行结果:

在这里插入图片描述

4.2 List接口

sort()方法的源码

default void sort(Comparator<? super E> c) {Object[] a = this.toArray();Arrays.sort(a, (Comparator) c);ListIterator<E> i = this.listIterator();for (Object e : a) {i.next();i.set((E) e);}
}

该方法表示:对容器中的元素进行指定规则的排序。

使用示例:

package LambdaDemo;import ReflectDemo.Person;import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Consumer;public class Demo5 {public static void main(String[] args) {Person p1 = new Person("张三",2023);Person p2 = new Person("李四",2022);Person p3 = new Person("王五",2021);ArrayList<Person> list = new ArrayList<>();list.add(p1);list.add(p2);list.add(p3);list.sort(new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {return o1.getId() - o2.getId();}});list.forEach(new Consumer<Person>() {@Overridepublic void accept(Person person) {System.out.println(person);}});System.out.println();System.out.println("使用lambda表达式改写:");//int compare(T o1, T o2);list.sort((o1,o2)-> o1.getId() - o2.getId());//public void forEach(Consumer<? super E> action)list.forEach((p)-> System.out.println(p));}
}

运行结果:

在这里插入图片描述

4.3 Map接口

HashMap 的 forEach**()** 源码**:**

@Override
public void forEach(BiConsumer<? super K, ? super V> action) {Node<K,V>[] tab;if (action == null)throw new NullPointerException();if (size > 0 && (tab = table) != null) {int mc = modCount;for (int i = 0; i < tab.length; ++i) {for (Node<K,V> e = tab[i]; e != null; e = e.next)action.accept(e.key, e.value);}if (modCount != mc)throw new ConcurrentModificationException();}
}

使用示例:

package LambdaDemo;import java.util.HashMap;
import java.util.function.BiConsumer;public class Demo6 {public static void main(String[] args) {HashMap<String, Integer> map = new HashMap();map.put("张三",19);map.put("李四",22);map.put("王五",39);map.forEach(new BiConsumer() {@Overridepublic void accept(Object o1, Object o2) {System.out.println(o1 +":"+ o2 + "岁了");}});System.out.println("\r\n用lambda表达式改写:");map.forEach((o1,o2)->System.out.println(o1 +":"+ o2 + "岁了"));}
}

运行结果:
在这里插入图片描述

4.4 结论

优点:

  1. 代码简洁,开发迅速
  2. 方便函数式编程
  3. java引入lambda,方便了集合的一些操作
  4. 非常容易进行并行计算

缺点:

  1. 可读性极差
  2. 不容易调试
  3. 在非并行计算中,效率未必有普通for高

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/178126.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据仓库建模下篇

在实际业务中&#xff0c;给了我们一堆数据&#xff0c;我们怎么拿这些数据进行数仓建设呢&#xff0c;数仓工具箱作者根据自身多年的实际业务经验&#xff0c;给我们总结了如下四步。 数仓工具箱中的维度建模四步走&#xff1a; 维度建模四步走 这四步是环环相扣&#xff0c…

JOSEF 可调漏电继电器 RT-L1KS φ25mm 导轨或面板安装

RT-L系列可调漏电继电器&#xff08;以下简称继电器&#xff09;适用于交流电压至690V&#xff0c;频率为50Hz&#xff0c;电流至1500A及以下漏电继电器中性点接地电路中。 RT-L系列可调型漏电继电器 RT-L1K可调型漏电继电器 RT-L2K可调型漏电继电器 RT-L3K可调型漏电继电器…

Mybaits-plus的使用

MybatisPlus特性 润物无声&#xff1a; 只做增强不做改变&#xff0c;引入它不会对现有工程产生改变&#xff0c;如丝般顺滑。 效率至上 只需简单配置&#xff0c;即可快速进行单表CRUD操作&#xff0c;从而节省大量时间。 使用MybatisPlus依赖基本步骤 引入MybatisPlus依…

echarts点击事件

有这么个需求要点击叶片的时候跳转页面 代码&#xff1a;点击之后 报错了 解决办法 1、使用箭头函数&#xff08;箭头函数没有自己的 this&#xff0c;所以在箭头函数中使用 this 时&#xff0c;其指向与外层作用域相同。&#xff09;或者使用闭包来解决上下文的问题。 2、使…

微信可以添加多少好友?

不知道有没有小伙伴好奇&#xff0c;微信到底可以添加多少好友&#xff1f;正好这个话题也上热搜了&#xff0c;我们就来了解一下。 有网友表示&#xff0c;自己的微信好友数量有10004个&#xff0c;已经不能再添加新的微信好友了。 一个微信号&#xff0c;可以添加的好友上限…

初识Linux(2).妈妈再也不用担心我Linux找不到门了。

文章目录 前言 1.man指令&#xff08;重要&#xff09;&#xff1a;例如&#xff1a; 2.cp指令&#xff08;重要&#xff09;&#xff1a;例如&#xff1a;把123.txt复制到a目录中类似window如下操作&#xff1a; 3.mv例如&#xff1a;类似window如下操作&#xff1a; 4.nano例…

算法效率的度量

算法效率的度量通常是通过时间复杂度和空间复杂度来描述的。 一、时间复杂度 算法中所有语句的执行次数之和为T(n)&#xff0c;它是算法问题规模n的函数&#xff0c;时间复杂度主要分析T(n)的数量级。 分类 1. 最好时间复杂度&#xff1a;最好情况下&#xff0c;算法的时间…

山西临县“5·7”火灾事故调查报告公布,揭秘富维烟火报警系统

近日&#xff0c;山西临县“57”火灾事故调查报告震惊全国&#xff0c;提醒我们火灾防控的重要性。在这起悲剧中&#xff0c;我们深刻认识到&#xff0c;及时发现火灾并迅速应对至关重要。这不仅是对生命安全的保护&#xff0c;也是对财产损失的有效减少。而在这方面&#xff0…

sCrypt 现已支持各类主流前端框架

sCrypt 现已支持各类主流前端框架&#xff0c;包括&#xff1a; ReactNext.jsAngularSvelteVue 3.x or 2.x bundled with Vite or Webpack 通过在这些支持的前端框架中集成sCrypt开发环境&#xff0c;你可以直接在前端项目里访问合约实例和调用合约&#xff0c;方便用户使用Se…

UE5 - 虚幻引擎各模块流程图

来自虚幻官方的一些资料&#xff0c;分享一下&#xff1b; 一些模块的流程图&#xff0c;比如动画模块&#xff1a; 或角色相关流程&#xff1a; 由于图片比较大&#xff0c;上传到了网络&#xff0c;可自取&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1BQ2KiuP08c…

【JavaScript】alert的使用方法 | 超详细

alert作用效果 alert&#xff08;&#xff09;方法用于显示带有一条指定消息和一个确认的按钮的警告框。 alert使用方法 方法一&#xff1a;直接写在script标签内 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…

Docker Swarm总结+基础、集群搭建维护、安全以及集群容灾(1/5)

博主介绍&#xff1a;Java领域优质创作者,博客之星城市赛道TOP20、专注于前端流行技术框架、Java后端技术领域、项目实战运维以及GIS地理信息领域。 &#x1f345;文末获取源码下载地址&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb;…

线上异步任务突然不能回写100%

项目场景&#xff1a; 需求是一个作业&#xff0c;需要运行一组sql&#xff0c;所有sql运行完成&#xff0c;更新作业进度为100%&#xff0c;状态为完成。sql需要是在大数据平台&#xff0c;通过yarn调度&#xff0c;异步执行。 kafka监听每个sql的执行状态&#xff0c;所有sql…

vue el-table表格中每行上传文件(上传简历)操作

1、HTML中 <el-table :data"formInfo.userListDto" border stripe max-height"400"><el-table-column type"index" label"序号" width"50"> </el-table-column><el-table-column prop"realName&q…

自动化接口测试:Pytest让你轻松搞定!了解一般流程及方法

首先我们要明确&#xff0c;通常所接口测试其实就属于功能测试&#xff0c;主要校验接口是否实现预定的功能&#xff0c;虽然有些情况下可能还需要对接口进行性能测试、安全性测试。 在学习接口自动化测试之前&#xff0c;我们先来了解手工接口测试怎样进行。 URL组成 为了更…

灰度发布专题---2、Dubbo灰度发布

通过上面描述&#xff0c;我们理解了什么是灰度发布&#xff0c;接下来我们基于Dubbo实现灰度发布。Dubbo的灰度发布常见的方式有版本控制灰度发布、路由灰度发布、基于Apollo实现灰度发布&#xff0c;我们把这每种灰度发布都实现一次。 在学习Dubbo灰度发布之前&#xff0c;我…

5款最常用的Android测试框架(含代码示例)

前言 今天&#xff0c;我们就要说说5款最常用的Android测试框架&#xff0c;并且每个框架都给出了基本的代码示例。 在这我为大家准备了一份软件测试视频教程&#xff08;含面试、接口、自动化、性能测试等&#xff09;&#xff0c;就在下方&#xff0c;需要的可以直接去观看…

csdn博客编写技巧

随便记录一下csdn博客编写时候用的到技巧&#xff0c;以作备忘。 1. 表格 1.1 Markdown-Table-Generator 这个是csdn编辑器中&#xff0c;工具栏自带的表格用法。主要优点是比较直观&#xff0c;缺点是无法设置表格中行列的宽高。 用法&#xff1a; | 表头一 | 表头二 | |-…

分享错误代码0x8007007b的解决办法,有效解决错误代码0x8007007b

错误代码0x8007007b是Windows操作系统中常见的错误代码之一。出现这样的错误代码0x8007007b通常与许可证问题相关&#xff0c;并表示Windows无法激活或验证已安装的操作系统副本&#xff0c;导致应用程序不能正常运行。下面是关于错误代码0x8007007b的解决办法希望能帮助大家解…

Vue3-Pinia

Pinia是什么 Pinia是Vue的最新状态管理工具&#xff0c;是Vuex的替代品 比Vuex更大的优势在于&#xff1a; 1.提供更加简单的API&#xff08;去掉了mutation&#xff09; 2.提供符合&#xff0c;组合式风格的API&#xff08;和Vue3新语法统一&#xff09; 3.去掉了modules…