⛳ 面向对象面试题

面向对象面试题目录

  • ⛳ 面向对象面试题
    • 🚜 一,成员变量,局部变量,类变量存储在内存的什么地方?
      • 🐾 1.1,类变量(静态成员变量)
      • 📝 1.2,成员变量
      • ⭐ 1.3,局部变量
    • 🏭 二,下面变量引用存放在哪里?
    • 💻 三,HotSpot 方法区的变迁
      • 🎁 3.1,JDK1.2 ~ JDK6
      • 💭 3.2,JDK7
      • ☁ 3.3,JDK8
      • 🎉 3.4,方法区的垃圾回收
    • 👣 四,为什么调整字符串常量池和静态变量的位置
    • 📢 五,为什么用原空间替换永久代
    • 📐 六,JDK1.8元空间会产生内存溢出么?在什么情况下会产生内存溢出?
      • 🚜 6.1,解析
      • 👣 6.2,代码演示
    • 🎨 七,JVM8的内存结构
    • 🎁 八,方法区和永久代的区别
      • 💬 8.1,**方法区**
      • 💭 8.2,**PermGen(永久代)**
    • 💖 九,你知道的几种主要的JVM参数

⛳ 面向对象面试题

🚜 一,成员变量,局部变量,类变量存储在内存的什么地方?

🐾 1.1,类变量(静态成员变量)

​ 类变量是用 static 修饰符修饰,定义在方法外的变量,随着Java进程产生和销毁在Java7及之前把静态变量存放于方法区,在Java7时存放在堆中。

📝 1.2,成员变量

​ 成员变量是定义在类中,但是没有 static 修饰符修饰的变量,随着类的实例产生和销毁,是类的实例的一部分

​ 由于是实例的一部分,在类初始化的时候,从运行时常量池取出直接引用或者值,与初始化的对象一起放入堆中。成员变量可以被类的成员方法访问和修改。如果成员变量是基本类型,则存储在堆内存的对象实例中;如果成员变量是引用类型,则存储在堆内存的对象实例中。

⭐ 1.3,局部变量

​ 局部变量是定义在类的方法中的变量

​ 在所在方法被调用时放入虚拟机栈的栈帧中,栈顶是正在执行的方法,方法执行结束后从虚拟机栈中弹出,所以存放在虚拟机栈中。

🏭 二,下面变量引用存放在哪里?

public class StaticObjTest {
    static class Test{
        // 静态变量
        // 一个java.lang.Class类型的对象实例引用了此变量
        static ObjectHolder staticObj = new ObjectHolder();
        // 实例变量
        ObjectHolder instanceObj = new ObjectHolder();
        void foo() {
            // 局部变量
            ObjectHolder localObj = new ObjectHolder()();
            System.out.println("done");
        }
    } 
    private static class ObjectHolder{
    } 
    public static void main(String[] args) {
        Test test = new StaticObjTest.Test();
        test.foo();
    }
}
  • 以上代码中,静态变量staticObj随着 Test 的类型信息存放在在方法区
  • 实例变量 instanceObj 随着 Test 的对象实例存放在堆区
  • 局部变量 localObj 则是存放在 foo() 方法栈帧的局部变量表中
  • 三个变量引用对应的对象实体都是在堆空间

a1

GC回收:

  • 地址为 0x004 的实例最容易被回收。
  • 地址为 0x003 的实例不容易被回收。
  • 地址为 0x001 的实例最不容易被回收,会进入到老年代里边。

💻 三,HotSpot 方法区的变迁

版本演进细节
JDK6及 之前方法区的实现为永久代,静态变量存放在永久代中,字符串常量池(StringTable)位于运行时常量池中。
JDK7方法区的实现为永久代,但已经逐步“去永久代”,静态变量、字符串常量池移除,保存在堆中
JDK8方法区的实现为本地内存的元空间,字符串常量池、静态变量仍在堆中

