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

JVM之【执行引擎】

执行引擎

执行引擎是JVM的核心组件之一,它负责将Java字节码文件转换为机器指令并执行。这一过程涉及多个组成部分,各部分协同工作来完成字节码到机器指令的转换和执行。以下是执行引擎的主要组成部分及其作用:

1. 解释器(Interpreter)

作用:逐行读取并执行字节码。

工作原理

  • 解释器读取程序计数器(PC)指定的字节码指令。
  • 将字节码指令翻译成相应的机器码指令,并立即执行。
  • 执行完一条指令后,更新程序计数器以指向下一条字节码指令。

解释器的优点是启动速度快,缺点是执行效率较低,因为每次都需要逐行翻译字节码。

2. 即时编译器(JIT Compiler)

作用:将字节码编译成高效的本地机器码,提高执行效率。

工作原理

  • 当某些方法或代码段被多次执行时,JIT编译器将这些热点代码(HotSpot Code)编译成本地机器码。
  • 编译后的本地代码被缓存起来,以便后续直接执行,无需再次解释。
  • JIT编译器还会进行各种优化,例如方法内联(Inlining)、循环展开(Loop Unrolling)等,以进一步提高执行性能。

3. 垃圾回收器(Garbage Collector)

作用:管理内存,自动回收不再使用的对象,防止内存泄漏。

工作原理

  • 在程序运行期间,垃圾回收器不断地监视对象的生命周期。
  • 当检测到某些对象不再被引用时,回收这些对象所占用的内存。
  • 垃圾回收策略和算法有多种,如标记-清除(Mark-Sweep)、复制算法(Copying)、标记-整理(Mark-Compact)等。

4. 本地接口(Native Interface)

作用:允许Java代码调用本地代码(通常是C或C++编写的库)。

工作原理

  • 通过Java本地接口(JNI),Java程序可以调用本地方法。
  • 本地方法被编译成机器码并直接在宿主机上执行。
  • 这部分主要用于与平台相关的功能或性能优化。

字节码到机器指令的转换过程

  1. 加载和解析

    • 类加载器(Class Loader)加载.class文件,将字节码加载到内存中,形成Class对象。
    • JVM对字节码进行验证,确保其符合JVM规范,避免非法指令和安全风险。
  2. 解释执行

    • 解释器逐行读取字节码指令,将其转换为对应的机器码并立即执行。
    • 每执行一条指令后,更新程序计数器以指向下一条指令。
  3. JIT编译和优化

    • 当某段代码被多次执行时,JIT编译器将其标记为热点代码。
    • JIT编译器将热点代码编译为本地机器码,并进行各种优化以提高执行效率。
    • 编译后的本地代码被缓存起来,后续执行时可以直接调用,不再需要解释。

通过解释器和JIT编译器的协同工作,JVM能够在初次启动时快速执行代码,并在运行过程中逐步优化性能,实现高效的执行。


什么是字节码文件

Java源代码文件

程序员编写的就是Java源代码文件。

字节码文件

字节码文件是Java编译器(例如javac)将Java源代码编译后生成的文件。字节码是一种中间表示形式,它是一种针对Java虚拟机(JVM)设计的机器独立的代码。字节码文件包含了JVM能够理解和执行的指令。

字节码文件的生成过程

以下是字节码文件从Java源代码生成的过程:

  1. 编写Java源代码:程序员编写Java源代码文件,这些文件通常以.java扩展名结尾。

    例如,一个简单的Java源文件 HelloWorld.java

    public class HelloWorld {public static void main(String[] args) {System.out.println("Hello, World!");}
    }
    
  2. 编译Java源代码:使用Java编译器(例如,javac)将Java源代码文件编译成字节码文件。编译器会将源代码中的每个Java类编译成一个独立的字节码文件,文件名与类名相同,扩展名为.class

    编译命令:

    javac HelloWorld.java
    

    这条命令会生成一个字节码文件 HelloWorld.class

  3. 执行字节码文件:生成的字节码文件可以由JVM执行。JVM读取.class文件中的字节码指令,并通过解释或即时编译(JIT)将其转换为特定平台的机器码,然后执行。

    执行命令:

    java HelloWorld
    

    JVM会加载 HelloWorld.class 文件,解释并执行其中的字节码指令,输出:

    Hello, World!
    

总结

  • Java源代码文件:由程序员编写,扩展名为 .java
  • 字节码文件:由Java编译器生成,包含JVM能够理解和执行的指令,扩展名为 .class

深入理解【解释器】和【编译器】

JVM中的解释器与即时编译器

HotSpot是当前高性能虚拟机的代表作之一,它采用了解释器与即时编译器(JIT)并存的架构。这种设计允许解释器和JIT编译器在Java虚拟机运行时相互协作,各自取长补短,选择最合适的方式来平衡编译本地代码的时间和直接解释执行代码的时间。

