2023年Java核心技术面试第三篇(篇篇万字精讲)

目录

六.  Java反射机制以及动态代理是基于什么原理

 6.1 反射机制:

6.2 反射例子:

6.3 动态代理:

6.4 例子:

6.5 总结:

6.5.1 代理模式

6.5.1.1动态代理:

*6.5.1.2 JDK动态代理:

*6.5.1.3 cglib动态代理:

6.5.1.4 反射与动态代理原理

6.5.2 应用场景:

6.5.2.3 组成要素:

6.5.2.4 实现方式:

七. int 和 Integer 有什么区别?  Integer的值缓存范围?

7.1   int:

7.2 Integer的值缓存:

7.3 考点分析:

7.3.1 理解自动装箱,拆箱

7.3.1.1 自动装箱实际上是一种语法糖。

7.3.1.2 语法糖解释:

7.3.1.2.1 语法糖例子

7.3.1.2.1 .1自动装箱和拆箱:

7.3.1.2.1.2 泛型:

7.3.1.2.1.3 Lambda表达式:

7.3.2 对象的组成

7.3.2.1对象头:

7.3.2.2对象实例:

7.3.2.3举个继承有父类的例子:

7.3.2.4举个正常的例子:

7.3.2.5 tips:

7.3.2.6 小结:

7.3.2.6.1 int和Integer有什么区别?

7.3.2.6.2 对象的内存结构是什么样的?


六.  Java反射机制以及动态代理是基于什么原理

 6.1 反射机制:

Java语言提供的一种基础功能,赋予程序在运行时自省(introspect)的能力。

通过反射我们可以直接操作类和对象:

比如获取某个对象的类定义,获取类声明的属性和方法,调用方法或者构造对象,甚至可以运行时修改类定义。

6.2 反射例子:

反射的示例,展示了如何获取类的信息、创建对象和调用方法

通过 Class<?> clazz = MyClass.class 获取了类 MyClass 的定义。然后使用反射获取了类的名称、属性和方法,并输出到控制台。

接下来,我们使用反射创建了 MyClass 类的对象实例,并通过反射调用了 setName()setAge() 方法来设置对象的属性值。

