橘子学JDK之JMH-02(BenchmarkModes)

一、案例二代码

这次我们来搞一下官网文档的第二个案例,我删除了一些没用的注释,然后对代码做了一下注释的翻译,可以看一下意思。

package com.levi;import org.openjdk.jmh.annotations.*;
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 java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Mode.Throughput, as stated in its Javadoc, measures the raw throughput by* continuously calling the benchmark method in a time-bound iteration, and* counting how many times we executed the method.** We are using the special annotation to select the units to measure in,* although you can use the default.** AI直译:Mode.Throughput,如其Javadoc所述,通过在时间限制的迭代中连续调用基准方法,* 并计算我们执行该方法的次数来衡量原始吞吐量。我们正在使用特殊注解来选择要测量的单位,尽管你可以使用默认值。** 我根据我的理解还是说几句人话吧,他的意思是我们之前不是在案例1中输出的是吞吐量的测试指标吗,这里的意思是你可以* 使用@BenchmarkMode这个注解,里面设置参数Mode.Throughput一样可以是通过吞吐量的指标的,或者说你不设置,默认* 本身就是吞吐量,我们第一个案例就是默认的。* 所以我们在第一个方法上看到新出现的两个注解* @BenchmarkMode:设置计算指标* @OutputTimeUnit:计算模式对应的单位*/@Benchmark@BenchmarkMode(Mode.Throughput)@OutputTimeUnit(TimeUnit.SECONDS)public void measureThroughput() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}/** Mode.AverageTime measures the average execution time, and it does it* in the way similar to Mode.Throughput.* 在性能测试或基准测试的背景下,Mode.AverageTime(平均时间模式)测量了给定操作或代码片段的平均执行时间。* 该模式计算了每次调用被测试代码所花费的平均时间。它与Mode.Throughput(吞吐量模式)相似,两种模式都专注于性能测量,* 但它们在优先考虑的性能方面存在差异。以下是Mode.AverageTime和Mode.Throughput之间的简要比较:* 平均时间:该模式计算每个操作或调用的平均执行时间。它提供了关于单个操作平均执行时间的信息。* 吞吐量:另一方面,Mode.Throughput关注的是在给定时间内完成的操作速率。它衡量每单位时间内可以执行多少操作,通常是每秒。* 它提供了系统在高负载下处理大量操作的效率信息。* 虽然两种模式都提供了有关性能的有价值的信息,但它们服务于不同的目的,可能适用于不同类型的性能分析。* Mode.AverageTime适用于了解单个操作的平均延迟或执行时间,而Mode.Throughput更适用于在指定时间范围内最大化完成的操作数量。*** Some might say it is the reciprocal throughput, and it really is.* There are workloads where measuring times is more convenient though.* 有人说,这个指标是吞吐量的倒数,你也可以这么理解,不过有时候你测试的时候,统计时间维度是更加直观的。** 换言之,这个是统计你方法的执行平均时间的,所以看起来比吞吐量更加直观,毕竟耗时是我们普遍关心的第一指标*/@Benchmark@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureAvgTime() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}/** Mode.SampleTime samples the execution time. With this mode, we are* still running the method in a time-bound iteration, but instead of* measuring the total time, we measure the time spent in *some* of* the benchmark method calls.** Mode.SampleTime是用于对方法执行时间进行采样的一种模式。在这种模式下,我们仍然在一个有时间限制的迭代中运行方法,* 但不再测量总时间,而是测量一部分基准方法调用所花费的时间。使用Mode.SampleTime模式时,* 基准测试框架会定期中断方法的执行并记录经过的时间。通过只对部分调用进行采样,可以减少与连续时间测量相关的开销,* 同时仍能提供有关方法执行时间分布的有意义数据,而不仅仅关注整体持续时间。这种模式对于识别执行时间的变化非常有用,* 特别是如果方法的某些部分可能具有不同的性能特点或表现出间歇性行为。它使开发人员能够了解方法在不同条件下的性能表现,* 并帮助优化其性能。** This allows us to infer the distributions, percentiles, etc.* JMH also tries to auto-adjust sampling frequency: if the method* is long enough, you will end up capturing all the samples.* 这样可以让我们推断出分布情况、百分位数等。JMH 还会尝试自动调整采样频率:如果方法足够长,你最终会捕获到所有的样本** 这个解释的不明确,我们待会通过现象来看一下具体啥意思。*/@Benchmark@BenchmarkMode(Mode.SampleTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureSamples() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}/** Mode.SingleShotTime measures the single method invocation time. As the Javadoc* suggests, we do only the single benchmark method invocation. The iteration* time is meaningless in this mode: as soon as benchmark method stops, the* iteration is over.** Mode.SingleShotTime测量的是单个方法调用的时间。正如Javadoc所建议的,我们只进行一次基准方法的调用。* 在这种模式下,迭代时间是没有意义的:一旦基准方法停止,迭代就结束了。** This mode is useful to do cold startup tests, when you specifically* do not want to call the benchmark method continuously.* 这种模式在进行冷启动测试时非常有用,当你不想连续调用基准方法时。** 说白了就是只测试一次,就跟你跑main函数一样的,没有预热,就是冷启动的测试。*/@Benchmark@BenchmarkMode(Mode.SingleShotTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureSingleShot() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}/** We can also ask for multiple benchmark modes at once. All the tests* above can be replaced with just a single test like this:** 这个注解还能写数组,指定多种测试指标,一起生效*/@Benchmark@BenchmarkMode({Mode.Throughput, Mode.AverageTime, Mode.SampleTime, Mode.SingleShotTime})@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureMultiple() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}/** Or even...* 如果你懒得写很多模式,你还能直接用Mode.All来表示全部的模式*/@Benchmark@BenchmarkMode(Mode.All)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureAll() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

