反射学习笔记

news2024/12/1 8:33:35

反射学习笔记

一、反射入门案例

  • 在反射中,万物皆对象,方法也是对象。
  • 反射可以在不修改源码的情况下,只需修改配置文件,就能实现功能的改变。

实体类

/**
 * 动物猫类
 */
public class Cat {
    private String name;

    public void hi(){
        System.out.println("hi "+name);
    }

    public void cry(){
        System.out.println(name+"喵喵喵...");
    }
}

re.properties配置文件

classfullpath=pers.jl.Cat
method=hi

反射demo

@SuppressWarnings({"all"})//抑制编译器的某些警告
public class ReflectionApplication {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        //读取配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src/main/resources/re.properties"));

        //从配置文件重读取属性
        String classfullpath = properties.getProperty("classfullpath").toString();
        String methodName = properties.getProperty("method").toString();


        System.out.println("=======================================");
        // 根据类名加载类
        Class cls = Class.forName(classfullpath);
        // 获得类的实例
        Object o = cls.newInstance();
        // 打印对象的运行类型
        System.out.println("对象的运行类型是:"+o.getClass());
        System.out.println("=======================================");
        // 根据方法名,获取类的方法对象
        Method method = cls.getMethod(methodName);
        // 通过方法对象实现调用方法
        method.invoke(o);
    }
}

二、反射机制

  • 反射机制允许程序在执行期间借助于ReflectionAPI取得任何类的内部信息(比如成员变量,构造器,成员方法等),并能操作对象的属性及方法。
  • 加载完类后,在堆中就产生了一个Class类型的对象,这个对象包含了类的完整结构信息,我们可以通过这个对象得到类的结构。这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以,形象的称之为:反射。
  • 三个阶段逻辑:一个类的源码编译之后生成字节码文件也就是Class文件,然后经过类加载器ClassLoader在堆中加载了一个Class类对象,包含类源码中所有的属性和方法等,并且都用数组存放,比如成员变量都放在一个Fidld[]数组中,方法都放在一个Method[]数组中,然后我们就可以使用这个Class类对象new一个该类对象并调用该对象的方法。由于类对象和Class类对象一一对应,所以在后续中我们也可以从类对象直到该类对象的Class类对象,然后就可以进行一系列的操作。
    在这里插入图片描述

反射相关类

  • java反射机制可以完成什么

    • 在运行时判断一个对象所属的类
    • 在运行时构造任意一个类的对象
    • 在运行时得到任意一个类所具有的成员变量和方法
    • 在运行时调用任意一个对象的成员变量和方法
    • 生成动态代理
  • 主要类

    • java.lang.Class:代表一个类,Class对象表示某个类加载后在堆中的对象
    • java.lang.reflect.Method:表示类的方法,Method对象标识某个类的方法
    • java.lang.reflect.Field:代表类的成员变量,Field对象标识某个类的成员变量
    • java.lang.reflect.Constructor:代表类的构造方法,Constructor对象表示构造器
  • getField()方法不能得到私有的属性。

  • 反射中,方法也好,成员变量也好,调用都是它们调用对象,反过来的,比如:成员变量.get(对象)就可以拿到成员变量的值。

System.out.println("=======================================");
Field field = cls.getField("age");
System.out.println("类中的成员变量年龄:"+field.get(o));

Constructor constructor = cls.getConstructor();
System.out.println("无参构造:"+constructor);

Constructor constructor1 = cls.getConstructor(String.class);
System.out.println("有参构造:"+constructor1);

反射调用优化

  • 反射的优缺点
    • 优点:可以动态的创建和使用对象(也是框架底层核心),使用灵活,没有反射机制,框架技术就失去底层支撑。
    • 缺点:使用反射基本是解释执行,对执行速度有影响。
  • 反射调用优化(轻微优化)
    • Method和Field、Constructor对象都有setAccessible()方法,setAccessible()的作用是启动和禁用访问安全检查的开关。
    • 参数值为true表示反射的对象在使用时取消访问检查,提高反射的效率。参数值为false则表示反射的对象执行访问检查。
  • 优化案例
