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

【jvm系列-07】深入理解执行引擎,解释器、JIT即时编译器

JVM系列整体栏目


内容链接地址
【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460
【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963
【三】运行时私有区域之虚拟机栈、程序计数器、本地方法栈https://blog.csdn.net/zhenghuishengq/article/details/129684076
【四】运行时数据区共享区域之堆、逃逸分析https://blog.csdn.net/zhenghuishengq/article/details/129796509
【五】运行时数据区共享区域之方法区、常量池https://blog.csdn.net/zhenghuishengq/article/details/129958466
【六】对象实例化、内存布局和访问定位https://blog.csdn.net/zhenghuishengq/article/details/130057210
【七】执行引擎,解释器、JIT即时编译器https://blog.csdn.net/zhenghuishengq/article/details/130088553

深入理解执行引擎,解释器、JIT即时编译器

  • 一,深入理解执行引擎
    • 1,执行引擎的概述
    • 2,Java代码编译和执行的过程
      • 2.1,解释器和编译器
      • 2.2,机器码、指令、汇编语言、高级语言
      • 2.3,解释器和编译器工作机制(重点)
      • 2.4,JIT编译器的热点代码和热点探测
      • 2.5,方法调用计数器和回边计数器
        • 2.5.1,方法调用计数器
        • 2.5.2,回边计数器
      • 2.6,编译器和解释器设置

一,深入理解执行引擎

1,执行引擎的概述

在JVM整个体系中,执行引擎属于第三层,主要用来执行具体的字节码文件。本文主要探讨的就是这个执行引擎。
在这里插入图片描述

执行引擎是Java虚拟机核心组成的一部分,“虚拟机” 是一个相对于 “物理机” 的一个概念,这两种机器都有执行代码的能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统的层面上的,而虚拟机的执行引擎是由软件自行实现的,因此可以不受物理条件制约的指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的格式。java虚拟机可以理解成一个抽象的计算机,相较于真正的物理机而言,java虚拟机的执行效率会略慢于物理机。

JVM的主要任务是负责装载字节码到其内部,但字节码并不能够直接运行在操作系统上面,因为字节码指令并非等价于本地机器指令,他内部包含的仅仅是一些能够被JVM识别的字节码指令等信息。如下图所示,这些字节码指令不能直接在操作系统上解释执行,而是需要现通过jvm虚拟机来执行这些字节码指令。

在这里插入图片描述

因此,执行引擎的主要作用就是:将字节码指令解释成或者编译成对应平台上面的本地机器指令 ,简单的来说,JVM中的执行引擎充当了将高级语言翻译成机器语言的翻译者

执行引擎在执行过程中,其需要的具体的字节码指令完全依赖于程序计数器,每当完成一项操作指令之后,程序计数器就会更新下一条需要被执行的指令地址。在方法的执行全过程中,执行引擎有可能会通过存储在局部变量表的对象引用准确的的获取存储在Java堆中的对象实例信息,以及通过对象头中的元数据指针定位到目标对象的类型信息。

2,Java代码编译和执行的过程

大部分的程序代码在转换成物理机的目标代码或者虚拟机能执行的指令集之前,都需要经历过几下几个步骤

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P1ERSNco-1681204070128)(img/1681115841091.png)]

🧢 前面的黄线流程代表的就是将 .java 文件编译成 .class 文件,属于是前端编译;

🧢 绿色部分属于解释器解释执行的过程,即逐行翻译、解释、执行的过程;

🧢 蓝色部分属于是JIT即时编译器编译性阶段,属于是后端编译。

2.1,解释器和编译器

解释器:当Java虚拟机启动的时候,会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容翻译成对应平台的本地机器指令

JIT编译器:jit,又名Just In Time Compiler , 就是直接将源代码编译成和本地平台相关的机器语言。

在java语言中,是既可以通过解释器来执行代码,也可以通过编译器来执行代码的,这二者都可以达到相同的目的,并且这二者以合作的方式相辅相成,取长补短,以最合适的方法让Java内部执行的效率更高。JVM虚拟机不仅仅是针对于Java语言,只要遵循Jvm虚拟机规范的语言,都可以使用JVM虚拟机解释执行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0OS32FeS-1681204070128)(img/1681179087753.png)]