🎁 3.1,JDK1.2 ~ JDK6

image-20230725211255816

在 JDK1.2 ~ JDK6 的实现中,HotSpot 使用永久代(持久代)实现方法区;HotSpot 使用 GC 分代实现方法区带来了很大便利;

💭 3.2,JDK7

image-20230725215644301

由于 GC 分代技术的影响,使之许多优秀的内存调试工具无法在 Oracle HotSpot之上运行,必须单独处理;

并且 Oracle 同时收购了 BEA 和 Sun 公司,同时拥有 JRockit 和 HotSpot,在将 JRockit 许多优秀特性移植到 HotSpot 时,由于 GC 分代技术遇到了种种困难,所以从 JDK8 开始 Oracle HotSpot 开始移除永久代。
JDK7中符号表被移动到 Native Heap中, 字符串常量和类引用被移动到 Java NON_HEAP中。

Native Heap 是程序运行时动态的向操作系统申请的内存,JVM Heap 是在 Native Heap 划分出一块区域,作为JVM Heap。

Java NON_HEAP :

在Java中,内存分为两个主要部分:堆内存(Heap)和非堆内存(Non-Heap)。

堆内存用于存储对象实例和数组等动态分配的数据。它是Java程序运行时的主要内存区域,由垃圾回收器管理。通过调整堆内存的大小,可以影响Java程序的性能和内存使用情况。

非堆内存是指除了堆内存之外的内存区域,主要包括以下几个部分:

  1. 方法区(Method Area):也称为永久代(Permanent Generation),在较早的JDK版本中使用。它用于存储类的元数据(如类的结构信息、常量池、静态变量等)和方法字节码等信息。在JDK 8及以后的版本中,永久代被元空间(Metaspace)取代。
  2. 常量池(Constant Pool):常量池是方法区的一部分,用于存储字符串常量、符号引用等。在JDK 7及以后的版本中,常量池被移至堆内存的一部分,称为字符串常量池(String Pool)。
  3. 直接内存(Direct Memory):直接内存是通过java.nio包提供的一种与操作系统直接交互的内存分配方式。它不受Java堆大小的限制,可以用于高效地进行I/O操作。直接内存的分配和释放由Java虚拟机管理,但实际的内存空间是在操作系统层面上分配的。

非堆内存的大小和使用情况通常由Java虚拟机的参数进行配置,例如-XX:MaxPermSize(用于设置永久代的最大大小)和-XX:MaxDirectMemorySize(用于设置直接内存的最大大小)等。

注:根据虚拟机版本的更迭,名词可能会发生变化。

☁ 3.3,JDK8

image-20230725220622305

在 JDK8 中,永久代已完全被元空间(Meatspace)所取代。

🎉 3.4,方法区的垃圾回收

image-20230725220755848