/**
 * @author 鹿先生
 * @version 1.0
 * 测试反射调用的性能,和优化方案
 */
@SuppressWarnings({"all"})
public class Reflection2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //Field
        //Method
        //Constructor
        m1();//传统
        m2();//反射
        m3();//反射优化
    }

    //传统方法来调用 hi
    public static void m1() {
        Cat cat = new Cat();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 90; i++) {
            cat.hi();
        }
        long end = System.currentTimeMillis();
        System.out.println("m1() 耗时=" + (end - start));
    }

    //反射机制调用方法 hi
    public static void m2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class cls = Class.forName("pers.jl.Cat");
        Object o = cls.newInstance();
        Method hi = cls.getMethod("hi");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);//反射调用方法
        }
        long end = System.currentTimeMillis();
        System.out.println("m2() 耗时=" + (end - start));

    }

    //反射调用优化 + 关闭访问检查
    public static void m3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class cls = Class.forName("pers.jl.Cat");
        Object o = cls.newInstance();
        Method hi = cls.getMethod("hi");
        hi.setAccessible(true);//在反射调用方法时,取消访问检查
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);//反射调用方法
        }
        long end = System.currentTimeMillis();
        System.out.println("m3() 耗时=" + (end - start));
    }
}

注意:查看类图更加方便理解类之间的关系,ctrl + alt + p查看该类的父类。

三、Class类

Class类分析

  1. Class也是类,因此也继承Object类。
  2. Class类对象不是new出来的,而是系统创建的。
  3. 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次。
  4. 每个类的实例都会记得自己是由哪个Class实例所生成。
  5. 通过Class对象可以完整地得到一个类的完整结构,同各国一系列API。
  6. Class对象是存放在堆的。
  7. 类的字节码二进制数据,是放在方法区的(在堆中创建Class对象时,就会在方法区创建该类字节码的二进制数据,二者之间有一些关系),有的地方称为类的元素据(包括方法代码,变量名,方法名,访问权限等等)
  8. 可以通过获取Class类对象的hashcode值判断Class类对象是否是同一个。

常用方法

  • 注意方法调用,打印字段都是反过来的。
/**
 * 演示class类的一些常用方法
 */
@SuppressWarnings({"all"})
public class Reflection3 {
    public static void main(String[] args) throws Exception{

        //获取类名路径
        String classAllPath = "pers.jl.Car";
        // 1. 根据类名加载Class对象
        Class<?> cls = Class.forName(classAllPath);
        // 2. 输出cls
        System.out.println("Class对象类型:"+cls);// class pers.jl.Car
        System.out.println("Class对象的运行类型:"+cls.getClass());// class java.lang.Class
        // 3. 获取包名
        System.out.println("包名:"+cls.getPackage().getName());// pers.jl
        // 4. 获取全类名
        System.out.println("全类名:"+cls.getName());// pers.jl.Car
        // 5. 获取对象实例
        Car car = (Car) cls.newInstance();
        System.out.println("对象:"+car);// Car{brand='宝马', price=500000, color='红色'}
        // 6. 通过属性名获取对象属性(正常情况下智能获取共有属性)
        Field brand = cls.getField("brand");
        System.out.println("对象属性:"+brand.get(car));// 宝马
        // 7. 通过反射修改属性值
        brand.set(car,"奔驰");
        System.out.println("对象属性:"+brand.get(car));// 奔驰
        // 8. 获取对象中的所有属性
        System.out.println("=========对象中的所有属性=========");
        for (Field field : cls.getFields()) {
            System.out.println("属性名:"+field.getName());
        }
    }
}

四、获取Class类对象

  • 四种方法
    1. Class.forName(代码阶段/编译阶段)
    2. 类名.class,应用场景: 用于参数传递(Class类加载阶段)
    3. 对象.getClass(),应用场景,有对象实例(RunTime运行阶段)
    4. 通过类加载器(4种)来获取到类的 Class 对象(编译阶段与Class类加载阶段之间)