如上图,将不同的语言通过统一处理,生成对应的字节码文件,然后通过虚拟机中的解释器或者JIT即时编译器对这些字节码进行解释执行,然后翻译成对应的字节码指令,最后将这些指令全部存储在方法区的CodeCache中。

2.2,机器码、指令、汇编语言、高级语言

1,机器码

各种用二进制编码方式表示的指令,叫做 机器指令码 ,如通过01010101 这种二进制的方式进行编码,最开始人们就用它编写程序,这就是 机器语言。机器语言虽然可以被计算机接收,但是和人们的语言差别太大,不易被人家理解和记忆,用它变成也容易出错。用它编写的程序,一经输入计算机,CPU直接读取运行,因此和其他语言的程序,执行速度最快。机器指令和CPU紧密相关,因此不同类型的CPU所对应的机器指令也就不同。

2,指令

由于机器码是由0和1的二进制组成,可读性实在是太差,于是人们发明了指令。指令就是把机器码特定的 0和1 序列,简化成了对应的指令,如mov和inc等,可读性好。但是由于不同的硬件平台,执行同一个操作,其对应的字节码可能会不同,所以不同硬件平台的同一种指令,对应的机器码也可能不同。在不同的硬件平台,各自支持各自的指令,每个平台所支持的指令总和,称之为对应平台的 指令集

3,汇编语言

又由于指令的可读性差,于是又发明了这个汇编语言。在汇编语言中,用助记符代替机器指令的操作码,用地址符号代替指令或者操作数的地址。在不同的硬件平台,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令,由于计算机只认识指令码,所以用汇编语言编写的程序还必须翻译成机器指令码,计算机才能识别。

4,高级语言

高级语言比上述语言接近人的语言,如当今流行的c或者c++,当计算机执行高级语言的时候,仍然需要把程序解释或者编译成机器指令码,完成这个过程的程序就叫做解释程序或者编译程序。因此不管是汇编语言还是这个高级语言,都需要最终生成这个机器指令,然后将这个机器指令放在CPU上面操作,最终解释执行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LHIXoJmv-1681204070129)(img/1681181185924.png)]

字节码属于是一种中间状态的二进制代码,他比机器码更加抽象,需要直译器转译后才能成为机器码,与硬件环境无关,可以直接通过编译器或者虚拟机器,将源码编译成字节码。

2.3,解释器和编译器工作机制(重点)

解释器真正意义上所承担的角色就是一个 “运行时的翻译者”,就是将字节码中的内容翻译成对应平台的本地机器指令执行。每当一条字节指令被解释执行完成后,接着再根据 程序计数器 中记录的下一条需要被执行的字节码指令执行解释操作。

在JVM平台中,也对解释器进行了优化,采用了一种JIT 的即时编译的技术,目的是避免函数被解释执行,而是将整个函数体编译成机器码,每次函数执行时,只执行编译后的编译码即可,这种方式大大的提升了执行效率。

在hotspot虚拟机中,JIT即时编译器的速度远快于解释器,并且将字节码指令直接生成机器指令,存储在这个方法区的CodeCache中缓存起来,比这个解释器逐行翻译的效率高很多。因此在今天,Java程序的运行性能早以脱胎换骨,已经可以达到和c/c++程序一较高下的地步。

但是即使这个jit即时编译器的速度很快,在HotSpot虚拟机中,依旧保留了这个解释器,原因是JIT即时编译器虽然效率很高,但是需要一定的时间编译成机器码,才能继续工作。但是这个编译器在程序启动之后,可以立马进行工作,省去编译的时间,立即执行。

所以综上两点,在程序启动的时候JIT需要编译,那么就由解释器来执行程序,待JIT即时编译器编译成机器码之后,再由这个JIT即时编译器来完成,这样就能让整个执行引擎发挥最大的效率。因此二者合作共存才能让效率最大化。

2.4,JIT编译器的热点代码和热点探测

Java语言的编译器其实是一段不太确定的操作过程,因为他可能是一指前端编译器(编译器的前端,.java文件编译成 .class文件)的过程,也可能是指后端的编译器(JIT编译器,将字节码转换成机器码)的过程,还有可能是指静态提前编译器,直接把 .java 文件编译成本地机器代码的过程。

在使用这个JIT编译器的时候,需要判断代码被调用执行的频率,对于需要被编译为本地代码的字节码,被称为热点代码 ,JIT编译器在运行时对那些频繁被调用的热点代码会做出深度优化,将其直接编译为对应平台的本地机器指令,以提升Java程序的执行性能。