方法区的垃圾回收主要分为两个部分:常量池中废弃的常量和不再使用的类。

  • 在JDK1.7及之前,HotSpot虚拟机将Java信息,常量池,静态变量,即使编译后的代码(JIT)等数据,存储在Perm(永久代)里(对于其它虚拟机如BEA JRockit、IBM J9等是不存在永久带概念的),类的元数据和静态变量在类加载的时候被分配到Perm里,当常量池回收或者类被卸载时,垃圾收集器会回收这部分内存,但效果不太理想。

  • JDK1.8中则把永久代给完全删除了,取而代之的是Meta Space,将类元数据放到了本地内存中,将常量池和静态变量放到了Java堆里,HotSpot VM将会为类的元数据明确地分配与释放本地内存,在这种架构下,类元数据就突破了-XX:MaxPermSize的限制,所以此配置已经失效了,现在可以使用更多的本地内存。这样一定程度上解决了原来在运行时生成大量的类,从而经常 Full GC 的问题 — 如运行时使用反射,代理等。

    1. 方法区的概念是Java内存模型(JMM)提出的规范,而永久代Perm是HotSpot对这种规范的实现。

    2. 为什么JDK1.8要把方法区从JVM里(永久代)移到直接内存(元空间)?

      1. 字符串存在永久代中,容易出现性能问题和内存溢出。

      2. 类及方法的信等比较难确定其大小,因此对于永久代的大小指定比较困难。

      3. 永久代会为GC带来不必要的复杂度,并且回收效率偏低。

      4. image-20230726081357334

        Java虚拟机(JVM)运行时常量池是一种用于存储编译期生成的各种字面量和符号引用的表。他是Class文件结构的一部分,位于每个类或接口的常量池区域。在运行Java程序是,JVM会使用这些常量池中的信息。

        JVM运行时常量池可以包含以下类型的内容:

        1. 字面量(Literal):这包括整数、浮点数、字符和字符串等常量值。
        2. 符号引用(Symbolic References):这是一种编译时的引用,包括类和接口的全限定名、字段的名称和描述符、方法的名称和描述符等。

        常量池中的数据可以被直接使用或者通过符号引用在运行时解析。它的主要目的是节省内存空间和提高执行性能,因为常量池中的数据可以被多个地方引用,而不需要每次都复制一份。

👣 四,为什么调整字符串常量池和静态变量的位置

JDK7中将字符串常量池放到了堆空间中:因为永久代的回收效率很低,在Full GC时才会触发,而Full GC在老年代的空间不足、永久代不足时才会触发,这就导致字符串常量池回收效率不高
而我们开发中会有大量的字符串被创建,回收效率低会导致永久代内存不足。
将字符串常量池放到堆里,能及时回收内存。

📢 五,为什么用原空间替换永久代

为永久代设置最大空间大小是难以确定的。

  • 在某些场景下,如果动态加载类过多,容易产生Perm区的OOM:比如某个实际Web工程中,因为功能点比较多,在运行过程中,要不断动态加载很多类,经常出现致命错误;而元空间和永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存,因此,默认情况下,元空间的最大大小仅受本地内存限制。
  • 对永久代进行调优是很困难的。

📐 六,JDK1.8元空间会产生内存溢出么?在什么情况下会产生内存溢出?

🚜 6.1,解析

Java8 及以后的版本使用Metaspace来代替永久代,Metaspace是方法区在HotSpot中的实现,它与永久代最大区别在于,Metaspace并不在虚拟机内存中而是使用本地内存也就是在JDK8中,classe meta data(the virtual machines internal presentation of Java class),被存储在叫做Metaspace的native memory。
永久代(java 8 后被元空间Metaspace取代了)存放了以下信息:

  • 虚拟机加载的类信息
  • 常量池
  • 即时编译后的代码

**内存溢出的原因:**加载到内存中的 class 数量太多或者体积太大。
**解决办法:**增加 Metaspace 的大小

-XX:MaxMetaspaceSize=512m

👣 6.2,代码演示

模拟Metaspace空间溢出,我们不断生成类往元空间灌,类占据的空间是会超过Metaspace指定的空间大小的
查看元空间大小

java -XX:+PrintFlagsInitial

官方标准:

1字节(Byte)=8字位=8个二进制数

1字位(bit)=1个二进制数

1B=8b

1KB=1024B

1MB=1024KB

1GB=1024MB

通常情况下,把B称为字节、b称为字位、KB称为千字节、MB称为兆字节、GB称为吉字节。

image-20230726083751076

默认是大约20.80M,这里设置10m方便演示效果

-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m

image-20230726083851626

测试代码(必须是一个spring boot工程)如下:

public class MetaspaceDemo {

    static class OOM{}

    public static void main(String[] args) {
        int i = 0;//模拟计数多少次以后发生异常
        try {
            while (true){
                i++;
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(OOM.class);
                enhancer.setUseCache(false);
                enhancer.setCallback(new MethodInterceptor() {
                    @Override
                    public Object intercept(Object o, Method method, Object[] objects,
                                            MethodProxy methodProxy) throws Throwable {
                        return methodProxy.invokeSuper(o,args);
                    }
                });
                enhancer.create();
            }
        } catch (Throwable e) {
            System.out.println("=================多少次后发生异常:"+i);
            e.printStackTrace();
        }
    }
}

