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

单元测试、反射、注解、动态代理

🏡个人主页 :@ 守夜人st
🚀系列专栏:Java
…持续更新中敬请关注…
🙉博主简介:软件工程专业,在校学生,写博客是为了总结回顾一些所学知识点

目录

  • 单元测试、反射、注解、动态代理
    • 单元测试
      • 单元测试概述
      • 单元测试快速入门
      • 单元测试常用注解
    • 反射
      • 反射概述
      • 反射获取类对象
      • 反射获取成员变量
      • 反射获取方法
      • 反射的作用——绕过编译阶段为集合添加数据(泛型擦除)
      • 反射的作用——通用框架的底层原理
    • 注解
      • 注解概述
      • 自定义注解
      • 元注解
      • 注解解析
      • 注解的应用场景一:JUnit框架
    • 动态代理
      • 动态代理概述、快速入门
      • 动态代理的应用案例:做性能分析,代理的好处

单元测试、反射、注解、动态代理

单元测试

单元测试概述

单元测试就是针对最小的功能单位编写测试代码,Java程序最小功能单元是方法,因此,单元测试就是针对方法的测试,进而检查方法的正确性

我们平常采用的测试存在的弊端:

  • 只有一个main方法,如果一个方法的测试失败了,其他反复测试会受到影响

  • 无法得到测试的结果报告,需要程序员自己去观察测试是否成功

  • 无法实现自动化测试

JUnit单元测试框架:

  • JUnit是使用Java语言实现的单元测试框架,他是开源的,Java开发者都应当学习并使用JUnit编写单元测试

  • 此外,几乎所有的IDE工具都集成了JUnit,这样我们就直接可以在IDE中编写并运行JUnit单元测试

    JUnit优点:

    • JUnit可以灵活的选择执行哪些测试方法,可以一键执行全部测试方法
    • 可以生成全部方法的测试报告
    • 单元测试中的某个方法测试失败了,不影响其他测试方法的测试

单元测试快速入门

需求:使用单元测试进行业务方法预期结果、正确性测试的快速入门

  1. 将JUnit的jar包导入到项目中
  • IDEA通常整合好了JUnit框架,一般不需要导入
  • 如果IDEA没有整合好,需要自己手工导入JUnit的jar包到模块
  1. 编写测试方法:该方法必须是公共的无参数无返回值的非静态方法
  2. 在测试方法上使用@Test注解:标注该方法是一个测试方法
  3. 在测试方法中完成被测试方法的预期正确性测试
  4. 选中测试方法,选择“ 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类对象的三种方式:

  1. Class c1 = Class.forName(“全类名”);
  2. Class c2 = 类名.class;
  3. 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);}
}

在这里插入图片描述

反射的作用——通用框架的底层原理

需求:给你任意一个对象,在不清楚对象字段的情况下,可以把对象的字段名称和对应值存储到文件中去

  1. 定义一个方法,可以接收任意类对象
  2. 每次收到一个对象后,需要解析这个对象的全部成员变量名称。
  3. 这个对象可能是任意的,那么怎么样才可以知道这个对象的全部成员变量名称呢
  4. 使用反射获取对象的Class文件,然后获取全部成员变量信息
  5. 遍历全部成员变量信息,然后提取本成员变量在对象中的具体值
  6. 存入成员变量名称和值到文件中
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注解,就可以在启动时被触发执行

分析:

  1. 定义一个自定义注解MyTest,只能注解方法,存活范围是一直在
  2. 定义若干个方法,只要有@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提供了一个静态方法,用于为对象产生一个代理对象返回

动态代理的应用案例:做性能分析,代理的好处

需求:

模拟某企业用户管理业务,需包含用户登录,用户删除,用户查询功能,并统计每个功能的耗时

分析:

  1. 定义一个UserService表示用户业务接口,规定必须完成用户登录,用户删除,用户查询功能
  2. 定义一个UserServiceImpl实现UserService,并完成相关功能,且统计每个功能的耗时
  3. 定义测试类,创建实现类对象,调用方法
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();}
}