最后,我们通过调用对象的 toString() 方法将对象信息输出到控制台。

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class ReflectionExample {public static void main(String[] args) throws Exception {// 获取类的定义Class<?> clazz = MyClass.class;// 获取类的名称String className = clazz.getName();System.out.println("Class Name: " + className);// 获取类声明的属性Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {String fieldName = field.getName();System.out.println("Field Name: " + fieldName);}// 获取类声明的方法Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {String methodName = method.getName();System.out.println("Method Name: " + methodName);}// 创建对象实例Constructor<?> constructor = clazz.getDeclaredConstructor();Object obj = constructor.newInstance();// 调用方法Method setNameMethod = clazz.getDeclaredMethod("setName", String.class);setNameMethod.invoke(obj, "John Doe");Method setAgeMethod = clazz.getDeclaredMethod("setAge", int.class);setAgeMethod.invoke(obj, 30);// 输出对象信息System.out.println(obj.toString());}
}class MyClass {private String name;private int age;public MyClass() {}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Name: " + name + ", Age: " + age;}
}

 输出

Class Name: MyClass
Field Name: name
Field Name: age
Method Name: setName
Method Name: setAge
Name: John Doe, Age: 30

展示了如何使用反射获取类的信息、创建对象实例和调用方法。通过反射,我们可以在运行时动态地操作类和对象,灵活应对不同的需求

6.3 动态代理:

是一种方便运行时动态构建代理,动态处理代理方法调用的机制,很多场景都是利用类似机制做到的。

比如用来面向切面的编程(AOP)

6.4 例子:

创建一个实现InvocationHandler接口的类,用于处理代理方法的调用

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class LogInvocationHandler implements InvocationHandler {private Object target; // 目标对象public LogInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 在方法执行前输出日志System.out.println("Before invoking " + method.getName() + "()");// 调用目标对象的方法Object result = method.invoke(target, args);// 在方法执行后输出日志System.out.println("After invoking " + method.getName() + "()");return result;}
}

使用Proxy类来动态生成代理对象,并将目标对象和LogInvocationHandler关联起来

import java.lang.reflect.Proxy;public class Main {public static void main(String[] args) {UserService userService = new UserServiceImpl(); // 原始的目标对象// 创建LogInvocationHandler实例LogInvocationHandler handler = new LogInvocationHandler(userService);// 使用Proxy类动态生成代理对象UserService proxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),userService.getClass().getInterfaces(),handler);// 调用代理对象的方法proxy.addUser("Alice");proxy.deleteUser("Bob");}
}

使用了Proxy类的newProxyInstance()方法来动态生成代理对象。

newProxyInstance()方法接受三个参数:

  1. ClassLoader loader: 指定用于定义代理类的类加载器。我们可以使用目标对象的类加载器,通过userService.getClass().getClassLoader()获取。

  2. Class<?>[] interfaces: 指定代理类要实现的接口列表。我们可以通过userService.getClass().getInterfaces()获取目标对象实现的接口数组。

  3. InvocationHandler handler: 指定用于处理代理方法调用的InvocationHandler实例。在我们的例子中,我们使用了自定义的LogInvocationHandler作为处理器。

每次调用代理对象的方法时,都会经过LogInvocationHandlerinvoke()方法。在方法执行前,会输出相应的日志信息(例如"Before invoking addUser()"),然后调用目标对象的对应方法,最后输出方法执行后的日志信息(例如"After invoking addUser()")。

6.5 总结:

6.5.1 代理模式

通过代理静默地解决一些业务无关的问题,比如远程、安全、事务、日志、资源关
闭......让应用开发者可以只关心他的业务
静态代理:

事先写好代理类,可以手工编写,也可以用工具生成。缺点是每个业务类都要
对应一个代理类,非常不灵活。


6.5.1.1动态代理:

运行时自动生成代理对象。缺点是生成代理代理对象和调用代理方法都要额外
花费时间。


*6.5.1.2 JDK动态代理:

基于Java反射机制实现,必须要实现了接口的业务类才能用这种办法生
成代理对象。新版本也开始结合ASM机制。


*6.5.1.3 cglib动态代理:

基于ASM机制实现,通过生成业务类的子类作为代理类。
Java 反射机制的常见应用:动态代理(AOP、RPC)、提供第三方开发者扩展能力(Servlet容
器,JDBC连接)、第三方组件创建对象(DI)

6.5.1.4 反射与动态代理原理


1 关于反射
反射最大的作用之一就在于我们可以不在编译时知道某个对象的类型,而在运行时通过提供
完整的”包名+类名.class”得到。注意:不是在编译时,而是在运行时。
功能:
•在运行时能判断任意一个对象所属的类。
•在运行时能构造任意一个类的对象。
•在运行时判断任意一个类所具有的成员变量和方法。
•在运行时调用任意一个对象的方法。
说大白话就是,利用Java反射机制我们可以加载一个运行时才得知名称的class,获悉其构造
方法,并生成其对象实体,能对其fields设值并唤起其methods。


6.5.2 应用场景:


反射技术常用在各类通用框架开发中。因为为了保证框架的通用性,需要根据配置文件加载
不同的对象或类,并调用不同的方法,这个时候就会用到反射——运行时动态加载需要加载
的对象。

6.5.2.1特点:


由于反射会额外消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要
用反射。另外,反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问
题。
6.5.2.2 动态代理
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不
能直接引用另一个对象,而代理对象可以在两者之间起到中介的作用(可类比房屋中介,房
东委托中介销售房屋、签订合同等)。
所谓动态代理,就是实现阶段不用关心代理谁,而是在运行阶段才指定代理哪个一个对象
(不确定性)。如果是自己写代理类的方式就是静态代理(确定性)。


6.5.2.3 组成要素:

(动态)代理模式主要涉及三个要素:
其一:抽象类接口
其二:被代理类(具体实现抽象接口的类)
其三:动态代理类:实际调用被代理类的方法和属性的类


6.5.2.4 实现方式:


实现动态代理的方式很多,比如 JDK 自身提供的动态代理,就是主要利用了反射机制。还有
其他的实现方式,比如利用字节码操作机制,类似 ASM、CGLIB(基于 ASM)、Javassist
等。
举例,常可采用的JDK提供的动态代理接口InvocationHandler来实现动态代理类。其中invoke
方法是该接口定义必须实现的,它完成对真实方法的调用。通过InvocationHandler接口,所
有方法都由该Handler来进行处理,即所有被代理的方法都由InvocationHandler接管实际的处
理任务。此外,我们常可以在invoke方法实现中增加自定义的逻辑实现,实现对被代理类的
业务逻辑无侵入。

七. int 和 Integer 有什么区别?  Integer的值缓存范围?

 Java虽然被称为面向对象的语言,但是原始数据类型仍然是重要的组成元素,经常考察原始数据类型和包装类等Java语言特性。

7.1   int:

int是我们是整型数字,是Java的8个原始数据类型(boolean,byte,short,char,int ,float,double,long)之一。

Java语言虽然号称一切都是对象,但原始数据类型是例外。

Integer 是 int 对应的包装类,有一个int 类型的字段存储数据,并且提供了基本操作,如数学运算,int和字符串之间的转换等

Java 5 中,引入了自动装箱和自动拆箱的功能(boxing/unboxing),Java根据上下文,自动进行转换,简化了相关编程。

7.2 Integer的值缓存:

涉及到Java5 中另一个改进,构建Integer对象的传统方式是直接调用构造器,直接进行new一个对象。

根据实践我们发现大部分数据都是集中在有限的,较小的数值范围,因此,在Java5中新增加静态工厂方法valueOf,调用时会利用缓存机制,带来了性能改进,默认值是-128到127之间。

7.3 考点分析:

上面的回答覆盖了,Java里面的两个基本要素,原始数据类型,包装类。

自然的就扩展:自动装箱,自动拆箱机制,可能会考察对封装类的一些设计和实践。

7.3.1 理解自动装箱,拆箱

7.3.1.1 自动装箱实际上是一种语法糖。

javac替我们自动把装箱转换为Integer.valueOf(),把拆箱替换为Integer.intValue(),调用的是Integer.valueOf,采取缓存。

valueOf()方法中,它是Integer类的静态方法,用于将基本类型int或字符串转换为对应的Integer对象。在valueOf()方法中,针对-128到127范围内的整数值会使用缓存,返回预先创建的对象,而不是每次都创建新的对象。

7.3.1.2 语法糖解释:

可以理解为Java平台为我们自动进行的一些转换,保证不同的写法在运行时等价,发生在编译阶段,生成的字节码是一样的。

7.3.1.2.1 语法糖例子
7.3.1.2.1 .1自动装箱和拆箱:

通过自动装箱和拆箱的语法糖,我们可以直接在基本类型和对应的包装类之间进行转换,无需手动编写繁琐的转换代码。

int num = 10;
Integer integer = num; // 自动装箱
int result = integer; // 自动拆箱
7.3.1.2.1.2 泛型:

Java的泛型提供了类型安全的编程方式,使代码更加灵活和易读。在使用泛型时,编译器会进行类型擦除,将泛型参数替换为实际的类型。例如,我们可以声明一个List来存储指定类型的元素,在编译时会进行类型检查和转换。

泛型解释:

定义了一个泛型类GenericClass<T>,它有一个类型参数T。这个类包含了一个成员变量value和对应的getter和setter方法

public class GenericClass<T> {private T value;public void setValue(T value) {this.value = value;}public T getValue() {return value;}
}

 在使用该泛型类时,我们可以传入不同的类型参数

GenericClass<String> strObj = new GenericClass<>();
strObj.setValue("Hello");
String strValue = strObj.getValue();GenericClass<Integer> intObj = new GenericClass<>();
intObj.setValue(10);
Integer intValue = intObj.getValue();

我们分别实例化了两个GenericClass对象:strObjintObj。一个使用了String类型作为类型参数,另一个使用了Integer类型作为类型参数。

在编译时,由于类型擦除的原因,编译器会将T替换为实际的类型或者限定类型。在上述代码中,泛型参数T会被擦除为Object类型。因此,编译器会将代码转换成如下形式

public class GenericClass {private Object value;public void setValue(Object value) {this.value = value;}public Object getValue() {return value;}
}
7.3.1.2.1.3 Lambda表达式:

Lambda表达式是一种语法糖,它可以简化匿名函数的编写。通过Lambda表达式,我们可以以更精炼的方式表示函数式接口的实现。

匿名函数:

一种没有具体名称的函数。它可以用来表示一段可执行的代码块或逻辑,但没有像普通函数那样被命名。匿名函数通常用于函数式编程中,以便在需要时传递给其他函数或方法作为参数。

 例子1:

List<Integer> numbers = Arrays.asList(5, 3, 1, 4, 2);// 使用匿名函数进行升序排序
Collections.sort(numbers, new Comparator<Integer>() {@Overridepublic int compare(Integer num1, Integer num2) {return num1.compareTo(num2);}
});// 使用Lambda表达式进行升序排序
Collections.sort(numbers, (num1, num2) -> num1.compareTo(num2));System.out.println(numbers); // 输出:[1, 2, 3, 4, 5]

例子2:

int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {System.out.println(num);
}
//对比Lambda
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(num -> System.out.println(num));

7.3.2 对象的组成

 对象由三部分组成,对象头,对象实例,对齐填充。

7.3.2.1对象头:

一般是十六个字节,包括两部分,

第一部分有哈希码,锁状态标志,线程持有的 锁,偏向线程id,gc分代年龄等。

第二部分是类型指针,也就是对象指向它的类元数据指针, 可以理解,对象指向它的类。

7.3.2.2对象实例:

就是对象存储的真正有效信息,也是程序中定义各种类型的字段包括父类继承的和子 类定义的。

虚拟机对对象字段的存储顺序不涉及重排序的概念。重排序主要指的是编译器或处理器对指令执行顺序进行优化的行为,而不是虚拟机对对象字段在内存中的排列顺序进行优化

第三部分对齐填充只是一个类似占位符的作用,因为内存的使用都会被填充为八字节的倍数。

7.3.2.3举个继承有父类的例子:

定义了一个Person类和一个继承自PersonEmployee类。Person类有一个私有字段name和一个公共方法getName()用于获取姓名。Employee类除了继承了Person类的字段和方法外,还添加了一个私有字段employeeId和一个公共方法getEmployeeId()用于获取员工ID。

public class Person {private String name;public Person(String name) {this.name = name;}public String getName() {return name;}
}public class Employee extends Person {private int employeeId;public Employee(String name, int employeeId) {super(name);this.employeeId = employeeId;}public int getEmployeeId() {return employeeId;}
}

创建一个Employee对象时,它在内存中的布局如下

对象头(Header):16字节
├── 哈希码、锁状态标志、线程持有的锁、偏向线程ID、GC分代年龄等信息
└── 类型指针,指向Employee类的元数据对象实例(Instance Data):
├── name字段(String类型,引用) - 继承自Person类
└── employeeId字段(int类型) - Employee类特有的字段对齐填充(Padding):占位符,使对象的总大小为8字节的倍数

Employee对象的实例数据部分包含了两个字段。其中,name字段是从Person类继承而来的,它是一个引用类型的字段,用于存储姓名信息。而employeeId字段是Employee类特有的字段,它是一个整数类型的字段,用于存储员工ID。

Employee对象的实例数据部分存储了name字段(继承自Person类)和employeeId字段(Employee类特有),这些字段组成了对象的真正有效信息

7.3.2.4举个正常的例子:

定义了一个Person类,它有两个字段:nameage

public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}
}