cglib默认开启了UserCache生成的代理类都会复用原先产生在缓存中的类,所以至始至终都只有一个代理类,所以不会产生内存溢出。手动关闭它,enhancer.setUseCache(false);

image-20230726084002915

🎨 七,JVM8的内存结构

image-20230726084052068

  1. 程序计数器(Program Counter Register)

程序计数器就是当前线程所执行的字节码的行号指示器,通过改变计数器的值,来选取下一行指令,通过他来实现跳转、循环、恢复线程等功能。

  • 在任何时刻,一个处理器内核只能运行一个线程,多线程是通过线程轮流切换,分配时间来完成的,这就需要有一个标志来记住每个线程执行到了哪里,这里便需要到了程序计数器。
  • 程序计数器是线程私有的,每个线程都已自己的程序计数器。
  1. 虚拟机栈(JVM Stacks)

虚拟机栈是线程私有的,随线程生灭。虚拟机栈描述的是线程中的方法的内存模型,每个方法被执行的时候,都会在虚拟机栈中同步创建一个栈帧(stack frame),**方法被执行时入栈,执行完后出栈,**每个栈帧的包含如下的内容

  • 局部变量表: 局部变量表中存储着方法里的java基本数据类型(byte/boolean/char/int/long/double/float/short)以及对象的引用(注:这里的基本数据类型
    指的是方法内的局部变量)
  • 操作数栈
  • 动态连接
  • 方法返回地址

虚拟机栈可能会抛出两种异常:

  • 如果线程请求的栈深度大于虚拟机所规定的栈深度,则会抛出StackOverFlowError即栈溢出
  • 如果虚拟机的栈容量可以动态扩展,那么当虚拟机栈申请不到内存时会抛出OutOfMemoryError即OOM内存溢出

产生StackOverFlowError的原因是:

  • 无限递归循环调用(最常见)。
  • 执行了大量方法,导致线程栈空间耗尽。
  • 方法内声明了海量的局部变量。
  1. 本地方法栈(Native Method Stacks)
    本地方法栈与虚拟机栈的作用是相似的,都会抛出OutOfMemoryError和StackOverFlowError,都是线
    程私有的,主要的区别在于:
  • 虚拟机栈执行的是java方法
  • 本地方法栈执行的是native方法
  1. Java堆(Java Heap)

java堆是JVM内存中最大的一块,由所有线程共享, 是由垃圾收集器管理的内存区域,主要存放对象实例,当然由于java虚拟机的发展,堆中也多了许多东西,现在主要有:

  • 对象实例

    • 类初始化生成的对象
    • 基本数据类型的数组也是对象实例
  • 字符串常量池

    • 字符串常量池原本存放于方法区,从jdk7开始放置于堆中。
    • 字符串常量池存储的是string对象的直接引用,而不是直接存放的对象,是一张string table
  • 静态变量

    • 静态变量是有static修饰的变量,jdk7时从方法区迁移至堆中
  • 线程分配缓冲区(Thread Local Allocation Buffer)

    • 线程私有,但是不影响java堆的共性
    • 增加线程分配缓冲区是为了提升对象分配时的效率

java堆既可以是固定大小的,也可以是可扩展的(通过参数-Xmx和-Xms设定),如果堆无法扩展或者无法分配内存时也会报OOM。

  1. 方法区(Method Area)

它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。

(1)类型信息:

对每个加载的 类型 (类class、接口interface、枚举enum、注解annotation),JVM必须在方法区中存储以下类型信息:

  • 这个类型的完整有效名称(全名=包名.类名)
  • 这个类型直接父类的完整有效名(对于interface或是java.lang. Object,都没有父类)
  • 这个类型的修饰符( public, abstract,final的某个子集)
  • 这个类型实现接口的一个有序列表。