动态代理的优点:

  • 可以在不改变方法源码的情况下,实现对方法功能的增加,提高了代码的复用。
  • 简化了编程 工作、提高了开发效率、同时提高了软件系统的可扩展性
  • 可以为被代理对象的所有方法做代理
    • 非常的灵活,支持任意接口类型的实现类对象做代理,也可以直接为接口本身做代理

在这里插入图片描述

感觉不错的话,动手点个赞吧!

相关文章:

单元测试、反射、注解、动态代理

&#x1f3e1;个人主页 &#xff1a; 守夜人st &#x1f680;系列专栏&#xff1a;Java …持续更新中敬请关注… &#x1f649;博主简介&#xff1a;软件工程专业&#xff0c;在校学生&#xff0c;写博客是为了总结回顾一些所学知识点 目录单元测试、反射、注解、动态代理单元测…...

【数据结构】夯实基础|线性表刷题01

作者&#xff1a;努力学习的大一在校计算机专业学生&#xff0c;热爱学习和创作。目前在学习和分享&#xff1a;算法、数据结构、Java等相关知识。博主主页&#xff1a; 是瑶瑶子啦所属专栏: 【数据结构|刷题专栏】&#xff1a;该专栏专注于数据结构知识&#xff0c;持续更新&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操作系统上进行性能测试 &#xff08;1&#xff09;打开github上 UnixBench 地址&#xff0c;找到发布的tag &#xff08;2&#xff09;找到tar.gz包&#xff0c;右键复制链接 比如这里是 https://github.com/kdlucas/byte-unix…...

于Java8 Stream教程之collect()

目录 前言正文第一个小玩法 将集合通过Stream.collect() 转换成其他集合/数组&#xff1a;第二个小玩法 聚合&#xff08;求和、最小、最大、平均值、分组&#xff09;总结前言 本身我是一个比较偏向少使用Stream的人&#xff0c;因为调试比较不方便。 但是, 不得不说&#…...

Python

1、str 三个关键点&#xff1a; 正着数&#xff0c;0&#xff0c;1&#xff0c;2 反着数&#xff0c;0&#xff0c;-1&#xff0c;-2 str[a&#xff0c;b] 左闭右开 [a&#xff0c;b) str123456789 print(str) # 输出字符串 print(str[0:-1]) # 输…...

Spring框架中IOC和DI详解

Spring框架学习一—IOC和DI 来源黑马Spring课程&#xff0c;觉得挺好的 目录 文章目录Spring框架学习一---IOC和DI目录学习目标第一章 Spring概述1、为什么要学习spring&#xff1f;2、Spring概述【了解】【1】Spring是什么【2】Spring发展历程【3】Spring优势【4】Spring体系…...

本地快速搭建Kubernetes单机版实验环境(含问题解决方案)

Kubernetes是一个容器编排系统&#xff0c;用于自动化应用程序部署、扩展和管理。本指南将介绍Kubernetes的基础知识&#xff0c;包括基本概念、安装部署和基础用法。 一、什么是Kubernetes&#xff1f; Kubernetes是Google开发的开源项目&#xff0c;是一个容器编排系统&…...

FPGA控制DDS产生1CLK周期误差的分析(二)

前文简短的介绍了DDS的产生原理&#xff0c;其实相当的简单&#xff0c;所以也不需要多做解释&#xff0c;本文详细阐述一下在调试DDS的过程中所产生的一个bug 问题发现 正如上文所述&#xff0c;再用FPGA控制存储在rom中的波形信号输出之后&#xff0c;在上板之前&#xff0…...

这一次,吃了Redis的亏,也败给了GPT

关注【离心计划】&#xff0c;一起离开地球表面 背景 组内有一个系统中有一个延迟任务的需求&#xff0c;关于延迟任务常见的做法有时间轮、延迟MQ还有Redis Zset等方案&#xff0c;关于时间轮&#xff0c;这边小苏有一个大学时候做的demo&#xff1a; https://github.com/JA…...