为什么需要解释器和JIT编译器并存?

尽管有些开发人员可能会诧异,既然HotSpot中已经内置了JIT编译器,为什么还需要解释器这种看似“拖累”程序执行性能的组件?例如,JRockit虚拟机内部就不包含解释器,所有字节码都依靠JIT编译器编译后执行。

优势与劣势

  1. 解释器的优势

    • 快速启动:当程序启动后,解释器可以立即发挥作用,省去编译时间,立即执行。这对于那些对启动时间有严格要求的应用场景非常重要。
    • 作为“逃生门”:在编译器进行激进优化时,如果优化不成立,解释器可以作为编译器的“逃生门”,确保程序继续运行。
  2. 即时编译器的优势

    • 高执行效率:JIT编译器将热点代码(频繁执行的代码段)编译成高效的本地机器码,优化后执行效率极高。
    • 长时间运行优化:随着程序运行时间的推移,JIT编译器逐渐发挥作用,根据热点探测功能,将有价值的字节码编译为本地机器指令,以换取更高的程序执行效率。

启动时间与运行效率的平衡

虽然JRockit中的程序执行效率很高,但由于其不包含解释器,程序启动时需要花费更多时间进行编译。对于服务端应用来说,启动时间并非关注重点,JRockit的架构可以提供较高的执行效率。但对于那些看重启动时间的应用场景(如桌面应用或某些实时响应系统),解释器与JIT编译器并存的架构则更为合适。

运行时的动态优化

在HotSpot虚拟机中,当Java虚拟机启动时,解释器首先发挥作用,快速启动并执行程序。随着时间推移,JIT编译器逐渐识别出热点代码,并将其编译为本地机器码。这样,程序可以在初期快速启动,并在后期逐渐优化执行效率。

实际应用中的注意事项

在实际应用中,解释执行与编译执行之间存在微妙的辩证关系。例如,系统在热机状态下可以承受的负载要大于冷机状态。如果在热机状态时进行流量切换,可能会使处于冷机状态的服务器因无法承载流量而假死。因此,理解和调节解释器与JIT编译器的工作方式,对于系统的稳定性和性能优化至关重要。

总结

HotSpot虚拟机采用解释器与即时编译器并存的架构,结合了快速启动和高效执行的优势。在Java虚拟机运行过程中,解释器和JIT编译器相互协作,动态调整执行策略,以提供最佳的性能和响应时间。这种设计不仅提升了应用程序的启动速度,还通过JIT编译器的动态优化,实现了长时间运行下的高效执行。


JIT如何定位热点代码

JVM中的即时编译器(JIT Compiler)通过定位热点代码来优化程序执行。热点代码是指那些被频繁执行的代码段。定位热点代码的过程依赖于JVM的性能监控和分析机制,通常被称为热点探测(HotSpot Detection)。以下是JVM实时编译器定位热点代码的具体流程:

热点代码的定位

  1. 计数器机制

    • 方法调用计数器:主要用于统计方法的调用次数。每次方法被调用时,JVM会增加该方法的调用计数。当调用计数超过特定阈值时,该方法被标记为热点方法。
    • 回边计数器:主要用于统计循环体执行的次数。每次代码块中的循环回边被执行时,JVM会增加相应的回边计数。当回边计数超过特定阈值时,该代码块被标记为热点代码。
  2. 性能监控

    • JVM内部维护了多个性能监控计数器,这些计数器跟踪方法调用次数、循环执行次数、异常抛出次数等。
    • 当某个方法或代码块的计数器值超过预定的阈值时,JVM认为它是热点代码,触发即时编译器进行优化。

热点探测的具体流程

  1. 初始化计数器

    • JVM启动时,为每个方法和重要代码块(如循环)初始化计数器。
  2. 计数器更新

    • 每当方法被调用或循环被执行,JVM会相应地更新这些计数器。
  3. 阈值判断

    • JVM中设有特定的阈值(可以通过参数调整),例如一个方法调用计数达到某个值或循环执行计数达到某个值时,认为该方法或循环是热点代码。
  4. 触发JIT编译

    • 一旦计数器超过阈值,JVM将该方法或代码块提交给JIT编译器进行编译。
    • JIT编译器将热点代码编译为本地机器码,并进行一系列的优化(如内联、循环展开等),以提高执行效率。
  5. 编译和替换

    • JIT编译器将热点代码编译为本地机器码,并替换原来的字节码。
    • 后续的执行直接调用编译后的本地代码,提高运行效率。

优化示例

  1. 方法内联:将频繁调用的小方法直接内联到调用它的方法中,减少方法调用开销。
  2. 循环展开:对频繁执行的小循环进行展开,减少循环控制的开销。
  3. 逃逸分析:确定对象是否逃逸出方法范围,如果没有逃逸,可以进行栈上分配而不是堆上分配,提高内存管理效率。