(2) 域(Field)信息:
JVM必须在方法区中保存类型的所有域的相关信息以及**域的声明顺序。**域的相关信息包括如下内容:

  • 域名称
  • 域类型
  • 域修饰符(public,private,protected,static,final, volatile,transient的某个子集)

(3) 方法(Method)信息:
JVM必须在方法区中保存类型的所有方法的相关信息以及方法的声明顺序。方法的相关信息包括:

  • 方法名称
  • 方法的返回类型(或void)
  • 方法参数的数量和类型(按顺序)
  • 方法的修饰符(public,private,protected,static,final,synchronized,native,abstract的一个子集)
  • 方法的字节码(bytecodes)、操作数栈、局部变量表及大小( abstract和native方法除外)
  • 异常表(abstract和 native方法除外)每个异常处理的开始位置、结束位置、代码处理在程序计数器中的偏移地址、被捕获的异常类的常量池索引

(4)静态变量(non-final的)

静态变量和类关联在一起,随着类的加载而加载,它们成为类数据在逻辑上的一部分。类变量被类的所有实例共享,即使没有类实例时你也可以访问它。
补充说明:被声明为final的静态变量的处理方法则不同,被static和final修饰的变量也称为全局变量,每个全局常量在编译的时候就会被赋值了。

public class Order {
    public static int num = 10;
    public static final int COUNT = 20;
}

通过javap命令反编译后的class文件:

image-20230726085106639

(5)运行时常量池:
理解运行时常量池,需要了解字节码文件(ClassFile)中的常量池;方法区内部包含运行时常量池,字节码文件内部包含了常量池。
常量池:一个有效的字节码文件中除了包含类的版本信息、字段、方法以及接口等描述信息外,还包含一项信息,那就是常量池( Constant Pool Table),包括各种字面量(数量值和字符串值)和对类型、域和方法的符号引用。常量池可以看做是一张表,虚拟机指令根据这张常量表,找到要执行的字面量、类名、方法名、参数类型等。
运行时常量池:

  • 运行时常量池(Runtime Constant pool)是方法区的一部分。
  • 常量池(Constant Pool Table)是class文件的一部分,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
  • 在加载类和接口到虚拟机后,就会创建对应的运行时常量池。
  • JVM为每个已加载的类型(类或接口)都维护一个运行时常量池,池中的数据项像数组项一样,是通过索引访问的。
  • 运行时常量池中包含多种不同的常量,包括编译期就已经明确的数值字面量,也包括到运行期解析后才能够获得的方法或者字段引用。此时不再是常量池中的符号地址了,会转换为真实地址。运行时常量池,相对于Class文件中的常量池的另一重要特征是:具备动态性。比如String.intern()方法会动态地向池中增加内容
  • 运行时常量池类似于传统编程语言中的符号表(symbol table),但是它所包含的数据比符号表要更加丰富。
  • 如果构造类或接口的运行时常量池时,所需的内存空间超过了方法区所能提供的最大值,则JVM会抛出OutOfMemoryError异常。
  1. 直接内存(Direct Memory)