创建Person对象时,它在内存中的布局大致如下所示:

对象头(Header):16字节
├── 哈希码、锁状态标志、线程持有的锁、偏向线程ID、GC分代年龄等信息
└── 类型指针,指向Person类的元数据对象实例(Instance Data):
├── name字段(String类型,引用)
└── age字段(int类型)对齐填充(Padding):占位符,使对象的总大小为8字节的倍数

对象头占据了16字节,并包含了对象的哈希码、锁状态等信息,以及指向Person类元数据的类型指针。接下来,对象实例部分包含了nameage两个字段,分别是一个引用类型的String和一个基本类型的int。在内存中,这两个字段按照定义的顺序存储。

需要注意的是,虚拟机对对象字段的存储顺序不涉及重排序的概念。重排序主要指的是编译器或处理器对指令执行顺序进行优化的行为,而不是虚拟机对对象字段在内存中的排列顺序进行优化。因此,在这个例子中,虚拟机不会影响对象实例中字段的存储顺序。

7.3.2.5 tips:

除了存储空间的区别外,基本数据类型是有默认值的,而对象数据类型没有默认值。比如
从数据库中查询用户年龄,如果用户并没有设置年龄信息,数据库中代表年龄的列age =null
,那么在使用基本数据类型接收年龄值的时候就无法区分用户是年龄为0还是未设置年龄的情
况,所以决定使用int还是Integer的时候除了考虑性能因素还要考虑业务场景。

