我写了两个基准来证明JIT可能是编写精细基准测试的问题(请跳过我在这里不使用@State):
@Fork(value = 1)
@Warmup(iterations = 2, time = 10)
@Measurement(iterations = 3, time = 2)
@BenchmarkMode(Mode.AverageTime)
public class DeadCodeTraps {
@Benchmark
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public static void summaryStatistics_standardDeviationForFourNumbers() {
final SummaryStatistics summaryStatistics = new SummaryStatistics();
summaryStatistics.addValue(10.0);
summaryStatistics.addValue(20.0);
summaryStatistics.addValue(30.0);
summaryStatistics.addValue(40.0);
summaryStatistics.getStandardDeviation();
}
@Benchmark
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public static void summaryStatistics_standardDeviationForTenNumbers() {
final SummaryStatistics summaryStatistics = new SummaryStatistics();
summaryStatistics.addValue(10.0);
summaryStatistics.addValue(20.0);
summaryStatistics.addValue(30.0);
summaryStatistics.addValue(40.0);
summaryStatistics.addValue(50.0);
summaryStatistics.addValue(60.0);
summaryStatistics.addValue(70.0);
summaryStatistics.addValue(80.0);
summaryStatistics.addValue(90.0);
summaryStatistics.addValue(100.0);
summaryStatistics.getStandardDeviation();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为JIT将消除死代码,因此两个方法将同时执行.但最后,我有:
summaryStatistics_standardDeviationForFourNumbers 0.158±0.046 DeadCodeTraps.summaryStatistics_standardDeviationForTenNumbers 0.359±0.294
为什么JIT不优化它?结果summaryStatistics.getStandardDeviation();不会在方法之外的任何地方使用,也不会被它返回.
(我使用的是OpenJDK build 10.0.2 + 13-Ubuntu-1ubuntu0.18.04.4)
我创建了一个构建规范对象的构建器类。它用于为JpaSpecificationExecutor. 使用了构建器,因为我有许多参数可以为空/空(来自用户用于过滤),Specifications没有它我就不能使用:
public class SpecificationBuilder<T> {
private Specifications<T> specification;
public SpecificationBuilder() {
}
public SpecificationBuilder(final Specification<T> spec) {
specification = Specifications.where(spec);
}
public SpecificationBuilder<T> appendOr(final Specification<T> spec) {
specification = Specifications.where(spec).or(specification);
return this;
}
public SpecificationBuilder<T> appendAnd(final Specification<T> spec) {
specification = Specifications.where(spec).and(specification);
return this;
}
public Specification<T> build() {
return Specifications.where(specification);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我不知道如何单独测试它。当然,我可以自动装配真实的存储库(在内存数据库上),但我不想涉及任何其他类,只测试逻辑,如何创建 OR 和 AND 子句。
不幸的是,在 spring API 中我找不到任何有帮助的方法
我正在学习使用 Flux/Mono 进行错误处理并遇到以下问题:
Flux.just("AAA", "BBB", "AAA", "CCC")
.map(s -> {
if (s.equals("AAA")) {
throw new IllegalArgumentException();
}
return s;
})
.map(s -> s + "-LOL")
.onErrorMap(IllegalArgumentException.class, cause -> new IllegalStateException())
.onErrorContinue(IllegalArgumentException.class, (e, a) -> System.out.println("Found IllegalArgumentException" + e))
.onErrorContinue(IllegalStateException.class, (e, a) -> System.out.println("Found IllegalStateException" + e))
.collectList()
.block();
Run Code Online (Sandbox Code Playgroud)
我想做的是将一个错误异常映射到另一个异常,然后我想以特定的方式处理它。
在我的代码中,我看到onErrorContinue仅针对 触发IllegalArgumentException,但我不明白为什么 - 我刚刚将错误映射到IllegalStateException
System.out.println(
DateTimeFormatter.ofPattern("YYYY-ww").withZone(ZoneOffset.UTC).format(Instant.parse("2022-05-10T00:00:00.00Z"))
);
System.out.println(
DateTimeFormatter.ofPattern("YYYY-ww").withZone(ZoneOffset.UTC).format(Instant.parse("2022-05-17T00:00:00.00Z"))
);
Run Code Online (Sandbox Code Playgroud)
为什么此模式YYYY-ww在 Ubuntu 和 Mac 上的解析不同:
Ubuntu:(默认区域设置 en_US,我的电脑)
2022-20
2022-21
Run Code Online (Sandbox Code Playgroud)
Mac:(默认区域设置 en_GB)
2022-19
2022-20
Run Code Online (Sandbox Code Playgroud)
编辑
System.out.println(
DateTimeFormatter.ofPattern("YYYY-ww").withLocale(Locale.UK).withZone(ZoneOffset.UTC).format(Instant.parse("2022-05-10T00:00:00.00Z"))
);
System.out.println(
DateTimeFormatter.ofPattern("YYYY-ww").withLocale(Locale.UK).withZone(ZoneOffset.UTC).format(Instant.parse("2022-05-17T00:00:00.00Z"))
);
Run Code Online (Sandbox Code Playgroud)
返回:
2022-19
2022-20
Run Code Online (Sandbox Code Playgroud)
不过,问题是为什么模式ww是特定于区域设置的?我在https://docs.oracle.com/javase/8/docs/api/java/time/temporal/WeekFields.html
或https://docs.oracle.com/javase/8的文档中没有看到这一点/docs/api/java/time/format/DateTimeFormatter.html
是否可以在@Query批注内调用参数的方法?
例:
@Query("SELECT user " +
"FROM User user " +
"WHERE (?1.getFilter() = '*' OR user.name = ?1)");
List<User> getUsers(UserNameFilter userNameFilter);
Run Code Online (Sandbox Code Playgroud)
我知道我可以做这样的事情:
@Query("SELECT user " +
"FROM User user " +
"WHERE (?1 = '*' OR user.name = ?1)");
List<User> getUsers(String userName);
Run Code Online (Sandbox Code Playgroud)
但是,当过滤器数量增加时,这意味着我需要更改许多参数。
为什么主线程杀死了我的 rxJava 线程?
public static void main(final String[] args) throws Exception {
Observable.just(10)
.subscribeOn(Schedulers.newThread())
.subscribe(i -> print(i));
Thread.sleep(100);
}
private static void print(final int i) {
try {
Thread.sleep(5000);
} catch(final InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
}
Run Code Online (Sandbox Code Playgroud)
print方法阻塞线程 5000 毫秒,我认为 JVM 正在等待应用程序下的所有线程被终止。在这种情况下,执行程序后关闭,我在控制台中看Thread.sleep(100)不到。10
注意:如果我将使用自定义执行器,那么Executors.newFixedThreadPool(1);它将等到关闭,但使用Schedulers.newThread()它则不会。
从HashMap文档中我们可以读到:
请注意,使用具有相同 hashCode() 的多个键肯定会降低任何哈希表的性能。为了减轻影响,当键是 Comparable 时,此类可以使用键之间的比较顺序来帮助打破平局。
我知道如果密钥实现Comparable接口,在许多哈希冲突时,桶可以从 转变List为TreeSet。
是否可以设置容量,或检查何时转换?