jdk1.4中加入了NIO(New Input/Putput)类,引入了一种基于通道(channel)与缓冲区(buffer)的新IO方式,它可以使用native函数直接分配堆外内存,然后通过存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作,这样可以在一些场景下大大提高IO性能,避免了在java堆和native堆来回复制数据。
java 的 NIO 库允许 java 程序使用直接内存。直接内存是在 java 堆外的、直接向系统申请的内存空间。通常访问直接内存的速度会优于 java 堆。因此出于性能的考虑,读写频繁的场合可能会考虑使用直接内存。由于直接内存在 java 堆外,因此它的大小不会直接受限于 Xmx (虚拟机参数)指定的最大堆大小,但是系统内存是有限的, java 堆和直接内存的总和依然受限于操作系统能给出的最大内存。直接内存位于本地内存,不属于JVM内存,不受GC管理,但是也会在物理内存耗尽的时候报OOM。
注意:direct buffer不受GC影响,但是direct buffer归属的JAVA对象是在堆上且能够被GC回收的,一旦它被回收,JVM将释放direct buffer的堆外空间
直接内存(Direct Memory)的特点:

  • 直接内存并非 JVMS 定义的标准 Java 运行时内存。
  • JDK1.4 加入了新的 NIO 机制,目的是防止 Java 堆 和 Native 堆之间往复的数据复制带来的性能损耗,此后 NIO 可以使用 Native 的方式直接在 Native 堆分配内存。
  • 直接内存区域是全局共享的内存区域。
  • 直接内存区域可以进行自动内存管理(GC),但机制并不完善。
  • 本机的 Native 堆(直接内存) 不受 JVM 堆内存大小限制。可能出现 OutOfMemoryError 异常。

🎁 八,方法区和永久代的区别

💬 8.1,方法区

​ 方法区属于JVM规范的内容,JVM规范中,方法区主要用于存储类的信息、常量池、方法数据、方法代码等。

​ 方法区 是 JVM 的规范,所有虚拟机 必须遵守的。常见的JVM 虚拟机 Hotspot 、 JRockit(Oracle)、J9(IBM)

💭 8.2,PermGen(永久代)

PermGen , 就是 PermGen space ,全称是 Permanent Generation space ,是指内存的永久保存区域。

这块内存主要是被JVM存放Class和Meta信息的, Class 在被 Loader 时就会被放到 PermGen space中。

​ 绝大部分 Java 程序员应该都见过 java.lang.OutOfMemoryError: PermGen space 这个异常。
这里的 PermGen space 其实指的就是 方法区 。

PermGen space 则是 HotSpot 虚拟机 基于 JVM 规范对 方法区 的一个落地实现,PermGen space 是 HotSpot 虚拟机有,而如 JRockit(Oracle)、J9(IBM) 虚拟机有 方法区 ,但是就没有 PermGen space。

强调: 只有 HotSpot 才有 PermGen space。

​ PermGen space 则是 HotSpot 虚拟机 基于 JVM 规范对 方法区 的一个落地实现,PermGen space 是 JDK7及之前, HotSpot 虚拟机 对 方法区 的一个落地实现。HotSpot jdk1.6 的 PermGen space 如下:

image-20230726104347027

HotSpot 也有去永久代的趋势,在 JDK 1.7 中 HotSpot 已经开始了“去永久化”,把原本放在永久代的字符串常量池移出。

HotSpot 1.7 永久代主要存放常量、类信息、静态变量等数据,与垃圾回收关系不大,新生代和老年代是垃圾回收的主要区域。
永久代 在JDK8被移除, JDK1.8方法区 叫做 元空间:

image-20230726110612147

Metaspace(元空间)是 JDK8及之后, HotSpot 虚拟机 对 方法区 的新的实现。

💖 九,你知道的几种主要的JVM参数

1,思路:

可以说一下堆栈配置相关的,垃圾收集器相关的,还有一下辅助信息相关的。

2,参考答案:

(1)堆栈配置相关

  • -Xmx3550m: 最大堆大小为3550m。

  • -Xms3550m: 设置初始堆大小为3550m。

  • -Xmn2g: 设置年轻代大小为2g。

  • -Xss128k: 每个线程的堆栈大小为128k。

  • -XX:MaxPermSize: 设置持久代大小为16m

  • -XX:NewRatio=4: **设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代),比例为1:4

    **-XX:SurvivorRatio=4: 设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6

  • -XX:MaxTenuringThreshold=0: **设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。
    **(2)垃圾收集器相关

  • -XX:+UseParallelGC: 选择垃圾收集器为并行收集器。

  • –XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器组合

  • -XX:ParallelGCThreads=20: 配置并行收集器的线程数

  • -XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组合

  • -XX:CMSFullGCsBeforeCompaction**:由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。**

  • -XX:+UseCMSCompactAtFullCollection: **打开对年老代的压缩。可能会影响性能,但是可以消除碎
    **

