java JMH 学习

JMH 是什么?

JMH(Java Microbenchmark Harness)是一款专用于代码微基准测试的工具集,其主要聚焦于方法层面的基准测试,精度可达纳秒级别。此工具由 Oracle 内部负责实现 JIT 的杰出人士编写,他们对 JIT 及 JVM 在基准测试方面的影响有着深刻的理解。JMH 不仅能够对 Java 语言进行基准测试,还能对运行在 JVM 上的其他语言开展基准测试。
当热点方法被确定,且希望进一步提升方法性能时,可借助 JMH 对优化后的结果进行量化分析。
JMH 具有一些典型的应用场景,如:

  • 精准了解某个方法的执行时间,以及执行时间与输入的相关性;
  • 对比接口不同实现方式在特定条件下的吞吐量;
  • 查看在特定时间段内完成的请求所占比例等。

JMH 在JDK9 中是自带的 在JDK9 之前 我们需要主动的引入下maven包

<dependency><groupId>org.openjdk.jmh</groupId><artifactId>jmh-core</artifactId><version>1.23</version>
</dependency>
<dependency><groupId>org.openjdk.jmh</groupId><artifactId>jmh-generator-annprocess</artifactId><version>1.23</version>
</dependency>

让我们来些第一个 JMH 测试代码吧!