7.3.2.6 小结:

7.3.2.6.1 int和Integer有什么区别?


1. int:是Java的8个原始数据类型之一(boolean,byte,char,short,int,long,floa
t,double)
2. Integer:是int对应的包装类,是引用类型。在Java5中,引入了自动装箱和自动拆箱
功能,Java可以根据上下文,自动进行转化,极大的简化了相关编程。自动装箱/自动拆箱发
生在编译期,自己调用valueOf和intValue方法来使用缓存机制(默认缓存是-128到127之
间)。注意:new 不使用缓存
3. int访问是直接访问数据内存地址,Integer是通过引用找到数据内存地址
4. 内存空间占用:Integer大于int
5. 数据操作效率上:int大于Integer
6. 线程安全方面:int等原始数据类型需要使用并发相关手段。Integer等包装类可以使
用类似AtomicInteger、AtomicLong等这样的线程安全类。
7. int等原始数据类型和Java泛型不能配合使用
8. Integer和String一样有final修饰,是不可变类型
9. Integer中定义了bytes常量,避免了因为环境 64位或32位不同造成的影响
实践中,建议避免无意中的装箱、拆箱行为


7.3.2.6.2 对象的内存结构是什么样的?


在HotSpot虚拟机中,对象在内存中存储的布局都可以分为3块区域。
1. 对象头(Header)
包含两部分信息:
1. Mark Word:用于存储对象自身的运行时数据,如:哈希码(HashCode),GC
分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等,
2. 类型指针:即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个
对象是哪个类的实例。
另外,如果对象是Java数组,那在对象头中还必须有一块用国语记录数组长度的数
据。
2. 实例数据(Instance Data):对象真正存储的有效信息,也是在程序代码中所定义的
各种类型的字段内容。
3. 对齐填充(Padding):对齐填充并不是必然存在的,也没有特别的含义,它仅仅起
着占位符的作用。使对象的大小必须是8字节的整数倍。

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

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

