面试题答案
一键面试1. 引入JMH依赖
在pom.xml
中添加JMH依赖:
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.35</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.35</version>
<scope>provided</scope>
</dependency>
2. 创建包含复杂业务逻辑的Java类
假设这个类为ComplexBusinessLogic
:
public class ComplexBusinessLogic {
public void coreMethod() {
// 复杂业务逻辑代码
for (int i = 0; i < 1000; i++) {
// 模拟复杂计算
double result = Math.sqrt(i * i + 1);
}
}
}
3. 使用JMH设置基准测试
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;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class ComplexBusinessLogicBenchmark {
private ComplexBusinessLogic businessLogic;
@Setup(Level.Trial)
public void setup() {
businessLogic = new ComplexBusinessLogic();
}
@Benchmark
public void measureCoreMethod() {
businessLogic.coreMethod();
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(ComplexBusinessLogicBenchmark.class.getSimpleName())
.warmupIterations(5)
.measurementIterations(10)
.threads(4)
.forks(1)
.build();
new Runner(opt).run();
}
}
4. 参数调优及影响
- 预热(Warmup Iterations):
- 设置:通过
.warmupIterations(5)
设置预热迭代次数为5次。 - 影响:JVM在执行代码时会进行即时编译(JIT),预热阶段让JVM有足够时间进行JIT优化,避免初始执行时由于编译等开销导致的性能波动,使测试结果更稳定、准确。如果预热次数太少,JVM可能未充分优化,测试结果偏高;预热次数过多,则会增加测试时间。
- 设置:通过
- 迭代次数(Measurement Iterations):
- 设置:通过
.measurementIterations(10)
设置测量迭代次数为10次。 - 影响:迭代次数决定了实际收集性能数据的次数。次数过少,数据可能不具有代表性,容易受到偶然因素影响;次数过多,会延长测试时间。一般根据业务场景和稳定性要求调整,确保结果的可靠性。
- 设置:通过
- 线程数(Threads):
- 设置:通过
.threads(4)
设置线程数为4个。 - 影响:多线程测试能模拟并发场景。增加线程数可以测试方法在高并发下的性能表现,观察是否存在线程安全问题、资源竞争等。但线程数过多可能导致线程上下文切换开销增大,掩盖方法本身性能问题;线程数过少则无法充分利用系统资源,不能准确反映高并发场景下的性能。
- 设置:通过