热点代码 :指的是一个被多次调用的方法,或者是一个方法体内部循环次数较多的循环体,都可以被称为"热点代码"。因此可以通过JIT编译器译为本地机器指令,由于这种编译方式发生在方法的执行过程中,因此也被称为栈上替换。

热点探测方式:而是否可以成为这个热点代码,主要是依靠这个热点探测功能,HotSpot虚拟机主要采用的热点探测方式是基于计数器的热点探测。HotSpot虚拟机又将每个方法建立两个不同类型的计数器,分别是方法调用计数器和回边计数器,方法调用计数器用于统计方法的调用次数,回边计数器用于统计循环体的执行次数。

2.5,方法调用计数器和回边计数器

在JIT的热点探测中,主要是通过计数器的方式来实现对代码的探测,计数器主要分为方法调用计数器和回边计数器。

2.5.1,方法调用计数器

这个计数器主要用于统计方法被调用的次数,它的默认阈值在Client模式下是1500次,在Server模式下是10000次,超过这个阈值,就会触发JIT编译。这个阈值也可以通过虚拟机参数 -XX:CompileThreshold进行设置。当一个方法被调用的时候,会先检查这个方法是否存在被JIT编译过的版本,如果存在,则优先使用编译后的本地代码来执行,如果不存在,则将此方法的调用计数器值加1,然后判断 方法调用计数器和回边计数器 值的和是否超过方法调用计数器的阈值,如果已经超过阈值,那么将会向即时编译器提交一个该方法的代码编译请求。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cqag20eo-1681204070129)(img/1681199074684.png)]

如上图所示,在调用方法时,会先判断该代码是否已经编译,如果已经编译,则直接通过这个JIT即时编译器将机器码生成对应的本地机器码指令;如果未编译,则将方法调用计数器加1,随后回去判断是否超过阈值,如果超过阈值,则会提交编译请求,通过JIT即时编译器进行动态编译,然后将编译后的机器指令缓存在CodeCache中,如果未超过阈值,那么继续通过解释器解释执行。

在JVM内部对调用的次数也做了一定的限制,并不是说一直对调用的次数进行类加,而是在一段时间内记录方法调用的次数,当超过一定的时间限度,如果方法调用的次数依旧没有达到这个阈值,那么方法的调用计数器就会进行一个 衰减 的过程,每次衰减一半,这段衰减的过程被称为方法统计的 半衰周期

进行衰减的动作是虚拟机在垃圾收集的时候顺便进行的,可以使用虚拟机参数 -XX:-UseCounterDecay 来关闭或者开启热度衰减,因此只要系统运行的时间足够长,那么绝大多数的方法都会编译成本地代码。同时也可以通过参数 -XX:CounterHalfLifeTime 设置半衰周期的时间,单位是s

2.5.2,回边计数器

主要是统计一个方法中的循环体的执行次数,在字节码中遇到流控流向后跳转的指令称为 “回边” 。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m3jwSAYv-1681204070130)(img/1681200519534.png)]

和方法调用计数器一样,会先判断一下该代码是否已经编译,如果未编译,则回边计数器的值加1,然后去判断将当前累加的值和方法调用计数器的值进行累加是否超过阈值,如果超过,则使用JIT编译器,否则依旧使用解释器执行。

2.6,编译器和解释器设置

上述可知在HotSpot虚拟机中存在解释器和编译器,如通过以下命令可以得知,当前虚拟机采用的是一种混合的方式共同执行程序。

java -version

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-opX28PhM-1681204070130)(img/1681201216857.png)]

除了这种之外,也可以通过显式的命令为Java虚拟机指定只由其中一种执行程序,如可以通过以下这个命令设置只使用解释器执行程序

java -Xint -version

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-46WgaCyF-1681204070130)(img/1681201422354.png)]

或者可以通过以下命令只设置使用编译器来执行程序,但是如果编译出现问题,解释器会接入执行

java -Xcomp -version

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yYh338Qn-1681204070131)(img/1681201514979.png)]

当然上面这两种需要在特殊的场景下使用,需要变回混合使用

java -Xmixed -version

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NHAkwa07-1681204070131)(img/1681201587824.png)]