二、@BenchmarkMode

我们先不急着运行程序,我们在看完上面的例子之后可以看到这次出现了一个新的注解,就是
@BenchmarkMode

@Inherited
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface BenchmarkMode {Mode[] value();
}

这个注解我们看到,作用的位置就是方法和类上面,你要是标注在类上,那就这个类所有的方法都按照这个配置生效了。
而且我们注意到他有一个变量,是Mode类型的数组,注意是数组,也就是可以传入多个。我们看一下这个Mode类型是啥。

public enum Mode {Throughput("thrpt", "Throughput, ops/time"),AverageTime("avgt", "Average time, time/op"),SampleTime("sample", "Sampling time"),SingleShotTime("ss", "Single shot invocation time"),All("all", "All benchmark modes");
}

就是个枚举类型,总共五个类型,我们上面的注释其实也标注了这五个类型的各自的作用。

三、 @OutputTimeUnit

与@BenchmarkMode 配套的还有一个注解就是@OutputTimeUnit。

@Inherited
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface OutputTimeUnit {TimeUnit value();
}

他的作用就是你输出指标的时间单位,没别的了。OK,我们在大致有个了解之后,我们开始通过执行程序来看一下结果,加深我们对于注解的理解。

四、执行程序

鉴于我们这里这次一次写了N个方法测试,输出的报告巨长,我们这里就一个一个的测试,这样方便观察。

1、测试吞吐模式:measureThroughput

package com.levi;import org.openjdk.jmh.annotations.*;
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 java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Mode.Throughput, as stated in its Javadoc, measures the raw throughput by* continuously calling the benchmark method in a time-bound iteration, and* counting how many times we executed the method.** We are using the special annotation to select the units to measure in,* although you can use the default.** AI直译:Mode.Throughput,如其Javadoc所述,通过在时间限制的迭代中连续调用基准方法,* 并计算我们执行该方法的次数来衡量原始吞吐量。我们正在使用特殊注解来选择要测量的单位,尽管你可以使用默认值。** 我根据我的理解还是说几句人话吧,他的意思是我们之前不是在案例1中输出的是吞吐量的测试指标吗,这里的意思是你可以* 使用@BenchmarkMode这个注解,里面设置参数Mode.Throughput一样可以是通过吞吐量的指标的,或者说你不设置,默认* 本身就是吞吐量,我们第一个案例就是默认的。* 所以我们在第一个方法上看到新出现的两个注解* @BenchmarkMode:设置计算指标* @OutputTimeUnit:计算模式对应的单位*/@Benchmark@BenchmarkMode(Mode.Throughput)@OutputTimeUnit(TimeUnit.SECONDS)public void measureThroughput() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