第一章 信息化知识

1、信息是客观事物状态和运动特征的一种普遍形式&#xff0c;信息的概念存在两个基本的层次&#xff0c;即本体论层次和认识论层次&#xff1a; 本体论层次&#xff1a;就是事物的运动状态和状态变化方式的自我表述认识论层次&#xff1a;就是主体对于该事物的运动状态以及状态…...

如何用matlab工具箱训练一个SOM神经网络

本站原创文章&#xff0c;转载请说明来自《老饼讲解-BP神经网络》bp.bbbdata.com本文展示如何用matlab工具箱训练一个SOM神经网络的DEMO并讲解其中的代码含义和相关使用说明- 01.SOM神经网络DEMO代码 -- 本文说明 -下面&#xff0c;我们先随机初始化一些样本点&#xff0c;然后…...

音视频技术开发周刊 | 285

每周一期&#xff0c;纵览音视频技术领域的干货。新闻投稿&#xff1a;contributelivevideostack.com。GPT-4 Office全家桶发布谷歌前脚刚宣布AI工具整合进Workspace&#xff0c;微软后脚就急匆匆召开了发布会&#xff0c;人狠话不多地祭出了办公软件王炸——Microsoft 365 Cop…...

安装flume

flume最主要的作用就是实时读取服务器本地磁盘的数据&#xff0c;将数据写入到hdfs中架构&#xff1a;开始安装一&#xff0c;上传压缩包&#xff0c;解压并更名解压&#xff1a;[rootsiwen install]# tar -zxf apache-flume-1.9.0-bin.tar.gz -C ../soft/[rootsiwen install]#…...

为工作排好优先级

工作&#xff0c;是干不完的&#xff0c;因此我们需要分清轻重缓急&#xff0c;为它们划分优先级&#xff0c;这样才不至于让自己手忙脚乱。 给手头的事情排上正确的优先级&#xff0c;是一项很重要的工作能力。 优先级有很多考量&#xff0c;并不是简单的先来后到的线性时间…...

超专业解析!10分钟带你搞懂Linux中直接I/O原理

我们先看一张图&#xff1a; 这张图大体上描述了 Linux 系统上&#xff0c;应用程序对磁盘上的文件进行读写时&#xff0c;从上到下经历了哪些事情。 这篇文章就以这张图为基础&#xff0c;介绍 Linux 在 I/O 上做了哪些事情。 文件系统 什么是文件系统 文件系统&#xff0…...

【C++】面试101,用两个栈实现队列,包含min函数的栈,有效括号序列,滑动窗口的最大值,最小的K个数,倒置字符串,排序子序列,跳跃,数字三角形,蓝肽子序列

目录 1. 用两个栈实现队列 2.包含min函数的栈 3.有效括号序列 4.滑动窗口的最大值 5.最小的K个数 6.倒置字符串 7.排序子序列 8.数字三角形&#xff08;蓝桥杯&#xff0c;学习一个大佬的博客....&#xff09; 9.跳跃&#xff08;蓝桥杯&#xff09; 10.蓝肽子序列 1. 用…...

WPF 认识WPF

什么是WPF?WPF是Windows Presentation Foundation(Windows展示基础)简称&#xff0c;顾名思义是专门编写表示层的技术。WPF绚丽界面如下&#xff1a;GUI发展及WPF历史&#xff1f;Windows系统平台上从事图形用户界面GUI(Graphic User Interface)已经经历了多次换代&#xff0c…...

【建议收藏】PHP单例模式详解以及实际运用

PHP单例模式详解以及实际运用 什么是单例模式? 首先我们百度百科他怎么说? 单例模式&#xff0c;属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例&#xff08;根据需要&#xff0c;也有可能一个线程中属于单例&#xff0c;如&a…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

多元隐函数 偏导公式

我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式&#xff0c;给定一个隐函数关系&#xff1a; F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 &#x1f9e0; 目标&#xff1a; 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z​、 …...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...