除了可以通过这个命令行设置之外,也可以通过这个虚拟机参数就行设置,其代码如下,通过虚拟机的不同参数设置,可以得到以下答案,纯解释需要花8666ms,纯编译只需要花2ms,混合使用也是1-2ms,因此选择这个混合是最佳的,同时也可以知道使用这个纯编译器的时间远远小于这个纯解释型。

/**** -Xint : 8666ms* -Xcomp:2ms* -Xmixed: 2ms* @author zhenghuisheng* @date : 2023/4/11*/
public class C {public static void main(String[] args) {long start = System.currentTimeMillis();test();long end = System.currentTimeMillis();System.out.println((end - start) + "ms");}public static void test(){int k = 0;for (int i = 0; i < 1000000; i++) {for (int j = 0; j < 1000; j++) {k = i + j;}}}
}

在虚拟机设置那里修改对应的参数即可。

在这里插入图片描述

而在HotSpot虚拟机中内嵌有两个JIT的编译器,分别是Client Compiler和Server Compiler,但是在绝大多数的情况下,这两个编译器被称为C1编译器和C2编译器。
🧢 -client :运行在Client模式下,对字节码进行可靠和简单的优化,耗时短
🧢 -server:运行在Server模式下,对字节码进行耗时长的优化、激进优化,效率更高

C1编译器的优化策略主要有:方法内联、去虚拟化、冗余消除
C2编译器的优化策略主要有:标量替换、栈上分配、同步消除

相关文章:

【jvm系列-07】深入理解执行引擎,解释器、JIT即时编译器

JVM系列整体栏目 内容链接地址【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963【三】运行时私有区域之虚拟机栈…...

【GCU体验】基于PaddlePaddle + GCU跑通模型并测试GCU性能

一、环境 地址&#xff1a;启智社区:https://openi.pcl.ac.cn/ 二、计算卡介绍 云燧T20是基于邃思2.0芯片打造的面向数据中心的第二代人工智能训练加速卡&#xff0c;具有模型覆盖面广、性能强、软件生态开放等特点&#xff0c;可支持多种人工智能训练场景。同时具备灵活的可…...

解析hash(散列)数据结构

前言 在学习完map、set这两个由红黑树构成的容器后&#xff0c;我们来到了这里hash&#xff0c;首先我们要有一个基础的认知——哈希和map与set的仅在使用时的差别区别&#xff1a;前者内部的元素没有序&#xff0c;而后者有序&#xff0c;其它的都相同&#xff0c;这里我们可…...

《2023金融科技·校园招聘白皮书》新鲜出炉|牛客独家

数智创新时代&#xff0c;科技人才为先。 眼下&#xff0c;在建设“数字中国”的时代背景下&#xff0c;金融行业全面数智化转型已箭在弦上。政策端&#xff0c;金融行业为中共中央、国务院印发《数字中国建设整体布局规划》的7大重点行业之一。 资本端&#xff0c;仅2022年三…...

文明的标志:书写系统、修建城市、使用金属器

文章目录 引言I 预备知识1.1 文明”和“文化”概念1.2 文明的标志1.3 应对水患II 定居开启了人类文明2.1 书写系统2.2 陶器2.3 家畜引言 一切和开启文明相关的技术都是围绕着两根主线展开: 多获取能量,以便于生存,信息能够管理起酋邦,总结、记录并传授经验。I 预备知识 1.…...

算法:将一个数组旋转k步

题目 输入一个数组如 [1,2,3,4,5,6,7]&#xff0c;输出旋转 k 步后的数组。 旋转 1 步&#xff1a;就是把尾部的 7 放在数组头部前面&#xff0c;也就是 [7,1,2,3,4,5,6]旋转 2 步&#xff1a;就是把尾部的 6 放在数组头部前面&#xff0c;也就是 [6,7,1,2,3,4,5]… 思路 思…...

使用大华惠智双目半球网络摄像机DH-IPC-HD4140X-E2获取人流量统计数据

记录一下使用Java的SpringBoot大华SDK在智慧公厕项目中使大华惠智双目半球网络摄像机DH-IPC-HD4140X-E2获取人流量统计数据 首先根据说明书登录摄像头&#xff0c;一般摄像头都有自己的账号和密码(可能是admin admin 也可能是admin 888888 还有可能是admin 12345)&#xff0c;…...

DC插装式流量阀压力阀

