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程序可以调用本地方法。
- 本地方法被编译成机器码并直接在宿主机上执行。
- 这部分主要用于与平台相关的功能或性能优化。
字节码到机器指令的转换过程
-
加载和解析:
- 类加载器(Class Loader)加载
.class
文件,将字节码加载到内存中,形成Class对象。 - JVM对字节码进行验证,确保其符合JVM规范,避免非法指令和安全风险。
- 类加载器(Class Loader)加载
-
解释执行:
- 解释器逐行读取字节码指令,将其转换为对应的机器码并立即执行。
- 每执行一条指令后,更新程序计数器以指向下一条指令。
-
JIT编译和优化:
- 当某段代码被多次执行时,JIT编译器将其标记为热点代码。
- JIT编译器将热点代码编译为本地机器码,并进行各种优化以提高执行效率。
- 编译后的本地代码被缓存起来,后续执行时可以直接调用,不再需要解释。
通过解释器和JIT编译器的协同工作,JVM能够在初次启动时快速执行代码,并在运行过程中逐步优化性能,实现高效的执行。
什么是字节码文件
Java源代码文件
程序员编写的就是Java源代码文件。
字节码文件
字节码文件是Java编译器(例如javac
)将Java源代码编译后生成的文件。字节码是一种中间表示形式,它是一种针对Java虚拟机(JVM)设计的机器独立的代码。字节码文件包含了JVM能够理解和执行的指令。
字节码文件的生成过程
以下是字节码文件从Java源代码生成的过程:
-
编写Java源代码:程序员编写Java源代码文件,这些文件通常以
.java
扩展名结尾。例如,一个简单的Java源文件
HelloWorld.java
:public class HelloWorld {public static void main(String[] args) {System.out.println("Hello, World!");} }
-
编译Java源代码:使用Java编译器(例如,
javac
)将Java源代码文件编译成字节码文件。编译器会将源代码中的每个Java类编译成一个独立的字节码文件,文件名与类名相同,扩展名为.class
。编译命令:
javac HelloWorld.java
这条命令会生成一个字节码文件
HelloWorld.class
。 -
执行字节码文件:生成的字节码文件可以由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编译器编译后执行。
优势与劣势
-
解释器的优势:
- 快速启动:当程序启动后,解释器可以立即发挥作用,省去编译时间,立即执行。这对于那些对启动时间有严格要求的应用场景非常重要。
- 作为“逃生门”:在编译器进行激进优化时,如果优化不成立,解释器可以作为编译器的“逃生门”,确保程序继续运行。
-
即时编译器的优势:
- 高执行效率:JIT编译器将热点代码(频繁执行的代码段)编译成高效的本地机器码,优化后执行效率极高。
- 长时间运行优化:随着程序运行时间的推移,JIT编译器逐渐发挥作用,根据热点探测功能,将有价值的字节码编译为本地机器指令,以换取更高的程序执行效率。
启动时间与运行效率的平衡
虽然JRockit中的程序执行效率很高,但由于其不包含解释器,程序启动时需要花费更多时间进行编译。对于服务端应用来说,启动时间并非关注重点,JRockit的架构可以提供较高的执行效率。但对于那些看重启动时间的应用场景(如桌面应用或某些实时响应系统),解释器与JIT编译器并存的架构则更为合适。
运行时的动态优化
在HotSpot虚拟机中,当Java虚拟机启动时,解释器首先发挥作用,快速启动并执行程序。随着时间推移,JIT编译器逐渐识别出热点代码,并将其编译为本地机器码。这样,程序可以在初期快速启动,并在后期逐渐优化执行效率。
实际应用中的注意事项
在实际应用中,解释执行与编译执行之间存在微妙的辩证关系。例如,系统在热机状态下可以承受的负载要大于冷机状态。如果在热机状态时进行流量切换,可能会使处于冷机状态的服务器因无法承载流量而假死。因此,理解和调节解释器与JIT编译器的工作方式,对于系统的稳定性和性能优化至关重要。
总结
HotSpot虚拟机采用解释器与即时编译器并存的架构,结合了快速启动和高效执行的优势。在Java虚拟机运行过程中,解释器和JIT编译器相互协作,动态调整执行策略,以提供最佳的性能和响应时间。这种设计不仅提升了应用程序的启动速度,还通过JIT编译器的动态优化,实现了长时间运行下的高效执行。
JIT如何定位热点代码
JVM中的即时编译器(JIT Compiler)通过定位热点代码来优化程序执行。热点代码是指那些被频繁执行的代码段。定位热点代码的过程依赖于JVM的性能监控和分析机制,通常被称为热点探测(HotSpot Detection)。以下是JVM实时编译器定位热点代码的具体流程:
热点代码的定位
-
计数器机制:
- 方法调用计数器:主要用于统计方法的调用次数。每次方法被调用时,JVM会增加该方法的调用计数。当调用计数超过特定阈值时,该方法被标记为热点方法。
- 回边计数器:主要用于统计循环体执行的次数。每次代码块中的循环回边被执行时,JVM会增加相应的回边计数。当回边计数超过特定阈值时,该代码块被标记为热点代码。
-
性能监控:
- JVM内部维护了多个性能监控计数器,这些计数器跟踪方法调用次数、循环执行次数、异常抛出次数等。
- 当某个方法或代码块的计数器值超过预定的阈值时,JVM认为它是热点代码,触发即时编译器进行优化。
热点探测的具体流程
-
初始化计数器:
- JVM启动时,为每个方法和重要代码块(如循环)初始化计数器。
-
计数器更新:
- 每当方法被调用或循环被执行,JVM会相应地更新这些计数器。
-
阈值判断:
- JVM中设有特定的阈值(可以通过参数调整),例如一个方法调用计数达到某个值或循环执行计数达到某个值时,认为该方法或循环是热点代码。
-
触发JIT编译:
- 一旦计数器超过阈值,JVM将该方法或代码块提交给JIT编译器进行编译。
- JIT编译器将热点代码编译为本地机器码,并进行一系列的优化(如内联、循环展开等),以提高执行效率。
-
编译和替换:
- JIT编译器将热点代码编译为本地机器码,并替换原来的字节码。
- 后续的执行直接调用编译后的本地代码,提高运行效率。
优化示例
- 方法内联:将频繁调用的小方法直接内联到调用它的方法中,减少方法调用开销。
- 循环展开:对频繁执行的小循环进行展开,减少循环控制的开销。
- 逃逸分析:确定对象是否逃逸出方法范围,如果没有逃逸,可以进行栈上分配而不是堆上分配,提高内存管理效率。
JVM参数配置
可以通过JVM参数来调整JIT编译的行为和阈值:
-XX:CompileThreshold=N
:设置方法调用计数的阈值,超过此值的方法将被编译。-XX:OnStackReplacePercentage=N
:设置循环回边的阈值,超过此值的循环将被编译。
总结
通过计数器机制和性能监控,JVM实时编译器能够有效地定位热点代码。通过对热点代码进行编译和优化,JVM在不影响启动时间的前提下,显著提高了长时间运行的Java应用程序的执行效率。
热点代码的热度衰减
在HotSpot的JIT编译器中,热点代码的热度衰减(Hot Code Deoptimization or Hot Code Cooling)是指随着时间推移,对某些被频繁执行的代码段减少其“热度”的过程。热度衰减的主要目的是动态地调整和优化JIT编译过程,以应对程序执行时的变化。具体来说,它避免了不再频繁执行的代码段继续被标记为热点代码,从而使JIT编译器能够更有效地分配资源给真正的热点代码。
热点代码的热度衰减机制
热度衰减的机制通过对方法和代码块的执行计数进行调整来实现。这通常涉及以下步骤:
-
计数器递减:定期地,对所有方法和循环回边的计数器进行递减操作。这可以通过一种称为“减半”的技术来实现,即定期将计数器的值减半。
-
时间窗口:引入时间窗口的概念,使得计数器值不仅仅反映历史总执行次数,还反映最近一段时间内的执行频率。这样可以更动态地反映当前的热点情况。
-
重新评估热点代码:在计数器值递减之后,重新评估哪些代码仍然是热点代码。那些计数器值较低的代码段会逐渐失去其热点状态,而计数器值较高的代码段会被继续视为热点代码。
热度衰减的目的和优势
-
动态调整:程序的执行模式可能会随着时间而变化。某些代码段在程序启动时可能被频繁执行,但在后续运行中执行频率降低。热度衰减机制能够动态调整JIT编译器的优化策略,确保资源分配更加合理。
-
资源节约:通过热度衰减机制,JIT编译器可以避免不必要的编译开销。只对真正需要优化的代码段进行编译和优化,减少资源浪费。
-
提高性能:热度衰减机制确保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. 编译器
-
解释器:
- Java在最初运行时使用解释器逐行解释字节码,这确实比C++编译后的本地机器码执行要慢。这是因为解释器需要将每一条字节码翻译成机器码再执行,而C++程序在编译后直接生成高效的本地机器码,可以直接在CPU上运行。
-
即时编译器(JIT Compiler):
- Java通过HotSpot JVM中的即时编译器(JIT)来优化执行效率。JIT编译器会将热点代码编译成高效的本地机器码,从而提升性能。尽管JIT编译能够显著提高Java程序的执行效率,但在某些场景下,JIT编译的开销和优化效果可能仍然无法完全达到C++预编译的效果。
-
C++的静态编译:
- C++程序在编译阶段将所有代码编译成高效的本地机器码,这个过程中可以进行各种高级优化(如内联函数、循环展开、寄存器分配等)。因此,C++程序的运行效率通常会更高。
Java是“半执行”语言的理解
Java被称为“半执行”语言,主要是指其混合了解释执行和编译执行的特点:
-
字节码解释执行:
- Java源代码被编译成字节码(.class文件),这是一种中间表示形式。字节码可以跨平台执行,但初始执行时通过解释器逐行翻译成机器码。
-
即时编译执行:
- 在运行过程中,JIT编译器将热点代码编译成本地机器码,这部分代码的执行效率与C++相当甚至更高,因为JIT编译可以利用运行时信息进行优化。
-
跨平台特性:
- Java程序编译成字节码后,可以在任何安装了Java虚拟机的环境中运行,具备良好的跨平台能力,而C++程序需要为每个目标平台进行重新编译。
性能差异的根本原因
解释器只是导致Java比C++效率低的一个因素,其他原因还包括:
-
内存管理:
- Java使用自动垃圾回收机制(Garbage Collection, GC),虽然简化了内存管理,但在某些情况下会引入额外的开销。而C++允许手动管理内存,可以通过更精细的控制来优化性能。
-
语言特性:
- Java的某些语言特性(如反射、动态类型检查)可能导致性能开销。
-
底层优化:
- 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中,事件对象是在事件触发时由浏览器自动创建的一个对象。它包含了与事件相关的信息,例如触发事件的元素、事件类型、鼠标的坐标等。 可以通过事件处理函数的第一个参数来访问事件对象。例如,在一个鼠标点击…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
Django RBAC项目后端实战 - 03 DRF权限控制实现
项目背景 在上一篇文章中,我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统,为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...
用鸿蒙HarmonyOS5实现国际象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码,使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...
Java中栈的多种实现类详解
Java中栈的多种实现类详解:Stack、LinkedList与ArrayDeque全方位对比 前言一、Stack类——Java最早的栈实现1.1 Stack类简介1.2 常用方法1.3 优缺点分析 二、LinkedList类——灵活的双端链表2.1 LinkedList类简介2.2 常用方法2.3 优缺点分析 三、ArrayDeque类——高…...

Linux 内存管理调试分析:ftrace、perf、crash 的系统化使用
Linux 内存管理调试分析:ftrace、perf、crash 的系统化使用 Linux 内核内存管理是构成整个内核性能和系统稳定性的基础,但这一子系统结构复杂,常常有设置失败、性能展示不良、OOM 杀进程等问题。要分析这些问题,需要一套工具化、…...