JVM参数配置

可以通过JVM参数来调整JIT编译的行为和阈值:

  • -XX:CompileThreshold=N:设置方法调用计数的阈值,超过此值的方法将被编译。
  • -XX:OnStackReplacePercentage=N:设置循环回边的阈值,超过此值的循环将被编译。

总结

通过计数器机制和性能监控,JVM实时编译器能够有效地定位热点代码。通过对热点代码进行编译和优化,JVM在不影响启动时间的前提下,显著提高了长时间运行的Java应用程序的执行效率。


热点代码的热度衰减

在HotSpot的JIT编译器中,热点代码的热度衰减(Hot Code Deoptimization or Hot Code Cooling)是指随着时间推移,对某些被频繁执行的代码段减少其“热度”的过程。热度衰减的主要目的是动态地调整和优化JIT编译过程,以应对程序执行时的变化。具体来说,它避免了不再频繁执行的代码段继续被标记为热点代码,从而使JIT编译器能够更有效地分配资源给真正的热点代码。

热点代码的热度衰减机制

热度衰减的机制通过对方法和代码块的执行计数进行调整来实现。这通常涉及以下步骤:

  1. 计数器递减:定期地,对所有方法和循环回边的计数器进行递减操作。这可以通过一种称为“减半”的技术来实现,即定期将计数器的值减半。

  2. 时间窗口:引入时间窗口的概念,使得计数器值不仅仅反映历史总执行次数,还反映最近一段时间内的执行频率。这样可以更动态地反映当前的热点情况。

  3. 重新评估热点代码:在计数器值递减之后,重新评估哪些代码仍然是热点代码。那些计数器值较低的代码段会逐渐失去其热点状态,而计数器值较高的代码段会被继续视为热点代码。

热度衰减的目的和优势

  1. 动态调整:程序的执行模式可能会随着时间而变化。某些代码段在程序启动时可能被频繁执行,但在后续运行中执行频率降低。热度衰减机制能够动态调整JIT编译器的优化策略,确保资源分配更加合理。

  2. 资源节约:通过热度衰减机制,JIT编译器可以避免不必要的编译开销。只对真正需要优化的代码段进行编译和优化,减少资源浪费。

  3. 提高性能:热度衰减机制确保JIT编译器能够及时识别和优化新的热点代码,从而提高程序的整体性能。

具体实现

热度衰减在具体实现中可能涉及以下技术:

  • 周期性递减:JVM内部有一个定时器,定期遍历所有方法和循环的计数器,将其值递减。这样可以防止某些代码段因历史调用频繁而一直保持高计数。

  • 阈值调整:根据热度衰减的结果,动态调整JIT编译的阈值。例如,如果某个方法的调用计数在递减后仍然较高,则可能需要进行更高级别的优化。

  • 编译策略调整:结合热度衰减的结果,JIT编译器可以决定是否降级某些已经编译的代码段。例如,如果某段代码在热度衰减后不再是热点,可以将其编译级别降低,以减少编译后的维护开销。

总结

在HotSpot的JIT编译器中,热度衰减机制通过定期递减方法和循环回边的执行计数,动态调整和优化JIT编译过程。这样可以确保JIT编译器将资源集中在当前真正的热点代码上,提高资源利用效率和程序性能。这种动态调整机制使得JVM能够更好地适应程序执行时的变化,提供更高效和智能的即时编译服务。


HotSpot JVM中内嵌的两种即时编译器

在Java虚拟机(JVM)中,C1编译器和C2编译器是两种即时编译器(Just-In-Time Compiler),用于将Java字节码编译为高效的本地机器码。这两种编译器各自有不同的优化策略和适用场景。以下是对C1编译器和C2编译器的详细描述,包括它们的区别、优劣以及各自的优化策略。

C1编译器

C1编译器,也称为客户端编译器(Client Compiler),适用于需要快速启动和响应的应用程序。C1编译器的主要特点和优化策略包括:

特点
  • 快速编译:C1编译器注重快速编译,编译时间较短,生成的机器码相对简单。
  • 轻量级优化:进行一些基本的优化,但不会进行复杂的、高度耗时的优化。
  • 适用于客户端应用:适合于需要快速启动和响应的应用,如桌面应用或移动应用。
优化策略
  • 方法内联(Method Inlining):将小方法的调用直接内联到调用方法中,减少栈帧的生成,减少参数传递及跳转过程。
  • 常量传播(Constant Propagation):将已知的常量值在编译时传播到代码中,减少运行时计算。
  • 死代码消除(Dead Code Elimination):移除不会被执行的代码,减少不必要的指令。
  • 基本块优化(Basic Block Optimization):优化局部代码块,提高执行效率。

C2编译器

C2编译器,也称为服务端编译器(Server Compiler),适用于长时间运行的服务端应用。C2编译器的主要特点和优化策略包括:

特点
  • 高级优化:C2编译器进行复杂的、高度耗时的优化,生成高度优化的机器码。
  • 适用于服务端应用:适合于需要高执行效率和长时间运行的应用,如服务器应用和后台服务。
  • 延迟编译:在应用运行一段时间后才开始编译热点代码,以获得足够的运行时信息进行优化。
优化策略
  • 全局优化(Global Optimization):在整个程序范围内进行优化,而不仅限于局部代码块。
  • 循环优化(Loop Optimization):如循环展开(Loop Unrolling)和循环变换(Loop Transformation),提高循环执行效率。
  • 逃逸分析/栈上分配(Escape Analysis):确定对象是否逃逸出方法范围,如果没有逃逸,可以进行栈上分配,提高内存管理效率。
  • 分支预测(Branch Prediction):通过统计信息预测分支的执行路径,优化分支指令的执行。
  • 寄存器分配(Register Allocation):优化寄存器使用,减少内存访问,提高执行速度。
  • 标量替换
  • 同步消除

C1和C2编译器的区别与优劣

区别
  • 编译速度:C1编译器编译速度快,适合快速启动;C2编译器编译速度较慢,但生成的代码执行效率更高。
  • 优化程度:C1编译器进行基本优化;C2编译器进行高级优化,适用于长时间运行的应用。
  • 适用场景:C1编译器适用于客户端应用;C2编译器适用于服务端应用。
优劣
  • C1编译器的优点

    • 快速启动,适用于需要快速响应的应用。
    • 编译开销低,对资源要求不高。
  • C1编译器的缺点

    • 优化程度有限,生成的代码执行效率较低。
  • C2编译器的优点

    • 高度优化,生成的代码执行效率高。
    • 适用于长时间运行的应用,能够显著提高性能。
  • C2编译器的缺点

    • 编译时间长,启动速度较慢。
    • 编译开销高,对资源要求较高。

组合使用

在实际应用中,HotSpot JVM通常会结合使用C1和C2编译器,这种组合称为分层编译(Tiered Compilation)。分层编译的策略如下:

  • 初始阶段:使用解释器和C1编译器,快速启动应用,并对部分代码进行基本优化。
  • 运行一段时间后:当JVM收集到足够的运行时信息后,C2编译器开始对热点代码进行高级优化,将其编译为高效的本地机器码。

通过分层编译,JVM能够在快速启动和高效执行之间取得平衡,提供最佳的运行时性能。

总结

C1编译器和C2编译器是JVM中两个重要的即时编译器,各自具有不同的优化策略和适用场景。C1编译器适用于需要快速启动和响应的应用,进行基本优化;C2编译器适用于需要高执行效率和长时间运行的应用,进行高级优化。通过结合使用C1和C2编译器,JVM能够在启动速度和执行效率之间取得最佳平衡。


为什么说Java的效率比C++低?是因为解释器慢嘛?

Java的效率比C++低,这种说法有一定的道理,但并不仅仅是因为解释器的存在。更深入理解这一点,需要从以下几个方面来考虑:

解释器 vs. 编译器

  1. 解释器

    • Java在最初运行时使用解释器逐行解释字节码,这确实比C++编译后的本地机器码执行要慢。这是因为解释器需要将每一条字节码翻译成机器码再执行,而C++程序在编译后直接生成高效的本地机器码,可以直接在CPU上运行。
  2. 即时编译器(JIT Compiler)

    • Java通过HotSpot JVM中的即时编译器(JIT)来优化执行效率。JIT编译器会将热点代码编译成高效的本地机器码,从而提升性能。尽管JIT编译能够显著提高Java程序的执行效率,但在某些场景下,JIT编译的开销和优化效果可能仍然无法完全达到C++预编译的效果。
  3. C++的静态编译

    • C++程序在编译阶段将所有代码编译成高效的本地机器码,这个过程中可以进行各种高级优化(如内联函数、循环展开、寄存器分配等)。因此,C++程序的运行效率通常会更高。

Java是“半执行”语言的理解

Java被称为“半执行”语言,主要是指其混合了解释执行和编译执行的特点:

  1. 字节码解释执行

    • Java源代码被编译成字节码(.class文件),这是一种中间表示形式。字节码可以跨平台执行,但初始执行时通过解释器逐行翻译成机器码。
  2. 即时编译执行

    • 在运行过程中,JIT编译器将热点代码编译成本地机器码,这部分代码的执行效率与C++相当甚至更高,因为JIT编译可以利用运行时信息进行优化。
  3. 跨平台特性

    • Java程序编译成字节码后,可以在任何安装了Java虚拟机的环境中运行,具备良好的跨平台能力,而C++程序需要为每个目标平台进行重新编译。

性能差异的根本原因