相关文章

【网络】DNS | ICMP | NAT | 代理服务器

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《网络》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 前面几篇文章虽然讲介绍了整个网络通信的协议栈&#xff0c;我们也知道了完整的网络通信过程&#xff…

56 | 国内游戏直播竞品分析

国内游戏直播竞品分析 一、需求分析 当前直播用户群可分为两大类: 主播观众用户需求: 1.主播: 作为直播内容的创造者,主播表现方式和内容很大程度上决定了观众的需求, 其中主播主要只有三点需求: (一) 通过某一手段(如游戏技术、唱歌技巧)获取他人关注,满足虚荣心…

rest_framework(4)序列化和反序列化(二)

本系列文章中的上一篇文章&#xff1a;序列化和反序列化&#xff08;一&#xff09; urls.py 代码 from django.urls import re_path from sers.views import BookDetailView urlpatterns [re_path(r"sers/book/(\d)", BookDetailView.as_view()), } models.py 代…

【⑬MySQL | 数据类型(一)】简介 | 整数 | 浮点 | 定点类型

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL数据类型简介 | 整数 | 浮点 | 定点类型的分享✨ 目录 前言0.数据类型简介1 整数类型2 浮点类型3 定点类型4 日期/时间类型总结 0.数据类型简介 数据类型&#xff08;data_type&#xff09;是指系统中所允许的…

LRU淘汰策略执行过程

1 介绍 Redis无论是惰性删除还是定期删除&#xff0c;都可能存在删除不尽的情况&#xff0c;无法删除完全&#xff0c;比如每次删除完过期的 key 还是超过 25%&#xff0c;且这些 key 再也不会被客户端访问。 这样的话&#xff0c;定期删除和堕性删除可能都彻底的清理掉。如果…

百度许少辉著Baidu《乡村振兴战略下传统村落文化旅游设计》图书馆新书通报

百度许少辉著Baidu《乡村振兴战略下传统村落文化旅游设计》图书馆新书通报

docker保存容器镜像并在新机器加载

保存镜像&#xff0c;主要用到 docker save命令 从镜像包加载镜像&#xff0c;主要用到 docker load命令 目录 方法1 多个镜像&#xff0c;且带额外操作&#xff0c;如压缩的情况 方法2 方法1 docker save 0fk8ab59a85f > im.tar 或 docker save 镜像名称:tag > im…

AWS SDK 3.x for .NET Framework 4.0 可行性测试

前言 为了应对日益增长的网络安全挑战, 越来越多的互联网厂商已经陆续开始或者已经彻底停止了对 SSL 3 / TLS 1.0 / TLS1.1 等上古加密算法的支持. 而对于一些同样拥有悠久历史的和 AWS 服务相关联的应用程序, 是否可以通过仅更新 SDK 版本的方式来适应新的环境. 本文将以 Win…

揭开pkill的秘密:在Linux中杀死进程的完整指南

