单元测试、反射、注解、动态代理
🏡个人主页 :@ 守夜人st
🚀系列专栏:Java
…持续更新中敬请关注…
🙉博主简介:软件工程专业,在校学生,写博客是为了总结回顾一些所学知识点
目录
- 单元测试、反射、注解、动态代理
- 单元测试
- 单元测试概述
- 单元测试快速入门
- 单元测试常用注解
- 反射
- 反射概述
- 反射获取类对象
- 反射获取成员变量
- 反射获取方法
- 反射的作用——绕过编译阶段为集合添加数据(泛型擦除)
- 反射的作用——通用框架的底层原理
- 注解
- 注解概述
- 自定义注解
- 元注解
- 注解解析
- 注解的应用场景一:JUnit框架
- 动态代理
- 动态代理概述、快速入门
- 动态代理的应用案例:做性能分析,代理的好处
单元测试、反射、注解、动态代理
单元测试
单元测试概述
单元测试就是针对最小的功能单位编写测试代码,Java程序最小功能单元是方法,因此,单元测试就是针对方法的测试,进而检查方法的正确性
我们平常采用的测试存在的弊端:
只有一个main方法,如果一个方法的测试失败了,其他反复测试会受到影响
无法得到测试的结果报告,需要程序员自己去观察测试是否成功
无法实现自动化测试
JUnit单元测试框架:
JUnit是使用Java语言实现的单元测试框架,他是开源的,Java开发者都应当学习并使用JUnit编写单元测试
此外,几乎所有的IDE工具都集成了JUnit,这样我们就直接可以在IDE中编写并运行JUnit单元测试
JUnit优点:
- JUnit可以灵活的选择执行哪些测试方法,可以一键执行全部测试方法
- 可以生成全部方法的测试报告
- 单元测试中的某个方法测试失败了,不影响其他测试方法的测试
单元测试快速入门
需求:使用单元测试进行业务方法预期结果、正确性测试的快速入门
- 将JUnit的jar包导入到项目中
- IDEA通常整合好了JUnit框架,一般不需要导入
- 如果IDEA没有整合好,需要自己手工导入JUnit的jar包到模块
- 编写测试方法:该方法必须是公共的无参数无返回值的非静态方法
- 在测试方法上使用@Test注解:标注该方法是一个测试方法
- 在测试方法中完成被测试方法的预期正确性测试
- 选中测试方法,选择“ JUnit运行 ”,如果测试良好是绿色,测试失败是红色
package com.shouyeren.test;public class UserService {public String loginName(String loginName,String passWord){if ("admin".equals(loginName) && "123456".equals(passWord)){return "登录成功";}else {return "用户名或者密码不正确";}}public void selectNames(){System.out.println("查询所有用户名成功!");}
}
package com.shouyeren.test;import org.junit.Assert;
import org.junit.Test;public class TestUserService {@Testpublic void testLoginName(){UserService userService = new UserService();String rs = userService.loginName("admin","123456");Assert.assertEquals("您的登录业务功能可能出BUG","登录成功",rs);}@Testpublic void testSelectNames(){UserService userService = new UserService();userService.selectNames();}
}

