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

【Java】JVM

一、介绍

1.什么是JVM?

  1. JVM是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的。
  2. JVM包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个存储方法域。
  3. JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

在这里插入图片描述

JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。

2.JDK、JRE、JVM是什么关系?

  1. JDK(Java Development Kit),Java 语言的软件开发工具包,是开发者用来编译、调试程序用的开发包。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。JDK也是Java程序需要在JRE上运行。

JDK包含的基本组件包括

  • javac – 编译器,将源程序转成字节码
  • jar – 打包工具,将相关的类文件打包成一个文件
  • javadoc – 文档生成器,从源码注释中提取文档
  • jdb – debugger,查错工具
  • java – 运行编译后的java程序(.class后缀的)
  • appletviewer:小程序浏览器,一种执行HTML文件上的Java小程序的Java浏览器。
  • Javah:产生可以调用Java过程的C过程,或建立能被Java程序调用的C过程的头文件。
  • Javap:Java反汇编器,显示编译类文件中的可访问功能和数据,同时显示字节代码含义。
  • Jconsole: Java进行系统调试和监控的工具
  1. JRE(Java Runtime Environment),也就是Java平台。所有的Java程序都要在JRE环境下才能运行。

JRE包括

  • 一个Java虚拟机(Java Virtual Machine,JVM)
  • 一些标准的类别函数库(Class Library
  1. JVM(Java Virtual Machine),是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

在这里插入图片描述

  • JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。
  • Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。

3.JVM原理

  1. JVM是Java的核心和基础,在Java编译器和OS平台之间的虚拟处理器,可在上面执行字节码程序。
  2. Java编译器只要面向JVM,生成JVM能理解的字节码文件。Java源文件经编译成字节码程序,通过JVM将每条指令翻译成不同的机器码,通过特定平台运行。

在这里插入图片描述

  • 线程私有区域:Java栈、本地方法栈、程序计数器;
  • 线程私有区域不会有垃圾回收;
  • 方法区属于特殊的堆;
  • JVM调优几乎都是调整堆;

4.JVM体系结构:

  • 类加载器:加载class文件;
  • 运行时数据区:包括方法区、堆、Java栈、程序计数器、本地方法栈
  • 执行引擎:执行字节码或者执行本地方法

在这里插入图片描述

二、运行时数据区

  • 方法区:属于共享内存区域,存储已被虚拟机加载的类信息常量静态变量即时编译器编译后的代码等数据。运行时常量池存在方法区中。

  • :Java虚拟机所管理的内存中最大的一块,一个JVM只有一个堆,堆的大小可以调节,唯一的目的是存放对象实例。由于是垃圾收集器管理的主要区域,因此有时候也被称作GC堆。

  • :用于描述Java方法执行的模型。每个方法在执行的同时都会创建一个栈帧,用于存储8大数据类型对象的引用局部变量表操作数栈动态链接方法出口等信息。每一个方法从调用至执行完成,对应于一个栈帧在虚拟机栈中从入栈到出栈。

  • 程序计数器:当前线程所执行字节码的行号指示器。每一个线程都有一个独立的程序计数器,线程的阻塞、恢复、挂起等一系列操作都需要程序计数器的参与,因此必须是线程私有的。

  • 本地方法栈:与虚拟机栈作用相似,只不过虚拟机栈为执行Java方法服务,而本地方法栈为执行Native方法服务,比如在Java中调用C/C++

三、类加载机制

类加载器通过一个类的全限定名来获取描述此类的二进制文件流的代码模块。

1. 类的生命周期(7个)

加载、验证、准备、解析、初始化、使用、卸载

2. 类加载的五个过程

虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、装换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型。

  • 加载:类加载器获取二进制字节流,将静态存储结构转化为方法区的运行时数据结构,并生成此类的Class对象,即把字节码通过二进制的方式转化到方法区中的运行数据区。

  • 验证:验证文件格式、元数据、字节码、符号引用,确保Class的字节流中包含的信息符合当前虚拟机的要求。

  • 准备:为类变量分配内存并设置其初始值,这些变量使用的内存都将在方法区中进行分配。

  • 解析:将常量池内的符号引用替换为直接引用,包括类或接口的解析、字段解析、类方法解析、接口方法解析。

  • 初始化:前面过程都是以虚拟机主导,而初始化阶段开始执行类中的 Java 代码。

3. 类加载器

  • 启动类加载器(BootStrap ClassLoader):主要负责加载jre/lib/rt.jar相关的字节码文件的。

  • 扩展类加载器(Extension Class Loader):主要负载加载 jre/lib/ext/*.jar 这些jar包的。

  • 应用程序类加载器(Application Class Loader):主要负责加载用户自定义的类以及classpath环境变量所配置的jar包的。

  • 自定义类加载器(User Class Loader):负责加载程序员指定的特殊目录下的字节码文件的。大多数情况下,自定义类加载器只需要继承ClassLoader这个抽象类,重写findClass()和loadClass()两个方法即可。

4. 类加载机制(双亲委派)

类的加载是通过双亲委派模型来完成的,双亲委派模型即为下图所示的类加载器之间的层次关系。

在这里插入图片描述

  • 工作过程:如果一个类加载器接收到类加载的请求,它会先把这个请求委派给父加载器去完成,只有当父加载器反馈自己无法完成加载请求时,子加载器才会尝试自己去加载。可以得知,所有的加载请求最终都会传送到启动类加载器中。

5. JVM类初始化顺序

  1. 父类静态代码块和静态成员变量
  2. 子类静态代码块和静态成员变量
  3. 父类代码块和普通成员变量
  4. 父类构造方法
  5. 子类代码块和普成员变量
  6. 子类构造方法

6. 对象的创建过程

  1. 检查:类是否已被加载,没有加载就先加载类

  2. 分配内存空间:使用 new 关键字在堆内存中分配一块空间,使用CAS方式分配,防止在为A分配内存时,执行当前地址的指针还没有来得及修改,对象B就拿来分配内存。

  3. 初始化对象头:在分配的内存空间中,Java 虚拟机会为对象头分配一定的空间,用于存储对象的元数据信息,如对象的类型、哈希码、GC 信息等。

  4. 执行构造方法:在对象头初始化完成后,Java 虚拟机会调用对象的构造方法,对对象进行初始化,包括成员变量的赋值、方法的调用等。

  5. 返回对象引用:构造方法执行完毕后,会返回对象的引用,该引用可以被赋值给变量,或者作为参数传递给其他方法。

7. 对象头中有哪些信息

对象头中有两部分:

  • 一部分是MarkWork,存储对象运行时的数据,如对象的hashcode、GC分代年龄、GC标记、锁的状态、获取到锁的线程ID等;
  • 另外一部分是表明对象所属类,如果是数组,还有一个部分存放数组长度。

四、垃圾回收

GC(Garbage Collection)垃圾收集,回收垃圾,释放内存。

程序计数器、虚拟机栈、本地方法栈是线程私有的,所以会随着线程结束而消亡。 Java 堆和方法区是线程共享的,在程序处于运行期才知道哪些对象会创建,这部分内存的分配和回收都是动态的,垃圾回收所关注的就是这部分内存。

GC的目的实现内存的自动释放,使用可达性分析法判断对象是否可回收,采用了分代回收思想,将堆分为新生代、老年代,新生代中采用复制算法,老年代采用整理算法,当新生代内存不足时会minorGC,老年代不足时会fullGC

1、判断对象已死

在进行内存回收之前要做的事情就是判断那些对象是‘死’的,哪些是‘活’的。

引用计数法
给对象中添加一个引用计数器,当一个地方引用了对象,计数加1;当引用失效,计数器减1;当计数器为0表示该对象已死、可回收;

注意:如果不下小心直接把 Obj1-reference 和 Obj2-reference 置 null。则在 Java 堆当中的两块内存依然保持着互相引用无法回收。引用计数法很难解决循环引用问题;

可达性分析
通过一系列的 ‘GC Roots’ 的对象作为起始点,从这些节点出发所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连的时候说明对象不可用。

可作为 GC Roots 的对象

  1. 虚拟机栈中引用的对象
  2. 方法区中类静态属性引用的对象
  3. 方法区中常量引用的对象
  4. 本地方法栈中native方法引用的对象

引用:下面四种引用强度依次减弱

  • 强引用:默认情况下,对象采用的均为强引用(new的对象)。哪怕内存溢出也不会回收
  • 软引用:SoftReference 类实现软引用。在系统要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行二次回收(只有内存不足时才会回收)。
  • 弱引用:WeakReference 类实现弱引用。对象只能生存到下一次垃圾收集之前。在垃圾收集器工作时,无论内存是否足够都会回收掉只被弱引用关联的对象。
  • 虚引用:PhantomReference 类实现虚引用。无法通过虚引用获取一个对象的实例,为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

什么情况下会内存溢出

  • 堆内存溢出:
  1. 当对象一直创建而不被回收时
  2. 加载的类越来越多时
  3. 虚拟机栈的线程越来越多时
  • 栈溢出:方法调用次数过多,一般是递归不当造成

2、垃圾收集算法

  • 标记清除算法:先标记出所有需要回收的对象,标记完成后统一回收所有被标记的对象。
  • 复制算法:将可用内存分为大小相等的两块,每次只使用其中一块,当这一块内存用完了,就将存活的对象复制到另一块,最后- 将此块内存一次性清理掉。
  • 标记整理算法:先标记所有需要回收的对象,然后让所有存活的对象向一端移动,最后直接清理掉边界以外的另一端内存。
  • 分代收集算法:把Java堆分为新生代和老年代。新生代中只有少量对象会存活,就选用复制算法;老年代中对象存活率较高,选用标记清除算法。

3、垃圾收集器

  • Serial收集器:单线程收集器。收集垃圾时必须暂停其他所有工作线程,直到它收集结束。
  • Parnew收集器:Serial收集器多线程版本。
  • Parallel Scavenge收集器:使用复制算法的新生代收集器。
  • Serial Old收集器:使用标记-整理算法的老年代单线程收集器。
  • Parallel Old收集器:使用标记-整理算法的老年代多线程收集器。
  • CMS收集器:基于标记-清除算法的低停顿并发收集器。运作步骤为①初始标记②并发标记③重新标记④并发清除。
  • G1收集器:最前沿的面向服务端应用的垃圾收集器。运作步骤为①初始标记②并发标记③最终标记④筛选回收。

CMS:收集器有以下特点

  1. 以最小的停顿时间为目标,优先降低GC停顿时间(相对地降低吞吐量)。
  2. 只运行在老年代的垃圾回收器。
  3. 使用标记-清除算法,可以并发收集。

G1收集器有以下特点

  1. 并行与并发:无需停顿Java线程来执行GC动作。
  2. 分代收集:可独立管理整个GC堆。
  3. 空间整合:运行期间不会产生内存空间碎片。
  4. 可预测的停顿:除了低停顿,还能建立可预测的停顿时间模型。

4、JVM内存分代机制

方法区即被称为永久代,而堆中存放的是对象实例,为了回收的时候对不同的对象采用不同的方法,又将堆分为新生代和老年代,默认情况下新生代占堆的1/3,老年代占堆的2/3。
在这里插入图片描述

注意:逻辑上存在,物理上不存在

新生代(Young)
HotSpot将新生代划分为三块,一块较大的Eden(伊甸园)空间和两块较小的Survivor(幸存)空间,默认比例为8:1:1。

老年代(Old)
在新生代中经历了多次GC后仍然存活下来的对象会进入老年代中。老年代中的对象生命周期较长,存活率比较高,在老年代中进行GC的频率相对而言较低,而且回收的速度也比较慢。

永久代(Permanent):永久代存储类信息、常量、静态变量、即时编译器编译后的代码等数据,对这一区域而言,一般而言不会进行垃圾回收。

元空间(metaspace)
从JDK 8开始,Java开始使用元空间取代永久代,元空间并不在虚拟机中,而是直接使用本地内存。那么,默认情况下,元空间的大小仅受本地内存限制。当然,也可以对元空间的大小手动的配置。

GC 过程
新生成的对象在Eden区分配(大对象除外,大对象直接进入老年代),当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC。

  • GC开始时,对象只会存在于Eden区和Survivor From区,Survivor To区是空的(作为保留区域)。
  • GC进行时,Eden区中所有存活的对象都会被复制到Survivor To区,而在Survivor From区中,仍存活的对象会根据它们的年龄值决定去向,年龄值达到年龄阀值(默认为15,新生代中的对象每熬过一轮垃圾回收,年龄值就加1,GC分代年龄存储在对象的Header中)的对象会被移到老年代中,没有达到阀值的对象会被复制到Survivor To区。接着清空Eden区和Survivor From区,新生代中存活的对象都在Survivor To区。
  • 接着,Survivor From区和Survivor To区会交换它们的角色,也就是新的Survivor To区就是上次GC清空的Survivor From区,新的Survivor From区就是上次GC的Survivor To区,总之,不管怎样都会保证Survivor To区在一轮GC后是空的。
  • GC时当Survivor To区没有足够的空间存放上一次新生代收集下来的存活对象时,需要依赖老年代进行分配担保,将这些对象存放在老年代中。

5、Minor GC、Major GC、Full GC之间的区别

Minor GC
Minor GC指新生代GC,即发生在新生代(包括Eden区和Survivor区)的垃圾回收操作,当新生代无法为新生对象分配内存空间的时候,会触发Minor GC。因为新生代中大多数对象的生命周期都很短,所以发生Minor GC的频率很高,虽然它会触发stop-the-world,但是它的回收速度很快。

Major GC
指发生在老年代的垃圾收集动作,出现了 Major GC,经常会伴随至少一次 Minor GC(非绝对),MajorGC 的速度一般会比 Minor GC 慢10倍以上。

Full GC
Full GC是针对整个新生代、老生代、元空间(metaspace,java8以上版本取代perm gen)的全局范围的GC。Full GC不等于Major GC,也不等于Minor GC+Major GC,发生Full GC需要看使用了什么垃圾收集器组合,才能解释是什么样的垃圾回收。

6、Minor GC、Major GC、Full GC触发条件

Minor GC触发条件
虚拟机在进行minorGC之前会判断老年代最大的可用连续空间是否大于新生代的所有对象总空间

  1. 如果大于的话,直接执行minorGC
  2. 如果小于,判断是否开启HandlerPromotionFailure,没有开启直接FullGC
  3. 如果开启了HanlerPromotionFailure, JVM会判断老年代的最大连续内存空间是否大于历次晋升(晋级老年代对象的平均大小)平均值的大小,如果小于直接执行FullGC
  4. 如果大于的话,执行minorGC

Full GC触发条件

  1. 老年代空间不足:如果创建一个大对象,Eden区域当中放不下这个大对象,会直接保存在老年代当中,如果老年代空间也不足,就会触发Full GC。为了避免这种情况,最好就是不要创建太大的对象。
  2. 方法区空间不足:系统当中需要加载的类,调用的方法很多,同时方法区当中没有足够的空间,就出触发一次Full GC
  3. 老年代最大可用连续空间小于Minor GC历次晋升到老年代对象的平均大小
  4. 调用System.gc()时(系统建议执行Full GC,但是不必然执行)

五、JVM监控和调优

工具:

  • Eclipse里面有 Eclipse Memory Analyzer tool(MAT)插件可以测试
  • Idea中也有这么一个插件,就是JProfiler

命令:

-Xms 设置初始化内存分配大小,默认 1/64
-Xmx 设置最大分配内存,默认 1/4
-XX:+PrintGCDetails 打印GC垃圾回收信息
-XX:+HeapDumpOnOutOfMoryError OOM DUMP-Xmx[]:堆空间最大内存-Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的-Xmn[]:新生代的最大内存-xx:[survivorRatio=3]:eden区与from+to区的比例为31,默认为41-xx[use 垃圾回收器名称]:指定垃圾回收器-xss:设置单个线程栈大小一般设堆空间为最大可用物理地址的百分之80

相关文章:

【Java】JVM

一、介绍 1.什么是JVM? JVM是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的。JVM包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个存储方法域。JVM屏…...

Linux 和数据库笔记-06

今日内容介绍全天内容无需立马掌握MySQL 的高级功能应用数据库设计ER模型定义: E 代表实体(数据表), R 代表联系(数据表之间对应的字段)![image-20200530092701017](Linux 和数据库 day06 随堂笔记.assets/image-20200530092701017.png)关系常见分类一对一一对多多对多外键如果…...

MySQL面试题-事务篇

1.事务的特性(ACID) 事务(Transaction)是指一组操作被看作是一个不可分割的工作单元,这组操作要么全部执行成功,要么全部执行失败。事务的特性通常用 ACID 四个单词来描述,它们分别代表原子性&…...

Linux嵌入式开发 | 汇编驱动LED(1)

文章目录🚗 🚗Linux嵌入式开发 | 汇编驱动LED(1)🚗 🚗初始化IO🚗 🚗STM32🚗 🚗使能GPIO时钟🚗 🚗设置IO复用🚗 &#x1f6…...

什么是EventLoop?怎么测试Node或页面的性能

Event Loop 机制大家应该都有了解。本文利用 EventLoop 去做一个有趣的检测node或页面性能的代码,顺便介绍了一下EventLoop,希望对大家有所帮助! Event Loop Event Loop 机制大家应该都有了解。我先重复总结一下。 Node.js 和 Javascript 的…...

1018 锤子剪刀布 1025 反转链表

现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。 输入格式: 输入第 1 行给出正整数 N(≤10 5 ),即双方交锋的次数。随后 N 行,每行给出一次交锋的信…...

卷积神经网络的原理及实现

专栏:神经网络复现目录 卷积神经网络 本章介绍的卷积神经网络(convolutional neural network,CNN)是一类强大的、为处理图像数据而设计的神经网络。 基于卷积神经网络架构的模型在计算机视觉领域中已经占主导地位,当今…...

【C++知识点】重载

✍个人博客:https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 📚专栏地址:C/C知识点 📣专栏定位:整理一下 C 相关的知识点,供大家学习参考~ ❤️如果有收获的话,欢迎点赞👍…...

apscheduler三种定时触发方式

#第一种# date: 特定的时间点触发# 2019-01-01 00:00:00 准时执行# import time # from apscheduler.schedulers.blocking import BlockingScheduler # # def my_job(): # print(time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(time.time()))) # sched BlockingSchedu…...

802.11 service服务类型

802.11 serviceservice定义service分类按照模块分为两类按照功能分为六类数据传输相关服务分布式服务DS(Distribution Service)整合服务IS(Integration Service)关联(association)重关联(reasso…...

pytest测试框架——allure报告

文章目录一、allure的介绍二、allure的运行方式三、allure报告的生成方式一、在线报告、会直接打开默认浏览器展示当前报告方式二、静态资源文件报告(带index.html、css、js等文件),需要将报告布置到web服务器上。四、allure中装饰器1、实现给…...

SQLI-Labs(3)8-14关【布尔盲注和时间盲注】

目录 第八关 第九关: 第十关 第十一关 第十二关 第十三关 第十四关 第八关 我们用测试语句来测试是否为注入点 从上图中得知存在注入点,那么接下来就是爆列 一共有三列,接下来用union select 和报错注入都试一下发现没有回显点&…...

ESP32学习笔记03-日志打印

ESP32日志 日志分为5个等级 ESP_LOGE - error (lowest)ESP_LOGW - warningESP_LOGI - infoESP_LOGD - debugESP_LOGV - verbose (highest)API 0.头文件 #include "esp_log.h"1.给一个日志标签设置等级...

mongoTemplate非string类型模糊查询

需求 为方便使用人员对任务Task的搜索,需要根据number实现模糊搜索。 背景 之前设计的number是long类型,但是mongodb只支持string类型的正则匹配。 方案 修改number为string类型;新增一个冗余字段,用于模糊查询;在…...

Redis是单线程还是多线程?Redis的10种数据类型,有哪些应用场景?

目录专栏导读一、同样是缓存,用map不行吗?二、Redis为什么是单线程的?三、Redis真的是单线程的吗?四、Redis优缺点1、优点2、缺点五、Redis常见业务场景六、Redis常见数据类型1、String2、List3、Hash4、Set5、Zset6、BitMap7、Bi…...

到底什么才是幻读?

💗推荐阅读文章💗 🌸JavaSE系列🌸👉1️⃣《JavaSE系列教程》🌺MySQL系列🌺👉2️⃣《MySQL系列教程》🍀JavaWeb系列🍀👉3️⃣《JavaWeb系列教程》…...

RPC重试机制和控制方案

重试机制 因为网络抖动等原因导致 RPC 调用失败,这时候使用重试机制可以提高请求的最终成功率,减少故障影响,让系统运行更稳定。 重试简易实现方案 在重试的过程中,为了能够在约定的时间内进行安全可靠地重试,在每次…...

【无标题】动态给结构体赋值

#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int id; char name[20]; double score; } Student; int main() { Student *p (Student *)malloc(sizeof(Student)); if (p NULL) { printf(“Memory allocation failed.”…...

centos7 soft raid每周自动同步的问题

之前redhat老版本时也遇到过这样的问题https://blog.csdn.net/jolly10/article/details/108768360centos7解决的办法略有不同&#xff0c;记录一下&#xff1a;centos7默认是每周日凌晨1点进行raid检查&#xff0c;有点太频繁了[oracleqht117 data]$ ls /etc/cron*/etc/cron.de…...

嵌入式Linux内核代码风格

这是一个简短的文档&#xff0c;描述了linux内核的首选代码风格。代码风格是因人而异的&#xff0c;而且我 不愿意把我的观点强加给任何人&#xff0c;不过这里所讲述的是我必须要维护的代码所遵守的风格&#xff0c; 并且我也希望绝大多数其他代码也能遵守这个风格。请在写代码…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...