package cn.ideamake.im.auth.service;import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;import com.google.common.collect.Lists;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;/*** @author Barcke* @version 1.0* @projectName im-auth* @className Test* @date 2024/4/30 16:30* @slogan: 源于生活 高于生活* @description:**/// 用来配置 Mode 选项,可用于类或者方法上,这个注解的 value 是一个数组,可以把几种 Mode 集合在一起执行 比如 @BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
@BenchmarkMode(// 每一次方法执行用的平均时间,每次操作的平均时间,单位为 time/op
//        Mode.AverageTime// 随机取样,最后输出取样结果的分布
//        Mode.SampleTime// 只运行一次,往往同时把 Warmup 次数设为 0,用于测试冷启动时的性能
//        Mode.SingleShotTime// 吞吐量,每秒执行了多少次调用,单位为 ops/timeMode.Throughput// 上面的所有模式都执行一次
//        Mode.All
)
// 预热所需要配置的一些基本测试参数,可用于类或者方法上。一般前几次进行程序测试的时候都会比较慢,所以要让程序进行几轮预热,保证测试的准确性。
@Warmup(// 预热次数iterations = 3// 每次预热的时间, time = 1// 时间单位,默认秒, timeUnit = TimeUnit.SECONDS// 批处理大小,每次操作调用几次方法, batchSize = 100
)
@Measurement(iterations = 5, time = 5)
// 每个测试线程数量,可用于类或者方法上。
@Threads(5)
// 进行 fork 的次数,可用于类或者方法上。如果 fork 数是 3 的话,则 JMH 会 fork 出三个进程来进行测试。
@Fork(3)
// 指定一个对象的作用范围,JMH 根据 scope 来进行实例化和共享操作。@State 可以被继承使用,如果父类定义了该注解,子类则无需定义。由于 JMH 允许多线程同时执行测试
@State(// 默认是 Scope.Benchmark 所有测试线程共享一个实例,测试有状态实例在多线程共享下的性能
//        value = Scope.Benchmark// 线程作用域,每个线程都有自己的实例,每个线程的实例相互独立,不会相互影响value = Scope.Thread// 线程组作用域,线程组内的线程共享一个实例,线程组外的线程不会共享实例,每个线程的实例相互独立,不会相互影响
//        value = Scope.Group
)
// 结果输出时间单位 可用于类或者方法注解
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class Test {private final String KEY = "barcke";private List<String> arrayList;private List<String> linkedList;// 测试参数@Param(value = {"10", "20", "30"})private int length;// @Setup 测试初始化方法 对应在执行测试方法之后调用的可以使用注解 @TearDown 声明@Setup(// 由于我们设置Warmup和Measurement的不同,因此每一个基准测试方法都会被执行若干个批次,如果想要在每一个基准测试批次执行的前后调用方法,则可以将Level设置为Iteration。
//            Level.Iteration// 意味着在每一个批次的度量过程中,每一次对基准方法的调用前都会执行套件方法。
//            Level.Invocation// Setup和TearDown默认的配置,该套件方法会在每一个基准测试方法的所有批次执行的前后被执行。Level.Trial)public void setup() {arrayList = Lists.newCopyOnWriteArrayList();linkedList = new LinkedList<>();}// Benchmark 用于 测试方法声明@Benchmarkpublic List<String> arrayListAdd() {for (int i = 0; i < length; i++) {arrayList.add(KEY);}return arrayList;}// Benchmark 用于 测试方法声明@Benchmarkpublic List<String> linkedListAdd() {for (int i = 0; i < length; i++) {linkedList.add(KEY);}return linkedList;}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder()// 要导入的测试类.include(Test.class.getSimpleName())// 输出测试结果的文件.result("result.json").resultFormat(ResultFormatType.JSON).build();new Runner(opt).run();}}

需要进行测试的方法会用@Benchmark 注解来标识,关于这些注解的详细含义,将在后续内容中进行具体阐述。
在 main()函数中,首先会对测试用例进行相应的配置。通过采用 Builder 模式来配置测试,将配置的各项参数存入 Options 对象中,然后再利用该 Options 对象来构建 Runner 并启动测试。

使用Main方法执行测试

需注意!!!
idea执行基准测试过程中可能会出现内存泄露的报错:java.lang.OutOfMemoryError: Java heap space
加大JVM的内存参数值即可
如:
image
image

做好准备工作后,开始运行代码,静待片刻,测试结果就会出炉,下面对结果做一个简单的分析:
image

image

image
最终结果:
image

可视化 JMH 工具

JMH Visual Chart:http://deepoove.com/jmh-visual-chart/
JMH Visualizer:https://jmh.morethan.io/

将json文件导入到网站中则可以得到可视化图表数据
image

我跑出来的json数据 不过吞吐量没有啥区别~

[{"jmhVersion" : "1.23","benchmark" : "cn.ideamake.im.auth.service.Test.arrayListAdd","mode" : "thrpt","threads" : 5,"forks" : 3,"jvm" : "/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/jre/bin/java","jvmArgs" : ["-javaagent:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/lib/idea_rt.jar=61534:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/bin","-Dfile.encoding=UTF-8"],"jdkVersion" : "1.8.0_261","vmName" : "Java HotSpot(TM) 64-Bit Server VM","vmVersion" : "25.261-b12","warmupIterations" : 3,"warmupTime" : "1 s","warmupBatchSize" : 100,"measurementIterations" : 5,"measurementTime" : "5 s","measurementBatchSize" : 1,"params" : {"length" : "10"},"primaryMetric" : {"score" : 2.4948150613578957E-6,"scoreError" : 1.1238982246115864E-6,"scoreConfidence" : [1.3709168367463092E-6,3.618713285969482E-6],"scorePercentiles" : {"0.0" : 1.4561640572531666E-6,"50.0" : 2.1912588467079646E-6,"90.0" : 4.420901428147037E-6,"95.0" : 4.841074442897258E-6,"99.0" : 4.841074442897258E-6,"99.9" : 4.841074442897258E-6,"99.99" : 4.841074442897258E-6,"99.999" : 4.841074442897258E-6,"99.9999" : 4.841074442897258E-6,"100.0" : 4.841074442897258E-6},"scoreUnit" : "ops/ns","rawData" : [[4.1138049369997915E-6,2.4765216035616155E-6,2.1912588467079646E-6,1.789423605929749E-6,1.4561640572531666E-6],[4.140786084980223E-6,2.5591632462186068E-6,2.2445508618694107E-6,1.7726205421615725E-6,1.5585637200319034E-6],[4.841074442897258E-6,2.800833094186311E-6,1.9730874497911443E-6,1.8848866640894546E-6,1.6194867636902629E-6]]},"secondaryMetrics" : {}},{"jmhVersion" : "1.23","benchmark" : "cn.ideamake.im.auth.service.Test.arrayListAdd","mode" : "thrpt","threads" : 5,"forks" : 3,"jvm" : "/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/jre/bin/java","jvmArgs" : ["-javaagent:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/lib/idea_rt.jar=61534:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/bin","-Dfile.encoding=UTF-8"],"jdkVersion" : "1.8.0_261","vmName" : "Java HotSpot(TM) 64-Bit Server VM","vmVersion" : "25.261-b12","warmupIterations" : 3,"warmupTime" : "1 s","warmupBatchSize" : 100,"measurementIterations" : 5,"measurementTime" : "5 s","measurementBatchSize" : 1,"params" : {"length" : "20"},"primaryMetric" : {"score" : 1.2859270068428564E-6,"scoreError" : 6.255401258543347E-7,"scoreConfidence" : [6.603868809885217E-7,1.911467132697191E-6],"scorePercentiles" : {"0.0" : 7.927250243370195E-7,"50.0" : 1.0489617370260857E-6,"90.0" : 2.4044188117910495E-6,"95.0" : 2.506172746185885E-6,"99.0" : 2.506172746185885E-6,"99.9" : 2.506172746185885E-6,"99.99" : 2.506172746185885E-6,"99.999" : 2.506172746185885E-6,"99.9999" : 2.506172746185885E-6,"100.0" : 2.506172746185885E-6},"scoreUnit" : "ops/ns","rawData" : [[2.506172746185885E-6,1.3749914022210378E-6,1.042460182653776E-6,8.085105009167249E-7,7.98261178607378E-7],[2.150161901013991E-6,1.362837559664351E-6,1.0489617370260857E-6,8.930920686728167E-7,7.940245030098016E-7],[2.336582855527826E-6,1.4214980159279697E-6,1.0585275386698327E-6,9.000978882083538E-7,7.927250243370195E-7]]},"secondaryMetrics" : {}},{"jmhVersion" : "1.23","benchmark" : "cn.ideamake.im.auth.service.Test.arrayListAdd","mode" : "thrpt","threads" : 5,"forks" : 3,"jvm" : "/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/jre/bin/java","jvmArgs" : ["-javaagent:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/lib/idea_rt.jar=61534:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/bin","-Dfile.encoding=UTF-8"],"jdkVersion" : "1.8.0_261","vmName" : "Java HotSpot(TM) 64-Bit Server VM","vmVersion" : "25.261-b12","warmupIterations" : 3,"warmupTime" : "1 s","warmupBatchSize" : 100,"measurementIterations" : 5,"measurementTime" : "5 s","measurementBatchSize" : 1,"params" : {"length" : "30"},"primaryMetric" : {"score" : 8.471727655992797E-7,"scoreError" : 3.7052359443423565E-7,"scoreConfidence" : [4.766491711650441E-7,1.2176963600335153E-6],"scorePercentiles" : {"0.0" : 5.302584706779764E-7,"50.0" : 6.834675315679355E-7,"90.0" : 1.52180707672635E-6,"95.0" : 1.5528636107639667E-6,"99.0" : 1.5528636107639667E-6,"99.9" : 1.5528636107639667E-6,"99.99" : 1.5528636107639667E-6,"99.999" : 1.5528636107639667E-6,"99.9999" : 1.5528636107639667E-6,"100.0" : 1.5528636107639667E-6},"scoreUnit" : "ops/ns","rawData" : [[1.5528636107639667E-6,9.596786727520295E-7,7.375483032591416E-7,6.000565980573166E-7,5.302584706779764E-7],[1.3089866553403504E-6,8.848246687708236E-7,6.728363935992605E-7,6.39243117656085E-7,5.589492168761859E-7],[1.5011027207012722E-6,9.477396838941437E-7,6.834675315679355E-7,5.996515606679904E-7,5.303842794047184E-7]]},"secondaryMetrics" : {}},{"jmhVersion" : "1.23","benchmark" : "cn.ideamake.im.auth.service.Test.linkedListAdd","mode" : "thrpt","threads" : 5,"forks" : 3,"jvm" : "/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/jre/bin/java","jvmArgs" : ["-javaagent:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/lib/idea_rt.jar=61534:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/bin","-Dfile.encoding=UTF-8"],"jdkVersion" : "1.8.0_261","vmName" : "Java HotSpot(TM) 64-Bit Server VM","vmVersion" : "25.261-b12","warmupIterations" : 3,"warmupTime" : "1 s","warmupBatchSize" : 100,"measurementIterations" : 5,"measurementTime" : "5 s","measurementBatchSize" : 1,"params" : {"length" : "10"},"primaryMetric" : {"score" : 3.1518365953260005E-4,"scoreError" : 2.650344132453461E-4,"scoreConfidence" : [5.0149246287253975E-5,5.802180727779462E-4],"scorePercentiles" : {"0.0" : 2.040936832220465E-9,"50.0" : 3.258020124110451E-4,"90.0" : 6.290582852453083E-4,"95.0" : 6.511044004158607E-4,"99.0" : 6.511044004158607E-4,"99.9" : 6.511044004158607E-4,"99.99" : 6.511044004158607E-4,"99.999" : 6.511044004158607E-4,"99.9999" : 6.511044004158607E-4,"100.0" : 6.511044004158607E-4},"scoreUnit" : "ops/ns","rawData" : [[5.799090206566678E-4,2.8203434053498754E-4,4.084852992147824E-4,5.5462968000398634E-5,2.040936832220465E-9],[5.959891124894796E-4,2.741420658031856E-4,4.050103147846094E-4,1.292647379800531E-4,2.1377832450477853E-9],[6.511044004158607E-4,3.258020124110451E-4,3.9017912291265433E-4]]},"secondaryMetrics" : {}},{"jmhVersion" : "1.23","benchmark" : "cn.ideamake.im.auth.service.Test.linkedListAdd","mode" : "thrpt","threads" : 5,"forks" : 3,"jvm" : "/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/jre/bin/java","jvmArgs" : ["-javaagent:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/lib/idea_rt.jar=61534:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/bin","-Dfile.encoding=UTF-8"],"jdkVersion" : "1.8.0_261","vmName" : "Java HotSpot(TM) 64-Bit Server VM","vmVersion" : "25.261-b12","warmupIterations" : 3,"warmupTime" : "1 s","warmupBatchSize" : 100,"measurementIterations" : 5,"measurementTime" : "5 s","measurementBatchSize" : 1,"params" : {"length" : "20"},"primaryMetric" : {"score" : 1.266940848706251E-4,"scoreError" : 1.067901481727194E-4,"scoreConfidence" : [1.9903936697905698E-5,2.334842330433445E-4],"scorePercentiles" : {"0.0" : 1.0570643716444602E-9,"50.0" : 1.277025840062132E-4,"90.0" : 2.873144880878097E-4,"95.0" : 3.0071795274955784E-4,"99.0" : 3.0071795274955784E-4,"99.9" : 3.0071795274955784E-4,"99.99" : 3.0071795274955784E-4,"99.999" : 3.0071795274955784E-4,"99.9999" : 3.0071795274955784E-4,"100.0" : 3.0071795274955784E-4},"scoreUnit" : "ops/ns","rawData" : [[2.7837884497997756E-4,1.4004379809432887E-4,1.690648751904472E-4,3.979439739105633E-5,1.0570643716444602E-9],[2.539248775424261E-4,1.2300171183989418E-4,1.6619190221717098E-4,9.198943682584735E-5,3.341751395204592E-7],[3.0071795274955784E-4,1.277025840062132E-4,1.712266253033709E-4,3.8037901883119315E-5,1.1328320741323733E-9]]},"secondaryMetrics" : {}},{"jmhVersion" : "1.23","benchmark" : "cn.ideamake.im.auth.service.Test.linkedListAdd","mode" : "thrpt","threads" : 5,"forks" : 3,"jvm" : "/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/jre/bin/java","jvmArgs" : ["-javaagent:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/lib/idea_rt.jar=61534:/Users/jeyyu/Applications/IntelliJ IDEA Ultimate.app/Contents/bin","-Dfile.encoding=UTF-8"],"jdkVersion" : "1.8.0_261","vmName" : "Java HotSpot(TM) 64-Bit Server VM","vmVersion" : "25.261-b12","warmupIterations" : 3,"warmupTime" : "1 s","warmupBatchSize" : 100,"measurementIterations" : 5,"measurementTime" : "5 s","measurementBatchSize" : 1,"params" : {"length" : "30"},"primaryMetric" : {"score" : 1.0018490369816409E-4,"scoreError" : 7.4688462191315E-5,"scoreConfidence" : [2.549644150684908E-5,1.748733658894791E-4],"scorePercentiles" : {"0.0" : 2.423143548980252E-8,"50.0" : 9.23894279692493E-5,"90.0" : 2.1170862702798537E-4,"95.0" : 2.220596797238462E-4,"99.0" : 2.220596797238462E-4,"99.9" : 2.220596797238462E-4,"99.99" : 2.220596797238462E-4,"99.999" : 2.220596797238462E-4,"99.9999" : 2.220596797238462E-4,"100.0" : 2.220596797238462E-4},"scoreUnit" : "ops/ns","rawData" : [[2.0480792523074482E-4,8.962885218669426E-5,1.1985924046108952E-4,6.011791224746196E-5,3.439292032454452E-8],[1.8999885350868268E-4,8.464552988300562E-5,1.1405865213041896E-4,7.856668953262646E-5,2.423143548980252E-8],[2.220596797238462E-4,1.1198263143710367E-4,1.345185179434591E-4,9.23894279692493E-5,8.101886226446768E-8]]},"secondaryMetrics" : {}}
]

本文到此结束,希望对你有帮助~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/7549.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

#LLM入门 | langchain | RAG # 4.1 简介_使用 LangChain 访问个人数据

课程介绍&#xff1a;《第四部分&#xff1a;使用 LangChain 访问个人数据》是基于LangChain创始人Harrison Chase与Deeplearning.ai合作开发的课程&#xff0c;旨在教授如何通过LangChain框架使语言模型&#xff08;LLM&#xff09;访问和应用用户个人数据。背景说明&#xff…

PD芯片取电:电子设备的动力之源6020 6500

随着现代电子技术的迅猛发展&#xff0c;电源管理技术在各种电子设备中扮演着越来越重要的角色。特别是近年来&#xff0c;随着USB Power Delivery&#xff08;PD&#xff09;技术的普及&#xff0c;PD芯片取电技术因其高效、灵活和安全的特点&#xff0c;成为了电子设备充电和…

java项目中如何更优雅的处理空值

在Java项目中&#xff0c;优雅地处理空值&#xff08;null&#xff09;是一个重要的实践&#xff0c;因为它有助于提高代码的健壮性和可读性。以下是一些建议&#xff0c;帮助你更优雅地处理空值&#xff1a; 使用Optional类&#xff08;Java 8及以上&#xff09; Java 8引入了…

Vue + Element-plus 快速入门

1. 构建项目 npm init vuelatest # 可选项一路回车&#xff0c;使用默认NO,按提示执行3条命令 cd 项目名 npm install npm run dev 2. 下载element-plus npm install element-plus --save 3.替换main.js import { createApp } from vue import ElementPlus from element-plu…

相关性分析

目录 1.交叉功率谱 2. 相关系数 1.交叉功率谱 % 生成两个信号 t 0:0.001:100; x sin(2*pi*1*t)sin(2*pi*2*t); y sin(2*pi*t )sin(2*pi*2*t); % 计算交叉功率谱密度 [Pxy, F] cpsd(x, y, [], [], [], 1/(t(2)-t(1))); % 使用正确的采样频率 % 绘制交叉功率谱密度图 …

ISIS的基本配置

1.IS-IS协议的基本配置&#xff08;1&#xff09; 2.IS-IS协议的基本配置&#xff08;2&#xff09; 3.IS-IS协议的基本配置&#xff08;3&#xff09; 4.案例&#xff1a;IS-IS配置 R1的配置如下&#xff1a; [AR1czy]isis 1 [AR1czy-isis-1]is-level level-1 [AR1czy-isis-…

电磁兼容(EMC):静电放电(ESD)基本原理

目录 1. 静电学简史 2. 摩擦生电原理 3. 总结 静电放电是电磁兼容&#xff08;EMC&#xff09;系列里最让人头疼的问题之一。无论是现在还是未来&#xff0c;静电问题肯定是做产品设计需要重点考虑的问题。这里来聊聊关于静电放电的一些发展历程和基本原理。 1. 静电学简史…

公开地图服务

XYZ参考: http://openwhatevermap.xyz/ 高德参考&#xff1a;https://blog.csdn.net/ldlzhy1984/article/details/81015180 https://blog.csdn.net/fredricen/article/details/77189453 高德矢量图&#xff1a;https://webrd02.is.autonavi.com/appmaptile?langzh_cn&size…

市面上好用的AI工具有哪些?

市面上的AI工具数不胜数&#xff0c;选择合适自己的AI工具则需要考虑自己的需求&#xff0c;看是否能满足的使用需求。那么市面上又有哪些好用的AI工具呢&#xff1f; 泰迪智能科技拥有简单易用的大数据挖掘建模平台&#xff0c;能够让数据创造更大的价值。 功能板块&…

技术干货:单体,SOA,微服务,分布式,集群架构详解

理解这些架构概念对于软件工程师至关重要。下面我会简要介绍这些架构&#xff0c;并提供一些示例代码来说明它们的实现方式。 单体架构&#xff1a; 在单体架构中&#xff0c;整个应用程序被构建为一个单独的、紧密耦合的单元。通常使用传统的三层架构&#xff1a;表示层、业务…

C++实现二叉搜索树(模型)

目录 1.二叉搜索树的概念 2.二叉搜索树的实现 2.1总体代码预览 2.2各个函数实现原理 链表结构体 二叉搜索树的成员变量 二叉搜索树的插入 二叉搜索树的查找 二叉搜索树的遍历 二叉搜索树的删除 1.二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#…

算法训练营第63天|LeetCode 84.柱状图中最大的矩形

完结&#xff01;撒花&#xff01; LeetCode 84.柱状图中最大的矩形 题目链接&#xff1a; LeetCode 84.柱状图中最大的矩形 代码&#xff1a; class Solution { public:int largestRectangleArea(vector<int>& heights) {heights.insert(heights.begin(),0);he…

字符设备驱动流程

字符设备驱动&#xff1a; linux系统驱动程序分为三大类&#xff0c;字符设备驱动&#xff0c;块设备驱动和网络设备驱动。其中字符设备驱动是使用最多的一种&#xff0c;从点灯到llC&#xff0c;SPI&#xff0c;音频设备等的驱动都是字符设备驱动。块设备和网络设备驱动要比字…

5.12 VUE项目实现Google 第三方登录

VUE项目实现Google 第三方登录 目录一、Google开发者平台配置1. 新建项目2. 配置 OAuth 权限请求页面并选择范围3. 启动API 和 服务 二、 登录代码实现1. 参考Google官网文档2. Google官网代码生成器3. 项目中实装 目录 一、Google开发者平台配置 Google Cloud: https://conso…

python读取xml文件并修改object目标label的信息

python读取xml文件并修改object目标label的信息 python读取xml文件并修改object目标label的信息 python读取xml文件并修改object目标label的信息 """ python 读取xml文件内容并完成修改 """ import os import xml.etree.ElementTree as ET from…

可自定义的海外仓系统与传统WMS:哪个更适合你?

在可自定义的海外仓系统和传统的WMS之间进行选择&#xff0c;想确定一个适合自己的正确方案往往并不那么容易。 这需要考虑企业的现状&#xff0c;仓库的经营情况&#xff0c;对管理系统具体的需求等等。今天我们将对这两种系统做一个完整的对比&#xff0c;帮助你决定哪一个更…

盒模型,BFC以及行内块级元素

一.盒模型篇 css基础框盒模型介绍&#xff1a; 当对一个文档进行布局的时候&#xff0c;浏览器的渲染引擎会根据标准之一的css基础框盒模型&#xff0c;将所有元素表示为一个个矩形的盒子&#xff0c;每个盒子由四部分组成&#xff0c;分别是内容 内边距 边框 外边距&#xff…

如何快速搭建nginx虚拟主机

华子目录 实验1&#xff1a;基于IP地址的虚拟主机原理 实验2&#xff1a;基于端口号的虚拟主机原理 实验3&#xff1a;基于域名的虚拟主机原理 实验1&#xff1a;基于IP地址的虚拟主机 原理 如果一台服务器有多个IP地址&#xff0c;而且每个IP地址与服务器上部署的每个网站一一…

beacon-chain+ethereum打镜像及推送镜像

部署详情 1、编写Dockerfile镜像 beacon chain对应Dockerfile文件 # 使用 Ubuntu 20.04 作为基础镜像 FROM ubuntu:20.04# 安装必要的系统库和工具 RUN apt-get update && \apt-get install -y curl && \apt-get clean# 创建存储数据的目录 RUN mkdir -p /dat…

HarmonyOS开发案例:【计算器】

介绍 基于基础组件、容器组件&#xff0c;实现一个支持加减乘除混合运算的计算器。 说明&#xff1a; 由于数字都是双精度浮点数&#xff0c;在计算机中是二进制存储数据的&#xff0c;因此小数和非安全整数&#xff08;超过整数的安全范围[-Math.pow(2, 53)&#xff0c;Math.…