解释器只是导致Java比C++效率低的一个因素,其他原因还包括:

  1. 内存管理

    • Java使用自动垃圾回收机制(Garbage Collection, GC),虽然简化了内存管理,但在某些情况下会引入额外的开销。而C++允许手动管理内存,可以通过更精细的控制来优化性能。
  2. 语言特性

    • Java的某些语言特性(如反射、动态类型检查)可能导致性能开销。
  3. 底层优化

    • C++允许直接操作指针和进行底层优化,这在某些性能敏感的场景下具有优势。

总结

尽管Java的初始执行效率可能比C++低,但通过JIT编译和其他优化技术,Java程序在长时间运行的场景中可以达到较高的性能。Java被称为“半执行”语言,是因为其结合了解释执行和即时编译执行的特点,兼顾了跨平台性和运行效率。在理解和优化Java程序性能时,需要综合考虑JVM的特性和具体应用场景。

相关文章:

JVM之【执行引擎】

执行引擎 执行引擎是JVM的核心组件之一,它负责将Java字节码文件转换为机器指令并执行。这一过程涉及多个组成部分,各部分协同工作来完成字节码到机器指令的转换和执行。以下是执行引擎的主要组成部分及其作用: 1. 解释器(Interp…...

maven部署到私服

方法一:网页上传 1、账号登录 用户名/密码 2、地址 http://自己的ip:自己的端口/nexus 3、查看Repositories列表,选择Public Repositories,确定待上传jar包不在私服中 4、选择3rd party仓库,点击Artifact Upload页签 5、GAV Definition选…...

Android精通值Fragment的使用 —— 不含底层逻辑(五)

1. Fragment 使用Fragment的目标:根据列表动态显示内容,更简洁显示界面、查找界面 eg. 使用新闻列表动态显示新闻 1.1 Fragment的特性 具备生命周期 —— 可以动态地移除一些Fragment必须委托在Activity中使用可以在Activity中进行复用 1.2 Fragmen…...

apache大数据各组件部署搭建(超级详细)

apache大数据数仓各组件部署搭建 第一章 环境准备 1. 机器规划 准备3台服务器用于集群部署,系统建议CentOS7+,2核8G内存 172.19.195.228 hadoop101 172.19.195.229 hadoop102 172.19.195.230 hadoop103 [root@hadoop101 ~]# cat /etc/redhat-release CentOS Linux rele…...

Servlet搭建博客系统

现在我们可以使用Servlet来搭建一个动态(前后端可以交互)的博客系统了(使用Hexo只能实现一个纯静态的网页,即只能在后台自己上传博客)。有一种"多年媳妇熬成婆"的感觉。 一、准备工作 首先创建好项目,引入相关依赖。具体过程在"Servlet的创建"中介绍了。…...

NextJs 渲染篇 - 什么是CSR、SSR、SSG、ISR 和服务端/客户端组件

NextJs 渲染篇 - 什么是CSR、SSR、SSG、ISR 和服务端/客户端组件 前言一. 什么是CSR、SSR、SSG、ISR1.1 CSR 客户端渲染1.2 SSR 服务端渲染1.3 SSG 静态站点生成① 没有数据请求的页面② 页面内容需要请求数据③ 页面路径需要获取数据 1.4 ISR 增量静态再生1.5 四种渲染方式的对…...

Python 二叉数的实例化及遍历

首先创建一个这样的二叉树,作为我们今天的实例。实例代码在下方。 #创建1个树类型 class TreeNode:def __init__(self,val,leftNone,rightNone):self.valvalself.leftleftself.rightright #实例化类 node1TreeNode(5) node2TreeNode(6) node3TreeNode(7) node4Tre…...

计算 x 的二进制表示中 1 的个数

计算 x 的二进制表示中 1 的个数 代码如下: int func(int x){int countx 0;while (x>0){countx;x x & (x - 1);}return countx;} 完整代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Dat…...

基于Vue的前端瀑布流布局组件的设计与实现

摘要 随着前端技术的不断演进,复杂业务场景和多次迭代后的产品对组件化开发提出了更高的要求。传统的整块应用开发方式已无法满足快速迭代和高效维护的需求。因此,本文将介绍一款基于Vue的瀑布流布局组件,旨在通过组件化开发提升开发效率和降…...

WinSW使用说明

WinSW使用说明 Windows系统下部署多个java程序 场景: 多个java的jar程序,通常来说一个程序使用一个cmd窗口,通过java -jar xxx.jar 命令来运行。这样如果程序多了打开cmd窗口也就多了。 解决: 通过使用WinSW程序,把ja…...

SpringBoot 多模块 多环境 项目 单元测试

环境描述 假设项目中有以下三个yml文件: application.ymlapplication-dev.ymlapplication-prod.yml 假设项目各Module之间依赖关系如下: 其中,D依赖C,C依赖B,B依赖A,D对外提供最终的访问接口 现在要想采…...

网络安全法中的网络安全规定和措施

《中华人民共和国网络安全法》是中国首部全面规范网络空间安全管理的基础性法律,旨在加强网络安全,保障国家安全和社会公共利益,保护公民、法人和其他组织的合法权益,促进互联网的健康发展。以下是该法律中关于网络安全的一些核心…...

一、搭建 Vue3 Admin 项目:从无到有的精彩历程

在前端开发的领域中,Vue3 展现出了强大的魅力,而搭建一个功能丰富的 Vue3 Admin 项目更是充满挑战与乐趣。今天,我将和大家分享我搭建 Vue3 Admin 项目的详细过程,其中用到了一系列重要的依赖包。 首先 让我们开启这个旅程。在确…...

Qt | Qt 资源简介(rcc、qmake)

1、资源系统是一种独立于平台的机制,用于在应用程序的可执行文件中存储二进制文件(前面所讨论的数据都存储在外部设备中)。若应用程序始终需要一组特定的文件(比如图标),则非常有用。 2、资源系统基于 qmake,rcc(Qt 的资源编译器,用于把资源转换为 C++代码)和 QFile …...

对boot项目拆分成cloud项目的笔记

引言:这里我用的是新版本的技术栈 spring-boot-starter-parent >3.2.5 mybatis-spring-boot-starter >3.0.3 mybatis-plus-boot-starter >3.5.5 spring-cloud-dependencies …...

CTF本地靶场搭建——基于阿里云ACR实现动态flag题型的创建

接上文,这篇主要是结合阿里云ACR来实现动态flag题型的创建。 这里顺便也介绍一下阿里云的ACR服务。 阿里云容器镜像服务(简称 ACR)是面向容器镜像、Helm Chart 等符合 OCI 标准的云原生制品安全托管及高效分发平台。 ACR 支持全球同步加速、…...

【面试经典150题】删除有序数组中的重复项

目录 一.删除有序数组中的重复项 一.删除有序数组中的重复项 题目如上图所示,这里非严格递增排序的定义是数字序列,其中相邻的数字可以相等,并且数字之间的差值为1。 这题我们依旧使用迭代器进行遍历,比较当前的数据是否与下一个数…...

太阳能辐射整车综合性能环境试验舱

产品别名 步入式恒温恒湿试验箱、步入式温湿度试验箱、温度试验室、模拟环境试验室、大型恒温恒湿箱、步入式高低温湿热交变试验箱、大型高低温箱、步入式老化箱、恒温恒湿试验房、步入式高低温试验箱. 整车综合性能环境试验舱:整车综合性能环境试验舱:主要用于整车高低温存放…...

JS脚本打包成一个 Chrome 扩展(CRX 插件)

受这篇博客 如何把CSDN的文章导出为PDF_csdn文章怎么导出-CSDN博客 启发,将 JavaScript 代码打包成一个 Chrome 扩展(CRX 插件)。 步骤: 1.创建必要的文件结构和文件: manifest.jsonbackground.jscontent.js 2.编写…...

js事件对象

js事件对象概念说明 在JavaScript中,事件对象是在事件触发时由浏览器自动创建的一个对象。它包含了与事件相关的信息,例如触发事件的元素、事件类型、鼠标的坐标等。 可以通过事件处理函数的第一个参数来访问事件对象。例如,在一个鼠标点击…...

希捷硬盘怎么恢复数据? 5 个免费希捷数据恢复软件

希捷已迅速成为全球最大的数字存储提供商。许多人选择并使用希捷外置硬盘来存储他们的媒体文件、学校或工作文件以及其他重要数据。有时,希捷硬盘中的数据会丢失。 如果您丢失了希捷硬盘上的数据,请不要惊慌。在专业的希捷数据恢复软件的帮助下&#xf…...

Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:京东无人配送机器人

电商巨头京东已选用NVIDIA Jetson AGX Xavier 平台,作为下一代自主配送机器人核心AI算力。 在过去的几十年中,中国占据了全球40%以上的电商交易——每年约为千亿美元。根据麦肯锡全球研究院的数据,这一数字已经高于法国、德国、…...

STM32作业实现(七)OLED显示数据

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…...

elementui el-tooltip文字提示组件弹出层内容格式换行处理

1、第一种 1.1 效果图 1.2、代码 <template><div class"wrapper"><el-tooltip class"content" effect"dark" placement"top"><div slot"content"><div v-html"getTextBrStr(text)"&…...

Python3 笔记:每天一个函数——str.join()

join() &#xff1a;连接字符串数组。将字符串、元组、列表中的元素以指定的字符&#xff08;分隔符&#xff09;连接生成一个新的字符串。 语法&#xff1a;sep.join(seq) 参数说明&#xff1a; sep&#xff1a;分隔符。可以为空。 seq&#xff1a;要连接的元素序列、字符串…...

深入解析Python中的None与null:它们真的不同吗?

标题&#xff1a;深入解析Python中的None与null&#xff1a;它们真的不同吗&#xff1f; 摘要 在Python编程中&#xff0c;None是一个常见的概念&#xff0c;而null则通常与Python之外的语言相关。尽管None和null在某些语言中可以互换使用&#xff0c;但在Python中&#xff0…...

论文作图之高压缩比导出PDF

笔者使用Adobe Illustrator 2023创建可编辑pdf图&#xff0c;按照默认的导出设置保存pdf文件时&#xff0c;得到的图存储很大。为了解决存储过大且还保留一定编辑功能的问题&#xff0c;作者实践出了一种导出pdf的设置方法。 首先在AI中点击文件->存储为&#xff0c;点击保…...

SpringBoot的启动流程

SpringBoot的启动流程 主要包括初始化配置、创建应用程序上下文、刷新上下文以及通知监听者等步骤。 下面将详细探讨SpringBoot的启动流程&#xff0c;以了解其背后的工作原理和机制&#xff1a; 初始化配置&#xff1a;当main方法被调用时&#xff0c;首先通过类加载器读取cla…...

Kubernetes资源调度策略及实现机制

目录 一、资源调度策略 1.默认调度器&#xff08;Default Scheduler&#xff09; 2.自定义调度器&#xff08;Custom Scheduler&#xff09; 3.亲和性与反亲和性&#xff08;Affinity and Anti-Affinity&#xff09; 4.污点与容忍&#xff08;Taint and Tolerations&#…...

finetuning大模型准备(基于Mac环境)

为finetuning进行的热身准备&#xff0c;涉及周边的软件工具&#xff0c;方法。 问题1&#xff1a;finetuning过程较长&#xff0c;采用系统自带命令行没有后台&#xff0c;前台被杀后&#xff0c;容易造成训练失败。 解决方法&#xff1a; tmux可以开启后台训练 问题2&…...

js检验一个字符串是否是正确时间格式的工具方法

js检验一个字符串是否是正确时间格式的工具方法 (()> {/*** 检验字符串是否为时间格式* param {String} date 需要检验的时间格式* returns true 为时间格式&#xff0c;false 为非时间格式*/const isTimaFormat (date) > {if(!date) return false;try{const tempTime …...

大型制造业集团IT信息化总体规划方案(65页PPT)

方案介绍&#xff1a; 本大型制造业集团IT信息化总体规划方案旨在通过构建先进、高效、稳定的IT信息化系统&#xff0c;支撑集团各业务领域的运营和管理需求&#xff0c;促进集团整体运营效率和竞争力的提升。通过实施本项目&#xff0c;集团将能够更好地应对市场变化和客户需…...

【LIN】STM32新能源汽车LIN通信实现过程

【LIN】STM32新能源汽车LIN通信实现过程 文章目录 前言一、软件二、接线图三、硬件原理图四、上位机五、PICO示波器串行解码1.软件中的LIN波特率设置-192002.PIC设置3.PIC串行解码 六.引用总结 前言 【电机控制】直流有刷电机、无刷电机汇总——持续更新 使用工具&#xff1a;…...

【LeetCode:575. 分糖果+ 哈希表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…...

全文检索-ElasticSearch

1.基本概念 1.Index索引 动词&#xff1a;相当于MySQL中的insert&#xff1b; 名词&#xff1a;相当于MySQL中的DataBase&#xff1b; 2.Type&#xff08;类型&#xff09; 在Index&#xff08;索引&#xff09;中&#xff0c;可以定义一个或多个类型 类似于MySQL中的Tab…...

C编程惯用法:深入剖析与实战指南

C编程惯用法&#xff1a;深入剖析与实战指南 在C语言编程的浩瀚海洋中&#xff0c;掌握一些惯用法对于提升代码质量、增强可读性以及降低出错率至关重要。本文将从四个方面、五个方面、六个方面和七个方面&#xff0c;详细剖析C编程中的惯用法&#xff0c;帮助您更好地理解和应…...

MySQL数据表的设计

实际工程中, 对于数据表的设计和创建, 我们遵循以下步骤: 首先确定实体, 找到关键名词, 提取关键信息, 设计表有哪些列, 每一列是什么. (有几个实体, 一般就创建几个表, 一般一个表对应一个实体) 实体之间的关系: 1. 一对一关系 例如: 一个学生, 只能有一个账号; 一个账号只…...

Flutter开发效率提升1000%,Flutter Quick教程之对写好的Widget进行嵌套

通常写代码的时候&#xff0c;我们是先写好外面的Widget&#xff0c;再写里面的Widget。但是&#xff0c;也有的时候&#xff0c;我们写好了一个Widget&#xff0c;但是我们觉得有必要再在外面嵌套一个Widget&#xff0c;这时候应该怎么做呢&#xff1f;&#xff08;还有其他方…...

2020编程语言排序:探索编程界的热门与趋势

2020编程语言排序&#xff1a;探索编程界的热门与趋势 在数字时代的浪潮中&#xff0c;编程语言作为构建数字世界的基石&#xff0c;其流行度和影响力不容忽视。2020年&#xff0c;各大编程语言在各自的领域里展现出独特的魅力和实力。本文将从四个方面、五个方面、六个方面和…...

提高工作效率的招数

自己的工作效率为啥比别人低&#xff0c;因为不会使用工具&#xff0c;这就是一个大冤种。 1.血泪教训&#xff0c;写代码调用第三方接口的时候已经要打印调用日志&#xff0c;不然扯皮真的难搞。 2.pg 上测试或的时候由于schema 错误mybatis会给你报空指针一样&#xff0c;还…...

css特殊效果和页面布局

特殊效果 圆角边框&#xff1a;div{border-radius: 20px 10px 50px 30px;} 四个属性值按顺时针排列&#xff0c;左上的1/4圆半径为20px&#xff0c;右上10&#xff0c;右下50&#xff0c;左下30。 div{border-radius: 20px;} 四角都为20px。 div{border-radius: 20px 10…...

JavaScript中对象的增删改查

1. 增&#xff08;添加属性&#xff09; let obj {}; // 添加一个属性 obj.name John Doe; // 或者使用方括号语法添加属性&#xff08;这对于动态属性名很有用&#xff09; let propName age; obj[propName] 30; console.log(obj); // 输出: { name: John Doe, …...

技术周总结 2024.05.27~06.02(java bean冲突 软件工程)

文章目录 一、05.28 周二1.1&#xff09;问题01&#xff1a;java 引用的jar包中bean名称冲突了&#xff0c;怎么解决&#xff1f;1.2&#xff09;问题02&#xff1a;使用SparkSession将json字符串转成 DataFrame 二、06.01 周六2.1&#xff09;问题01&#xff1a;系统架构师考试…...

「前端+鸿蒙」核心技术HTML5+CSS3(八)

1、网站布局详解 网站布局是前端开发中的核心概念之一,它决定了网页的视觉结构和用户浏览的逻辑顺序。以下是几种常见的布局方式及其代码示例: 固定布局: 固定布局通常具有固定的宽度和高度,适用于传统的桌面视图。 <!DOCTYPE html> <html> <head><…...

15届蓝桥杯决赛,java b组,蒟蒻赛时所写的题思路

这次题的数量是10题&#xff0c;初赛是8题&#xff0c;还多了两题&#xff0c;个人感觉java b组的题意还是比较清晰的&#xff08;不存在读不懂题的情况&#xff09;&#xff0c;但是时间感觉还是不够用&#xff0c;第4题一开始不会写&#xff0c;后面记起来写到结束也没调出来…...

2024蓝桥杯国赛C++研究生组游记+个人题解

Day0 开始复习&#xff0c;过了一遍大部分板子 本来打算再学一遍SAM&#xff0c;但是想到去年考了字符串大题今年应该不会再考了吧。。 过了一遍数据结构和图论&#xff0c;就1点了 两点的时候还没睡着&#xff0c;舍友打游戏好像打到2点过。。 Day1 相当困 第一题&…...

C#WPF数字大屏项目实战07--当日产量

1、第2列布局 第2列分三行&#xff0c;第一行分6列 2、当日产量布局 3、产量数据布局 运行效果 4、计划产量和完成度 运行效果 5、良品率布局 1、添加用户控件 2、用户控件绘制圆 2、使用用户控件 3、运行效果 4、注意点 这三个数值目前是静态的&#xff0c;可以由后台程序项…...

MyBatis源码分析--02:SqlSession建立过程

我们再来看看MyBatis使用流程&#xff1a; InputStream inputStream Resources.getResourceAsStream("myBatis_config.xml"); SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream); SqlSession session sqlSessionFactory.op…...

SOUI Combobox 实现半透明弹出下拉框

SOUI默认情况下combobox的弹出框不是半透明的&#xff0c;这个时候如果背景透明时&#xff0c;滚动条会出现黑色背景&#xff0c;这个时候只需要在在combobox下添加一个子节点 <dropdownStyle translucent"1"></dropdownStyle> 这样一个窗口默认即实现…...

Python 猜数系统 PyQt框架 有GUI界面 (源码在最后)【含Python源码 MX_002期】

一、系统简介 猜数界面是一个基于PyQt框架创建的简单图形用户界面&#xff08;GUI&#xff09;&#xff0c;用于让用户参与猜数字游戏。简要介绍一下界面的各个部分&#xff1a; 游戏开始按钮&#xff1a;点击此按钮开始游戏。在点击前&#xff0c;需要在文本框中输入参与游戏…...