/**
 * 获取Class对象的六种方式()本质上只有四种
 */
public class Reflection4 {
    public static void main(String[] args) throws Exception {

        // 1. Class.forName(代码阶段/编译阶段)
        String classAllPath = "pers.jl.Car";
        Class<?> cls1 = Class.forName(classAllPath);
        System.out.println("方法一:"+cls1);

        // 2. 类名.class,应用场景: 用于参数传递(Class类加载阶段)
        Class<Car> cls2 = Car.class;
        System.out.println("方法二:"+cls2);

        // 3. 对象.getClass(),应用场景,有对象实例(RunTime运行阶段)
        Car car = new Car();
        Class<? extends Car> cls3 = car.getClass();
        System.out.println("方法三:"+cls3);

        // 4. 通过类加载器(4种)来获取到类的 Class 对象(编译阶段与Class类加载阶段之间)
        ClassLoader classLoader = car.getClass().getClassLoader();
        Class<?> cls4 = classLoader.loadClass(classAllPath);
        System.out.println("方法四:"+cls4);

        // 注:上述四种方法获取到的Class类对象都是同一个,因为堆中只会存放一个
        System.out.println("===============四种方法得到的Class类对象hashCode值=============");
        System.out.println(cls1.hashCode());
        System.out.println(cls2.hashCode());
        System.out.println(cls3.hashCode());
        System.out.println(cls4.hashCode());

        // 5. 基本数据(int,char,boolean,float,double,byte,long,short)按如下方式得到Class类对象
        System.out.println("===============直接打印基础数据类型的Class类对象=============");
        Class<Integer> integerClass = int.class;
        Class<Character> characterClass = char.class;
        Class<Double> doubleClass = double.class;
        System.out.println(integerClass);
        System.out.println(characterClass);
        System.out.println(doubleClass);

        // 6. 基本数据类型对应的包装类,可以通过.TYPE得到Class类对象
        System.out.println("===============直接打印基础数据类型的包装类的Class类对象=============");
        Class<Integer> type = Integer.TYPE;
        Class<Character> type1 = Character.TYPE;
        Class<Double> type2 = Double.TYPE;
        System.out.println(type);
        System.out.println(type1);
        System.out.println(type2);

        // 注:基础数据类型的Class类对象和包装类的Class类对象是同一个
        System.out.println("===============基础数据类型和包装类得到的Class类对象hashCode值=============");
        System.out.println(integerClass.hashCode());
        System.out.println(type.hashCode());
    }
}

五、哪些类型有Class类对象

如下类型有Class对象

  • 外部类,成员内部类,静态内部类,局部内部类,匿名内部类。
  • interface:接口
  • 数组
  • enum:枚举
  • annotation:注解
  • 基本数据类型
  • void
/**
 * 查看哪些类有Class对象
 */
@SuppressWarnings({"all"})
public class Reflection5 {
    public static void main(String[] args) {
        System.out.println("=====================打印这些Class类对象=======================");
        Class<String> cls1 = String.class;//外部类
        Class<Serializable> cls2 = Serializable.class;//接口
        Class<Integer[]> cls3 = Integer[].class;//数组
        Class<float[][]> cls4 = float[][].class;//二维数组
        Class<Deprecated> cls5 = Deprecated.class;//注解
        Class<Thread.State> cls6 = Thread.State.class;//枚举
        Class<Long> cls7 = long.class;//基础数据类型
        Class<Void> cls8 = void.class;//void数据类型
        System.out.println(cls1);
        System.out.println(cls2);
        System.out.println(cls3);
        System.out.println(cls4);
        System.out.println(cls5);
        System.out.println(cls6);
        System.out.println(cls7);
        System.out.println(cls8);
    }
}

六、类加载

基本说明

  • 反射机制是Java实现动态语言的关键,也就是通过反射实现类动态加载。

    • 静态加载:编译时加载相关的类,如果没有则报错,依赖性太强。

    • 动态加载(延时加载):运行时加载需要的类,如果运行时不使用该类,即使不存在该类,则不报错,降低了依赖性。