Cartridge Valves 电磁阀 止回阀 运动控制阀 流量控制阀 溢流阀 压力控制阀 顺序阀 梭阀 方向阀 配件 Zero Profile Valves 止回阀 运动控制阀 流量控制阀 溢流阀 梭阀 In-Line Valves 止回阀和梭阀 方向阀 配件 微型系列 AB20S APIDC-30S C10B C10S C10S…...

NumPy 数组学习手册:6~7

原文&#xff1a;Learning NumPy Array 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 六、性能分析&#xff0c;调试和测试 分析&#xff0c;调试和测试是开发过程的组成部分。 您可能熟悉单元测试的概念。 单元测试是程序员编写的用于测试其代码的自动测试。 例如&…...

【笔试强训选择题】Day6.习题(错题)解析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、Day6习题&#xff08;错题&#xff09;解析 二、Day6习题&#xff08;原题&#xff09;练习 总结 前言 一、Day6习题&#xff08;错题&#xff09;解析…...

磁盘分区-LINUX

1、主分区&#xff08;primary&#xff09; 磁盘在Linux当中的命名&#xff1a; IDE /dev/hda hdb SCSI sda sdb 分区数字表示&#xff1a;sda1 、sda2、sda3 磁盘分区相当于给磁盘打隔断 ① 系统中必须要存在的分区&#xff0c;系统盘选择主分区安装 ② 数字编号只能是1-4&am…...

SpringAOP入门基础银行转账实例(进阶版)------------事务处理

SpringAOP入门基础银行转账实例**&#xff08;进阶版&#xff09;**------------事务处理 由上一节讲述的通过Connection和QueryRunner对事务进行的处理(详情可以去我之前写的博客文章&#xff1a;https://blog.csdn.net/m0_56245143/article/details/130069160?spm1001.2014…...

【python学习】基础篇-常用函数-format函数 格式化操作

format()可以对数据进行格式化处理操作&#xff0c;语法如下: format(value&#xff0c;format_spec) value 为要转换的数据&#xff0c;fommat spec 为格式化解释&#xff0c; 当参数 format spec 为空时&#xff0c;等同于函数 str(value)的方式。 format spec 可以设置非常复…...

团团面试经验

1、Redis同时访问大量不存在的key会发生什么&#xff1f; 如果是缓存和数据库中都不存在&#xff0c;那么就会发生缓存穿透。 举个例子&#xff1a;某个黑客故意制造一些非法的 key 发起大量请求&#xff0c;导致大量请求落到数据库&#xff0c;结果数据库上也没有查到对应的数…...

今天面了个京东拿 38K 出来的,让我见识到了基础的天花板

今年的春招已经开始了&#xff0c;很多小伙伴收获不错&#xff0c;拿到了心仪的 offer。 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的软件测试面试题和八股文&#xff0c;为此咱这里也统一做一次大整理和大归类&#xff0c;这也算是划重点了。 俗话说得好&#xff0…...

Qt创建SDK库(dll动态库)并调用SDK库(dll动态库)

Qt创建SDK库(dll动态库)并调用SDK库(dll动态库) 一、项目场景 在日常的项目中&#xff0c;我们经常会遇到调用别人的数学库、线程库、图形库等操作。这些库通常就被称为SDK&#xff0c;SDK全称是Software Development Kit&#xff08;软件开发工具包&#xff09;&#xff0c;…...

400以内的蓝牙耳机哪款好?400以内蓝牙耳机排行榜

谈起TWS&#xff0c;无论是传统的音频厂商还是手机厂商&#xff0c;都是其不可或缺的重要产品线&#xff0c;现在很多许多蓝牙耳机都不是千篇一律得形状&#xff0c;市场也鲜有商家在外观上下功夫&#xff0c;下面分享几款400元以内&#xff0c;内外兼具的耳机品牌。 一、南卡…...

基于飞桨实现的特定领域知识图谱融合方案:ERNIE-Gram文本匹配算法

文本匹配任务在自然语言处理领域中是非常重要的基础任务&#xff0c;一般用于研究两段文本之间的关系。文本匹配任务存在很多应用场景&#xff0c;如信息检索、问答系统、智能对话、文本鉴别、智能推荐、文本数据去重、文本相似度计算、自然语言推理、问答系统、信息检索等&…...

前端基础复习