揭开pkill的秘密&#xff1a;在Linux中杀死进程的完整指南 一、前言二、进程管理基础知识2.1、什么是进程&#xff1f;2.2、进程管理的原理和目的2.3、进程状态和标识符 三、理解Linux pkill命令3.1、pkill命令的概述和作用3.2、与kill命令的对比3.3、常见的pkill命令选项和参数…

Linux 编译内核模块出现--Unknown symbol mcount

文章目录 Linux suse&#xff1a; # cat /etc/os-release NAME"SLES" VERSION"12-SP2" VERSION_ID"12.2" PRETTY_NAME"SUSE Linux Enterprise Server 12 SP2" ID"sles" ANSI_COLOR"0;32" CPE_NAME"cpe:/o:s…

PCAP01介绍和STM32模拟SPI驱动

一.芯片介绍 Pcap01是德国acam公司设计的一款革命性的电容测量芯片。该芯片 内部有DSP计算单元&#xff0c;可以直接将电容元件接到Pcap01芯片&#xff0c;然后芯片计算出容值大小&#xff0c;通过SPI总线将电容容值数据传送给CPU&#xff0c;电容测量完全数字化。 二,测量原…

LeetCode 面试题 01.05. 一次编辑

文章目录 一、题目二、C# 题解法一&#xff1a;从第一个不同位置处判断后续相同子串法二&#xff1a;前后序遍历判断第一个不同字符的位置关系 优化法一法二 一、题目 字符串有三种编辑操作:插入一个英文字符、删除一个英文字符或者替换一个英文字符。 给定两个字符串&#xff…

无脑入门pytorch系列(五)—— nn.Dropout

本系列教程适用于没有任何pytorch的同学&#xff08;简单的python语法还是要的&#xff09;&#xff0c;从代码的表层出发挖掘代码的深层含义&#xff0c;理解具体的意思和内涵。pytorch的很多函数看着非常简单&#xff0c;但是其中包含了很多内容&#xff0c;不了解其中的意思…

docker启用cgroup v2

要求 本人的操作系统是kali&#xff0c;基于debian docker info如果你这里是2那么说明启用了&#xff0c;如果是1&#xff0c;那么就未启用 对于Docker来说&#xff0c;Cgroups v2的使用需要满足以下条件&#xff1a; Linux内核版本在4.15以上。 uname -r 系统已经启用Cgro…

前端处理图片文件的方法

在项目开发过程中&#xff0c;有一个需求&#xff0c;需要前端对上传的图片进行处理&#xff0c;以字符串的形式传给后端&#xff0c;实现效果如下&#xff1a; 1.上传图片的组件 在该项目中&#xff0c;使用了element plus组件库 <el-uploadv-model:file-list"fileL…

c++(8.23)类,this指针,构造函数,析构函数,拷贝构造函数

设计一个Per类&#xff0c;类中包含私有成员&#xff1a;姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员&#xff1a;成绩、Per类对象 p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #include <iostream>u…

Java中static的应用之单例模式

单例模式是一种创建对象的设计模式&#xff0c;它保证一个类只有一个实例&#xff0c;并提供一个全局访问点。由于单例模式只允许存在一个实例&#xff0c;因此它可以节省系统资源并提高程序的性能。在许多情况下&#xff0c;单例模式在应用程序中都是非常有用的&#xff0c;例…

Linux——Shell常用运算符

运算符说明举例-eq检测两个数是否相等&#xff0c;相等返回 true。[ $a -eq $b ] 返回 false。-ne检测两个数是否不相等&#xff0c;不相等返回 true。[ $a -ne $b ] 返回 true。-gt检测左边的数是否大于右边的&#xff0c;如果是&#xff0c;则返回 true。[ $a -gt $b ] 返回 …

​8th参考文献:[8]许少辉.乡村振兴战略下传统村落文化旅游设计[M]北京:中国建筑工业出版社,2022.

​&#xff18;th参考文献&#xff1a;&#xff3b;&#xff18;&#xff3d;许少辉&#xff0e;乡村振兴战略下传统村落文化旅游设计&#xff3b;&#xff2d;&#xff3d;北京&#xff1a;中国建筑工业出版社&#xff0c;&#xff12;&#xff10;&#xff12;&#xff12;&a…

notebook写好代码后直接生成PPT报告(html格式)

注&#xff1a;记录使用notebook直接生成html格式的PPT报告&#xff08;html格式&#xff09;。 前置内容&#xff1a;如果直接导出没有Reveal.js.slides(.slides.html)选项&#xff0c;需要安装插件nbextensions。 安装参考&#xff1a;插件nbextensions安装 操作步骤&#x…