类加载时机

  1. 当创建对象时(new)
  2. 当子类被加载时,父类也被加载。
  3. 调用类中的静态成员时。
  4. 通过反射

:前三种都是静态加载,最后一种是动态加载。

类加载案例

/**
 * 类的静态加载和动态加载
 */
public class classloadtest {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入key:");
        String key = scanner.next();
        switch (key) {
            case "1":
                Dog dog = new Dog();
                dog.cry();
                break;
            case "2":
                Class<?> cls = Class.forName("pers.jl.Person");
                Object o = cls.newInstance();
                Method method = cls.getMethod("hi");
                method.invoke(o);
                System.out.println("ok");
                break;
            default:
                System.out.println("do nothing..");
                break;
        }
    }
}

//因为new Dog()是静态加载,没有编写Dog类,编译时就会报错
//Person类是动态加载,所以没有编写Person类也不会报错,只有动态加载该类时,才会报错
class Dog {
    public void cry() {
        System.out.println("小狗汪汪汪!");
    }
}

class Person {
    public void hi() {
        System.out.println("小孩,hi!");
    }
}

类加载过程图

在这里插入图片描述

类加载各阶段完成任务

在这里插入图片描述

七、通过反射获取类的结构信息

java.lang.Class类
getName;//获取全类名
getSimpleName;//获取简单类名
getFields;//获取所有public修饰的属性,包含本类以及父类的
getDeclaredFields;//获取本类中的所有属性
getMethods;//获取所有public修饰的方法,包含本类以及父类的
getDeclaredMthods;//获取本类中的所有方法
getConsructors;//获取本类所有public修饰的构造器
getDeclaredConstructors;//获取本类中的所有构造器
getPackage;//以Package形式返回包信息
getSuperClass;//以Class类形式返回父类信息
getInterfaces;//以Class[]形式返回接口信息
getAnnotations://Annotation[]形式返回注解信息
java.lang.reflect.Field类
getModifiers;//以int形式返回修饰符{默认修饰符是0,public是1,private是2,protected是4,static是8,final是0,public(1) + static(8) = 9}
getType;//以Class形式返回类型
getName;//返回属性名
java.lang.reflect.Method类
getModifiers;//以int形式返回修饰符{默认修饰符是0,public是1,private是2,protected是4,static是8,final是0,public(1) + static(8) = 9}
getReturnType;//以Class形式获取返回类型
getName;//返回方法名
getParameterTypes;//以Class[]返回参数类型数组
java.lang.reflect.Constructor类
getModifiers;//以int形式返回修饰符{默认修饰符是0,public是1,private是2,protected是4,static是8,final是0,public(1) + static(8) = 9}
getName;//返回构造器名
getParameterTypes;//以Class[]返回参数类型数组

八、通过反射创建对象

1.方式一:调用类中的public修饰的无参构造器
2.方式二:调用类中的指定构造器
3.Class类相关方法
  • newInstance:调用类中的无参构造器,获取对应类的对象。
  • getConstryctor(Class…clazz):根据参数列表,获取对应的public构造器对象
  • getDecalaredConstructoe(Class…clazz):根据参数列表,获取对应的所有构造器对象
4.Contructor类相关方法
  • setAccessible:爆破
  • newInstance(Object…obj):调用构造器
5. 代码案例
public class Reflection6 {
    public static void main(String[] args) throws Exception {

        //1. 先获取到 User 类的 Class 对象
        Class<?> userClass = Class.forName("pers.jl.User");
        //2. 通过 public 的无参构造器创建实例
        Object o = userClass.newInstance();
        System.out.println(o);
        //3. 通过 public 的有参构造器创建实例
        //3.1 先得到对应构造器
        Constructor<?> constructor = userClass.getConstructor(String.class);
        //3.2 创建实例,并传入实参
        Object hsp = constructor.newInstance("hsp");
        System.out.println("hsp=" + hsp);
        //4. 通过非 public 的有参构造器创建实例
        //4.1 得到 private 的构造器对象
        Constructor<?> constructor1 = userClass.getDeclaredConstructor(int.class, String.class);
        //4.2 创建实例
        //暴破【暴力破解】 , 使用反射可以访问 private 构造器/方法/属性, 反射面前,都是纸老虎
        constructor1.setAccessible(true);
        Object user2 = constructor1.newInstance(100, "张三丰");
        System.out.println("user2=" + user2);
    }
}