运行结果为:
Benchmark :JMHSample_02_01_BenchmarkModes.measureThroughput
Mode :thrpt
Cnt : 因为我控制了1次,所以这里没东西
Score :9.160 这个分数在吞吐这里其实就是你执行的吞吐量,因为我写的@OutputTimeUnit(TimeUnit.SECONDS)单位是秒,所以意思就是一秒能执行9.16次。
Error :没输出
Units:ops/s
我们看到这个吞吐量其实和我们在第一个案例测试的差不多,其实他就是默认的。你不写就是他。

2、测试平均时间模式:measureAvgTime

package com.levi;import org.openjdk.jmh.annotations.*;
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 java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Mode.AverageTime measures the average execution time, and it does it* in the way similar to Mode.Throughput.* 在性能测试或基准测试的背景下,Mode.AverageTime(平均时间模式)测量了给定操作或代码片段的平均执行时间。* 该模式计算了每次调用被测试代码所花费的平均时间。它与Mode.Throughput(吞吐量模式)相似,两种模式都专注于性能测量,* 但它们在优先考虑的性能方面存在差异。以下是Mode.AverageTime和Mode.Throughput之间的简要比较:* 平均时间:该模式计算每个操作或调用的平均执行时间。它提供了关于单个操作平均执行时间的信息。* 吞吐量:另一方面,Mode.Throughput关注的是在给定时间内完成的操作速率。它衡量每单位时间内可以执行多少操作,通常是每秒。* 它提供了系统在高负载下处理大量操作的效率信息。* 虽然两种模式都提供了有关性能的有价值的信息,但它们服务于不同的目的,可能适用于不同类型的性能分析。* Mode.AverageTime适用于了解单个操作的平均延迟或执行时间,而Mode.Throughput更适用于在指定时间范围内最大化完成的操作数量。*** Some might say it is the reciprocal throughput, and it really is.* There are workloads where measuring times is more convenient though.* 有人说,这个指标是吞吐量的倒数,你也可以这么理解,不过有时候你测试的时候,统计时间维度是更加直观的。** 换言之,这个是统计你方法的执行平均时间的,所以看起来比吞吐量更加直观,毕竟耗时是我们普遍关心的第一指标*/@Benchmark@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureAvgTime() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

运行结果如下:
Benchmark :JMHSample_02_01_BenchmarkModes.measureAvgTime
Mode:avgt 平均统计模式
Cnt :同上
Score:108407.350
Error :没错误,不输出
Units:us/op 其实你能看出来,他是时间除以执行次数,所以就是吞吐量的倒数,吞吐量的意思是每秒能执行几次,这里就是执行一次需要几秒,不就是平均时间吗。只是我指定的时间单位是@OutputTimeUnit(TimeUnit.MICROSECONDS)微秒,所以这里自然也就是这个单位。
他主打的是一个平均耗时。

3、测试统计时间:measureSamples