1.什么叫HTML5&#xff1f;和原本的所说的HTML有什么区别&#xff1f; 本质上html和html5是一样的的。区别有&#xff1a; 1. 在文档类型声明上 HTML4.0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loos…...

Vue2 API-源码解析

目录 Vue.extend(option) delimiters functional Vue.component(id, Function | Object) Vue.directive( id, [definition] ) Vue.filter( id, function) Vue.nextTick() Vue.set() Vue.delete(target, index/key) Vue.compile(template) Vue.observable(object) …...

FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization

FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization 论文地址&#xff1a;https://arxiv.org/pdf/2303.14189.pdf 概述 本文提出了一种通用的 CNN 和 Transformer 混合的视觉基础模型 移动设备和 ImageNet 数据集上的精度相同的前提下&#xf…...

C/C++文档阅读笔记-A Simple Makefile Tutorial解析

Makefile文件可以使得程序编译变得简单。本博文并不是很系统的讲解makefile&#xff0c;本博文的目标是让读者快速编写自己的makefile文件并能应用到中小项目中。 简单实例 举个例子有下面3个文件&#xff0c;分别是hellomake.c&#xff0c;hellofunc.c&#xff0c;hellomake.…...

GraphSAGE的基础理论

文章目录GraphSAGE原理&#xff08;理解用&#xff09;GraphSAGE工作流程GraphSAGE的实用基础理论&#xff08;编代码用&#xff09;1. GraphSAGE的底层实现&#xff08;pytorch&#xff09;PyG中NeighorSampler实现节点维度的mini-batch GraphSAGE样例PyG中的SAGEConv实现2. …...

Windows 安装 GDAL C++库

Windows 安装 GDAL C库1. 方法1&#xff1a;下载配置网友编译的GDAL版本1.1 下载1.2 配置1.3 测试1.4 缺点2. 方法2&#xff1a;自己编译3. 参考1. 方法1&#xff1a;下载配置网友编译的GDAL版本 1.1 下载 CSDN: GDAL&#xff0c;geos联合编译的库&#xff0c;版本为1.8.0&am…...

二叉树基础概念

1.二叉树种类 1.1 满二叉树 满二叉树&#xff1a;如果一棵二叉树只有度为 0 0 0 的结点和度为 2 2 2 的结点&#xff0c;并且度为0的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。 如图所示&#xff1a; 这棵二叉树为满二叉树&#xff0c;也可以说深度为 k k k&…...

【MySQL】(1)数据库基础,库与表的增删查改,数据库的备份与还原

文章目录服务器&#xff0c;数据库&#xff0c;表关系MySQL 数据存储逻辑SQL 分类存储引擎库的操作查看数据库创建数据库查看创建语句删除数据库选择&#xff08;切换&#xff09;数据库查看当前选择的数据库修改数据库字符集和排序规则表的操作创建表查询表查询表结构插入数据…...

Python基础-01 变量

注释 注释的分类 在Python中,支持单行及多行注释 单行注释 使用#对代码进行说明,#右边的所有内容就是注释的内容,起辅助说明作用 # #右边的都是注释,解析器会忽略 print(hello world) #在控制台里打印一段话多行注释 多行注释中,允许换行,使用三个单引号开始,三个单引号结…...

springcloud2.1.0整合seata1.5.2+nacos2.10(附源码)

springcloud2.1.0整合seata1.5.2nacos2.10&#xff08;附源码&#xff09; 1.创建springboot2.2.2springcloud2.1.0的maven父子工程如下&#xff0c;不过多描述&#xff1a; 搭建过程中也出现很多问题&#xff0c;主要包括&#xff1a; 1.seataServer.properties配置文件的组…...

map原理

map源码结构体&#xff1a; type hmap struct {count int // 元素的个数B uint8 // buckets 数组的长度就是 2^B 个overflow uint16 // 溢出桶的数量​buckets unsafe.Pointer // 2^B个桶对应的数组指针oldbuckets unsafe.Pointer // 发生扩容时&#xff0…...

[Ext JS]3.6 Ext JS 表格(Grid)概览

Grid, 翻译过来是网格, 也就是表格。 Grid 的基本构成 面板 :Ext.grid.Panel表格视图 :Ext.view.Table。 不直接使用, 通过面板的viewConfig配置项进行配置。比如可以用来配置表格中行是否跳色显示列: Ext.grid.column.Column。 表格中的列定义store , 表格的数据示例代码…...