class User { //User 类
    private int age = 10;
    private String name = "韩顺平教育";

    public User() {//无参 public
    }

    public User(String name) {//public 的有参构造器
        this.name = name;
    }

    private User(int age, String name) {//private 有参构造器
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "User [age=" + age + ", name=" + name + "]";
    }
}

九、通过反射访问类中的成员

访问属性
  1. 根据属性名获取Field对象

    Fidle f = clazz对象.getDeclaredField(属性名);

  2. 暴破:f.setAccessible(true);//f是Field

  3. 访问

    f.set(o,值);//o表示对象

    syso(f.get(o));//o表示对象

:如果是静态属性,则set和get中的参数o,可以写成null

代码示例
public class Reflection {
    public static void main(String[] args) throws Exception {
        //1. 得到 Student 类对应的 Class 对象
        Class<?> stuClass = Class.forName("pers.jl.Student");
        //2. 创建对象
        Object o = stuClass.newInstance();//o 的运行类型就是 Student
        System.out.println(o.getClass());//Student
        //3. 使用反射得到 age 属性对象
        Field age = stuClass.getField("age");
        age.set(o, 88);//通过反射来操作属性
        System.out.println(o);//
        System.out.println(age.get(o));//返回 age 属性的值
        //4. 使用反射操作 name 属性
        Field name = stuClass.getDeclaredField("name");
        //对 name 进行暴破, 可以操作 private 属性
        name.setAccessible(true);
        //name.set(o, "老韩");
        name.set(null, "老韩~");//因为 name 是 static 属性,因此 o 也可以写出 null
        System.out.println(o);
        System.out.println(name.get(o)); //获取属性值
        System.out.println(name.get(null));//获取属性值, 要求 name 是 stati
    }
}

class Student {//类
    public int age;
    private static String name;

    public Student() {//构造器
    }
}
访问方法
  1. 根据方法名和参数列表获取Method方法对象:Method m = clazz.getDeclaredMethod(方法名,XX.class);//得到本类的所有方法
  2. 获取对象:Object o = clazz.newInstance();
  3. 暴破:m.setAccessible(true);
  4. 访问:Object returnValue = m.invoke(o,实参列表);//o就是对象

:如果是静态方法,则invoke的参数o,可以写成null!

代码示例
public class Reflection7 {
    public static void main(String[] args) throws Exception {
        //1. 得到 Boss 类对应的 Class 对象
        Class<?> bossCls = Class.forName("pers.jl.Boss");
        //2. 创建对象
        Object o = bossCls.newInstance();
        //3. 调用 public 的 hi 方法
        //3.1 得到 hi 方法对象
        Method hi = bossCls.getMethod("hi", String.class);//OK
        //3.2 调用
        hi.invoke(o, "韩顺平教育~");
        //4. 调用 private static 方法
        //4.1 得到 say 方法对象
        Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class);
        //4.2 因为 say 方法是 private, 所以需要暴破,原理和前面讲的构造器和属性一样
        say.setAccessible(true);
        System.out.println(say.invoke(o, 100, "张三", '男'));
        //4.3 因为 say 方法是 static 的,还可以这样调用 ,可以传入 null
        System.out.println(say.invoke(null, 200, "李四", '女'));
        //5. 在反射中,如果方法有返回值,统一返回 Object , 但是他运行类型和方法定义的返回类型一致
        Object reVal = say.invoke(null, 300, "王五", '男');
        System.out.println("reVal 的运行类型=" + reVal.getClass());//String
        //在演示一个返回的案例
        Method m1 = bossCls.getDeclaredMethod("m1");
        Object reVal2 = m1.invoke(o);
        System.out.println("reVal2 的运行类型=" + reVal2.getClass());//Monster
    }
}