package com.levi;import org.openjdk.jmh.annotations.*;
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 java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Mode.SampleTime samples the execution time. With this mode, we are* still running the method in a time-bound iteration, but instead of* measuring the total time, we measure the time spent in *some* of* the benchmark method calls.** Mode.SampleTime是用于对方法执行时间进行采样的一种模式。在这种模式下,我们仍然在一个有时间限制的迭代中运行方法,* 但不再测量总时间,而是测量一部分基准方法调用所花费的时间。使用Mode.SampleTime模式时,* 基准测试框架会定期中断方法的执行并记录经过的时间。通过只对部分调用进行采样,可以减少与连续时间测量相关的开销,* 同时仍能提供有关方法执行时间分布的有意义数据,而不仅仅关注整体持续时间。这种模式对于识别执行时间的变化非常有用,* 特别是如果方法的某些部分可能具有不同的性能特点或表现出间歇性行为。它使开发人员能够了解方法在不同条件下的性能表现,* 并帮助优化其性能。** This allows us to infer the distributions, percentiles, etc.* JMH also tries to auto-adjust sampling frequency: if the method* is long enough, you will end up capturing all the samples.* 这样可以让我们推断出分布情况、百分位数等。JMH 还会尝试自动调整采样频率:如果方法足够长,你最终会捕获到所有的样本** 这个解释的不明确,我们待会通过现象来看一下具体啥意思。*/@Benchmark@BenchmarkMode(Mode.SampleTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureSamples() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

在这里插入图片描述
他是以一种分布统计的方式输出的测试指标,单位还是平均时间耗时,等于说百分之99的测试跑一次是109707.264us的耗时,他内部给你做了一个测试,拆分出来测的,测出这么个结果来。
能看出来一个波动,和你实现的代码稳定性,而且他是抽样测试,不会都给你统计,比如我们设置的跑1轮,每轮一秒。可能这一秒跑了一万次,他不会像吞吐和平均那个样都算进去,他是一个抽样,可能抽了前面后面,没取中间。可能压根就是抽了前面。是一个分布统计。

4、测试只跑一次:measureSingleShot

package com.levi;import org.openjdk.jmh.annotations.*;
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 java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Mode.SingleShotTime measures the single method invocation time. As the Javadoc* suggests, we do only the single benchmark method invocation. The iteration* time is meaningless in this mode: as soon as benchmark method stops, the* iteration is over.** Mode.SingleShotTime测量的是单个方法调用的时间。正如Javadoc所建议的,我们只进行一次基准方法的调用。* 在这种模式下,迭代时间是没有意义的:一旦基准方法停止,迭代就结束了。** This mode is useful to do cold startup tests, when you specifically* do not want to call the benchmark method continuously.* 这种模式在进行冷启动测试时非常有用,当你不想连续调用基准方法时。** 说白了就是只测试一次,就跟你跑main函数一样的,没有预热,就是冷启动的测试。*/@Benchmark@BenchmarkMode(Mode.SingleShotTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureSingleShot() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

执行结果如下:
在这里插入图片描述
这就是测试冷启动的,没预热,就是直接跑,你也能看到单位是us/op。还是执行一次要多久。还是个平均值,只不过就是没预热直接开跑的。就跑一次。

5、测试多种模式组合:measureMultiple

package com.levi;import org.openjdk.jmh.annotations.*;
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 java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** We can also ask for multiple benchmark modes at once. All the tests* above can be replaced with just a single test like this:** 这个注解还能写数组,指定多种测试指标,一起生效*/@Benchmark@BenchmarkMode({Mode.Throughput, Mode.AverageTime, Mode.SampleTime, Mode.SingleShotTime})@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureMultiple() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

因为我们前面看了Mode是一个数组,所以可以传入多个模式。结果就是一起统计输出了。
在这里插入图片描述

6、测试全量模式:measureAll

package com.levi;import org.openjdk.jmh.annotations.*;
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 java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Or even...* 如果你懒得写很多模式,你还能直接用Mode.All来表示全部的模式*/@Benchmark@BenchmarkMode(Mode.All)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureAll() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

自然就是全部的统计都输出了:和上面一样。
在这里插入图片描述
你也可以看他的单位就知道他输出的计算方式了,次数除以时间,那就是平均时间的执行次数,就是吞吐。
时间除以次数,就是统计的某种模式下的平均时间。

五、总结

没啥总结的就是那两个注解,很详细了。

六、参考链接

1、JMH官方文档

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

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

相关文章

【算法练习】29:插入排序学习笔记

一、插入排序的算法思想 原理:将一个无序的数据序列逐步转化为有序序列。算法将待排序的数组分为两个部分已排序部分和未排序部分。 时间复杂度:插入排序的时间复杂度在最坏、平均和最好情况下的表现相同,均为 ,其中 n 是待排序数…

极狐GitLab对接OAuth2实现SSO

本文作者:极狐(GitLab) 高级解决方案架构师 武让 GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 企…

Python处理PDF:在PDF文档中插入页眉和页脚

在处理篇幅较长、结构复杂的PDF文档时,页眉和页脚的设计与插入就显得尤为重要。它们不仅扮演着美化文档、提升专业度的角色,更承担了导航指引、信息标注的重要功能。 页眉通常用于展示文档的标题或章节名称,有助于读者在翻阅过程中迅速定位所…

Java - 赋值运算符

在这个实战中,我们将学习赋值运算符的使用方法。首先,我们将介绍简单赋值运算符的基本概念和语法格式。然后,我们将通过案例演示来加深对赋值运算符的理解。接下来,我们将对比Java和Python这两种不同的编程语言,探讨它…

电能质量管理解决方案探讨 安科瑞 许敏

电能质量在线监测装置 本办法对发电企业(包括分布式电源)、电网企业、用电企业的电能质量管理均有明确要求,要求在发电企业并网点、电网企业非线性设施、用电企业公共连接点设置电能质量监测装置,这会促进市场对电能质量在线监测…

理解 编译和链接

目录 1. 翻译环境和运行环境 2. 翻译环境 2.1 预处理(预编译) 2.2 编译 2.2.1 词法分析: 2.2.2 语法分析 2.2.3 语义分析 2.3 汇编 2.4 链接 3. 运行环境 1. 翻译环境和运行环境 在ANSI C的任何一种实现中,存在两个不同…

Linux开发--进程

经典五问: 1.什么是程序?什么是进程? 从是否运行进行判断: gcc xxx -o pro,磁盘中生成的pro文件,就是程序 进程是程序一次运行活动 程序是静态的概念,进程是动态的概念。 2.如何查看系统中的进程: 在l…

二叉树练习day.6

654.最大二叉树 链接:. - 力扣(LeetCode) 题目描述: 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点,其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前…

MySQL——全文检索

不是所有的数据表都支持全文检索 MySQL支持多种底层数据库引擎,但是并非所有的引擎支持全文检索 ,目前最常用引擎是是MyISAM和InnoDB;前者支持全文检索,后者不支持。 booolean模式操作符 实验: 表productnotes &…

线程池参数如何设置

线程池参数设置 hello丫,各位小伙伴们,好久不见了! 下面,我们先来复习一下线程池的参数 1、线程池参数有哪些? corePoolSize(核心线程数):线程池中的常驻核心线程数。即使这些线程…

Java与Kotlin语言的特色之处

一、Java特色之处: 1.多异常捕获 一个try块可能捕获到多个异常,可以使用多个catch块分别处理每个异常,也可以使用一个catch块处理多个异常(多个异常使用管道符|分隔)。 多个catch块代码: try{ }catch(IOExc…

FMEA与各设计工具之间有哪些联系——SunFMEA软件

在设计领域,FMEA与其他设计工具之间存在着紧密的关系,这些工具共同支持设计师在产品开发的各个阶段做出明智的决策,今天SunFMEA软件和大家一起了解FMEA与各设计工具之间的联系。 首先,FMEA与CAD(计算机辅助设计&#…

搭建PyTorch神经网络进行气温预测(手写+调包两种方法)(保证学会!)+找到神经网络的最优情况

代码上有注释!!!!!! 本篇主要包括三大部分: 第一部分:导入数据集导入第三方库数据集简单介绍与可视化数据集简单预处理 第二部分:手写神经网络代码实现气温预测&#…

论文学习D2UNet:用于地震图像超分辨率重建的双解码器U-Net

标题::Dual Decoder U-Net for Seismic Image Super-Resolution Reconstruction ——D2UNet:用于地震图像超分辨率重建的双解码器U-Net 期刊:IEEE Transactions on Geoscience and Remote Sensing 摘要:从U-Net派生…

linux中rpm包与deb包的区别及使用

文章目录 1. rpm与deb的区别2. deb软件包的格式和使用2.1 deb软件包命令遵行如下约定2.2 dpkg命令2.3 apt-命令 3. Unix和Linux的区别Reference 1. rpm与deb的区别 有的系统只支持使用rpm包安装,有的只支持deb包安装,混乱安装会导致系统问题。 关于rpm和…

手拉手安装启动Kafka2.13

启动Kafka本地环境需Java 8以上 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 Kafka启动…

【ubuntu20.04】安装GeographicLib

下载地址 GeographicLib: Installing GeographicLib 我们是ubuntu20.04 ,所以下载第一个 GeographicLib-2.3.tar.gz 接着跟着官方步骤安装,会出错!!!!马的 官方错误示例:tar xfpz Geographi…

无重复字符串的最长子串

题目描述:给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度。 第一次提交记录 class Solution:def lengthOfLongestSubstring(self, s: str) -> int:if not s:return 0lookup set()left res 0for right in range(len(s)):while s…

基于Springboot的箱包存储系统(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的箱包存储系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&…

一辆新能源汽车需要多少颗传感器?

随着科技的发展和环保意识的日益提高,新能源汽车(包括纯电动汽车、混合动力汽车等)在全球范围内越来越受到欢迎。这些汽车不仅减少了碳排放,还推动了汽车产业的创新。然而,这些高科技汽车的背后,隐藏着许多…