diff --git a/404.html b/404.html index 4d9f6db..dda6e4f 100644 --- a/404.html +++ b/404.html @@ -30,11 +30,11 @@ 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/assets/0.redis7.html-D8dTCNAM.js b/assets/0.redis7.html-DIJ1znYd.js similarity index 97% rename from assets/0.redis7.html-D8dTCNAM.js rename to assets/0.redis7.html-DIJ1znYd.js index 9d16ef0..850b425 100644 --- a/assets/0.redis7.html-D8dTCNAM.js +++ b/assets/0.redis7.html-DIJ1znYd.js @@ -1,4 +1,4 @@ -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,b as s,o as n}from"./app-IPkfDkxj.js";const i={};function r(d,e){return n(),t("div",null,e[0]||(e[0]=[s(`

0.Redis7

登录

redis-cli -h host -p port -a password
+import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,b as s,o as n}from"./app-DGSXj59V.js";const i={};function r(d,e){return n(),t("div",null,e[0]||(e[0]=[s(`

0.Redis7

登录

redis-cli -h host -p port -a password
 
redis-cli
 >auth password
 

查看信息

info
diff --git "a/assets/1.\345\215\201\345\244\247\346\225\260\346\215\256\347\261\273\345\236\213.html-DetU5pF8.js" "b/assets/1.\345\215\201\345\244\247\346\225\260\346\215\256\347\261\273\345\236\213.html-M6yAsNAG.js"
similarity index 99%
rename from "assets/1.\345\215\201\345\244\247\346\225\260\346\215\256\347\261\273\345\236\213.html-DetU5pF8.js"
rename to "assets/1.\345\215\201\345\244\247\346\225\260\346\215\256\347\261\273\345\236\213.html-M6yAsNAG.js"
index 3a120a3..3ebf8bf 100644
--- "a/assets/1.\345\215\201\345\244\247\346\225\260\346\215\256\347\261\273\345\236\213.html-DetU5pF8.js"
+++ "b/assets/1.\345\215\201\345\244\247\346\225\260\346\215\256\347\261\273\345\236\213.html-M6yAsNAG.js"
@@ -1,4 +1,4 @@
-import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as n,o as t}from"./app-IPkfDkxj.js";const l={};function i(d,e){return t(),a("div",null,e[0]||(e[0]=[n(`

1.十大数据类型

CONFIG

CONFIG GET key
+import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as n,o as t}from"./app-DGSXj59V.js";const l={};function i(d,e){return t(),a("div",null,e[0]||(e[0]=[n(`

1.十大数据类型

CONFIG

CONFIG GET key
 CONFIG SET key
 

KEY

命令不区分大小写,而key是区分大小写的

操作

  • keys *
  • exist *
  • type key
  • del key 删除指定的key数据
  • unlink key 非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的删除会在后续异步中操作。
  • ttl key
  • expire key 秒钟
  • move key dbindex [0-15]
  • select dbindex
  • dbsize
  • flushdb 清空当前库
  • flushall 清空全部库

十大类型

帮助命令,help @类型

String

SET

SET key value [NX | XX] [GET] [EX seconds | PX milliseconds |
   EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]
diff --git "a/assets/10.\345\211\215\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-xpAp087Y.js" "b/assets/10.\345\211\215\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-CIsptAV2.js"
similarity index 99%
rename from "assets/10.\345\211\215\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-xpAp087Y.js"
rename to "assets/10.\345\211\215\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-CIsptAV2.js"
index acaf73c..2370ef7 100644
--- "a/assets/10.\345\211\215\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-xpAp087Y.js"
+++ "b/assets/10.\345\211\215\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-CIsptAV2.js"
@@ -1,4 +1,4 @@
-import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as t,o as e}from"./app-IPkfDkxj.js";const p={};function o(c,n){return e(),a("div",null,n[0]||(n[0]=[t(`

10.前端编译与优化

概述

在Java技术下谈“编译期”而没有具体上下文语境的话,其实是一句很含糊的表述,因为它可能是指一个前端编译器(叫“编译器的前端”更准确一些)把*.java文件转变成*.class文件的过程;也可能是指Java虚拟机的即时编译器(常称JIT编译器,Just In Time Compiler)运行期把字节码转变成本地机器码的过程;还可能是指使用静态的提前编译器(常称AOT编译器,Ahead Of Time Compiler)直接把程序编译成与目标机器指令集相关的二进制代码的过程。

·前端编译器:JDK的Javac、Eclipse JDT中的增量式编译器(ECJ)。 ·即时编译器:HotSpot虚拟机的C1、C2编译器,Graal编译器。 ·提前编译器:JDK的Jaotc、GNU Compiler for the Java(GCJ)、Excelsior JET。

Javac这类前端编译器对代码的运行效率几乎没有任何优化措施可言(在JDK 1.3之后,Javac的-O优化参数就不再有意义),哪怕是编译器真的采取了优化措施也不会产生什么实质的效果。因为Java虚拟机设计团队选择把对性能的优化全部集中到运行期的即时编译器中,这样可以让那些不是由Javac产生的Class文件(如JRuby、Groovy等语言的Class文件)也同样能享受到编译器优化措施所带来的性能红利。如果把“优化”的定义放宽,把对开发阶段的优化也计算进来的话,Javac确实是做了许多针对Java语言编码过程的优化措施来降低程序员的编码复杂度、提高编码效率。相当多新生的Java语法特性,都是靠编译器的“语法糖”来实现,而不是依赖字节码或者Java虚拟机的底层改进来支持。

Javac编译器

Javac的源码与调试

位置

JDK9之前: JDK_SRC_HOME/langtools/src/share/classes/com/sun/tools/javac JDK9之后: JDK_SRC_HOME/jdk.compiler/share/classes/com/sun/tools/javac

Javac编译器除了JDK自身的标准类库外,就只引用了JDK_SRC_HOME/langtools/src/share/classes/com/sun/*里面的代码,把JDK_SRC_HOME/langtools/src/share/classes/com/sun/*目录下的源文件全部复制到工程的源码目录中。

javac工程-jdk8
javac工程-jdk8

从Javac代码的总体结构来看,编译过程大致可以分为1个准备过程和3个处理过程,它们分别如下所示。

  1. 准备过程:初始化插入式注解处理器。

  2. 解析与填充符号表过程,包括:

    • 词法、语法分析。将源代码的字符流转变为标记集合,构造出抽象语法树。
    • 填充符号表。产生符号地址和符号信息。
  3. 插入式注解处理器的注解处理过程:插入式注解处理器的执行阶段,本章的实战部分会设计一个插入式注解处理器来影响Javac的编译行为。

  4. 分析与字节码生成过程,包括:

    • 标注检查。对语法的静态信息进行检查。
    • 数据流及控制流分析。对程序动态运行过程进行检查。
    • 解语法糖。将简化代码编写的语法糖还原为原有的形式。
    • 字节码生成。将前面各个步骤所生成的信息转化成字节码。

上述3个处理过程里,执行插入式注解时又可能会产生新的符号,如果有新的符号产生,就必须转回到之前的解析、填充符号表的过程中重新处理这些新符号,从总体来看,三者之间的关系与交互顺序如图所示。

Javac的编译过程
Javac的编译过程

我们可以把上述处理过程对应到代码中,Javac编译动作的入口是com.sun.tools.javac.main.JavaCompiler类,上述3个过程的代码逻辑集中在这个类的compile()compile2()方法里,其中主体代码如图所示,整个编译过程主要的处理由图中标注的8个方法来完成。

Javac编译过程的主体代码
Javac编译过程的主体代码

解析与填充符号表

解析过程由图的parseFiles()方法(过程1.1)来完成,解析过程包括了经典程序编译原理中的词法分析和语法分析两个步骤。

  1. 词法、语法分析

词法分析是将源代码的字符流转变为标记(Token)集合的过程,单个字符是程序编写时的最小元素,但标记才是编译时的最小元素。

语法分析是根据标记序列构造抽象语法树的过程,抽象语法树(Abstract Syntax Tree,AST)是一种用来描述程序代码语法结构的树形表示方式,抽象语法树的每一个节点都代表着程序代码中的一个语法结构(SyntaxConstruct),例如包、类型、修饰符、运算符、接口、返回值甚至连代码注释等都可以是一种特定的语法结构。

在Javac的源码中,语法分析过程由com.sun.tools.javac.parser.Parser类实现,这个阶段产出的抽象语法树是以com.sun.tools.javac.tree.JCTree类表示的。

经过词法和语法分析生成语法树以后,编译器就不会再对源码字符流进行操作了,后续的操作都建立在抽象语法树之上。

  1. 填充符号表

完成了语法分析和词法分析之后,下一个阶段是对符号表进行填充的过程,也就是图中enterTrees()方法(过程1.2)要做的事情。符号表(Symbol Table)是由一组符号地址和符号信息构成的数据结构,读者可以把它类比想象成哈希表中键值对的存储形式(实际上符号表不一定是哈希表实现,可以是有序符号表、树状符号表、栈结构符号表等各种形式)。符号表中所登记的信息在编译的不同阶段都要被用到。譬如在语义分析的过程中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的声明是否一致)和产生中间代码,在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的直接依据。

在Javac源代码中,填充符号表的过程由com.sun.tools.javac.comp.Enter类实现,该过程的产出物是一个待处理列表,其中包含了每一个编译单元的抽象语法树的顶级节点,以及package-info.java(如果存在的话)的顶级节点。

注解处理器

JDK 5之后,Java语言提供了对注解(Annotations)的支持,注解在设计上原本是与普通的Java代码一样,都只会在程序运行期间发挥作用的。但在JDK 6中又提出并通过了JSR-269提案,该提案设计了一组被称为“插入式注解处理器”的标准API,可以提前至编译期对代码中的特定注解进行处理,从而影响到前端编译器的工作过程。我们可以把插入式注解处理器看作是一组编译器的插件,当这些插件工作时,允许读取、修改、添加抽象语法树中的任意元素。如果这些插件在处理注解期间对语法树进行过修改,编译器将回到解析及填充符号表的过程重新处理,直到所有插入式注解处理器都没有再对语法树进行修改为止,每一次循环过程称为一个轮次(Round),这也就对应着图中的那个回环过程。

有了编译器注解处理的标准API后,程序员的代码才有可能干涉编译器的行为,由于语法树中的任意元素,甚至包括代码注释都可以在插件中被访问到,所以通过插入式注解处理器实现的插件在功能上有很大的发挥空间。只要有足够的创意,程序员能使用插入式注解处理器来实现许多原本只能在编码中由人工完成的事情。譬如Java著名的编码效率工具Lombok,它可以通过注解来实现自动产生getter/setter方法、进行空置检查、生成受查异常表、产生equals()和hashCode()方法,等等,帮助开发人员消除Java的冗长代码,这些都是依赖插入式注解处理器来实现的。

在Javac源码中,插入式注解处理器的初始化过程是在initPorcessAnnotations()方法中完成的,而它的执行过程则是在processAnnotations()方法中完成。这个方法会判断是否还有新的注解处理器需要执行,如果有的话,通过com.sun.tools.javac.processing.JavacProcessing-Environment类的doProcessing()方法来生成一个新的JavaCompiler对象,对编译的后续步骤进行处理。

语义分析与字节码生成

经过语法分析之后,编译器获得了程序代码的抽象语法树表示,抽象语法树能够表示一个结构正确的源程序,但无法保证源程序的语义是符合逻辑的。而语义分析的主要任务则是对结构上正确的源程序进行上下文相关性质的检查,譬如进行类型检查控制流检查数据流检查,等等。

  1. 标注检查

Javac在编译过程中,语义分析过程可分为标注检查和数据及控制流分析两个步骤,分别由图中的attribute()和flow()方法(过程3.1和过程3.2)完成。

标注检查步骤要检查的内容包括诸如变量使用前是否已被声明、变量与赋值之间的数据类型是否能够匹配,等等。在标注检查中,还会顺便进行一个称为常量折叠(Constant Folding)的代码优化,这是Javac编译器会对源代码做的极少量优化措施之一(代码优化几乎都在即时编译器中进行)。

如果我们在Java代码中写下如下所示的变量定义:

int a = 1 + 2;
+import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as t,o as e}from"./app-DGSXj59V.js";const p={};function o(c,n){return e(),a("div",null,n[0]||(n[0]=[t(`

10.前端编译与优化

概述

在Java技术下谈“编译期”而没有具体上下文语境的话,其实是一句很含糊的表述,因为它可能是指一个前端编译器(叫“编译器的前端”更准确一些)把*.java文件转变成*.class文件的过程;也可能是指Java虚拟机的即时编译器(常称JIT编译器,Just In Time Compiler)运行期把字节码转变成本地机器码的过程;还可能是指使用静态的提前编译器(常称AOT编译器,Ahead Of Time Compiler)直接把程序编译成与目标机器指令集相关的二进制代码的过程。

·前端编译器:JDK的Javac、Eclipse JDT中的增量式编译器(ECJ)。 ·即时编译器:HotSpot虚拟机的C1、C2编译器,Graal编译器。 ·提前编译器:JDK的Jaotc、GNU Compiler for the Java(GCJ)、Excelsior JET。

Javac这类前端编译器对代码的运行效率几乎没有任何优化措施可言(在JDK 1.3之后,Javac的-O优化参数就不再有意义),哪怕是编译器真的采取了优化措施也不会产生什么实质的效果。因为Java虚拟机设计团队选择把对性能的优化全部集中到运行期的即时编译器中,这样可以让那些不是由Javac产生的Class文件(如JRuby、Groovy等语言的Class文件)也同样能享受到编译器优化措施所带来的性能红利。如果把“优化”的定义放宽,把对开发阶段的优化也计算进来的话,Javac确实是做了许多针对Java语言编码过程的优化措施来降低程序员的编码复杂度、提高编码效率。相当多新生的Java语法特性,都是靠编译器的“语法糖”来实现,而不是依赖字节码或者Java虚拟机的底层改进来支持。

Javac编译器

Javac的源码与调试

位置

JDK9之前: JDK_SRC_HOME/langtools/src/share/classes/com/sun/tools/javac JDK9之后: JDK_SRC_HOME/jdk.compiler/share/classes/com/sun/tools/javac

Javac编译器除了JDK自身的标准类库外,就只引用了JDK_SRC_HOME/langtools/src/share/classes/com/sun/*里面的代码,把JDK_SRC_HOME/langtools/src/share/classes/com/sun/*目录下的源文件全部复制到工程的源码目录中。

javac工程-jdk8
javac工程-jdk8

从Javac代码的总体结构来看,编译过程大致可以分为1个准备过程和3个处理过程,它们分别如下所示。

  1. 准备过程:初始化插入式注解处理器。

  2. 解析与填充符号表过程,包括:

    • 词法、语法分析。将源代码的字符流转变为标记集合,构造出抽象语法树。
    • 填充符号表。产生符号地址和符号信息。
  3. 插入式注解处理器的注解处理过程:插入式注解处理器的执行阶段,本章的实战部分会设计一个插入式注解处理器来影响Javac的编译行为。

  4. 分析与字节码生成过程,包括:

    • 标注检查。对语法的静态信息进行检查。
    • 数据流及控制流分析。对程序动态运行过程进行检查。
    • 解语法糖。将简化代码编写的语法糖还原为原有的形式。
    • 字节码生成。将前面各个步骤所生成的信息转化成字节码。

上述3个处理过程里,执行插入式注解时又可能会产生新的符号,如果有新的符号产生,就必须转回到之前的解析、填充符号表的过程中重新处理这些新符号,从总体来看,三者之间的关系与交互顺序如图所示。

Javac的编译过程
Javac的编译过程

我们可以把上述处理过程对应到代码中,Javac编译动作的入口是com.sun.tools.javac.main.JavaCompiler类,上述3个过程的代码逻辑集中在这个类的compile()compile2()方法里,其中主体代码如图所示,整个编译过程主要的处理由图中标注的8个方法来完成。

Javac编译过程的主体代码
Javac编译过程的主体代码

解析与填充符号表

解析过程由图的parseFiles()方法(过程1.1)来完成,解析过程包括了经典程序编译原理中的词法分析和语法分析两个步骤。

  1. 词法、语法分析

词法分析是将源代码的字符流转变为标记(Token)集合的过程,单个字符是程序编写时的最小元素,但标记才是编译时的最小元素。

语法分析是根据标记序列构造抽象语法树的过程,抽象语法树(Abstract Syntax Tree,AST)是一种用来描述程序代码语法结构的树形表示方式,抽象语法树的每一个节点都代表着程序代码中的一个语法结构(SyntaxConstruct),例如包、类型、修饰符、运算符、接口、返回值甚至连代码注释等都可以是一种特定的语法结构。

在Javac的源码中,语法分析过程由com.sun.tools.javac.parser.Parser类实现,这个阶段产出的抽象语法树是以com.sun.tools.javac.tree.JCTree类表示的。

经过词法和语法分析生成语法树以后,编译器就不会再对源码字符流进行操作了,后续的操作都建立在抽象语法树之上。

  1. 填充符号表

完成了语法分析和词法分析之后,下一个阶段是对符号表进行填充的过程,也就是图中enterTrees()方法(过程1.2)要做的事情。符号表(Symbol Table)是由一组符号地址和符号信息构成的数据结构,读者可以把它类比想象成哈希表中键值对的存储形式(实际上符号表不一定是哈希表实现,可以是有序符号表、树状符号表、栈结构符号表等各种形式)。符号表中所登记的信息在编译的不同阶段都要被用到。譬如在语义分析的过程中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的声明是否一致)和产生中间代码,在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的直接依据。

在Javac源代码中,填充符号表的过程由com.sun.tools.javac.comp.Enter类实现,该过程的产出物是一个待处理列表,其中包含了每一个编译单元的抽象语法树的顶级节点,以及package-info.java(如果存在的话)的顶级节点。

注解处理器

JDK 5之后,Java语言提供了对注解(Annotations)的支持,注解在设计上原本是与普通的Java代码一样,都只会在程序运行期间发挥作用的。但在JDK 6中又提出并通过了JSR-269提案,该提案设计了一组被称为“插入式注解处理器”的标准API,可以提前至编译期对代码中的特定注解进行处理,从而影响到前端编译器的工作过程。我们可以把插入式注解处理器看作是一组编译器的插件,当这些插件工作时,允许读取、修改、添加抽象语法树中的任意元素。如果这些插件在处理注解期间对语法树进行过修改,编译器将回到解析及填充符号表的过程重新处理,直到所有插入式注解处理器都没有再对语法树进行修改为止,每一次循环过程称为一个轮次(Round),这也就对应着图中的那个回环过程。

有了编译器注解处理的标准API后,程序员的代码才有可能干涉编译器的行为,由于语法树中的任意元素,甚至包括代码注释都可以在插件中被访问到,所以通过插入式注解处理器实现的插件在功能上有很大的发挥空间。只要有足够的创意,程序员能使用插入式注解处理器来实现许多原本只能在编码中由人工完成的事情。譬如Java著名的编码效率工具Lombok,它可以通过注解来实现自动产生getter/setter方法、进行空置检查、生成受查异常表、产生equals()和hashCode()方法,等等,帮助开发人员消除Java的冗长代码,这些都是依赖插入式注解处理器来实现的。

在Javac源码中,插入式注解处理器的初始化过程是在initPorcessAnnotations()方法中完成的,而它的执行过程则是在processAnnotations()方法中完成。这个方法会判断是否还有新的注解处理器需要执行,如果有的话,通过com.sun.tools.javac.processing.JavacProcessing-Environment类的doProcessing()方法来生成一个新的JavaCompiler对象,对编译的后续步骤进行处理。

语义分析与字节码生成

经过语法分析之后,编译器获得了程序代码的抽象语法树表示,抽象语法树能够表示一个结构正确的源程序,但无法保证源程序的语义是符合逻辑的。而语义分析的主要任务则是对结构上正确的源程序进行上下文相关性质的检查,譬如进行类型检查控制流检查数据流检查,等等。

  1. 标注检查

Javac在编译过程中,语义分析过程可分为标注检查和数据及控制流分析两个步骤,分别由图中的attribute()和flow()方法(过程3.1和过程3.2)完成。

标注检查步骤要检查的内容包括诸如变量使用前是否已被声明、变量与赋值之间的数据类型是否能够匹配,等等。在标注检查中,还会顺便进行一个称为常量折叠(Constant Folding)的代码优化,这是Javac编译器会对源代码做的极少量优化措施之一(代码优化几乎都在即时编译器中进行)。

如果我们在Java代码中写下如下所示的变量定义:

int a = 1 + 2;
 
常量折叠
常量折叠

则在抽象语法树上仍然能看到字面量“1”“2”和操作符“+”号,但是在经过常量折叠优化之后,它们将会被折叠为字面量“3”,如图所示,这个插入式表达式(Infix Expression)的值已经在语法树上标注出来了(ConstantExpressionValue:3)。由于编译期间进行了常量折叠,所以在代码里面定义“a=1+2”比起直接定义“a=3”来,并不会增加程序运行期哪怕仅仅一个处理器时钟周期的处理工作量。

标注检查步骤在Javac源码中的实现类是com.sun.tools.javac.comp.Attr类和com.sun.tools.javac.comp.Check类。

  1. 数据及控制流分析

数据流分析和控制流分析是对程序上下文逻辑更进一步的验证,它可以检查出诸如程序局部变量在使用前是否有赋值、方法的每条路径是否都有返回值、是否所有的受查异常都被正确处理了等问题。编译时期的数据及控制流分析与类加载时的数据及控制流分析的目的基本上可以看作是一致的,但校验范围会有所区别,有一些校验项只有在编译期或运行期才能进行。

// 方法一带有final修饰
 public void foo(final int arg) {
     final int var = 0;
diff --git "a/assets/11.\345\220\216\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-Xs_v6BVk.js" "b/assets/11.\345\220\216\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-BXVBRKzU.js"
similarity index 99%
rename from "assets/11.\345\220\216\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-Xs_v6BVk.js"
rename to "assets/11.\345\220\216\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-BXVBRKzU.js"
index f35d60d..d5b9692 100644
--- "a/assets/11.\345\220\216\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-Xs_v6BVk.js"
+++ "b/assets/11.\345\220\216\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html-BXVBRKzU.js"
@@ -1,4 +1,4 @@
-import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as s,o as t}from"./app-IPkfDkxj.js";const i={};function o(l,n){return t(),a("div",null,n[0]||(n[0]=[s(`

11.后端编译与优化

概述

如果我们把字节码看作是程序语言的一种中间表示形式(Intermediate Representation,IR)的话,那编译器无论在何时、在何种状态下把Class文件转换成与本地基础设施(硬件指令集、操作系统)相关的二进制机器码,它都可以视为整个编译过程的后端。

无论是提前编译器抑或即时编译器,都不是Java虚拟机必需的组成部分,《Java虚拟机规范》中从来没有规定过虚拟机内部必须要包含这些编译器,更没有限定或指导这些编译器应该如何去实现。但是,后端编译器编译性能的好坏、代码优化质量的高低却是衡量一款商用虚拟机优秀与否的关键指标之一,它们也是商业Java虚拟机中的核心,是最能体现技术水平与价值的功能。

所提及的即时编译器都是特指HotSpot虚拟机内置的即时编译器,虚拟机也是特指HotSpot虚拟机。

即时编译器

目前主流的两款商用Java虚拟机(HotSpot、OpenJ9)里,Java程序最初都是通过解释器(Interpreter)进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁,就会把这些代码认定为“热点代码”(Hot Spot Code),为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成本地机器码,并以各种手段尽可能地进行代码优化,运行时完成这个任务的后端编译器被称为即时编译器。本节我们将会了解HotSpot虚拟机内的即时编译器的运作过程,此外,我们还将解决以下几个问题:

  • 为何HotSpot虚拟机要使用解释器与即时编译器并存的架构?
  • 为何HotSpot虚拟机要实现两个(或三个)不同的即时编译器?
  • 程序何时使用解释器执行?何时使用编译器执行?
  • 哪些程序代码会被编译为本地代码?如何编译本地代码?
  • 如何从外部观察到即时编译器的编译过程和编译结果?

解释器与编译器

尽管并不是所有的Java虚拟机都采用解释器与编译器并存的运行架构,但目前主流的商用Java虚拟机,譬如HotSpot、OpenJ9等,内部都同时包含解释器与编译器,解释器与编译器两者各有优势:当程序需要迅速启动和执行的时候,解释器可以首先发挥作用,省去编译的时间,立即运行。当程序启动后,随着时间的推移,编译器逐渐发挥作用,把越来越多的代码编译成本地代码,这样可以减少解释器的中间损耗,获得更高的执行效率。当程序运行环境中内存资源限制较大,可以使用解释执行节约内存(如部分嵌入式系统中和大部分的JavaCard应用中就只有解释器的存在),反之可以使用编译执行来提升效率。同时,解释器还可以作为编译器激进优化时后备的“逃生门”(如果情况允许,HotSpot虚拟机中也会采用不进行激进优化的客户端编译器充当“逃生门”的角色),让编译器根据概率选择一些不能保证所有情况都正确,但大多数时候都能提升运行速度的优化手段,当激进优化的假设不成立,如加载了新类以后,类型继承结构出现变化、出现“罕见陷阱”(Uncommon Trap)时可以通过逆优化(Deoptimization)退回到解释状态继续执行,因此在整个Java虚拟机执行架构里,解释器与编译器经常是相辅相成地配合工作,其交互关系如图11-1所示。

解释器与编译器的交互
解释器与编译器的交互

HotSpot虚拟机中内置了两个(或三个)即时编译器,其中有两个编译器存在已久,分别被称为“客户端编译器”(Client Compiler)和“服务端编译器”(Server Compiler),或者简称为C1编译器和C2编译器(部分资料和JDK源码中C2也叫Opto编译器),第三个是在JDK 10时才出现的、长期目标是代替C2的Graal编译器。

在分层编译(Tiered Compilation)的工作模式出现以前,HotSpot虚拟机通常是采用解释器与其中一个编译器直接搭配的方式工作,程序使用哪个编译器,只取决于虚拟机运行的模式,HotSpot虚拟机会根据自身版本与宿主机器的硬件性能自动选择运行模式,用户也可以使用“-client”或“-server”参数去强制指定虚拟机运行在客户端模式还是服务端模式。

无论采用的编译器是客户端编译器还是服务端编译器,解释器与编译器搭配使用的方式在虚拟机中被称为“混合模式”(Mixed Mode),用户也可以使用参数“-Xint”强制虚拟机运行于“解释模式”(Interpreted Mode),这时候编译器完全不介入工作,全部代码都使用解释方式执行。另外,也可以使用参数“-Xcomp”强制虚拟机运行于“编译模式”(Compiled Mode),这时候将优先采用编译方式执行程序,但是解释器仍然要在编译无法进行的情况下介入执行过程。可以通过虚拟机的“-version”命令的输出结果显示出这三种模式。可以通过虚拟机的“-version”命令的输出结果显示出这三种模式

$java -version
+import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as s,o as t}from"./app-DGSXj59V.js";const i={};function o(l,n){return t(),a("div",null,n[0]||(n[0]=[s(`

11.后端编译与优化

概述

如果我们把字节码看作是程序语言的一种中间表示形式(Intermediate Representation,IR)的话,那编译器无论在何时、在何种状态下把Class文件转换成与本地基础设施(硬件指令集、操作系统)相关的二进制机器码,它都可以视为整个编译过程的后端。

无论是提前编译器抑或即时编译器,都不是Java虚拟机必需的组成部分,《Java虚拟机规范》中从来没有规定过虚拟机内部必须要包含这些编译器,更没有限定或指导这些编译器应该如何去实现。但是,后端编译器编译性能的好坏、代码优化质量的高低却是衡量一款商用虚拟机优秀与否的关键指标之一,它们也是商业Java虚拟机中的核心,是最能体现技术水平与价值的功能。

所提及的即时编译器都是特指HotSpot虚拟机内置的即时编译器,虚拟机也是特指HotSpot虚拟机。

即时编译器

目前主流的两款商用Java虚拟机(HotSpot、OpenJ9)里,Java程序最初都是通过解释器(Interpreter)进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁,就会把这些代码认定为“热点代码”(Hot Spot Code),为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成本地机器码,并以各种手段尽可能地进行代码优化,运行时完成这个任务的后端编译器被称为即时编译器。本节我们将会了解HotSpot虚拟机内的即时编译器的运作过程,此外,我们还将解决以下几个问题:

  • 为何HotSpot虚拟机要使用解释器与即时编译器并存的架构?
  • 为何HotSpot虚拟机要实现两个(或三个)不同的即时编译器?
  • 程序何时使用解释器执行?何时使用编译器执行?
  • 哪些程序代码会被编译为本地代码?如何编译本地代码?
  • 如何从外部观察到即时编译器的编译过程和编译结果?

解释器与编译器

尽管并不是所有的Java虚拟机都采用解释器与编译器并存的运行架构,但目前主流的商用Java虚拟机,譬如HotSpot、OpenJ9等,内部都同时包含解释器与编译器,解释器与编译器两者各有优势:当程序需要迅速启动和执行的时候,解释器可以首先发挥作用,省去编译的时间,立即运行。当程序启动后,随着时间的推移,编译器逐渐发挥作用,把越来越多的代码编译成本地代码,这样可以减少解释器的中间损耗,获得更高的执行效率。当程序运行环境中内存资源限制较大,可以使用解释执行节约内存(如部分嵌入式系统中和大部分的JavaCard应用中就只有解释器的存在),反之可以使用编译执行来提升效率。同时,解释器还可以作为编译器激进优化时后备的“逃生门”(如果情况允许,HotSpot虚拟机中也会采用不进行激进优化的客户端编译器充当“逃生门”的角色),让编译器根据概率选择一些不能保证所有情况都正确,但大多数时候都能提升运行速度的优化手段,当激进优化的假设不成立,如加载了新类以后,类型继承结构出现变化、出现“罕见陷阱”(Uncommon Trap)时可以通过逆优化(Deoptimization)退回到解释状态继续执行,因此在整个Java虚拟机执行架构里,解释器与编译器经常是相辅相成地配合工作,其交互关系如图11-1所示。

解释器与编译器的交互
解释器与编译器的交互

HotSpot虚拟机中内置了两个(或三个)即时编译器,其中有两个编译器存在已久,分别被称为“客户端编译器”(Client Compiler)和“服务端编译器”(Server Compiler),或者简称为C1编译器和C2编译器(部分资料和JDK源码中C2也叫Opto编译器),第三个是在JDK 10时才出现的、长期目标是代替C2的Graal编译器。

在分层编译(Tiered Compilation)的工作模式出现以前,HotSpot虚拟机通常是采用解释器与其中一个编译器直接搭配的方式工作,程序使用哪个编译器,只取决于虚拟机运行的模式,HotSpot虚拟机会根据自身版本与宿主机器的硬件性能自动选择运行模式,用户也可以使用“-client”或“-server”参数去强制指定虚拟机运行在客户端模式还是服务端模式。

无论采用的编译器是客户端编译器还是服务端编译器,解释器与编译器搭配使用的方式在虚拟机中被称为“混合模式”(Mixed Mode),用户也可以使用参数“-Xint”强制虚拟机运行于“解释模式”(Interpreted Mode),这时候编译器完全不介入工作,全部代码都使用解释方式执行。另外,也可以使用参数“-Xcomp”强制虚拟机运行于“编译模式”(Compiled Mode),这时候将优先采用编译方式执行程序,但是解释器仍然要在编译无法进行的情况下介入执行过程。可以通过虚拟机的“-version”命令的输出结果显示出这三种模式。可以通过虚拟机的“-version”命令的输出结果显示出这三种模式

$java -version
 java version "11.0.3" 2019-04-16 LTS
 Java(TM) SE Runtime Environment 18.9 (build 11.0.3+12-LTS)
 Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.3+12-LTS, mixed mode)
diff --git "a/assets/2.Java\345\206\205\345\255\230\345\214\272\345\237\237\344\270\216\345\206\205\345\255\230\346\272\242\345\207\272\345\274\202\345\270\270.html-sguZT_xH.js" "b/assets/2.Java\345\206\205\345\255\230\345\214\272\345\237\237\344\270\216\345\206\205\345\255\230\346\272\242\345\207\272\345\274\202\345\270\270.html-DjsBGsDH.js"
similarity index 99%
rename from "assets/2.Java\345\206\205\345\255\230\345\214\272\345\237\237\344\270\216\345\206\205\345\255\230\346\272\242\345\207\272\345\274\202\345\270\270.html-sguZT_xH.js"
rename to "assets/2.Java\345\206\205\345\255\230\345\214\272\345\237\237\344\270\216\345\206\205\345\255\230\346\272\242\345\207\272\345\274\202\345\270\270.html-DjsBGsDH.js"
index e0ed502..b153169 100644
--- "a/assets/2.Java\345\206\205\345\255\230\345\214\272\345\237\237\344\270\216\345\206\205\345\255\230\346\272\242\345\207\272\345\274\202\345\270\270.html-sguZT_xH.js"
+++ "b/assets/2.Java\345\206\205\345\255\230\345\214\272\345\237\237\344\270\216\345\206\205\345\255\230\346\272\242\345\207\272\345\274\202\345\270\270.html-DjsBGsDH.js"
@@ -1 +1 @@
-import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as l,o as r}from"./app-IPkfDkxj.js";const n={};function i(p,t){return r(),a("div",null,t[0]||(t[0]=[l('

2.Java内存区域与内存溢出异常

运行时数据区域

Java虚拟机运行时数据区
Java虚拟机运行时数据区

程序计数器

线程私有

如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;

如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。

此内存区域是唯一一个在《Java虚拟机规范》中没有规定任何OutOfMemoryError情况的区域。

Java虚拟机栈

线程私有

虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它并不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。

局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

在《Java虚拟机规范》中,对这个内存区域规定了两类异常状况:

  • 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。

  • 如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。

本地方法栈

线程私有

虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。

与虚拟机栈一样,本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和OutOfMemoryError异常。

Java堆

线程共享

Java堆唯一目的就是存放对象实例,是垃圾收集器管理的内存区域

如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。

方法区

线程共享

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

根据《Java虚拟机规范》的规定,如果方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。

运行时常量池

Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池表(Constant Pool Table),用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

todo ??? 除了保存Class文件中描述的符号引用外,还会把由符号引用翻译出来的直接引用也存储在运行时常量池中。

运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是说,并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可以将新的常量放入池中,这种特性被开发人员利用得比较多的便是String类的intern()方法。

直接内存

在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

HotSpot虚拟机对象探秘

对象的创建

  1. 类加载检查

    当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

  2. 分配内存

    对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务实际上便等同于把一块确定大小的内存块从Java堆中划分出来。

    • 分配方式

      • Java堆中内存是绝对规整

        把那个指针向空闲空间方向挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump ThePointer)。

      • Java堆中的内存并不是规整

        须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”(Free List)。

      Java堆是否规整又由所采用的垃圾收集器是否带有空间压缩整理(Compact)的能力决定。

    • 保证线程安全方式

      1. 采用CAS配上失败重试的方式保证更新操作的原子性
      2. 把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local AllocationBuffer,TLAB)

        通过-XX:+/-UseTLAB参数来设定是否使用TLAB

  3. 初始化

    内存分配完成之后,虚拟机必须将分配到的内存空间(但不包括对象头)都初始化为零值,如果使用了TLAB的话,这一项工作也可以提前至TLAB分配时顺便进行。这步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,使程序能访问到这些字段的数据类型所对应的零值。

    Java虚拟机还要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码(实际上对象的哈希码会延后到真正调用Object::hashCode()方法时才计算)、对象的GC分代年龄等信息。这些信息存放在对象的对象头(Object Header)之中。根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。

对象的内存布局

在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

  • 对象头部分包括两类信息。

    1. 第一类是用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。官方称它为“Mark Word”。

      存储内容标志位状态位
      对象哈希码、对象分代对象01未锁定
      偏向线程ID、偏向时间戳、对象分代年龄01可偏向
      指向锁记录的指针00轻量级锁定
      指向重量级锁的指针10膨胀(重量级锁定)
      空,不需要记录信息11GC标记
      Mark Word (64 bits)State
      unused:25 | hashcode:31 | unused:1 | age:4 | biased_lock:0 | 01Normal
      thread:54 | epoch:2 | unused:1 | age:4 | biased_lock:1 | 01Biased
      ptr_to_lock_record:62 | 00Lightweight Locked
      ptr_to_heavyweight_monitor:62 | 10Heavyweight Locked
      | 11Marked for GC

      Mark Word被设计成一个有着动态定义的数据结构,以便在极小的空间内存储尽量多的数据,根据对象的状态复用自己的存储空间。

    2. 另外一部分是类型指针,即对象指向它的类型元数据的指针,Java虚拟机通过这个指针来确定该对象是哪个类的实例。

  • 实例数据部分

    是对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的字段都必须记录起来。

  • 对齐填充

    它仅仅起着占位符的作用,任何对象的大小都必须是8字节的整数倍。

对象的访问定位

Java程序会通过栈上的reference数据来操作堆上的具体对象。

对象访问方式也是由虚拟机实现而定的,主流的访问方式主要有使用句柄和直接指针两种:

  • 句柄访问

    Java堆中将可能会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息

    通过句柄访问对象
    通过句柄访问对象
  • 直接指针访问

    Java堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销

    通过直接指针访问对象
    通过直接指针访问对象

使用句柄来访问的最大好处就是reference中存储的是稳定句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针。直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销。

',44)]))}const s=e(n,[["render",i],["__file","2.Java内存区域与内存溢出异常.html.vue"]]),c=JSON.parse('{"path":"/books/UnderStandingTheJvm/2.Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8.html","title":"2.Java内存区域与内存溢出异常","lang":"zh-CN","frontmatter":{"description":"2.Java内存区域与内存溢出异常 运行时数据区域 Java虚拟机运行时数据区Java虚拟机运行时数据区 程序计数器 线程私有 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址; 如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。 此内存区域是唯一一个在《Java虚拟机规范》中...","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/2.Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"2.Java内存区域与内存溢出异常"}],["meta",{"property":"og:description","content":"2.Java内存区域与内存溢出异常 运行时数据区域 Java虚拟机运行时数据区Java虚拟机运行时数据区 程序计数器 线程私有 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址; 如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。 此内存区域是唯一一个在《Java虚拟机规范》中..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm2-1.jpg"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-09-02T05:37:18.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-09-02T05:37:18.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"2.Java内存区域与内存溢出异常\\",\\"image\\":[\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm2-1.jpg\\",\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm2-2.jpg\\",\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm2-3.jpg\\"],\\"dateModified\\":\\"2024-09-02T05:37:18.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"运行时数据区域","slug":"运行时数据区域","link":"#运行时数据区域","children":[{"level":3,"title":"程序计数器","slug":"程序计数器","link":"#程序计数器","children":[]},{"level":3,"title":"Java虚拟机栈","slug":"java虚拟机栈","link":"#java虚拟机栈","children":[]},{"level":3,"title":"本地方法栈","slug":"本地方法栈","link":"#本地方法栈","children":[]},{"level":3,"title":"Java堆","slug":"java堆","link":"#java堆","children":[]},{"level":3,"title":"方法区","slug":"方法区","link":"#方法区","children":[{"level":4,"title":"运行时常量池","slug":"运行时常量池","link":"#运行时常量池","children":[]}]},{"level":3,"title":"直接内存","slug":"直接内存","link":"#直接内存","children":[]}]},{"level":2,"title":"HotSpot虚拟机对象探秘","slug":"hotspot虚拟机对象探秘","link":"#hotspot虚拟机对象探秘","children":[{"level":3,"title":"对象的创建","slug":"对象的创建","link":"#对象的创建","children":[]},{"level":3,"title":"对象的内存布局","slug":"对象的内存布局","link":"#对象的内存布局","children":[]},{"level":3,"title":"对象的访问定位","slug":"对象的访问定位","link":"#对象的访问定位","children":[]}]}],"git":{"createdTime":1691573366000,"updatedTime":1725255438000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":2}]},"readingTime":{"minutes":8.8,"words":2639},"filePathRelative":"books/UnderStandingTheJvm/2.Java内存区域与内存溢出异常.md","localizedDate":"2023年8月9日","autoDesc":true}');export{s as comp,c as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as l,o as r}from"./app-DGSXj59V.js";const n={};function i(p,t){return r(),a("div",null,t[0]||(t[0]=[l('

2.Java内存区域与内存溢出异常

运行时数据区域

Java虚拟机运行时数据区
Java虚拟机运行时数据区

程序计数器

线程私有

如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;

如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。

此内存区域是唯一一个在《Java虚拟机规范》中没有规定任何OutOfMemoryError情况的区域。

Java虚拟机栈

线程私有

虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它并不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。

局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

在《Java虚拟机规范》中,对这个内存区域规定了两类异常状况:

  • 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。

  • 如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。

本地方法栈

线程私有

虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。

与虚拟机栈一样,本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和OutOfMemoryError异常。

Java堆

线程共享

Java堆唯一目的就是存放对象实例,是垃圾收集器管理的内存区域

如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。

方法区

线程共享

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

根据《Java虚拟机规范》的规定,如果方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。

运行时常量池

Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池表(Constant Pool Table),用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

todo ??? 除了保存Class文件中描述的符号引用外,还会把由符号引用翻译出来的直接引用也存储在运行时常量池中。

运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是说,并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可以将新的常量放入池中,这种特性被开发人员利用得比较多的便是String类的intern()方法。

直接内存

在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

HotSpot虚拟机对象探秘

对象的创建

  1. 类加载检查

    当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

  2. 分配内存

    对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务实际上便等同于把一块确定大小的内存块从Java堆中划分出来。

    • 分配方式

      • Java堆中内存是绝对规整

        把那个指针向空闲空间方向挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump ThePointer)。

      • Java堆中的内存并不是规整

        须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”(Free List)。

      Java堆是否规整又由所采用的垃圾收集器是否带有空间压缩整理(Compact)的能力决定。

    • 保证线程安全方式

      1. 采用CAS配上失败重试的方式保证更新操作的原子性
      2. 把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local AllocationBuffer,TLAB)

        通过-XX:+/-UseTLAB参数来设定是否使用TLAB

  3. 初始化

    内存分配完成之后,虚拟机必须将分配到的内存空间(但不包括对象头)都初始化为零值,如果使用了TLAB的话,这一项工作也可以提前至TLAB分配时顺便进行。这步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,使程序能访问到这些字段的数据类型所对应的零值。

    Java虚拟机还要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码(实际上对象的哈希码会延后到真正调用Object::hashCode()方法时才计算)、对象的GC分代年龄等信息。这些信息存放在对象的对象头(Object Header)之中。根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。

对象的内存布局

在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

  • 对象头部分包括两类信息。

    1. 第一类是用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。官方称它为“Mark Word”。

      存储内容标志位状态位
      对象哈希码、对象分代对象01未锁定
      偏向线程ID、偏向时间戳、对象分代年龄01可偏向
      指向锁记录的指针00轻量级锁定
      指向重量级锁的指针10膨胀(重量级锁定)
      空,不需要记录信息11GC标记
      Mark Word (64 bits)State
      unused:25 | hashcode:31 | unused:1 | age:4 | biased_lock:0 | 01Normal
      thread:54 | epoch:2 | unused:1 | age:4 | biased_lock:1 | 01Biased
      ptr_to_lock_record:62 | 00Lightweight Locked
      ptr_to_heavyweight_monitor:62 | 10Heavyweight Locked
      | 11Marked for GC

      Mark Word被设计成一个有着动态定义的数据结构,以便在极小的空间内存储尽量多的数据,根据对象的状态复用自己的存储空间。

    2. 另外一部分是类型指针,即对象指向它的类型元数据的指针,Java虚拟机通过这个指针来确定该对象是哪个类的实例。

  • 实例数据部分

    是对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的字段都必须记录起来。

  • 对齐填充

    它仅仅起着占位符的作用,任何对象的大小都必须是8字节的整数倍。

对象的访问定位

Java程序会通过栈上的reference数据来操作堆上的具体对象。

对象访问方式也是由虚拟机实现而定的,主流的访问方式主要有使用句柄和直接指针两种:

  • 句柄访问

    Java堆中将可能会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息

    通过句柄访问对象
    通过句柄访问对象
  • 直接指针访问

    Java堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销

    通过直接指针访问对象
    通过直接指针访问对象

使用句柄来访问的最大好处就是reference中存储的是稳定句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针。直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销。

',44)]))}const s=e(n,[["render",i],["__file","2.Java内存区域与内存溢出异常.html.vue"]]),c=JSON.parse('{"path":"/books/UnderStandingTheJvm/2.Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8.html","title":"2.Java内存区域与内存溢出异常","lang":"zh-CN","frontmatter":{"description":"2.Java内存区域与内存溢出异常 运行时数据区域 Java虚拟机运行时数据区Java虚拟机运行时数据区 程序计数器 线程私有 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址; 如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。 此内存区域是唯一一个在《Java虚拟机规范》中...","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/2.Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"2.Java内存区域与内存溢出异常"}],["meta",{"property":"og:description","content":"2.Java内存区域与内存溢出异常 运行时数据区域 Java虚拟机运行时数据区Java虚拟机运行时数据区 程序计数器 线程私有 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址; 如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。 此内存区域是唯一一个在《Java虚拟机规范》中..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm2-1.jpg"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-09-02T05:37:18.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-09-02T05:37:18.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"2.Java内存区域与内存溢出异常\\",\\"image\\":[\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm2-1.jpg\\",\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm2-2.jpg\\",\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm2-3.jpg\\"],\\"dateModified\\":\\"2024-09-02T05:37:18.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"运行时数据区域","slug":"运行时数据区域","link":"#运行时数据区域","children":[{"level":3,"title":"程序计数器","slug":"程序计数器","link":"#程序计数器","children":[]},{"level":3,"title":"Java虚拟机栈","slug":"java虚拟机栈","link":"#java虚拟机栈","children":[]},{"level":3,"title":"本地方法栈","slug":"本地方法栈","link":"#本地方法栈","children":[]},{"level":3,"title":"Java堆","slug":"java堆","link":"#java堆","children":[]},{"level":3,"title":"方法区","slug":"方法区","link":"#方法区","children":[{"level":4,"title":"运行时常量池","slug":"运行时常量池","link":"#运行时常量池","children":[]}]},{"level":3,"title":"直接内存","slug":"直接内存","link":"#直接内存","children":[]}]},{"level":2,"title":"HotSpot虚拟机对象探秘","slug":"hotspot虚拟机对象探秘","link":"#hotspot虚拟机对象探秘","children":[{"level":3,"title":"对象的创建","slug":"对象的创建","link":"#对象的创建","children":[]},{"level":3,"title":"对象的内存布局","slug":"对象的内存布局","link":"#对象的内存布局","children":[]},{"level":3,"title":"对象的访问定位","slug":"对象的访问定位","link":"#对象的访问定位","children":[]}]}],"git":{"createdTime":1691573366000,"updatedTime":1725255438000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":2}]},"readingTime":{"minutes":8.8,"words":2639},"filePathRelative":"books/UnderStandingTheJvm/2.Java内存区域与内存溢出异常.md","localizedDate":"2023年8月9日","autoDesc":true}');export{s as comp,c as data}; diff --git "a/assets/2.\346\214\201\344\271\205\345\214\226.html-Cj-6GcFe.js" "b/assets/2.\346\214\201\344\271\205\345\214\226.html-Btm7zx-d.js" similarity index 99% rename from "assets/2.\346\214\201\344\271\205\345\214\226.html-Cj-6GcFe.js" rename to "assets/2.\346\214\201\344\271\205\345\214\226.html-Btm7zx-d.js" index 0f3c3fe..9aba3ee 100644 --- "a/assets/2.\346\214\201\344\271\205\345\214\226.html-Cj-6GcFe.js" +++ "b/assets/2.\346\214\201\344\271\205\345\214\226.html-Btm7zx-d.js" @@ -1,4 +1,4 @@ -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as n,o as i}from"./app-IPkfDkxj.js";const l={};function d(r,e){return i(),s("div",null,e[0]||(e[0]=[n(`

2.Redis持久化

RDB (Redis Database)

RDB持久化以指定的时间间隔执行数据集的时间点快照

自动触发

配置

save 60 1000
+import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as n,o as i}from"./app-DGSXj59V.js";const l={};function d(r,e){return i(),s("div",null,e[0]||(e[0]=[n(`

2.Redis持久化

RDB (Redis Database)

RDB持久化以指定的时间间隔执行数据集的时间点快照

自动触发

配置

save 60 1000
 dir ./
 dbfilename dump6379.rdb
 

save <seconds> <changes> 如果seconds秒更新changes个key就保存 dir 修改备份路径 dbfilename 修改备份文件名称

手动触发

  • save 在主程序中执行会阻塞当前redis服务器,直到持久化工作完成执行save命令期间,Redis不能处理其他命令,线上禁止使用
  • bgsave redis会在后台异步进行快照操作,不阻塞快照同时还可以相应客户端请求,该触发方式会fork一个子进程由子进程复制持久化过程
  • LASTSAVE 获取最后一次成功执行快照的时间戳

优缺点

优点

  • 可以有不同时间段的多重备份
  • 适合大规模的数据恢复
  • 按照业务定时备份
  • 对数据完整性和一致性要求不高
  • RDB文件在内存中的加载速度要比AOF快很多

缺点

  • 在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失从当前至最近一次快照期间的数据,快照之间的数据会丢失
  • 内存数据的全量同步,如果数据量太大会导致IO严重影响服务器性能
  • RDB依赖于主进程的fork,在更大的数据集中,这可能会导致服务请求的瞬间延迟。fork的时候内存中的数据被克隆了一份,大致2倍的膨胀性,需要考虑

其他

修复RDB快照文件

redis-check-rdb ./redisconfig/dump.rdb
diff --git a/assets/2023.html-CZcJbhdh.js b/assets/2023.html-ArLS9RPY.js
similarity index 99%
rename from assets/2023.html-CZcJbhdh.js
rename to assets/2023.html-ArLS9RPY.js
index bce7604..6e3af31 100644
--- a/assets/2023.html-CZcJbhdh.js
+++ b/assets/2023.html-ArLS9RPY.js
@@ -1,4 +1,4 @@
-import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as t,o as e}from"./app-IPkfDkxj.js";const p={};function l(o,n){return e(),a("div",null,n[0]||(n[0]=[t(`

2023

内部类

内部类是指在一个类的内部定义的另一个类。在Java等面向对象的编程语言中,内部类可以嵌套在其他类中,形成类的层次结构。内部类有以下几种类型:

  1. 成员内部类(Member Inner Class): 定义在类的内部,并且与类的实例相关联。成员内部类可以访问外部类的所有成员,包括私有成员。

    public class OuterClass {
    +import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as t,o as e}from"./app-DGSXj59V.js";const p={};function l(o,n){return e(),a("div",null,n[0]||(n[0]=[t(`

    2023

    内部类

    内部类是指在一个类的内部定义的另一个类。在Java等面向对象的编程语言中,内部类可以嵌套在其他类中,形成类的层次结构。内部类有以下几种类型:

    1. 成员内部类(Member Inner Class): 定义在类的内部,并且与类的实例相关联。成员内部类可以访问外部类的所有成员,包括私有成员。

      public class OuterClass {
           private int outerVar;
       
           public class InnerClass {
      diff --git "a/assets/3.\344\272\213\345\212\241.html-D0FP5PwK.js" "b/assets/3.\344\272\213\345\212\241.html-CpmGsXBd.js"
      similarity index 99%
      rename from "assets/3.\344\272\213\345\212\241.html-D0FP5PwK.js"
      rename to "assets/3.\344\272\213\345\212\241.html-CpmGsXBd.js"
      index 0c7809f..fabf7e7 100644
      --- "a/assets/3.\344\272\213\345\212\241.html-D0FP5PwK.js"
      +++ "b/assets/3.\344\272\213\345\212\241.html-CpmGsXBd.js"
      @@ -1,4 +1,4 @@
      -import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as a,o as t}from"./app-IPkfDkxj.js";const i={};function p(o,e){return t(),n("div",null,e[0]||(e[0]=[a(`

      3.事务

      可以一次执行多个命令,本质是一组命令的集合,一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞

      Redis事务 VS 数据库事务

      1.单独的隔离操作Redis的事务仅仅是保证事务里的操作会被连续独占的执行,redis命令执行是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的
      2.没有隔离级别的概念因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了
      3.不保证原子性Redis的事务不保证原子性,也就是不保证所有指令同时成功或同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力
      4.排它性Redis会保证一个事务内的命令依次执行,而不会被其它命令插入

      命令

      • MULTI 标记事务开始

      • EXEC 执行事务

        127.0.0.1:6379> multi
        +import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as a,o as t}from"./app-DGSXj59V.js";const i={};function p(o,e){return t(),n("div",null,e[0]||(e[0]=[a(`

        3.事务

        可以一次执行多个命令,本质是一组命令的集合,一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞

        Redis事务 VS 数据库事务

        1.单独的隔离操作Redis的事务仅仅是保证事务里的操作会被连续独占的执行,redis命令执行是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的
        2.没有隔离级别的概念因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了
        3.不保证原子性Redis的事务不保证原子性,也就是不保证所有指令同时成功或同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力
        4.排它性Redis会保证一个事务内的命令依次执行,而不会被其它命令插入

        命令

        • MULTI 标记事务开始

        • EXEC 执行事务

          127.0.0.1:6379> multi
           OK
           127.0.0.1:6379(TX)> set k5 test
           QUEUED
          diff --git "a/assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\212\357\274\211.html-DOojsy_g.js" "b/assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\212\357\274\211.html-CIb-O2tW.js"
          similarity index 99%
          rename from "assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\212\357\274\211.html-DOojsy_g.js"
          rename to "assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\212\357\274\211.html-CIb-O2tW.js"
          index 189ffd1..c40c8dc 100644
          --- "a/assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\212\357\274\211.html-DOojsy_g.js"
          +++ "b/assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\212\357\274\211.html-CIb-O2tW.js"
          @@ -1,4 +1,4 @@
          -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as l,o as t}from"./app-IPkfDkxj.js";const p={};function i(o,e){return t(),n("div",null,e[0]||(e[0]=[l(`

          3.垃圾收集器与内存分配策略(上)

          判断对象存活

          引用计数法

          存在引用对象时,计数器加一。计数器为零时,判定其死亡。

          • 优点

            简单、高效。

          • 缺点

            无法处理一些特殊情况,需要许多额外的特殊判断。如:对象间的相互调用。

              objA.instance = objB;
            +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as l,o as t}from"./app-DGSXj59V.js";const p={};function i(o,e){return t(),n("div",null,e[0]||(e[0]=[l(`

            3.垃圾收集器与内存分配策略(上)

            判断对象存活

            引用计数法

            存在引用对象时,计数器加一。计数器为零时,判定其死亡。

            • 优点

              简单、高效。

            • 缺点

              无法处理一些特殊情况,需要许多额外的特殊判断。如:对象间的相互调用。

                objA.instance = objB;
                 objB.instance = objA;
               
                 objA = null;
              diff --git "a/assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\213\357\274\211.html-CvPGtoPK.js" "b/assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\213\357\274\211.html-Dxlni7rM.js"
              similarity index 99%
              rename from "assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\213\357\274\211.html-CvPGtoPK.js"
              rename to "assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\213\357\274\211.html-Dxlni7rM.js"
              index a5e8b04..b0a4b1c 100644
              --- "a/assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\213\357\274\211.html-CvPGtoPK.js"
              +++ "b/assets/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\213\357\274\211.html-Dxlni7rM.js"
              @@ -1,2 +1,2 @@
              -import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as d,b as l,a as e,d as a,e as i,w as r,r as p,o as s}from"./app-IPkfDkxj.js";const c={};function g(h,t){const n=p("RouteLink");return s(),d("div",null,[t[11]||(t[11]=l('

              3.垃圾收集器与内存分配策略(下)

              经典垃圾收集器

              HotSpot虚拟机的垃圾收集器
              HotSpot虚拟机的垃圾收集器

              两个收集器之间存在连线,就说明它们可以搭配使用

              Serial收集器

              新生代、标记-复制算法实现、单线程、阻塞

              优点

              • 简单而高效,是所有收集器里额外内存消耗(Memory Footprint)最小的。
              • 对于单核处理器或处理器核心数较少的环境来说,由于没有线程交互的开销,可以获得最高的单线程收集效率。

              ParNew收集器

              Serial收集器的多线程并行版本

              除了Serial收集器外,目前只有它能与CMS收集器配合工作。

              自JDK 9开始,ParNew合并入CMS。

              Parallel Scavenge收集器

              从表面上看和ParNew非常相似

              CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)。

              $$ \\text{吞吐量}= \\frac{ \\text{运行用户代码时间} }{ \\text{运行用户代码时间+运行垃圾收集时间} } $$

              停顿时间越短就越适合需要与用户交互或需要保证服务响应质量的程序,高吞吐量则可以最高效率地利用处理器资源,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的分析任务。

              Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量

              • -XX:MaxGCPauseMillis 控制最大垃圾收集停顿时间

                参数允许的值是一个大于0的毫秒数

                收集器将尽力保证内存回收花费的时间不超过用户设定值

              • -XX:GCTimeRatio 直接设置吞吐量大小

                参数的值则应当是一个大于0小于100的整数,相当于吞吐量的倒数。

              由于与吞吐量关系密切,Parallel Scavenge收集器也经常被称作“吞吐量优先收集器”。

              除上述两个参数之外,Parallel Scavenge收集器还有一个参数-XX:+UseAdaptiveSizePolicy值得我们关注。这是一个开关参数,当这个参数被激活之后,就不需要人工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象大小(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。这种调节方式称为垃圾收集的自适应的调节策略(GC Ergonomics)

              自适应调节策略也是Parallel Scavenge收集器区别于ParNew收集器的一个重要特性。

              Serial Old收集器

              Serial Old是Serial收集器的老年代版本

              用途

              1. 在JDK 5以及之前的版本中与Parallel Scavenge收集器搭配使用。
              2. 作为CMS收集器发生失败时的后备预案,在并发收集发生Concurrent Mode Failure时使用。

              Parallel Old收集器

              Parallel Old是Parallel Scavenge收集器的老年代版本

              基于标记-整理算法

              在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器这个组合。

              CMS收集器

              CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。

              基于标记-清除算法

              运作过程相对于前面几种收集器来说要更复杂一些,整个过程分为四个步骤,包括:

              ',34)),e("ol",null,[t[5]||(t[5]=e("li",null,[e("p",null,"初始标记(CMS initial mark)"),e("p",null,"STW"),e("p",null,"标记一下GCRoots能直接关联到的对象,速度很快。")],-1)),t[6]||(t[6]=e("li",null,[e("p",null,"并发标记(CMS concurrent mark)"),e("p",null,"从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行。")],-1)),e("li",null,[t[3]||(t[3]=e("p",null,"重新标记(CMS remark)",-1)),t[4]||(t[4]=e("p",null,"STW",-1)),e("p",null,[t[1]||(t[1]=a("为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录(")),i(n,{to:"/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8A%EF%BC%89.html#%E5%B9%B6%E5%8F%91%E7%9A%84%E5%8F%AF%E8%BE%BE%E6%80%A7%E5%88%86%E6%9E%90"},{default:r(()=>t[0]||(t[0]=[a("增量更新")])),_:1}),t[2]||(t[2]=a("),停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短。"))])]),t[7]||(t[7]=e("li",null,[e("p",null,"并发清除(CMS concurrent sweep)"),e("p",null,"清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。")],-1))]),t[12]||(t[12]=l('

              缺点

              • 会因为占用了一部分线程
              • 无法处理“浮动垃圾”(Floating Garbage),即在并发标记和并发清除的过程中出现的新的垃圾对象。
                • 必须预留一部分空间供并发收集时的程序运作使用
                • 预留的内存无法满足程序分配新对象的需要,就会出现一次“并发失败”(Concurrent Mode Failure)。然后冻结用户线程的执行,临时启用Serial Old收集器来重新进行老年代的垃圾收集。
              • 基于“标记-清除”算法,会有大量空间碎片产生。
                • -XX:+UseCMS-CompactAtFullCollection (默认是开启的,此参数从JDK 9开始废弃)用于在CMS收集器不得不进行Full GC时开启内存碎片的合并整理过程.
                • -XX:CMSFullGCsBefore-Compaction 要求CMS收集器在执行过若干次(数量由参数值决定)不整理空间的Full GC之后,下一次进入Full GC前会先进行碎片整理(默认值为0,表示每次进入Full GC时都进行碎片整理)。

              Garbage First收集器

              虽然G1也仍是遵循分代收集理论设计的,但其堆内存的布局与其他收集器有非常明显的差异:G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间。

              Region中还有一类特殊的Humongous区域,专门用来存储大对象。

              这种使用Region划分内存空间,以及具有优先级的区域回收方式,保证了G1收集器在有限的时间内获取尽可能高的收集效率。

              G1收集器Region分区示意图
              G1收集器Region分区示意图

              跨代引用问题

              G1的记忆集在存储结构的本质上是一种哈希表,Key是别的Region的起始地址,Value是一个集合,里面存储的元素是卡表的索引号。

              这种“双向”的卡表结构(卡表是“我指向谁”,这种结构还记录了“谁指向我”)比原来的卡表实现起来更复杂,同时由于Region数量比传统收集器的分代数量明显要多得多,因此G1收集器要比其他的传统垃圾收集器有着更高的内存占用负担。

              并发问题

              CMS收集器采用增量更新算法实现,而G1收集器则是通过原始快照(SATB) 算法来实现的。

              G1为每一个Region设计了两个名为TAMS(Top at Mark Start)的指针,把Region中的一部分空间划分出来用于并发回收过程中的新对象分配,并发回收时新分配的对象地址都必须要在这两个指针位置以上。G1收集器默认在这个地址以上的对象是被隐式标记过的,即默认它们是存活的,不纳入回收范围。

              如果内存回收的速度赶不上内存分配的速度,G1收集器也要被迫冻结用户线程执行,导致Full GC而产生长时间“Stop The World”。

              运作过程

              如果我们不去计算用户线程运行过程中的动作(如使用写屏障维护记忆集的操作),G1收集器的运作过程大致可划分为以下四个步骤:

              • 初始标记(Initial Marking)

                标记一下GC Roots能直接关联到的对象,并且修改TAMS指针的值。需要停顿线程,但耗时很短,而且是借用进行Minor GC的时候同步完成的,所以G1收集器在这个阶段实际并没有额外的停顿。

              • 并发标记(Concurrent Marking)

                对堆中对象进行可达性分析,当对象图扫描完成以后,还要重新处理SATB记录下的在并发时有引用变动的对象。

              • 最终标记(Final Marking)

                对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录。

              • 筛选回收(Live Data Counting and Evacuation)

                负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧Region的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。

              设置不同的期望停顿时间,可使得G1在不同应用场景中取得关注吞吐量和关注延迟之间的最佳平衡。

              G1从整体来看是基于“标记-整理”算法实现的收集器,但从局部(两个Region之间)上看又是基于“标记-复制”算法实现,无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片

              G1无论是为了垃圾收集产生的内存占用(Footprint)还是程序运行时的额外执行负载(Overload)都要比CMS要高。

              目前在小内存应用上CMS的表现大概率仍然要会优于G1,而在大内存应用上G1则大多能发挥其优势,这个优劣势的Java堆容量平衡点通常在6GB至8GB之间

              低延迟垃圾收集器

              衡量垃圾收集器的三项最重要的指标是:内存占用(Footprint)、吞吐量(Throughput)和延迟(Latency),三者共同构成了一个“不可能三角”。

              这三项指标里,延迟的重要性日益凸显,越发备受关注。

              各款收集器的并发情况
              各款收集器的并发情况

              浅色阶段表示必须挂起用户线程,深色表示收集器线程与用户线程是并发工作的。

              Shenandoah收集器

              Shenandoah也是使用基于Region的堆内存布局,同样有着用于存放大对象的Humongous Region,默认的回收策略也同样是优先处理回收价值最大的Region

              与G1至少有三个明显的不同之处:

              • 支持并发的整理算法

              • 默认不使用分代收集

              • 摒弃了在G1中耗费大量内存和计算资源去维护的记忆集,改用名为“连接矩阵”(ConnectionMatrix)的全局数据结构来记录跨Region的引用关系,降低了处理跨代指针时的记忆集维护消耗,也降低了伪共享问题的发生概率。

                连接矩阵可以简单理解为一张二维表格,如果Region N有对象指向Region M,就在表格的N行M列中打上一个标记

                Shenandoah收集器的连接矩阵示意图
                Shenandoah收集器的连接矩阵示意图

              过程

              • 初始标记(Initial Marking)

                与G1一样,首先标记与GC Roots直接关联的对象,这个阶段仍是“Stop The World”的,但停顿时间与堆大小无关,只与GC Roots的数量相关。

              • 并发标记(Concurrent Marking)

                与G1一样,遍历对象图,标记出全部可达的对象,这个阶段是与用户线程一起并发的,时间长短取决于堆中存活对象的数量以及对象图的结构复杂程度。

              • 最终标记(Final Marking)

                与G1一样,处理剩余的SATB扫描,并在这个阶段统计出回收价值最高的Region,将这些Region构成一组回收集(Collection Set)。最终标记阶段也会有一小段短暂的停顿。

              • 并发清理(Concurrent Cleanup)

                这个阶段用于清理那些整个区域内连一个存活对象都没有找到的Region(这类Region被称为Immediate Garbage Region)。

              • 并发回收(Concurrent Evacuation)

                并发回收阶段是Shenandoah与之前HotSpot中其他收集器的核心差异。在这个阶段,Shenandoah要把回收集里面的存活对象先复制一份到其他未被使用的Region之中。复制对象这件事情如果将用户线程冻结起来再做那是相当简单的,但如果两者必须要同时并发进行的话,就变得复杂起来了。其困难点是在移动对象的同时,用户线程仍然可能不停对被移动的对象进行读写访问,移动对象是一次性的行为,但移动之后整个内存中所有指向该对象的引用都还是旧对象的地址,这是很难一瞬间全部改变过来的。对于并发回收阶段遇到的这些困难,Shenandoah将会通过读屏障和被称为“Brooks Pointers”的转发指针来解决。并发回收阶段运行的时间长短取决于回收集的大小。

              • 初始引用更新(Initial Update Reference)

                并发回收阶段复制对象结束后,还需要把堆中所有指向旧对象的引用修正到复制后的新地址,这个操作称为引用更新。引用更新的初始化阶段实际上并未做什么具体的处理,设立这个阶段只是为了建立一个线程集合点,确保所有并发回收阶段中进行的收集器线程都已完成分配给它们的对象移动任务而已。初始引用更新时间很短,会产生一个非常短暂的停顿。

              • 并发引用更新(Concurrent Update Reference)

                真正开始进行引用更新操作,这个阶段是与用户线程一起并发的,时间长短取决于内存中涉及的引用数量的多少。并发引用更新与并发标记不同,它不再需要沿着对象图来搜索,只需要按照内存物理地址的顺序,线性地搜索出引用类型,把旧值改为新值即可。

              • 最终引用更新(Final Update Reference)

                解决了堆中的引用更新后,还要修正存在于GC Roots中的引用。这个阶段是Shenandoah的最后一次停顿,停顿时间只与GC Roots的数量相关。

              • 并发清理(Concurrent Cleanup)

                经过并发回收和引用更新之后,整个回收集中所有的Region已再无存活对象,这些Region都变成Immediate Garbage Regions了,最后再调用一次并发清理过程来回收这些Region的内存空间,供以后新对象分配使用。

                Shenandoah收集器的工作过程
                Shenandoah收集器的工作过程

                黄色的区域代表的是被选入回收集的Region
                绿色部分就代表还存活的对象
                蓝色就是用户线程可以用来分配对象的内存Region

              转发指针

              ',33)),e("p",null,[t[9]||(t[9]=a("在原有对象布局结构的最前面统一增加一个新的引用字段,用于指向对象地址。与")),i(n,{to:"/books/UnderStandingTheJvm/2.Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8.html#%E5%AF%B9%E8%B1%A1%E7%9A%84%E8%AE%BF%E9%97%AE%E5%AE%9A%E4%BD%8D"},{default:r(()=>t[8]||(t[8]=[a("句柄定位")])),_:1}),t[10]||(t[10]=a("类似"))]),t[13]||(t[13]=l(`

              Shenandoah收集器是通过比较并交换(Compare And Swap,CAS)操作来保证并发时对象的访问正确性的。

              ZGC收集器

              ZGC收集器是一款基于Region内存布局的,(暂时) 不设分代的,使用了读屏障染色指针内存多重映射等技术来实现可并发标记-整理算法的,以低延迟为首要目标的一款垃圾收集器。

              内存布局

              ZGC的Region具有动态性——动态创建和销毁,以及动态的区域容量大小。

              在x64硬件平台下,ZGC的Region可以具有如图3-19所示的大、中、小三类容量:

              • 小型Region(Small Region):容量固定为2MB,用于放置小于256KB的小对象。
              • 中型Region(Medium Region):容量固定为32MB,用于放置大于等于256KB但小于4MB的对象。
              • 大型Region(Large Region):容量不固定,可以动态变化,但必须为2MB的整数倍,用于放置4MB或以上的大对象。每个大型Region中只会存放一个大对象,这也预示着虽然名字叫作“大型Region”,但它的实际容量完全有可能小于中型Region,最小容量可低至4MB。
              ZGC的堆内存布局
              ZGC的堆内存布局

              染色指针

              染色指针是一种直接将少量额外的信息存储在指针上的技术。

              染色指针示意
              染色指针示意

              三大优势:

              • 一旦某个Region的存活对象被移走之后,这个Region立即就能够被释放和重用掉,而不必等待整个堆中所有指向该Region的引用都被修正后才能清理

              • 大幅减少在垃圾收集过程中内存屏障的使用数量

                到目前为止ZGC都并未使用任何写屏障,只使用了读屏障(一部分是染色指针的功劳,一部分是ZGC现在还不支持分代收集,天然就没有跨代引用的问题)。

              • 可以作为一种可扩展的存储结构用来记录更多与对象标记、重定位过程相关的数据,以便日后进一步提高性能

              多重映射

              Linux/x86-64平台上的ZGC使用了多重映射(Multi-Mapping)将多个不同的虚拟内存地址映射到同一个物理内存地址上,这是一种多对一映射,意味着ZGC在虚拟内存中看到的地址空间要比实际的堆内存容量来得更大。把染色指针中的标志位看作是地址的分段符,那只要将这些不同的地址段都映射到同一个物理内存空间,经过多重映射转换后,就可以使用染色指针正常进行寻址了

              流程 todo

              • 并发标记(Concurrent Mark)

                与G1、Shenandoah不同的是,ZGC的标记是在指针上而不是在对象上进行的,标记阶段会更新染色指针中的Marked 0、Marked 1标志位。

              • 并发预备重分配(Concurrent Prepare for Relocate)

                需要根据特定的查询条件统计得出本次收集过程要清理哪些Region,将这些Region组成重分配集(Relocation Set)。ZGC的重分配集只是决定了里面的存活对象会被重新复制到其他的Region中,里面的Region会被释放,而并不能说回收行为就只是针对这个集合里面的Region进行,因为标记过程是针对全堆的。

              • 并发重分配(Concurrent Relocate)

                重分配是ZGC执行过程中的核心阶段,这个过程要把重分配集中的存活对象复制到新的Region上,并为重分配集中的每个Region维护一个转发表(ForwardTable),记录从旧对象到新对象的转向关系。

              • 并发重映射(Concurrent Remap)

              选择合适的垃圾收集器

              Epsilon收集器

              Epsilon被形容成一个无操作的收集器(A No-Op Garbage Collector)

              收集器的权衡

              • 应用程序的主要关注点
                • 如果是数据分析、科学计算类的任务,目标是能尽快算出结果,那吞吐量就是主要关注点
                • 如果是SLA应用,那停顿时间直接影响服务质量,严重的甚至会导致事务超时,这样延迟就是主要关注点
                • 如果是客户端应用或者嵌入式应用,那垃圾收集的内存占用则是不可忽视的

              虚拟机及垃圾收集器日志

              HotSpot所有功能的日志都收归到了“-Xlog”参数上 (JDK9)

              -Xlog[:[selector][:[output][:[decorators][:output-options]]]]
              +import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as d,b as l,a as e,d as a,e as i,w as r,r as p,o as s}from"./app-DGSXj59V.js";const c={};function g(h,t){const n=p("RouteLink");return s(),d("div",null,[t[11]||(t[11]=l('

              3.垃圾收集器与内存分配策略(下)

              经典垃圾收集器

              HotSpot虚拟机的垃圾收集器
              HotSpot虚拟机的垃圾收集器

              两个收集器之间存在连线,就说明它们可以搭配使用

              Serial收集器

              新生代、标记-复制算法实现、单线程、阻塞

              优点

              • 简单而高效,是所有收集器里额外内存消耗(Memory Footprint)最小的。
              • 对于单核处理器或处理器核心数较少的环境来说,由于没有线程交互的开销,可以获得最高的单线程收集效率。

              ParNew收集器

              Serial收集器的多线程并行版本

              除了Serial收集器外,目前只有它能与CMS收集器配合工作。

              自JDK 9开始,ParNew合并入CMS。

              Parallel Scavenge收集器

              从表面上看和ParNew非常相似

              CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)。

              $$ \\text{吞吐量}= \\frac{ \\text{运行用户代码时间} }{ \\text{运行用户代码时间+运行垃圾收集时间} } $$

              停顿时间越短就越适合需要与用户交互或需要保证服务响应质量的程序,高吞吐量则可以最高效率地利用处理器资源,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的分析任务。

              Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量

              • -XX:MaxGCPauseMillis 控制最大垃圾收集停顿时间

                参数允许的值是一个大于0的毫秒数

                收集器将尽力保证内存回收花费的时间不超过用户设定值

              • -XX:GCTimeRatio 直接设置吞吐量大小

                参数的值则应当是一个大于0小于100的整数,相当于吞吐量的倒数。

              由于与吞吐量关系密切,Parallel Scavenge收集器也经常被称作“吞吐量优先收集器”。

              除上述两个参数之外,Parallel Scavenge收集器还有一个参数-XX:+UseAdaptiveSizePolicy值得我们关注。这是一个开关参数,当这个参数被激活之后,就不需要人工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象大小(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。这种调节方式称为垃圾收集的自适应的调节策略(GC Ergonomics)

              自适应调节策略也是Parallel Scavenge收集器区别于ParNew收集器的一个重要特性。

              Serial Old收集器

              Serial Old是Serial收集器的老年代版本

              用途

              1. 在JDK 5以及之前的版本中与Parallel Scavenge收集器搭配使用。
              2. 作为CMS收集器发生失败时的后备预案,在并发收集发生Concurrent Mode Failure时使用。

              Parallel Old收集器

              Parallel Old是Parallel Scavenge收集器的老年代版本

              基于标记-整理算法

              在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器这个组合。

              CMS收集器

              CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。

              基于标记-清除算法

              运作过程相对于前面几种收集器来说要更复杂一些,整个过程分为四个步骤,包括:

              ',34)),e("ol",null,[t[5]||(t[5]=e("li",null,[e("p",null,"初始标记(CMS initial mark)"),e("p",null,"STW"),e("p",null,"标记一下GCRoots能直接关联到的对象,速度很快。")],-1)),t[6]||(t[6]=e("li",null,[e("p",null,"并发标记(CMS concurrent mark)"),e("p",null,"从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行。")],-1)),e("li",null,[t[3]||(t[3]=e("p",null,"重新标记(CMS remark)",-1)),t[4]||(t[4]=e("p",null,"STW",-1)),e("p",null,[t[1]||(t[1]=a("为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录(")),i(n,{to:"/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8A%EF%BC%89.html#%E5%B9%B6%E5%8F%91%E7%9A%84%E5%8F%AF%E8%BE%BE%E6%80%A7%E5%88%86%E6%9E%90"},{default:r(()=>t[0]||(t[0]=[a("增量更新")])),_:1}),t[2]||(t[2]=a("),停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短。"))])]),t[7]||(t[7]=e("li",null,[e("p",null,"并发清除(CMS concurrent sweep)"),e("p",null,"清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。")],-1))]),t[12]||(t[12]=l('

              缺点

              • 会因为占用了一部分线程
              • 无法处理“浮动垃圾”(Floating Garbage),即在并发标记和并发清除的过程中出现的新的垃圾对象。
                • 必须预留一部分空间供并发收集时的程序运作使用
                • 预留的内存无法满足程序分配新对象的需要,就会出现一次“并发失败”(Concurrent Mode Failure)。然后冻结用户线程的执行,临时启用Serial Old收集器来重新进行老年代的垃圾收集。
              • 基于“标记-清除”算法,会有大量空间碎片产生。
                • -XX:+UseCMS-CompactAtFullCollection (默认是开启的,此参数从JDK 9开始废弃)用于在CMS收集器不得不进行Full GC时开启内存碎片的合并整理过程.
                • -XX:CMSFullGCsBefore-Compaction 要求CMS收集器在执行过若干次(数量由参数值决定)不整理空间的Full GC之后,下一次进入Full GC前会先进行碎片整理(默认值为0,表示每次进入Full GC时都进行碎片整理)。

              Garbage First收集器

              虽然G1也仍是遵循分代收集理论设计的,但其堆内存的布局与其他收集器有非常明显的差异:G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间。

              Region中还有一类特殊的Humongous区域,专门用来存储大对象。

              这种使用Region划分内存空间,以及具有优先级的区域回收方式,保证了G1收集器在有限的时间内获取尽可能高的收集效率。

              G1收集器Region分区示意图
              G1收集器Region分区示意图

              跨代引用问题

              G1的记忆集在存储结构的本质上是一种哈希表,Key是别的Region的起始地址,Value是一个集合,里面存储的元素是卡表的索引号。

              这种“双向”的卡表结构(卡表是“我指向谁”,这种结构还记录了“谁指向我”)比原来的卡表实现起来更复杂,同时由于Region数量比传统收集器的分代数量明显要多得多,因此G1收集器要比其他的传统垃圾收集器有着更高的内存占用负担。

              并发问题

              CMS收集器采用增量更新算法实现,而G1收集器则是通过原始快照(SATB) 算法来实现的。

              G1为每一个Region设计了两个名为TAMS(Top at Mark Start)的指针,把Region中的一部分空间划分出来用于并发回收过程中的新对象分配,并发回收时新分配的对象地址都必须要在这两个指针位置以上。G1收集器默认在这个地址以上的对象是被隐式标记过的,即默认它们是存活的,不纳入回收范围。

              如果内存回收的速度赶不上内存分配的速度,G1收集器也要被迫冻结用户线程执行,导致Full GC而产生长时间“Stop The World”。

              运作过程

              如果我们不去计算用户线程运行过程中的动作(如使用写屏障维护记忆集的操作),G1收集器的运作过程大致可划分为以下四个步骤:

              • 初始标记(Initial Marking)

                标记一下GC Roots能直接关联到的对象,并且修改TAMS指针的值。需要停顿线程,但耗时很短,而且是借用进行Minor GC的时候同步完成的,所以G1收集器在这个阶段实际并没有额外的停顿。

              • 并发标记(Concurrent Marking)

                对堆中对象进行可达性分析,当对象图扫描完成以后,还要重新处理SATB记录下的在并发时有引用变动的对象。

              • 最终标记(Final Marking)

                对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录。

              • 筛选回收(Live Data Counting and Evacuation)

                负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧Region的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。

              设置不同的期望停顿时间,可使得G1在不同应用场景中取得关注吞吐量和关注延迟之间的最佳平衡。

              G1从整体来看是基于“标记-整理”算法实现的收集器,但从局部(两个Region之间)上看又是基于“标记-复制”算法实现,无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片

              G1无论是为了垃圾收集产生的内存占用(Footprint)还是程序运行时的额外执行负载(Overload)都要比CMS要高。

              目前在小内存应用上CMS的表现大概率仍然要会优于G1,而在大内存应用上G1则大多能发挥其优势,这个优劣势的Java堆容量平衡点通常在6GB至8GB之间

              低延迟垃圾收集器

              衡量垃圾收集器的三项最重要的指标是:内存占用(Footprint)、吞吐量(Throughput)和延迟(Latency),三者共同构成了一个“不可能三角”。

              这三项指标里,延迟的重要性日益凸显,越发备受关注。

              各款收集器的并发情况
              各款收集器的并发情况

              浅色阶段表示必须挂起用户线程,深色表示收集器线程与用户线程是并发工作的。

              Shenandoah收集器

              Shenandoah也是使用基于Region的堆内存布局,同样有着用于存放大对象的Humongous Region,默认的回收策略也同样是优先处理回收价值最大的Region

              与G1至少有三个明显的不同之处:

              • 支持并发的整理算法

              • 默认不使用分代收集

              • 摒弃了在G1中耗费大量内存和计算资源去维护的记忆集,改用名为“连接矩阵”(ConnectionMatrix)的全局数据结构来记录跨Region的引用关系,降低了处理跨代指针时的记忆集维护消耗,也降低了伪共享问题的发生概率。

                连接矩阵可以简单理解为一张二维表格,如果Region N有对象指向Region M,就在表格的N行M列中打上一个标记

                Shenandoah收集器的连接矩阵示意图
                Shenandoah收集器的连接矩阵示意图

              过程

              • 初始标记(Initial Marking)

                与G1一样,首先标记与GC Roots直接关联的对象,这个阶段仍是“Stop The World”的,但停顿时间与堆大小无关,只与GC Roots的数量相关。

              • 并发标记(Concurrent Marking)

                与G1一样,遍历对象图,标记出全部可达的对象,这个阶段是与用户线程一起并发的,时间长短取决于堆中存活对象的数量以及对象图的结构复杂程度。

              • 最终标记(Final Marking)

                与G1一样,处理剩余的SATB扫描,并在这个阶段统计出回收价值最高的Region,将这些Region构成一组回收集(Collection Set)。最终标记阶段也会有一小段短暂的停顿。

              • 并发清理(Concurrent Cleanup)

                这个阶段用于清理那些整个区域内连一个存活对象都没有找到的Region(这类Region被称为Immediate Garbage Region)。

              • 并发回收(Concurrent Evacuation)

                并发回收阶段是Shenandoah与之前HotSpot中其他收集器的核心差异。在这个阶段,Shenandoah要把回收集里面的存活对象先复制一份到其他未被使用的Region之中。复制对象这件事情如果将用户线程冻结起来再做那是相当简单的,但如果两者必须要同时并发进行的话,就变得复杂起来了。其困难点是在移动对象的同时,用户线程仍然可能不停对被移动的对象进行读写访问,移动对象是一次性的行为,但移动之后整个内存中所有指向该对象的引用都还是旧对象的地址,这是很难一瞬间全部改变过来的。对于并发回收阶段遇到的这些困难,Shenandoah将会通过读屏障和被称为“Brooks Pointers”的转发指针来解决。并发回收阶段运行的时间长短取决于回收集的大小。

              • 初始引用更新(Initial Update Reference)

                并发回收阶段复制对象结束后,还需要把堆中所有指向旧对象的引用修正到复制后的新地址,这个操作称为引用更新。引用更新的初始化阶段实际上并未做什么具体的处理,设立这个阶段只是为了建立一个线程集合点,确保所有并发回收阶段中进行的收集器线程都已完成分配给它们的对象移动任务而已。初始引用更新时间很短,会产生一个非常短暂的停顿。

              • 并发引用更新(Concurrent Update Reference)

                真正开始进行引用更新操作,这个阶段是与用户线程一起并发的,时间长短取决于内存中涉及的引用数量的多少。并发引用更新与并发标记不同,它不再需要沿着对象图来搜索,只需要按照内存物理地址的顺序,线性地搜索出引用类型,把旧值改为新值即可。

              • 最终引用更新(Final Update Reference)

                解决了堆中的引用更新后,还要修正存在于GC Roots中的引用。这个阶段是Shenandoah的最后一次停顿,停顿时间只与GC Roots的数量相关。

              • 并发清理(Concurrent Cleanup)

                经过并发回收和引用更新之后,整个回收集中所有的Region已再无存活对象,这些Region都变成Immediate Garbage Regions了,最后再调用一次并发清理过程来回收这些Region的内存空间,供以后新对象分配使用。

                Shenandoah收集器的工作过程
                Shenandoah收集器的工作过程

                黄色的区域代表的是被选入回收集的Region
                绿色部分就代表还存活的对象
                蓝色就是用户线程可以用来分配对象的内存Region

              转发指针

              ',33)),e("p",null,[t[9]||(t[9]=a("在原有对象布局结构的最前面统一增加一个新的引用字段,用于指向对象地址。与")),i(n,{to:"/books/UnderStandingTheJvm/2.Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8.html#%E5%AF%B9%E8%B1%A1%E7%9A%84%E8%AE%BF%E9%97%AE%E5%AE%9A%E4%BD%8D"},{default:r(()=>t[8]||(t[8]=[a("句柄定位")])),_:1}),t[10]||(t[10]=a("类似"))]),t[13]||(t[13]=l(`

              Shenandoah收集器是通过比较并交换(Compare And Swap,CAS)操作来保证并发时对象的访问正确性的。

              ZGC收集器

              ZGC收集器是一款基于Region内存布局的,(暂时) 不设分代的,使用了读屏障染色指针内存多重映射等技术来实现可并发标记-整理算法的,以低延迟为首要目标的一款垃圾收集器。

              内存布局

              ZGC的Region具有动态性——动态创建和销毁,以及动态的区域容量大小。

              在x64硬件平台下,ZGC的Region可以具有如图3-19所示的大、中、小三类容量:

              • 小型Region(Small Region):容量固定为2MB,用于放置小于256KB的小对象。
              • 中型Region(Medium Region):容量固定为32MB,用于放置大于等于256KB但小于4MB的对象。
              • 大型Region(Large Region):容量不固定,可以动态变化,但必须为2MB的整数倍,用于放置4MB或以上的大对象。每个大型Region中只会存放一个大对象,这也预示着虽然名字叫作“大型Region”,但它的实际容量完全有可能小于中型Region,最小容量可低至4MB。
              ZGC的堆内存布局
              ZGC的堆内存布局

              染色指针

              染色指针是一种直接将少量额外的信息存储在指针上的技术。

              染色指针示意
              染色指针示意

              三大优势:

              • 一旦某个Region的存活对象被移走之后,这个Region立即就能够被释放和重用掉,而不必等待整个堆中所有指向该Region的引用都被修正后才能清理

              • 大幅减少在垃圾收集过程中内存屏障的使用数量

                到目前为止ZGC都并未使用任何写屏障,只使用了读屏障(一部分是染色指针的功劳,一部分是ZGC现在还不支持分代收集,天然就没有跨代引用的问题)。

              • 可以作为一种可扩展的存储结构用来记录更多与对象标记、重定位过程相关的数据,以便日后进一步提高性能

              多重映射

              Linux/x86-64平台上的ZGC使用了多重映射(Multi-Mapping)将多个不同的虚拟内存地址映射到同一个物理内存地址上,这是一种多对一映射,意味着ZGC在虚拟内存中看到的地址空间要比实际的堆内存容量来得更大。把染色指针中的标志位看作是地址的分段符,那只要将这些不同的地址段都映射到同一个物理内存空间,经过多重映射转换后,就可以使用染色指针正常进行寻址了

              流程 todo

              • 并发标记(Concurrent Mark)

                与G1、Shenandoah不同的是,ZGC的标记是在指针上而不是在对象上进行的,标记阶段会更新染色指针中的Marked 0、Marked 1标志位。

              • 并发预备重分配(Concurrent Prepare for Relocate)

                需要根据特定的查询条件统计得出本次收集过程要清理哪些Region,将这些Region组成重分配集(Relocation Set)。ZGC的重分配集只是决定了里面的存活对象会被重新复制到其他的Region中,里面的Region会被释放,而并不能说回收行为就只是针对这个集合里面的Region进行,因为标记过程是针对全堆的。

              • 并发重分配(Concurrent Relocate)

                重分配是ZGC执行过程中的核心阶段,这个过程要把重分配集中的存活对象复制到新的Region上,并为重分配集中的每个Region维护一个转发表(ForwardTable),记录从旧对象到新对象的转向关系。

              • 并发重映射(Concurrent Remap)

              选择合适的垃圾收集器

              Epsilon收集器

              Epsilon被形容成一个无操作的收集器(A No-Op Garbage Collector)

              收集器的权衡

              • 应用程序的主要关注点
                • 如果是数据分析、科学计算类的任务,目标是能尽快算出结果,那吞吐量就是主要关注点
                • 如果是SLA应用,那停顿时间直接影响服务质量,严重的甚至会导致事务超时,这样延迟就是主要关注点
                • 如果是客户端应用或者嵌入式应用,那垃圾收集的内存占用则是不可忽视的

              虚拟机及垃圾收集器日志

              HotSpot所有功能的日志都收归到了“-Xlog”参数上 (JDK9)

              -Xlog[:[selector][:[output][:[decorators][:output-options]]]]
               

              selector

              命令行中最关键的参数是选择器(Selector),它由标签(Tag)和日志级别(Level)共同组成。

              垃圾收集器的标签名称为“gc”

              HotSpot众多功能日志的其中一项,全部支持的功能模块标签名如下所示

              add,age,alloc,annotation,aot,arguments,attach,barrier,biasedlocking,blocks,bot,breakpoint,bytecode,census,class,classhisto,cleanup,compaction,comparator,constraints,constantpool,coops,cpu,cset,data,defaultmethods,dump,ergo,event,exceptions,exit,fingerprint,freelist,gc,hashtables,heap,humongous,ihop,iklass,init,itables,jfr,jni,jvmti,liveness,load,loader,logging,mark,marking,metadata,metaspace,method,mmu,modules,monitorinflation,monitormismatch,nmethod,normalize,objecttagging,obsolete,oopmap,os,pagesize,parser,patch,path,phases,plab,preorder,promotion,protectiondomain,purge,redefine,ref,refine,region,remset,resolve,safepoint,scavenge,scrub,setting,stackmap,stacktrace,stackwalk,start,startuptime,state,stats,stringdedup,stringtable,subclass,survivor,sweep,system,task,thread,time,timer,tlab,unload,update,verification,verify,vmoperation,vtables,workgang

              日志级别从低到高,共有Trace,Debug,Info,Warning,Error,Off六种级别:还可以使用修饰器(Decorator)来要求每行日志输出都附加上额外的内容,支持附加在日志行上的信息包括:

              • time:当前日期和时间。
              • uptime:虚拟机启动到现在经过的时间,以秒为单位。
              • timemillis:当前时间的毫秒数,相当于System.currentTimeMillis()的输出。
              • uptimemillis:虚拟机启动到现在经过的毫秒数。
              • timenanos:当前时间的纳秒数,相当于System.nanoTime()的输出。
              • uptimenanos:虚拟机启动到现在经过的纳秒数。
              • pid:进程ID。
              • tid:线程ID。
              • level:日志级别。
              • tags:日志输出的标签集。

              如果不指定,默认值是uptime、level、tags

              参数使用

              JDK 9前日志参数JDK 9后配置形式
              G1PrintHeapRegionsXlog:gc+region=trace
              G1PrintRegionLivenessInfoXlog:gc+liveness=trace
              G1SummarizeConcMarkXlog:gc+marking=trace
              G1SummarizeRSetStatsXlog:gc+remset*=trace
              GCLogFileSize, NumberOfGCLogFiles, UseGCLog File RotationXlog:gc*:file=<file>::filecount=<count>, filesize=<file size in kb>
              PrintAdaptiveSizePolicyXlog:gc+ergo*=trace
              PrintClassHistogramAfterFullGCXlog:classhisto*=trace
              PrintClassHistogramBeforeFullGCXlog:classhisto*=trace
              PrintGCApplicationConcurrentTimeXlog:safepoint
              PrintGCApplicationStoppedTimeXlog:safepoint
              PrintGCDateStamps使用time修饰器
              PrintGCTaskTimeStampsXlog:gc+task=trace
              PrintGCTimeStamps使用uptime修饰器
              PrintHeapAtGCXlog:gc+heap=debug
              PrintHeapAtGCExtendedXlog:gc+heap=trace
              PrintJNIGCStallsXlog:gc+jni=debug
              PrintOldPLABXlog:gc+plab=trace
              PrintParallelOldGCPhaseTimesXlog:gc+phases=trace
              PrintPLABXlog:gc+plab=trace
              PrintPromotionFailureXlog:gc+promotion=debug
              PrintReferenceGCXlog:gc+ref=debug
              PrintStringDeduplicationStatisticsXlog:gc+stringdedup
              PrintTaskqueueXlog:gc+task+stats=trace
              PrintTenuringDistributionXlog:gc+age=trace
              PrintTerminationStatsXlog:gc+task+stats=debug
              PrintTLABXlog:gc+tlab=trace
              TraceAdaptiveGCBoundaryXlog:heap+ergo=debug
              TraceDynamicGCThreadsXlog:gc+task=trace
              TraceMetadataHumongousAllocationXlog:ge+metaspace+alloc=debug
              G1TraceConcRefinementXlog:ge+refine=debug
              G1TraceEagerReclaimHumongousObjectsXlog:gc+humongous=debug
              G1TraceStringSymbolTableScrubbingXlog:gc+stringtable=trace

              #### 垃圾收集器参数总结

              参数描述
              UseSerialGC虚拟机运行在Client模式下的默认值,打开此开关后,使用Serial+Serial Old的收集器组合进行内存回收
              UseParNewGC打开此开关后,使用ParNew+Serial Old的收集器组合进行内存回收,在JDK9后不再支持
              UseConcMarkSweepGC打开此开关后,使用ParNew+CMS+Serial Old的收集器组合进行内存回收。Serial Old收集器将作为CMS收集器出现"Concurrent Mode Failure"失败后的后备收集器使用
              UseParallelGCJDK 9之前虚拟机运行在Server模式下的默认值,打开此开关后,使用Parallel Scavenge +Serial Old(PS MarkSweep)的收集器组合进行内存回收
              UseParallelOldGC打开此开关后,使用Parallel Scavenge +Parallel Old的收集器组合进行内存回收
              SurvivorRatio新生代中Eden区域与Survivor区域的容量比值,默认为8,代表Eden:Survivor=8:1
              PretenureSizeThreshold直接晋升到老年代的对象大小,设置这个参数后,大于这个参数的对象将直接在老年代分配
              MaxTenuringThreshold晋升到老年代的对象年龄。每个对象在坚持过一次Minor GC之后,年龄就增加1,当超过这个参数值时就进入老年代
              UseAdaptiveSizePolicy动态调整Java堆中各个区域的大小以及进入老年代的年龄
              HandlePromotionFailure是否允许分配担保失败,即老年代的剩余空间不足以应付新生代的整个Eden和Survivor区的所有对象都存活的极端情况
              ParallelGCThreads设置并行GC时进行内存回收的线程数
              GCTimeRatioGC时间占总时间的比率,默认值为99,即允许1%的GC时间。仅在使用Parallel Scavenge收集器时生效
              MaxGCPauseMillis设置GC的最大停顿时间。仅在使用Parallel Scavenge收集器时生效
              CMSInitiatingOccupancyFraction设置CMS收集器在老年代空间被使用多少后触发垃圾收集。默认值为68%,仅在使用CMS收集器时生效
              UseCMSCompactAtFullCollection设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片整理。仅在使用CMS收集器时生效,此参数从JDK 9开始废弃
              CMSFullGCsBeforeCompaction设置CMS收集器在进行若干次垃圾收集后再启动一次内存碎片整理。仅在使用CMS收集器时生效,此参数从JDK 9开始废弃
              UseG1GC使用G1收集器,这个是JDK 9后的Server模式默认值
              G1HeapRegionSize=n设置Region大小,并非最终值
              MaxGCPauseMillis设置G1收集过程目标时间,默认值是200ms,不是硬性条件
              G1NewSizePercent新生代最小值,默认值是5%
              G1MaxNewSizePercent新生代最大值,默认值是60%
              ParallelGCThreads用户线程冻结期间并行执行的收集器线程数
              ConcGCThreads=n并发标记、并发整理的执行线程数,对不同的收集器,根据其能够并发的阶段,有不同的含义
              InitiatingHeapOccupancyPercent设置触发标记周期的Java堆占用率阈值。默认值是45%。这里的java堆占比指的是non_young_capacity_bytes,包括old+humongous
              UseShenandoahGC使用Shenandoah收集器。这个选项在OracleJDK中不被支持,只能在OpenJDK 12或者某些支持Shenandoah的Backport发行版本使用。目前仍然要配合-XX:+UnlockExperimentalVMOptions使用
              ShenandoahGCHeuristicsShenandoah何时启动一次GC过程,其可选值有adaptive、static、compact、
              UseZGCpassive、aggressive使用ZGC收集器,目前仍然要配合-XX:+UnlockExperimentalVMOptions使用
              UseNUMA启用NUMA内存分配支持,目前只有Parallel和ZGC支持,以后G1收集器可能也会支持该选项

              内存分配与回收策略

              • 对象优先在Eden分配

              • 大对象直接进入老年代

              • 长期存活的对象将进入老年代

              • 动态年龄判断

                Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代

              • 空间分配担保

                在发生Minor GC之前,虚拟机必须先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那这一次Minor GC可以确保是安全的。如果不成立,则虚拟机会先查看-XX:HandlePromotionFailure参数的设置值是否允许担保失败(Handle Promotion Failure);如果允许,那会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试进行一次Minor GC,尽管这次Minor GC是有风险的;如果小于,或者-XX:HandlePromotionFailure设置不允许冒险,那这时就要改为进行一次Full GC。

                JDK 6 Update 24之后,这个测试结果就有了差异,-XX:HandlePromotionFailure参数不会再影响到虚拟机的空间分配担保策略,DK 6 Update 24之后的规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小,就会进行Minor GC,否则将进行Full GC。

              `,37))])}const C=o(c,[["render",g],["__file","3.垃圾收集器与内存分配策略(下).html.vue"]]),S=JSON.parse('{"path":"/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8B%EF%BC%89.html","title":"3.垃圾收集器与内存分配策略(下)","lang":"zh-CN","frontmatter":{"description":"3.垃圾收集器与内存分配策略(下) 经典垃圾收集器 HotSpot虚拟机的垃圾收集器HotSpot虚拟机的垃圾收集器 两个收集器之间存在连线,就说明它们可以搭配使用 Serial收集器 新生代、标记-复制算法实现、单线程、阻塞 优点 简单而高效,是所有收集器里额外内存消耗(Memory Footprint)最小的。 对于单核处理器或处理器核心数较少的环...","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8B%EF%BC%89.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"3.垃圾收集器与内存分配策略(下)"}],["meta",{"property":"og:description","content":"3.垃圾收集器与内存分配策略(下) 经典垃圾收集器 HotSpot虚拟机的垃圾收集器HotSpot虚拟机的垃圾收集器 两个收集器之间存在连线,就说明它们可以搭配使用 Serial收集器 新生代、标记-复制算法实现、单线程、阻塞 优点 简单而高效,是所有收集器里额外内存消耗(Memory Footprint)最小的。 对于单核处理器或处理器核心数较少的环..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm3-5.jpg"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-09-02T05:37:18.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-09-02T05:37:18.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"3.垃圾收集器与内存分配策略(下)\\",\\"image\\":[\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm3-5.jpg\\",\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm3-6.jpg\\",\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm3-7.jpg\\",\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm3-8.jpg\\",\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm3-9.jpg\\",\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm3-10.jpg\\",\\"https://docs-r2.hanhan12.cc/Java/JVM/UTJVM/jvm3-11.jpg\\"],\\"dateModified\\":\\"2024-09-02T05:37:18.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"经典垃圾收集器","slug":"经典垃圾收集器","link":"#经典垃圾收集器","children":[{"level":3,"title":"Serial收集器","slug":"serial收集器","link":"#serial收集器","children":[{"level":4,"title":"优点","slug":"优点","link":"#优点","children":[]}]},{"level":3,"title":"ParNew收集器","slug":"parnew收集器","link":"#parnew收集器","children":[]},{"level":3,"title":"Parallel Scavenge收集器","slug":"parallel-scavenge收集器","link":"#parallel-scavenge收集器","children":[]},{"level":3,"title":"Serial Old收集器","slug":"serial-old收集器","link":"#serial-old收集器","children":[{"level":4,"title":"用途","slug":"用途","link":"#用途","children":[]}]},{"level":3,"title":"Parallel Old收集器","slug":"parallel-old收集器","link":"#parallel-old收集器","children":[]},{"level":3,"title":"CMS收集器","slug":"cms收集器","link":"#cms收集器","children":[{"level":4,"title":"缺点","slug":"缺点","link":"#缺点","children":[]}]},{"level":3,"title":"Garbage First收集器","slug":"garbage-first收集器","link":"#garbage-first收集器","children":[{"level":4,"title":"跨代引用问题","slug":"跨代引用问题","link":"#跨代引用问题","children":[]},{"level":4,"title":"并发问题","slug":"并发问题","link":"#并发问题","children":[]},{"level":4,"title":"运作过程","slug":"运作过程","link":"#运作过程","children":[]}]}]},{"level":2,"title":"低延迟垃圾收集器","slug":"低延迟垃圾收集器","link":"#低延迟垃圾收集器","children":[{"level":3,"title":"Shenandoah收集器","slug":"shenandoah收集器","link":"#shenandoah收集器","children":[{"level":4,"title":"过程","slug":"过程","link":"#过程","children":[]},{"level":4,"title":"转发指针","slug":"转发指针","link":"#转发指针","children":[]}]},{"level":3,"title":"ZGC收集器","slug":"zgc收集器","link":"#zgc收集器","children":[{"level":4,"title":"内存布局","slug":"内存布局","link":"#内存布局","children":[]},{"level":4,"title":"染色指针","slug":"染色指针","link":"#染色指针","children":[]},{"level":4,"title":"流程 todo","slug":"流程-todo","link":"#流程-todo","children":[]}]}]},{"level":2,"title":"选择合适的垃圾收集器","slug":"选择合适的垃圾收集器","link":"#选择合适的垃圾收集器","children":[{"level":3,"title":"Epsilon收集器","slug":"epsilon收集器","link":"#epsilon收集器","children":[]},{"level":3,"title":"收集器的权衡","slug":"收集器的权衡","link":"#收集器的权衡","children":[]},{"level":3,"title":"虚拟机及垃圾收集器日志","slug":"虚拟机及垃圾收集器日志","link":"#虚拟机及垃圾收集器日志","children":[{"level":4,"title":"selector","slug":"selector","link":"#selector","children":[]},{"level":4,"title":"参数使用","slug":"参数使用","link":"#参数使用","children":[]}]},{"level":3,"title":"#### 垃圾收集器参数总结","slug":"垃圾收集器参数总结","link":"#垃圾收集器参数总结","children":[]},{"level":3,"title":"内存分配与回收策略","slug":"内存分配与回收策略","link":"#内存分配与回收策略","children":[]}]}],"git":{"createdTime":1692084578000,"updatedTime":1725255438000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":2}]},"readingTime":{"minutes":23.29,"words":6988},"filePathRelative":"books/UnderStandingTheJvm/3.垃圾收集器与内存分配策略(下).md","localizedDate":"2023年8月15日","autoDesc":true}');export{C as comp,S as data}; diff --git "a/assets/4.\347\256\241\351\201\223.html-B3H0WI8v.js" "b/assets/4.\347\256\241\351\201\223.html-CWD-xPd8.js" similarity index 98% rename from "assets/4.\347\256\241\351\201\223.html-B3H0WI8v.js" rename to "assets/4.\347\256\241\351\201\223.html-CWD-xPd8.js" index 8869563..8ed8751 100644 --- "a/assets/4.\347\256\241\351\201\223.html-B3H0WI8v.js" +++ "b/assets/4.\347\256\241\351\201\223.html-CWD-xPd8.js" @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as i,b as l,o as p}from"./app-IPkfDkxj.js";const o={};function n(r,e){return p(),i("div",null,e[0]||(e[0]=[l('

              4.管道

              管道(pipeline)可以一次性发送多条命令给服务端,服务端依次处理完毕后,通过一 条响应一次性将结果返回,通过减少客户端与redis的通信次数来实现降低往返延时时间。pipeline实现的原理是队列,先进先出特性就保证数据的顺序性。

              批处理命令变种优化措施,类似Redis的原生批命令(mget和mset)

              小总结

              • pipeline与原生批量命令对比
                1. 原生批量命令是原子性(例如:mset、mget),$\\textcolor{red}{pipeline\\text{是}\\text{非}\\text{原}\\text{子}\\text{性}\\text{的}}$
                2. 原生批量命令一次只能执行一种命令,pipeline支持批量执行不同命令
                3. 原生批量命令是服务端实现,而pipeline需要服务端与客户端共同完成
              • pipeline与事务对比
                1. 事务具有原子性,管道不具有原子性
                2. 管道一次性将多条命令发送到服务器,事务是一条一条的发,事务只有在接收到exec命令后才会执行,管道不会
                3. 执行事务时会阻塞其他命令的执行,而执行管道中的命令时不会
              • 使用pipeline注意事项
                1. pipeline缓冲的指令只是会依次执行,不保证原子性,如果执行中指令发生异常,将会继续执行后续的指令
                2. 使用pipeline组装的命令个数不能太多,不然数量过大客户端阻塞的时间可能过久,同时服务端此时也被迫回复一个队列答复,占用很多内存
              ',5)]))}const c=t(o,[["render",n],["__file","4.管道.html.vue"]]),m=JSON.parse('{"path":"/dbs/redis/4.%E7%AE%A1%E9%81%93.html","title":"管道","lang":"zh-CN","frontmatter":{"title":"管道","order":5,"description":"4.管道 管道(pipeline)可以一次性发送多条命令给服务端,服务端依次处理完毕后,通过一 条响应一次性将结果返回,通过减少客户端与redis的通信次数来实现降低往返延时时间。pipeline实现的原理是队列,先进先出特性就保证数据的顺序性。 批处理命令变种优化措施,类似Redis的原生批命令(mget和mset) 小总结 pipeline与原生批...","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/4.%E7%AE%A1%E9%81%93.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"管道"}],["meta",{"property":"og:description","content":"4.管道 管道(pipeline)可以一次性发送多条命令给服务端,服务端依次处理完毕后,通过一 条响应一次性将结果返回,通过减少客户端与redis的通信次数来实现降低往返延时时间。pipeline实现的原理是队列,先进先出特性就保证数据的顺序性。 批处理命令变种优化措施,类似Redis的原生批命令(mget和mset) 小总结 pipeline与原生批..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-06-14T09:34:35.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-06-14T09:34:35.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"管道\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-06-14T09:34:35.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":3,"title":"小总结","slug":"小总结","link":"#小总结","children":[]}],"git":{"createdTime":1695377321000,"updatedTime":1718357675000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":1.41,"words":423},"filePathRelative":"dbs/redis/4.管道.md","localizedDate":"2023年9月22日","autoDesc":true}');export{c as comp,m as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as i,b as l,o as p}from"./app-DGSXj59V.js";const o={};function n(r,e){return p(),i("div",null,e[0]||(e[0]=[l('

              4.管道

              管道(pipeline)可以一次性发送多条命令给服务端,服务端依次处理完毕后,通过一 条响应一次性将结果返回,通过减少客户端与redis的通信次数来实现降低往返延时时间。pipeline实现的原理是队列,先进先出特性就保证数据的顺序性。

              批处理命令变种优化措施,类似Redis的原生批命令(mget和mset)

              小总结

              • pipeline与原生批量命令对比
                1. 原生批量命令是原子性(例如:mset、mget),$\\textcolor{red}{pipeline\\text{是}\\text{非}\\text{原}\\text{子}\\text{性}\\text{的}}$
                2. 原生批量命令一次只能执行一种命令,pipeline支持批量执行不同命令
                3. 原生批量命令是服务端实现,而pipeline需要服务端与客户端共同完成
              • pipeline与事务对比
                1. 事务具有原子性,管道不具有原子性
                2. 管道一次性将多条命令发送到服务器,事务是一条一条的发,事务只有在接收到exec命令后才会执行,管道不会
                3. 执行事务时会阻塞其他命令的执行,而执行管道中的命令时不会
              • 使用pipeline注意事项
                1. pipeline缓冲的指令只是会依次执行,不保证原子性,如果执行中指令发生异常,将会继续执行后续的指令
                2. 使用pipeline组装的命令个数不能太多,不然数量过大客户端阻塞的时间可能过久,同时服务端此时也被迫回复一个队列答复,占用很多内存
              ',5)]))}const c=t(o,[["render",n],["__file","4.管道.html.vue"]]),m=JSON.parse('{"path":"/dbs/redis/4.%E7%AE%A1%E9%81%93.html","title":"管道","lang":"zh-CN","frontmatter":{"title":"管道","order":5,"description":"4.管道 管道(pipeline)可以一次性发送多条命令给服务端,服务端依次处理完毕后,通过一 条响应一次性将结果返回,通过减少客户端与redis的通信次数来实现降低往返延时时间。pipeline实现的原理是队列,先进先出特性就保证数据的顺序性。 批处理命令变种优化措施,类似Redis的原生批命令(mget和mset) 小总结 pipeline与原生批...","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/4.%E7%AE%A1%E9%81%93.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"管道"}],["meta",{"property":"og:description","content":"4.管道 管道(pipeline)可以一次性发送多条命令给服务端,服务端依次处理完毕后,通过一 条响应一次性将结果返回,通过减少客户端与redis的通信次数来实现降低往返延时时间。pipeline实现的原理是队列,先进先出特性就保证数据的顺序性。 批处理命令变种优化措施,类似Redis的原生批命令(mget和mset) 小总结 pipeline与原生批..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-06-14T09:34:35.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-06-14T09:34:35.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"管道\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-06-14T09:34:35.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":3,"title":"小总结","slug":"小总结","link":"#小总结","children":[]}],"git":{"createdTime":1695377321000,"updatedTime":1718357675000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":1.41,"words":423},"filePathRelative":"dbs/redis/4.管道.md","localizedDate":"2023年9月22日","autoDesc":true}');export{c as comp,m as data}; diff --git "a/assets/4.\350\231\232\346\213\237\346\234\272\346\200\247\350\203\275\347\233\221\346\216\247\343\200\201\346\225\205\351\232\234\345\244\204\347\220\206\345\267\245\345\205\267.html-BURKEJxN.js" "b/assets/4.\350\231\232\346\213\237\346\234\272\346\200\247\350\203\275\347\233\221\346\216\247\343\200\201\346\225\205\351\232\234\345\244\204\347\220\206\345\267\245\345\205\267.html-D4U1I6eG.js" similarity index 99% rename from "assets/4.\350\231\232\346\213\237\346\234\272\346\200\247\350\203\275\347\233\221\346\216\247\343\200\201\346\225\205\351\232\234\345\244\204\347\220\206\345\267\245\345\205\267.html-BURKEJxN.js" rename to "assets/4.\350\231\232\346\213\237\346\234\272\346\200\247\350\203\275\347\233\221\346\216\247\343\200\201\346\225\205\351\232\234\345\244\204\347\220\206\345\267\245\345\205\267.html-D4U1I6eG.js" index ba9603b..1b1969e 100644 --- "a/assets/4.\350\231\232\346\213\237\346\234\272\346\200\247\350\203\275\347\233\221\346\216\247\343\200\201\346\225\205\351\232\234\345\244\204\347\220\206\345\267\245\345\205\267.html-BURKEJxN.js" +++ "b/assets/4.\350\231\232\346\213\237\346\234\272\346\200\247\350\203\275\347\233\221\346\216\247\343\200\201\346\225\205\351\232\234\345\244\204\347\220\206\345\267\245\345\205\267.html-D4U1I6eG.js" @@ -1,4 +1,4 @@ -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as s,o as e}from"./app-IPkfDkxj.js";const d={};function o(r,t){return e(),n("div",null,t[0]||(t[0]=[s(`

              4.虚拟机性能监控、故障处理工具

              基础故障处理工具

              jps:虚拟机进程状况工具

              可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一ID(LVMID,Local Virtual Machine Identifier)。

              jps [ options ] [ hostid ]
              +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as s,o as e}from"./app-DGSXj59V.js";const d={};function o(r,t){return e(),n("div",null,t[0]||(t[0]=[s(`

              4.虚拟机性能监控、故障处理工具

              基础故障处理工具

              jps:虚拟机进程状况工具

              可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一ID(LVMID,Local Virtual Machine Identifier)。

              jps [ options ] [ hostid ]
               
              options作用
              -q只输出LVMID,省略主类的名称
              -m输出虚拟机进程启动时传递给主类main()函数的参数
              -l输出主类的全名,如果进程执行的是JAR包,则输出JAR路径
              -V输出虚拟机进程启动时的JVM参数

              jstat:虚拟机统计信息监视工具

              用于监视虚拟机各种运行状态信息的命令行工具

              jstat -<option> [-t] [-h<lines>] <vmid> [<interval["ms"|"s"]> [<count>]]
               
              选项作用
              -class监视类加载、卸载数量、总空间以及类装载所耗费的时间
              -gc监视Java堆状况,包括Eden区、2个Survivor区、老年代、永久代等的容量,已用空间,垃圾收集时间合计等信息
              -gccapacity监视内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间
              -gcutil监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比
              -gccause与-gcutil功能一样,但是会额外输出导致上一次垃圾收集产生的原因
              -gcnew监视新生代垃圾收集状况
              -gcnewcapacity监视内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间
              -gcold监视老年代垃圾收集状况
              -gcoldcapacity监视内容与-gcold基本相同,输出主要关注使用到的最大、最小空间
              -gcpermcapacity输出永久代使用到的最大、最小空间
              -compiler输出即时编译器编译过的方法、耗时等信息
              -printcompilation输出已经被即时编译的方法
              • vmid<lvmid>[@<hostname>[:<port>]]

              jinfo:Java配置信息工具

              实时查看和调整虚拟机各项参数

              jinfo [option] <pid>
                   (to connect to running process)
              diff --git a/assets/404.html-B4CKWbuD.js b/assets/404.html-CkT6DnzW.js
              similarity index 94%
              rename from assets/404.html-B4CKWbuD.js
              rename to assets/404.html-CkT6DnzW.js
              index 1cfb5a0..3b117a7 100644
              --- a/assets/404.html-B4CKWbuD.js
              +++ b/assets/404.html-CkT6DnzW.js
              @@ -1 +1 @@
              -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a as n,o as r}from"./app-IPkfDkxj.js";const a={};function p(s,t){return r(),o("div",null,t[0]||(t[0]=[n("p",null,"404 Not Found",-1)]))}const l=e(a,[["render",p],["__file","404.html.vue"]]),m=JSON.parse('{"path":"/404.html","title":"","lang":"zh-CN","frontmatter":{"layout":"NotFound","description":"404 Not Found","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/404.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:description","content":"404 Not Found"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"\\",\\"description\\":\\"404 Not Found\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0.01,"words":3},"filePathRelative":null,"autoDesc":true}');export{l as comp,m as data};
              +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a as n,o as r}from"./app-DGSXj59V.js";const a={};function p(s,t){return r(),o("div",null,t[0]||(t[0]=[n("p",null,"404 Not Found",-1)]))}const l=e(a,[["render",p],["__file","404.html.vue"]]),m=JSON.parse('{"path":"/404.html","title":"","lang":"zh-CN","frontmatter":{"layout":"NotFound","description":"404 Not Found","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/404.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:description","content":"404 Not Found"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"\\",\\"description\\":\\"404 Not Found\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0.01,"words":3},"filePathRelative":null,"autoDesc":true}');export{l as comp,m as data};
              diff --git "a/assets/5.\345\217\221\345\270\203\344\270\216\350\256\242\351\230\205.html-DGZVcgfp.js" "b/assets/5.\345\217\221\345\270\203\344\270\216\350\256\242\351\230\205.html-Crzq7Y5K.js"
              similarity index 99%
              rename from "assets/5.\345\217\221\345\270\203\344\270\216\350\256\242\351\230\205.html-DGZVcgfp.js"
              rename to "assets/5.\345\217\221\345\270\203\344\270\216\350\256\242\351\230\205.html-Crzq7Y5K.js"
              index 67d0a43..44fbb6f 100644
              --- "a/assets/5.\345\217\221\345\270\203\344\270\216\350\256\242\351\230\205.html-DGZVcgfp.js"
              +++ "b/assets/5.\345\217\221\345\270\203\344\270\216\350\256\242\351\230\205.html-Crzq7Y5K.js"
              @@ -1,4 +1,4 @@
              -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as s,o as t}from"./app-IPkfDkxj.js";const i={};function l(d,a){return t(),n("div",null,a[0]||(a[0]=[s(`

              5.发布与订阅

              发布/订阅其实是一个轻量的队列,只不过数据不会被持久化,一般用来处理实时性较高的异步消息

              订阅

              订阅后会挂起操作,等待消息发布

              • SUBSCRIBE 订阅频道

                SUBSCRIBE channel [channel ...]
                +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as s,o as t}from"./app-DGSXj59V.js";const i={};function l(d,a){return t(),n("div",null,a[0]||(a[0]=[s(`

                5.发布与订阅

                发布/订阅其实是一个轻量的队列,只不过数据不会被持久化,一般用来处理实时性较高的异步消息

                订阅

                订阅后会挂起操作,等待消息发布

                • SUBSCRIBE 订阅频道

                  SUBSCRIBE channel [channel ...]
                   

                  订阅成功之前发布的消息是收不到的

                • PSUBSCRIBE 按模式匹配订阅

                  PSUBSCRIBE pattern [pattern ...]
                   

                发布

                • PUBLISH 像频道发布消息

                  PUBLISH channel message
                   

                  订阅的客户端每次可以收到一个3个参数的消息

                  1. 消息种类
                  2. 始发频道的名称
                  3. 实际的消息内容

                查看

                • PUBSUB CHANNELS 查看当前活跃的频道

                  PUBSUB CHANNELS [pattern]
                  diff --git "a/assets/5.\350\260\203\344\274\230\346\241\210\344\276\213\345\210\206\346\236\220\344\270\216\345\256\236\346\210\230.html-DdFwZo66.js" "b/assets/5.\350\260\203\344\274\230\346\241\210\344\276\213\345\210\206\346\236\220\344\270\216\345\256\236\346\210\230.html-MlkdMvhD.js"
                  similarity index 97%
                  rename from "assets/5.\350\260\203\344\274\230\346\241\210\344\276\213\345\210\206\346\236\220\344\270\216\345\256\236\346\210\230.html-DdFwZo66.js"
                  rename to "assets/5.\350\260\203\344\274\230\346\241\210\344\276\213\345\210\206\346\236\220\344\270\216\345\256\236\346\210\230.html-MlkdMvhD.js"
                  index e903220..3606bff 100644
                  --- "a/assets/5.\350\260\203\344\274\230\346\241\210\344\276\213\345\210\206\346\236\220\344\270\216\345\256\236\346\210\230.html-DdFwZo66.js"
                  +++ "b/assets/5.\350\260\203\344\274\230\346\241\210\344\276\213\345\210\206\346\236\220\344\270\216\345\256\236\346\210\230.html-MlkdMvhD.js"
                  @@ -1 +1 @@
                  -import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,a as e,o as a}from"./app-IPkfDkxj.js";const r={};function i(p,t){return a(),n("div",null,t[0]||(t[0]=[e("h1",{id:"_5-调优案例分析与实战",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-调优案例分析与实战"},[e("span",null,"5.调优案例分析与实战")])],-1)]))}const s=o(r,[["render",i],["__file","5.调优案例分析与实战.html.vue"]]),d=JSON.parse('{"path":"/books/UnderStandingTheJvm/5.%E8%B0%83%E4%BC%98%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E6%88%98.html","title":"5.调优案例分析与实战","lang":"zh-CN","frontmatter":{"description":"5.调优案例分析与实战","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/5.%E8%B0%83%E4%BC%98%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E6%88%98.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"5.调优案例分析与实战"}],["meta",{"property":"og:description","content":"5.调优案例分析与实战"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"5.调优案例分析与实战\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1693477892000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.03,"words":10},"filePathRelative":"books/UnderStandingTheJvm/5.调优案例分析与实战.md","localizedDate":"2023年8月31日","autoDesc":true}');export{s as comp,d as data};
                  +import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,a as e,o as a}from"./app-DGSXj59V.js";const r={};function i(p,t){return a(),n("div",null,t[0]||(t[0]=[e("h1",{id:"_5-调优案例分析与实战",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-调优案例分析与实战"},[e("span",null,"5.调优案例分析与实战")])],-1)]))}const s=o(r,[["render",i],["__file","5.调优案例分析与实战.html.vue"]]),d=JSON.parse('{"path":"/books/UnderStandingTheJvm/5.%E8%B0%83%E4%BC%98%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E6%88%98.html","title":"5.调优案例分析与实战","lang":"zh-CN","frontmatter":{"description":"5.调优案例分析与实战","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/5.%E8%B0%83%E4%BC%98%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E6%88%98.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"5.调优案例分析与实战"}],["meta",{"property":"og:description","content":"5.调优案例分析与实战"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"5.调优案例分析与实战\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1693477892000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.03,"words":10},"filePathRelative":"books/UnderStandingTheJvm/5.调优案例分析与实战.md","localizedDate":"2023年8月31日","autoDesc":true}');export{s as comp,d as data};
                  diff --git "a/assets/6.\345\244\215\345\210\266.html-BXO5kx7f.js" "b/assets/6.\345\244\215\345\210\266.html-CH73emLp.js"
                  similarity index 99%
                  rename from "assets/6.\345\244\215\345\210\266.html-BXO5kx7f.js"
                  rename to "assets/6.\345\244\215\345\210\266.html-CH73emLp.js"
                  index 100ea6b..0b587f5 100644
                  --- "a/assets/6.\345\244\215\345\210\266.html-BXO5kx7f.js"
                  +++ "b/assets/6.\345\244\215\345\210\266.html-CH73emLp.js"
                  @@ -1,4 +1,4 @@
                  -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as n,o as l}from"./app-IPkfDkxj.js";const i={};function t(d,e){return l(),s("div",null,e[0]||(e[0]=[n(`

                  6.复制

                  简介

                  就是主从复制,master以写为主,slave以读为主,当master数据变化的时候,自动将新的数据异步同步到其他的slave数据库

                  作用

                  • 读写分离
                  • 容灾恢复
                  • 数据备份
                  • 水平扩容支撑高并发

                  使用

                  配从不配主

                  权限

                  master如果配置了requirepass参数,需要密码登录 ,那么slave就要配置masterauth来设置校验密码,否则的话master会拒绝slave的访问请求

                  masterauth password
                  +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as n,o as l}from"./app-DGSXj59V.js";const i={};function t(d,e){return l(),s("div",null,e[0]||(e[0]=[n(`

                  6.复制

                  简介

                  就是主从复制,master以写为主,slave以读为主,当master数据变化的时候,自动将新的数据异步同步到其他的slave数据库

                  作用

                  • 读写分离
                  • 容灾恢复
                  • 数据备份
                  • 水平扩容支撑高并发

                  使用

                  配从不配主

                  权限

                  master如果配置了requirepass参数,需要密码登录 ,那么slave就要配置masterauth来设置校验密码,否则的话master会拒绝slave的访问请求

                  masterauth password
                   

                  操作命令

                  • INFO 查看复制详情

                    INFO 
                     
                  • REPLICAOF

                    since 5.0.0

                    一般写入进Redis.conf配置文件内,重启后依然生效

                    REPLICAOF host port
                     

                    特殊

                    数据库停止与其他数据库的同步

                    REPLICAOF NO ONE
                    diff --git "a/assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\212\357\274\211.html-bMezDIIg.js" "b/assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\212\357\274\211.html-BtxCAsyy.js"
                    similarity index 99%
                    rename from "assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\212\357\274\211.html-bMezDIIg.js"
                    rename to "assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\212\357\274\211.html-BtxCAsyy.js"
                    index 0b67d0b..02422d2 100644
                    --- "a/assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\212\357\274\211.html-bMezDIIg.js"
                    +++ "b/assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\212\357\274\211.html-BtxCAsyy.js"
                    @@ -1,4 +1,4 @@
                    -import{_ as d}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,b as r,o as a}from"./app-IPkfDkxj.js";const n={};function i(o,t){return a(),e("div",null,t[0]||(t[0]=[r(`

                    6.类文件结构(上)

                    Class类文件的结构

                    Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:“无符号数”和“表”。

                    • 无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。
                    • 表是由多个无符号数或者其他表作为数据项构成的复合数据类型,为了便于区分,所有表的命名都习惯性地以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上也可以视作是一张表
                    类 型名 称数 量
                    u4magic1
                    u2minor_version1
                    u2major_version1
                    u2constant_pool_count1
                    cp_infoconstant_poolconstant_pool_count-1
                    u2access_flags1
                    u2this_class1
                    u2super_class1
                    u2interfaces_count1
                    u2interfacesinterfaces_count
                    u2fields_count1
                    field_infofieldsfields_count
                    u2methods_count1
                    method_infomethodsmethods_count
                    u2attributes_count1
                    attribute_infoattributesattributes_count

                    无论是顺序还是数量,甚至于数据存储的字节序(Byte Ordering,Class文件中字节序为Big-Endian)这样的细节,都是被严格限定的,哪个字节代表什么含义,长度是多少,先后顺序如何,全部都不允许改变。

                    魔数与Class文件的版本

                    每个Class文件的头4个字节被称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。

                    紧接着魔数的4个字节存储的是Class文件的版本号:第5和第6个字节是次版本号(Minor Version),第7和第8个字节是主版本号(Major Version)。Java的版本号是从45开始的,JDK 1.1之后的每个JDK大版本发布主版本号向上加1。(JDK 1.0~1.1使用了45.0~45.3的版本号),高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件,因为《Java虚拟机规范》在Class文件校验部分明确要求了即使文件格式并未发生任何变化,虚拟机也必须拒绝执行超过其版本号的Class文件。

                    常量池

                    紧接着主、次版本号之后的是常量池入口

                    由于常量池中常量的数量是不固定的,所以在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值(constant_pool_count)。与Java中语言习惯不同,这个容量计数是从1而不是0开始

                    常量池中主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References)。

                    字面量比较接近于Java语言层面的常量概念,如文本字符串、被声明为final的常量值等。

                    而符号引用则属于编译原理方面的概念,主要包括下面几类常量:

                    • 被模块导出或者开放的包(Package)
                    • 类和接口的全限定名(Fully Qualified Name)
                    • 字段的名称和描述符(Descriptor)
                    • 方法的名称和描述符
                    • 方法句柄和方法类型(Method Handle、Method Type、Invoke Dynamic)
                    • 动态调用点和动态常量(Dynamically-Computed Call Site、Dynamically-Computed Constant)

                    截至JDK13,常量表中分别有17种不同类型的常量。这17类表都有一个共同的特点,表结构起始的第一位是个u1类型的标志位,代表着当前常量属于哪种常量类型。

                    类型标志描述
                    CONSTANT_Utf8_info1UTF-8编码的字符串
                    CONSTANT_Integer_info3整型字面量
                    CONSTANT_Float_info4浮点型字面量
                    CONSTANT_Long_info5长整型字面量
                    CONSTANT_Double_info6双精度浮点型字面量
                    CONSTANT_Class_info7类或接口的符号引用
                    CONSTANT_String_info8字符串类型字面量
                    CONSTANT_Fieldref_info9字段的符号引用
                    CONSTANT_Methodref_info10类中方法的符号引用
                    CONSTANT_InterfaceMethodref_info11接口中方法的符号引用
                    CONSTANT_NameAndType_info12字段或方法的部分符号引用
                    CONSTANT_MethodHandle_info15表示方法句柄
                    CONSTANT_MethodType_info16表示方法类型
                    CONSTANT_Dynamic_info17表示一个动态计算常量
                    CONSTANT_InvokeDynamic_info18表示一个动态方法调用点
                    CONSTANT_Module_info19表示一个模块
                    CONSTANT_Package_info20表示一个模块中开放或者导出的包
                    常 量项 目类 型描 述
                    CONSTANT_Utf8_infotagu1值为1
                    lengthu2UTF-8编码的字符串占用了字节数
                    bytesu1长度为length的UTF-8编码的字符串
                    CONSTANT_Integer_infotagu1值为3
                    bytesu4按照高位在前存储的int值
                    CONSTANT_Float_infotagu1值为4
                    bytesu4按照高位在前存储的float值
                    CONSTANT_Long_infotagu1值为5
                    bytesu8按照高位在前存储的long值
                    CONSTANT_Double_infotagu1值为6
                    bytesu8按照高位在前存储的double值
                    CONSTANT_Class_infotagu1值为7
                    bytesu2指向全限定名常量项的索引
                    CONSTANT_String_infotagu1值为8
                    indexu2指向字符串字面量的索引
                    CONSTANT_Fieldref_infotagu1值为9
                    indexu2指向声明字段的类或者接口描述符CONSTANT_Class_info的索引项
                    indexu2指向字段描述符CONSTANT_NameAndType的索引项
                    CONSTANT_Methodref_infotagu1值10
                    indexu2指向声明方法的类描述符CONSTANT_Class_info的索引项
                    indexu2指向名称及类型描述符CONSTANT_NameAndType的索引项
                    CONSTANT_InterfaceMethodref_infotagu1值11
                    indexu2指向声明方法的接口描述符CONSTANT_Class_info的索引项
                    indexu2指向名称及类型描述符CONSTANT_NameAndType的索引项
                    CONSTANT_NameAndType_infotagu1值为12
                    indexu2指向该字段或方法名称常量项的索引
                    indexu2指向该字段或方法描述符常量项的索引
                    CONSTANT_MethodHandle_infotagu1值为15
                    reference_kindu1值必须在1至9之间(包括1和9).它决定了方法句柄的类型。方法句柄类型的值表示方法句柄的字节码行为
                    reference_indexu2值必须是对常量池的有效索引
                    CONSTANT_MethodType_infotagu1值为16
                    descriptor_indexu2值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANTUtf8_info结构,表示方法的描述符
                    CONSTANT_Dynamic_infotagu1值为17
                    bootstrap_method_attr_indexu2值必须是对当前Class文件中引导方法表的bootstrap_methods[]数组的有效索引
                    name_and_type_indexu2值必须是对当前常量池的有效索引,常量池在该索引处的项必须是CONSTANTNameAndType_info结构,表示方法名和方法描述符
                    CONSTANT_InvokeDynamic_infotagu1值为18
                    bootstrap_method_attr_indexu1值必须是对当前Class文件中引导方法表的bootstrap_methods[]数组的有效索引
                    name_and_type_indexu2值必须是对当前常量池的有效索引,常量池在该索引处的项必须是CONSTANT_NameAndType_info结构,表示方法名和方法描述符
                    CONSTANT_Module_infotagu1值为19
                    name_indexu2值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示模块名字
                    CONSTANT_Package_infotagu1值为20
                    name_indexu2值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示包名称

                    访问标志

                    在常量池结束之后,紧接着的2个字节代表访问标志(access_flags),这个标志用于识别一些类或 者接口层次的访问信息

                    标志名称标志值含义
                    ACC_PUBLIC0x0001是否为public类型
                    ACC_FINAL0x0010是否被声明为final,只有类可设置
                    ACC_SUPER0x0020是否允许使用invokespecial字节码指令的新语义,invokespecial指令的语义在JDK 1.0.2发生过改变,为了区别这条指令使用哪种语义,JDK1.0.2之后编译出来的类的这个标志都必须为真
                    ACC_INTERFACE0x0200标识这是一个接口
                    ACC_ABSTRACT0x0400是否为abstract类型,对于接口或者抽象类来说,此标志值为真,其他类型值为假
                    ACC_SYNTHETIC0x1000标识这个类并非由用户代码产生的
                    ACC_ANNOTATION0x2000标识这是一个注解
                    ACC_ENUM0x4000标识这是一个枚举
                    ACC_MODULE0x8000标识这是一个模块

                    access_flags中一共有16个标志位可以使用,当前只定义了其中9个[1],没有使用到的标志位要求一律为零。

                    类索引、父类索引与接口索引集合

                    类索引(this_class)和父类索引(super_class)都是一个u2类型的数据,而接口索引集合(interfaces)是一组u2类型的数据的集合,Class文件中由这三项数据来确定该类型的继承关系。

                    类索引、父类索引和接口索引集合都按顺序排列在访问标志之后,类索引和父类索引用两个u2类型的索引值表示,它们各自指向一个类型为CONSTANT_Class_info的类描述符常量,通过CONSTANT_Class_info类型的常量中的索引值可以找到定义CONSTANT_Utf8_info类型的常量中的全限定名字符串。

                    类索引查找全限定名的过程
                    类索引查找全限定名的过程

                    对于接口索引集合,入口的第一项u2类型的数据为接口计数器(interfaces_count),表示索引表的容量。如果该类没有实现任何接口,则该计数器值为0,后面接口的索引表不再占用任何字节。

                    字段表集合

                    字段表(field_info)用于描述接口或者类中声明的变量。Java语言中的“字段”(Field)包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。

                    字段表结构:

                    类 型名 称数 量
                    u2access_flags1
                    u2name_index1
                    u2descriptor_index1
                    u2attributes_count1
                    attribute_infoattributesattributes_count

                    字段修饰符放在access_flags项目中,它与类中的access_flags项目是非常类似的,都是一个u2的数据类型,其中可以设置的标志位和含义

                    字段访问标志:

                    标志名称标志值含 义
                    ACC_PUBLIC0x0001字段是否public
                    ACC_PRIVATE0x0002字段是否private
                    ACC_PROTECTED0x0004字段是否protected
                    ACC_STATIC0x0008字段是否static
                    ACC_FINAL0x0010字段是否final
                    ACC_VOLATILE0x0040字段是否volatile
                    ACC_TRANSIENT0x0080字段是否transient
                    ACC_SYNTHETIC0x1000字段是否由编译器自动产生
                    ACC_ENUM0x4000字段是否enum

                    跟随access_flags标志的是两项索引值:name_index和descriptor_index。它们都是对常量池项的引用,分别代表着字段的简单名称以及字段和方法的描述符。

                    全限定名:把类全名中的“.”替换成了“/”,为了使连续的多个全限定名之间不产生混淆,在使用时最后一般会加入一个“;”号表示全限定名结束

                    简单名称:没有类型和参数修饰的方法或者字段名称

                    描述符: 描述符的作用是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。

                    • 基本数据类型(byte、char、double、float、int、long、short、boolean)以及代表无返回值的void类型都用一个大写字符来表示

                      标识字符含义
                      B基本类型byte
                      C基本类型char
                      D基本类型double
                      F基本类型float
                      I基本类型int
                      J基本类型long
                      S基本类型short
                      Z基本类型boolean
                      V特殊类型void
                      L对象类型,如Ljava/lang/Objet;

                      void类型在《Java虚拟机规范》之中单独列出为“VoidDescriptor”

                    • 数组类型,每一维度将使用一个前置的“[”字符来描述

                      eg:

                      java.lang.String[][] -> [[Ljava/lang/String;
                      +import{_ as d}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,b as r,o as a}from"./app-DGSXj59V.js";const n={};function i(o,t){return a(),e("div",null,t[0]||(t[0]=[r(`

                      6.类文件结构(上)

                      Class类文件的结构

                      Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:“无符号数”和“表”。

                      • 无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。
                      • 表是由多个无符号数或者其他表作为数据项构成的复合数据类型,为了便于区分,所有表的命名都习惯性地以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上也可以视作是一张表
                      类 型名 称数 量
                      u4magic1
                      u2minor_version1
                      u2major_version1
                      u2constant_pool_count1
                      cp_infoconstant_poolconstant_pool_count-1
                      u2access_flags1
                      u2this_class1
                      u2super_class1
                      u2interfaces_count1
                      u2interfacesinterfaces_count
                      u2fields_count1
                      field_infofieldsfields_count
                      u2methods_count1
                      method_infomethodsmethods_count
                      u2attributes_count1
                      attribute_infoattributesattributes_count

                      无论是顺序还是数量,甚至于数据存储的字节序(Byte Ordering,Class文件中字节序为Big-Endian)这样的细节,都是被严格限定的,哪个字节代表什么含义,长度是多少,先后顺序如何,全部都不允许改变。

                      魔数与Class文件的版本

                      每个Class文件的头4个字节被称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。

                      紧接着魔数的4个字节存储的是Class文件的版本号:第5和第6个字节是次版本号(Minor Version),第7和第8个字节是主版本号(Major Version)。Java的版本号是从45开始的,JDK 1.1之后的每个JDK大版本发布主版本号向上加1。(JDK 1.0~1.1使用了45.0~45.3的版本号),高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件,因为《Java虚拟机规范》在Class文件校验部分明确要求了即使文件格式并未发生任何变化,虚拟机也必须拒绝执行超过其版本号的Class文件。

                      常量池

                      紧接着主、次版本号之后的是常量池入口

                      由于常量池中常量的数量是不固定的,所以在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值(constant_pool_count)。与Java中语言习惯不同,这个容量计数是从1而不是0开始

                      常量池中主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References)。

                      字面量比较接近于Java语言层面的常量概念,如文本字符串、被声明为final的常量值等。

                      而符号引用则属于编译原理方面的概念,主要包括下面几类常量:

                      • 被模块导出或者开放的包(Package)
                      • 类和接口的全限定名(Fully Qualified Name)
                      • 字段的名称和描述符(Descriptor)
                      • 方法的名称和描述符
                      • 方法句柄和方法类型(Method Handle、Method Type、Invoke Dynamic)
                      • 动态调用点和动态常量(Dynamically-Computed Call Site、Dynamically-Computed Constant)

                      截至JDK13,常量表中分别有17种不同类型的常量。这17类表都有一个共同的特点,表结构起始的第一位是个u1类型的标志位,代表着当前常量属于哪种常量类型。

                      类型标志描述
                      CONSTANT_Utf8_info1UTF-8编码的字符串
                      CONSTANT_Integer_info3整型字面量
                      CONSTANT_Float_info4浮点型字面量
                      CONSTANT_Long_info5长整型字面量
                      CONSTANT_Double_info6双精度浮点型字面量
                      CONSTANT_Class_info7类或接口的符号引用
                      CONSTANT_String_info8字符串类型字面量
                      CONSTANT_Fieldref_info9字段的符号引用
                      CONSTANT_Methodref_info10类中方法的符号引用
                      CONSTANT_InterfaceMethodref_info11接口中方法的符号引用
                      CONSTANT_NameAndType_info12字段或方法的部分符号引用
                      CONSTANT_MethodHandle_info15表示方法句柄
                      CONSTANT_MethodType_info16表示方法类型
                      CONSTANT_Dynamic_info17表示一个动态计算常量
                      CONSTANT_InvokeDynamic_info18表示一个动态方法调用点
                      CONSTANT_Module_info19表示一个模块
                      CONSTANT_Package_info20表示一个模块中开放或者导出的包
                      常 量项 目类 型描 述
                      CONSTANT_Utf8_infotagu1值为1
                      lengthu2UTF-8编码的字符串占用了字节数
                      bytesu1长度为length的UTF-8编码的字符串
                      CONSTANT_Integer_infotagu1值为3
                      bytesu4按照高位在前存储的int值
                      CONSTANT_Float_infotagu1值为4
                      bytesu4按照高位在前存储的float值
                      CONSTANT_Long_infotagu1值为5
                      bytesu8按照高位在前存储的long值
                      CONSTANT_Double_infotagu1值为6
                      bytesu8按照高位在前存储的double值
                      CONSTANT_Class_infotagu1值为7
                      bytesu2指向全限定名常量项的索引
                      CONSTANT_String_infotagu1值为8
                      indexu2指向字符串字面量的索引
                      CONSTANT_Fieldref_infotagu1值为9
                      indexu2指向声明字段的类或者接口描述符CONSTANT_Class_info的索引项
                      indexu2指向字段描述符CONSTANT_NameAndType的索引项
                      CONSTANT_Methodref_infotagu1值10
                      indexu2指向声明方法的类描述符CONSTANT_Class_info的索引项
                      indexu2指向名称及类型描述符CONSTANT_NameAndType的索引项
                      CONSTANT_InterfaceMethodref_infotagu1值11
                      indexu2指向声明方法的接口描述符CONSTANT_Class_info的索引项
                      indexu2指向名称及类型描述符CONSTANT_NameAndType的索引项
                      CONSTANT_NameAndType_infotagu1值为12
                      indexu2指向该字段或方法名称常量项的索引
                      indexu2指向该字段或方法描述符常量项的索引
                      CONSTANT_MethodHandle_infotagu1值为15
                      reference_kindu1值必须在1至9之间(包括1和9).它决定了方法句柄的类型。方法句柄类型的值表示方法句柄的字节码行为
                      reference_indexu2值必须是对常量池的有效索引
                      CONSTANT_MethodType_infotagu1值为16
                      descriptor_indexu2值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANTUtf8_info结构,表示方法的描述符
                      CONSTANT_Dynamic_infotagu1值为17
                      bootstrap_method_attr_indexu2值必须是对当前Class文件中引导方法表的bootstrap_methods[]数组的有效索引
                      name_and_type_indexu2值必须是对当前常量池的有效索引,常量池在该索引处的项必须是CONSTANTNameAndType_info结构,表示方法名和方法描述符
                      CONSTANT_InvokeDynamic_infotagu1值为18
                      bootstrap_method_attr_indexu1值必须是对当前Class文件中引导方法表的bootstrap_methods[]数组的有效索引
                      name_and_type_indexu2值必须是对当前常量池的有效索引,常量池在该索引处的项必须是CONSTANT_NameAndType_info结构,表示方法名和方法描述符
                      CONSTANT_Module_infotagu1值为19
                      name_indexu2值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示模块名字
                      CONSTANT_Package_infotagu1值为20
                      name_indexu2值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示包名称

                      访问标志

                      在常量池结束之后,紧接着的2个字节代表访问标志(access_flags),这个标志用于识别一些类或 者接口层次的访问信息

                      标志名称标志值含义
                      ACC_PUBLIC0x0001是否为public类型
                      ACC_FINAL0x0010是否被声明为final,只有类可设置
                      ACC_SUPER0x0020是否允许使用invokespecial字节码指令的新语义,invokespecial指令的语义在JDK 1.0.2发生过改变,为了区别这条指令使用哪种语义,JDK1.0.2之后编译出来的类的这个标志都必须为真
                      ACC_INTERFACE0x0200标识这是一个接口
                      ACC_ABSTRACT0x0400是否为abstract类型,对于接口或者抽象类来说,此标志值为真,其他类型值为假
                      ACC_SYNTHETIC0x1000标识这个类并非由用户代码产生的
                      ACC_ANNOTATION0x2000标识这是一个注解
                      ACC_ENUM0x4000标识这是一个枚举
                      ACC_MODULE0x8000标识这是一个模块

                      access_flags中一共有16个标志位可以使用,当前只定义了其中9个[1],没有使用到的标志位要求一律为零。

                      类索引、父类索引与接口索引集合

                      类索引(this_class)和父类索引(super_class)都是一个u2类型的数据,而接口索引集合(interfaces)是一组u2类型的数据的集合,Class文件中由这三项数据来确定该类型的继承关系。

                      类索引、父类索引和接口索引集合都按顺序排列在访问标志之后,类索引和父类索引用两个u2类型的索引值表示,它们各自指向一个类型为CONSTANT_Class_info的类描述符常量,通过CONSTANT_Class_info类型的常量中的索引值可以找到定义CONSTANT_Utf8_info类型的常量中的全限定名字符串。

                      类索引查找全限定名的过程
                      类索引查找全限定名的过程

                      对于接口索引集合,入口的第一项u2类型的数据为接口计数器(interfaces_count),表示索引表的容量。如果该类没有实现任何接口,则该计数器值为0,后面接口的索引表不再占用任何字节。

                      字段表集合

                      字段表(field_info)用于描述接口或者类中声明的变量。Java语言中的“字段”(Field)包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。

                      字段表结构:

                      类 型名 称数 量
                      u2access_flags1
                      u2name_index1
                      u2descriptor_index1
                      u2attributes_count1
                      attribute_infoattributesattributes_count

                      字段修饰符放在access_flags项目中,它与类中的access_flags项目是非常类似的,都是一个u2的数据类型,其中可以设置的标志位和含义

                      字段访问标志:

                      标志名称标志值含 义
                      ACC_PUBLIC0x0001字段是否public
                      ACC_PRIVATE0x0002字段是否private
                      ACC_PROTECTED0x0004字段是否protected
                      ACC_STATIC0x0008字段是否static
                      ACC_FINAL0x0010字段是否final
                      ACC_VOLATILE0x0040字段是否volatile
                      ACC_TRANSIENT0x0080字段是否transient
                      ACC_SYNTHETIC0x1000字段是否由编译器自动产生
                      ACC_ENUM0x4000字段是否enum

                      跟随access_flags标志的是两项索引值:name_index和descriptor_index。它们都是对常量池项的引用,分别代表着字段的简单名称以及字段和方法的描述符。

                      全限定名:把类全名中的“.”替换成了“/”,为了使连续的多个全限定名之间不产生混淆,在使用时最后一般会加入一个“;”号表示全限定名结束

                      简单名称:没有类型和参数修饰的方法或者字段名称

                      描述符: 描述符的作用是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。

                      • 基本数据类型(byte、char、double、float、int、long、short、boolean)以及代表无返回值的void类型都用一个大写字符来表示

                        标识字符含义
                        B基本类型byte
                        C基本类型char
                        D基本类型double
                        F基本类型float
                        I基本类型int
                        J基本类型long
                        S基本类型short
                        Z基本类型boolean
                        V特殊类型void
                        L对象类型,如Ljava/lang/Objet;

                        void类型在《Java虚拟机规范》之中单独列出为“VoidDescriptor”

                      • 数组类型,每一维度将使用一个前置的“[”字符来描述

                        eg:

                        java.lang.String[][] -> [[Ljava/lang/String;
                         
                         int[] -> [I
                         
                      • 描述符来描述方法时,按照先参数列表、后返回值的顺序描述,参数列表按照参数的严格顺序放在一组小括号“()”之内

                        eg:

                        void inc() -> ()V
                        diff --git "a/assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\213\357\274\211.html-BR-9LCfV.js" "b/assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\213\357\274\211.html-CHYdIYsk.js"
                        similarity index 99%
                        rename from "assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\213\357\274\211.html-BR-9LCfV.js"
                        rename to "assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\213\357\274\211.html-CHYdIYsk.js"
                        index 1b8de4d..e6bc6c3 100644
                        --- "a/assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\213\357\274\211.html-BR-9LCfV.js"
                        +++ "b/assets/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\213\357\274\211.html-CHYdIYsk.js"
                        @@ -1,4 +1,4 @@
                        -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,b as o,o as c}from"./app-IPkfDkxj.js";const a={};function n(i,d){return c(),e("div",null,d[0]||(d[0]=[o(`

                        6.类文件结构(下)

                        字节码指令简介

                        Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需的参数(称为操作数,Operand)构成。

                        字节码与数据类型

                        部分特殊的字符来表明专门为哪种数据类型服务:i代表对int类型的数据操作,l代表long,s代表short,b代表byte,c代表char,f代表float,d代表double,a代表reference。

                        Java虚拟机指令集所支持的数据类型:

                        opcodebyteshortintlongfloatdoublecharreference
                        Tipushbipushsipush
                        Tconsticonstlconstfconstdconstaconst
                        Tloadiloadlloadfloaddloadaload
                        Tstoreistorelstorefstoredstoreastore
                        Tinciinc
                        Taloadbaloadsaloadialoadlaloadfaloaddaloadcaloadaaload
                        Tastorebastoresastoreiastorelastorefastoredastorecastoreaastore
                        Taddiaddladdfadddadd
                        Tsubisublsubfsubdsub
                        Tmulimullmulfmuldmul
                        Tdividivldivfdivddiv
                        Tremiremlremfremdrem
                        Tnegineglnegfnegdneg
                        Tshlishllshl
                        Tshrishrlshr
                        Tushriushrlushr
                        Tandiandland
                        Toriorlor
                        Txorixorlxor
                        i2Ti2bi2si21i2fi2d
                        l2Tl2il2fl2d
                        f2Tf2if21f2d
                        d2Td2id2ld2f
                        Tcmplcmp
                        Tcmplfcmpldcmpl
                        Tcmpgfcmpgdcmpg
                        if_TcmpOPif_icmpOPif_acmpOP
                        Treturnireturnlreturnfreturndreturnareturn

                        编译器会在编译期或运行期将byte和short类型的数据带符号扩展(Sign-Extend)为相应的int类型数据,将boolean和char类型数据零位扩展(Zero-Extend)为相应的int类型数据。

                        加载和存储指令

                        加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输

                        • 将一个局部变量加载到操作栈:TloadTload_<n>
                        • 将一个数值从操作数栈存储到局部变量表:TstoreTstore_<n>
                        • 将一个常量加载到操作数栈:Tipushldcldc_wldc2_waconst_nulliconst_m1iconst_<i>lconst_<l>fconst_<f>dconst_<d>
                        • 扩充局部变量表的访问索引的指令:wide

                        <>中为操作数

                        存储数据的操作数栈和局部变量表主要由加载和存储指令进行操作,除此之外,还有少量指令,如访问对象的字段或数组元素的指令也会向操作数栈传输数据。

                        运算指令

                        算术指令用于对两个操作数栈上的值进行某种特定运算,并把结果重新存入到操作栈顶。

                        无论是哪种算术指令,均是使用Java虚拟机的算术类型来进行计算的。

                        • 加法指令:Tadd
                        • 减法指令:Tsub
                        • 乘法指令:Tmul
                        • 除法指令:Tdiv
                        • 求余指令:Trem
                        • 取反指令:Tneg
                        • 位移指令:TshlTshrTushr
                        • 按位或指令:Tor
                        • 按位与指令:Tand
                        • 按位异或指令:Txor
                        • 局部变量自增指令:Tinc
                        • 比较指令:TcmpgTcmplTcmp

                        只有除法指令(Tdiv)以及求余指令(Trem)中当出现除数为零时会导致虚拟机抛出ArithmeticException异常,其余任何整型数运算场景都不应该抛出运行时异常。

                        IEEE 754规范

                        类型转换指令

                        Java虚拟机直接支持(即转换时无须显式的转换指令)以下数值类型的宽化类型转换(Widening Numeric Conversion,即小范围类型向大范围类型的安全转换)与之相对的,处理窄化类型转换(Narrowing Numeric Conversion)时,就必须显式地使用转换指令来完成,这些转换指令包括i2bi2ci2sl2if2if2ld2id2ld2f。窄化类型转换可能会导致转换结果产生不同的正负号、不同的数量级的情况,转换过程很可能会导致数值的精度丢失

                        Java虚拟机将一个浮点值窄化转换为整数类型T(T限于int或long类型之一)的时候,必须遵循以下转换规则:

                        • 如果浮点值是NaN,那转换结果就是int或long类型的0。
                        • 如果浮点值不是无穷大的话,浮点值使用IEEE 754的向零舍入模式取整,获得整数值v。如果v在目标类型T(int或long)的表示范围之类,那转换结果就是v;否则,将根据v的符号,转换为T所能表示的最大或者最小正数。

                        从double类型到float类型做窄化转换的过程与IEEE 754中定义的一致,通过IEEE 754向最接近数舍入模式舍入得到一个可以使用float类型表示的数字。如果转换结果的绝对值太小、无法使用float来表示的话,将返回float类型的正负零;如果转换结果的绝对值太大、无法使用float来表示的话,将返回float类型的正负无穷大。对于double类型的NaN值将按规定转换为float类型的NaN值。

                        数值类型的窄化转换指令永远不可能导致虚拟机抛出运行时异常。

                        对象创建与访问指令

                        • 创建类实例的指令:new
                        • 创建数组的指令:newarrayanewarraymultianewarray
                        • 访问类字段(static字段,或者称为类变量)和实例字段(非static字段,或者称为实例变量)的指令:getfieldputfieldgetstaticputstatic
                        • 把一个数组元素加载到操作数栈的指令:baloadcaloadsaloadialoadlaloadfaloaddaloadaaload
                        • 将一个操作数栈的值储存到数组元素中的指令:bastorecastoresastoreiastorefastoredastoreaastore
                        • 取数组长度的指令:arraylength
                        • 检查类实例类型的指令:instanceofcheckcast

                        操作数栈管理指令

                        直接操作操作数栈的指令

                        • 将操作数栈的栈顶一个或两个元素出栈:poppop2
                        • 复制栈顶一个或两个数值并将复制值或双份的复制值重新压入栈顶:dupdup2dup_x1dup2_x1dup_x2dup2_x2
                        • 将栈最顶端的两个数值互换:swap

                        控制转移指令

                        控制转移指令可以让Java虚拟机有条件或无条件地从指定位置指令(而不是控制转移指令)的下一条指令继续执行程序,从概念模型上理解,可以认为控制指令就是在有条件或无条件地修改PC寄存器的值。

                        • 条件分支:ifeqifltifleifneifgtifgeifnullifnonnullif_icmpeqif_icmpneif_icmpltif_icmpgtif_icmpleif_icmpgeif_acmpeqif_acmpne
                        • 复合条件分支:tableswitchlookupswitch
                        • 无条件分支:gotogoto_wjsrjsr_wret

                        在Java虚拟机中有专门的指令集用来处理int和reference类型的条件分支比较操作,为了可以无须明显标识一个数据的值是否null,也有专门的指令用来检测null值。

                        与前面算术运算的规则一致,对于boolean类型、byte类型、char类型和short类型的条件分支比较操作,都使用int类型的比较指令来完成,而对于long类型、float类型和double类型的条件分支比较操作,则会先执行相应类型的比较运算指令(dcmpgdcmplfcmpgfcmpllcmp),运算指令会返回一个整型值到操作数栈中,随后再执行int类型的条件分支比较操作来完成整个分支跳转

                        方法调用和返回指令

                        • invokevirtual指令:用于调用对象的实例方法,根据对象的实际类型进行分派(虚方法分派),这也是Java语言中最常见的方法分派方式。
                        • invokeinterface指令:用于调用接口方法,它会在运行时搜索一个实现了这个接口方法的对象,找出适合的方法进行调用。
                        • invokespecial指令:用于调用一些需要特殊处理的实例方法,包括实例初始化方法、私有方法和父类方法。
                        • invokestatic指令:用于调用类静态方法(static方法)。
                        • invokedynamic指令:用于在运行时动态解析出调用点限定符所引用的方法。并执行该方法。前面四条调用指令的分派逻辑都固化在Java虚拟机内部,用户无法改变,而invokedynamic指令的分派逻辑是由用户所设定的引导方法决定的。

                        方法调用指令与数据类型无关,而方法返回指令是根据返回值的类型区分的,包括ireturn(当返回值是boolean、byte、char、short和int类型时使用)、lreturnfreturndreturnareturn,另外还有一条return指令供声明为void的方法、实例初始化方法、类和接口的类初始化方法使用。

                        异常处理指令

                        在Java程序中显式抛出异常的操作(throw语句)都由athrow指令来实现。《Java虚拟机规范》还规定了许多运行时异常会在其他Java虚拟机指令检测到异常状况时自动抛出。

                        而在Java虚拟机中,处理异常(catch语句)不是由字节码指令来实现的,而是采用异常表来完成。

                        同步指令

                        Java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步,这两种同步结构都是使用管程(Monitor,更常见的是直接将它称为“锁”)来实现的。

                        方法级的同步是隐式的,无须通过字节码指令来控制,它实现在方法调用和返回操作之中。虚拟机可以从方法常量池中的方法表结构中的ACC_SYNCHRONIZED访问标志得知一个方法是否被声明为同步方法。当方法调用时,调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置,如果设置了,执行线程就要求先成功持有管程,然后才能执行方法,最后当方法完成(无论是正常完成还是非正常完成)时释放管程。在方法执行期间,执行线程持有了管程,其他任何线程都无法再获取到同一个管程。如果一个同步方法执行期间抛出了异常,并且在方法内部无法处理此异常,那这个同步方法所持有的管程将在异常抛到同步方法边界之外时自动释放

                        同步一段指令集序列通常是由Java语言中的synchronized语句块来表示的,Java虚拟机的指令集中有monitorentermonitorexit两条指令来支持synchronized关键字的语义,正确实现synchronized关键字需要Javac编译器与Java虚拟机两者共同协作支持

                        eg:

                        void onlyMe(Foo f) {
                        +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,b as o,o as c}from"./app-DGSXj59V.js";const a={};function n(i,d){return c(),e("div",null,d[0]||(d[0]=[o(`

                        6.类文件结构(下)

                        字节码指令简介

                        Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需的参数(称为操作数,Operand)构成。

                        字节码与数据类型

                        部分特殊的字符来表明专门为哪种数据类型服务:i代表对int类型的数据操作,l代表long,s代表short,b代表byte,c代表char,f代表float,d代表double,a代表reference。

                        Java虚拟机指令集所支持的数据类型:

                        opcodebyteshortintlongfloatdoublecharreference
                        Tipushbipushsipush
                        Tconsticonstlconstfconstdconstaconst
                        Tloadiloadlloadfloaddloadaload
                        Tstoreistorelstorefstoredstoreastore
                        Tinciinc
                        Taloadbaloadsaloadialoadlaloadfaloaddaloadcaloadaaload
                        Tastorebastoresastoreiastorelastorefastoredastorecastoreaastore
                        Taddiaddladdfadddadd
                        Tsubisublsubfsubdsub
                        Tmulimullmulfmuldmul
                        Tdividivldivfdivddiv
                        Tremiremlremfremdrem
                        Tnegineglnegfnegdneg
                        Tshlishllshl
                        Tshrishrlshr
                        Tushriushrlushr
                        Tandiandland
                        Toriorlor
                        Txorixorlxor
                        i2Ti2bi2si21i2fi2d
                        l2Tl2il2fl2d
                        f2Tf2if21f2d
                        d2Td2id2ld2f
                        Tcmplcmp
                        Tcmplfcmpldcmpl
                        Tcmpgfcmpgdcmpg
                        if_TcmpOPif_icmpOPif_acmpOP
                        Treturnireturnlreturnfreturndreturnareturn

                        编译器会在编译期或运行期将byte和short类型的数据带符号扩展(Sign-Extend)为相应的int类型数据,将boolean和char类型数据零位扩展(Zero-Extend)为相应的int类型数据。

                        加载和存储指令

                        加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输

                        • 将一个局部变量加载到操作栈:TloadTload_<n>
                        • 将一个数值从操作数栈存储到局部变量表:TstoreTstore_<n>
                        • 将一个常量加载到操作数栈:Tipushldcldc_wldc2_waconst_nulliconst_m1iconst_<i>lconst_<l>fconst_<f>dconst_<d>
                        • 扩充局部变量表的访问索引的指令:wide

                        <>中为操作数

                        存储数据的操作数栈和局部变量表主要由加载和存储指令进行操作,除此之外,还有少量指令,如访问对象的字段或数组元素的指令也会向操作数栈传输数据。

                        运算指令

                        算术指令用于对两个操作数栈上的值进行某种特定运算,并把结果重新存入到操作栈顶。

                        无论是哪种算术指令,均是使用Java虚拟机的算术类型来进行计算的。

                        • 加法指令:Tadd
                        • 减法指令:Tsub
                        • 乘法指令:Tmul
                        • 除法指令:Tdiv
                        • 求余指令:Trem
                        • 取反指令:Tneg
                        • 位移指令:TshlTshrTushr
                        • 按位或指令:Tor
                        • 按位与指令:Tand
                        • 按位异或指令:Txor
                        • 局部变量自增指令:Tinc
                        • 比较指令:TcmpgTcmplTcmp

                        只有除法指令(Tdiv)以及求余指令(Trem)中当出现除数为零时会导致虚拟机抛出ArithmeticException异常,其余任何整型数运算场景都不应该抛出运行时异常。

                        IEEE 754规范

                        类型转换指令

                        Java虚拟机直接支持(即转换时无须显式的转换指令)以下数值类型的宽化类型转换(Widening Numeric Conversion,即小范围类型向大范围类型的安全转换)与之相对的,处理窄化类型转换(Narrowing Numeric Conversion)时,就必须显式地使用转换指令来完成,这些转换指令包括i2bi2ci2sl2if2if2ld2id2ld2f。窄化类型转换可能会导致转换结果产生不同的正负号、不同的数量级的情况,转换过程很可能会导致数值的精度丢失

                        Java虚拟机将一个浮点值窄化转换为整数类型T(T限于int或long类型之一)的时候,必须遵循以下转换规则:

                        • 如果浮点值是NaN,那转换结果就是int或long类型的0。
                        • 如果浮点值不是无穷大的话,浮点值使用IEEE 754的向零舍入模式取整,获得整数值v。如果v在目标类型T(int或long)的表示范围之类,那转换结果就是v;否则,将根据v的符号,转换为T所能表示的最大或者最小正数。

                        从double类型到float类型做窄化转换的过程与IEEE 754中定义的一致,通过IEEE 754向最接近数舍入模式舍入得到一个可以使用float类型表示的数字。如果转换结果的绝对值太小、无法使用float来表示的话,将返回float类型的正负零;如果转换结果的绝对值太大、无法使用float来表示的话,将返回float类型的正负无穷大。对于double类型的NaN值将按规定转换为float类型的NaN值。

                        数值类型的窄化转换指令永远不可能导致虚拟机抛出运行时异常。

                        对象创建与访问指令

                        • 创建类实例的指令:new
                        • 创建数组的指令:newarrayanewarraymultianewarray
                        • 访问类字段(static字段,或者称为类变量)和实例字段(非static字段,或者称为实例变量)的指令:getfieldputfieldgetstaticputstatic
                        • 把一个数组元素加载到操作数栈的指令:baloadcaloadsaloadialoadlaloadfaloaddaloadaaload
                        • 将一个操作数栈的值储存到数组元素中的指令:bastorecastoresastoreiastorefastoredastoreaastore
                        • 取数组长度的指令:arraylength
                        • 检查类实例类型的指令:instanceofcheckcast

                        操作数栈管理指令

                        直接操作操作数栈的指令

                        • 将操作数栈的栈顶一个或两个元素出栈:poppop2
                        • 复制栈顶一个或两个数值并将复制值或双份的复制值重新压入栈顶:dupdup2dup_x1dup2_x1dup_x2dup2_x2
                        • 将栈最顶端的两个数值互换:swap

                        控制转移指令

                        控制转移指令可以让Java虚拟机有条件或无条件地从指定位置指令(而不是控制转移指令)的下一条指令继续执行程序,从概念模型上理解,可以认为控制指令就是在有条件或无条件地修改PC寄存器的值。

                        • 条件分支:ifeqifltifleifneifgtifgeifnullifnonnullif_icmpeqif_icmpneif_icmpltif_icmpgtif_icmpleif_icmpgeif_acmpeqif_acmpne
                        • 复合条件分支:tableswitchlookupswitch
                        • 无条件分支:gotogoto_wjsrjsr_wret

                        在Java虚拟机中有专门的指令集用来处理int和reference类型的条件分支比较操作,为了可以无须明显标识一个数据的值是否null,也有专门的指令用来检测null值。

                        与前面算术运算的规则一致,对于boolean类型、byte类型、char类型和short类型的条件分支比较操作,都使用int类型的比较指令来完成,而对于long类型、float类型和double类型的条件分支比较操作,则会先执行相应类型的比较运算指令(dcmpgdcmplfcmpgfcmpllcmp),运算指令会返回一个整型值到操作数栈中,随后再执行int类型的条件分支比较操作来完成整个分支跳转

                        方法调用和返回指令

                        • invokevirtual指令:用于调用对象的实例方法,根据对象的实际类型进行分派(虚方法分派),这也是Java语言中最常见的方法分派方式。
                        • invokeinterface指令:用于调用接口方法,它会在运行时搜索一个实现了这个接口方法的对象,找出适合的方法进行调用。
                        • invokespecial指令:用于调用一些需要特殊处理的实例方法,包括实例初始化方法、私有方法和父类方法。
                        • invokestatic指令:用于调用类静态方法(static方法)。
                        • invokedynamic指令:用于在运行时动态解析出调用点限定符所引用的方法。并执行该方法。前面四条调用指令的分派逻辑都固化在Java虚拟机内部,用户无法改变,而invokedynamic指令的分派逻辑是由用户所设定的引导方法决定的。

                        方法调用指令与数据类型无关,而方法返回指令是根据返回值的类型区分的,包括ireturn(当返回值是boolean、byte、char、short和int类型时使用)、lreturnfreturndreturnareturn,另外还有一条return指令供声明为void的方法、实例初始化方法、类和接口的类初始化方法使用。

                        异常处理指令

                        在Java程序中显式抛出异常的操作(throw语句)都由athrow指令来实现。《Java虚拟机规范》还规定了许多运行时异常会在其他Java虚拟机指令检测到异常状况时自动抛出。

                        而在Java虚拟机中,处理异常(catch语句)不是由字节码指令来实现的,而是采用异常表来完成。

                        同步指令

                        Java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步,这两种同步结构都是使用管程(Monitor,更常见的是直接将它称为“锁”)来实现的。

                        方法级的同步是隐式的,无须通过字节码指令来控制,它实现在方法调用和返回操作之中。虚拟机可以从方法常量池中的方法表结构中的ACC_SYNCHRONIZED访问标志得知一个方法是否被声明为同步方法。当方法调用时,调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置,如果设置了,执行线程就要求先成功持有管程,然后才能执行方法,最后当方法完成(无论是正常完成还是非正常完成)时释放管程。在方法执行期间,执行线程持有了管程,其他任何线程都无法再获取到同一个管程。如果一个同步方法执行期间抛出了异常,并且在方法内部无法处理此异常,那这个同步方法所持有的管程将在异常抛到同步方法边界之外时自动释放

                        同步一段指令集序列通常是由Java语言中的synchronized语句块来表示的,Java虚拟机的指令集中有monitorentermonitorexit两条指令来支持synchronized关键字的语义,正确实现synchronized关键字需要Javac编译器与Java虚拟机两者共同协作支持

                        eg:

                        void onlyMe(Foo f) {
                             synchronized(f) {
                                 doSomething();
                             }
                        diff --git "a/assets/7.\345\223\250\345\205\265.html-BgjEihqV.js" "b/assets/7.\345\223\250\345\205\265.html-C92G7akQ.js"
                        similarity index 99%
                        rename from "assets/7.\345\223\250\345\205\265.html-BgjEihqV.js"
                        rename to "assets/7.\345\223\250\345\205\265.html-C92G7akQ.js"
                        index ee96f98..837b982 100644
                        --- "a/assets/7.\345\223\250\345\205\265.html-BgjEihqV.js"
                        +++ "b/assets/7.\345\223\250\345\205\265.html-C92G7akQ.js"
                        @@ -1,4 +1,4 @@
                        -import{_ as i}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as l,o as s}from"./app-IPkfDkxj.js";const a={};function t(d,e){return s(),n("div",null,e[0]||(e[0]=[l(`

                        7.哨兵

                        作用

                        • 主从监控:监控主从redis库运行是否正常
                        • 消息通知:哨兵可以将故障转移的结果发送给客户端
                        • 故障转移:如果master异常,则会进行主从切换,将其中一个slave作为新- master
                        • 配置中心:客户端通过连接哨兵来获得当前Redis服务的主节点地址

                        启动

                        建议至少三个,且为奇数个

                        redis-sentinel /path/to/sentinel.conf
                        +import{_ as i}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as l,o as s}from"./app-DGSXj59V.js";const a={};function t(d,e){return s(),n("div",null,e[0]||(e[0]=[l(`

                        7.哨兵

                        作用

                        • 主从监控:监控主从redis库运行是否正常
                        • 消息通知:哨兵可以将故障转移的结果发送给客户端
                        • 故障转移:如果master异常,则会进行主从切换,将其中一个slave作为新- master
                        • 配置中心:客户端通过连接哨兵来获得当前Redis服务的主节点地址

                        启动

                        建议至少三个,且为奇数个

                        redis-sentinel /path/to/sentinel.conf
                         

                        redis-server /path/to/sentinel.conf --sentinel
                         

                        配置

                        redis相关

                        主库建议设置masterauth,保证主库掉线后作为从库重连可以连接成功

                        masterauth password
                         

                        sentinel相关

                        sentinel能监控多个redis

                        sentinel monitor mymaster 127.0.0.1 6379 2
                        diff --git "a/assets/7.\350\231\232\346\213\237\346\234\272\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.html-D6upEAca.js" "b/assets/7.\350\231\232\346\213\237\346\234\272\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.html-BjfyysKr.js"
                        similarity index 99%
                        rename from "assets/7.\350\231\232\346\213\237\346\234\272\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.html-D6upEAca.js"
                        rename to "assets/7.\350\231\232\346\213\237\346\234\272\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.html-BjfyysKr.js"
                        index e257175..6c7d890 100644
                        --- "a/assets/7.\350\231\232\346\213\237\346\234\272\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.html-D6upEAca.js"
                        +++ "b/assets/7.\350\231\232\346\213\237\346\234\272\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.html-BjfyysKr.js"
                        @@ -1,4 +1,4 @@
                        -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as e,o as t}from"./app-IPkfDkxj.js";const p={};function l(c,n){return t(),s("div",null,n[0]||(n[0]=[e(`

                        7.虚拟机类加载机制

                        概述

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

                        在Java语言里面,类型的加载、连接和初始化过程都是在程序运行期间完成的。

                        Java天生可以动态扩展的语言特性就是依赖运行期动态加载和动态连接这个特点实现的。

                        类加载的时机

                        类的生命周期
                        类的生命周期

                        加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的。类型的加载过程必须按照这种顺序按部就班地开始

                        有且只有六种情况必须立即对类进行“初始化”:

                        1. 遇到new、getstatic、putstatic或invokestatic这四条字节码指令时,如果类型没有进行过初始化,则需要先触发其初始化阶段。能够生成这四条指令的典型Java代码场景有:
                          • 使用new关键字实例化对象的时候。
                          • 读取或设置一个类型的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候。
                          • 调用一个类型的静态方法的时候。
                        2. 使用java.lang.reflect包的方法对类型进行反射调用的时候,如果类型没有进行过初始化,则需要先触发其初始化。
                        3. 当初始化类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
                        4. 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
                        5. 当使用JDK 7新加入的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial四种类型的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要先触发其初始化。
                        6. 当一个接口中定义了JDK 8新加入的默认方法(被default关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化。

                        类加载的过程

                        加载

                        在加载阶段,Java虚拟机需要完成以下三件事情:

                        1. 通过一个类的全限定名来获取定义此类的二进制字节流。
                        2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
                        3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

                        ????todo

                        对于数组类而言,情况就有所不同,数组类本身不通过类加载器创建,它是由Java虚拟机直接在内存中动态构造出来的。但数组类与类加载器仍然有很密切的关系,因为数组类的元素类型(ElementType,指的是数组去掉所有维度的类型)最终还是要靠类加载器来完成加载,一个数组类(下面简称为C)创建过程遵循以下规则:

                        • 如果数组的组件类型(Component Type,指的是数组去掉一个维度的类型,注意和前面的元素类型区分开来)是引用类型,那就递归采用本节中定义的加载过程去加载这个组件类型,数组C将被标识在加载该组件类型的类加载器的类名称空间上(这点很重要,在7.4节会介绍,一个类型必须与类加载器一起确定唯一性)。
                        • 如果数组的组件类型不是引用类型(例如int[]数组的组件类型为int),Java虚拟机将会把数组C标记为与引导类加载器关联。
                        • 数组类的可访问性与它的组件类型的可访问性一致,如果组件类型不是引用类型,它的数组类的可访问性将默认为public,可被所有的类和接口访问到。

                        加载阶段结束后,Java虚拟机外部的二进制字节流就按照虚拟机所设定的格式存储在方法区之中了,方法区中的数据存储格式完全由虚拟机实现自行定义。类型数据妥善安置在方法区之后,会在Java堆内存中实例化一个java.lang.Class类的对象,这个对象将作为程序访问方法区中的类型数据的外部接口。

                        加载阶段与连接阶段的部分动作(如一部分字节码文件格式验证动作)是交叉进行的,加载阶段尚未完成,连接阶段可能已经开始,但这些夹在加载阶段之中进行的动作,仍然属于连接阶段的一部分,这两个阶段的开始时间仍然保持着固定的先后顺序。

                        验证

                        确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求

                        文件格式验证

                        • 是否以魔数0xCAFEBABE开头。
                        • 主、次版本号是否在当前Java虚拟机接受范围之内。
                        • 常量池的常量中是否有不被支持的常量类型(检查常量tag标志)。
                        • 指向常量的各种索引值中是否有指向不存在的常量或不符合类型的常量。
                        • CONSTANT_Utf8_info型的常量中是否有不符合UTF-8编码的数据。
                        • Class文件中各个部分及文件本身是否有被删除的或附加的其他信息。
                        • ……

                        主要目的是保证输入的字节流能正确地解析并存储于方法区之内,格式上符合描述一个Java类型信息的要求。只有通过了这个阶段的验证之后,这段字节流才被允许进入Java虚拟机内存的方法区中进行存储,所以后面的三个验证阶段全部是基于方法区的存储结构上进行的,不会再直接读取、操作字节流了。

                        元数据验证

                        • 这个类是否有父类(除了java.lang.Object之外,所有的类都应当有父类)。
                        • 这个类的父类是否继承了不允许被继承的类(被final修饰的类)。
                        • 如果这个类不是抽象类,是否实现了其父类或接口之中要求实现的所有方法。
                        • 类中的字段、方法是否与父类产生矛盾(例如覆盖了父类的final字段,或者出现不符合规则的方法重载,例如方法参数都一致,但返回值类型却不同等)。
                        • ……

                        主要目的是对类的元数据信息进行语义校验,保证不存在与《Java语言规范》定义相悖的元数据信息。

                        字节码验证

                        主要目的是通过数据流分析和控制流分析,确定程序语义是合法的、符合逻辑的。

                        • 保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作,例如不会出现类似于“在操作栈放置了一个int类型的数据,使用时却按long类型来加载入本地变量表中”这样的情况。
                        • 保证任何跳转指令都不会跳转到方法体以外的字节码指令上。
                        • 保证方法体中的类型转换总是有效的,例如可以把一个子类对象赋值给父类数据类型,这是安全的,但是把父类对象赋值给子类数据类型,甚至把对象赋值给与它毫无继承关系、完全不相干的一个数据类型,则是危险和不合法的。
                        • ……

                        符号引用验证

                        符号引用验证可以看作是对类自身以外(常量池中的各种符号引用)的各类信息进行匹配性校验,通俗来说就是,该类是否缺少或者被禁止访问它依赖的某些外部类、方法、字段等资源。本阶段通常需要校验下列内容:

                        • 符号引用中通过字符串描述的全限定名是否能找到对应的类。
                        • 在指定类中是否存在符合方法的字段描述符及简单名称所描述的方法和字段。
                        • 符号引用中的类、字段、方法的可访问性(privateprotectedpublic<package>)是否可被当前类访问。
                        • ……

                        主要目的是确保解析行为能正常执行,如果无法通过符号引用验证,Java虚拟机将会抛出一个java.lang.IncompatibleClassChangeError的子类异常,典型的如:java.lang.IllegalAccessErrorjava.lang.NoSuchFieldErrorjava.lang.NoSuchMethodError等。

                        准备

                        正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段

                        首先是这时候进行内存分配的仅包括类变量,而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中。 其次是这里所说的初始值“通常情况”下是数据类型的零值。

                        eg:

                        public static int value = 123;
                        +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as e,o as t}from"./app-DGSXj59V.js";const p={};function l(c,n){return t(),s("div",null,n[0]||(n[0]=[e(`

                        7.虚拟机类加载机制

                        概述

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

                        在Java语言里面,类型的加载、连接和初始化过程都是在程序运行期间完成的。

                        Java天生可以动态扩展的语言特性就是依赖运行期动态加载和动态连接这个特点实现的。

                        类加载的时机

                        类的生命周期
                        类的生命周期

                        加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的。类型的加载过程必须按照这种顺序按部就班地开始

                        有且只有六种情况必须立即对类进行“初始化”:

                        1. 遇到new、getstatic、putstatic或invokestatic这四条字节码指令时,如果类型没有进行过初始化,则需要先触发其初始化阶段。能够生成这四条指令的典型Java代码场景有:
                          • 使用new关键字实例化对象的时候。
                          • 读取或设置一个类型的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候。
                          • 调用一个类型的静态方法的时候。
                        2. 使用java.lang.reflect包的方法对类型进行反射调用的时候,如果类型没有进行过初始化,则需要先触发其初始化。
                        3. 当初始化类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
                        4. 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
                        5. 当使用JDK 7新加入的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial四种类型的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要先触发其初始化。
                        6. 当一个接口中定义了JDK 8新加入的默认方法(被default关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化。

                        类加载的过程

                        加载

                        在加载阶段,Java虚拟机需要完成以下三件事情:

                        1. 通过一个类的全限定名来获取定义此类的二进制字节流。
                        2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
                        3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

                        ????todo

                        对于数组类而言,情况就有所不同,数组类本身不通过类加载器创建,它是由Java虚拟机直接在内存中动态构造出来的。但数组类与类加载器仍然有很密切的关系,因为数组类的元素类型(ElementType,指的是数组去掉所有维度的类型)最终还是要靠类加载器来完成加载,一个数组类(下面简称为C)创建过程遵循以下规则:

                        • 如果数组的组件类型(Component Type,指的是数组去掉一个维度的类型,注意和前面的元素类型区分开来)是引用类型,那就递归采用本节中定义的加载过程去加载这个组件类型,数组C将被标识在加载该组件类型的类加载器的类名称空间上(这点很重要,在7.4节会介绍,一个类型必须与类加载器一起确定唯一性)。
                        • 如果数组的组件类型不是引用类型(例如int[]数组的组件类型为int),Java虚拟机将会把数组C标记为与引导类加载器关联。
                        • 数组类的可访问性与它的组件类型的可访问性一致,如果组件类型不是引用类型,它的数组类的可访问性将默认为public,可被所有的类和接口访问到。

                        加载阶段结束后,Java虚拟机外部的二进制字节流就按照虚拟机所设定的格式存储在方法区之中了,方法区中的数据存储格式完全由虚拟机实现自行定义。类型数据妥善安置在方法区之后,会在Java堆内存中实例化一个java.lang.Class类的对象,这个对象将作为程序访问方法区中的类型数据的外部接口。

                        加载阶段与连接阶段的部分动作(如一部分字节码文件格式验证动作)是交叉进行的,加载阶段尚未完成,连接阶段可能已经开始,但这些夹在加载阶段之中进行的动作,仍然属于连接阶段的一部分,这两个阶段的开始时间仍然保持着固定的先后顺序。

                        验证

                        确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求

                        文件格式验证

                        • 是否以魔数0xCAFEBABE开头。
                        • 主、次版本号是否在当前Java虚拟机接受范围之内。
                        • 常量池的常量中是否有不被支持的常量类型(检查常量tag标志)。
                        • 指向常量的各种索引值中是否有指向不存在的常量或不符合类型的常量。
                        • CONSTANT_Utf8_info型的常量中是否有不符合UTF-8编码的数据。
                        • Class文件中各个部分及文件本身是否有被删除的或附加的其他信息。
                        • ……

                        主要目的是保证输入的字节流能正确地解析并存储于方法区之内,格式上符合描述一个Java类型信息的要求。只有通过了这个阶段的验证之后,这段字节流才被允许进入Java虚拟机内存的方法区中进行存储,所以后面的三个验证阶段全部是基于方法区的存储结构上进行的,不会再直接读取、操作字节流了。

                        元数据验证

                        • 这个类是否有父类(除了java.lang.Object之外,所有的类都应当有父类)。
                        • 这个类的父类是否继承了不允许被继承的类(被final修饰的类)。
                        • 如果这个类不是抽象类,是否实现了其父类或接口之中要求实现的所有方法。
                        • 类中的字段、方法是否与父类产生矛盾(例如覆盖了父类的final字段,或者出现不符合规则的方法重载,例如方法参数都一致,但返回值类型却不同等)。
                        • ……

                        主要目的是对类的元数据信息进行语义校验,保证不存在与《Java语言规范》定义相悖的元数据信息。

                        字节码验证

                        主要目的是通过数据流分析和控制流分析,确定程序语义是合法的、符合逻辑的。

                        • 保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作,例如不会出现类似于“在操作栈放置了一个int类型的数据,使用时却按long类型来加载入本地变量表中”这样的情况。
                        • 保证任何跳转指令都不会跳转到方法体以外的字节码指令上。
                        • 保证方法体中的类型转换总是有效的,例如可以把一个子类对象赋值给父类数据类型,这是安全的,但是把父类对象赋值给子类数据类型,甚至把对象赋值给与它毫无继承关系、完全不相干的一个数据类型,则是危险和不合法的。
                        • ……

                        符号引用验证

                        符号引用验证可以看作是对类自身以外(常量池中的各种符号引用)的各类信息进行匹配性校验,通俗来说就是,该类是否缺少或者被禁止访问它依赖的某些外部类、方法、字段等资源。本阶段通常需要校验下列内容:

                        • 符号引用中通过字符串描述的全限定名是否能找到对应的类。
                        • 在指定类中是否存在符合方法的字段描述符及简单名称所描述的方法和字段。
                        • 符号引用中的类、字段、方法的可访问性(privateprotectedpublic<package>)是否可被当前类访问。
                        • ……

                        主要目的是确保解析行为能正常执行,如果无法通过符号引用验证,Java虚拟机将会抛出一个java.lang.IncompatibleClassChangeError的子类异常,典型的如:java.lang.IllegalAccessErrorjava.lang.NoSuchFieldErrorjava.lang.NoSuchMethodError等。

                        准备

                        正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段

                        首先是这时候进行内存分配的仅包括类变量,而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中。 其次是这里所说的初始值“通常情况”下是数据类型的零值。

                        eg:

                        public static int value = 123;
                         

                        在准备阶段过后的初始值为0而不是123

                        把value赋值为123的putstatic指令是程序被编译后,存放于类构造器<clinit>()方法之中,所以把value赋值为123的动作要到类的初始化阶段才会被执行

                        基本数据类型的零值

                        数据类型零值
                        int0
                        booleanfalse
                        longOL
                        float0.0f
                        short(short) 0
                        double0.0d
                        char\\u0000
                        referencenull
                        byte(byte) 0

                        例外

                        如果类字段的字段属性表中存在ConstantValue属性,那在准备阶段变量值就会被初始化为ConstantValue属性所指定的初始值

                        eg:

                        public static final int value = 123;
                         

                        编译时Javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据Con-stantValue的设置将value赋值为123。

                        解析

                        Java虚拟机将常量池内的符号引用替换为直接引用的过程

                        • 符号引用(Symbolic References):符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。符号引用与虚拟机实现的内存布局无关,引用的目标并不一定是已经加载到虚拟机内存当中的内容。各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须都是一致的,因为符号引用的字面量形式明确定义在《Java虚拟机规范》的Class文件格式中。
                        • 直接引用(Direct References):直接引用是可以直接指向目标的指针、相对偏移量或者是一个能间接定位到目标的句柄。直接引用是和虚拟机实现的内存布局直接相关的,同一个符号引用在不同虚拟机实例上翻译出来的直接引用一般不会相同。如果有了直接引用,那引用的目标必定已经在虚拟机的内存中存在。

                        《Java虚拟机规范》之中并未规定解析阶段发生的具体时间,只要求了在执行ane-warray、checkcast、getfield、getstatic、instanceof、invokedynamic、invokeinterface、invoke-special、invokestatic、invokevirtual、ldc、ldc_w、ldc2_w、multianewarray、new、putfield和putstatic这17个用于操作符号引用的字节码指令之前,先对它们所使用的符号引用进行解析。

                        对方法或者字段的访问,也会在解析阶段中对它们的可访问性(publicprotectedprivate<package>)进行检查。

                        对同一个符号引用进行多次解析请求是很常见的事情,除invokedynamic指令以外,虚拟机实现可以对第一次解析的结果进行缓存。invokedynamic指令的目的本来就是用于动态语言支持[1],它对应的引用称为“动态调用点限定符(Dynamically-Computed Call Site Specifier)”,这里“动态”的含义是指必须等到程序实际运行到这条指令时,解析动作才能进行。相对地,其余可触发解析的指令都是“静态”的,可以在刚刚完成加载阶段,还没有开始执行代码时就提前进行解析。

                        解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符这7类符号引用进行,分别对应于常量池的CONSTANT_Class_info、CON-STANT_Fieldref_info、CONSTANT_Methodref_info、CONSTANT_InterfaceMethodref_info、 CONSTANT_MethodType_info、CONSTANT_MethodHandle_info、CONSTANT_Dyna-mic_info和CONSTANT_InvokeDynamic_info 8种常量类型。

                        类或接口的解析

                        假设当前代码所处的类为D,如果要把一个从未解析过的符号引用N解析为一个类或接口C的直接引用,那虚拟机完成整个解析的过程需要包括以下3个步骤:

                        1. 如果C不是一个数组类型,那虚拟机将会把代表N的全限定名传递给D的类加载器去加载这个类C。在加载过程中,由于元数据验证、字节码验证的需要,又可能触发其他相关类的加载动作,例如加载这个类的父类或实现的接口。一旦这个加载过程出现了任何异常,解析过程就将宣告失败。
                        2. 如果C是一个数组类型,并且数组的元素类型为对象,也就是N的描述符会是类似“[Ljava/lang/Integer”的形式,那将会按照第一点的规则加载数组元素类型。如果N的描述符如前面所假设的形式,需要加载的元素类型就是“java.lang.Integer”,接着由虚拟机生成一个代表该数组维度和元素的数组对象。
                        3. 如果上面两步没有出现任何异常,那么C在虚拟机中实际上已经成为一个有效的类或接口了,但在解析完成前还要进行符号引用验证,确认D是否具备对C的访问权限。如果发现不具备访问权限,将抛出java.lang.IllegalAccessError异常。

                        针对上面第3点访问权限验证,在JDK 9引入了模块化以后,一个public类型也不再意味着程序任何位置都有它的访问权限,我们还必须检查模块间的访问权限。

                        如果我们说一个D拥有C的访问权限,那就意味着以下3条规则中至少有其中一条成立:

                        • 被访问类C是public的,并且与访问类D处于同一个模块。
                        • 被访问类C是public的,不与访问类D处于同一个模块,但是被访问类C的模块允许被访问类D的模块进行访问。
                        • 被访问类C不是public的,但是它与访问类D处于同一个包中。

                        字段解析

                        要解析一个未被解析过的字段符号引用,首先将会对字段表内class_index项中索引的CONSTANT_Class_info符号引用进行解析,也就是字段所属的类或接口的符号引用。如果在解析这个类或接口符号引用的过程中出现了任何异常,都会导致字段符号引用解析的失败。

                        如果解析成功完成,那把这个字段所属的类或接口用C表示,《Java虚拟机规范》要求按照如下步骤对C进行后续字段的搜索:

                        1. 如果C本身就包含了简单名称和字段描述符都与目标相匹配的字段,则返回这个字段的直接引用,查找结束。
                        2. 否则,如果在C中实现了接口,将会按照继承关系从下往上递归搜索各个接口和它的父接口,如果接口中包含了简单名称和字段描述符都与目标相匹配的字段,则返回这个字段的直接引用,查找结束。
                        3. 否则,如果C不是java.lang.Object的话,将会按照继承关系从下往上递归搜索其父类,如果在父类中包含了简单名称和字段描述符都与目标相匹配的字段,则返回这个字段的直接引用,查找结束。
                        4. 否则,查找失败,抛出java.lang.NoSuchFieldError异常。

                        如果查找过程成功返回了引用,将会对这个字段进行权限验证,如果发现不具备对字段的访问权限,将抛出java.lang.IllegalAccessError异常。

                        以上解析规则能够确保Java虚拟机获得字段唯一的解析结果,但在实际情况中,Javac编译器往往会采取比上述规范更加严格一些的约束,譬如有一个同名字段同时出现在某个类的接口和父类当中,或者同时在自己或父类的多个接口中出现,按照解析规则仍是可以确定唯一的访问字段,但Javac编译器就可能直接拒绝其编译为Class文件。在代码清单7-4中演示了这种情况,如果注释了Sub类中的“public static int A=4;”,接口与父类同时存在字段A,那Oracle公司实现的Javac编译器将提示“Thefield Sub.A is ambiguous”,并且会拒绝编译这段代码。

                        package org.fenixsoft.classloading;
                         public class FieldResolution {
                        diff --git "a/assets/8.\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.html-CHO3Bc_W.js" "b/assets/8.\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.html-Cjs8katk.js"
                        similarity index 99%
                        rename from "assets/8.\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.html-CHO3Bc_W.js"
                        rename to "assets/8.\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.html-Cjs8katk.js"
                        index a042849..fe4697a 100644
                        --- "a/assets/8.\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.html-CHO3Bc_W.js"
                        +++ "b/assets/8.\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.html-Cjs8katk.js"
                        @@ -1,4 +1,4 @@
                        -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as t,o as e}from"./app-IPkfDkxj.js";const p={};function o(c,n){return e(),s("div",null,n[0]||(n[0]=[t(`

                        8.虚拟机字节码执行引擎

                        概述

                        “虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟机的执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式

                        在《Java虚拟机规范》中制定了Java虚拟机字节码执行引擎的概念模型,这个概念模型成为各大发行商的Java虚拟机执行引擎的统一外观(Facade)

                        在不同的虚拟机实现中,执行引擎在执行字节码的时候,通常会有解释执行(通过解释器执行)和编译执行(通过即时编译器产生本地代码执行)两种选择,也可能两者兼备,还可能会有同时包含几个不同级别的即时编译器一起工作的执行引擎。但从外观上来看,所有的Java虚拟机的执行引擎输入、输出都是一致的:输入的是字节码二进制流,处理过程是字节码解析执行的等效过程,输出的是执行结果。

                        运行时栈帧结构

                        Java虚拟机以方法作为最基本的执行单元,“栈帧”(Stack Frame)则是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈(Virtual MachineStack)的栈元素。每一个方法从调用开始至执行结束的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。

                        在编译Java程序源码的时候,栈帧中需要多大的局部变量表,需要多深的操作数栈就已经被分析计算出来,并且写入到方法表的Code属性之中。一个栈帧需要分配多少内存,并不会受到程序运行期变量数据的影响,而仅仅取决于程序源码和具体的虚拟机实现的栈内存布局形式

                        一个线程中的方法调用链可能会很长,以Java程序的角度来看,同一时刻、同一条线程里面,在调用堆栈的所有方法都同时处于执行状态。而对于执行引擎来讲,在活动线程中,只有位于栈顶的方法才是在运行的,只有位于栈顶的栈帧才是生效的,其被称为“当前栈帧”(Current Stack Frame),与这个栈帧所关联的方法被称为“当前方法”(Current Method)。执行引擎所运行的所有字节码指令都只针对当前栈帧进行操作,

                        栈帧的概念结构
                        栈帧的概念结构

                        局部变量表

                        局部变量表(Local Variables Table)是一组变量值的存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序被编译为Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需分配的局部变量表的最大容量。

                        局部变量表的容量以变量槽(Variable Slot)为最小单位,《Java虚拟机规范》中并没有明确指出一个变量槽应占用的内存空间大小,只是很有导向性地说到每个变量槽都应该能存放一个boolean、byte、char、short、int、float、reference或returnAddress类型的数据。它允许变量槽的长度可以随着处理器、操作系统或虚拟机实现的不同而发生变化。

                        对于64位的数据类型,Java虚拟机会以高位对齐的方式为其分配两个连续的变量槽空间。由于局部变量表是建立在线程堆栈中的,属于线程私有的数据,无论读写两个连续的变量槽是否为原子操作,都不会引起数据竞争和线程安全问题。对于两个相邻的共同存放一个64位数据的两个变量槽,虚拟机不允许采用任何方式单独访问其中的某一个,

                        当一个方法被调用时,Java虚拟机会使用局部变量表来完成参数值到参数变量列表的传递过程,即实参到形参的传递。如果执行的是实例方法(没有被static修饰的方法),那局部变量表中第0位索引的变量槽默认是用于传递方法所属对象实例的引用,在方法中可以通过关键字“this”来访问到这个隐含的参数。其余参数则按照参数表顺序排列,占用从1开始的局部变量槽,参数表分配完毕后,再根据方法体内部定义的变量顺序和作用域分配其余的变量槽。

                        为了尽可能节省栈帧耗用的内存空间,局部变量表中的变量槽是可以重用的,方法体中定义的变量,其作用域并不一定会覆盖整个方法体,如果当前字节码PC计数器的值已经超出了某个变量的作用域,那这个变量对应的变量槽就可以交给其他变量来重用。

                        某些情况下变量槽的复用会直接影响到系统的垃圾收集行为

                        1. public static void main(String[] args)() {
                          +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as t,o as e}from"./app-DGSXj59V.js";const p={};function o(c,n){return e(),s("div",null,n[0]||(n[0]=[t(`

                          8.虚拟机字节码执行引擎

                          概述

                          “虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟机的执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式

                          在《Java虚拟机规范》中制定了Java虚拟机字节码执行引擎的概念模型,这个概念模型成为各大发行商的Java虚拟机执行引擎的统一外观(Facade)

                          在不同的虚拟机实现中,执行引擎在执行字节码的时候,通常会有解释执行(通过解释器执行)和编译执行(通过即时编译器产生本地代码执行)两种选择,也可能两者兼备,还可能会有同时包含几个不同级别的即时编译器一起工作的执行引擎。但从外观上来看,所有的Java虚拟机的执行引擎输入、输出都是一致的:输入的是字节码二进制流,处理过程是字节码解析执行的等效过程,输出的是执行结果。

                          运行时栈帧结构

                          Java虚拟机以方法作为最基本的执行单元,“栈帧”(Stack Frame)则是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈(Virtual MachineStack)的栈元素。每一个方法从调用开始至执行结束的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。

                          在编译Java程序源码的时候,栈帧中需要多大的局部变量表,需要多深的操作数栈就已经被分析计算出来,并且写入到方法表的Code属性之中。一个栈帧需要分配多少内存,并不会受到程序运行期变量数据的影响,而仅仅取决于程序源码和具体的虚拟机实现的栈内存布局形式

                          一个线程中的方法调用链可能会很长,以Java程序的角度来看,同一时刻、同一条线程里面,在调用堆栈的所有方法都同时处于执行状态。而对于执行引擎来讲,在活动线程中,只有位于栈顶的方法才是在运行的,只有位于栈顶的栈帧才是生效的,其被称为“当前栈帧”(Current Stack Frame),与这个栈帧所关联的方法被称为“当前方法”(Current Method)。执行引擎所运行的所有字节码指令都只针对当前栈帧进行操作,

                          栈帧的概念结构
                          栈帧的概念结构

                          局部变量表

                          局部变量表(Local Variables Table)是一组变量值的存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序被编译为Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需分配的局部变量表的最大容量。

                          局部变量表的容量以变量槽(Variable Slot)为最小单位,《Java虚拟机规范》中并没有明确指出一个变量槽应占用的内存空间大小,只是很有导向性地说到每个变量槽都应该能存放一个boolean、byte、char、short、int、float、reference或returnAddress类型的数据。它允许变量槽的长度可以随着处理器、操作系统或虚拟机实现的不同而发生变化。

                          对于64位的数据类型,Java虚拟机会以高位对齐的方式为其分配两个连续的变量槽空间。由于局部变量表是建立在线程堆栈中的,属于线程私有的数据,无论读写两个连续的变量槽是否为原子操作,都不会引起数据竞争和线程安全问题。对于两个相邻的共同存放一个64位数据的两个变量槽,虚拟机不允许采用任何方式单独访问其中的某一个,

                          当一个方法被调用时,Java虚拟机会使用局部变量表来完成参数值到参数变量列表的传递过程,即实参到形参的传递。如果执行的是实例方法(没有被static修饰的方法),那局部变量表中第0位索引的变量槽默认是用于传递方法所属对象实例的引用,在方法中可以通过关键字“this”来访问到这个隐含的参数。其余参数则按照参数表顺序排列,占用从1开始的局部变量槽,参数表分配完毕后,再根据方法体内部定义的变量顺序和作用域分配其余的变量槽。

                          为了尽可能节省栈帧耗用的内存空间,局部变量表中的变量槽是可以重用的,方法体中定义的变量,其作用域并不一定会覆盖整个方法体,如果当前字节码PC计数器的值已经超出了某个变量的作用域,那这个变量对应的变量槽就可以交给其他变量来重用。

                          某些情况下变量槽的复用会直接影响到系统的垃圾收集行为

                          1. public static void main(String[] args)() {
                                 byte[] placeholder = new byte[64 * 1024 * 1024];
                                 System.gc();
                             }
                            diff --git "a/assets/9.\347\261\273\345\212\240\350\275\275\345\217\212\346\211\247\350\241\214\345\255\220\347\263\273\347\273\237\347\232\204\346\241\210\344\276\213\344\270\216\345\256\236\346\210\230.html-BEJe7Ncf.js" "b/assets/9.\347\261\273\345\212\240\350\275\275\345\217\212\346\211\247\350\241\214\345\255\220\347\263\273\347\273\237\347\232\204\346\241\210\344\276\213\344\270\216\345\256\236\346\210\230.html-DnCZ_kpU.js"
                            similarity index 99%
                            rename from "assets/9.\347\261\273\345\212\240\350\275\275\345\217\212\346\211\247\350\241\214\345\255\220\347\263\273\347\273\237\347\232\204\346\241\210\344\276\213\344\270\216\345\256\236\346\210\230.html-BEJe7Ncf.js"
                            rename to "assets/9.\347\261\273\345\212\240\350\275\275\345\217\212\346\211\247\350\241\214\345\255\220\347\263\273\347\273\237\347\232\204\346\241\210\344\276\213\344\270\216\345\256\236\346\210\230.html-DnCZ_kpU.js"
                            index e73091a..5ed2cc6 100644
                            --- "a/assets/9.\347\261\273\345\212\240\350\275\275\345\217\212\346\211\247\350\241\214\345\255\220\347\263\273\347\273\237\347\232\204\346\241\210\344\276\213\344\270\216\345\256\236\346\210\230.html-BEJe7Ncf.js"
                            +++ "b/assets/9.\347\261\273\345\212\240\350\275\275\345\217\212\346\211\247\350\241\214\345\255\220\347\263\273\347\273\237\347\232\204\346\241\210\344\276\213\344\270\216\345\256\236\346\210\230.html-DnCZ_kpU.js"
                            @@ -1,4 +1,4 @@
                            -import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as t,o as e}from"./app-IPkfDkxj.js";const p={};function o(c,n){return e(),a("div",null,n[0]||(n[0]=[t(`

                            9.类加载及执行子系统的案例与实战

                            概述

                            在Class文件格式与执行引擎这部分里,用户的程序能直接参与的内容并不太多,Class文件以何种格式存储,类型何时加载、如何连接,以及虚拟机如何执行字节码指令等都是由虚拟机直接控制的行为,用户程序无法对其进行改变。能通过程序进行操作的,主要是字节码生成与类加载器这两部分的功能,但仅仅在如何处理这两点上,就已经出现了许多值得欣赏和借鉴的思路,这些思路后来成为许多常用功能和程序实现的基础。

                            案例分析

                            Tomcat:正统的类加载器架构

                            主流的Java Web服务器,如Tomcat、Jetty、WebLogic、WebSphere或其他笔者没有列举的服务器,都实现了自己定义的类加载器,而且一般还都不止一个。因为一个功能健全的Web服务器,都要解决如下的这些问题:

                            • 部署在同一个服务器上的两个Web应用程序所使用的Java类库可以实现相互隔离。这是最基本的需求,两个不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求每个类库在一个服务器中只能有一份,服务器应当能够保证两个独立应用程序的类库可以互相独立使用。
                            • 部署在同一个服务器上的两个Web应用程序所使用的Java类库可以互相共享。这个需求与前面一点正好相反,但是也很常见,例如用户可能有10个使用Spring组织的应用程序部署在同一台服务器上,如果把10份Spring分别存放在各个应用程序的隔离目录中,将会是很大的资源浪费——这主要倒不是浪费磁盘空间的问题,而是指类库在使用时都要被加载到服务器内存,如果类库不能共享,虚拟机的方法区就会很容易出现过度膨胀的风险。
                            • 服务器需要尽可能地保证自身的安全不受部署的Web应用程序影响。目前,有许多主流的JavaWeb服务器自身也是使用Java语言来实现的。因此服务器本身也有类库依赖的问题,一般来说,基于安全考虑,服务器所使用的类库应该与应用程序的类库互相独立。
                            • 支持JSP应用的Web服务器,十有八九都需要支持HotSwap功能。我们知道JSP文件最终要被编译成Java的Class文件才能被虚拟机执行,但JSP文件由于其纯文本存储的特性,被运行时修改的概率远大于第三方类库或程序自己的Class文件。而且ASP、PHP和JSP这些网页应用也把修改后无须重启作为一个很大的“优势”来看待,因此“主流”的Web服务器都会支持JSP生成类的热替换,当然也有“非主流”的,如运行在生产模式(Production Mode)下的WebLogic服务器默认就不会处理JSP文件的变化。

                            由于存在上述问题,在部署Web应用时,单独的一个ClassPath就不能满足需求了,所以各种Web服务器都不约而同地提供了好几个有着不同含义的ClassPath路径供用户存放第三方类库,这些路径一般会以“lib”或“classes”命名。被放置到不同路径中的类库,具备不同的访问范围和服务对象,通常每一个目录都会有一个相应的自定义类加载器去加载放置在里面的Java类库。

                            在Tomcat目录结构中,可以设置3组目录(/common/*、/server/和/shared/,但默认不一定是开放的,可能只有/lib/目录存在)用于存放Java类库,另外还应该加上Web应用程序自身的“/WEB-INF/”目录,一共4组。把Java类库放置在这4组目录中,每一组都有独立的含义,分别是:

                            • 放置在/common目录中。类库可被Tomcat和所有的Web应用程序共同使用。
                            • 放置在/server目录中。类库可被Tomcat使用,对所有的Web应用程序都不可见。
                            • 放置在/shared目录中。类库可被所有的Web应用程序共同使用,但对Tomcat自己不可见。
                            • 放置在/WebApp/WEB-INF目录中。类库仅仅可以被该Web应用程序使用,对Tomcat和其他Web应用程序都不可见。

                            为了支持这套目录结构,并对目录里面的类库进行加载和隔离,Tomcat自定义了多个类加载器,这些类加载器按照经典的双亲委派模型来实现。

                            Tomcat服务器的类加载架构
                            Tomcat服务器的类加载架构

                            灰色背景的3个类加载器是JDK(以JDK 9之前经典的三层类加载器为例)默认提供的类加载器,这3个加载器的作用在第7章中已经介绍过了。而Common类加载器、Catalina类加载器(也称为Server类加载器)、Shared类加载器和Webapp类加载器则是Tomcat自己定义的类加载器,它们分别加载/common/、/server/、/shared/*和/WebApp/WEB-INF/*中的Java类库。其中WebApp类加载器和JSP类加载器通常还会存在多个实例,每一个Web应用程序对应一个WebApp类加载器,每一个JSP文件对应一个JasperLoader类加载器。

                            Common类加载器能加载的类都可以被Catalina类加载器和Shared类加载器使用,而Catalina类加载器和Shared类加载器自己能加载的类则与对方相互隔离。WebApp类加载器可以使用Shared类加载器加载到的类,但各个WebApp类加载器实例之间相互隔离。而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个Class文件,它存在的目的就是为了被丢弃:当服务器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的JSP类加载器来实现JSP文件的HotSwap功能。

                            本例中的类加载结构在Tomcat 6以前是它默认的类加载器结构,在Tomcat 6及之后的版本简化了默认的目录结构,只有指定了tomcat/conf/catalina.properties配置文件的server.loader和share.loader项后才会真正建立Catalina类加载器和Shared类加载器的实例,否则会用到这两个类加载器的地方都会用Common类加载器的实例代替,而默认的配置文件中并没有设置这两个loader项,所以Tomcat 6之后也顺理成章地把/common、/server和/shared这3个目录默认合并到一起变成1个/lib目录,这个目录里的类库相当于以前/common目录中类库的作用,是Tomcat的开发团队为了简化大多数的部署场景所做的一项易用性改进。如果默认设置不能满足需要,用户可以通过修改配置文件指定server.loader和share.loader的方式重新启用原来完整的加载器架构。

                            OSGi:灵活的类加载器架构

                            OSGi(Open Service Gateway Initiative)是OSGi联盟(OSGi Alliance)制订的一个基于Java语言的动态模块化规范(在JDK 9引入的JPMS是静态的模块系统),这个规范最初由IBM、爱立信等公司联合发起,在早期连Sun公司都有参与。目的是使服务提供商通过住宅网关为各种家用智能设备提供服务,后来这个规范在Java的其他技术领域也有相当不错的发展,现在已经成为Java世界中“事实上”的动态模块化标准,并且已经有了Equinox、Felix等成熟的实现。

                            OSGi中的每个模块(称为Bundle)与普通的Java类库区别并不太大,两者一般都以JAR格式进行封装,并且内部存储的都是Java的Package和Class。但是一个Bundle可以声明它所依赖的Package(通过Import-Package描述),也可以声明它允许导出发布的Package(通过Export-Package描述)。在OSGi里面,Bundle之间的依赖关系从传统的上层模块依赖底层模块转变为平级模块之间的依赖,而且类库的可见性能得到非常精确的控制,一个模块里只有被Export过的Package才可能被外界访问,其他的Package和Class将会被隐藏起来。

                            以上这些静态的模块化特性原本也是OSGi的核心需求之一,不过它和后来出现的Java的模块化系统互相重叠了,所以OSGi现在着重向动态模块化系统的方向发展。在今天,通常引入OSGi的主要理由是基于OSGi架构的程序很可能(只是很可能,并不是一定会,需要考虑热插拔后的内存管理、上下文状态维护问题等复杂因素)会实现模块级的热插拔功能,当程序升级更新或调试除错时,可以只停用、重新安装然后启用程序的其中一部分,这对大型软件、企业级程序开发来说是一个非常有诱惑力的特性,譬如Eclipse中安装、卸载、更新插件而不需要重启动,就使用到了这种特性。

                            OSGi之所以能有上述诱人的特点,必须要归功于它灵活的类加载器架构。OSGi的Bundle类加载器之间只有规则,没有固定的委派关系。例如,某个Bundle声明了一个它依赖的Package,如果有其他Bundle声明了发布这个Package后,那么所有对这个Package的类加载动作都会委派给发布它的Bundle类加载器去完成。不涉及某个具体的Package时,各个Bundle加载器都是平级的关系,只有具体使用到某个Package和Class的时候,才会根据Package导入导出定义来构造Bundle间的委派和依赖。

                            另外,一个Bundle类加载器为其他Bundle提供服务时,会根据Export-Package列表严格控制访问范围。如果一个类存在于Bundle的类库中但是没有被Export,那么这个Bundle的类加载器能找到这个类,但不会提供给其他Bundle使用,而且OSGi框架也不会把其他Bundle的类加载请求分配给这个Bundle来处理。

                            我们可以举一个更具体些的简单例子来解释上面的规则,假设存在Bundle A、Bundle B、BundleC3个模块,并且这3个Bundle定义的依赖关系如下所示。

                            • Bundle A:声明发布了packageA,依赖了java.*的包;
                            • Bundle B:声明依赖了packageA和packageC,同时也依赖了java.*的包;
                            • Bundle C:声明发布了packageC,依赖了packageA。

                            那么,这3个Bundle之间的类加载器及父类加载器之间的关系如图9-2所示。

                            OSGi的类加载器架构
                            OSGi的类加载器架构

                            由于没有涉及具体的OSGi实现,图中的类加载器都没有指明具体的加载器实现,它只是一个体现了加载器之间关系的概念模型,并且只是体现了OSGi中最简单的加载器委派关系。一般来说,在OSGi里,加载一个类可能发生的查找行为和委派关系会远远比图中显示的复杂,类加载时可能进行的查找规则如下:

                            • 以java.*开头的类,委派给父类加载器加载。
                            • 否则,委派列表名单内的类,委派给父类加载器加载。
                            • 否则,Import列表中的类,委派给Export这个类的Bundle的类加载器加载。
                            • 否则,查找当前Bundle的Classpath,使用自己的类加载器加载。
                            • 否则,查找是否在自己的Fragment Bundle中,如果是则委派给Fragment Bundle的类加载器加载。
                            • 否则,查找Dynamic Import列表的Bundle,委派给对应Bundle的类加载器加载。
                            • 否则,类查找失败。

                            从图中还可以看出,在OSGi中,加载器之间的关系不再是双亲委派模型的树形结构,而是已经进一步发展成一种更为复杂的、运行时才能确定的网状结构。这种网状的类加载器架构在带来更优秀的灵活性的同时,也可能会产生许多新的隐患。在JDK 7时才终于出现了JDK层面的解决方案,类加载器架构进行了一次专门的升级,在ClassLoader中增加了registerAsParallelCapable方法对可并行的类加载进行注册声明,把锁的级别从ClassLoader对象本身,降低为要加载的类名这个级别,目的是从底层避免以上这类死锁出现的可能。

                            总体来说,OSGi描绘了一个很美好的模块化开发的目标,而且定义了实现这个目标所需的各种服务,同时也有成熟框架对其提供实现支持。对于单个虚拟机下的应用,从开发初期就建立在OSGi上是一个很不错的选择,这样便于约束依赖。但并非所有的应用都适合采用OSGi作为基础架构,OSGi在提供强大功能的同时,也引入了额外而且非常高的复杂度,带来了额外的风险。

                            字节码生成技术与动态代理的实现

                            动态代理的简单示例

                            public class DynamicProxyTest {
                            +import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as t,o as e}from"./app-DGSXj59V.js";const p={};function o(c,n){return e(),a("div",null,n[0]||(n[0]=[t(`

                            9.类加载及执行子系统的案例与实战

                            概述

                            在Class文件格式与执行引擎这部分里,用户的程序能直接参与的内容并不太多,Class文件以何种格式存储,类型何时加载、如何连接,以及虚拟机如何执行字节码指令等都是由虚拟机直接控制的行为,用户程序无法对其进行改变。能通过程序进行操作的,主要是字节码生成与类加载器这两部分的功能,但仅仅在如何处理这两点上,就已经出现了许多值得欣赏和借鉴的思路,这些思路后来成为许多常用功能和程序实现的基础。

                            案例分析

                            Tomcat:正统的类加载器架构

                            主流的Java Web服务器,如Tomcat、Jetty、WebLogic、WebSphere或其他笔者没有列举的服务器,都实现了自己定义的类加载器,而且一般还都不止一个。因为一个功能健全的Web服务器,都要解决如下的这些问题:

                            • 部署在同一个服务器上的两个Web应用程序所使用的Java类库可以实现相互隔离。这是最基本的需求,两个不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求每个类库在一个服务器中只能有一份,服务器应当能够保证两个独立应用程序的类库可以互相独立使用。
                            • 部署在同一个服务器上的两个Web应用程序所使用的Java类库可以互相共享。这个需求与前面一点正好相反,但是也很常见,例如用户可能有10个使用Spring组织的应用程序部署在同一台服务器上,如果把10份Spring分别存放在各个应用程序的隔离目录中,将会是很大的资源浪费——这主要倒不是浪费磁盘空间的问题,而是指类库在使用时都要被加载到服务器内存,如果类库不能共享,虚拟机的方法区就会很容易出现过度膨胀的风险。
                            • 服务器需要尽可能地保证自身的安全不受部署的Web应用程序影响。目前,有许多主流的JavaWeb服务器自身也是使用Java语言来实现的。因此服务器本身也有类库依赖的问题,一般来说,基于安全考虑,服务器所使用的类库应该与应用程序的类库互相独立。
                            • 支持JSP应用的Web服务器,十有八九都需要支持HotSwap功能。我们知道JSP文件最终要被编译成Java的Class文件才能被虚拟机执行,但JSP文件由于其纯文本存储的特性,被运行时修改的概率远大于第三方类库或程序自己的Class文件。而且ASP、PHP和JSP这些网页应用也把修改后无须重启作为一个很大的“优势”来看待,因此“主流”的Web服务器都会支持JSP生成类的热替换,当然也有“非主流”的,如运行在生产模式(Production Mode)下的WebLogic服务器默认就不会处理JSP文件的变化。

                            由于存在上述问题,在部署Web应用时,单独的一个ClassPath就不能满足需求了,所以各种Web服务器都不约而同地提供了好几个有着不同含义的ClassPath路径供用户存放第三方类库,这些路径一般会以“lib”或“classes”命名。被放置到不同路径中的类库,具备不同的访问范围和服务对象,通常每一个目录都会有一个相应的自定义类加载器去加载放置在里面的Java类库。

                            在Tomcat目录结构中,可以设置3组目录(/common/*、/server/和/shared/,但默认不一定是开放的,可能只有/lib/目录存在)用于存放Java类库,另外还应该加上Web应用程序自身的“/WEB-INF/”目录,一共4组。把Java类库放置在这4组目录中,每一组都有独立的含义,分别是:

                            • 放置在/common目录中。类库可被Tomcat和所有的Web应用程序共同使用。
                            • 放置在/server目录中。类库可被Tomcat使用,对所有的Web应用程序都不可见。
                            • 放置在/shared目录中。类库可被所有的Web应用程序共同使用,但对Tomcat自己不可见。
                            • 放置在/WebApp/WEB-INF目录中。类库仅仅可以被该Web应用程序使用,对Tomcat和其他Web应用程序都不可见。

                            为了支持这套目录结构,并对目录里面的类库进行加载和隔离,Tomcat自定义了多个类加载器,这些类加载器按照经典的双亲委派模型来实现。

                            Tomcat服务器的类加载架构
                            Tomcat服务器的类加载架构

                            灰色背景的3个类加载器是JDK(以JDK 9之前经典的三层类加载器为例)默认提供的类加载器,这3个加载器的作用在第7章中已经介绍过了。而Common类加载器、Catalina类加载器(也称为Server类加载器)、Shared类加载器和Webapp类加载器则是Tomcat自己定义的类加载器,它们分别加载/common/、/server/、/shared/*和/WebApp/WEB-INF/*中的Java类库。其中WebApp类加载器和JSP类加载器通常还会存在多个实例,每一个Web应用程序对应一个WebApp类加载器,每一个JSP文件对应一个JasperLoader类加载器。

                            Common类加载器能加载的类都可以被Catalina类加载器和Shared类加载器使用,而Catalina类加载器和Shared类加载器自己能加载的类则与对方相互隔离。WebApp类加载器可以使用Shared类加载器加载到的类,但各个WebApp类加载器实例之间相互隔离。而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个Class文件,它存在的目的就是为了被丢弃:当服务器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的JSP类加载器来实现JSP文件的HotSwap功能。

                            本例中的类加载结构在Tomcat 6以前是它默认的类加载器结构,在Tomcat 6及之后的版本简化了默认的目录结构,只有指定了tomcat/conf/catalina.properties配置文件的server.loader和share.loader项后才会真正建立Catalina类加载器和Shared类加载器的实例,否则会用到这两个类加载器的地方都会用Common类加载器的实例代替,而默认的配置文件中并没有设置这两个loader项,所以Tomcat 6之后也顺理成章地把/common、/server和/shared这3个目录默认合并到一起变成1个/lib目录,这个目录里的类库相当于以前/common目录中类库的作用,是Tomcat的开发团队为了简化大多数的部署场景所做的一项易用性改进。如果默认设置不能满足需要,用户可以通过修改配置文件指定server.loader和share.loader的方式重新启用原来完整的加载器架构。

                            OSGi:灵活的类加载器架构

                            OSGi(Open Service Gateway Initiative)是OSGi联盟(OSGi Alliance)制订的一个基于Java语言的动态模块化规范(在JDK 9引入的JPMS是静态的模块系统),这个规范最初由IBM、爱立信等公司联合发起,在早期连Sun公司都有参与。目的是使服务提供商通过住宅网关为各种家用智能设备提供服务,后来这个规范在Java的其他技术领域也有相当不错的发展,现在已经成为Java世界中“事实上”的动态模块化标准,并且已经有了Equinox、Felix等成熟的实现。

                            OSGi中的每个模块(称为Bundle)与普通的Java类库区别并不太大,两者一般都以JAR格式进行封装,并且内部存储的都是Java的Package和Class。但是一个Bundle可以声明它所依赖的Package(通过Import-Package描述),也可以声明它允许导出发布的Package(通过Export-Package描述)。在OSGi里面,Bundle之间的依赖关系从传统的上层模块依赖底层模块转变为平级模块之间的依赖,而且类库的可见性能得到非常精确的控制,一个模块里只有被Export过的Package才可能被外界访问,其他的Package和Class将会被隐藏起来。

                            以上这些静态的模块化特性原本也是OSGi的核心需求之一,不过它和后来出现的Java的模块化系统互相重叠了,所以OSGi现在着重向动态模块化系统的方向发展。在今天,通常引入OSGi的主要理由是基于OSGi架构的程序很可能(只是很可能,并不是一定会,需要考虑热插拔后的内存管理、上下文状态维护问题等复杂因素)会实现模块级的热插拔功能,当程序升级更新或调试除错时,可以只停用、重新安装然后启用程序的其中一部分,这对大型软件、企业级程序开发来说是一个非常有诱惑力的特性,譬如Eclipse中安装、卸载、更新插件而不需要重启动,就使用到了这种特性。

                            OSGi之所以能有上述诱人的特点,必须要归功于它灵活的类加载器架构。OSGi的Bundle类加载器之间只有规则,没有固定的委派关系。例如,某个Bundle声明了一个它依赖的Package,如果有其他Bundle声明了发布这个Package后,那么所有对这个Package的类加载动作都会委派给发布它的Bundle类加载器去完成。不涉及某个具体的Package时,各个Bundle加载器都是平级的关系,只有具体使用到某个Package和Class的时候,才会根据Package导入导出定义来构造Bundle间的委派和依赖。

                            另外,一个Bundle类加载器为其他Bundle提供服务时,会根据Export-Package列表严格控制访问范围。如果一个类存在于Bundle的类库中但是没有被Export,那么这个Bundle的类加载器能找到这个类,但不会提供给其他Bundle使用,而且OSGi框架也不会把其他Bundle的类加载请求分配给这个Bundle来处理。

                            我们可以举一个更具体些的简单例子来解释上面的规则,假设存在Bundle A、Bundle B、BundleC3个模块,并且这3个Bundle定义的依赖关系如下所示。

                            • Bundle A:声明发布了packageA,依赖了java.*的包;
                            • Bundle B:声明依赖了packageA和packageC,同时也依赖了java.*的包;
                            • Bundle C:声明发布了packageC,依赖了packageA。

                            那么,这3个Bundle之间的类加载器及父类加载器之间的关系如图9-2所示。

                            OSGi的类加载器架构
                            OSGi的类加载器架构

                            由于没有涉及具体的OSGi实现,图中的类加载器都没有指明具体的加载器实现,它只是一个体现了加载器之间关系的概念模型,并且只是体现了OSGi中最简单的加载器委派关系。一般来说,在OSGi里,加载一个类可能发生的查找行为和委派关系会远远比图中显示的复杂,类加载时可能进行的查找规则如下:

                            • 以java.*开头的类,委派给父类加载器加载。
                            • 否则,委派列表名单内的类,委派给父类加载器加载。
                            • 否则,Import列表中的类,委派给Export这个类的Bundle的类加载器加载。
                            • 否则,查找当前Bundle的Classpath,使用自己的类加载器加载。
                            • 否则,查找是否在自己的Fragment Bundle中,如果是则委派给Fragment Bundle的类加载器加载。
                            • 否则,查找Dynamic Import列表的Bundle,委派给对应Bundle的类加载器加载。
                            • 否则,类查找失败。

                            从图中还可以看出,在OSGi中,加载器之间的关系不再是双亲委派模型的树形结构,而是已经进一步发展成一种更为复杂的、运行时才能确定的网状结构。这种网状的类加载器架构在带来更优秀的灵活性的同时,也可能会产生许多新的隐患。在JDK 7时才终于出现了JDK层面的解决方案,类加载器架构进行了一次专门的升级,在ClassLoader中增加了registerAsParallelCapable方法对可并行的类加载进行注册声明,把锁的级别从ClassLoader对象本身,降低为要加载的类名这个级别,目的是从底层避免以上这类死锁出现的可能。

                            总体来说,OSGi描绘了一个很美好的模块化开发的目标,而且定义了实现这个目标所需的各种服务,同时也有成熟框架对其提供实现支持。对于单个虚拟机下的应用,从开发初期就建立在OSGi上是一个很不错的选择,这样便于约束依赖。但并非所有的应用都适合采用OSGi作为基础架构,OSGi在提供强大功能的同时,也引入了额外而且非常高的复杂度,带来了额外的风险。

                            字节码生成技术与动态代理的实现

                            动态代理的简单示例

                            public class DynamicProxyTest {
                             
                                 interface IHello {
                                     void sayHello();
                            diff --git a/assets/SpringSecurity.html-B-4pbTrz.js b/assets/SpringSecurity.html-BdbZDA5T.js
                            similarity index 97%
                            rename from assets/SpringSecurity.html-B-4pbTrz.js
                            rename to assets/SpringSecurity.html-BdbZDA5T.js
                            index fc86019..8f29b93 100644
                            --- a/assets/SpringSecurity.html-B-4pbTrz.js
                            +++ b/assets/SpringSecurity.html-BdbZDA5T.js
                            @@ -1 +1 @@
                            -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as a,o as i}from"./app-IPkfDkxj.js";const o={};function r(c,t){return i(),n("div",null,t[0]||(t[0]=[a('

                            Authentication

                            接口

                            AbstractAuthenticationToken

                            实现Authentication接口的基类(模板模式)

                            UsernamePasswordAuthenticationToken

                            常用

                            ',7)]))}const p=e(o,[["render",r],["__file","SpringSecurity.html.vue"]]),u=JSON.parse('{"path":"/java/spring/SpringSecurity.html","title":"","lang":"zh-CN","frontmatter":{"description":"Authentication 接口 AbstractAuthenticationToken 实现Authentication接口的基类(模板模式) UsernamePasswordAuthenticationToken 常用","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/spring/SpringSecurity.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:description","content":"Authentication 接口 AbstractAuthenticationToken 实现Authentication接口的基类(模板模式) UsernamePasswordAuthenticationToken 常用"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"Authentication","slug":"authentication","link":"#authentication","children":[{"level":3,"title":"AbstractAuthenticationToken","slug":"abstractauthenticationtoken","link":"#abstractauthenticationtoken","children":[]},{"level":3,"title":"UsernamePasswordAuthenticationToken","slug":"usernamepasswordauthenticationtoken","link":"#usernamepasswordauthenticationtoken","children":[]}]}],"git":{"createdTime":1710225495000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.06,"words":19},"filePathRelative":"java/spring/SpringSecurity.md","localizedDate":"2024年3月12日","autoDesc":true}');export{p as comp,u as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as a,o as i}from"./app-DGSXj59V.js";const o={};function r(c,t){return i(),n("div",null,t[0]||(t[0]=[a('

                            Authentication

                            接口

                            AbstractAuthenticationToken

                            实现Authentication接口的基类(模板模式)

                            UsernamePasswordAuthenticationToken

                            常用

                            ',7)]))}const p=e(o,[["render",r],["__file","SpringSecurity.html.vue"]]),u=JSON.parse('{"path":"/java/spring/SpringSecurity.html","title":"","lang":"zh-CN","frontmatter":{"description":"Authentication 接口 AbstractAuthenticationToken 实现Authentication接口的基类(模板模式) UsernamePasswordAuthenticationToken 常用","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/spring/SpringSecurity.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:description","content":"Authentication 接口 AbstractAuthenticationToken 实现Authentication接口的基类(模板模式) UsernamePasswordAuthenticationToken 常用"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"Authentication","slug":"authentication","link":"#authentication","children":[{"level":3,"title":"AbstractAuthenticationToken","slug":"abstractauthenticationtoken","link":"#abstractauthenticationtoken","children":[]},{"level":3,"title":"UsernamePasswordAuthenticationToken","slug":"usernamepasswordauthenticationtoken","link":"#usernamepasswordauthenticationtoken","children":[]}]}],"git":{"createdTime":1710225495000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.06,"words":19},"filePathRelative":"java/spring/SpringSecurity.md","localizedDate":"2024年3月12日","autoDesc":true}');export{p as comp,u as data}; diff --git a/assets/app-IPkfDkxj.js b/assets/app-DGSXj59V.js similarity index 96% rename from assets/app-IPkfDkxj.js rename to assets/app-DGSXj59V.js index c9c8045..63ab876 100644 --- a/assets/app-IPkfDkxj.js +++ b/assets/app-DGSXj59V.js @@ -1,4 +1,4 @@ -const __vite__fileDeps=["assets/index.html-Roc1x59k.js","assets/plugin-vue_export-helper-DlAUqK2U.js","assets/index.html-6X9t5qpu.js","assets/2023.html-CZcJbhdh.js","assets/index.html-BLJjaEnE.js","assets/index.html-BWMmt9_Q.js","assets/index.html-BFkKlz8G.js","assets/index.html-3g_tXqhW.js","assets/10.前端编译与优化.html-xpAp087Y.js","assets/11.后端编译与优化.html-Xs_v6BVk.js","assets/2.Java内存区域与内存溢出异常.html-sguZT_xH.js","assets/3.垃圾收集器与内存分配策略(上).html-DOojsy_g.js","assets/3.垃圾收集器与内存分配策略(下).html-CvPGtoPK.js","assets/4.虚拟机性能监控、故障处理工具.html-BURKEJxN.js","assets/5.调优案例分析与实战.html-DdFwZo66.js","assets/6.类文件结构(上).html-bMezDIIg.js","assets/6.类文件结构(下).html-BR-9LCfV.js","assets/7.虚拟机类加载机制.html-D6upEAca.js","assets/8.虚拟机字节码执行引擎.html-CHO3Bc_W.js","assets/9.类加载及执行子系统的案例与实战.html-BEJe7Ncf.js","assets/index.html-je-vdzFE.js","assets/basis.html-BeJJBQWv.js","assets/dump.html-CgS7EZ3W.js","assets/logs.html-CteEoTLH.js","assets/0.redis7.html-D8dTCNAM.js","assets/1.十大数据类型.html-DetU5pF8.js","assets/2.持久化.html-Cj-6GcFe.js","assets/3.事务.html-D0FP5PwK.js","assets/4.管道.html-B3H0WI8v.js","assets/5.发布与订阅.html-DGZVcgfp.js","assets/6.复制.html-BXO5kx7f.js","assets/7.哨兵.html-BgjEihqV.js","assets/index.html-CAhMCF-2.js","assets/index.html-WY8-PpYT.js","assets/index.html-CDxqUD9S.js","assets/basis.html-wEn3fTf7.js","assets/no.html-Bggz8Mf2.js","assets/index.html-BjxWTrKZ.js","assets/basis.html-6Q8zK8Bd.js","assets/index.html-WkXnwUCZ.js","assets/basis.html-Jvc2997A.js","assets/index.html-Bito5Fo8.js","assets/SpringSecurity.html-B-4pbTrz.js","assets/demo.html-_U9HoCj_.js","assets/index.html-C4Md3jw-.js","assets/basis.html-DHIr7USm.js","assets/index.html-CQfPShe9.js","assets/index.html-aNDDDL4S.js","assets/string-compression.html-IQPW5i69.js","assets/index.html-BVtf9Xg2.js","assets/install.html-DfRGkxGy.js","assets/index.html-2TimMen1.js","assets/basis.html-CbUDOSOT.js","assets/index.html-DpohJUce.js","assets/arthas.html-DqXfZ7t8.js","assets/basis.html-BxbtaanI.js","assets/drone.html-CbMyU2PH.js","assets/nginx.html-DVjCG_xK.js","assets/podman-compose.html-Bm6gmrrd.js","assets/podman.html-CQmzNTKG.js","assets/basis.html-D-H00zGl.js","assets/basis.html-XXSTSKO_.js","assets/basis.html-zu40gkWN.js","assets/basis.html-Ds0kWP9C.js","assets/404.html-B4CKWbuD.js","assets/index.html-Dlv9CWZJ.js","assets/index.html-CbO2TWOo.js","assets/index.html-BOlVANES.js","assets/index.html-CMw-ULdl.js","assets/index.html-DG4ffYH3.js","assets/index.html-DJf5TL8z.js","assets/index.html-Cgvzxj0k.js","assets/index.html-CZl1qWB6.js","assets/index.html-rLTebBeh.js"],__vite__mapDeps=i=>i.map(i=>__vite__fileDeps[i]); +const __vite__fileDeps=["assets/index.html-Dlf95nvk.js","assets/plugin-vue_export-helper-DlAUqK2U.js","assets/2023.html-ArLS9RPY.js","assets/index.html-DXlT849A.js","assets/index.html-C6tUEycf.js","assets/index.html-DYp-5F_m.js","assets/index.html-BmE5rtpR.js","assets/index.html-wv-PNDDj.js","assets/10.前端编译与优化.html-CIsptAV2.js","assets/11.后端编译与优化.html-BXVBRKzU.js","assets/2.Java内存区域与内存溢出异常.html-DjsBGsDH.js","assets/3.垃圾收集器与内存分配策略(上).html-CIb-O2tW.js","assets/3.垃圾收集器与内存分配策略(下).html-Dxlni7rM.js","assets/4.虚拟机性能监控、故障处理工具.html-D4U1I6eG.js","assets/5.调优案例分析与实战.html-MlkdMvhD.js","assets/6.类文件结构(上).html-BtxCAsyy.js","assets/6.类文件结构(下).html-CHYdIYsk.js","assets/7.虚拟机类加载机制.html-BjfyysKr.js","assets/8.虚拟机字节码执行引擎.html-Cjs8katk.js","assets/9.类加载及执行子系统的案例与实战.html-DnCZ_kpU.js","assets/index.html-BnG1jZ_a.js","assets/basis.html-DZPqHWrC.js","assets/dump.html-upIgPA-c.js","assets/logs.html-B49m8Ki1.js","assets/0.redis7.html-DIJ1znYd.js","assets/1.十大数据类型.html-M6yAsNAG.js","assets/2.持久化.html-Btm7zx-d.js","assets/3.事务.html-CpmGsXBd.js","assets/4.管道.html-CWD-xPd8.js","assets/5.发布与订阅.html-Crzq7Y5K.js","assets/6.复制.html-CH73emLp.js","assets/7.哨兵.html-C92G7akQ.js","assets/index.html-DSsHnpqp.js","assets/index.html-m-iOeLa_.js","assets/index.html-BmNTlG-Z.js","assets/basis.html-2ahAkI4f.js","assets/no.html-DSfEWxWZ.js","assets/index.html-t50OORIi.js","assets/basis.html-DUj1Wnj7.js","assets/index.html-BjuNRCNw.js","assets/basis.html-95B3ZLlj.js","assets/index.html-Cz8jDxAY.js","assets/SpringSecurity.html-BdbZDA5T.js","assets/demo.html-CkMNEXQC.js","assets/index.html-DhqTU2xX.js","assets/basis.html-GlRiLsmg.js","assets/index.html-BqzKiupE.js","assets/index.html-D8OfGtcT.js","assets/string-compression.html-pFNlH1Er.js","assets/index.html-Caayfztk.js","assets/install.html-Dug0d3yu.js","assets/index.html-uEv93DTy.js","assets/basis.html-2JCN_GSw.js","assets/index.html-CMFNipnT.js","assets/arthas.html-BmuamiK8.js","assets/basis.html-DQim-pLK.js","assets/drone.html-D1mwj-od.js","assets/nginx.html-BXoNRXpL.js","assets/podman-compose.html-49_0XMa0.js","assets/podman.html-CPwV8nQQ.js","assets/basis.html-BLw4eSnF.js","assets/basis.html-02RvDNho.js","assets/basis.html-CV6VoMyY.js","assets/basis.html-Cl860v1g.js","assets/404.html-CkT6DnzW.js","assets/index.html-Bk17tqnU.js","assets/index.html-DIJfQi65.js","assets/index.html-Dd2UFmj8.js","assets/index.html-Dy81h_sK.js","assets/index.html-YCjvOQL7.js","assets/index.html-B9KtETue.js","assets/index.html-BgmHQsum.js","assets/index.html-9CuuwwcO.js","assets/index.html-NBqlJgDk.js"],__vite__mapDeps=i=>i.map(i=>__vite__fileDeps[i]); /** * @vue/shared v3.5.11 * (c) 2018-present Yuxi (Evan) You and Vue contributors @@ -16,14 +16,14 @@ const __vite__fileDeps=["assets/index.html-Roc1x59k.js","assets/plugin-vue_expor * @vue/runtime-dom v3.5.11 * (c) 2018-present Yuxi (Evan) You and Vue contributors * @license MIT -**/let fo;const jl=typeof window<"u"&&window.trustedTypes;if(jl)try{fo=jl.createPolicy("vue",{createHTML:e=>e})}catch{}const Qi=fo?e=>fo.createHTML(e):e=>e,Zd="http://www.w3.org/2000/svg",e1="http://www.w3.org/1998/Math/MathML",Dt=typeof document<"u"?document:null,Fl=Dt&&Dt.createElement("template"),t1={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const s=t==="svg"?Dt.createElementNS(Zd,e):t==="mathml"?Dt.createElementNS(e1,e):n?Dt.createElement(e,{is:n}):Dt.createElement(e);return e==="select"&&r&&r.multiple!=null&&s.setAttribute("multiple",r.multiple),s},createText:e=>Dt.createTextNode(e),createComment:e=>Dt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Dt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,s,o){const l=n?n.previousSibling:t.lastChild;if(s&&(s===o||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),!(s===o||!(s=s.nextSibling)););else{Fl.innerHTML=Qi(r==="svg"?`${e}`:r==="mathml"?`${e}`:e);const a=Fl.content;if(r==="svg"||r==="mathml"){const i=a.firstChild;for(;i.firstChild;)a.appendChild(i.firstChild);a.removeChild(i)}t.insertBefore(a,n)}return[l?l.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Vt="transition",Yn="animation",Bn=Symbol("_vtc"),Xi={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Zi=xe({},_i,Xi),n1=e=>(e.displayName="Transition",e.props=Zi,e),Nn=n1((e,{slots:t})=>f(Gf,ec(e),t)),on=(e,t=[])=>{ne(e)?e.forEach(n=>n(...t)):e&&e(...t)},Hl=e=>e?ne(e)?e.some(t=>t.length>1):e.length>1:!1;function ec(e){const t={};for(const D in e)D in Xi||(t[D]=e[D]);if(e.css===!1)return t;const{name:n="v",type:r,duration:s,enterFromClass:o=`${n}-enter-from`,enterActiveClass:l=`${n}-enter-active`,enterToClass:a=`${n}-enter-to`,appearFromClass:i=o,appearActiveClass:c=l,appearToClass:u=a,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:p=`${n}-leave-active`,leaveToClass:h=`${n}-leave-to`}=e,b=r1(s),y=b&&b[0],w=b&&b[1],{onBeforeEnter:_,onEnter:C,onEnterCancelled:g,onLeave:E,onLeaveCancelled:I,onBeforeAppear:V=_,onAppear:k=C,onAppearCancelled:q=g}=t,M=(D,X,ue)=>{qt(D,X?u:a),qt(D,X?c:l),ue&&ue()},L=(D,X)=>{D._isLeaving=!1,qt(D,d),qt(D,h),qt(D,p),X&&X()},F=D=>(X,ue)=>{const ve=D?k:C,W=()=>M(X,D,ue);on(ve,[X,W]),Vl(()=>{qt(X,D?i:o),Ot(X,D?u:a),Hl(ve)||zl(X,r,y,W)})};return xe(t,{onBeforeEnter(D){on(_,[D]),Ot(D,o),Ot(D,l)},onBeforeAppear(D){on(V,[D]),Ot(D,i),Ot(D,c)},onEnter:F(!1),onAppear:F(!0),onLeave(D,X){D._isLeaving=!0;const ue=()=>L(D,X);Ot(D,d),Ot(D,p),nc(),Vl(()=>{D._isLeaving&&(qt(D,d),Ot(D,h),Hl(E)||zl(D,r,w,ue))}),on(E,[D,ue])},onEnterCancelled(D){M(D,!1),on(g,[D])},onAppearCancelled(D){M(D,!0),on(q,[D])},onLeaveCancelled(D){L(D),on(I,[D])}})}function r1(e){if(e==null)return null;if(Se(e))return[js(e.enter),js(e.leave)];{const t=js(e);return[t,t]}}function js(e){return Xu(e)}function Ot(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Bn]||(e[Bn]=new Set)).add(t)}function qt(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[Bn];n&&(n.delete(t),n.size||(e[Bn]=void 0))}function Vl(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let s1=0;function zl(e,t,n,r){const s=e._endId=++s1,o=()=>{s===e._endId&&r()};if(n!=null)return setTimeout(o,n);const{type:l,timeout:a,propCount:i}=tc(e,t);if(!l)return r();const c=l+"end";let u=0;const d=()=>{e.removeEventListener(c,p),o()},p=h=>{h.target===e&&++u>=i&&d()};setTimeout(()=>{u(n[b]||"").split(", "),s=r(`${Vt}Delay`),o=r(`${Vt}Duration`),l=Ul(s,o),a=r(`${Yn}Delay`),i=r(`${Yn}Duration`),c=Ul(a,i);let u=null,d=0,p=0;t===Vt?l>0&&(u=Vt,d=l,p=o.length):t===Yn?c>0&&(u=Yn,d=c,p=i.length):(d=Math.max(l,c),u=d>0?l>c?Vt:Yn:null,p=u?u===Vt?o.length:i.length:0);const h=u===Vt&&/\b(transform|all)(,|$)/.test(r(`${Vt}Property`).toString());return{type:u,timeout:d,propCount:p,hasTransform:h}}function Ul(e,t){for(;e.lengthql(n)+ql(e[r])))}function ql(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function nc(){return document.body.offsetHeight}function o1(e,t,n){const r=e[Bn];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Wl=Symbol("_vod"),l1=Symbol("_vsh"),a1=Symbol(""),i1=/(^|;)\s*display\s*:/;function c1(e,t,n){const r=e.style,s=Re(n);let o=!1;if(n&&!s){if(t)if(Re(t))for(const l of t.split(";")){const a=l.slice(0,l.indexOf(":")).trim();n[a]==null&&ts(r,a,"")}else for(const l in t)n[l]==null&&ts(r,l,"");for(const l in n)l==="display"&&(o=!0),ts(r,l,n[l])}else if(s){if(t!==n){const l=r[a1];l&&(n+=";"+l),r.cssText=n,o=i1.test(n)}}else t&&e.removeAttribute("style");Wl in e&&(e[Wl]=o?r.display:"",e[l1]&&(r.display="none"))}const Gl=/\s*!important$/;function ts(e,t,n){if(ne(n))n.forEach(r=>ts(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=u1(e,t);Gl.test(n)?e.setProperty(gn(r),n.replace(Gl,""),"important"):e[r]=n}}const Kl=["Webkit","Moz","ms"],Fs={};function u1(e,t){const n=Fs[t];if(n)return n;let r=Ge(t);if(r!=="filter"&&r in e)return Fs[t]=r;r=Cr(r);for(let s=0;sHs||(v1.then(()=>Hs=0),Hs=Date.now());function g1(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;bt(b1(r,n.value),t,5,[r])};return n.value=e,n.attached=m1(),n}function b1(e,t){if(ne(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>s=>!s._stopped&&r&&r(s))}else return t}const ea=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,y1=(e,t,n,r,s,o)=>{const l=s==="svg";t==="class"?o1(e,r,l):t==="style"?c1(e,n,r):Sr(t)?Ro(t)||p1(e,t,n,r,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):_1(e,t,r,l))?(Ql(e,t,r),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Yl(e,t,r,l,o,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!Re(r))?Ql(e,Ge(t),r):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Yl(e,t,r,l))};function _1(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&ea(t)&&re(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const s=e.tagName;if(s==="IMG"||s==="VIDEO"||s==="CANVAS"||s==="SOURCE")return!1}return ea(t)&&Re(n)?!1:t in e}const rc=new WeakMap,sc=new WeakMap,ds=Symbol("_moveCb"),ta=Symbol("_enterCb"),E1=e=>(delete e.props.mode,e),w1=E1({name:"TransitionGroup",props:xe({},Zi,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=Rr(),r=yi();let s,o;return Ai(()=>{if(!s.length)return;const l=e.moveClass||`${e.name||"v"}-move`;if(!T1(s[0].el,n.vnode.el,l))return;s.forEach(C1),s.forEach(A1);const a=s.filter(x1);nc(),a.forEach(i=>{const c=i.el,u=c.style;Ot(c,l),u.transform=u.webkitTransform=u.transitionDuration="";const d=c[ds]=p=>{p&&p.target!==c||(!p||/transform$/.test(p.propertyName))&&(c.removeEventListener("transitionend",d),c[ds]=null,qt(c,l))};c.addEventListener("transitionend",d)})}),()=>{const l=ae(e),a=ec(l);let i=l.tag||Ze;if(s=[],o)for(let c=0;c{a.split(/\s+/).forEach(i=>i&&r.classList.remove(i))}),n.split(/\s+/).forEach(a=>a&&r.classList.add(a)),r.style.display="none";const o=t.nodeType===1?t:t.parentNode;o.appendChild(r);const{hasTransform:l}=tc(r);return o.removeChild(r),l}const k1=xe({patchProp:y1},t1);let Vs,na=!1;function L1(){return Vs=na?Vs:xd(k1),na=!0,Vs}const R1=(...e)=>{const t=L1().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=O1(r);if(s)return n(s,!0,P1(s))},t};function P1(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function O1(e){return Re(e)?document.querySelector(e):e}var I1=["link","meta","script","style","noscript","template"],D1=["title","base"],$1=([e,t,n])=>D1.includes(e)?e:I1.includes(e)?e==="meta"&&t.name?`${e}.${t.name}`:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,Object.entries(t).map(([r,s])=>typeof s=="boolean"?s?[r,""]:null:[r,s]).filter(r=>r!=null).sort(([r],[s])=>r.localeCompare(s)),n]):null,M1=e=>{const t=new Set,n=[];return e.forEach(r=>{const s=$1(r);s&&!t.has(s)&&(t.add(s),n.push(r))}),n},B1=e=>e[0]==="/"?e:`/${e}`,oc=e=>e[e.length-1]==="/"||e.endsWith(".html")?e:`${e}/`,bn=e=>/^(https?:)?\/\//.test(e),N1=/.md((\?|#).*)?$/,Xo=(e,t="/")=>!!(bn(e)||e.startsWith("/")&&!e.startsWith(t)&&!N1.test(e)),_s=e=>/^[a-z][a-z0-9+.-]*:/.test(e),Un=e=>Object.prototype.toString.call(e)==="[object Object]",j1=e=>{const[t,...n]=e.split(/(\?|#)/);if(!t||t.endsWith("/"))return e;let r=t.replace(/(^|\/)README.md$/i,"$1index.html");return r.endsWith(".md")?r=r.substring(0,r.length-3)+".html":r.endsWith(".html")||(r=r+".html"),r.endsWith("/index.html")&&(r=r.substring(0,r.length-10)),r+n.join("")},Zo=e=>e[e.length-1]==="/"?e.slice(0,-1):e,lc=e=>e[0]==="/"?e.slice(1):e,F1=(e,t)=>{const n=Object.keys(e).sort((r,s)=>{const o=s.split("/").length-r.split("/").length;return o!==0?o:s.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"},Ce=e=>typeof e=="string";const H1="modulepreload",V1=function(e){return"/my-docs/"+e},ra={},j=function(t,n,r){let s=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));s=Promise.all(n.map(a=>{if(a=V1(a),a in ra)return;ra[a]=!0;const i=a.endsWith(".css"),c=i?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${a}"]${c}`))return;const u=document.createElement("link");if(u.rel=i?"stylesheet":H1,i||(u.as="script",u.crossOrigin=""),u.href=a,l&&u.setAttribute("nonce",l),document.head.appendChild(u),i)return new Promise((d,p)=>{u.addEventListener("load",d),u.addEventListener("error",()=>p(new Error(`Unable to preload CSS for ${a}`)))})}))}return s.then(()=>t()).catch(o=>{const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o})},z1=JSON.parse("{}"),U1=Object.fromEntries([["/",{loader:()=>j(()=>import("./index.html-Roc1x59k.js"),__vite__mapDeps([0,1])),meta:{t:"主页",i:"home"}}],["/dbs/",{loader:()=>j(()=>import("./index.html-6X9t5qpu.js"),__vite__mapDeps([2,1])),meta:{t:"数据库DB",i:"lightbulb"}}],["/interview/2023.html",{loader:()=>j(()=>import("./2023.html-CZcJbhdh.js"),__vite__mapDeps([3,1])),meta:{t:"2023"}}],["/interview/",{loader:()=>j(()=>import("./index.html-BLJjaEnE.js"),__vite__mapDeps([4,1])),meta:{t:"面试准备",i:"lightbulb"}}],["/java/",{loader:()=>j(()=>import("./index.html-BWMmt9_Q.js"),__vite__mapDeps([5,1])),meta:{t:"Java",i:"lightbulb"}}],["/linux/",{loader:()=>j(()=>import("./index.html-BFkKlz8G.js"),__vite__mapDeps([6,1])),meta:{t:"Linux"}}],["/books/HighPerformanceMySQL/",{loader:()=>j(()=>import("./index.html-3g_tXqhW.js"),__vite__mapDeps([7,1])),meta:{t:"高性能MySQL"}}],["/books/UnderStandingTheJvm/10.%E5%89%8D%E7%AB%AF%E7%BC%96%E8%AF%91%E4%B8%8E%E4%BC%98%E5%8C%96.html",{loader:()=>j(()=>import("./10.前端编译与优化.html-xpAp087Y.js"),__vite__mapDeps([8,1])),meta:{t:"10.前端编译与优化"}}],["/books/UnderStandingTheJvm/11.%E5%90%8E%E7%AB%AF%E7%BC%96%E8%AF%91%E4%B8%8E%E4%BC%98%E5%8C%96.html",{loader:()=>j(()=>import("./11.后端编译与优化.html-Xs_v6BVk.js"),__vite__mapDeps([9,1])),meta:{t:"11.后端编译与优化"}}],["/books/UnderStandingTheJvm/2.Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8.html",{loader:()=>j(()=>import("./2.Java内存区域与内存溢出异常.html-sguZT_xH.js"),__vite__mapDeps([10,1])),meta:{t:"2.Java内存区域与内存溢出异常"}}],["/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8A%EF%BC%89.html",{loader:()=>j(()=>import("./3.垃圾收集器与内存分配策略(上).html-DOojsy_g.js"),__vite__mapDeps([11,1])),meta:{t:"3.垃圾收集器与内存分配策略(上)"}}],["/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8B%EF%BC%89.html",{loader:()=>j(()=>import("./3.垃圾收集器与内存分配策略(下).html-CvPGtoPK.js"),__vite__mapDeps([12,1])),meta:{t:"3.垃圾收集器与内存分配策略(下)"}}],["/books/UnderStandingTheJvm/4.%E8%99%9A%E6%8B%9F%E6%9C%BA%E6%80%A7%E8%83%BD%E7%9B%91%E6%8E%A7%E3%80%81%E6%95%85%E9%9A%9C%E5%A4%84%E7%90%86%E5%B7%A5%E5%85%B7.html",{loader:()=>j(()=>import("./4.虚拟机性能监控、故障处理工具.html-BURKEJxN.js"),__vite__mapDeps([13,1])),meta:{t:"4.虚拟机性能监控、故障处理工具"}}],["/books/UnderStandingTheJvm/5.%E8%B0%83%E4%BC%98%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E6%88%98.html",{loader:()=>j(()=>import("./5.调优案例分析与实战.html-DdFwZo66.js"),__vite__mapDeps([14,1])),meta:{t:"5.调优案例分析与实战"}}],["/books/UnderStandingTheJvm/6.%E7%B1%BB%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%EF%BC%88%E4%B8%8A%EF%BC%89.html",{loader:()=>j(()=>import("./6.类文件结构(上).html-bMezDIIg.js"),__vite__mapDeps([15,1])),meta:{t:"6.类文件结构(上)"}}],["/books/UnderStandingTheJvm/6.%E7%B1%BB%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%EF%BC%88%E4%B8%8B%EF%BC%89.html",{loader:()=>j(()=>import("./6.类文件结构(下).html-BR-9LCfV.js"),__vite__mapDeps([16,1])),meta:{t:"6.类文件结构(下)"}}],["/books/UnderStandingTheJvm/7.%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6.html",{loader:()=>j(()=>import("./7.虚拟机类加载机制.html-D6upEAca.js"),__vite__mapDeps([17,1])),meta:{t:"7.虚拟机类加载机制"}}],["/books/UnderStandingTheJvm/8.%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%AD%97%E8%8A%82%E7%A0%81%E6%89%A7%E8%A1%8C%E5%BC%95%E6%93%8E.html",{loader:()=>j(()=>import("./8.虚拟机字节码执行引擎.html-CHO3Bc_W.js"),__vite__mapDeps([18,1])),meta:{t:"8.虚拟机字节码执行引擎"}}],["/books/UnderStandingTheJvm/9.%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%8F%8A%E6%89%A7%E8%A1%8C%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%A1%88%E4%BE%8B%E4%B8%8E%E5%AE%9E%E6%88%98.html",{loader:()=>j(()=>import("./9.类加载及执行子系统的案例与实战.html-BEJe7Ncf.js"),__vite__mapDeps([19,1])),meta:{t:"9.类加载及执行子系统的案例与实战"}}],["/books/UnderStandingTheJvm/",{loader:()=>j(()=>import("./index.html-je-vdzFE.js"),__vite__mapDeps([20,1])),meta:{t:"深入理解Java虚拟机"}}],["/dbs/elasticsearch/basis.html",{loader:()=>j(()=>import("./basis.html-BeJJBQWv.js"),__vite__mapDeps([21,1])),meta:{t:"基础"}}],["/dbs/mysql/dump.html",{loader:()=>j(()=>import("./dump.html-CgS7EZ3W.js"),__vite__mapDeps([22,1])),meta:{t:"dump",O:2}}],["/dbs/mysql/logs.html",{loader:()=>j(()=>import("./logs.html-CteEoTLH.js"),__vite__mapDeps([23,1])),meta:{t:"log",O:1}}],["/dbs/redis/0.redis7.html",{loader:()=>j(()=>import("./0.redis7.html-D8dTCNAM.js"),__vite__mapDeps([24,1])),meta:{t:"开始",O:1}}],["/dbs/redis/1.%E5%8D%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html",{loader:()=>j(()=>import("./1.十大数据类型.html-DetU5pF8.js"),__vite__mapDeps([25,1])),meta:{t:"十大数据类型",O:2}}],["/dbs/redis/2.%E6%8C%81%E4%B9%85%E5%8C%96.html",{loader:()=>j(()=>import("./2.持久化.html-Cj-6GcFe.js"),__vite__mapDeps([26,1])),meta:{t:"持久化",O:3}}],["/dbs/redis/3.%E4%BA%8B%E5%8A%A1.html",{loader:()=>j(()=>import("./3.事务.html-D0FP5PwK.js"),__vite__mapDeps([27,1])),meta:{t:"事务",O:4}}],["/dbs/redis/4.%E7%AE%A1%E9%81%93.html",{loader:()=>j(()=>import("./4.管道.html-B3H0WI8v.js"),__vite__mapDeps([28,1])),meta:{t:"管道",O:5}}],["/dbs/redis/5.%E5%8F%91%E5%B8%83%E4%B8%8E%E8%AE%A2%E9%98%85.html",{loader:()=>j(()=>import("./5.发布与订阅.html-DGZVcgfp.js"),__vite__mapDeps([29,1])),meta:{t:"发布与订阅",O:6}}],["/dbs/redis/6.%E5%A4%8D%E5%88%B6.html",{loader:()=>j(()=>import("./6.复制.html-BXO5kx7f.js"),__vite__mapDeps([30,1])),meta:{t:"复制",O:7}}],["/dbs/redis/7.%E5%93%A8%E5%85%B5.html",{loader:()=>j(()=>import("./7.哨兵.html-BgjEihqV.js"),__vite__mapDeps([31,1])),meta:{t:"哨兵",O:8}}],["/java/SpringCloud/",{loader:()=>j(()=>import("./index.html-CAhMCF-2.js"),__vite__mapDeps([32,1])),meta:{t:"SpringCloud"}}],["/java/SpringCloudAlibaba/",{loader:()=>j(()=>import("./index.html-WY8-PpYT.js"),__vite__mapDeps([33,1])),meta:{t:"SpringCloudAlibaba"}}],["/java/basis/",{loader:()=>j(()=>import("./index.html-CDxqUD9S.js"),__vite__mapDeps([34,1])),meta:{t:"基础"}}],["/java/basis/basis.html",{loader:()=>j(()=>import("./basis.html-wEn3fTf7.js"),__vite__mapDeps([35,1])),meta:{t:"暂且不知道叫什么"}}],["/java/basis/no.html",{loader:()=>j(()=>import("./no.html-Bggz8Mf2.js"),__vite__mapDeps([36,1])),meta:{t:"乱锅炖"}}],["/java/jvm/",{loader:()=>j(()=>import("./index.html-BjxWTrKZ.js"),__vite__mapDeps([37,1])),meta:{t:"JVM"}}],["/java/jvm/basis.html",{loader:()=>j(()=>import("./basis.html-6Q8zK8Bd.js"),__vite__mapDeps([38,1])),meta:{t:"基础todo"}}],["/java/rocketmq/",{loader:()=>j(()=>import("./index.html-WkXnwUCZ.js"),__vite__mapDeps([39,1])),meta:{t:"rocket",i:"lightbulb"}}],["/java/rocketmq/basis.html",{loader:()=>j(()=>import("./basis.html-Jvc2997A.js"),__vite__mapDeps([40,1])),meta:{t:"docker 启动!"}}],["/java/spring/",{loader:()=>j(()=>import("./index.html-Bito5Fo8.js"),__vite__mapDeps([41,1])),meta:{t:"Spring"}}],["/java/spring/SpringSecurity.html",{loader:()=>j(()=>import("./SpringSecurity.html-B-4pbTrz.js"),__vite__mapDeps([42,1])),meta:{t:""}}],["/java/spring/demo.html",{loader:()=>j(()=>import("./demo.html-_U9HoCj_.js"),__vite__mapDeps([43,1])),meta:{t:"Spring"}}],["/java/thread/",{loader:()=>j(()=>import("./index.html-C4Md3jw-.js"),__vite__mapDeps([44,1])),meta:{t:"多线程"}}],["/java/thread/basis.html",{loader:()=>j(()=>import("./basis.html-DHIr7USm.js"),__vite__mapDeps([45,1])),meta:{t:"基础"}}],["/leetcode/daily/",{loader:()=>j(()=>import("./index.html-CQfPShe9.js"),__vite__mapDeps([46,1])),meta:{t:"每日一题",i:"lightbulb"}}],["/leetcode/leetcode-75/",{loader:()=>j(()=>import("./index.html-aNDDDL4S.js"),__vite__mapDeps([47,1])),meta:{t:"LeetCode 75",i:"lightbulb"}}],["/leetcode/leetcode-75/string-compression.html",{loader:()=>j(()=>import("./string-compression.html-IQPW5i69.js"),__vite__mapDeps([48,1])),meta:{t:"压缩字符串"}}],["/linux/archLinux/",{loader:()=>j(()=>import("./index.html-BVtf9Xg2.js"),__vite__mapDeps([49,1])),meta:{t:"ArchLinux"}}],["/linux/archLinux/install.html",{loader:()=>j(()=>import("./install.html-DfRGkxGy.js"),__vite__mapDeps([50,1])),meta:{t:"安装"}}],["/linux/basis/",{loader:()=>j(()=>import("./index.html-2TimMen1.js"),__vite__mapDeps([51,1])),meta:{t:"基础"}}],["/linux/basis/basis.html",{loader:()=>j(()=>import("./basis.html-CbUDOSOT.js"),__vite__mapDeps([52,1])),meta:{t:"基础"}}],["/linux/software/",{loader:()=>j(()=>import("./index.html-DpohJUce.js"),__vite__mapDeps([53,1])),meta:{t:"软件"}}],["/linux/software/arthas.html",{loader:()=>j(()=>import("./arthas.html-DqXfZ7t8.js"),__vite__mapDeps([54,1])),meta:{t:"arthas"}}],["/linux/software/basis.html",{loader:()=>j(()=>import("./basis.html-BxbtaanI.js"),__vite__mapDeps([55,1])),meta:{t:"基础工具"}}],["/linux/software/drone.html",{loader:()=>j(()=>import("./drone.html-CbMyU2PH.js"),__vite__mapDeps([56,1])),meta:{t:"drone"}}],["/linux/software/nginx.html",{loader:()=>j(()=>import("./nginx.html-DVjCG_xK.js"),__vite__mapDeps([57,1])),meta:{t:""}}],["/linux/software/podman-compose.html",{loader:()=>j(()=>import("./podman-compose.html-Bm6gmrrd.js"),__vite__mapDeps([58,1])),meta:{t:"podman-compose"}}],["/linux/software/podman.html",{loader:()=>j(()=>import("./podman.html-CQmzNTKG.js"),__vite__mapDeps([59,1])),meta:{t:"Podman"}}],["/java/SpringCloudAlibaba/dubbo/basis.html",{loader:()=>j(()=>import("./basis.html-D-H00zGl.js"),__vite__mapDeps([60,1])),meta:{t:"基础"}}],["/java/SpringCloudAlibaba/nacos/basis.html",{loader:()=>j(()=>import("./basis.html-XXSTSKO_.js"),__vite__mapDeps([61,1])),meta:{t:"基础"}}],["/java/SpringCloudAlibaba/seata/basis.html",{loader:()=>j(()=>import("./basis.html-zu40gkWN.js"),__vite__mapDeps([62,1])),meta:{t:"基础"}}],["/java/SpringCloudAlibaba/sentinel/basis.html",{loader:()=>j(()=>import("./basis.html-Ds0kWP9C.js"),__vite__mapDeps([63,1])),meta:{t:"基础"}}],["/404.html",{loader:()=>j(()=>import("./404.html-B4CKWbuD.js"),__vite__mapDeps([64,1])),meta:{t:""}}],["/books/",{loader:()=>j(()=>import("./index.html-Dlv9CWZJ.js"),__vite__mapDeps([65,1])),meta:{t:"Books"}}],["/dbs/elasticsearch/",{loader:()=>j(()=>import("./index.html-CbO2TWOo.js"),__vite__mapDeps([66,1])),meta:{t:"Elasticsearch"}}],["/dbs/mysql/",{loader:()=>j(()=>import("./index.html-BOlVANES.js"),__vite__mapDeps([67,1])),meta:{t:"Mysql"}}],["/dbs/redis/",{loader:()=>j(()=>import("./index.html-CMw-ULdl.js"),__vite__mapDeps([68,1])),meta:{t:"Redis"}}],["/leetcode/",{loader:()=>j(()=>import("./index.html-DG4ffYH3.js"),__vite__mapDeps([69,1])),meta:{t:"Leetcode"}}],["/java/SpringCloudAlibaba/dubbo/",{loader:()=>j(()=>import("./index.html-DJf5TL8z.js"),__vite__mapDeps([70,1])),meta:{t:"Dubbo"}}],["/java/SpringCloudAlibaba/nacos/",{loader:()=>j(()=>import("./index.html-Cgvzxj0k.js"),__vite__mapDeps([71,1])),meta:{t:"Nacos"}}],["/java/SpringCloudAlibaba/seata/",{loader:()=>j(()=>import("./index.html-CZl1qWB6.js"),__vite__mapDeps([72,1])),meta:{t:"Seata"}}],["/java/SpringCloudAlibaba/sentinel/",{loader:()=>j(()=>import("./index.html-rLTebBeh.js"),__vite__mapDeps([73,1])),meta:{t:"Sentinel"}}]]);/*! +**/let fo;const jl=typeof window<"u"&&window.trustedTypes;if(jl)try{fo=jl.createPolicy("vue",{createHTML:e=>e})}catch{}const Qi=fo?e=>fo.createHTML(e):e=>e,Zd="http://www.w3.org/2000/svg",e1="http://www.w3.org/1998/Math/MathML",Dt=typeof document<"u"?document:null,Fl=Dt&&Dt.createElement("template"),t1={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const s=t==="svg"?Dt.createElementNS(Zd,e):t==="mathml"?Dt.createElementNS(e1,e):n?Dt.createElement(e,{is:n}):Dt.createElement(e);return e==="select"&&r&&r.multiple!=null&&s.setAttribute("multiple",r.multiple),s},createText:e=>Dt.createTextNode(e),createComment:e=>Dt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Dt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,s,o){const l=n?n.previousSibling:t.lastChild;if(s&&(s===o||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),!(s===o||!(s=s.nextSibling)););else{Fl.innerHTML=Qi(r==="svg"?`${e}`:r==="mathml"?`${e}`:e);const a=Fl.content;if(r==="svg"||r==="mathml"){const i=a.firstChild;for(;i.firstChild;)a.appendChild(i.firstChild);a.removeChild(i)}t.insertBefore(a,n)}return[l?l.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Vt="transition",Yn="animation",Bn=Symbol("_vtc"),Xi={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Zi=xe({},_i,Xi),n1=e=>(e.displayName="Transition",e.props=Zi,e),Nn=n1((e,{slots:t})=>f(Gf,ec(e),t)),on=(e,t=[])=>{ne(e)?e.forEach(n=>n(...t)):e&&e(...t)},Hl=e=>e?ne(e)?e.some(t=>t.length>1):e.length>1:!1;function ec(e){const t={};for(const D in e)D in Xi||(t[D]=e[D]);if(e.css===!1)return t;const{name:n="v",type:r,duration:s,enterFromClass:o=`${n}-enter-from`,enterActiveClass:l=`${n}-enter-active`,enterToClass:a=`${n}-enter-to`,appearFromClass:i=o,appearActiveClass:c=l,appearToClass:u=a,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:p=`${n}-leave-active`,leaveToClass:h=`${n}-leave-to`}=e,b=r1(s),y=b&&b[0],w=b&&b[1],{onBeforeEnter:_,onEnter:C,onEnterCancelled:g,onLeave:E,onLeaveCancelled:I,onBeforeAppear:V=_,onAppear:k=C,onAppearCancelled:q=g}=t,M=(D,X,ue)=>{qt(D,X?u:a),qt(D,X?c:l),ue&&ue()},L=(D,X)=>{D._isLeaving=!1,qt(D,d),qt(D,h),qt(D,p),X&&X()},F=D=>(X,ue)=>{const ve=D?k:C,W=()=>M(X,D,ue);on(ve,[X,W]),Vl(()=>{qt(X,D?i:o),Ot(X,D?u:a),Hl(ve)||zl(X,r,y,W)})};return xe(t,{onBeforeEnter(D){on(_,[D]),Ot(D,o),Ot(D,l)},onBeforeAppear(D){on(V,[D]),Ot(D,i),Ot(D,c)},onEnter:F(!1),onAppear:F(!0),onLeave(D,X){D._isLeaving=!0;const ue=()=>L(D,X);Ot(D,d),Ot(D,p),nc(),Vl(()=>{D._isLeaving&&(qt(D,d),Ot(D,h),Hl(E)||zl(D,r,w,ue))}),on(E,[D,ue])},onEnterCancelled(D){M(D,!1),on(g,[D])},onAppearCancelled(D){M(D,!0),on(q,[D])},onLeaveCancelled(D){L(D),on(I,[D])}})}function r1(e){if(e==null)return null;if(Se(e))return[js(e.enter),js(e.leave)];{const t=js(e);return[t,t]}}function js(e){return Xu(e)}function Ot(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Bn]||(e[Bn]=new Set)).add(t)}function qt(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[Bn];n&&(n.delete(t),n.size||(e[Bn]=void 0))}function Vl(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let s1=0;function zl(e,t,n,r){const s=e._endId=++s1,o=()=>{s===e._endId&&r()};if(n!=null)return setTimeout(o,n);const{type:l,timeout:a,propCount:i}=tc(e,t);if(!l)return r();const c=l+"end";let u=0;const d=()=>{e.removeEventListener(c,p),o()},p=h=>{h.target===e&&++u>=i&&d()};setTimeout(()=>{u(n[b]||"").split(", "),s=r(`${Vt}Delay`),o=r(`${Vt}Duration`),l=Ul(s,o),a=r(`${Yn}Delay`),i=r(`${Yn}Duration`),c=Ul(a,i);let u=null,d=0,p=0;t===Vt?l>0&&(u=Vt,d=l,p=o.length):t===Yn?c>0&&(u=Yn,d=c,p=i.length):(d=Math.max(l,c),u=d>0?l>c?Vt:Yn:null,p=u?u===Vt?o.length:i.length:0);const h=u===Vt&&/\b(transform|all)(,|$)/.test(r(`${Vt}Property`).toString());return{type:u,timeout:d,propCount:p,hasTransform:h}}function Ul(e,t){for(;e.lengthql(n)+ql(e[r])))}function ql(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function nc(){return document.body.offsetHeight}function o1(e,t,n){const r=e[Bn];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Wl=Symbol("_vod"),l1=Symbol("_vsh"),a1=Symbol(""),i1=/(^|;)\s*display\s*:/;function c1(e,t,n){const r=e.style,s=Re(n);let o=!1;if(n&&!s){if(t)if(Re(t))for(const l of t.split(";")){const a=l.slice(0,l.indexOf(":")).trim();n[a]==null&&ts(r,a,"")}else for(const l in t)n[l]==null&&ts(r,l,"");for(const l in n)l==="display"&&(o=!0),ts(r,l,n[l])}else if(s){if(t!==n){const l=r[a1];l&&(n+=";"+l),r.cssText=n,o=i1.test(n)}}else t&&e.removeAttribute("style");Wl in e&&(e[Wl]=o?r.display:"",e[l1]&&(r.display="none"))}const Gl=/\s*!important$/;function ts(e,t,n){if(ne(n))n.forEach(r=>ts(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=u1(e,t);Gl.test(n)?e.setProperty(gn(r),n.replace(Gl,""),"important"):e[r]=n}}const Kl=["Webkit","Moz","ms"],Fs={};function u1(e,t){const n=Fs[t];if(n)return n;let r=Ge(t);if(r!=="filter"&&r in e)return Fs[t]=r;r=Cr(r);for(let s=0;sHs||(v1.then(()=>Hs=0),Hs=Date.now());function g1(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;bt(b1(r,n.value),t,5,[r])};return n.value=e,n.attached=m1(),n}function b1(e,t){if(ne(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>s=>!s._stopped&&r&&r(s))}else return t}const ea=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,y1=(e,t,n,r,s,o)=>{const l=s==="svg";t==="class"?o1(e,r,l):t==="style"?c1(e,n,r):Sr(t)?Ro(t)||p1(e,t,n,r,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):_1(e,t,r,l))?(Ql(e,t,r),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Yl(e,t,r,l,o,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!Re(r))?Ql(e,Ge(t),r):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Yl(e,t,r,l))};function _1(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&ea(t)&&re(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const s=e.tagName;if(s==="IMG"||s==="VIDEO"||s==="CANVAS"||s==="SOURCE")return!1}return ea(t)&&Re(n)?!1:t in e}const rc=new WeakMap,sc=new WeakMap,ds=Symbol("_moveCb"),ta=Symbol("_enterCb"),E1=e=>(delete e.props.mode,e),w1=E1({name:"TransitionGroup",props:xe({},Zi,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=Rr(),r=yi();let s,o;return Ai(()=>{if(!s.length)return;const l=e.moveClass||`${e.name||"v"}-move`;if(!T1(s[0].el,n.vnode.el,l))return;s.forEach(C1),s.forEach(A1);const a=s.filter(x1);nc(),a.forEach(i=>{const c=i.el,u=c.style;Ot(c,l),u.transform=u.webkitTransform=u.transitionDuration="";const d=c[ds]=p=>{p&&p.target!==c||(!p||/transform$/.test(p.propertyName))&&(c.removeEventListener("transitionend",d),c[ds]=null,qt(c,l))};c.addEventListener("transitionend",d)})}),()=>{const l=ae(e),a=ec(l);let i=l.tag||Ze;if(s=[],o)for(let c=0;c{a.split(/\s+/).forEach(i=>i&&r.classList.remove(i))}),n.split(/\s+/).forEach(a=>a&&r.classList.add(a)),r.style.display="none";const o=t.nodeType===1?t:t.parentNode;o.appendChild(r);const{hasTransform:l}=tc(r);return o.removeChild(r),l}const k1=xe({patchProp:y1},t1);let Vs,na=!1;function L1(){return Vs=na?Vs:xd(k1),na=!0,Vs}const R1=(...e)=>{const t=L1().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=O1(r);if(s)return n(s,!0,P1(s))},t};function P1(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function O1(e){return Re(e)?document.querySelector(e):e}var I1=["link","meta","script","style","noscript","template"],D1=["title","base"],$1=([e,t,n])=>D1.includes(e)?e:I1.includes(e)?e==="meta"&&t.name?`${e}.${t.name}`:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,Object.entries(t).map(([r,s])=>typeof s=="boolean"?s?[r,""]:null:[r,s]).filter(r=>r!=null).sort(([r],[s])=>r.localeCompare(s)),n]):null,M1=e=>{const t=new Set,n=[];return e.forEach(r=>{const s=$1(r);s&&!t.has(s)&&(t.add(s),n.push(r))}),n},B1=e=>e[0]==="/"?e:`/${e}`,oc=e=>e[e.length-1]==="/"||e.endsWith(".html")?e:`${e}/`,bn=e=>/^(https?:)?\/\//.test(e),N1=/.md((\?|#).*)?$/,Xo=(e,t="/")=>!!(bn(e)||e.startsWith("/")&&!e.startsWith(t)&&!N1.test(e)),_s=e=>/^[a-z][a-z0-9+.-]*:/.test(e),Un=e=>Object.prototype.toString.call(e)==="[object Object]",j1=e=>{const[t,...n]=e.split(/(\?|#)/);if(!t||t.endsWith("/"))return e;let r=t.replace(/(^|\/)README.md$/i,"$1index.html");return r.endsWith(".md")?r=r.substring(0,r.length-3)+".html":r.endsWith(".html")||(r=r+".html"),r.endsWith("/index.html")&&(r=r.substring(0,r.length-10)),r+n.join("")},Zo=e=>e[e.length-1]==="/"?e.slice(0,-1):e,lc=e=>e[0]==="/"?e.slice(1):e,F1=(e,t)=>{const n=Object.keys(e).sort((r,s)=>{const o=s.split("/").length-r.split("/").length;return o!==0?o:s.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"},Ce=e=>typeof e=="string";const H1="modulepreload",V1=function(e){return"/my-docs/"+e},ra={},j=function(t,n,r){let s=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));s=Promise.all(n.map(a=>{if(a=V1(a),a in ra)return;ra[a]=!0;const i=a.endsWith(".css"),c=i?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${a}"]${c}`))return;const u=document.createElement("link");if(u.rel=i?"stylesheet":H1,i||(u.as="script",u.crossOrigin=""),u.href=a,l&&u.setAttribute("nonce",l),document.head.appendChild(u),i)return new Promise((d,p)=>{u.addEventListener("load",d),u.addEventListener("error",()=>p(new Error(`Unable to preload CSS for ${a}`)))})}))}return s.then(()=>t()).catch(o=>{const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o})},z1=JSON.parse("{}"),U1=Object.fromEntries([["/",{loader:()=>j(()=>import("./index.html-Dlf95nvk.js"),__vite__mapDeps([0,1])),meta:{t:"主页",i:"home"}}],["/interview/2023.html",{loader:()=>j(()=>import("./2023.html-ArLS9RPY.js"),__vite__mapDeps([2,1])),meta:{t:"2023"}}],["/interview/",{loader:()=>j(()=>import("./index.html-DXlT849A.js"),__vite__mapDeps([3,1])),meta:{t:"面试准备",i:"lightbulb"}}],["/dbs/",{loader:()=>j(()=>import("./index.html-C6tUEycf.js"),__vite__mapDeps([4,1])),meta:{t:"数据库DB",i:"lightbulb"}}],["/java/",{loader:()=>j(()=>import("./index.html-DYp-5F_m.js"),__vite__mapDeps([5,1])),meta:{t:"Java",i:"lightbulb"}}],["/linux/",{loader:()=>j(()=>import("./index.html-BmE5rtpR.js"),__vite__mapDeps([6,1])),meta:{t:"Linux"}}],["/books/HighPerformanceMySQL/",{loader:()=>j(()=>import("./index.html-wv-PNDDj.js"),__vite__mapDeps([7,1])),meta:{t:"高性能MySQL"}}],["/books/UnderStandingTheJvm/10.%E5%89%8D%E7%AB%AF%E7%BC%96%E8%AF%91%E4%B8%8E%E4%BC%98%E5%8C%96.html",{loader:()=>j(()=>import("./10.前端编译与优化.html-CIsptAV2.js"),__vite__mapDeps([8,1])),meta:{t:"10.前端编译与优化"}}],["/books/UnderStandingTheJvm/11.%E5%90%8E%E7%AB%AF%E7%BC%96%E8%AF%91%E4%B8%8E%E4%BC%98%E5%8C%96.html",{loader:()=>j(()=>import("./11.后端编译与优化.html-BXVBRKzU.js"),__vite__mapDeps([9,1])),meta:{t:"11.后端编译与优化"}}],["/books/UnderStandingTheJvm/2.Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8.html",{loader:()=>j(()=>import("./2.Java内存区域与内存溢出异常.html-DjsBGsDH.js"),__vite__mapDeps([10,1])),meta:{t:"2.Java内存区域与内存溢出异常"}}],["/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8A%EF%BC%89.html",{loader:()=>j(()=>import("./3.垃圾收集器与内存分配策略(上).html-CIb-O2tW.js"),__vite__mapDeps([11,1])),meta:{t:"3.垃圾收集器与内存分配策略(上)"}}],["/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8B%EF%BC%89.html",{loader:()=>j(()=>import("./3.垃圾收集器与内存分配策略(下).html-Dxlni7rM.js"),__vite__mapDeps([12,1])),meta:{t:"3.垃圾收集器与内存分配策略(下)"}}],["/books/UnderStandingTheJvm/4.%E8%99%9A%E6%8B%9F%E6%9C%BA%E6%80%A7%E8%83%BD%E7%9B%91%E6%8E%A7%E3%80%81%E6%95%85%E9%9A%9C%E5%A4%84%E7%90%86%E5%B7%A5%E5%85%B7.html",{loader:()=>j(()=>import("./4.虚拟机性能监控、故障处理工具.html-D4U1I6eG.js"),__vite__mapDeps([13,1])),meta:{t:"4.虚拟机性能监控、故障处理工具"}}],["/books/UnderStandingTheJvm/5.%E8%B0%83%E4%BC%98%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E6%88%98.html",{loader:()=>j(()=>import("./5.调优案例分析与实战.html-MlkdMvhD.js"),__vite__mapDeps([14,1])),meta:{t:"5.调优案例分析与实战"}}],["/books/UnderStandingTheJvm/6.%E7%B1%BB%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%EF%BC%88%E4%B8%8A%EF%BC%89.html",{loader:()=>j(()=>import("./6.类文件结构(上).html-BtxCAsyy.js"),__vite__mapDeps([15,1])),meta:{t:"6.类文件结构(上)"}}],["/books/UnderStandingTheJvm/6.%E7%B1%BB%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%EF%BC%88%E4%B8%8B%EF%BC%89.html",{loader:()=>j(()=>import("./6.类文件结构(下).html-CHYdIYsk.js"),__vite__mapDeps([16,1])),meta:{t:"6.类文件结构(下)"}}],["/books/UnderStandingTheJvm/7.%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6.html",{loader:()=>j(()=>import("./7.虚拟机类加载机制.html-BjfyysKr.js"),__vite__mapDeps([17,1])),meta:{t:"7.虚拟机类加载机制"}}],["/books/UnderStandingTheJvm/8.%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%AD%97%E8%8A%82%E7%A0%81%E6%89%A7%E8%A1%8C%E5%BC%95%E6%93%8E.html",{loader:()=>j(()=>import("./8.虚拟机字节码执行引擎.html-Cjs8katk.js"),__vite__mapDeps([18,1])),meta:{t:"8.虚拟机字节码执行引擎"}}],["/books/UnderStandingTheJvm/9.%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%8F%8A%E6%89%A7%E8%A1%8C%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%A1%88%E4%BE%8B%E4%B8%8E%E5%AE%9E%E6%88%98.html",{loader:()=>j(()=>import("./9.类加载及执行子系统的案例与实战.html-DnCZ_kpU.js"),__vite__mapDeps([19,1])),meta:{t:"9.类加载及执行子系统的案例与实战"}}],["/books/UnderStandingTheJvm/",{loader:()=>j(()=>import("./index.html-BnG1jZ_a.js"),__vite__mapDeps([20,1])),meta:{t:"深入理解Java虚拟机"}}],["/dbs/elasticsearch/basis.html",{loader:()=>j(()=>import("./basis.html-DZPqHWrC.js"),__vite__mapDeps([21,1])),meta:{t:"基础"}}],["/dbs/mysql/dump.html",{loader:()=>j(()=>import("./dump.html-upIgPA-c.js"),__vite__mapDeps([22,1])),meta:{t:"dump",O:2}}],["/dbs/mysql/logs.html",{loader:()=>j(()=>import("./logs.html-B49m8Ki1.js"),__vite__mapDeps([23,1])),meta:{t:"log",O:1}}],["/dbs/redis/0.redis7.html",{loader:()=>j(()=>import("./0.redis7.html-DIJ1znYd.js"),__vite__mapDeps([24,1])),meta:{t:"开始",O:1}}],["/dbs/redis/1.%E5%8D%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html",{loader:()=>j(()=>import("./1.十大数据类型.html-M6yAsNAG.js"),__vite__mapDeps([25,1])),meta:{t:"十大数据类型",O:2}}],["/dbs/redis/2.%E6%8C%81%E4%B9%85%E5%8C%96.html",{loader:()=>j(()=>import("./2.持久化.html-Btm7zx-d.js"),__vite__mapDeps([26,1])),meta:{t:"持久化",O:3}}],["/dbs/redis/3.%E4%BA%8B%E5%8A%A1.html",{loader:()=>j(()=>import("./3.事务.html-CpmGsXBd.js"),__vite__mapDeps([27,1])),meta:{t:"事务",O:4}}],["/dbs/redis/4.%E7%AE%A1%E9%81%93.html",{loader:()=>j(()=>import("./4.管道.html-CWD-xPd8.js"),__vite__mapDeps([28,1])),meta:{t:"管道",O:5}}],["/dbs/redis/5.%E5%8F%91%E5%B8%83%E4%B8%8E%E8%AE%A2%E9%98%85.html",{loader:()=>j(()=>import("./5.发布与订阅.html-Crzq7Y5K.js"),__vite__mapDeps([29,1])),meta:{t:"发布与订阅",O:6}}],["/dbs/redis/6.%E5%A4%8D%E5%88%B6.html",{loader:()=>j(()=>import("./6.复制.html-CH73emLp.js"),__vite__mapDeps([30,1])),meta:{t:"复制",O:7}}],["/dbs/redis/7.%E5%93%A8%E5%85%B5.html",{loader:()=>j(()=>import("./7.哨兵.html-C92G7akQ.js"),__vite__mapDeps([31,1])),meta:{t:"哨兵",O:8}}],["/java/SpringCloud/",{loader:()=>j(()=>import("./index.html-DSsHnpqp.js"),__vite__mapDeps([32,1])),meta:{t:"SpringCloud"}}],["/java/SpringCloudAlibaba/",{loader:()=>j(()=>import("./index.html-m-iOeLa_.js"),__vite__mapDeps([33,1])),meta:{t:"SpringCloudAlibaba"}}],["/java/basis/",{loader:()=>j(()=>import("./index.html-BmNTlG-Z.js"),__vite__mapDeps([34,1])),meta:{t:"基础"}}],["/java/basis/basis.html",{loader:()=>j(()=>import("./basis.html-2ahAkI4f.js"),__vite__mapDeps([35,1])),meta:{t:"暂且不知道叫什么"}}],["/java/basis/no.html",{loader:()=>j(()=>import("./no.html-DSfEWxWZ.js"),__vite__mapDeps([36,1])),meta:{t:"乱锅炖"}}],["/java/jvm/",{loader:()=>j(()=>import("./index.html-t50OORIi.js"),__vite__mapDeps([37,1])),meta:{t:"JVM"}}],["/java/jvm/basis.html",{loader:()=>j(()=>import("./basis.html-DUj1Wnj7.js"),__vite__mapDeps([38,1])),meta:{t:"基础todo"}}],["/java/rocketmq/",{loader:()=>j(()=>import("./index.html-BjuNRCNw.js"),__vite__mapDeps([39,1])),meta:{t:"rocket",i:"lightbulb"}}],["/java/rocketmq/basis.html",{loader:()=>j(()=>import("./basis.html-95B3ZLlj.js"),__vite__mapDeps([40,1])),meta:{t:"docker 启动!"}}],["/java/spring/",{loader:()=>j(()=>import("./index.html-Cz8jDxAY.js"),__vite__mapDeps([41,1])),meta:{t:"Spring"}}],["/java/spring/SpringSecurity.html",{loader:()=>j(()=>import("./SpringSecurity.html-BdbZDA5T.js"),__vite__mapDeps([42,1])),meta:{t:""}}],["/java/spring/demo.html",{loader:()=>j(()=>import("./demo.html-CkMNEXQC.js"),__vite__mapDeps([43,1])),meta:{t:"Spring"}}],["/java/thread/",{loader:()=>j(()=>import("./index.html-DhqTU2xX.js"),__vite__mapDeps([44,1])),meta:{t:"多线程"}}],["/java/thread/basis.html",{loader:()=>j(()=>import("./basis.html-GlRiLsmg.js"),__vite__mapDeps([45,1])),meta:{t:"基础"}}],["/leetcode/daily/",{loader:()=>j(()=>import("./index.html-BqzKiupE.js"),__vite__mapDeps([46,1])),meta:{t:"每日一题",i:"lightbulb"}}],["/leetcode/leetcode-75/",{loader:()=>j(()=>import("./index.html-D8OfGtcT.js"),__vite__mapDeps([47,1])),meta:{t:"LeetCode 75",i:"lightbulb"}}],["/leetcode/leetcode-75/string-compression.html",{loader:()=>j(()=>import("./string-compression.html-pFNlH1Er.js"),__vite__mapDeps([48,1])),meta:{t:"压缩字符串"}}],["/linux/archLinux/",{loader:()=>j(()=>import("./index.html-Caayfztk.js"),__vite__mapDeps([49,1])),meta:{t:"ArchLinux"}}],["/linux/archLinux/install.html",{loader:()=>j(()=>import("./install.html-Dug0d3yu.js"),__vite__mapDeps([50,1])),meta:{t:"安装"}}],["/linux/basis/",{loader:()=>j(()=>import("./index.html-uEv93DTy.js"),__vite__mapDeps([51,1])),meta:{t:"基础"}}],["/linux/basis/basis.html",{loader:()=>j(()=>import("./basis.html-2JCN_GSw.js"),__vite__mapDeps([52,1])),meta:{t:"基础"}}],["/linux/software/",{loader:()=>j(()=>import("./index.html-CMFNipnT.js"),__vite__mapDeps([53,1])),meta:{t:"软件"}}],["/linux/software/arthas.html",{loader:()=>j(()=>import("./arthas.html-BmuamiK8.js"),__vite__mapDeps([54,1])),meta:{t:"arthas"}}],["/linux/software/basis.html",{loader:()=>j(()=>import("./basis.html-DQim-pLK.js"),__vite__mapDeps([55,1])),meta:{t:"基础工具"}}],["/linux/software/drone.html",{loader:()=>j(()=>import("./drone.html-D1mwj-od.js"),__vite__mapDeps([56,1])),meta:{t:"drone"}}],["/linux/software/nginx.html",{loader:()=>j(()=>import("./nginx.html-BXoNRXpL.js"),__vite__mapDeps([57,1])),meta:{t:""}}],["/linux/software/podman-compose.html",{loader:()=>j(()=>import("./podman-compose.html-49_0XMa0.js"),__vite__mapDeps([58,1])),meta:{t:"podman-compose"}}],["/linux/software/podman.html",{loader:()=>j(()=>import("./podman.html-CPwV8nQQ.js"),__vite__mapDeps([59,1])),meta:{t:"Podman"}}],["/java/SpringCloudAlibaba/dubbo/basis.html",{loader:()=>j(()=>import("./basis.html-BLw4eSnF.js"),__vite__mapDeps([60,1])),meta:{t:"基础"}}],["/java/SpringCloudAlibaba/nacos/basis.html",{loader:()=>j(()=>import("./basis.html-02RvDNho.js"),__vite__mapDeps([61,1])),meta:{t:"基础"}}],["/java/SpringCloudAlibaba/seata/basis.html",{loader:()=>j(()=>import("./basis.html-CV6VoMyY.js"),__vite__mapDeps([62,1])),meta:{t:"基础"}}],["/java/SpringCloudAlibaba/sentinel/basis.html",{loader:()=>j(()=>import("./basis.html-Cl860v1g.js"),__vite__mapDeps([63,1])),meta:{t:"基础"}}],["/404.html",{loader:()=>j(()=>import("./404.html-CkT6DnzW.js"),__vite__mapDeps([64,1])),meta:{t:""}}],["/books/",{loader:()=>j(()=>import("./index.html-Bk17tqnU.js"),__vite__mapDeps([65,1])),meta:{t:"Books"}}],["/dbs/elasticsearch/",{loader:()=>j(()=>import("./index.html-DIJfQi65.js"),__vite__mapDeps([66,1])),meta:{t:"Elasticsearch"}}],["/dbs/mysql/",{loader:()=>j(()=>import("./index.html-Dd2UFmj8.js"),__vite__mapDeps([67,1])),meta:{t:"Mysql"}}],["/dbs/redis/",{loader:()=>j(()=>import("./index.html-Dy81h_sK.js"),__vite__mapDeps([68,1])),meta:{t:"Redis"}}],["/leetcode/",{loader:()=>j(()=>import("./index.html-YCjvOQL7.js"),__vite__mapDeps([69,1])),meta:{t:"Leetcode"}}],["/java/SpringCloudAlibaba/dubbo/",{loader:()=>j(()=>import("./index.html-B9KtETue.js"),__vite__mapDeps([70,1])),meta:{t:"Dubbo"}}],["/java/SpringCloudAlibaba/nacos/",{loader:()=>j(()=>import("./index.html-BgmHQsum.js"),__vite__mapDeps([71,1])),meta:{t:"Nacos"}}],["/java/SpringCloudAlibaba/seata/",{loader:()=>j(()=>import("./index.html-9CuuwwcO.js"),__vite__mapDeps([72,1])),meta:{t:"Seata"}}],["/java/SpringCloudAlibaba/sentinel/",{loader:()=>j(()=>import("./index.html-NBqlJgDk.js"),__vite__mapDeps([73,1])),meta:{t:"Sentinel"}}]]);/*! * vue-router v4.4.5 * (c) 2024 Eduardo San Martin Morote * @license MIT */const Cn=typeof document<"u";function ac(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function q1(e){return e.__esModule||e[Symbol.toStringTag]==="Module"||e.default&&ac(e.default)}const de=Object.assign;function zs(e,t){const n={};for(const r in t){const s=t[r];n[r]=yt(s)?s.map(e):e(s)}return n}const ar=()=>{},yt=Array.isArray,ic=/#/g,W1=/&/g,G1=/\//g,K1=/=/g,J1=/\?/g,cc=/\+/g,Y1=/%5B/g,Q1=/%5D/g,uc=/%5E/g,X1=/%60/g,fc=/%7B/g,Z1=/%7C/g,dc=/%7D/g,ep=/%20/g;function el(e){return encodeURI(""+e).replace(Z1,"|").replace(Y1,"[").replace(Q1,"]")}function tp(e){return el(e).replace(fc,"{").replace(dc,"}").replace(uc,"^")}function po(e){return el(e).replace(cc,"%2B").replace(ep,"+").replace(ic,"%23").replace(W1,"%26").replace(X1,"`").replace(fc,"{").replace(dc,"}").replace(uc,"^")}function np(e){return po(e).replace(K1,"%3D")}function rp(e){return el(e).replace(ic,"%23").replace(J1,"%3F")}function sp(e){return e==null?"":rp(e).replace(G1,"%2F")}function vr(e){try{return decodeURIComponent(""+e)}catch{}return""+e}const op=/\/$/,lp=e=>e.replace(op,"");function Us(e,t,n="/"){let r,s={},o="",l="";const a=t.indexOf("#");let i=t.indexOf("?");return a=0&&(i=-1),i>-1&&(r=t.slice(0,i),o=t.slice(i+1,a>-1?a:t.length),s=e(o)),a>-1&&(r=r||t.slice(0,a),l=t.slice(a,t.length)),r=up(r??t,n),{fullPath:r+(o&&"?")+o+l,path:r,query:s,hash:vr(l)}}function ap(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function sa(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function ip(e,t,n){const r=t.matched.length-1,s=n.matched.length-1;return r>-1&&r===s&&jn(t.matched[r],n.matched[s])&&pc(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function jn(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function pc(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!cp(e[n],t[n]))return!1;return!0}function cp(e,t){return yt(e)?oa(e,t):yt(t)?oa(t,e):e===t}function oa(e,t){return yt(t)?e.length===t.length&&e.every((n,r)=>n===t[r]):e.length===1&&e[0]===t}function up(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),r=e.split("/"),s=r[r.length-1];(s===".."||s===".")&&r.push("");let o=n.length-1,l,a;for(l=0;l1&&o--;else break;return n.slice(0,o).join("/")+"/"+r.slice(l).join("/")}const It={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};var mr;(function(e){e.pop="pop",e.push="push"})(mr||(mr={}));var ir;(function(e){e.back="back",e.forward="forward",e.unknown=""})(ir||(ir={}));function fp(e){if(!e)if(Cn){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),lp(e)}const dp=/^[^#]+#/;function pp(e,t){return e.replace(dp,"#")+t}function hp(e,t){const n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}const Es=()=>({left:window.scrollX,top:window.scrollY});function vp(e){let t;if("el"in e){const n=e.el,r=typeof n=="string"&&n.startsWith("#"),s=typeof n=="string"?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!s)return;t=hp(s,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function la(e,t){return(history.state?history.state.position-t:-1)+e}const ho=new Map;function mp(e,t){ho.set(e,t)}function gp(e){const t=ho.get(e);return ho.delete(e),t}let bp=()=>location.protocol+"//"+location.host;function hc(e,t){const{pathname:n,search:r,hash:s}=t,o=e.indexOf("#");if(o>-1){let a=s.includes(e.slice(o))?e.slice(o).length:1,i=s.slice(a);return i[0]!=="/"&&(i="/"+i),sa(i,"")}return sa(n,e)+r+s}function yp(e,t,n,r){let s=[],o=[],l=null;const a=({state:p})=>{const h=hc(e,location),b=n.value,y=t.value;let w=0;if(p){if(n.value=h,t.value=p,l&&l===b){l=null;return}w=y?p.position-y.position:0}else r(h);s.forEach(_=>{_(n.value,b,{delta:w,type:mr.pop,direction:w?w>0?ir.forward:ir.back:ir.unknown})})};function i(){l=n.value}function c(p){s.push(p);const h=()=>{const b=s.indexOf(p);b>-1&&s.splice(b,1)};return o.push(h),h}function u(){const{history:p}=window;p.state&&p.replaceState(de({},p.state,{scroll:Es()}),"")}function d(){for(const p of o)p();o=[],window.removeEventListener("popstate",a),window.removeEventListener("beforeunload",u)}return window.addEventListener("popstate",a),window.addEventListener("beforeunload",u,{passive:!0}),{pauseListeners:i,listen:c,destroy:d}}function aa(e,t,n,r=!1,s=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:s?Es():null}}function _p(e){const{history:t,location:n}=window,r={value:hc(e,n)},s={value:t.state};s.value||o(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function o(i,c,u){const d=e.indexOf("#"),p=d>-1?(n.host&&document.querySelector("base")?e:e.slice(d))+i:bp()+e+i;try{t[u?"replaceState":"pushState"](c,"",p),s.value=c}catch(h){console.error(h),n[u?"replace":"assign"](p)}}function l(i,c){const u=de({},t.state,aa(s.value.back,i,s.value.forward,!0),c,{position:s.value.position});o(i,u,!0),r.value=i}function a(i,c){const u=de({},s.value,t.state,{forward:i,scroll:Es()});o(u.current,u,!0);const d=de({},aa(r.value,i,null),{position:u.position+1},c);o(i,d,!1),r.value=i}return{location:r,state:s,push:a,replace:l}}function Ep(e){e=fp(e);const t=_p(e),n=yp(e,t.state,t.location,t.replace);function r(o,l=!0){l||n.pauseListeners(),history.go(o)}const s=de({location:"",base:e,go:r,createHref:pp.bind(null,e)},t,n);return Object.defineProperty(s,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(s,"state",{enumerable:!0,get:()=>t.state.value}),s}function wp(e){return typeof e=="string"||e&&typeof e=="object"}function vc(e){return typeof e=="string"||typeof e=="symbol"}const mc=Symbol("");var ia;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(ia||(ia={}));function Fn(e,t){return de(new Error,{type:e,[mc]:!0},t)}function Pt(e,t){return e instanceof Error&&mc in e&&(t==null||!!(e.type&t))}const ca="[^/]+?",Sp={sensitive:!1,strict:!1,start:!0,end:!0},Cp=/[.+*?^${}()[\]/\\]/g;function Ap(e,t){const n=de({},Sp,t),r=[];let s=n.start?"^":"";const o=[];for(const c of e){const u=c.length?[]:[90];n.strict&&!c.length&&(s+="/");for(let d=0;dt.length?t.length===1&&t[0]===80?1:-1:0}function gc(e,t){let n=0;const r=e.score,s=t.score;for(;n0&&t[t.length-1]<0}const Tp={type:0,value:""},kp=/[a-zA-Z0-9_]/;function Lp(e){if(!e)return[[]];if(e==="/")return[[Tp]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(h){throw new Error(`ERR (${n})/"${c}": ${h}`)}let n=0,r=n;const s=[];let o;function l(){o&&s.push(o),o=[]}let a=0,i,c="",u="";function d(){c&&(n===0?o.push({type:0,value:c}):n===1||n===2||n===3?(o.length>1&&(i==="*"||i==="+")&&t(`A repeatable param (${c}) must be alone in its segment. eg: '/:ids+.`),o.push({type:1,value:c,regexp:u,repeatable:i==="*"||i==="+",optional:i==="*"||i==="?"})):t("Invalid state to consume buffer"),c="")}function p(){c+=i}for(;a{l(g)}:ar}function l(d){if(vc(d)){const p=r.get(d);p&&(r.delete(d),n.splice(n.indexOf(p),1),p.children.forEach(l),p.alias.forEach(l))}else{const p=n.indexOf(d);p>-1&&(n.splice(p,1),d.record.name&&r.delete(d.record.name),d.children.forEach(l),d.alias.forEach(l))}}function a(){return n}function i(d){const p=Dp(d,n);n.splice(p,0,d),d.record.name&&!pa(d)&&r.set(d.record.name,d)}function c(d,p){let h,b={},y,w;if("name"in d&&d.name){if(h=r.get(d.name),!h)throw Fn(1,{location:d});w=h.record.name,b=de(fa(p.params,h.keys.filter(g=>!g.optional).concat(h.parent?h.parent.keys.filter(g=>g.optional):[]).map(g=>g.name)),d.params&&fa(d.params,h.keys.map(g=>g.name))),y=h.stringify(b)}else if(d.path!=null)y=d.path,h=n.find(g=>g.re.test(y)),h&&(b=h.parse(y),w=h.record.name);else{if(h=p.name?r.get(p.name):n.find(g=>g.re.test(p.path)),!h)throw Fn(1,{location:d,currentLocation:p});w=h.record.name,b=de({},p.params,d.params),y=h.stringify(b)}const _=[];let C=h;for(;C;)_.unshift(C.record),C=C.parent;return{name:w,path:y,params:b,matched:_,meta:Ip(_)}}e.forEach(d=>o(d));function u(){n.length=0,r.clear()}return{addRoute:o,resolve:c,removeRoute:l,clearRoutes:u,getRoutes:a,getRecordMatcher:s}}function fa(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}function da(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:Op(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function Op(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const r in e.components)t[r]=typeof n=="object"?n[r]:n;return t}function pa(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Ip(e){return e.reduce((t,n)=>de(t,n.meta),{})}function ha(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];return n}function Dp(e,t){let n=0,r=t.length;for(;n!==r;){const o=n+r>>1;gc(e,t[o])<0?r=o:n=o+1}const s=$p(e);return s&&(r=t.lastIndexOf(s,r-1)),r}function $p(e){let t=e;for(;t=t.parent;)if(bc(t)&&gc(e,t)===0)return t}function bc({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Mp(e){const t={};if(e===""||e==="?")return t;const r=(e[0]==="?"?e.slice(1):e).split("&");for(let s=0;so&&po(o)):[r&&po(r)]).forEach(o=>{o!==void 0&&(t+=(t.length?"&":"")+n,o!=null&&(t+="="+o))})}return t}function Bp(e){const t={};for(const n in e){const r=e[n];r!==void 0&&(t[n]=yt(r)?r.map(s=>s==null?null:""+s):r==null?r:""+r)}return t}const Np=Symbol(""),ma=Symbol(""),ws=Symbol(""),tl=Symbol(""),vo=Symbol("");function Qn(){let e=[];function t(r){return e.push(r),()=>{const s=e.indexOf(r);s>-1&&e.splice(s,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function Jt(e,t,n,r,s,o=l=>l()){const l=r&&(r.enterCallbacks[s]=r.enterCallbacks[s]||[]);return()=>new Promise((a,i)=>{const c=p=>{p===!1?i(Fn(4,{from:n,to:t})):p instanceof Error?i(p):wp(p)?i(Fn(2,{from:t,to:p})):(l&&r.enterCallbacks[s]===l&&typeof p=="function"&&l.push(p),a())},u=o(()=>e.call(r&&r.instances[s],t,n,c));let d=Promise.resolve(u);e.length<3&&(d=d.then(c)),d.catch(p=>i(p))})}function qs(e,t,n,r,s=o=>o()){const o=[];for(const l of e)for(const a in l.components){let i=l.components[a];if(!(t!=="beforeRouteEnter"&&!l.instances[a]))if(ac(i)){const u=(i.__vccOpts||i)[t];u&&o.push(Jt(u,n,r,l,a,s))}else{let c=i();o.push(()=>c.then(u=>{if(!u)throw new Error(`Couldn't resolve component "${a}" at "${l.path}"`);const d=q1(u)?u.default:u;l.mods[a]=u,l.components[a]=d;const h=(d.__vccOpts||d)[t];return h&&Jt(h,n,r,l,a,s)()}))}}return o}function ga(e){const t=Me(ws),n=Me(tl),r=A(()=>{const i=dn(e.to);return t.resolve(i)}),s=A(()=>{const{matched:i}=r.value,{length:c}=i,u=i[c-1],d=n.matched;if(!u||!d.length)return-1;const p=d.findIndex(jn.bind(null,u));if(p>-1)return p;const h=ba(i[c-2]);return c>1&&ba(u)===h&&d[d.length-1].path!==h?d.findIndex(jn.bind(null,i[c-2])):p}),o=A(()=>s.value>-1&&Vp(n.params,r.value.params)),l=A(()=>s.value>-1&&s.value===n.matched.length-1&&pc(n.params,r.value.params));function a(i={}){return Hp(i)?t[dn(e.replace)?"replace":"push"](dn(e.to)).catch(ar):Promise.resolve()}return{route:r,href:A(()=>r.value.href),isActive:o,isExactActive:l,navigate:a}}const jp=J({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:ga,setup(e,{slots:t}){const n=Ar(ga(e)),{options:r}=Me(ws),s=A(()=>({[ya(e.activeClass,r.linkActiveClass,"router-link-active")]:n.isActive,[ya(e.exactActiveClass,r.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const o=t.default&&t.default(n);return e.custom?o:f("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:s.value},o)}}}),Fp=jp;function Hp(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Vp(e,t){for(const n in t){const r=t[n],s=e[n];if(typeof r=="string"){if(r!==s)return!1}else if(!yt(s)||s.length!==r.length||r.some((o,l)=>o!==s[l]))return!1}return!0}function ba(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const ya=(e,t,n)=>e??t??n,zp=J({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const r=Me(vo),s=A(()=>e.route||r.value),o=Me(ma,0),l=A(()=>{let c=dn(o);const{matched:u}=s.value;let d;for(;(d=u[c])&&!d.components;)c++;return c}),a=A(()=>s.value.matched[l.value]);Dn(ma,A(()=>l.value+1)),Dn(Np,a),Dn(vo,s);const i=Q();return ie(()=>[i.value,a.value,e.name],([c,u,d],[p,h,b])=>{u&&(u.instances[d]=c,h&&h!==u&&c&&c===p&&(u.leaveGuards.size||(u.leaveGuards=h.leaveGuards),u.updateGuards.size||(u.updateGuards=h.updateGuards))),c&&u&&(!h||!jn(u,h)||!p)&&(u.enterCallbacks[d]||[]).forEach(y=>y(c))},{flush:"post"}),()=>{const c=s.value,u=e.name,d=a.value,p=d&&d.components[u];if(!p)return _a(n.default,{Component:p,route:c});const h=d.props[u],b=h?h===!0?c.params:typeof h=="function"?h(c):h:null,w=f(p,de({},b,t,{onVnodeUnmounted:_=>{_.component.isUnmounted&&(d.instances[u]=null)},ref:i}));return _a(n.default,{Component:w,route:c})||w}}});function _a(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Up=zp;function qp(e){const t=Pp(e.routes,e),n=e.parseQuery||Mp,r=e.stringifyQuery||va,s=e.history,o=Qn(),l=Qn(),a=Qn(),i=$e(It);let c=It;Cn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const u=zs.bind(null,x=>""+x),d=zs.bind(null,sp),p=zs.bind(null,vr);function h(x,z){let N,K;return vc(x)?(N=t.getRecordMatcher(x),K=z):K=x,t.addRoute(K,N)}function b(x){const z=t.getRecordMatcher(x);z&&t.removeRoute(z)}function y(){return t.getRoutes().map(x=>x.record)}function w(x){return!!t.getRecordMatcher(x)}function _(x,z){if(z=de({},z||i.value),typeof x=="string"){const m=Us(n,x,z.path),S=t.resolve({path:m.path},z),R=s.createHref(m.fullPath);return de(m,S,{params:p(S.params),hash:vr(m.hash),redirectedFrom:void 0,href:R})}let N;if(x.path!=null)N=de({},x,{path:Us(n,x.path,z.path).path});else{const m=de({},x.params);for(const S in m)m[S]==null&&delete m[S];N=de({},x,{params:d(m)}),z.params=d(z.params)}const K=t.resolve(N,z),oe=x.hash||"";K.params=u(p(K.params));const he=ap(r,de({},x,{hash:tp(oe),path:K.path})),v=s.createHref(he);return de({fullPath:he,hash:oe,query:r===va?Bp(x.query):x.query||{}},K,{redirectedFrom:void 0,href:v})}function C(x){return typeof x=="string"?Us(n,x,i.value.path):de({},x)}function g(x,z){if(c!==x)return Fn(8,{from:z,to:x})}function E(x){return k(x)}function I(x){return E(de(C(x),{replace:!0}))}function V(x){const z=x.matched[x.matched.length-1];if(z&&z.redirect){const{redirect:N}=z;let K=typeof N=="function"?N(x):N;return typeof K=="string"&&(K=K.includes("?")||K.includes("#")?K=C(K):{path:K},K.params={}),de({query:x.query,hash:x.hash,params:K.path!=null?{}:x.params},K)}}function k(x,z){const N=c=_(x),K=i.value,oe=x.state,he=x.force,v=x.replace===!0,m=V(N);if(m)return k(de(C(m),{state:typeof m=="object"?de({},oe,m.state):oe,force:he,replace:v}),z||N);const S=N;S.redirectedFrom=z;let R;return!he&&ip(r,K,N)&&(R=Fn(16,{to:S,from:K}),ot(K,K,!0,!1)),(R?Promise.resolve(R):L(S,K)).catch(T=>Pt(T)?Pt(T,2)?T:Et(T):G(T,S,K)).then(T=>{if(T){if(Pt(T,2))return k(de({replace:v},C(T.to),{state:typeof T.to=="object"?de({},oe,T.to.state):oe,force:he}),z||S)}else T=D(S,K,!0,v,oe);return F(S,K,T),T})}function q(x,z){const N=g(x,z);return N?Promise.reject(N):Promise.resolve()}function M(x){const z=Lt.values().next().value;return z&&typeof z.runWithContext=="function"?z.runWithContext(x):x()}function L(x,z){let N;const[K,oe,he]=Wp(x,z);N=qs(K.reverse(),"beforeRouteLeave",x,z);for(const m of K)m.leaveGuards.forEach(S=>{N.push(Jt(S,x,z))});const v=q.bind(null,x,z);return N.push(v),Ne(N).then(()=>{N=[];for(const m of o.list())N.push(Jt(m,x,z));return N.push(v),Ne(N)}).then(()=>{N=qs(oe,"beforeRouteUpdate",x,z);for(const m of oe)m.updateGuards.forEach(S=>{N.push(Jt(S,x,z))});return N.push(v),Ne(N)}).then(()=>{N=[];for(const m of he)if(m.beforeEnter)if(yt(m.beforeEnter))for(const S of m.beforeEnter)N.push(Jt(S,x,z));else N.push(Jt(m.beforeEnter,x,z));return N.push(v),Ne(N)}).then(()=>(x.matched.forEach(m=>m.enterCallbacks={}),N=qs(he,"beforeRouteEnter",x,z,M),N.push(v),Ne(N))).then(()=>{N=[];for(const m of l.list())N.push(Jt(m,x,z));return N.push(v),Ne(N)}).catch(m=>Pt(m,8)?m:Promise.reject(m))}function F(x,z,N){a.list().forEach(K=>M(()=>K(x,z,N)))}function D(x,z,N,K,oe){const he=g(x,z);if(he)return he;const v=z===It,m=Cn?history.state:{};N&&(K||v?s.replace(x.fullPath,de({scroll:v&&m&&m.scroll},oe)):s.push(x.fullPath,oe)),i.value=x,ot(x,z,N,v),Et()}let X;function ue(){X||(X=s.listen((x,z,N)=>{if(!wt.listening)return;const K=_(x),oe=V(K);if(oe){k(de(oe,{replace:!0}),K).catch(ar);return}c=K;const he=i.value;Cn&&mp(la(he.fullPath,N.delta),Es()),L(K,he).catch(v=>Pt(v,12)?v:Pt(v,2)?(k(v.to,K).then(m=>{Pt(m,20)&&!N.delta&&N.type===mr.pop&&s.go(-1,!1)}).catch(ar),Promise.reject()):(N.delta&&s.go(-N.delta,!1),G(v,K,he))).then(v=>{v=v||D(K,he,!1),v&&(N.delta&&!Pt(v,8)?s.go(-N.delta,!1):N.type===mr.pop&&Pt(v,20)&&s.go(-1,!1)),F(K,he,v)}).catch(ar)}))}let ve=Qn(),W=Qn(),ee;function G(x,z,N){Et(x);const K=W.list();return K.length?K.forEach(oe=>oe(x,z,N)):console.error(x),Promise.reject(x)}function pe(){return ee&&i.value!==It?Promise.resolve():new Promise((x,z)=>{ve.add([x,z])})}function Et(x){return ee||(ee=!x,ue(),ve.list().forEach(([z,N])=>x?N(x):z()),ve.reset()),x}function ot(x,z,N,K){const{scrollBehavior:oe}=e;if(!Cn||!oe)return Promise.resolve();const he=!N&&gp(la(x.fullPath,0))||(K||!N)&&history.state&&history.state.scroll||null;return Nt().then(()=>oe(x,z,he)).then(v=>v&&vp(v)).catch(v=>G(v,x,z))}const Oe=x=>s.go(x);let Ke;const Lt=new Set,wt={currentRoute:i,listening:!0,addRoute:h,removeRoute:b,clearRoutes:t.clearRoutes,hasRoute:w,getRoutes:y,resolve:_,options:e,push:E,replace:I,go:Oe,back:()=>Oe(-1),forward:()=>Oe(1),beforeEach:o.add,beforeResolve:l.add,afterEach:a.add,onError:W.add,isReady:pe,install(x){const z=this;x.component("RouterLink",Fp),x.component("RouterView",Up),x.config.globalProperties.$router=z,Object.defineProperty(x.config.globalProperties,"$route",{enumerable:!0,get:()=>dn(i)}),Cn&&!Ke&&i.value===It&&(Ke=!0,E(s.location).catch(oe=>{}));const N={};for(const oe in It)Object.defineProperty(N,oe,{get:()=>i.value[oe],enumerable:!0});x.provide(ws,z),x.provide(tl,ui(N)),x.provide(vo,i);const K=x.unmount;Lt.add(x),x.unmount=function(){Lt.delete(x),Lt.size<1&&(c=It,X&&X(),X=null,i.value=It,Ke=!1,ee=!1),K()}}};function Ne(x){return x.reduce((z,N)=>z.then(()=>M(N)),Promise.resolve())}return wt}function Wp(e,t){const n=[],r=[],s=[],o=Math.max(t.matched.length,e.matched.length);for(let l=0;ljn(c,a))?r.push(a):n.push(a));const i=e.matched[l];i&&(t.matched.find(c=>jn(c,i))||s.push(i))}return[n,r,s]}function qn(){return Me(ws)}function nn(e){return Me(tl)}var nl=Symbol(""),_t=()=>{const e=Me(nl);if(!e)throw new Error("useClientData() is called without provider.");return e},Gp=()=>_t().pageComponent,Te=()=>_t().pageData,we=()=>_t().pageFrontmatter,Kp=()=>_t().pageHead,yc=()=>_t().pageLang,Jp=()=>_t().pageLayout,Ir=()=>_t().routeLocale,Yp=()=>_t().routePath,Qp=()=>_t().routes,_c=()=>_t().siteData,rl=()=>_t().siteLocaleData,Xp=Symbol(""),mo=$e(z1),gr=$e(U1),Ec=e=>{const t=j1(e);if(gr.value[t])return t;const n=encodeURI(t);return gr.value[n]?n:mo.value[t]||mo.value[n]||t},Zt=e=>{const t=Ec(e),n=gr.value[t]??{...gr.value["/404.html"],notFound:!0};return{path:t,notFound:!1,...n}},Ss=J({name:"ClientOnly",setup(e,t){const n=Q(!1);return Ee(()=>{n.value=!0}),()=>{var r,s;return n.value?(s=(r=t.slots).default)==null?void 0:s.call(r):null}}}),wc=J({name:"Content",props:{path:{type:String,required:!1,default:""}},setup(e){const t=Gp(),n=A(()=>{if(!e.path)return t.value;const r=Zt(e.path);return Zf(()=>r.loader().then(({comp:s})=>s))});return()=>f(n.value)}}),kt=(e={})=>e,De=e=>bn(e)?e:`/my-docs/${lc(e)}`,Zp=e=>{if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget){const t=e.currentTarget.getAttribute("target");if(t!=null&&t.match(/\b_blank\b/i))return}return e.preventDefault(),!0}},rt=({active:e=!1,activeClass:t="route-link-active",to:n,...r},{slots:s})=>{var i;const o=qn(),l=Ec(n),a=l.startsWith("#")||l.startsWith("?")?l:De(l);return f("a",{...r,class:["route-link",{[t]:e}],href:a,onClick:(c={})=>{Zp(c)?o.push(n).catch():Promise.resolve()}},(i=s.default)==null?void 0:i.call(s))};rt.displayName="RouteLink";rt.props={active:Boolean,activeClass:String,to:String};var e0="Layout",t0="en-US",ln=Ar({resolveLayouts:e=>e.reduce((t,n)=>({...t,...n.layouts}),{}),resolvePageHead:(e,t,n)=>{const r=Ce(t.description)?t.description:n.description,s=[...Array.isArray(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:r}]];return M1(s)},resolvePageHeadTitle:(e,t)=>[e.title,t.title].filter(n=>!!n).join(" | "),resolvePageLang:(e,t)=>e.lang||t.lang||t0,resolvePageLayout:(e,t)=>{const n=Ce(e.frontmatter.layout)?e.frontmatter.layout:e0;if(!t[n])throw new Error(`[vuepress] Cannot resolve layout: ${n}`);return t[n]},resolveRouteLocale:(e,t)=>F1(e,t),resolveSiteLocaleData:(e,t)=>{var n;return{...e,...e.locales[t],head:[...((n=e.locales[t])==null?void 0:n.head)??[],...e.head??[]]}}});const n0={},Dr=e=>{const t=Ir();return A(()=>e[t.value]??{})};var tt=Uint8Array,Tn=Uint16Array,r0=Int32Array,Sc=new tt([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),Cc=new tt([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),s0=new tt([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Ac=function(e,t){for(var n=new Tn(31),r=0;r<31;++r)n[r]=t+=1<>1|(_e&21845)<<1;zt=(zt&52428)>>2|(zt&13107)<<2,zt=(zt&61680)>>4|(zt&3855)<<4,go[_e]=((zt&65280)>>8|(zt&255)<<8)>>1}var cr=function(e,t,n){for(var r=e.length,s=0,o=new Tn(t);s>i]=c}else for(a=new Tn(r),s=0;s>15-e[s]);return a},$r=new tt(288);for(var _e=0;_e<144;++_e)$r[_e]=8;for(var _e=144;_e<256;++_e)$r[_e]=9;for(var _e=256;_e<280;++_e)$r[_e]=7;for(var _e=280;_e<288;++_e)$r[_e]=8;var kc=new tt(32);for(var _e=0;_e<32;++_e)kc[_e]=5;var i0=cr($r,9,1),c0=cr(kc,5,1),Ws=function(e){for(var t=e[0],n=1;nt&&(t=e[n]);return t},ht=function(e,t,n){var r=t/8|0;return(e[r]|e[r+1]<<8)>>(t&7)&n},Gs=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(t&7)},u0=function(e){return(e+7)/8|0},Lc=function(e,t,n){return(t==null||t<0)&&(t=0),(n==null||n>e.length)&&(n=e.length),new tt(e.subarray(t,n))},f0=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],it=function(e,t,n){var r=new Error(t||f0[e]);if(r.code=e,Error.captureStackTrace&&Error.captureStackTrace(r,it),!n)throw r;return r},d0=function(e,t,n,r){var s=e.length,o=0;if(!s||t.f&&!t.l)return n||new tt(0);var l=!n,a=l||t.i!=2,i=t.i;l&&(n=new tt(s*3));var c=function(oe){var he=n.length;if(oe>he){var v=new tt(Math.max(he*2,oe));v.set(n),n=v}},u=t.f||0,d=t.p||0,p=t.b||0,h=t.l,b=t.d,y=t.m,w=t.n,_=s*8;do{if(!h){u=ht(e,d,1);var C=ht(e,d+1,3);if(d+=3,C)if(C==1)h=i0,b=c0,y=9,w=5;else if(C==2){var V=ht(e,d,31)+257,k=ht(e,d+10,15)+4,q=V+ht(e,d+5,31)+1;d+=14;for(var M=new tt(q),L=new tt(19),F=0;F>4;if(g<16)M[F++]=g;else{var W=0,ee=0;for(g==16?(ee=3+ht(e,d,3),d+=2,W=M[F-1]):g==17?(ee=3+ht(e,d,7),d+=3):g==18&&(ee=11+ht(e,d,127),d+=7);ee--;)M[F++]=W}}var G=M.subarray(0,V),pe=M.subarray(V);y=Ws(G),w=Ws(pe),h=cr(G,y,1),b=cr(pe,w,1)}else it(1);else{var g=u0(d)+4,E=e[g-4]|e[g-3]<<8,I=g+E;if(I>s){i&&it(0);break}a&&c(p+E),n.set(e.subarray(g,I),p),t.b=p+=E,t.p=d=I*8,t.f=u;continue}if(d>_){i&&it(0);break}}a&&c(p+131072);for(var Et=(1<>4;if(d+=W&15,d>_){i&&it(0);break}if(W||it(2),Ke<256)n[p++]=Ke;else if(Ke==256){Oe=d,h=null;break}else{var Lt=Ke-254;if(Ke>264){var F=Ke-257,wt=Sc[F];Lt=ht(e,d,(1<>4;Ne||it(3),d+=Ne&15;var pe=a0[x];if(x>3){var wt=Cc[x];pe+=Gs(e,d)&(1<_){i&&it(0);break}a&&c(p+131072);var z=p+Lt;if(p>4>7||(e[0]<<8|e[1])%31)&&it(6,"invalid zlib data"),(e[1]>>5&1)==+!t&&it(6,"invalid zlib data: "+(e[1]&32?"need":"unexpected")+" dictionary"),(e[1]>>3&4)+2};function v0(e,t){return d0(e.subarray(h0(e,t),-4),{i:2},t,t)}var bo=typeof TextDecoder<"u"&&new TextDecoder,m0=0;try{bo.decode(p0,{stream:!0}),m0=1}catch{}var g0=function(e){for(var t="",n=0;;){var r=e[n++],s=(r>127)+(r>223)+(r>239);if(n+s>e.length)return{s:t,r:Lc(e,n-1)};s?s==3?(r=((r&15)<<18|(e[n++]&63)<<12|(e[n++]&63)<<6|e[n++]&63)-65536,t+=String.fromCharCode(55296|r>>10,56320|r&1023)):s&1?t+=String.fromCharCode((r&31)<<6|e[n++]&63):t+=String.fromCharCode((r&15)<<12|(e[n++]&63)<<6|e[n++]&63):t+=String.fromCharCode(r)}};function b0(e,t){{for(var n=new tt(e.length),r=0;r{const t=atob(e);return y0(v0(b0(t)))},dt=(e,t)=>{var r;const n=(r=(t==null?void 0:t._instance)||Rr())==null?void 0:r.appContext.components;return n?e in n||Ge(e)in n||Cr(Ge(e))in n:!1},Rc=e=>typeof e<"u",Ks=e=>typeof e=="number",yo=Array.isArray,Hn=(e,t)=>Ce(e)&&e.startsWith(t),_0=(e,t)=>Ce(e)&&e.endsWith(t),E0=Object.entries,yn=Object.keys,w0=e=>{if(e){if(typeof e=="number")return new Date(e);const t=Date.parse(e.toString());if(!Number.isNaN(t))return new Date(t)}return null},Cs=e=>Hn(e,"/"),S0="http://.",C0=(e,t)=>{if(Cs(e)||typeof t!="string")return Zt(e);const n=t.slice(0,t.lastIndexOf("/"));return Zt(new URL(`${n}/${encodeURI(e)}`,S0).pathname)},Pc=e=>new Promise(t=>setTimeout(t,e));function Wn(e){return Ja()?(lf(e),!0):!1}function Be(e){return typeof e=="function"?e():dn(e)}const Mr=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const A0=Object.prototype.toString,x0=e=>A0.call(e)==="[object Object]",mn=()=>{},wa=T0();function T0(){var e,t;return Mr&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((t=window==null?void 0:window.navigator)==null?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function sl(e,t){function n(...r){return new Promise((s,o)=>{Promise.resolve(e(()=>t.apply(this,r),{fn:t,thisArg:this,args:r})).then(s).catch(o)})}return n}const Oc=e=>e();function k0(e,t={}){let n,r,s=mn;const o=a=>{clearTimeout(a),s(),s=mn};return a=>{const i=Be(e),c=Be(t.maxWait);return n&&o(n),i<=0||c!==void 0&&c<=0?(r&&(o(r),r=null),Promise.resolve(a())):new Promise((u,d)=>{s=t.rejectOnCancel?d:u,c&&!r&&(r=setTimeout(()=>{n&&o(n),r=null,u(a())},c)),n=setTimeout(()=>{r&&o(r),r=null,u(a())},i)})}}function L0(...e){let t=0,n,r=!0,s=mn,o,l,a,i,c;!Ae(e[0])&&typeof e[0]=="object"?{delay:l,trailing:a=!0,leading:i=!0,rejectOnCancel:c=!1}=e[0]:[l,a=!0,i=!0,c=!1]=e;const u=()=>{n&&(clearTimeout(n),n=void 0,s(),s=mn)};return p=>{const h=Be(l),b=Date.now()-t,y=()=>o=p();return u(),h<=0?(t=Date.now(),y()):(b>h&&(i||!r)?(t=Date.now(),y()):a&&(o=new Promise((w,_)=>{s=c?_:w,n=setTimeout(()=>{t=Date.now(),r=!0,w(y()),u()},Math.max(0,h-b))})),!i&&!n&&(n=setTimeout(()=>r=!0,h)),r=!1,o)}}function R0(e=Oc){const t=Q(!0);function n(){t.value=!1}function r(){t.value=!0}const s=(...o)=>{t.value&&e(...o)};return{isActive:xr(t),pause:n,resume:r,eventFilter:s}}function P0(e){let t;function n(){return t||(t=e()),t}return n.reset=async()=>{const r=t;t=void 0,r&&await r},n}function Ic(e){return Rr()}function O0(...e){if(e.length!==1)return gs(...e);const t=e[0];return typeof t=="function"?xr(pi(()=>({get:t,set:mn}))):Q(t)}function I0(e,t=200,n={}){return sl(k0(t,n),e)}function D0(e,t=200,n=!1,r=!0,s=!1){return sl(L0(t,n,r,s),e)}function $0(e,t,n={}){const{eventFilter:r=Oc,...s}=n;return ie(e,sl(r,t),s)}function M0(e,t,n={}){const{eventFilter:r,...s}=n,{eventFilter:o,pause:l,resume:a,isActive:i}=R0(r);return{stop:$0(e,t,{...s,eventFilter:o}),pause:l,resume:a,isActive:i}}function As(e,t=!0,n){Ic()?Ee(e,n):t?e():Nt(e)}function B0(e,t){Ic()&&zn(e,t)}function N0(e,t,n={}){const{immediate:r=!0}=n,s=Q(!1);let o=null;function l(){o&&(clearTimeout(o),o=null)}function a(){s.value=!1,l()}function i(...c){l(),s.value=!0,o=setTimeout(()=>{s.value=!1,o=null,e(...c)},Be(t))}return r&&(s.value=!0,Mr&&i()),Wn(a),{isPending:xr(s),start:i,stop:a}}function br(e=!1,t={}){const{truthyValue:n=!0,falsyValue:r=!1}=t,s=Ae(e),o=Q(e);function l(a){if(arguments.length)return o.value=a,o.value;{const i=Be(n);return o.value=o.value===i?Be(r):i,o.value}}return s?l:[o,l]}function $t(e){var t;const n=Be(e);return(t=n==null?void 0:n.$el)!=null?t:n}const Bt=Mr?window:void 0,Dc=Mr?window.document:void 0,$c=Mr?window.navigator:void 0;function Pe(...e){let t,n,r,s;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,r,s]=e,t=Bt):[t,n,r,s]=e,!t)return mn;Array.isArray(n)||(n=[n]),Array.isArray(r)||(r=[r]);const o=[],l=()=>{o.forEach(u=>u()),o.length=0},a=(u,d,p,h)=>(u.addEventListener(d,p,h),()=>u.removeEventListener(d,p,h)),i=ie(()=>[$t(t),Be(s)],([u,d])=>{if(l(),!u)return;const p=x0(d)?{...d}:d;o.push(...n.flatMap(h=>r.map(b=>a(u,h,b,p))))},{immediate:!0,flush:"post"}),c=()=>{i(),l()};return Wn(c),c}function j0(){const e=Q(!1),t=Rr();return t&&Ee(()=>{e.value=!0},t),e}function Br(e){const t=j0();return A(()=>(t.value,!!e()))}function Mc(e,t={}){const{window:n=Bt}=t,r=Br(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let s;const o=Q(!1),l=c=>{o.value=c.matches},a=()=>{s&&("removeEventListener"in s?s.removeEventListener("change",l):s.removeListener(l))},i=Hi(()=>{r.value&&(a(),s=n.matchMedia(Be(e)),"addEventListener"in s?s.addEventListener("change",l):s.addListener(l),o.value=s.matches)});return Wn(()=>{i(),a(),s=void 0}),o}function Sa(e,t={}){const{controls:n=!1,navigator:r=$c}=t,s=Br(()=>r&&"permissions"in r);let o;const l=typeof e=="string"?{name:e}:e,a=Q(),i=()=>{o&&(a.value=o.state)},c=P0(async()=>{if(s.value){if(!o)try{o=await r.permissions.query(l),Pe(o,"change",i),i()}catch{a.value="prompt"}return o}});return c(),n?{state:a,isSupported:s,query:c}:a}function F0(e={}){const{navigator:t=$c,read:n=!1,source:r,copiedDuring:s=1500,legacy:o=!1}=e,l=Br(()=>t&&"clipboard"in t),a=Sa("clipboard-read"),i=Sa("clipboard-write"),c=A(()=>l.value||o),u=Q(""),d=Q(!1),p=N0(()=>d.value=!1,s);function h(){l.value&&_(a.value)?t.clipboard.readText().then(C=>{u.value=C}):u.value=w()}c.value&&n&&Pe(["copy","cut"],h);async function b(C=Be(r)){c.value&&C!=null&&(l.value&&_(i.value)?await t.clipboard.writeText(C):y(C),u.value=C,d.value=!0,p.start())}function y(C){const g=document.createElement("textarea");g.value=C??"",g.style.position="absolute",g.style.opacity="0",document.body.appendChild(g),g.select(),document.execCommand("copy"),g.remove()}function w(){var C,g,E;return(E=(g=(C=document==null?void 0:document.getSelection)==null?void 0:C.call(document))==null?void 0:g.toString())!=null?E:""}function _(C){return C==="granted"||C==="prompt"}return{isSupported:c,text:u,copied:d,copy:b}}const Kr=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},Jr="__vueuse_ssr_handlers__",H0=V0();function V0(){return Jr in Kr||(Kr[Jr]=Kr[Jr]||{}),Kr[Jr]}function z0(e,t){return H0[e]||t}function U0(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const q0={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},Ca="vueuse-storage";function Gn(e,t,n,r={}){var s;const{flush:o="pre",deep:l=!0,listenToStorageChanges:a=!0,writeDefaults:i=!0,mergeDefaults:c=!1,shallow:u,window:d=Bt,eventFilter:p,onError:h=L=>{console.error(L)},initOnMounted:b}=r,y=(u?$e:Q)(typeof t=="function"?t():t);if(!n)try{n=z0("getDefaultStorage",()=>{var L;return(L=Bt)==null?void 0:L.localStorage})()}catch(L){h(L)}if(!n)return y;const w=Be(t),_=U0(w),C=(s=r.serializer)!=null?s:q0[_],{pause:g,resume:E}=M0(y,()=>V(y.value),{flush:o,deep:l,eventFilter:p});d&&a&&As(()=>{Pe(d,"storage",q),Pe(d,Ca,M),b&&q()}),b||q();function I(L,F){d&&d.dispatchEvent(new CustomEvent(Ca,{detail:{key:e,oldValue:L,newValue:F,storageArea:n}}))}function V(L){try{const F=n.getItem(e);if(L==null)I(F,null),n.removeItem(e);else{const D=C.write(L);F!==D&&(n.setItem(e,D),I(F,D))}}catch(F){h(F)}}function k(L){const F=L?L.newValue:n.getItem(e);if(F==null)return i&&w!=null&&n.setItem(e,C.write(w)),w;if(!L&&c){const D=C.read(F);return typeof c=="function"?c(D,w):_==="object"&&!Array.isArray(D)?{...w,...D}:D}else return typeof F!="string"?F:C.read(F)}function q(L){if(!(L&&L.storageArea!==n)){if(L&&L.key==null){y.value=w;return}if(!(L&&L.key!==e)){g();try{(L==null?void 0:L.newValue)!==C.write(y.value)&&(y.value=k(L))}catch(F){h(F)}finally{L?Nt(E):E()}}}}function M(L){q(L.detail)}return y}function W0(e){return Mc("(prefers-color-scheme: dark)",e)}function G0(e,t,n={}){const{window:r=Bt,...s}=n;let o;const l=Br(()=>r&&"ResizeObserver"in r),a=()=>{o&&(o.disconnect(),o=void 0)},i=A(()=>Array.isArray(e)?e.map(d=>$t(d)):[$t(e)]),c=ie(i,d=>{if(a(),l.value&&r){o=new ResizeObserver(t);for(const p of d)p&&o.observe(p,s)}},{immediate:!0,flush:"post"}),u=()=>{a(),c()};return Wn(u),{isSupported:l,stop:u}}function K0(e,t={width:0,height:0},n={}){const{window:r=Bt,box:s="content-box"}=n,o=A(()=>{var d,p;return(p=(d=$t(e))==null?void 0:d.namespaceURI)==null?void 0:p.includes("svg")}),l=Q(t.width),a=Q(t.height),{stop:i}=G0(e,([d])=>{const p=s==="border-box"?d.borderBoxSize:s==="content-box"?d.contentBoxSize:d.devicePixelContentBoxSize;if(r&&o.value){const h=$t(e);if(h){const b=h.getBoundingClientRect();l.value=b.width,a.value=b.height}}else if(p){const h=Array.isArray(p)?p:[p];l.value=h.reduce((b,{inlineSize:y})=>b+y,0),a.value=h.reduce((b,{blockSize:y})=>b+y,0)}else l.value=d.contentRect.width,a.value=d.contentRect.height},n);As(()=>{const d=$t(e);d&&(l.value="offsetWidth"in d?d.offsetWidth:t.width,a.value="offsetHeight"in d?d.offsetHeight:t.height)});const c=ie(()=>$t(e),d=>{l.value=d?t.width:0,a.value=d?t.height:0});function u(){i(),c()}return{width:l,height:a,stop:u}}const Aa=["fullscreenchange","webkitfullscreenchange","webkitendfullscreen","mozfullscreenchange","MSFullscreenChange"];function ol(e,t={}){const{document:n=Dc,autoExit:r=!1}=t,s=A(()=>{var _;return(_=$t(e))!=null?_:n==null?void 0:n.querySelector("html")}),o=Q(!1),l=A(()=>["requestFullscreen","webkitRequestFullscreen","webkitEnterFullscreen","webkitEnterFullScreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen"].find(_=>n&&_ in n||s.value&&_ in s.value)),a=A(()=>["exitFullscreen","webkitExitFullscreen","webkitExitFullScreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen"].find(_=>n&&_ in n||s.value&&_ in s.value)),i=A(()=>["fullScreen","webkitIsFullScreen","webkitDisplayingFullscreen","mozFullScreen","msFullscreenElement"].find(_=>n&&_ in n||s.value&&_ in s.value)),c=["fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement"].find(_=>n&&_ in n),u=Br(()=>s.value&&n&&l.value!==void 0&&a.value!==void 0&&i.value!==void 0),d=()=>c?(n==null?void 0:n[c])===s.value:!1,p=()=>{if(i.value){if(n&&n[i.value]!=null)return n[i.value];{const _=s.value;if((_==null?void 0:_[i.value])!=null)return!!_[i.value]}}return!1};async function h(){if(!(!u.value||!o.value)){if(a.value)if((n==null?void 0:n[a.value])!=null)await n[a.value]();else{const _=s.value;(_==null?void 0:_[a.value])!=null&&await _[a.value]()}o.value=!1}}async function b(){if(!u.value||o.value)return;p()&&await h();const _=s.value;l.value&&(_==null?void 0:_[l.value])!=null&&(await _[l.value](),o.value=!0)}async function y(){await(o.value?h():b())}const w=()=>{const _=p();(!_||_&&d())&&(o.value=_)};return Pe(n,Aa,w,!1),Pe(()=>$t(s),Aa,w,!1),r&&Wn(h),{isSupported:u,isFullscreen:o,enter:b,exit:h,toggle:y}}function Js(e){return typeof Window<"u"&&e instanceof Window?e.document.documentElement:typeof Document<"u"&&e instanceof Document?e.documentElement:e}function Ys(e,t=mn,n={}){const{immediate:r=!0,manual:s=!1,type:o="text/javascript",async:l=!0,crossOrigin:a,referrerPolicy:i,noModule:c,defer:u,document:d=Dc,attrs:p={}}=n,h=Q(null);let b=null;const y=C=>new Promise((g,E)=>{const I=q=>(h.value=q,g(q),q);if(!d){g(!1);return}let V=!1,k=d.querySelector(`script[src="${Be(e)}"]`);k?k.hasAttribute("data-loaded")&&I(k):(k=d.createElement("script"),k.type=o,k.async=l,k.src=Be(e),u&&(k.defer=u),a&&(k.crossOrigin=a),c&&(k.noModule=c),i&&(k.referrerPolicy=i),Object.entries(p).forEach(([q,M])=>k==null?void 0:k.setAttribute(q,M)),V=!0),k.addEventListener("error",q=>E(q)),k.addEventListener("abort",q=>E(q)),k.addEventListener("load",()=>{k.setAttribute("data-loaded","true"),t(k),I(k)}),V&&(k=d.head.appendChild(k)),C||I(k)}),w=(C=!0)=>(b||(b=y(C)),b),_=()=>{if(!d)return;b=null,h.value&&(h.value=null);const C=d.querySelector(`script[src="${Be(e)}"]`);C&&d.head.removeChild(C)};return r&&!s&&As(w),s||B0(_),{scriptTag:h,load:w,unload:_}}function Bc(e){const t=window.getComputedStyle(e);if(t.overflowX==="scroll"||t.overflowY==="scroll"||t.overflowX==="auto"&&e.clientWidth1?!0:(t.preventDefault&&t.preventDefault(),!1)}const Qs=new WeakMap;function Nc(e,t=!1){const n=Q(t);let r=null,s="";ie(O0(e),a=>{const i=Js(Be(a));if(i){const c=i;if(Qs.get(c)||Qs.set(c,c.style.overflow),c.style.overflow!=="hidden"&&(s=c.style.overflow),c.style.overflow==="hidden")return n.value=!0;if(n.value)return c.style.overflow="hidden"}},{immediate:!0});const o=()=>{const a=Js(Be(e));!a||n.value||(wa&&(r=Pe(a,"touchmove",i=>{J0(i)},{passive:!1})),a.style.overflow="hidden",n.value=!0)},l=()=>{const a=Js(Be(e));!a||!n.value||(wa&&(r==null||r()),a.style.overflow=s,Qs.delete(a),n.value=!1)};return Wn(l),A({get(){return n.value},set(a){a?o():l()}})}function jc(e,t,n={}){const{window:r=Bt}=n;return Gn(e,t,r==null?void 0:r.sessionStorage,n)}function Y0(e={}){const{window:t=Bt,behavior:n="auto"}=e;if(!t)return{x:Q(0),y:Q(0)};const r=Q(t.scrollX),s=Q(t.scrollY),o=A({get(){return r.value},set(a){scrollTo({left:a,behavior:n})}}),l=A({get(){return s.value},set(a){scrollTo({top:a,behavior:n})}});return Pe(t,"scroll",()=>{r.value=t.scrollX,s.value=t.scrollY},{capture:!1,passive:!0}),{x:o,y:l}}function Q0(e={}){const{window:t=Bt,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:r=Number.POSITIVE_INFINITY,listenOrientation:s=!0,includeScrollbar:o=!0}=e,l=Q(n),a=Q(r),i=()=>{t&&(o?(l.value=t.innerWidth,a.value=t.innerHeight):(l.value=t.document.documentElement.clientWidth,a.value=t.document.documentElement.clientHeight))};if(i(),As(i),Pe("resize",i,{passive:!0}),s){const c=Mc("(orientation: portrait)");ie(c,()=>i())}return{width:l,height:a}}const Fc=({type:e="info",text:t="",vertical:n,color:r},{slots:s})=>{var o;return f("span",{class:["vp-badge",e,{diy:r}],style:{verticalAlign:n??!1,backgroundColor:r??!1}},((o=s.default)==null?void 0:o.call(s))??t)};Fc.displayName="Badge";var X0=J({name:"FontIcon",props:{icon:{type:String,default:""},color:{type:String,default:""},size:{type:[String,Number],default:""}},setup(e){const t=A(()=>{const r=["font-icon icon"],s=`fas fa-${e.icon}`;return r.push("fa-fw fa-sm"),r.push(e.icon.includes(" ")?e.icon:s),r}),n=A(()=>{const r={};return e.color&&(r.color=e.color),e.size&&(r["font-size"]=Number.isNaN(Number(e.size))?e.size:`${e.size}px`),yn(r).length?r:null});return()=>e.icon?f("span",{key:e.icon,class:t.value,style:n.value}):null}});const Z0=kt({enhance:({app:e})=>{dt("Badge")||e.component("Badge",Fc),dt("FontIcon")||e.component("FontIcon",X0)},setup:()=>{Ys("https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/js/brands.min.js",()=>{},{attrs:{"data-auto-replace-svg":"nest"}}),Ys("https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/js/solid.min.js",()=>{},{attrs:{"data-auto-replace-svg":"nest"}}),Ys("https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/js/fontawesome.min.js",()=>{},{attrs:{"data-auto-replace-svg":"nest"}})},rootComponents:[]}),xa=async(e,t)=>{const{path:n,query:r}=e.currentRoute.value,{scrollBehavior:s}=e.options;e.options.scrollBehavior=void 0,await e.replace({path:n,query:r,hash:t}),e.options.scrollBehavior=s},e2=({headerLinkSelector:e,headerAnchorSelector:t,delay:n,offset:r=5})=>{const s=qn();Pe("scroll",I0(()=>{var b,y;const l=Math.max(window.scrollY,document.documentElement.scrollTop,document.body.scrollTop);if(Math.abs(l-0)d.some(_=>_.hash===w.hash));for(let w=0;w=(((b=_.parentElement)==null?void 0:b.offsetTop)??0)-r,E=!C||l<(((y=C.parentElement)==null?void 0:y.offsetTop)??0)-r;if(!(g&&E))continue;const V=decodeURIComponent(s.currentRoute.value.hash),k=decodeURIComponent(_.hash);if(V===k)return;if(u){for(let q=w+1;qCe(e.title)?{title:e.title}:null;const Vc=Symbol(""),l2=e=>{Hc=e},a2=()=>Me(Vc),i2=e=>{e.provide(Vc,Hc)};var c2={"/":{title:"目录",empty:"暂无目录"}};const u2=J({name:"Catalog",props:{base:{type:String,default:""},level:{type:Number,default:3},index:Boolean,hideHeading:Boolean},setup(e){const t=a2(),n=Dr(c2),r=Te(),s=Qp(),o=_c(),a=$e(E0(s.value).map(([c,{meta:u}])=>{const d=t(u);if(!d)return null;const p=c.split("/").length;return{level:_0(c,"/")?p-2:p-1,base:c.replace(/\/[^/]+\/?$/,"/"),path:c,...d}}).filter(c=>Un(c)&&Ce(c.title))),i=A(()=>{const c=e.base?B1(oc(e.base)):r.value.path.replace(/\/[^/]+$/,"/"),u=c.split("/").length-2,d=[];return a.value.filter(({level:p,path:h})=>{if(!Hn(h,c)||h===c)return!1;if(c==="/"){const b=yn(o.value.locales).filter(y=>y!=="/");if(h==="/404.html"||b.some(y=>Hn(h,y)))return!1}return p-u<=e.level}).sort(({title:p,level:h,order:b},{title:y,level:w,order:_})=>{const C=h-w;return C||(Ks(b)?Ks(_)?b>0?_>0?b-_:-1:_<0?b-_:1:b:Ks(_)?_:p.localeCompare(y))}).forEach(p=>{var y;const{base:h,level:b}=p;switch(b-u){case 1:{d.push(p);break}case 2:{const w=d.find(_=>_.path===h);w&&(w.children??(w.children=[])).push(p);break}default:{const w=d.find(_=>_.path===h.replace(/\/[^/]+\/$/,"/"));if(w){const _=(y=w.children)==null?void 0:y.find(C=>C.path===h);_&&(_.children??(_.children=[])).push(p)}}}}),d});return()=>{const c=i.value.some(u=>u.children);return f("div",{class:["vp-catalog-wrapper",{index:e.index}]},[e.hideHeading?null:f("h2",{class:"vp-catalog-main-title"},n.value.title),i.value.length?f(e.index?"ol":"ul",{class:["vp-catalogs",{deep:c}]},i.value.map(({children:u=[],title:d,path:p,content:h})=>{const b=f(rt,{class:"vp-catalog-title",to:p},()=>h?f(h):d);return f("li",{class:"vp-catalog"},c?[f("h3",{id:d,class:["vp-catalog-child-title",{"has-children":u.length}]},[f("a",{href:`#${d}`,class:"vp-catalog-header-anchor","aria-hidden":!0},"#"),b]),u.length?f(e.index?"ol":"ul",{class:"vp-child-catalogs"},u.map(({children:y=[],content:w,path:_,title:C})=>f("li",{class:"vp-child-catalog"},[f("div",{class:["vp-catalog-sub-title",{"has-children":y.length}]},[f("a",{href:`#${C}`,class:"vp-catalog-header-anchor"},"#"),f(rt,{class:"vp-catalog-title",to:_},()=>w?f(w):C)]),y.length?f(e.index?"ol":"div",{class:e.index?"vp-sub-catalogs":"vp-sub-catalogs-wrapper"},y.map(({content:g,path:E,title:I})=>e.index?f("li",{class:"vp-sub-catalog"},f(rt,{to:E},()=>g?f(g):I)):f(rt,{class:"vp-sub-catalog-link",to:E},()=>g?f(g):I))):null]))):null]:f("div",{class:"vp-catalog-child-title"},b))})):f("p",{class:"vp-empty-catalog"},n.value.empty)])}}}),f2=kt({enhance:({app:e})=>{i2(e),dt("Catalog",e)||e.component("Catalog",u2)}});var d2={"/":{backToTop:"返回顶部"}};const p2=J({name:"BackToTop",setup(){const e=we(),t=Dr(d2),n=$e(),{height:r}=K0(n),{height:s}=Q0(),{y:o}=Y0(),l=A(()=>e.value.backToTop!==!1&&o.value>100),a=A(()=>o.value/(r.value-s.value)*100);return Ee(()=>{n.value=document.body}),()=>f(Nn,{name:"back-to-top"},()=>l.value?f("button",{type:"button",class:"vp-back-to-top-button","aria-label":t.value.backToTop,onClick:()=>{window.scrollTo({top:0,behavior:"smooth"})}},[f("span",{class:"vp-scroll-progress",role:"progressbar","aria-labelledby":"loadinglabel","aria-valuenow":a.value},f("svg",f("circle",{cx:"26",cy:"26",r:"24",fill:"none",stroke:"currentColor","stroke-width":"4","stroke-dasharray":`${Math.PI*a.value*.48} ${Math.PI*(100-a.value)*.48}`}))),f("div",{class:"back-to-top-icon"})]):null)}}),h2=kt({rootComponents:[p2]});/** * NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress * @license MIT - */const le={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
                            '},status:null,set:e=>{const t=le.isStarted();e=Xs(e,le.settings.minimum,1),le.status=e===1?null:e;const n=le.render(!t),r=n.querySelector(le.settings.barSelector),s=le.settings.speed,o=le.settings.easing;return n.offsetWidth,v2(l=>{Yr(r,{transform:"translate3d("+Ta(e)+"%,0,0)",transition:"all "+s+"ms "+o}),e===1?(Yr(n,{transition:"none",opacity:"1"}),n.offsetWidth,setTimeout(function(){Yr(n,{transition:"all "+s+"ms linear",opacity:"0"}),setTimeout(function(){le.remove(),l()},s)},s)):setTimeout(()=>l(),s)}),le},isStarted:()=>typeof le.status=="number",start:()=>{le.status||le.set(0);const e=()=>{setTimeout(()=>{le.status&&(le.trickle(),e())},le.settings.trickleSpeed)};return le.settings.trickle&&e(),le},done:e=>!e&&!le.status?le:le.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=le.status;return t?(typeof e!="number"&&(e=(1-t)*Xs(Math.random()*t,.1,.95)),t=Xs(t+e,0,.994),le.set(t)):le.start()},trickle:()=>le.inc(Math.random()*le.settings.trickleRate),render:e=>{if(le.isRendered())return document.getElementById("nprogress");ka(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=le.settings.template;const n=t.querySelector(le.settings.barSelector),r=e?"-100":Ta(le.status||0),s=document.querySelector(le.settings.parent);return Yr(n,{transition:"all 0 linear",transform:"translate3d("+r+"%,0,0)"}),s!==document.body&&ka(s,"nprogress-custom-parent"),s==null||s.appendChild(t),t},remove:()=>{La(document.documentElement,"nprogress-busy"),La(document.querySelector(le.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&m2(e)},isRendered:()=>!!document.getElementById("nprogress")},Xs=(e,t,n)=>en?n:e,Ta=e=>(-1+e)*100,v2=function(){const e=[];function t(){const n=e.shift();n&&n(t)}return function(n){e.push(n),e.length===1&&t()}}(),Yr=function(){const e=["Webkit","O","Moz","ms"],t={};function n(l){return l.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(a,i){return i.toUpperCase()})}function r(l){const a=document.body.style;if(l in a)return l;let i=e.length;const c=l.charAt(0).toUpperCase()+l.slice(1);let u;for(;i--;)if(u=e[i]+c,u in a)return u;return l}function s(l){return l=n(l),t[l]??(t[l]=r(l))}function o(l,a,i){a=s(a),l.style[a]=i}return function(l,a){for(const i in a){const c=a[i];c!==void 0&&Object.prototype.hasOwnProperty.call(a,i)&&o(l,i,c)}}}(),zc=(e,t)=>(typeof e=="string"?e:ll(e)).indexOf(" "+t+" ")>=0,ka=(e,t)=>{const n=ll(e),r=n+t;zc(n,t)||(e.className=r.substring(1))},La=(e,t)=>{const n=ll(e);if(!zc(e,t))return;const r=n.replace(" "+t+" "," ");e.className=r.substring(1,r.length-1)},ll=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),m2=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)},g2=()=>{Ee(()=>{const e=qn(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||le.start()}),e.afterEach(n=>{t.add(n.path),le.done()})})},b2=kt({setup(){g2()}}),y2=JSON.parse(`{"encrypt":{"config":{"/demo/encrypt.html":["$2a$10$MGIo6L4e4bZe/ygAgMOR1.9gBNEtWu9KBlnbGFeIt/6c0u.RHkjFi"]}},"author":{"name":"憨憨十二","url":"https://mister-hope.com"},"logo":"/logo.svg","repo":"knightio/my-docs","docsDir":"src","footer":"京ICP备2023018079号","displayFooter":true,"contributors":false,"locales":{"/":{"lang":"zh-CN","navbarLocales":{"langName":"简体中文","selectLangAriaLabel":"选择语言"},"metaLocales":{"author":"作者","date":"写作日期","origin":"原创","views":"访问量","category":"分类","tag":"标签","readingTime":"阅读时间","words":"字数","toc":"此页内容","prev":"上一页","next":"下一页","lastUpdated":"上次编辑于","contributors":"贡献者","editLink":"在 GitHub 上编辑此页","print":"打印"},"outlookLocales":{"themeColor":"主题色","darkmode":"外观","fullscreen":"全屏"},"encryptLocales":{"iconLabel":"文章已加密","placeholder":"输入密码","remember":"记住密码","errorHint":"请输入正确的密码"},"routeLocales":{"skipToContent":"跳至主要內容","notFoundTitle":"页面不存在","notFoundMsg":["这里什么也没有","我们是怎么来到这儿的?","这 是 四 零 四 !","看起来你访问了一个失效的链接"],"back":"返回上一页","home":"带我回家","openInNewWindow":"Open in new window"},"navbar":[{"text":"主页","icon":"lightbulb","link":"/"},"/java/","/books/",{"text":"数据库","icon":"lightbulb","link":"/dbs/"},{"text":"Linux","icon":"lightbulb","link":"/linux/"},{"text":"面试","icon":"lightbulb","link":"/interview/"},{"text":"LeetCode","icon":"lightbulb","prefix":"/leetcode/","children":[{"text":"Daily","icon":"lightbulb","link":"daily/"},{"text":"Leetcode-75","icon":"lightbulb","link":"leetcode-75/"}]}],"sidebar":{"/java":"structure","/redis":"structure","/linux":"structure","/interview":"structure","/dbs":"structure","/books":"structure","/":[""]}}}}`),_2=Q(y2),Uc=()=>_2,qc=Symbol(""),E2=()=>{const e=Me(qc);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},w2=(e,t)=>{const{locales:n,...r}=e;return{...r,...n==null?void 0:n[t]}},S2=kt({enhance({app:e}){const t=Uc(),n=e._context.provides[nl],r=A(()=>w2(t.value,n.routeLocale.value));e.provide(qc,r),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return r.value}}})}}),C2=/\b(?:Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini)/i,A2=()=>typeof window<"u"&&window.navigator&&"userAgent"in window.navigator&&C2.test(navigator.userAgent),x2=({delay:e=500,duration:t=2e3,locales:n,selector:r,showInMobile:s})=>{const{copy:o,copied:l}=F0({legacy:!0,copiedDuring:t}),a=Dr(n),i=Te(),c=p=>{if(!p.hasAttribute("copy-code-registered")){const h=document.createElement("button");h.type="button",h.classList.add("vp-copy-code-button"),h.innerHTML='
                            ',h.setAttribute("aria-label",a.value.copy),h.setAttribute("data-copied",a.value.copied),p.parentElement&&p.parentElement.insertBefore(h,p),p.setAttribute("copy-code-registered","")}},u=()=>{Nt().then(()=>Pc(e)).then(()=>{r.forEach(p=>{document.querySelectorAll(p).forEach(c)})})},d=(p,h,b)=>{let{innerText:y=""}=h;/language-(shellscript|shell|bash|sh|zsh)/.test(p.classList.toString())&&(y=y.replace(/^ *(\$|>) /gm,"")),o(y).then(()=>{b.classList.add("copied"),ie(l,()=>{b.classList.remove("copied"),b.blur()},{once:!0})})};Ee(()=>{const p=!A2()||s;p&&u(),Pe("click",h=>{const b=h.target;if(b.matches('div[class*="language-"] > button.copy')){const y=b.parentElement,w=b.nextElementSibling;w&&d(y,w,b)}else if(b.matches('div[class*="language-"] div.vp-copy-icon')){const y=b.parentElement,w=y.parentElement,_=y.nextElementSibling;_&&d(w,_,y)}}),ie(()=>i.value.path,()=>{p&&u()})})};var T2={"/":{copy:"复制代码",copied:"已复制"}},k2=['.theme-hope-content div[class*="language-"] pre'];const L2=kt({setup:()=>{x2({selector:k2,locales:T2,duration:2e3,delay:500,showInMobile:!1})}}),Qr=Gn("VUEPRESS_CODE_TAB_STORE",{});var R2=J({name:"CodeTabs",props:{active:{type:Number,default:0},data:{type:Array,required:!0},id:{type:String,required:!0},tabId:{type:String,default:""}},slots:Object,setup(e,{slots:t}){const n=Q(e.active),r=$e([]),s=()=>{e.tabId&&(Qr.value[e.tabId]=e.data[n.value].id)},o=(c=n.value)=>{n.value=c{n.value=c>0?c-1:r.value.length-1,r.value[n.value].focus()},a=(c,u)=>{c.key===" "||c.key==="Enter"?(c.preventDefault(),n.value=u):c.key==="ArrowRight"?(c.preventDefault(),o()):c.key==="ArrowLeft"&&(c.preventDefault(),l()),e.tabId&&(Qr.value[e.tabId]=e.data[n.value].id)},i=()=>{if(e.tabId){const c=e.data.findIndex(({id:u})=>Qr.value[e.tabId]===u);if(c!==-1)return c}return e.active};return Ee(()=>{n.value=i(),ie(()=>Qr.value[e.tabId],(c,u)=>{if(e.tabId&&c!==u){const d=e.data.findIndex(({id:p})=>p===c);d!==-1&&(n.value=d)}})}),()=>e.data.length?f("div",{class:"vp-code-tabs"},[f("div",{class:"vp-code-tabs-nav",role:"tablist"},e.data.map(({id:c},u)=>{const d=u===n.value;return f("button",{type:"button",ref:p=>{p&&(r.value[u]=p)},class:["vp-code-tab-nav",{active:d}],role:"tab","aria-controls":`codetab-${e.id}-${u}`,"aria-selected":d,onClick:()=>{n.value=u,s()},onKeydown:p=>a(p,u)},t[`title${u}`]({value:c,isActive:d}))})),e.data.map(({id:c},u)=>{const d=u===n.value;return f("div",{class:["vp-code-tab",{active:d}],id:`codetab-${e.id}-${u}`,role:"tabpanel","aria-expanded":d},[f("div",{class:"vp-code-tab-title"},t[`title${u}`]({value:c,isActive:d})),t[`tab${u}`]({value:c,isActive:d})])})]):null}});const Wc=({active:e=!1},{slots:t})=>{var n;return f("div",{class:["code-group-item",{active:e}],"aria-selected":e},(n=t.default)==null?void 0:n.call(t))};Wc.displayName="CodeGroupItem";const P2=J({name:"CodeGroup",slots:Object,setup(e,{slots:t}){const n=Q(-1),r=$e([]),s=(a=n.value)=>{n.value=a{n.value=a>0?a-1:r.value.length-1,r.value[n.value].focus()},l=(a,i)=>{a.key===" "||a.key==="Enter"?(a.preventDefault(),n.value=i):a.key==="ArrowRight"?(a.preventDefault(),s(i)):a.key==="ArrowLeft"&&(a.preventDefault(),o(i))};return()=>{var i;const a=(((i=t.default)==null?void 0:i.call(t))||[]).filter(c=>c.type.name==="CodeGroupItem").map(c=>(c.props===null&&(c.props={}),c));return a.length===0?null:(n.value<0||n.value>a.length-1?(n.value=a.findIndex(c=>"active"in c.props),n.value===-1&&(n.value=0)):a.forEach((c,u)=>{c.props.active=u===n.value}),f("div",{class:"code-group"},[f("div",{class:"code-group-nav"},a.map((c,u)=>{const d=u===n.value;return f("button",{type:"button",ref:p=>{p&&(r.value[u]=p)},class:["code-group-nav-tab",{active:d}],"aria-pressed":d,"aria-expanded":d,onClick:()=>{n.value=u},onKeydown:p=>l(p,u)},c.props.title)})),a]))}}}),ke=({name:e="",color:t="currentColor",ariaLabel:n},{attrs:r,slots:s})=>{var o;return f("svg",{xmlns:"http://www.w3.org/2000/svg",class:["icon",`${e}-icon`],viewBox:"0 0 1024 1024",fill:t,"aria-label":n??`${e} icon`,...r},(o=s.default)==null?void 0:o.call(s))};ke.displayName="IconBase";const Gc=({size:e=48,stroke:t=4,wrapper:n=!0,height:r=2*e})=>{const s=f("svg",{xmlns:"http://www.w3.org/2000/svg",width:e,height:e,preserveAspectRatio:"xMidYMid",viewBox:"25 25 50 50"},[f("animateTransform",{attributeName:"transform",type:"rotate",dur:"2s",keyTimes:"0;1",repeatCount:"indefinite",values:"0;360"}),f("circle",{cx:"50",cy:"50",r:"20",fill:"none",stroke:"currentColor","stroke-width":t,"stroke-linecap":"round"},[f("animate",{attributeName:"stroke-dasharray",dur:"1.5s",keyTimes:"0;0.5;1",repeatCount:"indefinite",values:"1,200;90,200;1,200"}),f("animate",{attributeName:"stroke-dashoffset",dur:"1.5s",keyTimes:"0;0.5;1",repeatCount:"indefinite",values:"0;-35px;-125px"})])]);return n?f("div",{class:"loading-icon-wrapper",style:`display:flex;align-items:center;justify-content:center;height:${r}px`},s):s};Gc.displayName="LoadingIcon";const xs=(e,{slots:t})=>{var n;return(n=t.default)==null?void 0:n.call(t)},O2=e=>bn(e)?e:`https://github.com/${e}`,al=(e="")=>!bn(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,Kc=()=>f(ke,{name:"github"},()=>f("path",{d:"M511.957 21.333C241.024 21.333 21.333 240.981 21.333 512c0 216.832 140.544 400.725 335.574 465.664 24.49 4.395 32.256-10.07 32.256-23.083 0-11.69.256-44.245 0-85.205-136.448 29.61-164.736-64.64-164.736-64.64-22.315-56.704-54.4-71.765-54.4-71.765-44.587-30.464 3.285-29.824 3.285-29.824 49.195 3.413 75.179 50.517 75.179 50.517 43.776 75.008 114.816 53.333 142.762 40.79 4.523-31.66 17.152-53.377 31.19-65.537-108.971-12.458-223.488-54.485-223.488-242.602 0-53.547 19.114-97.323 50.517-131.67-5.035-12.33-21.93-62.293 4.779-129.834 0 0 41.258-13.184 134.912 50.346a469.803 469.803 0 0 1 122.88-16.554c41.642.213 83.626 5.632 122.88 16.554 93.653-63.488 134.784-50.346 134.784-50.346 26.752 67.541 9.898 117.504 4.864 129.834 31.402 34.347 50.474 78.123 50.474 131.67 0 188.586-114.73 230.016-224.042 242.09 17.578 15.232 33.578 44.672 33.578 90.454v135.85c0 13.142 7.936 27.606 32.854 22.87C862.25 912.597 1002.667 728.747 1002.667 512c0-271.019-219.648-490.667-490.71-490.667z"}));Kc.displayName="GitHubIcon";const Jc=()=>f(ke,{name:"gitee"},()=>f("path",{d:"M512 992C246.92 992 32 777.08 32 512S246.92 32 512 32s480 214.92 480 480-214.92 480-480 480zm242.97-533.34H482.39a23.7 23.7 0 0 0-23.7 23.7l-.03 59.28c0 13.08 10.59 23.7 23.7 23.7h165.96a23.7 23.7 0 0 1 23.7 23.7v11.85a71.1 71.1 0 0 1-71.1 71.1H375.71a23.7 23.7 0 0 1-23.7-23.7V423.11a71.1 71.1 0 0 1 71.1-71.1h331.8a23.7 23.7 0 0 0 23.7-23.7l.06-59.25a23.73 23.73 0 0 0-23.7-23.73H423.11a177.78 177.78 0 0 0-177.78 177.75v331.83c0 13.08 10.62 23.7 23.7 23.7h349.62a159.99 159.99 0 0 0 159.99-159.99V482.33a23.7 23.7 0 0 0-23.7-23.7z"}));Jc.displayName="GiteeIcon";const Yc=()=>f(ke,{name:"bitbucket"},()=>f("path",{d:"M575.256 490.862c6.29 47.981-52.005 85.723-92.563 61.147-45.714-20.004-45.714-92.562-1.133-113.152 38.29-23.442 93.696 7.424 93.696 52.005zm63.451-11.996c-10.276-81.152-102.29-134.839-177.152-101.156-47.433 21.138-79.433 71.424-77.129 124.562 2.853 69.705 69.157 126.866 138.862 120.576S647.3 548.571 638.708 478.83zm136.558-309.723c-25.161-33.134-67.986-38.839-105.728-45.13-106.862-17.151-216.576-17.7-323.438 1.134-35.438 5.706-75.447 11.996-97.719 43.996 36.572 34.304 88.576 39.424 135.424 45.129 84.553 10.862 171.447 11.447 256 .585 47.433-5.705 99.987-10.276 135.424-45.714zm32.585 591.433c-16.018 55.99-6.839 131.438-66.304 163.986-102.29 56.576-226.304 62.867-338.87 42.862-59.43-10.862-129.135-29.696-161.72-85.723-14.3-54.858-23.442-110.848-32.585-166.84l3.438-9.142 10.276-5.157c170.277 112.567 408.576 112.567 579.438 0 26.844 8.01 6.84 40.558 6.29 60.014zm103.424-549.157c-19.42 125.148-41.728 249.71-63.415 374.272-6.29 36.572-41.728 57.162-71.424 72.558-106.862 53.724-231.424 62.866-348.562 50.286-79.433-8.558-160.585-29.696-225.134-79.433-30.28-23.443-30.28-63.415-35.986-97.134-20.005-117.138-42.862-234.277-57.161-352.585 6.839-51.42 64.585-73.728 107.447-89.71 57.16-21.138 118.272-30.866 178.87-36.571 129.134-12.58 261.157-8.01 386.304 28.562 44.581 13.13 92.563 31.415 122.844 69.705 13.714 17.7 9.143 40.01 6.29 60.014z"}));Yc.displayName="BitbucketIcon";const Qc=()=>f(ke,{name:"source"},()=>f("path",{d:"M601.92 475.2c0 76.428-8.91 83.754-28.512 99.594-14.652 11.88-43.956 14.058-78.012 16.434-18.81 1.386-40.392 2.97-62.172 6.534-18.612 2.97-36.432 9.306-53.064 17.424V299.772c37.818-21.978 63.36-62.766 63.36-109.692 0-69.894-56.826-126.72-126.72-126.72S190.08 120.186 190.08 190.08c0 46.926 25.542 87.714 63.36 109.692v414.216c-37.818 21.978-63.36 62.766-63.36 109.692 0 69.894 56.826 126.72 126.72 126.72s126.72-56.826 126.72-126.72c0-31.086-11.286-59.598-29.7-81.576 13.266-9.504 27.522-17.226 39.996-19.206 16.038-2.574 32.868-3.762 50.688-5.148 48.312-3.366 103.158-7.326 148.896-44.55 61.182-49.698 74.25-103.158 75.24-187.902V475.2h-126.72zM316.8 126.72c34.848 0 63.36 28.512 63.36 63.36s-28.512 63.36-63.36 63.36-63.36-28.512-63.36-63.36 28.512-63.36 63.36-63.36zm0 760.32c-34.848 0-63.36-28.512-63.36-63.36s28.512-63.36 63.36-63.36 63.36 28.512 63.36 63.36-28.512 63.36-63.36 63.36zM823.68 158.4h-95.04V63.36h-126.72v95.04h-95.04v126.72h95.04v95.04h126.72v-95.04h95.04z"}));Qc.displayName="SourceIcon";const I2=({link:e,type:t=al(e??"")})=>{if(!t)return null;const n=t.toLowerCase();return f(n==="bitbucket"?Yc:n==="github"?Kc:n==="gitlab"?"GitLab":n==="gitee"?Jc:Qc)},D2=(e,t=0)=>{let n=3735928559^t,r=1103547991^t;for(let s=0,o;s>>16,2246822507),n^=Math.imul(r^r>>>13,3266489909),r=Math.imul(r^r>>>16,2246822507),r^=Math.imul(n^n>>>13,3266489909),4294967296*(2097151&r)+(n>>>0)},Xc=(e,t)=>D2(e)%t,Zc=/#.*$/u,$2=e=>{const t=Zc.exec(e);return t?t[0]:""},Ra=e=>decodeURI(e).replace(Zc,"").replace(/\/index\.html$/iu,"/").replace(/\.html$/iu,"").replace(/(README|index)?\.md$/iu,""),eu=(e,t)=>{if(!Rc(t))return!1;const n=Ra(e.path),r=Ra(t),s=$2(t);return s?s===e.hash&&(!r||n===r):n===r};var M2=e=>Object.prototype.toString.call(e)==="[object Object]",yr=e=>typeof e=="string";const tu=Array.isArray,Pa=e=>M2(e)&&yr(e.name),Oa=(e,t=!1)=>e?tu(e)?e.map(n=>yr(n)?{name:n}:Pa(n)?n:null).filter(n=>n!==null):yr(e)?[{name:e}]:Pa(e)?[e]:(console.error(`Expect "author" to be \`AuthorInfo[] | AuthorInfo | string[] | string ${t?"":"| false"} | undefined\`, but got`,e),[]):[],nu=(e,t)=>{if(e){if(tu(e)&&e.every(yr))return e;if(yr(e))return[e];console.error(`Expect ${t} to be \`string[] | string | undefined\`, but got`,e)}return[]},B2=e=>nu(e,"category"),N2=e=>nu(e,"tag"),j2='',F2='';var H2={useBabel:!1,jsLib:[],cssLib:[],codepenLayout:"left",codepenEditors:"101",babel:"https://unpkg.com/@babel/standalone/babel.min.js",vue:"https://unpkg.com/vue/dist/vue.global.prod.js",react:"https://unpkg.com/react/umd/react.production.min.js",reactDOM:"https://unpkg.com/react-dom/umd/react-dom.production.min.js"};const Zs=H2,Ia={html:{types:["html","slim","haml","md","markdown","vue"],map:{html:"none",vue:"none",md:"markdown"}},js:{types:["js","javascript","coffee","coffeescript","ts","typescript","ls","livescript"],map:{js:"none",javascript:"none",coffee:"coffeescript",ls:"livescript",ts:"typescript"}},css:{types:["css","less","sass","scss","stylus","styl"],map:{css:"none",styl:"stylus"}}},V2=(e,t,n)=>{const r=document.createElement(e);return Un(t)&&yn(t).forEach(s=>{if(s.indexOf("data"))r[s]=t[s];else{const o=s.replace("data","");r.dataset[o]=t[s]}}),r},il=e=>({...Zs,...e,jsLib:Array.from(new Set([...Zs.jsLib??[],...e.jsLib??[]])),cssLib:Array.from(new Set([...Zs.cssLib??[],...e.cssLib??[]]))}),$n=(e,t)=>{if(Rc(e[t]))return e[t];const n=new Promise(r=>{var o;const s=document.createElement("script");s.src=t,(o=document.querySelector("body"))==null||o.appendChild(s),s.onload=()=>{r()}});return e[t]=n,n},z2=(e,t)=>{if(t.css&&Array.from(e.childNodes).every(n=>n.nodeName!=="STYLE")){const n=V2("style",{innerHTML:t.css});e.appendChild(n)}},U2=(e,t,n)=>{const r=n.getScript();if(r&&Array.from(t.childNodes).every(s=>s.nodeName!=="SCRIPT")){const s=document.createElement("script");s.appendChild(document.createTextNode(`{const document=window.document.querySelector('#${e} .vp-code-demo-display').shadowRoot; + */const le={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
                            '},status:null,set:e=>{const t=le.isStarted();e=Xs(e,le.settings.minimum,1),le.status=e===1?null:e;const n=le.render(!t),r=n.querySelector(le.settings.barSelector),s=le.settings.speed,o=le.settings.easing;return n.offsetWidth,v2(l=>{Yr(r,{transform:"translate3d("+Ta(e)+"%,0,0)",transition:"all "+s+"ms "+o}),e===1?(Yr(n,{transition:"none",opacity:"1"}),n.offsetWidth,setTimeout(function(){Yr(n,{transition:"all "+s+"ms linear",opacity:"0"}),setTimeout(function(){le.remove(),l()},s)},s)):setTimeout(()=>l(),s)}),le},isStarted:()=>typeof le.status=="number",start:()=>{le.status||le.set(0);const e=()=>{setTimeout(()=>{le.status&&(le.trickle(),e())},le.settings.trickleSpeed)};return le.settings.trickle&&e(),le},done:e=>!e&&!le.status?le:le.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=le.status;return t?(typeof e!="number"&&(e=(1-t)*Xs(Math.random()*t,.1,.95)),t=Xs(t+e,0,.994),le.set(t)):le.start()},trickle:()=>le.inc(Math.random()*le.settings.trickleRate),render:e=>{if(le.isRendered())return document.getElementById("nprogress");ka(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=le.settings.template;const n=t.querySelector(le.settings.barSelector),r=e?"-100":Ta(le.status||0),s=document.querySelector(le.settings.parent);return Yr(n,{transition:"all 0 linear",transform:"translate3d("+r+"%,0,0)"}),s!==document.body&&ka(s,"nprogress-custom-parent"),s==null||s.appendChild(t),t},remove:()=>{La(document.documentElement,"nprogress-busy"),La(document.querySelector(le.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&m2(e)},isRendered:()=>!!document.getElementById("nprogress")},Xs=(e,t,n)=>en?n:e,Ta=e=>(-1+e)*100,v2=function(){const e=[];function t(){const n=e.shift();n&&n(t)}return function(n){e.push(n),e.length===1&&t()}}(),Yr=function(){const e=["Webkit","O","Moz","ms"],t={};function n(l){return l.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(a,i){return i.toUpperCase()})}function r(l){const a=document.body.style;if(l in a)return l;let i=e.length;const c=l.charAt(0).toUpperCase()+l.slice(1);let u;for(;i--;)if(u=e[i]+c,u in a)return u;return l}function s(l){return l=n(l),t[l]??(t[l]=r(l))}function o(l,a,i){a=s(a),l.style[a]=i}return function(l,a){for(const i in a){const c=a[i];c!==void 0&&Object.prototype.hasOwnProperty.call(a,i)&&o(l,i,c)}}}(),zc=(e,t)=>(typeof e=="string"?e:ll(e)).indexOf(" "+t+" ")>=0,ka=(e,t)=>{const n=ll(e),r=n+t;zc(n,t)||(e.className=r.substring(1))},La=(e,t)=>{const n=ll(e);if(!zc(e,t))return;const r=n.replace(" "+t+" "," ");e.className=r.substring(1,r.length-1)},ll=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),m2=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)},g2=()=>{Ee(()=>{const e=qn(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||le.start()}),e.afterEach(n=>{t.add(n.path),le.done()})})},b2=kt({setup(){g2()}}),y2=JSON.parse(`{"encrypt":{"config":{"/demo/encrypt.html":["$2a$10$O2SbbkQG8sbldDn2TDqKMeUuPNTEavAhW1L5R907FgzG55F6FZ4Lm"]}},"author":{"name":"憨憨十二","url":"https://mister-hope.com"},"logo":"/logo.svg","repo":"knightio/my-docs","docsDir":"src","footer":"京ICP备2023018079号","displayFooter":true,"contributors":false,"locales":{"/":{"lang":"zh-CN","navbarLocales":{"langName":"简体中文","selectLangAriaLabel":"选择语言"},"metaLocales":{"author":"作者","date":"写作日期","origin":"原创","views":"访问量","category":"分类","tag":"标签","readingTime":"阅读时间","words":"字数","toc":"此页内容","prev":"上一页","next":"下一页","lastUpdated":"上次编辑于","contributors":"贡献者","editLink":"在 GitHub 上编辑此页","print":"打印"},"outlookLocales":{"themeColor":"主题色","darkmode":"外观","fullscreen":"全屏"},"encryptLocales":{"iconLabel":"文章已加密","placeholder":"输入密码","remember":"记住密码","errorHint":"请输入正确的密码"},"routeLocales":{"skipToContent":"跳至主要內容","notFoundTitle":"页面不存在","notFoundMsg":["这里什么也没有","我们是怎么来到这儿的?","这 是 四 零 四 !","看起来你访问了一个失效的链接"],"back":"返回上一页","home":"带我回家","openInNewWindow":"Open in new window"},"navbar":[{"text":"主页","icon":"lightbulb","link":"/"},"/java/","/books/",{"text":"数据库","icon":"lightbulb","link":"/dbs/"},{"text":"Linux","icon":"lightbulb","link":"/linux/"},{"text":"面试","icon":"lightbulb","link":"/interview/"},{"text":"LeetCode","icon":"lightbulb","prefix":"/leetcode/","children":[{"text":"Daily","icon":"lightbulb","link":"daily/"},{"text":"Leetcode-75","icon":"lightbulb","link":"leetcode-75/"}]}],"sidebar":{"/java":"structure","/redis":"structure","/linux":"structure","/interview":"structure","/dbs":"structure","/books":"structure","/":[""]}}}}`),_2=Q(y2),Uc=()=>_2,qc=Symbol(""),E2=()=>{const e=Me(qc);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},w2=(e,t)=>{const{locales:n,...r}=e;return{...r,...n==null?void 0:n[t]}},S2=kt({enhance({app:e}){const t=Uc(),n=e._context.provides[nl],r=A(()=>w2(t.value,n.routeLocale.value));e.provide(qc,r),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return r.value}}})}}),C2=/\b(?:Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini)/i,A2=()=>typeof window<"u"&&window.navigator&&"userAgent"in window.navigator&&C2.test(navigator.userAgent),x2=({delay:e=500,duration:t=2e3,locales:n,selector:r,showInMobile:s})=>{const{copy:o,copied:l}=F0({legacy:!0,copiedDuring:t}),a=Dr(n),i=Te(),c=p=>{if(!p.hasAttribute("copy-code-registered")){const h=document.createElement("button");h.type="button",h.classList.add("vp-copy-code-button"),h.innerHTML='
                            ',h.setAttribute("aria-label",a.value.copy),h.setAttribute("data-copied",a.value.copied),p.parentElement&&p.parentElement.insertBefore(h,p),p.setAttribute("copy-code-registered","")}},u=()=>{Nt().then(()=>Pc(e)).then(()=>{r.forEach(p=>{document.querySelectorAll(p).forEach(c)})})},d=(p,h,b)=>{let{innerText:y=""}=h;/language-(shellscript|shell|bash|sh|zsh)/.test(p.classList.toString())&&(y=y.replace(/^ *(\$|>) /gm,"")),o(y).then(()=>{b.classList.add("copied"),ie(l,()=>{b.classList.remove("copied"),b.blur()},{once:!0})})};Ee(()=>{const p=!A2()||s;p&&u(),Pe("click",h=>{const b=h.target;if(b.matches('div[class*="language-"] > button.copy')){const y=b.parentElement,w=b.nextElementSibling;w&&d(y,w,b)}else if(b.matches('div[class*="language-"] div.vp-copy-icon')){const y=b.parentElement,w=y.parentElement,_=y.nextElementSibling;_&&d(w,_,y)}}),ie(()=>i.value.path,()=>{p&&u()})})};var T2={"/":{copy:"复制代码",copied:"已复制"}},k2=['.theme-hope-content div[class*="language-"] pre'];const L2=kt({setup:()=>{x2({selector:k2,locales:T2,duration:2e3,delay:500,showInMobile:!1})}}),Qr=Gn("VUEPRESS_CODE_TAB_STORE",{});var R2=J({name:"CodeTabs",props:{active:{type:Number,default:0},data:{type:Array,required:!0},id:{type:String,required:!0},tabId:{type:String,default:""}},slots:Object,setup(e,{slots:t}){const n=Q(e.active),r=$e([]),s=()=>{e.tabId&&(Qr.value[e.tabId]=e.data[n.value].id)},o=(c=n.value)=>{n.value=c{n.value=c>0?c-1:r.value.length-1,r.value[n.value].focus()},a=(c,u)=>{c.key===" "||c.key==="Enter"?(c.preventDefault(),n.value=u):c.key==="ArrowRight"?(c.preventDefault(),o()):c.key==="ArrowLeft"&&(c.preventDefault(),l()),e.tabId&&(Qr.value[e.tabId]=e.data[n.value].id)},i=()=>{if(e.tabId){const c=e.data.findIndex(({id:u})=>Qr.value[e.tabId]===u);if(c!==-1)return c}return e.active};return Ee(()=>{n.value=i(),ie(()=>Qr.value[e.tabId],(c,u)=>{if(e.tabId&&c!==u){const d=e.data.findIndex(({id:p})=>p===c);d!==-1&&(n.value=d)}})}),()=>e.data.length?f("div",{class:"vp-code-tabs"},[f("div",{class:"vp-code-tabs-nav",role:"tablist"},e.data.map(({id:c},u)=>{const d=u===n.value;return f("button",{type:"button",ref:p=>{p&&(r.value[u]=p)},class:["vp-code-tab-nav",{active:d}],role:"tab","aria-controls":`codetab-${e.id}-${u}`,"aria-selected":d,onClick:()=>{n.value=u,s()},onKeydown:p=>a(p,u)},t[`title${u}`]({value:c,isActive:d}))})),e.data.map(({id:c},u)=>{const d=u===n.value;return f("div",{class:["vp-code-tab",{active:d}],id:`codetab-${e.id}-${u}`,role:"tabpanel","aria-expanded":d},[f("div",{class:"vp-code-tab-title"},t[`title${u}`]({value:c,isActive:d})),t[`tab${u}`]({value:c,isActive:d})])})]):null}});const Wc=({active:e=!1},{slots:t})=>{var n;return f("div",{class:["code-group-item",{active:e}],"aria-selected":e},(n=t.default)==null?void 0:n.call(t))};Wc.displayName="CodeGroupItem";const P2=J({name:"CodeGroup",slots:Object,setup(e,{slots:t}){const n=Q(-1),r=$e([]),s=(a=n.value)=>{n.value=a{n.value=a>0?a-1:r.value.length-1,r.value[n.value].focus()},l=(a,i)=>{a.key===" "||a.key==="Enter"?(a.preventDefault(),n.value=i):a.key==="ArrowRight"?(a.preventDefault(),s(i)):a.key==="ArrowLeft"&&(a.preventDefault(),o(i))};return()=>{var i;const a=(((i=t.default)==null?void 0:i.call(t))||[]).filter(c=>c.type.name==="CodeGroupItem").map(c=>(c.props===null&&(c.props={}),c));return a.length===0?null:(n.value<0||n.value>a.length-1?(n.value=a.findIndex(c=>"active"in c.props),n.value===-1&&(n.value=0)):a.forEach((c,u)=>{c.props.active=u===n.value}),f("div",{class:"code-group"},[f("div",{class:"code-group-nav"},a.map((c,u)=>{const d=u===n.value;return f("button",{type:"button",ref:p=>{p&&(r.value[u]=p)},class:["code-group-nav-tab",{active:d}],"aria-pressed":d,"aria-expanded":d,onClick:()=>{n.value=u},onKeydown:p=>l(p,u)},c.props.title)})),a]))}}}),ke=({name:e="",color:t="currentColor",ariaLabel:n},{attrs:r,slots:s})=>{var o;return f("svg",{xmlns:"http://www.w3.org/2000/svg",class:["icon",`${e}-icon`],viewBox:"0 0 1024 1024",fill:t,"aria-label":n??`${e} icon`,...r},(o=s.default)==null?void 0:o.call(s))};ke.displayName="IconBase";const Gc=({size:e=48,stroke:t=4,wrapper:n=!0,height:r=2*e})=>{const s=f("svg",{xmlns:"http://www.w3.org/2000/svg",width:e,height:e,preserveAspectRatio:"xMidYMid",viewBox:"25 25 50 50"},[f("animateTransform",{attributeName:"transform",type:"rotate",dur:"2s",keyTimes:"0;1",repeatCount:"indefinite",values:"0;360"}),f("circle",{cx:"50",cy:"50",r:"20",fill:"none",stroke:"currentColor","stroke-width":t,"stroke-linecap":"round"},[f("animate",{attributeName:"stroke-dasharray",dur:"1.5s",keyTimes:"0;0.5;1",repeatCount:"indefinite",values:"1,200;90,200;1,200"}),f("animate",{attributeName:"stroke-dashoffset",dur:"1.5s",keyTimes:"0;0.5;1",repeatCount:"indefinite",values:"0;-35px;-125px"})])]);return n?f("div",{class:"loading-icon-wrapper",style:`display:flex;align-items:center;justify-content:center;height:${r}px`},s):s};Gc.displayName="LoadingIcon";const xs=(e,{slots:t})=>{var n;return(n=t.default)==null?void 0:n.call(t)},O2=e=>bn(e)?e:`https://github.com/${e}`,al=(e="")=>!bn(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,Kc=()=>f(ke,{name:"github"},()=>f("path",{d:"M511.957 21.333C241.024 21.333 21.333 240.981 21.333 512c0 216.832 140.544 400.725 335.574 465.664 24.49 4.395 32.256-10.07 32.256-23.083 0-11.69.256-44.245 0-85.205-136.448 29.61-164.736-64.64-164.736-64.64-22.315-56.704-54.4-71.765-54.4-71.765-44.587-30.464 3.285-29.824 3.285-29.824 49.195 3.413 75.179 50.517 75.179 50.517 43.776 75.008 114.816 53.333 142.762 40.79 4.523-31.66 17.152-53.377 31.19-65.537-108.971-12.458-223.488-54.485-223.488-242.602 0-53.547 19.114-97.323 50.517-131.67-5.035-12.33-21.93-62.293 4.779-129.834 0 0 41.258-13.184 134.912 50.346a469.803 469.803 0 0 1 122.88-16.554c41.642.213 83.626 5.632 122.88 16.554 93.653-63.488 134.784-50.346 134.784-50.346 26.752 67.541 9.898 117.504 4.864 129.834 31.402 34.347 50.474 78.123 50.474 131.67 0 188.586-114.73 230.016-224.042 242.09 17.578 15.232 33.578 44.672 33.578 90.454v135.85c0 13.142 7.936 27.606 32.854 22.87C862.25 912.597 1002.667 728.747 1002.667 512c0-271.019-219.648-490.667-490.71-490.667z"}));Kc.displayName="GitHubIcon";const Jc=()=>f(ke,{name:"gitee"},()=>f("path",{d:"M512 992C246.92 992 32 777.08 32 512S246.92 32 512 32s480 214.92 480 480-214.92 480-480 480zm242.97-533.34H482.39a23.7 23.7 0 0 0-23.7 23.7l-.03 59.28c0 13.08 10.59 23.7 23.7 23.7h165.96a23.7 23.7 0 0 1 23.7 23.7v11.85a71.1 71.1 0 0 1-71.1 71.1H375.71a23.7 23.7 0 0 1-23.7-23.7V423.11a71.1 71.1 0 0 1 71.1-71.1h331.8a23.7 23.7 0 0 0 23.7-23.7l.06-59.25a23.73 23.73 0 0 0-23.7-23.73H423.11a177.78 177.78 0 0 0-177.78 177.75v331.83c0 13.08 10.62 23.7 23.7 23.7h349.62a159.99 159.99 0 0 0 159.99-159.99V482.33a23.7 23.7 0 0 0-23.7-23.7z"}));Jc.displayName="GiteeIcon";const Yc=()=>f(ke,{name:"bitbucket"},()=>f("path",{d:"M575.256 490.862c6.29 47.981-52.005 85.723-92.563 61.147-45.714-20.004-45.714-92.562-1.133-113.152 38.29-23.442 93.696 7.424 93.696 52.005zm63.451-11.996c-10.276-81.152-102.29-134.839-177.152-101.156-47.433 21.138-79.433 71.424-77.129 124.562 2.853 69.705 69.157 126.866 138.862 120.576S647.3 548.571 638.708 478.83zm136.558-309.723c-25.161-33.134-67.986-38.839-105.728-45.13-106.862-17.151-216.576-17.7-323.438 1.134-35.438 5.706-75.447 11.996-97.719 43.996 36.572 34.304 88.576 39.424 135.424 45.129 84.553 10.862 171.447 11.447 256 .585 47.433-5.705 99.987-10.276 135.424-45.714zm32.585 591.433c-16.018 55.99-6.839 131.438-66.304 163.986-102.29 56.576-226.304 62.867-338.87 42.862-59.43-10.862-129.135-29.696-161.72-85.723-14.3-54.858-23.442-110.848-32.585-166.84l3.438-9.142 10.276-5.157c170.277 112.567 408.576 112.567 579.438 0 26.844 8.01 6.84 40.558 6.29 60.014zm103.424-549.157c-19.42 125.148-41.728 249.71-63.415 374.272-6.29 36.572-41.728 57.162-71.424 72.558-106.862 53.724-231.424 62.866-348.562 50.286-79.433-8.558-160.585-29.696-225.134-79.433-30.28-23.443-30.28-63.415-35.986-97.134-20.005-117.138-42.862-234.277-57.161-352.585 6.839-51.42 64.585-73.728 107.447-89.71 57.16-21.138 118.272-30.866 178.87-36.571 129.134-12.58 261.157-8.01 386.304 28.562 44.581 13.13 92.563 31.415 122.844 69.705 13.714 17.7 9.143 40.01 6.29 60.014z"}));Yc.displayName="BitbucketIcon";const Qc=()=>f(ke,{name:"source"},()=>f("path",{d:"M601.92 475.2c0 76.428-8.91 83.754-28.512 99.594-14.652 11.88-43.956 14.058-78.012 16.434-18.81 1.386-40.392 2.97-62.172 6.534-18.612 2.97-36.432 9.306-53.064 17.424V299.772c37.818-21.978 63.36-62.766 63.36-109.692 0-69.894-56.826-126.72-126.72-126.72S190.08 120.186 190.08 190.08c0 46.926 25.542 87.714 63.36 109.692v414.216c-37.818 21.978-63.36 62.766-63.36 109.692 0 69.894 56.826 126.72 126.72 126.72s126.72-56.826 126.72-126.72c0-31.086-11.286-59.598-29.7-81.576 13.266-9.504 27.522-17.226 39.996-19.206 16.038-2.574 32.868-3.762 50.688-5.148 48.312-3.366 103.158-7.326 148.896-44.55 61.182-49.698 74.25-103.158 75.24-187.902V475.2h-126.72zM316.8 126.72c34.848 0 63.36 28.512 63.36 63.36s-28.512 63.36-63.36 63.36-63.36-28.512-63.36-63.36 28.512-63.36 63.36-63.36zm0 760.32c-34.848 0-63.36-28.512-63.36-63.36s28.512-63.36 63.36-63.36 63.36 28.512 63.36 63.36-28.512 63.36-63.36 63.36zM823.68 158.4h-95.04V63.36h-126.72v95.04h-95.04v126.72h95.04v95.04h126.72v-95.04h95.04z"}));Qc.displayName="SourceIcon";const I2=({link:e,type:t=al(e??"")})=>{if(!t)return null;const n=t.toLowerCase();return f(n==="bitbucket"?Yc:n==="github"?Kc:n==="gitlab"?"GitLab":n==="gitee"?Jc:Qc)},D2=(e,t=0)=>{let n=3735928559^t,r=1103547991^t;for(let s=0,o;s>>16,2246822507),n^=Math.imul(r^r>>>13,3266489909),r=Math.imul(r^r>>>16,2246822507),r^=Math.imul(n^n>>>13,3266489909),4294967296*(2097151&r)+(n>>>0)},Xc=(e,t)=>D2(e)%t,Zc=/#.*$/u,$2=e=>{const t=Zc.exec(e);return t?t[0]:""},Ra=e=>decodeURI(e).replace(Zc,"").replace(/\/index\.html$/iu,"/").replace(/\.html$/iu,"").replace(/(README|index)?\.md$/iu,""),eu=(e,t)=>{if(!Rc(t))return!1;const n=Ra(e.path),r=Ra(t),s=$2(t);return s?s===e.hash&&(!r||n===r):n===r};var M2=e=>Object.prototype.toString.call(e)==="[object Object]",yr=e=>typeof e=="string";const tu=Array.isArray,Pa=e=>M2(e)&&yr(e.name),Oa=(e,t=!1)=>e?tu(e)?e.map(n=>yr(n)?{name:n}:Pa(n)?n:null).filter(n=>n!==null):yr(e)?[{name:e}]:Pa(e)?[e]:(console.error(`Expect "author" to be \`AuthorInfo[] | AuthorInfo | string[] | string ${t?"":"| false"} | undefined\`, but got`,e),[]):[],nu=(e,t)=>{if(e){if(tu(e)&&e.every(yr))return e;if(yr(e))return[e];console.error(`Expect ${t} to be \`string[] | string | undefined\`, but got`,e)}return[]},B2=e=>nu(e,"category"),N2=e=>nu(e,"tag"),j2='',F2='';var H2={useBabel:!1,jsLib:[],cssLib:[],codepenLayout:"left",codepenEditors:"101",babel:"https://unpkg.com/@babel/standalone/babel.min.js",vue:"https://unpkg.com/vue/dist/vue.global.prod.js",react:"https://unpkg.com/react/umd/react.production.min.js",reactDOM:"https://unpkg.com/react-dom/umd/react-dom.production.min.js"};const Zs=H2,Ia={html:{types:["html","slim","haml","md","markdown","vue"],map:{html:"none",vue:"none",md:"markdown"}},js:{types:["js","javascript","coffee","coffeescript","ts","typescript","ls","livescript"],map:{js:"none",javascript:"none",coffee:"coffeescript",ls:"livescript",ts:"typescript"}},css:{types:["css","less","sass","scss","stylus","styl"],map:{css:"none",styl:"stylus"}}},V2=(e,t,n)=>{const r=document.createElement(e);return Un(t)&&yn(t).forEach(s=>{if(s.indexOf("data"))r[s]=t[s];else{const o=s.replace("data","");r.dataset[o]=t[s]}}),r},il=e=>({...Zs,...e,jsLib:Array.from(new Set([...Zs.jsLib??[],...e.jsLib??[]])),cssLib:Array.from(new Set([...Zs.cssLib??[],...e.cssLib??[]]))}),$n=(e,t)=>{if(Rc(e[t]))return e[t];const n=new Promise(r=>{var o;const s=document.createElement("script");s.src=t,(o=document.querySelector("body"))==null||o.appendChild(s),s.onload=()=>{r()}});return e[t]=n,n},z2=(e,t)=>{if(t.css&&Array.from(e.childNodes).every(n=>n.nodeName!=="STYLE")){const n=V2("style",{innerHTML:t.css});e.appendChild(n)}},U2=(e,t,n)=>{const r=n.getScript();if(r&&Array.from(t.childNodes).every(s=>s.nodeName!=="SCRIPT")){const s=document.createElement("script");s.appendChild(document.createTextNode(`{const document=window.document.querySelector('#${e} .vp-code-demo-display').shadowRoot; ${r}}`)),t.appendChild(s)}},q2=["html","js","css"],W2=e=>{const t=yn(e),n={html:[],js:[],css:[],isLegal:!1};return q2.forEach(r=>{const s=t.filter(o=>Ia[r].types.includes(o));if(s.length){const o=s[0];n[r]=[e[o].replace(/^\n|\n$/g,""),Ia[r].map[o]??o]}}),n.isLegal=(!n.html.length||n.html[1]==="none")&&(!n.js.length||n.js[1]==="none")&&(!n.css.length||n.css[1]==="none"),n},ru=e=>e.replace(/
                            /g,"
                            ").replace(/<((\S+)[^<]*?)\s+\/>/g,"<$1>"),su=e=>`
                            ${ru(e)}
                            `,G2=e=>`${e.replace("export default ","const $reactApp = ").replace(/App\.__style__(\s*)=(\s*)`([\s\S]*)?`/,"")}; diff --git a/assets/arthas.html-DqXfZ7t8.js b/assets/arthas.html-BmuamiK8.js similarity index 97% rename from assets/arthas.html-DqXfZ7t8.js rename to assets/arthas.html-BmuamiK8.js index 2e0db18..4130c73 100644 --- a/assets/arthas.html-DqXfZ7t8.js +++ b/assets/arthas.html-BmuamiK8.js @@ -1,3 +1,3 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as r,o as n}from"./app-IPkfDkxj.js";const s={};function i(o,e){return n(),a("div",null,e[0]||(e[0]=[r(`

                            arthas

                            热部署

                            retransform /tmp/test.class
                            +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as r,o as n}from"./app-DGSXj59V.js";const s={};function i(o,e){return n(),a("div",null,e[0]||(e[0]=[r(`

                            arthas

                            热部署

                            retransform /tmp/test.class
                             

                            watch 监控方法的执行入参

                            watch class method -x 3 -n 3
                             
                            `,5)]))}const d=t(s,[["render",i],["__file","arthas.html.vue"]]),h=JSON.parse('{"path":"/linux/software/arthas.html","title":"arthas","lang":"zh-CN","frontmatter":{"description":"arthas 热部署 watch 监控方法的执行入参","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/arthas.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"arthas"}],["meta",{"property":"og:description","content":"arthas 热部署 watch 监控方法的执行入参"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"arthas\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"热部署","slug":"热部署","link":"#热部署","children":[]},{"level":2,"title":"watch 监控方法的执行入参","slug":"watch-监控方法的执行入参","link":"#watch-监控方法的执行入参","children":[]}],"git":{"createdTime":1710225495000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.08,"words":23},"filePathRelative":"linux/software/arthas.md","localizedDate":"2024年3月12日","autoDesc":true}');export{d as comp,h as data}; diff --git a/assets/basis.html-XXSTSKO_.js b/assets/basis.html-02RvDNho.js similarity index 96% rename from assets/basis.html-XXSTSKO_.js rename to assets/basis.html-02RvDNho.js index bc47336..7b0d2e2 100644 --- a/assets/basis.html-XXSTSKO_.js +++ b/assets/basis.html-02RvDNho.js @@ -1 +1 @@ -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a as e,o as r}from"./app-IPkfDkxj.js";const n={};function i(s,t){return r(),o("div",null,t[0]||(t[0]=[e("h1",{id:"基础",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基础"},[e("span",null,"基础")])],-1)]))}const m=a(n,[["render",i],["__file","basis.html.vue"]]),l=JSON.parse('{"path":"/java/SpringCloudAlibaba/nacos/basis.html","title":"基础","lang":"zh-CN","frontmatter":{"description":"基础","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/nacos/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"基础"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-10-08T03:40:12.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-10-08T03:40:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-10-08T03:40:12.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1728358812000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.01,"words":2},"filePathRelative":"java/SpringCloudAlibaba/nacos/basis.md","localizedDate":"2023年11月28日","autoDesc":true}');export{m as comp,l as data}; +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a as e,o as r}from"./app-DGSXj59V.js";const n={};function i(s,t){return r(),o("div",null,t[0]||(t[0]=[e("h1",{id:"基础",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基础"},[e("span",null,"基础")])],-1)]))}const m=a(n,[["render",i],["__file","basis.html.vue"]]),l=JSON.parse('{"path":"/java/SpringCloudAlibaba/nacos/basis.html","title":"基础","lang":"zh-CN","frontmatter":{"description":"基础","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/nacos/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"基础"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-10-08T03:40:12.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-10-08T03:40:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-10-08T03:40:12.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1728358812000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.01,"words":2},"filePathRelative":"java/SpringCloudAlibaba/nacos/basis.md","localizedDate":"2023年11月28日","autoDesc":true}');export{m as comp,l as data}; diff --git a/assets/basis.html-CbUDOSOT.js b/assets/basis.html-2JCN_GSw.js similarity index 99% rename from assets/basis.html-CbUDOSOT.js rename to assets/basis.html-2JCN_GSw.js index df63a05..3188f9e 100644 --- a/assets/basis.html-CbUDOSOT.js +++ b/assets/basis.html-2JCN_GSw.js @@ -1,3 +1,3 @@ -import{_ as d}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,b as a,o as r}from"./app-IPkfDkxj.js";const s={};function n(i,t){return r(),e("div",null,t[0]||(t[0]=[a(`

                            pwd 显示当前工作目录的绝对路径 pwd:print working directory 打印工作目录

                            Vim

                            一般模式

                            语法功能描述
                            yy复制光标当前一行
                            y 数字 y复制一段(从第几行到第几行)
                            p箭头移动到目的行粘贴
                            u撤销上一步
                            dd删除光标当前行
                            d 数字 d删除光标(含)后多少行
                            x剪切一个字母,相当于 del
                            X剪切一个字母,相当于 Backspace
                            yw复制一个词
                            dw删除一个词
                            shift+6(^)移动到行头
                            shift+4 ($)移动到行尾
                            shift+g移动到页尾
                            数字+shift+g移动到目标行

                            编辑模式

                            进入编辑模式

                            按键功能
                            i当前光标前
                            a当前光标后
                            o当前光标行的下一行
                            I光标所在行最前
                            A光标所在行最后
                            O当前光标行的上一行

                            退出编辑模式

                            按『Esc』键 退出编辑模式,之后所在的模式为一般模式。

                            指令模式

                            命令功能
                            :w保存
                            :q退出
                            :!强制执行
                            /要查找的词n 查找下一个,N 往上查找
                            :noh取消高亮显示
                            :set nu显示行号
                            :set nonu关闭行号
                            :%s/old/new/g替换内容 /g 替换匹配到的所有内容

                            磁盘查看

                            du 查看文件和目录占用的磁盘空间

                            du: disk usage 磁盘占用情况

                            du [选项] 目录/文件 (功能描述:显示目录下每个子目录的磁盘使用情况)
                            +import{_ as d}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,b as a,o as r}from"./app-DGSXj59V.js";const s={};function n(i,t){return r(),e("div",null,t[0]||(t[0]=[a(`

                            pwd 显示当前工作目录的绝对路径 pwd:print working directory 打印工作目录

                            Vim

                            一般模式

                            语法功能描述
                            yy复制光标当前一行
                            y 数字 y复制一段(从第几行到第几行)
                            p箭头移动到目的行粘贴
                            u撤销上一步
                            dd删除光标当前行
                            d 数字 d删除光标(含)后多少行
                            x剪切一个字母,相当于 del
                            X剪切一个字母,相当于 Backspace
                            yw复制一个词
                            dw删除一个词
                            shift+6(^)移动到行头
                            shift+4 ($)移动到行尾
                            shift+g移动到页尾
                            数字+shift+g移动到目标行

                            编辑模式

                            进入编辑模式

                            按键功能
                            i当前光标前
                            a当前光标后
                            o当前光标行的下一行
                            I光标所在行最前
                            A光标所在行最后
                            O当前光标行的上一行

                            退出编辑模式

                            按『Esc』键 退出编辑模式,之后所在的模式为一般模式。

                            指令模式

                            命令功能
                            :w保存
                            :q退出
                            :!强制执行
                            /要查找的词n 查找下一个,N 往上查找
                            :noh取消高亮显示
                            :set nu显示行号
                            :set nonu关闭行号
                            :%s/old/new/g替换内容 /g 替换匹配到的所有内容

                            磁盘查看

                            du 查看文件和目录占用的磁盘空间

                            du: disk usage 磁盘占用情况

                            du [选项] 目录/文件 (功能描述:显示目录下每个子目录的磁盘使用情况)
                             
                            选项功能
                            -h以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
                            -a不仅查看子目录大小,还要包括文件
                            -c显示所有的文件和子目录大小后,显示总和
                            -s只显示总和
                            --max-depth=n指定统计子目录的深度为第 n 层

                            df 查看磁盘空间使用情况

                            df: disk free 空余磁盘

                            df [选项] (功能描述:列出文件系统的整体磁盘使用量,检查文件系统的磁盘空间占 用情况)
                             
                            选项功能
                            -h以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
                            `,21)]))}const o=d(s,[["render",n],["__file","basis.html.vue"]]),c=JSON.parse('{"path":"/linux/basis/basis.html","title":"基础","lang":"zh-CN","frontmatter":{"title":"基础","description":"pwd 显示当前工作目录的绝对路径 pwd:print working directory 打印工作目录 Vim 一般模式 编辑模式 进入编辑模式 退出编辑模式 按『Esc』键 退出编辑模式,之后所在的模式为一般模式。 指令模式 磁盘查看 du 查看文件和目录占用的磁盘空间 du: disk usage 磁盘占用情况 df 查看磁盘空间使用情况 df:...","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/basis/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"pwd 显示当前工作目录的绝对路径 pwd:print working directory 打印工作目录 Vim 一般模式 编辑模式 进入编辑模式 退出编辑模式 按『Esc』键 退出编辑模式,之后所在的模式为一般模式。 指令模式 磁盘查看 du 查看文件和目录占用的磁盘空间 du: disk usage 磁盘占用情况 df 查看磁盘空间使用情况 df:..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-01-02T13:39:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-01-02T13:39:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-02T13:39:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":3,"title":"","slug":"","link":"#","children":[]},{"level":2,"title":"Vim","slug":"vim","link":"#vim","children":[{"level":3,"title":"一般模式","slug":"一般模式","link":"#一般模式","children":[]},{"level":3,"title":"编辑模式","slug":"编辑模式","link":"#编辑模式","children":[{"level":4,"title":"进入编辑模式","slug":"进入编辑模式","link":"#进入编辑模式","children":[]},{"level":4,"title":"退出编辑模式","slug":"退出编辑模式","link":"#退出编辑模式","children":[]}]},{"level":3,"title":"指令模式","slug":"指令模式","link":"#指令模式","children":[]}]},{"level":2,"title":"磁盘查看","slug":"磁盘查看","link":"#磁盘查看","children":[{"level":3,"title":"du 查看文件和目录占用的磁盘空间","slug":"du-查看文件和目录占用的磁盘空间","link":"#du-查看文件和目录占用的磁盘空间","children":[]}]},{"level":2,"title":"df 查看磁盘空间使用情况","slug":"df-查看磁盘空间使用情况","link":"#df-查看磁盘空间使用情况","children":[]}],"git":{"createdTime":1699343281000,"updatedTime":1704202784000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":3}]},"readingTime":{"minutes":1.81,"words":542},"filePathRelative":"linux/basis/basis.md","localizedDate":"2023年11月7日","autoDesc":true}');export{o as comp,c as data}; diff --git a/assets/basis.html-wEn3fTf7.js b/assets/basis.html-2ahAkI4f.js similarity index 99% rename from assets/basis.html-wEn3fTf7.js rename to assets/basis.html-2ahAkI4f.js index 9e81ce0..618d9c4 100644 --- a/assets/basis.html-wEn3fTf7.js +++ b/assets/basis.html-2ahAkI4f.js @@ -1,4 +1,4 @@ -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as t,o as e}from"./app-IPkfDkxj.js";const c={};function p(l,n){return e(),s("div",null,n[0]||(n[0]=[t(`

                            暂且不知道叫什么

                            基本类型

                            基本类型字节默认值包装类
                            byte10Byte
                            short22Short
                            char2'u0000'Character
                            int40Integer
                            float40fFloat
                            long80LLong
                            double80dDouble
                            booleanfalseBoolean

                            boolean 官方文档未明确定义,依赖于JVMs实现。

                            包装类

                            基本类型有默认值,包装类默认为null

                            基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中,基本数据类型的成员变量(未被 static 修饰 )存放在 Java 虚拟机的堆中。包装类型属于对象类型,我们知道几乎所有对象实例都存在于堆中。

                            为什么说是几乎所有对象实例呢?

                            HotSpot 虚拟机引入了 JIT 优化之后,会对对象进行逃逸分析,如果发现某一个对象并没有逃逸到方法外部,那么就可能通过标量替换来实现栈上分配,而避免堆上分配内存。

                            常量池

                            类型范围
                            Byte,Short,Integer,Long[-128,127]
                            Character[0,127]
                            BooleanTrue,False

                            异常

                            Exception 和 Error

                            • Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获。
                              • Checked Exception (受检查异常,必须处理)
                              • Unchecked Exception (不受检查异常,可以不处理)。
                            • Error:Error 属于程序无法处理的错误 ,不建议通过catch捕获 。例如 Java 虚拟机运行错误(Virtual MachineError)、虚拟机内存不够错误(OutOfMemoryError)、类定义错误(NoClassDefFoundError)等 。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。

                            Checked Exception 和 Unchecked Exception

                            Checked Exception 即 受检查异常 ,Java 代码在编译过程中,如果受检查异常没有被 catch或者throws 关键字处理的话,就没办法通过编译。

                            除了RuntimeException及其子类以外,其他的Exception类及其子类都属于受检查异常。

                            RuntimeException 及其子类都统称为非受检查异常

                            try-catch-finally

                            try块:用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。

                            catch块:用于处理 try 捕获到的异常。

                            finally 块:无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。

                            If the try clause executes a return, the compiled code does the following:

                            1. Saves the return value (if any) in a local variable.
                            2. Executes a jsr to the code for the finally clause.
                            3. Upon return from the finally clause, returns the value saved in the local variable.

                            finally 不一定会执行

                            1. 虚拟机被终止运行
                            2. 程序所在的线程死亡
                            3. 关闭 CPU

                            try-with-resources

                            面对必须要关闭的资源,我们总是应该优先使用 try-with-resources 而不是try-finally。随之产生的代码更简短,更清晰,产生的异常对我们也更有用。try-with-resources语句让我们更容易编写必须要关闭的资源的代码,若采用try-finally则几乎做不到这点。

                            try(
                            +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as t,o as e}from"./app-DGSXj59V.js";const c={};function p(l,n){return e(),s("div",null,n[0]||(n[0]=[t(`

                            暂且不知道叫什么

                            基本类型

                            基本类型字节默认值包装类
                            byte10Byte
                            short22Short
                            char2'u0000'Character
                            int40Integer
                            float40fFloat
                            long80LLong
                            double80dDouble
                            booleanfalseBoolean

                            boolean 官方文档未明确定义,依赖于JVMs实现。

                            包装类

                            基本类型有默认值,包装类默认为null

                            基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中,基本数据类型的成员变量(未被 static 修饰 )存放在 Java 虚拟机的堆中。包装类型属于对象类型,我们知道几乎所有对象实例都存在于堆中。

                            为什么说是几乎所有对象实例呢?

                            HotSpot 虚拟机引入了 JIT 优化之后,会对对象进行逃逸分析,如果发现某一个对象并没有逃逸到方法外部,那么就可能通过标量替换来实现栈上分配,而避免堆上分配内存。

                            常量池

                            类型范围
                            Byte,Short,Integer,Long[-128,127]
                            Character[0,127]
                            BooleanTrue,False

                            异常

                            Exception 和 Error

                            • Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获。
                              • Checked Exception (受检查异常,必须处理)
                              • Unchecked Exception (不受检查异常,可以不处理)。
                            • Error:Error 属于程序无法处理的错误 ,不建议通过catch捕获 。例如 Java 虚拟机运行错误(Virtual MachineError)、虚拟机内存不够错误(OutOfMemoryError)、类定义错误(NoClassDefFoundError)等 。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。

                            Checked Exception 和 Unchecked Exception

                            Checked Exception 即 受检查异常 ,Java 代码在编译过程中,如果受检查异常没有被 catch或者throws 关键字处理的话,就没办法通过编译。

                            除了RuntimeException及其子类以外,其他的Exception类及其子类都属于受检查异常。

                            RuntimeException 及其子类都统称为非受检查异常

                            try-catch-finally

                            try块:用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。

                            catch块:用于处理 try 捕获到的异常。

                            finally 块:无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。

                            If the try clause executes a return, the compiled code does the following:

                            1. Saves the return value (if any) in a local variable.
                            2. Executes a jsr to the code for the finally clause.
                            3. Upon return from the finally clause, returns the value saved in the local variable.

                            finally 不一定会执行

                            1. 虚拟机被终止运行
                            2. 程序所在的线程死亡
                            3. 关闭 CPU

                            try-with-resources

                            面对必须要关闭的资源,我们总是应该优先使用 try-with-resources 而不是try-finally。随之产生的代码更简短,更清晰,产生的异常对我们也更有用。try-with-resources语句让我们更容易编写必须要关闭的资源的代码,若采用try-finally则几乎做不到这点。

                            try(
                                 Scanner scanner = new Scanner(new File("test.txt"))
                             ){
                             
                            diff --git a/assets/basis.html-Jvc2997A.js b/assets/basis.html-95B3ZLlj.js
                            similarity index 99%
                            rename from assets/basis.html-Jvc2997A.js
                            rename to assets/basis.html-95B3ZLlj.js
                            index 76f9618..c13347f 100644
                            --- a/assets/basis.html-Jvc2997A.js
                            +++ b/assets/basis.html-95B3ZLlj.js
                            @@ -1,4 +1,4 @@
                            -import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as i,b as r,o as s}from"./app-IPkfDkxj.js";const d={};function a(l,e){return s(),i("div",null,e[0]||(e[0]=[r(`

                            docker 启动!

                            version: '3.8'
                            +import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as i,b as r,o as s}from"./app-DGSXj59V.js";const d={};function a(l,e){return s(),i("div",null,e[0]||(e[0]=[r(`

                            docker 启动!

                            version: '3.8'
                             services:
                               namesrv:
                                 image: apache/rocketmq:5.2.0
                            diff --git a/assets/basis.html-D-H00zGl.js b/assets/basis.html-BLw4eSnF.js
                            similarity index 96%
                            rename from assets/basis.html-D-H00zGl.js
                            rename to assets/basis.html-BLw4eSnF.js
                            index 67a7e6a..1c49002 100644
                            --- a/assets/basis.html-D-H00zGl.js
                            +++ b/assets/basis.html-BLw4eSnF.js
                            @@ -1 +1 @@
                            -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a as e,o as r}from"./app-IPkfDkxj.js";const n={};function i(p,t){return r(),o("div",null,t[0]||(t[0]=[e("h1",{id:"基础",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基础"},[e("span",null,"基础")])],-1)]))}const m=a(n,[["render",i],["__file","basis.html.vue"]]),l=JSON.parse('{"path":"/java/SpringCloudAlibaba/dubbo/basis.html","title":"基础","lang":"zh-CN","frontmatter":{"description":"基础","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/dubbo/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"基础"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-10-08T03:40:12.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-10-08T03:40:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-10-08T03:40:12.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1728358812000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.01,"words":2},"filePathRelative":"java/SpringCloudAlibaba/dubbo/basis.md","localizedDate":"2023年11月28日","autoDesc":true}');export{m as comp,l as data};
                            +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a as e,o as r}from"./app-DGSXj59V.js";const n={};function i(p,t){return r(),o("div",null,t[0]||(t[0]=[e("h1",{id:"基础",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基础"},[e("span",null,"基础")])],-1)]))}const m=a(n,[["render",i],["__file","basis.html.vue"]]),l=JSON.parse('{"path":"/java/SpringCloudAlibaba/dubbo/basis.html","title":"基础","lang":"zh-CN","frontmatter":{"description":"基础","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/dubbo/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"基础"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-10-08T03:40:12.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-10-08T03:40:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-10-08T03:40:12.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1728358812000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.01,"words":2},"filePathRelative":"java/SpringCloudAlibaba/dubbo/basis.md","localizedDate":"2023年11月28日","autoDesc":true}');export{m as comp,l as data};
                            diff --git a/assets/basis.html-zu40gkWN.js b/assets/basis.html-CV6VoMyY.js
                            similarity index 99%
                            rename from assets/basis.html-zu40gkWN.js
                            rename to assets/basis.html-CV6VoMyY.js
                            index 42d27a1..924ac29 100644
                            --- a/assets/basis.html-zu40gkWN.js
                            +++ b/assets/basis.html-CV6VoMyY.js
                            @@ -1,4 +1,4 @@
                            -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,b as i,o as n}from"./app-IPkfDkxj.js";const s={};function l(r,e){return n(),t("div",null,e[0]||(e[0]=[i(`

                            基础

                            分布式事务

                            下载

                            https://github.com/apache/incubator-seata/releases

                            Usage: sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows) [options]
                            +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,b as i,o as n}from"./app-DGSXj59V.js";const s={};function l(r,e){return n(),t("div",null,e[0]||(e[0]=[i(`

                            基础

                            分布式事务

                            下载

                            https://github.com/apache/incubator-seata/releases

                            Usage: sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows) [options]
                               Options:
                                 --host, -h
                                   The address is expose to registration center and other service can access seata-server via this ip
                            diff --git a/assets/basis.html-Ds0kWP9C.js b/assets/basis.html-Cl860v1g.js
                            similarity index 96%
                            rename from assets/basis.html-Ds0kWP9C.js
                            rename to assets/basis.html-Cl860v1g.js
                            index 7011810..5a789c7 100644
                            --- a/assets/basis.html-Ds0kWP9C.js
                            +++ b/assets/basis.html-Cl860v1g.js
                            @@ -1 +1 @@
                            -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a as e,o as n}from"./app-IPkfDkxj.js";const r={};function i(s,t){return n(),o("div",null,t[0]||(t[0]=[e("h1",{id:"基础",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基础"},[e("span",null,"基础")])],-1)]))}const l=a(r,[["render",i],["__file","basis.html.vue"]]),m=JSON.parse('{"path":"/java/SpringCloudAlibaba/sentinel/basis.html","title":"基础","lang":"zh-CN","frontmatter":{"description":"基础","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/sentinel/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"基础"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-10-08T03:40:12.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-10-08T03:40:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-10-08T03:40:12.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1728358812000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.01,"words":2},"filePathRelative":"java/SpringCloudAlibaba/sentinel/basis.md","localizedDate":"2023年11月28日","autoDesc":true}');export{l as comp,m as data};
                            +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a as e,o as n}from"./app-DGSXj59V.js";const r={};function i(s,t){return n(),o("div",null,t[0]||(t[0]=[e("h1",{id:"基础",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基础"},[e("span",null,"基础")])],-1)]))}const l=a(r,[["render",i],["__file","basis.html.vue"]]),m=JSON.parse('{"path":"/java/SpringCloudAlibaba/sentinel/basis.html","title":"基础","lang":"zh-CN","frontmatter":{"description":"基础","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/sentinel/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"基础"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-10-08T03:40:12.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-10-08T03:40:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-10-08T03:40:12.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1728358812000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.01,"words":2},"filePathRelative":"java/SpringCloudAlibaba/sentinel/basis.md","localizedDate":"2023年11月28日","autoDesc":true}');export{l as comp,m as data};
                            diff --git a/assets/basis.html-BxbtaanI.js b/assets/basis.html-DQim-pLK.js
                            similarity index 97%
                            rename from assets/basis.html-BxbtaanI.js
                            rename to assets/basis.html-DQim-pLK.js
                            index f515cb7..9bf732f 100644
                            --- a/assets/basis.html-BxbtaanI.js
                            +++ b/assets/basis.html-DQim-pLK.js
                            @@ -1,2 +1,2 @@
                            -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as r,o}from"./app-IPkfDkxj.js";const d={};function n(i,t){return o(),a("div",null,t[0]||(t[0]=[r(`

                            基础工具

                            curl

                            curl [options...] <url>
                            +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as r,o}from"./app-DGSXj59V.js";const d={};function n(i,t){return o(),a("div",null,t[0]||(t[0]=[r(`

                            基础工具

                            curl

                            curl [options...] <url>
                             

                            默认为GET请求

                            常用options

                            options作用示例
                            -X / --request请求方式-X POST
                            -d / --data请求数据-d '{"test": 1}'
                            -H / --header请求头-H 'Content-Type:application/json'
                            -v / --verbose显示请求的信息-v
                            -V / --version显示版本-V
                            `,6)]))}const c=e(d,[["render",n],["__file","basis.html.vue"]]),p=JSON.parse('{"path":"/linux/software/basis.html","title":"基础工具","lang":"zh-CN","frontmatter":{"description":"基础工具 curl 默认为GET请求 常用options","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础工具"}],["meta",{"property":"og:description","content":"基础工具 curl 默认为GET请求 常用options"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-11-05T06:43:49.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-11-05T06:43:49.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础工具\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-11-05T06:43:49.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"curl","slug":"curl","link":"#curl","children":[]}],"git":{"createdTime":1730789029000,"updatedTime":1730789029000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.23,"words":70},"filePathRelative":"linux/software/basis.md","localizedDate":"2024年11月5日","autoDesc":true}');export{c as comp,p as data}; diff --git a/assets/basis.html-6Q8zK8Bd.js b/assets/basis.html-DUj1Wnj7.js similarity index 96% rename from assets/basis.html-6Q8zK8Bd.js rename to assets/basis.html-DUj1Wnj7.js index a2249f4..0fb6d71 100644 --- a/assets/basis.html-6Q8zK8Bd.js +++ b/assets/basis.html-DUj1Wnj7.js @@ -1 +1 @@ -import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,a as t,o as r}from"./app-IPkfDkxj.js";const n={};function i(m,e){return r(),a("div",null,e[0]||(e[0]=[t("h1",{id:"基础todo",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#基础todo"},[t("span",null,"基础todo")])],-1)]))}const p=o(n,[["render",i],["__file","basis.html.vue"]]),d=JSON.parse('{"path":"/java/jvm/basis.html","title":"基础todo","lang":"zh-CN","frontmatter":{"description":"基础todo","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/jvm/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础todo"}],["meta",{"property":"og:description","content":"基础todo"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-08-30T03:49:20.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-08-30T03:49:20.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础todo\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-08-30T03:49:20.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701870112000,"updatedTime":1724989760000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1},{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.01,"words":3},"filePathRelative":"java/jvm/basis.md","localizedDate":"2023年12月6日","autoDesc":true}');export{p as comp,d as data}; +import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,a as t,o as r}from"./app-DGSXj59V.js";const n={};function i(m,e){return r(),a("div",null,e[0]||(e[0]=[t("h1",{id:"基础todo",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#基础todo"},[t("span",null,"基础todo")])],-1)]))}const p=o(n,[["render",i],["__file","basis.html.vue"]]),d=JSON.parse('{"path":"/java/jvm/basis.html","title":"基础todo","lang":"zh-CN","frontmatter":{"description":"基础todo","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/jvm/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础todo"}],["meta",{"property":"og:description","content":"基础todo"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-08-30T03:49:20.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-08-30T03:49:20.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础todo\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-08-30T03:49:20.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701870112000,"updatedTime":1724989760000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1},{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.01,"words":3},"filePathRelative":"java/jvm/basis.md","localizedDate":"2023年12月6日","autoDesc":true}');export{p as comp,d as data}; diff --git a/assets/basis.html-BeJJBQWv.js b/assets/basis.html-DZPqHWrC.js similarity index 98% rename from assets/basis.html-BeJJBQWv.js rename to assets/basis.html-DZPqHWrC.js index 2c41eca..0156f0b 100644 --- a/assets/basis.html-BeJJBQWv.js +++ b/assets/basis.html-DZPqHWrC.js @@ -1,4 +1,4 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as n,o as s}from"./app-IPkfDkxj.js";const i={};function d(l,e){return s(),a("div",null,e[0]||(e[0]=[n(`

                            基础

                            定义

                            关系型数据库 RDBElasticsearch
                            数据库 database索引 index
                            表 table类型 type
                            行 rows文档 documents
                            字段 column字段 fields
                            字段属性、键映射 mapping

                            增删改查

                            添加

                            添加类型

                            查询

                            查询所有索引 (Index)

                            GET
                            +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as n,o as s}from"./app-DGSXj59V.js";const i={};function d(l,e){return s(),a("div",null,e[0]||(e[0]=[n(`

                            基础

                            定义

                            关系型数据库 RDBElasticsearch
                            数据库 database索引 index
                            表 table类型 type
                            行 rows文档 documents
                            字段 column字段 fields
                            字段属性、键映射 mapping

                            增删改查

                            添加

                            添加类型

                            查询

                            查询所有索引 (Index)

                            GET
                             
                             localhost:9200/_cat/indices
                             

                            查询索引信息

                            POST
                            diff --git a/assets/basis.html-DHIr7USm.js b/assets/basis.html-GlRiLsmg.js
                            similarity index 96%
                            rename from assets/basis.html-DHIr7USm.js
                            rename to assets/basis.html-GlRiLsmg.js
                            index 7769880..012c3c8 100644
                            --- a/assets/basis.html-DHIr7USm.js
                            +++ b/assets/basis.html-GlRiLsmg.js
                            @@ -1 +1 @@
                            -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a as e,o as r}from"./app-IPkfDkxj.js";const n={};function i(s,t){return r(),o("div",null,t[0]||(t[0]=[e("h1",{id:"基础",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基础"},[e("span",null,"基础")])],-1),e("h1",{id:"线程池",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#线程池"},[e("span",null,"线程池")])],-1)]))}const m=a(n,[["render",i],["__file","basis.html.vue"]]),d=JSON.parse('{"path":"/java/thread/basis.html","title":"基础","lang":"zh-CN","frontmatter":{"description":"基础 线程池","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/thread/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"基础 线程池"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1710225495000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.02,"words":5},"filePathRelative":"java/thread/basis.md","localizedDate":"2024年3月12日","autoDesc":true}');export{m as comp,d as data};
                            +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a as e,o as r}from"./app-DGSXj59V.js";const n={};function i(s,t){return r(),o("div",null,t[0]||(t[0]=[e("h1",{id:"基础",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基础"},[e("span",null,"基础")])],-1),e("h1",{id:"线程池",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#线程池"},[e("span",null,"线程池")])],-1)]))}const m=a(n,[["render",i],["__file","basis.html.vue"]]),d=JSON.parse('{"path":"/java/thread/basis.html","title":"基础","lang":"zh-CN","frontmatter":{"description":"基础 线程池","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/thread/basis.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"基础 线程池"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1710225495000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.02,"words":5},"filePathRelative":"java/thread/basis.md","localizedDate":"2024年3月12日","autoDesc":true}');export{m as comp,d as data};
                            diff --git a/assets/demo.html-_U9HoCj_.js b/assets/demo.html-CkMNEXQC.js
                            similarity index 99%
                            rename from assets/demo.html-_U9HoCj_.js
                            rename to assets/demo.html-CkMNEXQC.js
                            index 34fa02d..20be7cf 100644
                            --- a/assets/demo.html-_U9HoCj_.js
                            +++ b/assets/demo.html-CkMNEXQC.js
                            @@ -1,4 +1,4 @@
                            -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as e,o as t}from"./app-IPkfDkxj.js";const p={};function o(c,n){return t(),s("div",null,n[0]||(n[0]=[e(`

                            Spring

                            web请求数据绑定

                            HandlerMethodArgumentResolverComposite.resolveArgument() ->


                            GET

                            ModelAttributeMethodProcessor.resolveArgument() ->

                            WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
                            +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as e,o as t}from"./app-DGSXj59V.js";const p={};function o(c,n){return t(),s("div",null,n[0]||(n[0]=[e(`

                            Spring

                            web请求数据绑定

                            HandlerMethodArgumentResolverComposite.resolveArgument() ->


                            GET

                            ModelAttributeMethodProcessor.resolveArgument() ->

                            WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
                             if (binder.getTarget() != null) {
                                 if (!mavContainer.isBindingDisabled(name)) {
                                     bindRequestParameters(binder, webRequest);
                            diff --git a/assets/drone.html-CbMyU2PH.js b/assets/drone.html-D1mwj-od.js
                            similarity index 98%
                            rename from assets/drone.html-CbMyU2PH.js
                            rename to assets/drone.html-D1mwj-od.js
                            index 1ac0a8f..3fedab2 100644
                            --- a/assets/drone.html-CbMyU2PH.js
                            +++ b/assets/drone.html-D1mwj-od.js
                            @@ -1,4 +1,4 @@
                            -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as i,o as a}from"./app-IPkfDkxj.js";const r={};function o(d,e){return a(),n("div",null,e[0]||(e[0]=[i(`

                            drone

                            与gitea 集成

                            启动

                            docker run \\
                            +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,b as i,o as a}from"./app-DGSXj59V.js";const r={};function o(d,e){return a(),n("div",null,e[0]||(e[0]=[i(`

                            drone

                            与gitea 集成

                            启动

                            docker run \\
                               --volume=/home/data/drone/data:/data \\
                               --env=DRONE_GITEA_SERVER=https://try.gitea.io \\
                               --env=DRONE_GITEA_CLIENT_ID=05136e57d80189bef462 \\
                            diff --git a/assets/dump.html-CgS7EZ3W.js b/assets/dump.html-upIgPA-c.js
                            similarity index 97%
                            rename from assets/dump.html-CgS7EZ3W.js
                            rename to assets/dump.html-upIgPA-c.js
                            index 82ba2a3..7ee1243 100644
                            --- a/assets/dump.html-CgS7EZ3W.js
                            +++ b/assets/dump.html-upIgPA-c.js
                            @@ -1 +1 @@
                            -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as s,o as n}from"./app-IPkfDkxj.js";const p={};function r(o,e){return n(),a("div",null,e[0]||(e[0]=[s('

                            从全库备份中抽取出t表的表结构

                            sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `t`/!d;q' dump.sql\n

                            从全库备份中抽取出t表的内容

                            grep  'INSERT INTO `t`' dump.sql\n\n\ngrep -C 3  'INSERT INTO `t`' dump.sql\n
                            ',4)]))}const l=t(p,[["render",r],["__file","dump.html.vue"]]),c=JSON.parse('{"path":"/dbs/mysql/dump.html","title":"dump","lang":"zh-CN","frontmatter":{"title":"dump","order":2,"description":"从全库备份中抽取出t表的表结构 从全库备份中抽取出t表的内容","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/mysql/dump.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"dump"}],["meta",{"property":"og:description","content":"从全库备份中抽取出t表的表结构 从全库备份中抽取出t表的内容"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-10-08T03:40:12.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-10-08T03:40:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"dump\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-10-08T03:40:12.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1728358812000,"updatedTime":1728358812000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.2,"words":61},"filePathRelative":"dbs/mysql/dump.md","localizedDate":"2024年10月8日","autoDesc":true}');export{l as comp,c as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as s,o as n}from"./app-DGSXj59V.js";const p={};function r(o,e){return n(),a("div",null,e[0]||(e[0]=[s('

                            从全库备份中抽取出t表的表结构

                            sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `t`/!d;q' dump.sql\n

                            从全库备份中抽取出t表的内容

                            grep  'INSERT INTO `t`' dump.sql\n\n\ngrep -C 3  'INSERT INTO `t`' dump.sql\n
                            ',4)]))}const l=t(p,[["render",r],["__file","dump.html.vue"]]),c=JSON.parse('{"path":"/dbs/mysql/dump.html","title":"dump","lang":"zh-CN","frontmatter":{"title":"dump","order":2,"description":"从全库备份中抽取出t表的表结构 从全库备份中抽取出t表的内容","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/mysql/dump.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"dump"}],["meta",{"property":"og:description","content":"从全库备份中抽取出t表的表结构 从全库备份中抽取出t表的内容"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-10-08T03:40:12.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-10-08T03:40:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"dump\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-10-08T03:40:12.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1728358812000,"updatedTime":1728358812000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.2,"words":61},"filePathRelative":"dbs/mysql/dump.md","localizedDate":"2024年10月8日","autoDesc":true}');export{l as comp,c as data}; diff --git a/assets/index.html-CZl1qWB6.js b/assets/index.html-9CuuwwcO.js similarity index 94% rename from assets/index.html-CZl1qWB6.js rename to assets/index.html-9CuuwwcO.js index 1c7d277..21e545c 100644 --- a/assets/index.html-CZl1qWB6.js +++ b/assets/index.html-9CuuwwcO.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,e as o,o as n,r}from"./app-IPkfDkxj.js";const p={};function l(s,c){const e=r("Catalog");return n(),a("div",null,[o(e)])}const d=t(p,[["render",l],["__file","index.html.vue"]]),g=JSON.parse('{"path":"/java/SpringCloudAlibaba/seata/","title":"Seata","lang":"zh-CN","frontmatter":{"title":"Seata","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/seata/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Seata"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Seata\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,g as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,e as o,o as n,r}from"./app-DGSXj59V.js";const p={};function l(s,c){const e=r("Catalog");return n(),a("div",null,[o(e)])}const d=t(p,[["render",l],["__file","index.html.vue"]]),g=JSON.parse('{"path":"/java/SpringCloudAlibaba/seata/","title":"Seata","lang":"zh-CN","frontmatter":{"title":"Seata","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/seata/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Seata"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Seata\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,g as data}; diff --git a/assets/index.html-DJf5TL8z.js b/assets/index.html-B9KtETue.js similarity index 94% rename from assets/index.html-DJf5TL8z.js rename to assets/index.html-B9KtETue.js index b7595a5..bbe4bbf 100644 --- a/assets/index.html-DJf5TL8z.js +++ b/assets/index.html-B9KtETue.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-IPkfDkxj.js";const p={};function l(c,s){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(p,[["render",l],["__file","index.html.vue"]]),b=JSON.parse('{"path":"/java/SpringCloudAlibaba/dubbo/","title":"Dubbo","lang":"zh-CN","frontmatter":{"title":"Dubbo","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/dubbo/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Dubbo"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Dubbo\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,b as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-DGSXj59V.js";const p={};function l(c,s){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(p,[["render",l],["__file","index.html.vue"]]),b=JSON.parse('{"path":"/java/SpringCloudAlibaba/dubbo/","title":"Dubbo","lang":"zh-CN","frontmatter":{"title":"Dubbo","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/dubbo/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Dubbo"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Dubbo\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,b as data}; diff --git a/assets/index.html-Cgvzxj0k.js b/assets/index.html-BgmHQsum.js similarity index 94% rename from assets/index.html-Cgvzxj0k.js rename to assets/index.html-BgmHQsum.js index 921389d..b5bd857 100644 --- a/assets/index.html-Cgvzxj0k.js +++ b/assets/index.html-BgmHQsum.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-IPkfDkxj.js";const c={};function s(p,l){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(c,[["render",s],["__file","index.html.vue"]]),g=JSON.parse('{"path":"/java/SpringCloudAlibaba/nacos/","title":"Nacos","lang":"zh-CN","frontmatter":{"title":"Nacos","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/nacos/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Nacos"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Nacos\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,g as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-DGSXj59V.js";const c={};function s(p,l){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(c,[["render",s],["__file","index.html.vue"]]),g=JSON.parse('{"path":"/java/SpringCloudAlibaba/nacos/","title":"Nacos","lang":"zh-CN","frontmatter":{"title":"Nacos","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/nacos/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Nacos"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Nacos\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,g as data}; diff --git a/assets/index.html-WkXnwUCZ.js b/assets/index.html-BjuNRCNw.js similarity index 95% rename from assets/index.html-WkXnwUCZ.js rename to assets/index.html-BjuNRCNw.js index d72e346..51837e1 100644 --- a/assets/index.html-WkXnwUCZ.js +++ b/assets/index.html-BjuNRCNw.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const r={};function a(n,c){return o(),t("div")}const p=e(r,[["render",a],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/java/rocketmq/","title":"rocket","lang":"zh-CN","frontmatter":{"title":"rocket","icon":"lightbulb","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/rocketmq/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"rocket"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-06-07T09:24:38.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-06-07T09:24:38.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"rocket\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-06-07T09:24:38.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1717752278000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.02,"words":6},"filePathRelative":"java/rocketmq/README.md","localizedDate":"2023年11月28日"}');export{p as comp,s as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const r={};function a(n,c){return o(),t("div")}const p=e(r,[["render",a],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/java/rocketmq/","title":"rocket","lang":"zh-CN","frontmatter":{"title":"rocket","icon":"lightbulb","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/rocketmq/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"rocket"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-06-07T09:24:38.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-06-07T09:24:38.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"rocket\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-06-07T09:24:38.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1717752278000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.02,"words":6},"filePathRelative":"java/rocketmq/README.md","localizedDate":"2023年11月28日"}');export{p as comp,s as data}; diff --git a/assets/index.html-Dlv9CWZJ.js b/assets/index.html-Bk17tqnU.js similarity index 94% rename from assets/index.html-Dlv9CWZJ.js rename to assets/index.html-Bk17tqnU.js index c323060..a4b71c4 100644 --- a/assets/index.html-Dlv9CWZJ.js +++ b/assets/index.html-Bk17tqnU.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-IPkfDkxj.js";const s={};function p(c,l){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(s,[["render",p],["__file","index.html.vue"]]),h=JSON.parse('{"path":"/books/","title":"Books","lang":"zh-CN","frontmatter":{"title":"Books","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Books"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Books\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,h as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-DGSXj59V.js";const s={};function p(c,l){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(s,[["render",p],["__file","index.html.vue"]]),h=JSON.parse('{"path":"/books/","title":"Books","lang":"zh-CN","frontmatter":{"title":"Books","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Books"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Books\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,h as data}; diff --git a/assets/index.html-BFkKlz8G.js b/assets/index.html-BmE5rtpR.js similarity index 95% rename from assets/index.html-BFkKlz8G.js rename to assets/index.html-BmE5rtpR.js index 6a84e60..545d719 100644 --- a/assets/index.html-BFkKlz8G.js +++ b/assets/index.html-BmE5rtpR.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const n={};function a(r,i){return o(),t("div")}const m=e(n,[["render",a],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/linux/","title":"Linux","lang":"zh-CN","frontmatter":{"title":"Linux","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Linux"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Linux\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1690729537000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":3}]},"readingTime":{"minutes":0.01,"words":4},"filePathRelative":"linux/README.md","localizedDate":"2023年7月30日"}');export{m as comp,l as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const n={};function a(r,i){return o(),t("div")}const m=e(n,[["render",a],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/linux/","title":"Linux","lang":"zh-CN","frontmatter":{"title":"Linux","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Linux"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Linux\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1690729537000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":3}]},"readingTime":{"minutes":0.01,"words":4},"filePathRelative":"linux/README.md","localizedDate":"2023年7月30日"}');export{m as comp,l as data}; diff --git a/assets/index.html-CDxqUD9S.js b/assets/index.html-BmNTlG-Z.js similarity index 96% rename from assets/index.html-CDxqUD9S.js rename to assets/index.html-BmNTlG-Z.js index bf1357f..ec7ec35 100644 --- a/assets/index.html-CDxqUD9S.js +++ b/assets/index.html-BmNTlG-Z.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o as a}from"./app-IPkfDkxj.js";const o={};function n(r,i){return a(),t("div")}const p=e(o,[["render",n],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/java/basis/","title":"基础","lang":"zh-CN","frontmatter":{"title":"基础","index":false,"order":1,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/basis/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-05-27T06:50:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-05-27T06:50:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-05-27T06:50:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1699343281000,"updatedTime":1716792644000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":2},{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.02,"words":7},"filePathRelative":"java/basis/README.md","localizedDate":"2023年11月7日"}');export{p as comp,s as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o as a}from"./app-DGSXj59V.js";const o={};function n(r,i){return a(),t("div")}const p=e(o,[["render",n],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/java/basis/","title":"基础","lang":"zh-CN","frontmatter":{"title":"基础","index":false,"order":1,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/basis/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-05-27T06:50:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-05-27T06:50:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-05-27T06:50:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1699343281000,"updatedTime":1716792644000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":2},{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.02,"words":7},"filePathRelative":"java/basis/README.md","localizedDate":"2023年11月7日"}');export{p as comp,s as data}; diff --git a/assets/index.html-je-vdzFE.js b/assets/index.html-BnG1jZ_a.js similarity index 96% rename from assets/index.html-je-vdzFE.js rename to assets/index.html-BnG1jZ_a.js index eeee5cb..59eb637 100644 --- a/assets/index.html-je-vdzFE.js +++ b/assets/index.html-BnG1jZ_a.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const a={};function n(r,i){return o(),t("div")}const p=e(a,[["render",n],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/books/UnderStandingTheJvm/","title":"深入理解Java虚拟机","lang":"zh-CN","frontmatter":{"title":"深入理解Java虚拟机","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"深入理解Java虚拟机"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"深入理解Java虚拟机\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1691076771000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.04,"words":11},"filePathRelative":"books/UnderStandingTheJvm/README.md","localizedDate":"2023年8月3日"}');export{p as comp,s as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const a={};function n(r,i){return o(),t("div")}const p=e(a,[["render",n],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/books/UnderStandingTheJvm/","title":"深入理解Java虚拟机","lang":"zh-CN","frontmatter":{"title":"深入理解Java虚拟机","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"深入理解Java虚拟机"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"深入理解Java虚拟机\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1691076771000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.04,"words":11},"filePathRelative":"books/UnderStandingTheJvm/README.md","localizedDate":"2023年8月3日"}');export{p as comp,s as data}; diff --git a/assets/index.html-CQfPShe9.js b/assets/index.html-BqzKiupE.js similarity index 96% rename from assets/index.html-CQfPShe9.js rename to assets/index.html-BqzKiupE.js index bf4aa55..dee8ad9 100644 --- a/assets/index.html-CQfPShe9.js +++ b/assets/index.html-BqzKiupE.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const a={};function n(r,i){return o(),t("div")}const p=e(a,[["render",n],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/leetcode/daily/","title":"每日一题","lang":"zh-CN","frontmatter":{"title":"每日一题","icon":"lightbulb","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/daily/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"每日一题"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-07-31T03:10:06.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-07-31T03:10:06.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"每日一题\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-07-31T03:10:06.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1690729537000,"updatedTime":1690773006000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":1},{"name":"wangkai","email":"wangkai@yqun.com.cn","commits":1}]},"readingTime":{"minutes":0.02,"words":7},"filePathRelative":"leetcode/daily/README.md","localizedDate":"2023年7月30日"}');export{p as comp,l as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const a={};function n(r,i){return o(),t("div")}const p=e(a,[["render",n],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/leetcode/daily/","title":"每日一题","lang":"zh-CN","frontmatter":{"title":"每日一题","icon":"lightbulb","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/daily/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"每日一题"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-07-31T03:10:06.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-07-31T03:10:06.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"每日一题\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-07-31T03:10:06.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1690729537000,"updatedTime":1690773006000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":1},{"name":"wangkai","email":"wangkai@yqun.com.cn","commits":1}]},"readingTime":{"minutes":0.02,"words":7},"filePathRelative":"leetcode/daily/README.md","localizedDate":"2023年7月30日"}');export{p as comp,l as data}; diff --git a/assets/index.html-6X9t5qpu.js b/assets/index.html-C6tUEycf.js similarity index 95% rename from assets/index.html-6X9t5qpu.js rename to assets/index.html-C6tUEycf.js index ead3162..7d90d99 100644 --- a/assets/index.html-6X9t5qpu.js +++ b/assets/index.html-C6tUEycf.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const a={};function n(r,i){return o(),t("div")}const m=e(a,[["render",n],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/dbs/","title":"数据库DB","lang":"zh-CN","frontmatter":{"title":"数据库DB","icon":"lightbulb","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"数据库DB"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-06-14T09:34:35.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-06-14T09:34:35.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"数据库DB\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-06-14T09:34:35.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1718357675000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.03,"words":9},"filePathRelative":"dbs/README.md","localizedDate":"2023年11月28日"}');export{m as comp,s as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const a={};function n(r,i){return o(),t("div")}const m=e(a,[["render",n],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/dbs/","title":"数据库DB","lang":"zh-CN","frontmatter":{"title":"数据库DB","icon":"lightbulb","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"数据库DB"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-06-14T09:34:35.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-06-14T09:34:35.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"数据库DB\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-06-14T09:34:35.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1718357675000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.03,"words":9},"filePathRelative":"dbs/README.md","localizedDate":"2023年11月28日"}');export{m as comp,s as data}; diff --git a/assets/index.html-DpohJUce.js b/assets/index.html-CMFNipnT.js similarity index 95% rename from assets/index.html-DpohJUce.js rename to assets/index.html-CMFNipnT.js index c7acd99..2454cf5 100644 --- a/assets/index.html-DpohJUce.js +++ b/assets/index.html-CMFNipnT.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const a={};function r(n,i){return o(),t("div")}const m=e(a,[["render",r],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/linux/software/","title":"软件","lang":"zh-CN","frontmatter":{"title":"软件","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"软件"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"软件\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1699343281000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":2}]},"readingTime":{"minutes":0.02,"words":5},"filePathRelative":"linux/software/README.md","localizedDate":"2023年11月7日"}');export{m as comp,s as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const a={};function r(n,i){return o(),t("div")}const m=e(a,[["render",r],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/linux/software/","title":"软件","lang":"zh-CN","frontmatter":{"title":"软件","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"软件"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"软件\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1699343281000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":2}]},"readingTime":{"minutes":0.02,"words":5},"filePathRelative":"linux/software/README.md","localizedDate":"2023年11月7日"}');export{m as comp,s as data}; diff --git a/assets/index.html-BVtf9Xg2.js b/assets/index.html-Caayfztk.js similarity index 95% rename from assets/index.html-BVtf9Xg2.js rename to assets/index.html-Caayfztk.js index 27ad813..d633550 100644 --- a/assets/index.html-BVtf9Xg2.js +++ b/assets/index.html-Caayfztk.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const r={};function n(a,i){return o(),t("div")}const m=e(r,[["render",n],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/linux/archLinux/","title":"ArchLinux","lang":"zh-CN","frontmatter":{"title":"ArchLinux","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/archLinux/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"ArchLinux"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"ArchLinux\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1699343281000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":2}]},"readingTime":{"minutes":0.01,"words":4},"filePathRelative":"linux/archLinux/README.md","localizedDate":"2023年11月7日"}');export{m as comp,l as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const r={};function n(a,i){return o(),t("div")}const m=e(r,[["render",n],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/linux/archLinux/","title":"ArchLinux","lang":"zh-CN","frontmatter":{"title":"ArchLinux","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/archLinux/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"ArchLinux"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"ArchLinux\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1699343281000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":2}]},"readingTime":{"minutes":0.01,"words":4},"filePathRelative":"linux/archLinux/README.md","localizedDate":"2023年11月7日"}');export{m as comp,l as data}; diff --git a/assets/index.html-Bito5Fo8.js b/assets/index.html-Cz8jDxAY.js similarity index 95% rename from assets/index.html-Bito5Fo8.js rename to assets/index.html-Cz8jDxAY.js index a823f55..208c1b7 100644 --- a/assets/index.html-Bito5Fo8.js +++ b/assets/index.html-Cz8jDxAY.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const r={};function a(n,i){return o(),t("div")}const m=e(r,[["render",a],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/java/spring/","title":"Spring","lang":"zh-CN","frontmatter":{"title":"Spring","index":false,"order":2,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/spring/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Spring"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Spring\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1699343281000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":2}]},"readingTime":{"minutes":0.02,"words":6},"filePathRelative":"java/spring/README.md","localizedDate":"2023年11月7日"}');export{m as comp,s as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const r={};function a(n,i){return o(),t("div")}const m=e(r,[["render",a],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/java/spring/","title":"Spring","lang":"zh-CN","frontmatter":{"title":"Spring","index":false,"order":2,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/spring/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Spring"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Spring\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1699343281000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":2}]},"readingTime":{"minutes":0.02,"words":6},"filePathRelative":"java/spring/README.md","localizedDate":"2023年11月7日"}');export{m as comp,s as data}; diff --git a/assets/index.html-aNDDDL4S.js b/assets/index.html-D8OfGtcT.js similarity index 96% rename from assets/index.html-aNDDDL4S.js rename to assets/index.html-D8OfGtcT.js index e32eadc..53005fd 100644 --- a/assets/index.html-aNDDDL4S.js +++ b/assets/index.html-D8OfGtcT.js @@ -1 +1 @@ -import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as r,a as e,o as a}from"./app-IPkfDkxj.js";const n={};function c(l,t){return a(),r("div",null,t[0]||(t[0]=[e("h2",{id:"网址",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#网址"},[e("span",null,"网址")])],-1),e("p",null,[e("a",{href:"https://leetcode.cn/studyplan/leetcode-75/",target:"_blank",rel:"noopener noreferrer"},"LeetCode 75")],-1)]))}const p=o(n,[["render",c],["__file","index.html.vue"]]),m=JSON.parse('{"path":"/leetcode/leetcode-75/","title":"LeetCode 75","lang":"zh-CN","frontmatter":{"title":"LeetCode 75","icon":"lightbulb","description":"网址 LeetCode 75","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/leetcode-75/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"LeetCode 75"}],["meta",{"property":"og:description","content":"网址 LeetCode 75"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-07-30T15:05:37.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-07-30T15:05:37.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"LeetCode 75\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-07-30T15:05:37.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"网址","slug":"网址","link":"#网址","children":[]}],"git":{"createdTime":1690729537000,"updatedTime":1690729537000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.04,"words":12},"filePathRelative":"leetcode/leetcode-75/README.md","localizedDate":"2023年7月30日","autoDesc":true}');export{p as comp,m as data}; +import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as r,a as e,o as a}from"./app-DGSXj59V.js";const n={};function c(l,t){return a(),r("div",null,t[0]||(t[0]=[e("h2",{id:"网址",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#网址"},[e("span",null,"网址")])],-1),e("p",null,[e("a",{href:"https://leetcode.cn/studyplan/leetcode-75/",target:"_blank",rel:"noopener noreferrer"},"LeetCode 75")],-1)]))}const p=o(n,[["render",c],["__file","index.html.vue"]]),m=JSON.parse('{"path":"/leetcode/leetcode-75/","title":"LeetCode 75","lang":"zh-CN","frontmatter":{"title":"LeetCode 75","icon":"lightbulb","description":"网址 LeetCode 75","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/leetcode-75/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"LeetCode 75"}],["meta",{"property":"og:description","content":"网址 LeetCode 75"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-07-30T15:05:37.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-07-30T15:05:37.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"LeetCode 75\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-07-30T15:05:37.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"网址","slug":"网址","link":"#网址","children":[]}],"git":{"createdTime":1690729537000,"updatedTime":1690729537000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.04,"words":12},"filePathRelative":"leetcode/leetcode-75/README.md","localizedDate":"2023年7月30日","autoDesc":true}');export{p as comp,m as data}; diff --git a/assets/index.html-CbO2TWOo.js b/assets/index.html-DIJfQi65.js similarity index 94% rename from assets/index.html-CbO2TWOo.js rename to assets/index.html-DIJfQi65.js index 3fc62d7..a65b2a3 100644 --- a/assets/index.html-CbO2TWOo.js +++ b/assets/index.html-DIJfQi65.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,e as o,o as r,r as s}from"./app-IPkfDkxj.js";const c={};function n(l,p){const e=s("Catalog");return r(),a("div",null,[o(e)])}const h=t(c,[["render",n],["__file","index.html.vue"]]),d=JSON.parse('{"path":"/dbs/elasticsearch/","title":"Elasticsearch","lang":"zh-CN","frontmatter":{"title":"Elasticsearch","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/elasticsearch/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Elasticsearch"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Elasticsearch\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{h as comp,d as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,e as o,o as r,r as s}from"./app-DGSXj59V.js";const c={};function n(l,p){const e=s("Catalog");return r(),a("div",null,[o(e)])}const h=t(c,[["render",n],["__file","index.html.vue"]]),d=JSON.parse('{"path":"/dbs/elasticsearch/","title":"Elasticsearch","lang":"zh-CN","frontmatter":{"title":"Elasticsearch","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/elasticsearch/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Elasticsearch"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Elasticsearch\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{h as comp,d as data}; diff --git a/assets/index.html-CAhMCF-2.js b/assets/index.html-DSsHnpqp.js similarity index 96% rename from assets/index.html-CAhMCF-2.js rename to assets/index.html-DSsHnpqp.js index d8fc804..bcb51e3 100644 --- a/assets/index.html-CAhMCF-2.js +++ b/assets/index.html-DSsHnpqp.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const a={};function n(r,i){return o(),t("div")}const c=e(a,[["render",n],["__file","index.html.vue"]]),d=JSON.parse('{"path":"/java/SpringCloud/","title":"SpringCloud","lang":"zh-CN","frontmatter":{"title":"SpringCloud","index":false,"order":3,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloud/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"SpringCloud"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-05-27T06:50:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-05-27T06:50:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"SpringCloud\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-05-27T06:50:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1716792644000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1},{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.02,"words":6},"filePathRelative":"java/SpringCloud/README.md","localizedDate":"2023年11月28日"}');export{c as comp,d as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const a={};function n(r,i){return o(),t("div")}const c=e(a,[["render",n],["__file","index.html.vue"]]),d=JSON.parse('{"path":"/java/SpringCloud/","title":"SpringCloud","lang":"zh-CN","frontmatter":{"title":"SpringCloud","index":false,"order":3,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloud/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"SpringCloud"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-05-27T06:50:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-05-27T06:50:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"SpringCloud\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-05-27T06:50:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1716792644000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1},{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.02,"words":6},"filePathRelative":"java/SpringCloud/README.md","localizedDate":"2023年11月28日"}');export{c as comp,d as data}; diff --git a/assets/index.html-BLJjaEnE.js b/assets/index.html-DXlT849A.js similarity index 95% rename from assets/index.html-BLJjaEnE.js rename to assets/index.html-DXlT849A.js index e4d4bcb..cec5b15 100644 --- a/assets/index.html-BLJjaEnE.js +++ b/assets/index.html-DXlT849A.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const r={};function a(i,n){return o(),t("div")}const m=e(r,[["render",a],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/interview/","title":"面试准备","lang":"zh-CN","frontmatter":{"title":"面试准备","icon":"lightbulb","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/interview/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"面试准备"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"面试准备\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.03,"words":9},"filePathRelative":"interview/README.md","localizedDate":"2023年11月28日"}');export{m as comp,l as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const r={};function a(i,n){return o(),t("div")}const m=e(r,[["render",a],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/interview/","title":"面试准备","lang":"zh-CN","frontmatter":{"title":"面试准备","icon":"lightbulb","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/interview/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"面试准备"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"面试准备\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.03,"words":9},"filePathRelative":"interview/README.md","localizedDate":"2023年11月28日"}');export{m as comp,l as data}; diff --git a/assets/index.html-BWMmt9_Q.js b/assets/index.html-DYp-5F_m.js similarity index 97% rename from assets/index.html-BWMmt9_Q.js rename to assets/index.html-DYp-5F_m.js index a059588..c28c040 100644 --- a/assets/index.html-BWMmt9_Q.js +++ b/assets/index.html-DYp-5F_m.js @@ -1 +1 @@ -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,a as e,o}from"./app-IPkfDkxj.js";const i={};function r(c,t){return o(),n("div",null,t[0]||(t[0]=[e("h2",{id:"尝试写一下",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#尝试写一下"},[e("span",null,"尝试写一下")])],-1),e("figure",null,[e("img",{src:"https://cos.becurious.cn/Snipaste_2023-07-28_14-32-02.png",alt:"TEST",tabindex:"0",loading:"lazy"}),e("figcaption",null,"test")],-1)]))}const m=a(i,[["render",r],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/java/","title":"Java","lang":"zh-CN","frontmatter":{"title":"Java","icon":"lightbulb","index":false,"description":"尝试写一下 TESTtest","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Java"}],["meta",{"property":"og:description","content":"尝试写一下 TESTtest"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://cos.becurious.cn/Snipaste_2023-07-28_14-32-02.png \\"test\\""}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-09-03T01:40:07.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-09-03T01:40:07.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Java\\",\\"image\\":[\\"https://cos.becurious.cn/Snipaste_2023-07-28_14-32-02.png \\\\\\"test\\\\\\"\\"],\\"dateModified\\":\\"2024-09-03T01:40:07.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"尝试写一下","slug":"尝试写一下","link":"#尝试写一下","children":[]}],"git":{"createdTime":1690729537000,"updatedTime":1725327607000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":2},{"name":"hanhan12","email":"1607077440@qq.com","commits":2},{"name":"wangkai","email":"wangkai@yqun.com.cn","commits":1}]},"readingTime":{"minutes":0.06,"words":19},"filePathRelative":"java/README.md","localizedDate":"2023年7月30日","autoDesc":true}');export{m as comp,l as data}; +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,a as e,o}from"./app-DGSXj59V.js";const i={};function r(c,t){return o(),n("div",null,t[0]||(t[0]=[e("h2",{id:"尝试写一下",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#尝试写一下"},[e("span",null,"尝试写一下")])],-1),e("figure",null,[e("img",{src:"https://cos.becurious.cn/Snipaste_2023-07-28_14-32-02.png",alt:"TEST",tabindex:"0",loading:"lazy"}),e("figcaption",null,"test")],-1)]))}const m=a(i,[["render",r],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/java/","title":"Java","lang":"zh-CN","frontmatter":{"title":"Java","icon":"lightbulb","index":false,"description":"尝试写一下 TESTtest","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Java"}],["meta",{"property":"og:description","content":"尝试写一下 TESTtest"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://cos.becurious.cn/Snipaste_2023-07-28_14-32-02.png \\"test\\""}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-09-03T01:40:07.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-09-03T01:40:07.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Java\\",\\"image\\":[\\"https://cos.becurious.cn/Snipaste_2023-07-28_14-32-02.png \\\\\\"test\\\\\\"\\"],\\"dateModified\\":\\"2024-09-03T01:40:07.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"尝试写一下","slug":"尝试写一下","link":"#尝试写一下","children":[]}],"git":{"createdTime":1690729537000,"updatedTime":1725327607000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":2},{"name":"hanhan12","email":"1607077440@qq.com","commits":2},{"name":"wangkai","email":"wangkai@yqun.com.cn","commits":1}]},"readingTime":{"minutes":0.06,"words":19},"filePathRelative":"java/README.md","localizedDate":"2023年7月30日","autoDesc":true}');export{m as comp,l as data}; diff --git a/assets/index.html-BOlVANES.js b/assets/index.html-Dd2UFmj8.js similarity index 94% rename from assets/index.html-BOlVANES.js rename to assets/index.html-Dd2UFmj8.js index f6f3735..866e05b 100644 --- a/assets/index.html-BOlVANES.js +++ b/assets/index.html-Dd2UFmj8.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-IPkfDkxj.js";const s={};function l(p,c){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(s,[["render",l],["__file","index.html.vue"]]),y=JSON.parse('{"path":"/dbs/mysql/","title":"Mysql","lang":"zh-CN","frontmatter":{"title":"Mysql","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/mysql/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Mysql"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Mysql\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,y as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-DGSXj59V.js";const s={};function l(p,c){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(s,[["render",l],["__file","index.html.vue"]]),y=JSON.parse('{"path":"/dbs/mysql/","title":"Mysql","lang":"zh-CN","frontmatter":{"title":"Mysql","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/mysql/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Mysql"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Mysql\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,y as data}; diff --git a/assets/index.html-C4Md3jw-.js b/assets/index.html-DhqTU2xX.js similarity index 95% rename from assets/index.html-C4Md3jw-.js rename to assets/index.html-DhqTU2xX.js index bbe3025..934546d 100644 --- a/assets/index.html-C4Md3jw-.js +++ b/assets/index.html-DhqTU2xX.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const a={};function r(n,i){return o(),t("div")}const m=e(a,[["render",r],["__file","index.html.vue"]]),d=JSON.parse('{"path":"/java/thread/","title":"多线程","lang":"zh-CN","frontmatter":{"title":"多线程","index":false,"order":5,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/thread/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"多线程"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-05-27T06:50:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-05-27T06:50:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"多线程\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-05-27T06:50:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1716792644000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":2}]},"readingTime":{"minutes":0.03,"words":8},"filePathRelative":"java/thread/README.md","localizedDate":"2023年11月28日"}');export{m as comp,d as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const a={};function r(n,i){return o(),t("div")}const m=e(a,[["render",r],["__file","index.html.vue"]]),d=JSON.parse('{"path":"/java/thread/","title":"多线程","lang":"zh-CN","frontmatter":{"title":"多线程","index":false,"order":5,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/thread/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"多线程"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-05-27T06:50:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-05-27T06:50:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"多线程\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-05-27T06:50:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1716792644000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":2}]},"readingTime":{"minutes":0.03,"words":8},"filePathRelative":"java/thread/README.md","localizedDate":"2023年11月28日"}');export{m as comp,d as data}; diff --git a/assets/index.html-Roc1x59k.js b/assets/index.html-Dlf95nvk.js similarity index 97% rename from assets/index.html-Roc1x59k.js rename to assets/index.html-Dlf95nvk.js index fe20812..7a7dabb 100644 --- a/assets/index.html-Roc1x59k.js +++ b/assets/index.html-Dlf95nvk.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a,o as r}from"./app-IPkfDkxj.js";const n={};function s(p,e){return r(),o("div",null,e[0]||(e[0]=[a("p",null,"这是一个主页!",-1)]))}const c=t(n,[["render",s],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/","title":"主页","lang":"zh-CN","frontmatter":{"home":true,"icon":"home","title":"主页","heroImage":"/logo.svg","bgImage":"https://theme-hope-assets.vuejs.press/bg/6-light.svg","bgImageDark":"https://theme-hope-assets.vuejs.press/bg/6-dark.svg","bgImageStyle":{"background-attachment":"fixed"},"heroText":"十二的Docs","tagline":"大概是一些笔记","actions":[{"text":"文档","link":"./guide/","type":"primary"}],"copyright":false,"footer":"使用 VuePress Theme Hope 主题 | MIT 协议, 版权所有 © 2019-present Mr.Hope","description":"这是一个主页!","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"主页"}],["meta",{"property":"og:description","content":"这是一个主页!"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-07T07:48:01.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-07T07:48:01.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"主页\\",\\"description\\":\\"这是一个主页!\\"}"]]},"headers":[],"git":{"createdTime":1690435655000,"updatedTime":1699343281000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":3},{"name":"wangkai","email":"wangkai@yqun.com.cn","commits":3}]},"readingTime":{"minutes":0.27,"words":80},"filePathRelative":"README.md","localizedDate":"2023年7月27日","autoDesc":true}');export{c as comp,l as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,a,o as r}from"./app-DGSXj59V.js";const n={};function s(p,e){return r(),o("div",null,e[0]||(e[0]=[a("p",null,"这是一个主页!",-1)]))}const c=t(n,[["render",s],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/","title":"主页","lang":"zh-CN","frontmatter":{"home":true,"icon":"home","title":"主页","heroImage":"/logo.svg","bgImage":"https://theme-hope-assets.vuejs.press/bg/6-light.svg","bgImageDark":"https://theme-hope-assets.vuejs.press/bg/6-dark.svg","bgImageStyle":{"background-attachment":"fixed"},"heroText":"十二的Docs","tagline":"大概是一些笔记","actions":[{"text":"文档","link":"./guide/","type":"primary"}],"copyright":false,"footer":"使用 VuePress Theme Hope 主题 | MIT 协议, 版权所有 © 2019-present Mr.Hope","description":"这是一个主页!","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"主页"}],["meta",{"property":"og:description","content":"这是一个主页!"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-07T07:48:01.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-07T07:48:01.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"主页\\",\\"description\\":\\"这是一个主页!\\"}"]]},"headers":[],"git":{"createdTime":1690435655000,"updatedTime":1699343281000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":3},{"name":"wangkai","email":"wangkai@yqun.com.cn","commits":3}]},"readingTime":{"minutes":0.27,"words":80},"filePathRelative":"README.md","localizedDate":"2023年7月27日","autoDesc":true}');export{c as comp,l as data}; diff --git a/assets/index.html-CMw-ULdl.js b/assets/index.html-Dy81h_sK.js similarity index 94% rename from assets/index.html-CMw-ULdl.js rename to assets/index.html-Dy81h_sK.js index a859bf1..c677cd2 100644 --- a/assets/index.html-CMw-ULdl.js +++ b/assets/index.html-Dy81h_sK.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-IPkfDkxj.js";const s={};function p(c,i){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(s,[["render",p],["__file","index.html.vue"]]),h=JSON.parse('{"path":"/dbs/redis/","title":"Redis","lang":"zh-CN","frontmatter":{"title":"Redis","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Redis"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Redis\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,h as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-DGSXj59V.js";const s={};function p(c,i){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(s,[["render",p],["__file","index.html.vue"]]),h=JSON.parse('{"path":"/dbs/redis/","title":"Redis","lang":"zh-CN","frontmatter":{"title":"Redis","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Redis"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Redis\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,h as data}; diff --git a/assets/index.html-rLTebBeh.js b/assets/index.html-NBqlJgDk.js similarity index 94% rename from assets/index.html-rLTebBeh.js rename to assets/index.html-NBqlJgDk.js index 6cbb646..17c538f 100644 --- a/assets/index.html-rLTebBeh.js +++ b/assets/index.html-NBqlJgDk.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,e as o,o as a,r}from"./app-IPkfDkxj.js";const l={};function i(p,s){const e=r("Catalog");return a(),n("div",null,[o(e)])}const d=t(l,[["render",i],["__file","index.html.vue"]]),g=JSON.parse('{"path":"/java/SpringCloudAlibaba/sentinel/","title":"Sentinel","lang":"zh-CN","frontmatter":{"title":"Sentinel","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/sentinel/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Sentinel"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Sentinel\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,g as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as n,e as o,o as a,r}from"./app-DGSXj59V.js";const l={};function i(p,s){const e=r("Catalog");return a(),n("div",null,[o(e)])}const d=t(l,[["render",i],["__file","index.html.vue"]]),g=JSON.parse('{"path":"/java/SpringCloudAlibaba/sentinel/","title":"Sentinel","lang":"zh-CN","frontmatter":{"title":"Sentinel","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/sentinel/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Sentinel"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Sentinel\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,g as data}; diff --git a/assets/index.html-DG4ffYH3.js b/assets/index.html-YCjvOQL7.js similarity index 94% rename from assets/index.html-DG4ffYH3.js rename to assets/index.html-YCjvOQL7.js index b840b7a..250e747 100644 --- a/assets/index.html-DG4ffYH3.js +++ b/assets/index.html-YCjvOQL7.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-IPkfDkxj.js";const c={};function p(l,s){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(c,[["render",p],["__file","index.html.vue"]]),h=JSON.parse('{"path":"/leetcode/","title":"Leetcode","lang":"zh-CN","frontmatter":{"title":"Leetcode","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Leetcode"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Leetcode\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,h as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,e as a,o as n,r}from"./app-DGSXj59V.js";const c={};function p(l,s){const e=r("Catalog");return n(),o("div",null,[a(e)])}const d=t(c,[["render",p],["__file","index.html.vue"]]),h=JSON.parse('{"path":"/leetcode/","title":"Leetcode","lang":"zh-CN","frontmatter":{"title":"Leetcode","article":false,"feed":false,"sitemap":false,"gitInclude":[],"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"Leetcode"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"憨憨十二"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"Leetcode\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null}');export{d as comp,h as data}; diff --git a/assets/index.html-WY8-PpYT.js b/assets/index.html-m-iOeLa_.js similarity index 96% rename from assets/index.html-WY8-PpYT.js rename to assets/index.html-m-iOeLa_.js index 81e0472..766e1cd 100644 --- a/assets/index.html-WY8-PpYT.js +++ b/assets/index.html-m-iOeLa_.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o as a}from"./app-IPkfDkxj.js";const o={};function n(r,i){return a(),t("div")}const c=e(o,[["render",n],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/java/SpringCloudAlibaba/","title":"SpringCloudAlibaba","lang":"zh-CN","frontmatter":{"title":"SpringCloudAlibaba","index":false,"order":4,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"SpringCloudAlibaba"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-05-27T06:50:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-05-27T06:50:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"SpringCloudAlibaba\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-05-27T06:50:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1716792644000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1},{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.02,"words":6},"filePathRelative":"java/SpringCloudAlibaba/README.md","localizedDate":"2023年11月28日"}');export{c as comp,l as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o as a}from"./app-DGSXj59V.js";const o={};function n(r,i){return a(),t("div")}const c=e(o,[["render",n],["__file","index.html.vue"]]),l=JSON.parse('{"path":"/java/SpringCloudAlibaba/","title":"SpringCloudAlibaba","lang":"zh-CN","frontmatter":{"title":"SpringCloudAlibaba","index":false,"order":4,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"SpringCloudAlibaba"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-05-27T06:50:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-05-27T06:50:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"SpringCloudAlibaba\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-05-27T06:50:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1716792644000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1},{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.02,"words":6},"filePathRelative":"java/SpringCloudAlibaba/README.md","localizedDate":"2023年11月28日"}');export{c as comp,l as data}; diff --git a/assets/index.html-BjxWTrKZ.js b/assets/index.html-t50OORIi.js similarity index 96% rename from assets/index.html-BjxWTrKZ.js rename to assets/index.html-t50OORIi.js index b0b3995..25ce121 100644 --- a/assets/index.html-BjxWTrKZ.js +++ b/assets/index.html-t50OORIi.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o as a}from"./app-IPkfDkxj.js";const o={};function n(r,m){return a(),t("div")}const p=e(o,[["render",n],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/java/jvm/","title":"JVM","lang":"zh-CN","frontmatter":{"title":"JVM","index":false,"order":6,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/jvm/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"JVM"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-05-27T06:50:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-05-27T06:50:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"JVM\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-05-27T06:50:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1690729537000,"updatedTime":1716792644000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":3},{"name":"consen3464","email":"wangkai@consen.net","commits":1},{"name":"wangkai","email":"wangkai@yqun.com.cn","commits":1}]},"readingTime":{"minutes":0.02,"words":6},"filePathRelative":"java/jvm/README.md","localizedDate":"2023年7月30日"}');export{p as comp,s as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o as a}from"./app-DGSXj59V.js";const o={};function n(r,m){return a(),t("div")}const p=e(o,[["render",n],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/java/jvm/","title":"JVM","lang":"zh-CN","frontmatter":{"title":"JVM","index":false,"order":6,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/jvm/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"JVM"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-05-27T06:50:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-05-27T06:50:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"JVM\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-05-27T06:50:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1690729537000,"updatedTime":1716792644000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":3},{"name":"consen3464","email":"wangkai@consen.net","commits":1},{"name":"wangkai","email":"wangkai@yqun.com.cn","commits":1}]},"readingTime":{"minutes":0.02,"words":6},"filePathRelative":"java/jvm/README.md","localizedDate":"2023年7月30日"}');export{p as comp,s as data}; diff --git a/assets/index.html-2TimMen1.js b/assets/index.html-uEv93DTy.js similarity index 95% rename from assets/index.html-2TimMen1.js rename to assets/index.html-uEv93DTy.js index 428719d..cca2cf1 100644 --- a/assets/index.html-2TimMen1.js +++ b/assets/index.html-uEv93DTy.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const a={};function r(n,i){return o(),t("div")}const m=e(a,[["render",r],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/linux/basis/","title":"基础","lang":"zh-CN","frontmatter":{"title":"基础","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/basis/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1699343281000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":2}]},"readingTime":{"minutes":0.02,"words":5},"filePathRelative":"linux/basis/README.md","localizedDate":"2023年11月7日"}');export{m as comp,s as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const a={};function r(n,i){return o(),t("div")}const m=e(a,[["render",r],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/linux/basis/","title":"基础","lang":"zh-CN","frontmatter":{"title":"基础","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/basis/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1699343281000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":2}]},"readingTime":{"minutes":0.02,"words":5},"filePathRelative":"linux/basis/README.md","localizedDate":"2023年11月7日"}');export{m as comp,s as data}; diff --git a/assets/index.html-3g_tXqhW.js b/assets/index.html-wv-PNDDj.js similarity index 96% rename from assets/index.html-3g_tXqhW.js rename to assets/index.html-wv-PNDDj.js index 016d866..4ba3b69 100644 --- a/assets/index.html-3g_tXqhW.js +++ b/assets/index.html-wv-PNDDj.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const r={};function a(n,i){return o(),t("div")}const p=e(r,[["render",a],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/books/HighPerformanceMySQL/","title":"高性能MySQL","lang":"zh-CN","frontmatter":{"title":"高性能MySQL","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/HighPerformanceMySQL/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"高性能MySQL"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"高性能MySQL\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701870112000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.02,"words":7},"filePathRelative":"books/HighPerformanceMySQL/README.md","localizedDate":"2023年12月6日"}');export{p as comp,s as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const r={};function a(n,i){return o(),t("div")}const p=e(r,[["render",a],["__file","index.html.vue"]]),s=JSON.parse('{"path":"/books/HighPerformanceMySQL/","title":"高性能MySQL","lang":"zh-CN","frontmatter":{"title":"高性能MySQL","index":false,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/HighPerformanceMySQL/"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"高性能MySQL"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-03-12T06:38:15.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-03-12T06:38:15.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"高性能MySQL\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-12T06:38:15.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701870112000,"updatedTime":1710225495000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":1}]},"readingTime":{"minutes":0.02,"words":7},"filePathRelative":"books/HighPerformanceMySQL/README.md","localizedDate":"2023年12月6日"}');export{p as comp,s as data}; diff --git a/assets/install.html-DfRGkxGy.js b/assets/install.html-Dug0d3yu.js similarity index 95% rename from assets/install.html-DfRGkxGy.js rename to assets/install.html-Dug0d3yu.js index 9bd6df3..e4653e8 100644 --- a/assets/install.html-DfRGkxGy.js +++ b/assets/install.html-Dug0d3yu.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,o}from"./app-IPkfDkxj.js";const a={};function n(r,i){return o(),e("div")}const m=t(a,[["render",n],["__file","install.html.vue"]]),p=JSON.parse('{"path":"/linux/archLinux/install.html","title":"安装","lang":"zh-CN","frontmatter":{"title":"安装","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/archLinux/install.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"安装"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"安装\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.01,"words":3},"filePathRelative":"linux/archLinux/install.md","localizedDate":"2023年11月28日"}');export{m as comp,p as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,o}from"./app-DGSXj59V.js";const a={};function n(r,i){return o(),e("div")}const m=t(a,[["render",n],["__file","install.html.vue"]]),p=JSON.parse('{"path":"/linux/archLinux/install.html","title":"安装","lang":"zh-CN","frontmatter":{"title":"安装","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/archLinux/install.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"安装"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-11-28T01:58:43.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-11-28T01:58:43.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"安装\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-28T01:58:43.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701136723000,"updatedTime":1701136723000,"contributors":[{"name":"hanhan12","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0.01,"words":3},"filePathRelative":"linux/archLinux/install.md","localizedDate":"2023年11月28日"}');export{m as comp,p as data}; diff --git a/assets/logs.html-CteEoTLH.js b/assets/logs.html-B49m8Ki1.js similarity index 95% rename from assets/logs.html-CteEoTLH.js rename to assets/logs.html-B49m8Ki1.js index d54b9d5..3d31247 100644 --- a/assets/logs.html-CteEoTLH.js +++ b/assets/logs.html-B49m8Ki1.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const r={};function a(n,m){return o(),t("div")}const l=e(r,[["render",a],["__file","logs.html.vue"]]),p=JSON.parse('{"path":"/dbs/mysql/logs.html","title":"log","lang":"zh-CN","frontmatter":{"title":"log","order":1,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/mysql/logs.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"log"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-08-30T03:34:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-08-30T03:34:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"log\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-08-30T03:34:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701870112000,"updatedTime":1724988884000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":2}]},"readingTime":{"minutes":0.01,"words":4},"filePathRelative":"dbs/mysql/logs.md","localizedDate":"2023年12月6日"}');export{l as comp,p as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const r={};function a(n,m){return o(),t("div")}const l=e(r,[["render",a],["__file","logs.html.vue"]]),p=JSON.parse('{"path":"/dbs/mysql/logs.html","title":"log","lang":"zh-CN","frontmatter":{"title":"log","order":1,"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/mysql/logs.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"log"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-08-30T03:34:44.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-08-30T03:34:44.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"log\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-08-30T03:34:44.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1701870112000,"updatedTime":1724988884000,"contributors":[{"name":"consen3464","email":"wangkai@consen.net","commits":2}]},"readingTime":{"minutes":0.01,"words":4},"filePathRelative":"dbs/mysql/logs.md","localizedDate":"2023年12月6日"}');export{l as comp,p as data}; diff --git a/assets/nginx.html-DVjCG_xK.js b/assets/nginx.html-BXoNRXpL.js similarity index 95% rename from assets/nginx.html-DVjCG_xK.js rename to assets/nginx.html-BXoNRXpL.js index 3eddfa4..735ac7f 100644 --- a/assets/nginx.html-DVjCG_xK.js +++ b/assets/nginx.html-BXoNRXpL.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-IPkfDkxj.js";const n={};function r(a,i){return o(),t("div")}const p=e(n,[["render",r],["__file","nginx.html.vue"]]),s=JSON.parse('{"path":"/linux/software/nginx.html","title":"","lang":"zh-CN","frontmatter":{"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/nginx.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-09-02T12:41:04.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-09-02T12:41:04.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-09-02T12:41:04.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1725280864000,"updatedTime":1725280864000,"contributors":[{"name":"憨憨十二","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0,"words":0},"filePathRelative":"linux/software/nginx.md","localizedDate":"2024年9月2日"}');export{p as comp,s as data}; +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,o}from"./app-DGSXj59V.js";const n={};function r(a,i){return o(),t("div")}const p=e(n,[["render",r],["__file","nginx.html.vue"]]),s=JSON.parse('{"path":"/linux/software/nginx.html","title":"","lang":"zh-CN","frontmatter":{"head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/nginx.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-09-02T12:41:04.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2024-09-02T12:41:04.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-09-02T12:41:04.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[],"git":{"createdTime":1725280864000,"updatedTime":1725280864000,"contributors":[{"name":"憨憨十二","email":"1607077440@qq.com","commits":1}]},"readingTime":{"minutes":0,"words":0},"filePathRelative":"linux/software/nginx.md","localizedDate":"2024年9月2日"}');export{p as comp,s as data}; diff --git a/assets/no.html-Bggz8Mf2.js b/assets/no.html-DSfEWxWZ.js similarity index 99% rename from assets/no.html-Bggz8Mf2.js rename to assets/no.html-DSfEWxWZ.js index 3be7cad..423ffa5 100644 --- a/assets/no.html-Bggz8Mf2.js +++ b/assets/no.html-DSfEWxWZ.js @@ -1,4 +1,4 @@ -import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as t,o as e}from"./app-IPkfDkxj.js";const o={};function p(c,n){return e(),s("div",null,n[0]||(n[0]=[t(`

                            乱锅炖

                            未分类

                            注入

                            bean名称

                            默认首字母小写的驼峰命名法

                            @Bean
                            +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as t,o as e}from"./app-DGSXj59V.js";const o={};function p(c,n){return e(),s("div",null,n[0]||(n[0]=[t(`

                            乱锅炖

                            未分类

                            注入

                            bean名称

                            默认首字母小写的驼峰命名法

                            @Bean
                             public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
                             {
                                 String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
                            diff --git a/assets/podman-compose.html-Bm6gmrrd.js b/assets/podman-compose.html-49_0XMa0.js
                            similarity index 99%
                            rename from assets/podman-compose.html-Bm6gmrrd.js
                            rename to assets/podman-compose.html-49_0XMa0.js
                            index 7df3444..e130569 100644
                            --- a/assets/podman-compose.html-Bm6gmrrd.js
                            +++ b/assets/podman-compose.html-49_0XMa0.js
                            @@ -1,4 +1,4 @@
                            -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as i,b as o,o as n}from"./app-IPkfDkxj.js";const l={};function a(c,e){return n(),i("div",null,e[0]||(e[0]=[o(`

                            podman-compose

                            dockerfile

                            构成

                            • FROM:指定基础镜像

                            • MAINTAINER:镜像维护者姓名及邮箱地址

                            • RUN:容器构建时需要运行的命令

                            • EXPOSE:当前容器对外暴露的端口号

                            • WORKDIR:指定在创建容器后,终端默认登录进来的工作目录

                            • ENV:用来在构建镜像过程中设置环境变量

                            • ADD:将宿主机目录下的文件拷贝进镜像,ADD命令会自动处理URL和解压tar压缩包

                            • COPY:拷贝文件、目录到镜像中。具体是将从构建上下文目录中<src原路径>的文件或目录复制到新一层镜像的<目标路径>位置 ,有两种写法:COPY src dest 或者 COPY ["src", "dest"]

                            • VOLUME:容器数据卷,用于数据保存和持久化工作

                            • CMD:指定一个容器启动时要运行的命令

                              • 注意DockerFile中可以有多个CMD指令,但只有最后一个在启动时生效,CMD会被 docker run 之后的命令或参数覆盖

                              • CMD指令的格式和RUN相似,也是两种格式:

                                • shell格式:CMD <命令>
                                • exec格式:CMD ["可执行文件", "参数1", "参数2" ...]
                            • 参数列表格式:CMD ["参数1", "参数2", ...],在指定了ENTRYPOINT 指令后,用CMD指定具体的参数。

                            • ENTRYPOINT:指定一个容器启动时要运行的命令,与CMD一样都是在指定容器启动程序及参数(下面通过实例2将他们的区别)。

                            • ONBUILD:当构建一个被继承的DockerFile时运行命令, 父镜像在被子镜像继承后,父镜像的ONBUILD被触发。

                            example

                            • ohttps
                            FROM nginx:stable-alpine
                            +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as i,b as o,o as n}from"./app-DGSXj59V.js";const l={};function a(c,e){return n(),i("div",null,e[0]||(e[0]=[o(`

                            podman-compose

                            dockerfile

                            构成

                            • FROM:指定基础镜像

                            • MAINTAINER:镜像维护者姓名及邮箱地址

                            • RUN:容器构建时需要运行的命令

                            • EXPOSE:当前容器对外暴露的端口号

                            • WORKDIR:指定在创建容器后,终端默认登录进来的工作目录

                            • ENV:用来在构建镜像过程中设置环境变量

                            • ADD:将宿主机目录下的文件拷贝进镜像,ADD命令会自动处理URL和解压tar压缩包

                            • COPY:拷贝文件、目录到镜像中。具体是将从构建上下文目录中<src原路径>的文件或目录复制到新一层镜像的<目标路径>位置 ,有两种写法:COPY src dest 或者 COPY ["src", "dest"]

                            • VOLUME:容器数据卷,用于数据保存和持久化工作

                            • CMD:指定一个容器启动时要运行的命令

                              • 注意DockerFile中可以有多个CMD指令,但只有最后一个在启动时生效,CMD会被 docker run 之后的命令或参数覆盖

                              • CMD指令的格式和RUN相似,也是两种格式:

                                • shell格式:CMD <命令>
                                • exec格式:CMD ["可执行文件", "参数1", "参数2" ...]
                            • 参数列表格式:CMD ["参数1", "参数2", ...],在指定了ENTRYPOINT 指令后,用CMD指定具体的参数。

                            • ENTRYPOINT:指定一个容器启动时要运行的命令,与CMD一样都是在指定容器启动程序及参数(下面通过实例2将他们的区别)。

                            • ONBUILD:当构建一个被继承的DockerFile时运行命令, 父镜像在被子镜像继承后,父镜像的ONBUILD被触发。

                            example

                            • ohttps
                            FROM nginx:stable-alpine
                             # 删除官方容器镜像中的默认日志
                             # 否则启动nginx命令会报日志权限异常
                             RUN unlink /var/log/nginx/access.log
                            diff --git a/assets/podman.html-CQmzNTKG.js b/assets/podman.html-CPwV8nQQ.js
                            similarity index 99%
                            rename from assets/podman.html-CQmzNTKG.js
                            rename to assets/podman.html-CPwV8nQQ.js
                            index 8ca9a3e..4aac6ae 100644
                            --- a/assets/podman.html-CQmzNTKG.js
                            +++ b/assets/podman.html-CPwV8nQQ.js
                            @@ -1,4 +1,4 @@
                            -import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as n,o as i}from"./app-IPkfDkxj.js";const t={};function l(r,a){return i(),s("div",null,a[0]||(a[0]=[n(`

                            Podman

                            docker的替代?

                            1. rootless模式
                            2. 无守护线程

                            配置镜像地址

                            修改文件

                            • 全局镜像:/etc/containers/registries.conf

                            • 用户镜像:~/.config/containers/registries.conf

                            unqualified-search-registries = ["docker.io", "registry.access.redhat.com"]
                            +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as s,b as n,o as i}from"./app-DGSXj59V.js";const t={};function l(r,a){return i(),s("div",null,a[0]||(a[0]=[n(`

                            Podman

                            docker的替代?

                            1. rootless模式
                            2. 无守护线程

                            配置镜像地址

                            修改文件

                            • 全局镜像:/etc/containers/registries.conf

                            • 用户镜像:~/.config/containers/registries.conf

                            unqualified-search-registries = ["docker.io", "registry.access.redhat.com"]
                             

                            拉取镜像

                            podman pull podname
                             

                            运行容器

                            如果本地没有容器镜像,会自动拉去对应镜像

                            podman run podname
                             

                            简单案例

                            nginx

                            podman run -d -p 80:80 -p 443:443 \\
                            diff --git a/assets/string-compression.html-IQPW5i69.js b/assets/string-compression.html-pFNlH1Er.js
                            similarity index 98%
                            rename from assets/string-compression.html-IQPW5i69.js
                            rename to assets/string-compression.html-pFNlH1Er.js
                            index df80eaa..64ad116 100644
                            --- a/assets/string-compression.html-IQPW5i69.js
                            +++ b/assets/string-compression.html-pFNlH1Er.js
                            @@ -1,2 +1,2 @@
                            -import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,b as r,o as s}from"./app-IPkfDkxj.js";const a={};function n(c,t){return s(),e("div",null,t[0]||(t[0]=[r(`

                            压缩字符串

                            压缩字符串

                            题目

                            给你一个字符数组 chars ,请使用下述算法压缩:

                            从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符

                            • 如果这一组长度为 1 ,则将字符追加到 s 中。
                            • 否则,需要向 s 追加字符,后跟这一组的长度。

                            压缩后得到的字符串 s 不应该直接返回 ,需要转储到字符数组 chars 中。需要注意的是,如果组长度为 1010 以上,则在 chars 数组中会被拆分为多个字符。

                            请在 修改完输入数组后 ,返回该数组的新长度。

                            你必须设计并实现一个只使用常量额外空间的算法来解决此问题。

                            示例 1:

                            输入: chars = ["a","a","b","b","c","c","c"]
                            输出: 返回 6 ,输入数组的前 6 个字符应该是:["a","2","b","2","c","3"]
                            解释: "aa" 被 "a2" 替代。"bb" 被 "b2" 替代。"ccc" 被 "c3" 替代。

                            示例 2:

                            输入: chars = ["a"]
                            输出: 返回 1 ,输入数组的前 1 个字符应该是:["a"]
                            解释: 唯一的组是“a”,它保持未压缩,因为它是一个字符。

                            示例 3:

                            输入: chars = ["a","b","b","b","b","b","b","b","b","b","b","b","b"]
                            输出: 返回 4 ,输入数组的前 4 个字符应该是:["a","b","1","2"]。
                            解释: 由于字符 "a" 不重复,所以不会被压缩。"bbbbbbbbbbbb" 被 “b12” 替代。

                            提示:

                            • 1 <= chars.length <= 2000
                            • chars[i] 可以是小写英文字母、大写英文字母、数字或符号

                            解法

                            
                            +import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,b as r,o as s}from"./app-DGSXj59V.js";const a={};function n(c,t){return s(),e("div",null,t[0]||(t[0]=[r(`

                            压缩字符串

                            压缩字符串

                            题目

                            给你一个字符数组 chars ,请使用下述算法压缩:

                            从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符

                            • 如果这一组长度为 1 ,则将字符追加到 s 中。
                            • 否则,需要向 s 追加字符,后跟这一组的长度。

                            压缩后得到的字符串 s 不应该直接返回 ,需要转储到字符数组 chars 中。需要注意的是,如果组长度为 1010 以上,则在 chars 数组中会被拆分为多个字符。

                            请在 修改完输入数组后 ,返回该数组的新长度。

                            你必须设计并实现一个只使用常量额外空间的算法来解决此问题。

                            示例 1:

                            输入: chars = ["a","a","b","b","c","c","c"]
                            输出: 返回 6 ,输入数组的前 6 个字符应该是:["a","2","b","2","c","3"]
                            解释: "aa" 被 "a2" 替代。"bb" 被 "b2" 替代。"ccc" 被 "c3" 替代。

                            示例 2:

                            输入: chars = ["a"]
                            输出: 返回 1 ,输入数组的前 1 个字符应该是:["a"]
                            解释: 唯一的组是“a”,它保持未压缩,因为它是一个字符。

                            示例 3:

                            输入: chars = ["a","b","b","b","b","b","b","b","b","b","b","b","b"]
                            输出: 返回 4 ,输入数组的前 4 个字符应该是:["a","b","1","2"]。
                            解释: 由于字符 "a" 不重复,所以不会被压缩。"bbbbbbbbbbbb" 被 “b12” 替代。

                            提示:

                            • 1 <= chars.length <= 2000
                            • chars[i] 可以是小写英文字母、大写英文字母、数字或符号

                            解法

                            
                             
                            `,19)]))}const p=o(a,[["render",n],["__file","string-compression.html.vue"]]),d=JSON.parse('{"path":"/leetcode/leetcode-75/string-compression.html","title":"压缩字符串","lang":"zh-CN","frontmatter":{"description":"压缩字符串 压缩字符串 题目 给你一个字符数组 chars ,请使用下述算法压缩: 从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 : 如果这一组长度为 1 ,则将字符追加到 s 中。 否则,需要向 s 追加字符,后跟这一组的长度。 压缩后得到的字符串 s 不应该直接返回 ,需要转储到字符数组 chars 中。需要注意的是,如果组长...","head":[["meta",{"property":"og:url","content":"https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/leetcode-75/string-compression.html"}],["meta",{"property":"og:site_name","content":"一切为了更好的自己"}],["meta",{"property":"og:title","content":"压缩字符串"}],["meta",{"property":"og:description","content":"压缩字符串 压缩字符串 题目 给你一个字符数组 chars ,请使用下述算法压缩: 从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 : 如果这一组长度为 1 ,则将字符追加到 s 中。 否则,需要向 s 追加字符,后跟这一组的长度。 压缩后得到的字符串 s 不应该直接返回 ,需要转储到字符数组 chars 中。需要注意的是,如果组长..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2023-08-24T10:13:49.000Z"}],["meta",{"property":"article:author","content":"憨憨十二"}],["meta",{"property":"article:modified_time","content":"2023-08-24T10:13:49.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"压缩字符串\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-08-24T10:13:49.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"憨憨十二\\",\\"url\\":\\"https://mister-hope.com\\"}]}"]]},"headers":[{"level":2,"title":"题目","slug":"题目","link":"#题目","children":[]},{"level":2,"title":"解法","slug":"解法","link":"#解法","children":[]}],"git":{"createdTime":1692872029000,"updatedTime":1692872029000,"contributors":[{"name":"wangkai","email":"wangkai@yqun.com.cn","commits":1}]},"readingTime":{"minutes":1.34,"words":401},"filePathRelative":"leetcode/leetcode-75/string-compression.md","localizedDate":"2023年8月24日","autoDesc":true}');export{p as comp,d as data}; diff --git a/books/HighPerformanceMySQL/index.html b/books/HighPerformanceMySQL/index.html index 0d44bb8..ebf9236 100644 --- a/books/HighPerformanceMySQL/index.html +++ b/books/HighPerformanceMySQL/index.html @@ -30,11 +30,11 @@ 高性能MySQL | 一切为了更好的自己 - - + +
                            跳至主要內容
                            - + diff --git "a/books/UnderStandingTheJvm/10.\345\211\215\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html" "b/books/UnderStandingTheJvm/10.\345\211\215\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html" index 4714dbf..098260e 100644 --- "a/books/UnderStandingTheJvm/10.\345\211\215\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html" +++ "b/books/UnderStandingTheJvm/10.\345\211\215\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html" @@ -30,8 +30,8 @@ 10.前端编译与优化 | 一切为了更好的自己 - - + +
                            跳至主要內容
                            - + diff --git "a/books/UnderStandingTheJvm/11.\345\220\216\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html" "b/books/UnderStandingTheJvm/11.\345\220\216\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html" index 9534306..bde839e 100644 --- "a/books/UnderStandingTheJvm/11.\345\220\216\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html" +++ "b/books/UnderStandingTheJvm/11.\345\220\216\347\253\257\347\274\226\350\257\221\344\270\216\344\274\230\345\214\226.html" @@ -30,8 +30,8 @@ 11.后端编译与优化 | 一切为了更好的自己 - - + +
                            跳至主要內容
                            - + diff --git "a/books/UnderStandingTheJvm/2.Java\345\206\205\345\255\230\345\214\272\345\237\237\344\270\216\345\206\205\345\255\230\346\272\242\345\207\272\345\274\202\345\270\270.html" "b/books/UnderStandingTheJvm/2.Java\345\206\205\345\255\230\345\214\272\345\237\237\344\270\216\345\206\205\345\255\230\346\272\242\345\207\272\345\274\202\345\270\270.html" index 3fce4b0..bea2bda 100644 --- "a/books/UnderStandingTheJvm/2.Java\345\206\205\345\255\230\345\214\272\345\237\237\344\270\216\345\206\205\345\255\230\346\272\242\345\207\272\345\274\202\345\270\270.html" +++ "b/books/UnderStandingTheJvm/2.Java\345\206\205\345\255\230\345\214\272\345\237\237\344\270\216\345\206\205\345\255\230\346\272\242\345\207\272\345\274\202\345\270\270.html" @@ -30,11 +30,11 @@ 2.Java内存区域与内存溢出异常 | 一切为了更好的自己 - - + +
                            跳至主要內容
                            - + diff --git "a/books/UnderStandingTheJvm/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\212\357\274\211.html" "b/books/UnderStandingTheJvm/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\212\357\274\211.html" index 96473ef..dbf0552 100644 --- "a/books/UnderStandingTheJvm/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\212\357\274\211.html" +++ "b/books/UnderStandingTheJvm/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\212\357\274\211.html" @@ -30,8 +30,8 @@ 3.垃圾收集器与内存分配策略(上) | 一切为了更好的自己 - - + +
                            跳至主要內容
                            - + diff --git "a/books/UnderStandingTheJvm/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\213\357\274\211.html" "b/books/UnderStandingTheJvm/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\213\357\274\211.html" index 4675c5f..263b272 100644 --- "a/books/UnderStandingTheJvm/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\213\357\274\211.html" +++ "b/books/UnderStandingTheJvm/3.\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\344\270\216\345\206\205\345\255\230\345\210\206\351\205\215\347\255\226\347\225\245\357\274\210\344\270\213\357\274\211.html" @@ -30,12 +30,12 @@ 3.垃圾收集器与内存分配策略(下) | 一切为了更好的自己 - - + +
                            跳至主要內容
                            - + diff --git "a/books/UnderStandingTheJvm/4.\350\231\232\346\213\237\346\234\272\346\200\247\350\203\275\347\233\221\346\216\247\343\200\201\346\225\205\351\232\234\345\244\204\347\220\206\345\267\245\345\205\267.html" "b/books/UnderStandingTheJvm/4.\350\231\232\346\213\237\346\234\272\346\200\247\350\203\275\347\233\221\346\216\247\343\200\201\346\225\205\351\232\234\345\244\204\347\220\206\345\267\245\345\205\267.html" index 0cc2a5f..671cb64 100644 --- "a/books/UnderStandingTheJvm/4.\350\231\232\346\213\237\346\234\272\346\200\247\350\203\275\347\233\221\346\216\247\343\200\201\346\225\205\351\232\234\345\244\204\347\220\206\345\267\245\345\205\267.html" +++ "b/books/UnderStandingTheJvm/4.\350\231\232\346\213\237\346\234\272\346\200\247\350\203\275\347\233\221\346\216\247\343\200\201\346\225\205\351\232\234\345\244\204\347\220\206\345\267\245\345\205\267.html" @@ -30,8 +30,8 @@ 4.虚拟机性能监控、故障处理工具 | 一切为了更好的自己 - - + +
                            跳至主要內容
                            - + diff --git "a/books/UnderStandingTheJvm/5.\350\260\203\344\274\230\346\241\210\344\276\213\345\210\206\346\236\220\344\270\216\345\256\236\346\210\230.html" "b/books/UnderStandingTheJvm/5.\350\260\203\344\274\230\346\241\210\344\276\213\345\210\206\346\236\220\344\270\216\345\256\236\346\210\230.html" index 7bd644c..f424bc7 100644 --- "a/books/UnderStandingTheJvm/5.\350\260\203\344\274\230\346\241\210\344\276\213\345\210\206\346\236\220\344\270\216\345\256\236\346\210\230.html" +++ "b/books/UnderStandingTheJvm/5.\350\260\203\344\274\230\346\241\210\344\276\213\345\210\206\346\236\220\344\270\216\345\256\236\346\210\230.html" @@ -30,11 +30,11 @@ 5.调优案例分析与实战 | 一切为了更好的自己 - - + + - + diff --git "a/books/UnderStandingTheJvm/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\212\357\274\211.html" "b/books/UnderStandingTheJvm/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\212\357\274\211.html" index 85a1b14..b77c5e3 100644 --- "a/books/UnderStandingTheJvm/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\212\357\274\211.html" +++ "b/books/UnderStandingTheJvm/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\212\357\274\211.html" @@ -30,8 +30,8 @@ 6.类文件结构(上) | 一切为了更好的自己 - - + +
                            跳至主要內容
                            - + diff --git "a/books/UnderStandingTheJvm/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\213\357\274\211.html" "b/books/UnderStandingTheJvm/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\213\357\274\211.html" index 57173c6..93d4b93 100644 --- "a/books/UnderStandingTheJvm/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\213\357\274\211.html" +++ "b/books/UnderStandingTheJvm/6.\347\261\273\346\226\207\344\273\266\347\273\223\346\236\204\357\274\210\344\270\213\357\274\211.html" @@ -30,8 +30,8 @@ 6.类文件结构(下) | 一切为了更好的自己 - - + +
                            跳至主要內容
                            - + diff --git "a/books/UnderStandingTheJvm/7.\350\231\232\346\213\237\346\234\272\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.html" "b/books/UnderStandingTheJvm/7.\350\231\232\346\213\237\346\234\272\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.html" index 5365c5b..4deb004 100644 --- "a/books/UnderStandingTheJvm/7.\350\231\232\346\213\237\346\234\272\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.html" +++ "b/books/UnderStandingTheJvm/7.\350\231\232\346\213\237\346\234\272\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.html" @@ -30,8 +30,8 @@ 7.虚拟机类加载机制 | 一切为了更好的自己 - - + +
                            跳至主要內容

                      本章小结

                      本章介绍了类加载过程的“加载”“验证”“准备”“解析”和“初始化”这5个阶段中虚拟机进行了哪些动 作,还介绍了类加载器的工作原理及其对虚拟机的意义。

                  - + diff --git "a/books/UnderStandingTheJvm/8.\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.html" "b/books/UnderStandingTheJvm/8.\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.html" index b4d9fe0..b3a2fa5 100644 --- "a/books/UnderStandingTheJvm/8.\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.html" +++ "b/books/UnderStandingTheJvm/8.\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.html" @@ -30,8 +30,8 @@ 8.虚拟机字节码执行引擎 | 一切为了更好的自己 - - + +
                  跳至主要內容
                  - + diff --git "a/books/UnderStandingTheJvm/9.\347\261\273\345\212\240\350\275\275\345\217\212\346\211\247\350\241\214\345\255\220\347\263\273\347\273\237\347\232\204\346\241\210\344\276\213\344\270\216\345\256\236\346\210\230.html" "b/books/UnderStandingTheJvm/9.\347\261\273\345\212\240\350\275\275\345\217\212\346\211\247\350\241\214\345\255\220\347\263\273\347\273\237\347\232\204\346\241\210\344\276\213\344\270\216\345\256\236\346\210\230.html" index 563c1b7..50593d0 100644 --- "a/books/UnderStandingTheJvm/9.\347\261\273\345\212\240\350\275\275\345\217\212\346\211\247\350\241\214\345\255\220\347\263\273\347\273\237\347\232\204\346\241\210\344\276\213\344\270\216\345\256\236\346\210\230.html" +++ "b/books/UnderStandingTheJvm/9.\347\261\273\345\212\240\350\275\275\345\217\212\346\211\247\350\241\214\345\255\220\347\263\273\347\273\237\347\232\204\346\241\210\344\276\213\344\270\216\345\256\236\346\210\230.html" @@ -30,8 +30,8 @@ 9.类加载及执行子系统的案例与实战 | 一切为了更好的自己 - - + +
                  跳至主要內容
                  - + diff --git a/books/UnderStandingTheJvm/index.html b/books/UnderStandingTheJvm/index.html index 26c7ca6..7eb579e 100644 --- a/books/UnderStandingTheJvm/index.html +++ b/books/UnderStandingTheJvm/index.html @@ -30,11 +30,11 @@ 深入理解Java虚拟机 | 一切为了更好的自己 - - + + - + diff --git a/books/index.html b/books/index.html index 05a9f4e..48505dc 100644 --- a/books/index.html +++ b/books/index.html @@ -30,11 +30,11 @@ Books | 一切为了更好的自己 - - + + - + diff --git a/dbs/elasticsearch/basis.html b/dbs/elasticsearch/basis.html index 99f5cc4..43bde79 100644 --- a/dbs/elasticsearch/basis.html +++ b/dbs/elasticsearch/basis.html @@ -30,8 +30,8 @@ 基础 | 一切为了更好的自己 - - + +
                  跳至主要內容
                  - + diff --git a/dbs/elasticsearch/index.html b/dbs/elasticsearch/index.html index ca31d1e..3693477 100644 --- a/dbs/elasticsearch/index.html +++ b/dbs/elasticsearch/index.html @@ -30,11 +30,11 @@ Elasticsearch | 一切为了更好的自己 - - + +
                  跳至主要內容
                  - + diff --git a/dbs/index.html b/dbs/index.html index 0e49c20..20a3a88 100644 --- a/dbs/index.html +++ b/dbs/index.html @@ -30,11 +30,11 @@ 数据库DB | 一切为了更好的自己 - - + +
                  跳至主要內容
                  - + diff --git a/dbs/mysql/dump.html b/dbs/mysql/dump.html index 56bace9..ccb4928 100644 --- a/dbs/mysql/dump.html +++ b/dbs/mysql/dump.html @@ -30,8 +30,8 @@ dump | 一切为了更好的自己 - - + +
                  跳至主要內容
                  - + diff --git a/dbs/mysql/index.html b/dbs/mysql/index.html index f09a6b5..206b514 100644 --- a/dbs/mysql/index.html +++ b/dbs/mysql/index.html @@ -30,11 +30,11 @@ Mysql | 一切为了更好的自己 - - + + - + diff --git a/dbs/mysql/logs.html b/dbs/mysql/logs.html index 56ffd7b..6a79338 100644 --- a/dbs/mysql/logs.html +++ b/dbs/mysql/logs.html @@ -30,11 +30,11 @@ log | 一切为了更好的自己 - - + + - + diff --git a/dbs/redis/0.redis7.html b/dbs/redis/0.redis7.html index 66b5666..572a08e 100644 --- a/dbs/redis/0.redis7.html +++ b/dbs/redis/0.redis7.html @@ -30,8 +30,8 @@ 开始 | 一切为了更好的自己 - - + + - + diff --git "a/dbs/redis/1.\345\215\201\345\244\247\346\225\260\346\215\256\347\261\273\345\236\213.html" "b/dbs/redis/1.\345\215\201\345\244\247\346\225\260\346\215\256\347\261\273\345\236\213.html" index 57e09b0..93b0370 100644 --- "a/dbs/redis/1.\345\215\201\345\244\247\346\225\260\346\215\256\347\261\273\345\236\213.html" +++ "b/dbs/redis/1.\345\215\201\345\244\247\346\225\260\346\215\256\347\261\273\345\236\213.html" @@ -30,8 +30,8 @@ 十大数据类型 | 一切为了更好的自己 - - + +
                  跳至主要內容
              - + diff --git "a/dbs/redis/2.\346\214\201\344\271\205\345\214\226.html" "b/dbs/redis/2.\346\214\201\344\271\205\345\214\226.html" index b7ebf14..6b8b635 100644 --- "a/dbs/redis/2.\346\214\201\344\271\205\345\214\226.html" +++ "b/dbs/redis/2.\346\214\201\344\271\205\345\214\226.html" @@ -30,8 +30,8 @@ 持久化 | 一切为了更好的自己 - - + +
              跳至主要內容
              - + diff --git "a/dbs/redis/3.\344\272\213\345\212\241.html" "b/dbs/redis/3.\344\272\213\345\212\241.html" index 894eacc..d925d02 100644 --- "a/dbs/redis/3.\344\272\213\345\212\241.html" +++ "b/dbs/redis/3.\344\272\213\345\212\241.html" @@ -30,8 +30,8 @@ 事务 | 一切为了更好的自己 - - + +
              跳至主要內容
              - + diff --git "a/dbs/redis/4.\347\256\241\351\201\223.html" "b/dbs/redis/4.\347\256\241\351\201\223.html" index 93643bb..0597050 100644 --- "a/dbs/redis/4.\347\256\241\351\201\223.html" +++ "b/dbs/redis/4.\347\256\241\351\201\223.html" @@ -30,11 +30,11 @@ 管道 | 一切为了更好的自己 - - + +
              跳至主要內容
              - + diff --git "a/dbs/redis/5.\345\217\221\345\270\203\344\270\216\350\256\242\351\230\205.html" "b/dbs/redis/5.\345\217\221\345\270\203\344\270\216\350\256\242\351\230\205.html" index 0f8d7e1..d58d498 100644 --- "a/dbs/redis/5.\345\217\221\345\270\203\344\270\216\350\256\242\351\230\205.html" +++ "b/dbs/redis/5.\345\217\221\345\270\203\344\270\216\350\256\242\351\230\205.html" @@ -30,8 +30,8 @@ 发布与订阅 | 一切为了更好的自己 - - + +
              跳至主要內容
              - + diff --git "a/dbs/redis/6.\345\244\215\345\210\266.html" "b/dbs/redis/6.\345\244\215\345\210\266.html" index 15ce162..a3fdf9f 100644 --- "a/dbs/redis/6.\345\244\215\345\210\266.html" +++ "b/dbs/redis/6.\345\244\215\345\210\266.html" @@ -30,8 +30,8 @@ 复制 | 一切为了更好的自己 - - + +
              跳至主要內容

            薪火相传

            • 上一个slave可以是下一个slave的master,slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻主master的写压力
            • 中途变更转向:会清除之前的数据,重新建立主从关系并拷贝最新的

            复制原理和工作流程

            slave启动,同步初请

            • slave启动成功链接到master后会发送一个sync命令
            • slave首次全新连接master,一次完全同步(全量复制)将被自动执行,slave自身原有数据会被master数据覆盖清除

            首次连接,全量复制

            • master节点收到sync命令后会开始在后台保存快照(即RDB持久化,主从复制时会触发RDB),同时收集所有接收到的用于修改数据集的命令并缓存起来,master节点执行RDB持久化完后,master将RDB快照文件和所有缓存的命令发送到所有slave,以完成一次完全同步
            • 而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中,从而完成复制初始化

            心跳持续,保持通信

            master发出PING包的周期,默认10秒

            repl-ping-replica-period 10
             

            进入平稳,增量复制

            • master继续将新的所有收集到的修改命令自动依次传送给slave,完成同步

            从机下线,重连续传

            • master会检查backlog里面的offset,master和slave都会保存一个复制的offset还有一个masterId,offset是保存在backlog中的。
            • 只会把已经缓存的offset后面的数据复制给slave,类似断点续传

            复制的缺点

            • 复制延时,信号衰减

              由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

        - + diff --git "a/dbs/redis/7.\345\223\250\345\205\265.html" "b/dbs/redis/7.\345\223\250\345\205\265.html" index c77d83f..338c300 100644 --- "a/dbs/redis/7.\345\223\250\345\205\265.html" +++ "b/dbs/redis/7.\345\223\250\345\205\265.html" @@ -30,8 +30,8 @@ 哨兵 | 一切为了更好的自己 - - + +
        跳至主要內容
      • 哨兵集群+主从复制,并不能保证数据零丢失,所以需要使用集群
- + diff --git a/dbs/redis/index.html b/dbs/redis/index.html index bca72fc..fa1f374 100644 --- a/dbs/redis/index.html +++ b/dbs/redis/index.html @@ -30,11 +30,11 @@ Redis | 一切为了更好的自己 - - + + - + diff --git a/index.html b/index.html index afa2f90..05fbf45 100644 --- a/index.html +++ b/index.html @@ -30,11 +30,11 @@ 主页 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/interview/2023.html b/interview/2023.html index 1833b7c..71096be 100644 --- a/interview/2023.html +++ b/interview/2023.html @@ -30,8 +30,8 @@ 2023 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/interview/index.html b/interview/index.html index 35bf95a..8c73286 100644 --- a/interview/index.html +++ b/interview/index.html @@ -30,11 +30,11 @@ 面试准备 | 一切为了更好的自己 - - + + - + diff --git a/java/SpringCloud/index.html b/java/SpringCloud/index.html index 36f87f4..5a75195 100644 --- a/java/SpringCloud/index.html +++ b/java/SpringCloud/index.html @@ -30,11 +30,11 @@ SpringCloud | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/SpringCloudAlibaba/dubbo/basis.html b/java/SpringCloudAlibaba/dubbo/basis.html index a7b8cea..80566e8 100644 --- a/java/SpringCloudAlibaba/dubbo/basis.html +++ b/java/SpringCloudAlibaba/dubbo/basis.html @@ -30,11 +30,11 @@ 基础 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/SpringCloudAlibaba/dubbo/index.html b/java/SpringCloudAlibaba/dubbo/index.html index d8bdf91..b9ebebd 100644 --- a/java/SpringCloudAlibaba/dubbo/index.html +++ b/java/SpringCloudAlibaba/dubbo/index.html @@ -30,11 +30,11 @@ Dubbo | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/SpringCloudAlibaba/index.html b/java/SpringCloudAlibaba/index.html index dc56ce4..df1c6c2 100644 --- a/java/SpringCloudAlibaba/index.html +++ b/java/SpringCloudAlibaba/index.html @@ -30,11 +30,11 @@ SpringCloudAlibaba | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/SpringCloudAlibaba/nacos/basis.html b/java/SpringCloudAlibaba/nacos/basis.html index e77ff6b..7511827 100644 --- a/java/SpringCloudAlibaba/nacos/basis.html +++ b/java/SpringCloudAlibaba/nacos/basis.html @@ -30,11 +30,11 @@ 基础 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/SpringCloudAlibaba/nacos/index.html b/java/SpringCloudAlibaba/nacos/index.html index 307b87f..29aae2e 100644 --- a/java/SpringCloudAlibaba/nacos/index.html +++ b/java/SpringCloudAlibaba/nacos/index.html @@ -30,11 +30,11 @@ Nacos | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/SpringCloudAlibaba/seata/basis.html b/java/SpringCloudAlibaba/seata/basis.html index 0fa4780..cc1e58f 100644 --- a/java/SpringCloudAlibaba/seata/basis.html +++ b/java/SpringCloudAlibaba/seata/basis.html @@ -30,8 +30,8 @@ 基础 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/SpringCloudAlibaba/seata/index.html b/java/SpringCloudAlibaba/seata/index.html index feda044..6a984de 100644 --- a/java/SpringCloudAlibaba/seata/index.html +++ b/java/SpringCloudAlibaba/seata/index.html @@ -30,11 +30,11 @@ Seata | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/SpringCloudAlibaba/sentinel/basis.html b/java/SpringCloudAlibaba/sentinel/basis.html index 29be15f..5655194 100644 --- a/java/SpringCloudAlibaba/sentinel/basis.html +++ b/java/SpringCloudAlibaba/sentinel/basis.html @@ -30,11 +30,11 @@ 基础 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/SpringCloudAlibaba/sentinel/index.html b/java/SpringCloudAlibaba/sentinel/index.html index 6227bf6..944dbb5 100644 --- a/java/SpringCloudAlibaba/sentinel/index.html +++ b/java/SpringCloudAlibaba/sentinel/index.html @@ -30,11 +30,11 @@ Sentinel | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/basis/basis.html b/java/basis/basis.html index d351ceb..26b1a2b 100644 --- a/java/basis/basis.html +++ b/java/basis/basis.html @@ -30,8 +30,8 @@ 暂且不知道叫什么 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/basis/index.html b/java/basis/index.html index aec7634..b00a36f 100644 --- a/java/basis/index.html +++ b/java/basis/index.html @@ -30,11 +30,11 @@ 基础 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/basis/no.html b/java/basis/no.html index da49551..14c6f4d 100644 --- a/java/basis/no.html +++ b/java/basis/no.html @@ -30,8 +30,8 @@ 乱锅炖 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/index.html b/java/index.html index 2e568b9..1965e32 100644 --- a/java/index.html +++ b/java/index.html @@ -30,11 +30,11 @@ Java | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/jvm/basis.html b/java/jvm/basis.html index 27c35f5..ef3d1ee 100644 --- a/java/jvm/basis.html +++ b/java/jvm/basis.html @@ -30,11 +30,11 @@ 基础todo | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/jvm/index.html b/java/jvm/index.html index c6fcb9f..3cd8a8a 100644 --- a/java/jvm/index.html +++ b/java/jvm/index.html @@ -30,11 +30,11 @@ JVM | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/rocketmq/basis.html b/java/rocketmq/basis.html index e75aa2f..0444269 100644 --- a/java/rocketmq/basis.html +++ b/java/rocketmq/basis.html @@ -30,8 +30,8 @@ docker 启动! | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/rocketmq/index.html b/java/rocketmq/index.html index 573fd6f..ed44a07 100644 --- a/java/rocketmq/index.html +++ b/java/rocketmq/index.html @@ -30,11 +30,11 @@ rocket | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/spring/SpringSecurity.html b/java/spring/SpringSecurity.html index cd55104..1f498eb 100644 --- a/java/spring/SpringSecurity.html +++ b/java/spring/SpringSecurity.html @@ -30,11 +30,11 @@ 一切为了更好的自己 - - + + - + diff --git a/java/spring/demo.html b/java/spring/demo.html index 72795ec..a37bd1e 100644 --- a/java/spring/demo.html +++ b/java/spring/demo.html @@ -30,8 +30,8 @@ Spring | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/spring/index.html b/java/spring/index.html index 39bef17..cea9f4e 100644 --- a/java/spring/index.html +++ b/java/spring/index.html @@ -30,11 +30,11 @@ Spring | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/thread/basis.html b/java/thread/basis.html index 52f0d21..c0ae073 100644 --- a/java/thread/basis.html +++ b/java/thread/basis.html @@ -30,11 +30,11 @@ 基础 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/java/thread/index.html b/java/thread/index.html index 4dbd22a..f1281c4 100644 --- a/java/thread/index.html +++ b/java/thread/index.html @@ -30,11 +30,11 @@ 多线程 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/leetcode/daily/index.html b/leetcode/daily/index.html index 3214af1..edf4461 100644 --- a/leetcode/daily/index.html +++ b/leetcode/daily/index.html @@ -30,11 +30,11 @@ 每日一题 | 一切为了更好的自己 - - + + - + diff --git a/leetcode/index.html b/leetcode/index.html index 63b04de..7d48d0e 100644 --- a/leetcode/index.html +++ b/leetcode/index.html @@ -30,11 +30,11 @@ Leetcode | 一切为了更好的自己 - - + + - + diff --git a/leetcode/leetcode-75/index.html b/leetcode/leetcode-75/index.html index c2e5c60..ddd0294 100644 --- a/leetcode/leetcode-75/index.html +++ b/leetcode/leetcode-75/index.html @@ -30,11 +30,11 @@ LeetCode 75 | 一切为了更好的自己 - - + + - + diff --git a/leetcode/leetcode-75/string-compression.html b/leetcode/leetcode-75/string-compression.html index 9ad0a18..babc2ff 100644 --- a/leetcode/leetcode-75/string-compression.html +++ b/leetcode/leetcode-75/string-compression.html @@ -30,12 +30,12 @@ 压缩字符串 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/linux/archLinux/index.html b/linux/archLinux/index.html index 27ba969..a636b02 100644 --- a/linux/archLinux/index.html +++ b/linux/archLinux/index.html @@ -30,11 +30,11 @@ ArchLinux | 一切为了更好的自己 - - + + - + diff --git a/linux/archLinux/install.html b/linux/archLinux/install.html index aaf273d..832690e 100644 --- a/linux/archLinux/install.html +++ b/linux/archLinux/install.html @@ -30,11 +30,11 @@ 安装 | 一切为了更好的自己 - - + + - + diff --git a/linux/basis/basis.html b/linux/basis/basis.html index 1789cb5..f781f63 100644 --- a/linux/basis/basis.html +++ b/linux/basis/basis.html @@ -30,13 +30,13 @@ 基础 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/linux/basis/index.html b/linux/basis/index.html index cb59b77..32ff348 100644 --- a/linux/basis/index.html +++ b/linux/basis/index.html @@ -30,11 +30,11 @@ 基础 | 一切为了更好的自己 - - + + - + diff --git a/linux/index.html b/linux/index.html index 65ad4d0..a590b63 100644 --- a/linux/index.html +++ b/linux/index.html @@ -30,11 +30,11 @@ Linux | 一切为了更好的自己 - - + + - + diff --git a/linux/software/arthas.html b/linux/software/arthas.html index d6baa1e..f6890fe 100644 --- a/linux/software/arthas.html +++ b/linux/software/arthas.html @@ -30,13 +30,13 @@ arthas | 一切为了更好的自己 - - + + - + diff --git a/linux/software/basis.html b/linux/software/basis.html index 84ce195..10ff531 100644 --- a/linux/software/basis.html +++ b/linux/software/basis.html @@ -30,12 +30,12 @@ 基础工具 | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/linux/software/drone.html b/linux/software/drone.html index 616450e..e1af6f9 100644 --- a/linux/software/drone.html +++ b/linux/software/drone.html @@ -30,8 +30,8 @@ drone | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/linux/software/index.html b/linux/software/index.html index 9f02b91..9485f7e 100644 --- a/linux/software/index.html +++ b/linux/software/index.html @@ -30,11 +30,11 @@ 软件 | 一切为了更好的自己 - - + + - + diff --git a/linux/software/nginx.html b/linux/software/nginx.html index 12adf8b..3b11edf 100644 --- a/linux/software/nginx.html +++ b/linux/software/nginx.html @@ -30,11 +30,11 @@ 一切为了更好的自己 - - + + - + diff --git a/linux/software/podman-compose.html b/linux/software/podman-compose.html index 9f81894..e613251 100644 --- a/linux/software/podman-compose.html +++ b/linux/software/podman-compose.html @@ -30,8 +30,8 @@ podman-compose | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/linux/software/podman.html b/linux/software/podman.html index 2483b13..389bf2d 100644 --- a/linux/software/podman.html +++ b/linux/software/podman.html @@ -30,8 +30,8 @@ Podman | 一切为了更好的自己 - - + +
跳至主要內容
- + diff --git a/sitemap.xml b/sitemap.xml index 7c404be..d2e61cf 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1,3 +1,3 @@ -https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/2023-11-07T07:48:01.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/interview/2023.html2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/interview/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/2024-09-03T01:40:07.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/HighPerformanceMySQL/2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/10.%E5%89%8D%E7%AB%AF%E7%BC%96%E8%AF%91%E4%B8%8E%E4%BC%98%E5%8C%96.html2024-10-28T09:40:50.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/11.%E5%90%8E%E7%AB%AF%E7%BC%96%E8%AF%91%E4%B8%8E%E4%BC%98%E5%8C%96.html2024-11-05T06:43:49.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/2.Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8.html2024-09-02T05:37:18.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8A%EF%BC%89.html2024-09-02T05:37:18.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8B%EF%BC%89.html2024-09-02T05:37:18.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/4.%E8%99%9A%E6%8B%9F%E6%9C%BA%E6%80%A7%E8%83%BD%E7%9B%91%E6%8E%A7%E3%80%81%E6%95%85%E9%9A%9C%E5%A4%84%E7%90%86%E5%B7%A5%E5%85%B7.html2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/5.%E8%B0%83%E4%BC%98%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E6%88%98.html2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/6.%E7%B1%BB%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%EF%BC%88%E4%B8%8A%EF%BC%89.html2024-09-02T05:37:18.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/6.%E7%B1%BB%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%EF%BC%88%E4%B8%8B%EF%BC%89.html2024-08-30T03:45:50.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/7.%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/8.%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%AD%97%E8%8A%82%E7%A0%81%E6%89%A7%E8%A1%8C%E5%BC%95%E6%93%8E.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/9.%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%8F%8A%E6%89%A7%E8%A1%8C%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%A1%88%E4%BE%8B%E4%B8%8E%E5%AE%9E%E6%88%98.html2024-10-09T08:10:00.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/elasticsearch/basis.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/mysql/dump.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/mysql/logs.html2024-08-30T03:34:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/0.redis7.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/1.%E5%8D%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/2.%E6%8C%81%E4%B9%85%E5%8C%96.html2024-09-02T05:37:18.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/3.%E4%BA%8B%E5%8A%A1.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/4.%E7%AE%A1%E9%81%93.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/5.%E5%8F%91%E5%B8%83%E4%B8%8E%E8%AE%A2%E9%98%85.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/6.%E5%A4%8D%E5%88%B6.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/7.%E5%93%A8%E5%85%B5.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloud/2024-05-27T06:50:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/2024-05-27T06:50:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/basis/2024-05-27T06:50:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/basis/basis.html2023-09-18T14:39:52.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/basis/no.html2023-09-22T10:08:41.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/jvm/2024-05-27T06:50:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/jvm/basis.html2024-08-30T03:49:20.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/rocketmq/2024-06-07T09:24:38.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/rocketmq/basis.html2024-06-12T09:19:26.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/spring/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/spring/SpringSecurity.html2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/spring/demo.html2023-08-24T10:13:55.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/thread/2024-05-27T06:50:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/thread/basis.html2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/daily/2023-07-31T03:10:06.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/leetcode-75/2023-07-30T15:05:37.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/leetcode-75/string-compression.html2023-08-24T10:13:49.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/archLinux/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/archLinux/install.html2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/basis/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/basis/basis.html2024-01-02T13:39:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/arthas.html2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/basis.html2024-11-05T06:43:49.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/drone.html2024-08-30T03:34:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/nginx.html2024-09-02T12:41:04.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/podman-compose.html2024-05-27T03:17:50.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/podman.html2024-05-27T03:17:50.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/dubbo/basis.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/nacos/basis.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/seata/basis.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/sentinel/basis.html2024-10-08T03:40:12.000Zdaily \ No newline at end of file +https://vuepress-theme-hope-docs-demo.netlify.app/my-docs/2023-11-07T07:48:01.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/interview/2023.html2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/interview/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/2024-09-03T01:40:07.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/HighPerformanceMySQL/2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/10.%E5%89%8D%E7%AB%AF%E7%BC%96%E8%AF%91%E4%B8%8E%E4%BC%98%E5%8C%96.html2024-10-28T09:40:50.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/11.%E5%90%8E%E7%AB%AF%E7%BC%96%E8%AF%91%E4%B8%8E%E4%BC%98%E5%8C%96.html2024-11-05T06:43:49.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/2.Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8.html2024-09-02T05:37:18.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8A%EF%BC%89.html2024-09-02T05:37:18.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/3.%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5%EF%BC%88%E4%B8%8B%EF%BC%89.html2024-09-02T05:37:18.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/4.%E8%99%9A%E6%8B%9F%E6%9C%BA%E6%80%A7%E8%83%BD%E7%9B%91%E6%8E%A7%E3%80%81%E6%95%85%E9%9A%9C%E5%A4%84%E7%90%86%E5%B7%A5%E5%85%B7.html2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/5.%E8%B0%83%E4%BC%98%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E6%88%98.html2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/6.%E7%B1%BB%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%EF%BC%88%E4%B8%8A%EF%BC%89.html2024-09-02T05:37:18.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/6.%E7%B1%BB%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%EF%BC%88%E4%B8%8B%EF%BC%89.html2024-08-30T03:45:50.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/7.%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/8.%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%AD%97%E8%8A%82%E7%A0%81%E6%89%A7%E8%A1%8C%E5%BC%95%E6%93%8E.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/9.%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%8F%8A%E6%89%A7%E8%A1%8C%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%A1%88%E4%BE%8B%E4%B8%8E%E5%AE%9E%E6%88%98.html2024-10-09T08:10:00.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/books/UnderStandingTheJvm/2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/elasticsearch/basis.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/mysql/dump.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/mysql/logs.html2024-08-30T03:34:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/0.redis7.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/1.%E5%8D%81%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/2.%E6%8C%81%E4%B9%85%E5%8C%96.html2024-09-02T05:37:18.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/3.%E4%BA%8B%E5%8A%A1.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/4.%E7%AE%A1%E9%81%93.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/5.%E5%8F%91%E5%B8%83%E4%B8%8E%E8%AE%A2%E9%98%85.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/6.%E5%A4%8D%E5%88%B6.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/dbs/redis/7.%E5%93%A8%E5%85%B5.html2024-06-14T09:34:35.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloud/2024-05-27T06:50:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/2024-05-27T06:50:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/basis/2024-05-27T06:50:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/basis/basis.html2023-09-18T14:39:52.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/basis/no.html2023-09-22T10:08:41.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/jvm/2024-05-27T06:50:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/jvm/basis.html2024-08-30T03:49:20.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/rocketmq/2024-06-07T09:24:38.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/rocketmq/basis.html2024-06-12T09:19:26.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/spring/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/spring/SpringSecurity.html2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/spring/demo.html2023-08-24T10:13:55.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/thread/2024-05-27T06:50:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/thread/basis.html2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/daily/2023-07-31T03:10:06.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/leetcode-75/2023-07-30T15:05:37.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/leetcode/leetcode-75/string-compression.html2023-08-24T10:13:49.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/archLinux/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/archLinux/install.html2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/basis/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/basis/basis.html2024-01-02T13:39:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/2023-11-28T01:58:43.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/arthas.html2024-03-12T06:38:15.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/basis.html2024-11-05T06:43:49.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/drone.html2024-08-30T03:34:44.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/nginx.html2024-09-02T12:41:04.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/podman-compose.html2024-05-27T03:17:50.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/linux/software/podman.html2024-05-27T03:17:50.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/dubbo/basis.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/nacos/basis.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/seata/basis.html2024-10-08T03:40:12.000Zdailyhttps://vuepress-theme-hope-docs-demo.netlify.app/my-docs/java/SpringCloudAlibaba/sentinel/basis.html2024-10-08T03:40:12.000Zdaily \ No newline at end of file