(3)辅助信息相关

  • -XX:+PrintGC 输出形式:

    [GC 118250K->113543K(130112K), 0.0094143 secs] [Full GC 121376K->10414K(130112K),
    0.0650971 secs]
    
  • -XX:+PrintGCDetails 输出形式:

    [GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633
    secs] [GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K),
    0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs
    

    image-20230726111215878image-20230726111239265

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis(四)—— Redis基本的事务操作、Redis实现乐观锁

一、Redis基本的事务操作 首先声明: redis的单条命令是保证原子性的(回想一下setnx k1 v1 k5 v5命令如果k1已经存在,那么k5也会设置失败)但是redis的事务不保证原子性!见下面“1.2 某条命令有错怎么办?”…

Ueditor 百度强大富文本Springboot 项目集成使用(包含上传文件和上传图片的功能使用)简单易懂,举一反三

Ueditor 百度强大富文本Springboot 项目集成使用 首先如果大家的富文本中不考虑图片或者附件的情况下,只考虑纯文本且排版的情况下我们可以直接让前端的vue来继承UEditor就可以啦。但是要让前端将那几个上传图片和附件的哪些功能给阉割掉! 然后就是说如…

SpringMvc+Mybatis完整项目

0目录 1.SpringmybatisSpringmvc查询功能(记录数) 2.查询所有 3.增删改查(根据id) 4.增加用户注册登录功能 1.SpringmybatisSpringmvc增删改查 新建数据库 创建工程 配置web.xml 配置applicationContext.xml 实体类 My…

SpringBoot 配置⽂件

1.配置文件作用 整个项⽬中所有重要的数据都是在配置⽂件中配置的,⽐如: 数据库的连接信息(包含⽤户名和密码的设置);项⽬的启动端⼝;第三⽅系统的调⽤秘钥等信息;⽤于发现和定位问题的普通⽇…

EMP-SSL: TOWARDS SELF-SUPERVISED LEARNING IN ONETRAINING EPOCH

Recently, self-supervised learning (SSL) has achieved tremendous success in learning image representation. Despite the empirical success, most self-supervised learning methods are rather “inefficient” learners, typically taking hundreds of training epoch…

MySQL高可用之MHA集群

目录 一、MHA概述 1.1 什么是 MHA 1.2 MHA 的组成 1.3 MHA 的特点 二、MySQL MHA搭建准备 2.1 实验思路 2.2 实验准备 MHA一主两从高可用集群示意图: 三、搭建 MySQL MHA 3.1 配置主从复制 1、四台服务器都关闭防火墙 2、修改 Master、Slave1、Slave2 节…

汇编调用C语言定义的全局变量

在threadx移植中,系统的systick通过了宏定义的方式定义,很难对接库函数的时钟频率,不太利于进行维护 所以在C文件中自己定义了一个systick_Div的变量,通过宏定义方式设定systick的时钟频率 在汇编下要加载这个systick分频系数 …

STM32 串口基础知识学习

串行/并行通信 串行通信:数据逐位按顺序依次传输。 并行通信:数据各位通过多条线同时传输。 对比 传输速率:串行通信较低,并行通信较高。抗干扰能力:串行通信较强,并行通信较弱。通信距离:串…

在Windows server 2012上使用virtualBox运行CentOS7虚拟机,被强制休眠(二)

问题场景 本月7月10日处理了一个虚拟机被强制暂停的问题,详见:在Windows server 2012上使用virtualBox运行CentOS7虚拟机,被强制暂停当时是由于C盘存储空间不足,导致虚拟机被强制暂停,将虚拟机迁移后,问题…