class Monster {
}

class Boss {//类
    public int age;
    private static String name;

    public Boss() {//构造器
    }

    public Monster m1() {
        return new Monster();
    }

    private static String say(int n, String s, char c) {//静态方法
        return n + " " + s + " " + c;
    }

    public void hi(String s) {//普通 public 方法
        System.out.println("hi " + s);
    }
}

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

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

相关文章

openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化:x86

文章目录 openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化&#xff1a;x8684.1 BIOS84.2 操作系统环境设置84.3 网络 openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化&#xff1a;x86 …

大学各个专业介绍

计算机类 五米高考-计算机类 注&#xff1a;此处平均薪酬为毕业五年平均薪酬&#xff0c;薪酬数据仅供参考 来源&#xff1a; 掌上高考 电气类 五米高考-电气类 机械类 五米高考-机械类 电子信息类 五米高考-电子信息类 土木类 五米高考-土木类

Cloudflare进阶技巧:缓存利用最大化

1. 引言 cloudflare我想你应该知道是什么&#xff0c;一家真正意义上免费无限量的CDN&#xff0c;至今未曾有哥们喷它的。当然&#xff0c;在国内的速度确实比较一般&#xff0c;不过这也不能怪它。 CDN最大的特色&#xff0c;我想就是它的缓存功能&#xff0c;达到防攻击&am…

【数据结构】归并排序、基数排序算法的学习知识点总结

目录 1、归并排序 1.1 算法思想 1.2 代码实现 1.3 例题分析 2、基数排序 2.1 算法思想 2.2 代码实现 2.3 例题分析 1、归并排序 1.1 算法思想 归并排序是一种采用分治思想的经典排序算法&#xff0c;通过将待排序数组分成若干个子序列&#xff0c;将每个子序列排序&#xff…

安卓玩机-----给app加注册码 app加弹窗 云注入弹窗

在对接很多工作室业务中有些客户需要在他们自带的有些app中加注册码或者验证码的需求。其实操作起来也很简单。很多反编译软件有自带的注入功能。例如注入弹窗。这个是需要对应的注册码来启动应用。而且是随机id。重新安装app后需要重新注册才可以继续使用&#xff0c;原则上可…

Ubuntu 20.04部署Promethues

sudo lsb_release -r可以看到操作系统版本是20.04&#xff0c;sudo uname -r可以看到内核版本是5.5.19。 sudo wget -c https://github.com/prometheus/prometheus/releases/download/v2.37.1/prometheus-2.37.1.linux-amd64.tar.gz下载必要的组件。 tar -zxf prometheus-2.…

python对RabbitMQ的简单使用

原文链接&#xff1a;https://blog.csdn.net/weixin_43810267/article/details/123914324 RabbitMq 是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理中间件。消息队列是一种应用程序对应用程序的通行方式&#xff0c;应用程序通过写消息&#xff0c;将消…

日常学习之:如何基于 OpenAI 构建自己的向量数据库

文章目录 原理前期准备依赖安装Pinecone 数据库注册Index 创建&#xff08;相当于传统数据库中的创建 table&#xff09; 基于 pinecone 数据库的代码实现尝试用 OpenAI 的 API 构建 embedding将示例的数据 embedding 后写入你的 pinecode &#xff08;构建向量数据库&#xff…

【三次握手、四次挥手】TCP建立连接和断开连接的过程、为什么需要三次握手,为什么需要四次挥手、TCP的可靠传输如何保证、为什么需要等待2MSL等重点知识汇总

目录 三次握手 为什么握手需要三次 四次挥手 为什么挥手需要四次 TCP的可靠传输如何保证 TIME_WAIT等待的时间是2MSL 三次握手 三次握手其实就是指建立一个TCP连接。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的…

【【萌新的RISCV学习之流水线通路的控制-8】】