单元测试常用注解
| 注解 | 说明(JUnit4) |
|---|---|
| @Test | 测试方法 |
| @Before | 用来修饰实例方法,该方法会在每一个测试方法执行之前执行一次 |
| @After | 用来修饰实例方法,该方法会在每一个测试方法执行之后执行一次 |
| @BeforeClass | 用来修饰静态方法,该方法会在所有测试方法执行之前执行一次 |
| @AfterClass | 用来修饰静态方法,该方法会在所有测试方法执行之后执行一次 |
- 开始执行的方法:初始化资源
- 执行完之后的方法:释放资源
反射
反射概述
反射是指对于任何一个Class类,在“运行的时候”都可以直接得到这个类的全部成分
构造器对象:Constructor
成员变量对象:Field
成员方法对象:Method
这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言的反射机制
反射的基本作用、关键?
- 反射是在运行时获取类的字节码文件对象,解析获得类中全部成分
- 反射的核心思想和关键就是:得到编译后的Class文件
反射获取类对象
获取Class类对象的三种方式:
- Class c1 = Class.forName(“全类名”);
- Class c2 = 类名.class;
- Class c3 = 对象.getClass();
Class类中用于获取构造器的方法
| 方法 | 说明 |
|---|---|
| Constructor<?>[ ] getConstructors() | 返回所有构造器对象的数组(只能拿public的) |
| Constructor<?>[ ] getDeclaredConstructors() | 返回所有构造器对象的数组 |
| Constructor<?>[ ] getConstructor(Class<?>…parmeterTypes) | 返回单个构造器对象(只能拿public的) |
| Constructor<?>[ ] getDeclaredConstructors(getConstructor(Class<?>…parmeterTypes) | 返回单个构造器对象 |
package com.shouyeren.reflect;import org.junit.Test;import java.lang.reflect.Constructor;public class TestStudent {/*** 获取类中的全部构造器对象(public)*/@Testpublic void getConstructors(){Class<Student> c = Student.class;Constructor[] constructors = c.getConstructors();for (Constructor constructor : constructors) {System.out.println(constructor.getName() + "==>" + constructor.getParameterCount());}}/*** 获取类中的全部构造器对象*/@Testpublic void getDeclaredConstructors(){Class<Student> c = Student.class;Constructor[] constructors = c.getDeclaredConstructors();for (Constructor constructor : constructors) {System.out.println(constructor.getName() + "==>" + constructor.getParameterCount());}}/*** 获取某个构造器对象(public)*/@Testpublic void getConstructor() throws NoSuchMethodException {Class<Student> c = Student.class;//可以添加参数Constructor cons = c.getConstructor(String.class,int.class);System.out.println(cons.getName() + "==>" + cons.getParameterCount());}/*** 获取某个构造器对象*/@Testpublic void getDeclaredConstructor() throws NoSuchMethodException {Class<Student> c = Student.class;//可以添加参数类型Constructor cons = c.getDeclaredConstructor();System.out.println(cons.getName() + "==>" + cons.getParameterCount());Constructor cons1 = c.getDeclaredConstructor(String.class,int.class);System.out.println(cons.getName() + "==>" + cons1.getParameterCount());}
}
package com.shouyeren.reflect;public class Student {private String name;private int age;private Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
使用反射技术获取构造器对象并使用
- 获取构造器的作用依然是初始化一个对象返回
| 符号 | 说明 |
|---|---|
| T newInstance(Object… initargs) | 根据指定的构造器创建对象 |
| public void setAccessible(boolean flag) | 设置为true,表示取消访问检查,进行暴力反射 |
package com.shouyeren.reflect;import org.junit.Test;import java.lang.reflect.Constructor;public class TestStudent1 {@Testpublic void getDeclaredConstructor() throws Exception {Class<Student> c = Student.class;//可以添加参数类型Constructor cons = c.getDeclaredConstructor();System.out.println(cons.getName() + "==>" + cons.getParameterCount());//私有构造器无法访问时,可以暴力反射cons.setAccessible(true);Student s = (Student) cons.newInstance();System.out.println(s);Constructor cons1 = c.getDeclaredConstructor(String.class,int.class);System.out.println(cons.getName() + "==>" + cons1.getParameterCount());Student s1 = (Student) cons1.newInstance("叶文洁", 58);System.out.println(s1.getName() + s1.getAge());}
}
反射获取成员变量
使用反射技术获取成员变量对象并使用
- 反射的第一步是先得到类对象,然后从类对象中获取类的成分对象
- Class类中用于获取成员变量的方法
| 方法 | 说明 |
|---|---|
| Field[] getFields() | 返回所有成员变量对象的数组(public) |
| Field[] getDeclaredFields() | 返回所有成员变量对象的数组 |
| Field[] getField(String name) | 返回单个成员变量对象(public) |
| Field[] getDeclaredField(String name) | 返回单个成员变量对象 |
package com.shouyeren.reflect;import org.junit.Test;import java.lang.reflect.Field;
/*** | Field[] getFields() | 返回所有成员变量对象的数组(**public**) |* | Field[] getDeclaredFields() | 返回所有成员变量对象的数组 |* | Field[] getField(String name) | 返回单个成员变量对象(**public**) |* | Field[] getDeclaredField(String name) | 返回单个成员变量对象 |*/
public class FieldDemo {/*** Field[] getDeclaredFields() | 返回所有成员变量对象的数组 |*/@Testpublic void getDeclaredFields(){//定位Class对象Class<Student> s = Student.class;//定位所有成员变量对象Field[] fields = s.getDeclaredFields();for (Field field : fields) {System.out.println(field.getName() + "==>" + field.getType());}}/*** Field[] getFields() | 返回所有成员变量对象的数组(**public**) |*/@Testpublic void getFields(){//定位Class对象Class<Student> s = Student.class;//定位所有成员变量对象Field[] fields = s.getFields();for (Field field : fields) {System.out.println(field.getName() + "==>" + field.getType());}}/*** Field[] getField(String name) | 返回单个成员变量对象(**public**)* @throws Exception*/@Testpublic void getField() throws Exception {//定位Class对象Class<Student> s = Student.class;//成员变量对象Field field = s.getField("schoolName");System.out.println(field.getName() + "==>" + field.getType());}/*** Field[] getDeclaredField(String name) | 返回单个成员变量对象 |* @throws Exception*/@Testpublic void getDeclaredField() throws Exception {//定位Class对象Class<Student> s = Student.class;//成员变量对象Field field = s.getDeclaredField("age"); //打开权限field.setAccessible(true);Student student = new Student("张三",20);//赋值field.set(student,18);//取值System.out.println(field.get(student));}}
反射获取方法
使用反射技术获取方法对象并使用
- 反射的第一步是先得到类对象,然后从类对象中获取类的成分对象
- Class类中用于获取成员方法的方法
| 方法 | 说明 |
|---|---|
| Method[ ] getMethods() | 返回所有成员方法对象的数组(public) |
| Method[ ] getDeclaredMethods() | 返回所有成员方法对象的数组 |
| Method[ ] getMethod() | 返回单个成员方法对象的数组(public) |
| Method[ ] getDeclaredMethod() | 返回单个指定成员方法对象的数组 |
反射的作用——绕过编译阶段为集合添加数据(泛型擦除)
反射是作用在运行时的技术,此时集合的泛型将不能产生约束了,此时是可以为集合存入其他任意类型的元素的
ArrayList<Integer> list = new ArrayList<>();
list.add(100);
list.add("字符串");//报错
泛型只是在编译阶段可以约束集合只能操作某种数据类型,在编译成Class文件进入运行阶段的时候,其真实类型都是ArrayList,泛型相当于被擦除了
package com.shouyeren.reflect;import java.lang.reflect.Method;
import java.util.ArrayList;public class ReflectDemo {public static void main(String[] args) throws Exception {ArrayList<Integer> list1 = new ArrayList<>();ArrayList<Integer> list2 = new ArrayList<>();System.out.println(list1.getClass() == list2.getClass());System.out.println("--------------------------------------");ArrayList<Integer> list3 = new ArrayList<>();list3.add(18);list3.add(20);//list3.add("字符串");Class c = list3.getClass();Method add = c.getDeclaredMethod("add", Object.class);boolean rs = (boolean) add.invoke(list3,"字符串");System.out.println(list3);System.out.println(rs);}
}

反射的作用——通用框架的底层原理
需求:给你任意一个对象,在不清楚对象字段的情况下,可以把对象的字段名称和对应值存储到文件中去
- 定义一个方法,可以接收任意类对象
- 每次收到一个对象后,需要解析这个对象的全部成员变量名称。
- 这个对象可能是任意的,那么怎么样才可以知道这个对象的全部成员变量名称呢
- 使用反射获取对象的Class文件,然后获取全部成员变量信息
- 遍历全部成员变量信息,然后提取本成员变量在对象中的具体值
- 存入成员变量名称和值到文件中
package com.shouyeren.reflect.framework;import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;public class MybatisUtil {/*** 保存任意类型的对象* @param obj*/public static void save(Object obj){try(PrintStream ps = new PrintStream(new FileOutputStream("src/data.txt",true))) {//获取这个对象的全部成员变量Class c = obj.getClass();ps.println("----------------" + c.getSimpleName() + "----------------");Field[] fields = c.getDeclaredFields();for (Field field : fields) {String name = field.getName();field.setAccessible(true);String value = field.get(obj) + "";ps.println(name + " = " + value);}} catch (Exception e) {e.printStackTrace();}}
}
package com.shouyeren.reflect.framework;/*** 提供一个通用框架,支持保存所有对象的具体信息*/
public class ReflectDemo {public static void main(String[] args) {Student student = new Student();student.setName("张三");student.setClassName("实验一班");student.setAge(20);student.setHobby("打球");student.setSex('男');MybatisUtil.save(student);Teacher teacher = new Teacher();teacher.setName("苍老师");teacher.setSex('女');teacher.setSalary(12000);MybatisUtil.save(teacher);}
}
反射的作用:
- 可以在运行阶段得到一个类的全部成分然后操作
- 可以破坏封装性
- 可以破坏泛型约束
- 更重要的用途是适合:做Java高级框架
注解
注解概述
Java注解(Annotation)又称Java标注,是JDK5.0引入的一种注释机制
Java语言中的类、构造器、方法、成员变量、参数等都可以被注解进行标注
例如:JUnit框架中,标记了注解@Test的方法就可以被当成测试方法执行
自定义注解
自定义注解格式:
public @interface 注解名称{public 属性类型 属性名() default 默认值;
}
特殊属性:
- value属性,如果只有一个value属性的情况下,使用value属性的时候可以省略value名称不写
- 但是如果有多个属性,且多个属性没有默认值,那么value名称是不能省略的
元注解
元注解就是注解的注解
元注解有两个:
- @Target:约束自定义注解只能在哪些地方使用
- @Retention:声明注解的生命周期
@Target:
- TYPE,类,接口
- FIELD,成员变量
- METHOD,成员方法
- PARAMETER,方法参数
- CONSTRUCTOR,构造器
- LOCAL_VARIABLE,局部变量
@Retention中可使用的值定义在RetentionPolicy枚举类中,常用值如下:
- SOURCE:注解只作用在源码阶段,生成的字节码文件中不存在
- CLASS:注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值
- RUNTIME:注释在源码阶段、字节码文件阶段,运行阶段(开发常用)
注解解析
注解的操作中经常需要进行解析,注解的解析就是判断是否存在注解,存在注解就解析出内容
与注解解析相关的接口:
- Annotation:注解的顶级接口,注解都是Annotation类型的对象
- AnnotatedElement:该接口定义了与注解解析相关的解析方法
注解解析的技巧:
- 注解在哪个成分上,就先拿哪个成分对象
- 比如注解作用成员方法,则要获得该成员方法对应的Method对象,再拿上面的注解
注解的应用场景一:JUnit框架
模拟JUnit框架
定义若干个方法,只要加了MyTest注解,就可以在启动时被触发执行
分析:
- 定义一个自定义注解MyTest,只能注解方法,存活范围是一直在
- 定义若干个方法,只要有@MyTest注解的方法就能在启动时被触发执行,没有该注解则不能执行
package com.shouyeren.annotation;import java.lang.annotation.*;@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {}
package com.shouyeren.annotation;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class AnnotationTest {@MyTestpublic void test1(){System.out.println("===test1===");}public void test2(){System.out.println("===test2===");}@MyTestpublic void test3(){System.out.println("===test3===");}public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {AnnotationTest test = new AnnotationTest();Class c = AnnotationTest.class;Method[] methods = c.getDeclaredMethods();for (Method method : methods) {if (method.isAnnotationPresent(MyTest.class)){method.invoke(test);}}}
}
动态代理
动态代理概述、快速入门
如何创建代理对象:
- Java中代理的代表类是:java.lang.reflect.Proxy
- Proxy提供了一个静态方法,用于为对象产生一个代理对象返回
动态代理的应用案例:做性能分析,代理的好处
需求:
模拟某企业用户管理业务,需包含用户登录,用户删除,用户查询功能,并统计每个功能的耗时
分析:
- 定义一个UserService表示用户业务接口,规定必须完成用户登录,用户删除,用户查询功能
- 定义一个UserServiceImpl实现UserService,并完成相关功能,且统计每个功能的耗时
- 定义测试类,创建实现类对象,调用方法
package com.shouyeren.proxy;public interface UserService {String login(String loginName,String passWord);void deleteUsers();String selectUsers();
}
package com.shouyeren.proxy;public class UserServiceImpl implements UserService{@Overridepublic String login(String loginName, String passWord) {String rs = "登录名和密码错误";if ("admin".equals(loginName) && "132456".equals(passWord)){rs = "登录成功";}try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}return rs;}@Overridepublic void deleteUsers() {System.out.println("正在删除用户数据。。。");try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}}@Overridepublic String selectUsers() {String rs = "正在查询10000个用户数据。。。";try {Thread.sleep(2500);} catch (Exception e) {e.printStackTrace();}return rs;}
}
package com.shouyeren.proxy;import java.lang.reflect.Proxy;public class ProxyUtil {public static UserService getProxy(UserService obj){return (UserService) Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(), (proxy, method, args) -> {long startTime = System.currentTimeMillis();Object rs = method.invoke(obj, args);long endTime = System.currentTimeMillis();System.out.println(method.getName() + "方法耗时:" + (endTime-startTime)/1000 + "S");return rs;});}
}
package com.shouyeren.proxy;public class Test {public static void main(String[] args) {UserService userService = ProxyUtil.getProxy(new UserServiceImpl());System.out.println(userService.login("admin", "132456"));System.out.println(userService.selectUsers());userService.deleteUsers();}
}
动态代理的优点:
- 可以在不改变方法源码的情况下,实现对方法功能的增加,提高了代码的复用。
- 简化了编程 工作、提高了开发效率、同时提高了软件系统的可扩展性
- 可以为被代理对象的所有方法做代理
- 非常的灵活,支持任意接口类型的实现类对象做代理,也可以直接为接口本身做代理

相关文章:
单元测试、反射、注解、动态代理
🏡个人主页 : 守夜人st 🚀系列专栏:Java …持续更新中敬请关注… 🙉博主简介:软件工程专业,在校学生,写博客是为了总结回顾一些所学知识点 目录单元测试、反射、注解、动态代理单元测…...
【数据结构】夯实基础|线性表刷题01
作者:努力学习的大一在校计算机专业学生,热爱学习和创作。目前在学习和分享:算法、数据结构、Java等相关知识。博主主页: 是瑶瑶子啦所属专栏: 【数据结构|刷题专栏】:该专栏专注于数据结构知识,持续更新&a…...
Java怎么实现几十万条数据插入(30万条数据插入MySQL仅需13秒)
本文主要讲述通过MyBatis、JDBC等做大数据量数据插入的案例和结果。 30万条数据插入插入数据库验证实体类、mapper和配置文件定义User实体mapper接口mapper.xml文件jdbc.propertiessqlMapConfig.xml不分批次直接梭哈循环逐条插入MyBatis实现插入30万条数据JDBC实现插入30万条数…...
java多线程之线程的六种状态
线程的六种状态(1) NEW(初始状态)(2) TERMINATED(终止状态 / 死亡状态)(3) RUNNABLE(运行时状态)(4) TIMED_WAITING(超时等待状态)(5) WAITING(等待状态)(6) BLOCK(阻塞状态)sleep和wait的区别:操作系统里的线程自身是有一个状态的,但是java Thread 是对系统线程的封装,把这里的…...
UnixBench----x86架构openEuler操作系统上进行性能测试
【原文链接】UnixBench----x86架构openEuler操作系统上进行性能测试 (1)打开github上 UnixBench 地址,找到发布的tag (2)找到tar.gz包,右键复制链接 比如这里是 https://github.com/kdlucas/byte-unix…...
于Java8 Stream教程之collect()
目录 前言正文第一个小玩法 将集合通过Stream.collect() 转换成其他集合/数组:第二个小玩法 聚合(求和、最小、最大、平均值、分组)总结前言 本身我是一个比较偏向少使用Stream的人,因为调试比较不方便。 但是, 不得不说&#…...
Python
1、str 三个关键点: 正着数,0,1,2 反着数,0,-1,-2 str[a,b] 左闭右开 [a,b) str123456789 print(str) # 输出字符串 print(str[0:-1]) # 输…...
Spring框架中IOC和DI详解
Spring框架学习一—IOC和DI 来源黑马Spring课程,觉得挺好的 目录 文章目录Spring框架学习一---IOC和DI目录学习目标第一章 Spring概述1、为什么要学习spring?2、Spring概述【了解】【1】Spring是什么【2】Spring发展历程【3】Spring优势【4】Spring体系…...
本地快速搭建Kubernetes单机版实验环境(含问题解决方案)
Kubernetes是一个容器编排系统,用于自动化应用程序部署、扩展和管理。本指南将介绍Kubernetes的基础知识,包括基本概念、安装部署和基础用法。 一、什么是Kubernetes? Kubernetes是Google开发的开源项目,是一个容器编排系统&…...
FPGA控制DDS产生1CLK周期误差的分析(二)
前文简短的介绍了DDS的产生原理,其实相当的简单,所以也不需要多做解释,本文详细阐述一下在调试DDS的过程中所产生的一个bug 问题发现 正如上文所述,再用FPGA控制存储在rom中的波形信号输出之后,在上板之前࿰…...
这一次,吃了Redis的亏,也败给了GPT
关注【离心计划】,一起离开地球表面 背景 组内有一个系统中有一个延迟任务的需求,关于延迟任务常见的做法有时间轮、延迟MQ还有Redis Zset等方案,关于时间轮,这边小苏有一个大学时候做的demo: https://github.com/JA…...
第一章 信息化知识
1、信息是客观事物状态和运动特征的一种普遍形式,信息的概念存在两个基本的层次,即本体论层次和认识论层次: 本体论层次:就是事物的运动状态和状态变化方式的自我表述认识论层次:就是主体对于该事物的运动状态以及状态…...
如何用matlab工具箱训练一个SOM神经网络
本站原创文章,转载请说明来自《老饼讲解-BP神经网络》bp.bbbdata.com本文展示如何用matlab工具箱训练一个SOM神经网络的DEMO并讲解其中的代码含义和相关使用说明- 01.SOM神经网络DEMO代码 -- 本文说明 -下面,我们先随机初始化一些样本点,然后…...
音视频技术开发周刊 | 285
每周一期,纵览音视频技术领域的干货。新闻投稿:contributelivevideostack.com。GPT-4 Office全家桶发布谷歌前脚刚宣布AI工具整合进Workspace,微软后脚就急匆匆召开了发布会,人狠话不多地祭出了办公软件王炸——Microsoft 365 Cop…...
安装flume
flume最主要的作用就是实时读取服务器本地磁盘的数据,将数据写入到hdfs中架构:开始安装一,上传压缩包,解压并更名解压:[rootsiwen install]# tar -zxf apache-flume-1.9.0-bin.tar.gz -C ../soft/[rootsiwen install]#…...
为工作排好优先级
工作,是干不完的,因此我们需要分清轻重缓急,为它们划分优先级,这样才不至于让自己手忙脚乱。 给手头的事情排上正确的优先级,是一项很重要的工作能力。 优先级有很多考量,并不是简单的先来后到的线性时间…...
超专业解析!10分钟带你搞懂Linux中直接I/O原理
我们先看一张图: 这张图大体上描述了 Linux 系统上,应用程序对磁盘上的文件进行读写时,从上到下经历了哪些事情。 这篇文章就以这张图为基础,介绍 Linux 在 I/O 上做了哪些事情。 文件系统 什么是文件系统 文件系统࿰…...
【C++】面试101,用两个栈实现队列,包含min函数的栈,有效括号序列,滑动窗口的最大值,最小的K个数,倒置字符串,排序子序列,跳跃,数字三角形,蓝肽子序列
目录 1. 用两个栈实现队列 2.包含min函数的栈 3.有效括号序列 4.滑动窗口的最大值 5.最小的K个数 6.倒置字符串 7.排序子序列 8.数字三角形(蓝桥杯,学习一个大佬的博客....) 9.跳跃(蓝桥杯) 10.蓝肽子序列 1. 用…...
WPF 认识WPF
什么是WPF?WPF是Windows Presentation Foundation(Windows展示基础)简称,顾名思义是专门编写表示层的技术。WPF绚丽界面如下:GUI发展及WPF历史?Windows系统平台上从事图形用户界面GUI(Graphic User Interface)已经经历了多次换代,…...
【建议收藏】PHP单例模式详解以及实际运用
PHP单例模式详解以及实际运用 什么是单例模式? 首先我们百度百科他怎么说? 单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如&a…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