Mybatis-plus 配置自定义sql(.xml文件)查询语句的步骤

这是使用Mybatis-plus 的自动生成实体类代码生成.xml文件, 所以他会在java目录下,不在resources目录下 如果在java目录下的xml文件,需要分别配置application.yml和pom.xml文件 application.yml 文件进行以下配置: mybatis-plus…

【C刷题】矩阵相等判断与序列中删除指定的数字

目录 BC105-矩阵相等判断 方法1:两矩阵输入完毕后,进行比较 方法2:在接收过程中直接比较 BC98 - 序列中删除指定的数字 方法1:把要删除的元素改为0 方法2:打印不用删除的元素 方法3:定义两个下标 i 和 j(动图演示) 此篇文章是关于牛客网刷题的做题思路和代码…

Docker的数据管理和Dockerfile的指令

Docker的数据管理 一、Docker数据的概念1、数据卷2、数据卷容器 二、端口映射三、容器互联(使用centos镜像)四、Docker 镜像的创建1、基于现有镜像创建(1)首先启动一个镜像,在容器里做修改(2)然…

记录Selenium自动化测试过程中接口的调用信息

上一篇博客,我写了python自动化框架的一些知识和粗浅的看法,在上一篇中我也给自己提出一个需求:如果记录在测试过程中接口的调用情况?提出这个需求,我觉得是有意义的。你在测试过程中肯定会遇到一些莫名其妙的问题&…

K8S故障排查

故障现象:部署pod时,报错没发调度到节点。 排查步骤: 1、查看集群的状态 [rootk8s-master1 nginx]#kubectl get nodes2、查看k8s组件的状态-kubelet,kube-apiservice 3、查看docker的Cgroup driver和k8s的Cgroup driver类型&…

创建Electron项目

一、使用vite 构建 electron项目 npm init vitelatest Need to install the following packages:create-vitelatest Ok to proceed? (y) y √ Project name: ... CertificateDownload √ Package name: ... certificatedownload √ Select a framework: Vue √ Select a var…

Packet Tracer - 配置和验证 NTP

Packet Tracer - 配置和验证 NTP 地址分配表 设备 接口 IP 地址 子网掩码 N1 NIC 209.165.200.225 255.255.255.0 R1 G0/0 209.165.200.226 255.255.255.0 R2 G0/0 209.165.200.227 255.255.255.0 目标 在本练习中,您将在 R1 和 R2 中配置 NTP 以…

1.react useState使用与常见问题

文章目录 0. 取消批处理合并更新, render 2次1. 合并更新,setCount(异步更新) 3次相当于1次, count值为12. 如何取消批处理合并,让值累加?,改为回调函数写法,内部会依次执行函数, 执行3次 count值为33. 异步更新,获取异步更新的值?useEffect4.利用扩展运算符的形式来解决对象…

NSS [SWPUCTF 2021 新生赛]pop

NSS [SWPUCTF 2021 新生赛]pop 倒推一下,最后一步是调用getflag函数,admin和password要求为w44m和08067。 第一步应该从w22m类的魔术方法__destruct()入手,所以中间第二步应该是w33m(第一步w22m类的魔术方法__destruct()里面的ec…

【LeetCode热题100】打卡第44天:倒数第30~25题

文章目录 【LeetCode热题100】打卡第44天:倒数第30~25题⛅前言 移动零🔒题目🔑题解 寻找重复数🔒题目🔑题解 二叉树的序列化与反序列化🔒题目🔑题解 最长递增子序列🔒题目&#x1f5…

pytorch分类和回归:阿里天池宠物年龄预测

文章目录 dog年龄预测论文Deep expectation of real and apparent age from a single image without facial landmarks分类的损失函数1.多分类交叉熵损失函数:2.KLDiv Loss: 分布差异3.facenet 三元组损失函数 timm and torchvisiontorchvision 尝试一&a…
最新文章