萌新的RISCV学习之流水线通路的控制-8 我们在之前学习了整个单周期的模块工作流程 我们按照整体的思路分段 将数据通路划分为5个阶段 IF &#xff1a; 取地址 ID &#xff1a;指令译码和读存储器堆 EX :执行或计算地址 MEM : 数据存储器访问 WB : 写回 单周期数据通路&…

Three.js加载360全景图片/视频

Three.js加载360全景图片/视频 效果 原理 将全景图片/视频作为texture引入到three.js场景中将贴图与球形网格模型融合&#xff0c;将球模型当做成环境容器使用处理视频时需要以dom为载体&#xff0c;加载与控制视频动作每次渲染时更新当前texture&#xff0c;以达到视频播放效…

强化学习到底是什么?它是怎么运维的

https://mp.weixin.qq.com/s/LL3HfU2iNlmSqaTX_3J7fQ 强化学习是一种行为学习模型,由算法提供数据分析反馈,引导用户逐步获取最佳结果。 来源丨Towards Data Science 作者丨Jair Ribeiro 编译丨科技行者 强化学习属于机器学习中的一个子集,它使代理能够理解在特定环境中…

TensorFlow入门(四、数据流向机制)

session与"图"工作过程中存在的两种数据的流向机制,即:注入机制和取回机制 注入机制(feed):即通过占位符向模式中传入数据 取回机制(fetch):指在执行计算图时&#xff0c;可以同时获取多个操作节点的计算结果 实例代码如下: import tensorflow.compat.v1 as tftf…

【Java】建筑工地智慧管理系统源码

智慧工地系统运用物联网信息技术&#xff0c;致力于推动建筑工程行业的建设发展&#xff0c;做到全自动、信息化&#xff0c;智能化的全方位智慧工地&#xff0c;实现工程施工可视化智能管理以提高工程管理信息化水平。 智慧工地平台拥有一整套完善的智慧工地解决方案&#xff…

C语言入门Day_27 开发环境

前言&#xff1a; 在线编译环境涉及到联网&#xff0c;如果在没有网的情况下&#xff0c;我们就不能写代码了&#xff0c;这一章节&#xff0c;我们将会给大家介绍一下如何搭建一个本地的C语言编译环境。 如果想要设置 C 语言环境&#xff0c;需要确保电脑上有以下两款可用的…

Hive【Hive(三)查询语句】

前言 今天是中秋节&#xff0c;早上七点就醒了&#xff0c;干啥呢&#xff0c;大一开学后空教室紧缺&#xff0c;还不趁着假期来学校等啥呢。顺便偷偷许个愿吧&#xff0c;希望在明年的这个时候&#xff0c;秋招不知道赶不赶得上&#xff0c;我希望拿几个国奖&#xff0c;蓝桥杯…

基于微信小程序的宠物寄养平台小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

Spark SQL案例【电商购买数据分析】

数据说明 Spark 数据分析 &#xff08;Scala&#xff09; import org.apache.spark.rdd.RDD import org.apache.spark.sql.{DataFrame, SparkSession} import org.apache.spark.{SparkConf, SparkContext}import java.io.{File, PrintWriter}object Taobao {case class Info(u…

26270-2010 数字电视接收设备标准测试信号

声明 本文是学习GB-T 26270-2010 数字电视接收设备标准测试信号. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了数字电视接收设备测试用的标准测试信号。 本标准适用于我国地面、有线和卫星数字电视广播接收设备测试。数字电视…

【小余送书第二期】《MLOps工程实践:工具、技术与企业级应用》参与活动,即有机会中奖哦!!!祝各位铁铁们双节快乐!

目录 1、背景介绍 2、内容简介 3、读者对象 4、专家推荐 5、书籍目录 目  录 作者简介 前言 第1章 全面了解MLOps1 1.1 人工智能的趋势和现状 1 1.1.1 趋势1&#xff1a;人工智能在企业中加速落地&#xff0c;彰显更多业务价值 1 1.1.2 趋势2&#xff1a;人…