文章目录
Java
Spring Boot 即将迎来3.0
Spring Boot 即将迎来3.0
Spring Boot自2018年发布2.x以来已经维护了4年,并且发布了95个不同的版本。
Spring Boot 3.0将要在2022年11月推出。
修改主要基于Spring Framework 6.0和Java 17,也将会是Spring Boot第一个使用Jakarta EE 9 API替换EE 8的版本.
- Springboot3.0将会删除所有不推荐使用的代码,所以建议使用
-Werror
编译选项检查项目中的deprecation warning
。 - 开发者需要对Springboot2.4中对于
application.properties
和application.yaml
的强调(如果你的配置项中有profile-specific properties或者profile activation properties的话)多加注意,因为SpringBoot3.0中spring.config.use-legacy-processing
选项将会被弃用。 - Spring Boot3.0推荐使用
Spring MVC’s PathPatternParser
。 - 因为兼容性问题,检查使用的第三方项目是否有Jakarta EE 9兼容版本
- 检查第三方项目是否更新Spring兼容版本
- 尝试Spring Boot Milestones(尽管我们不建议将其用于生产,但您今天可以尝试Spring Boot 3.0里程碑,看看迁移项目有多困难。)
- 考虑商业支持
IntelliJ UI征集中
Intellij官网正在征集新的UI方案
OPENJDK发起了旨在解决Java启动速度慢等问题的Leyden项目
该项目的目的是为了解决Java的启动时间慢,性能达到峰值的时间慢,占用空间大的问题。
Leyden引入了static run-time images
,它具有如下特点:
static image
是一个独立程序,仅仅依靠JDK运行image
运行时不能够在image
外加载类或者动态创建类
image
对于Java原有的动态能力施加了很多限制,尤其是在运行时反射和类加载机制上。因此image
运行限制被称为“closed-world”。
Mark Reinhold提到,比起closed-world
,将会渐进的探索对原有代码限制更小的方法,以适用于更多的代码。
改解决方案将会依赖于原有JDK组件,包括HotSpot JVM、C2编译器、CDS、jlink等进行。
使用SonarLint检查代码
Sonaralint是一个免费的开源IDE扩展,它可以在您编写代码时直接在IDE中识别并捕获bug和漏洞。立即从您喜爱的IDE市场安装。
生产环境中使用Datafaker获取可用数据
Datafaker是一个用Java编写的库,可以由流行的JVM语言(如Java、Kotlin或Groovy)使用。它一开始是作为不再维护的Javafaker的分支,但自其诞生以来,它已经看到了许多改进。Datafaker由一个核心组成,用于处理数据的生成,此外,它还拥有各种特定于域的数据提供程序。这些提供者可能非常有用,例如,可以生成真实的地址、姓名、电话号码、信用卡和其他数据,或者有时更为简单,例如在生成电视节目《老友记》或IT人群的角色时。无论您使用何种用例,Datafaker都很有可能向您的应用程序提供数据。而且,当有可用的数据提供者时,Datafaker提供了可插入系统的选项来创建您自己的提供者!
使用Cleaners替换Finalizer
这应该是一个很久的Proposal了,根据JEP 421所指出的,Finalizer有critical,fundamental flaws:
- 不确定的调用时间
- 没有限制的行为,也就是说finalizer反而可能延长了对象生命周期
- finalizer是始终启用的,无法被取消
- 无法控制执行线程和顺序
建议的替换方案如下:
- 使用Try-with-resources(从Java 7开始)
- 使用Cleaners(从Java 9开始)
当资源生命周期过长时,就要借助于Cleaners了,cleaner的特点如下:
- cleaner不能访问对象,没有对象生命周期的延长
- 可以自由控制cleaner行为,cleaner不能访问未初始化的对象
- 没有相互干扰,子类和父类之间,线程之间不能够相互干扰cleaning操作
来自Java官网的这篇最新文章提供了一些Cleaner的用法。
Java Newscast 25
来自Youtube的Java的新闻播报
首先是Vitual Threads,VirtualThreads使用时不需要池化,不需要缓存大的对象,不要在同步中IO,线程需要和Native Code绑定,Loom增加了Carrier thread
用来在IO线程之间切换
更多内容参见JEP 425
然后是Lilliput,该项目旨在将object header从128bit降至64bit
最后是JDK 19将要推出的Record Patterns
几篇博客
Java data access technology survey results - 2022 vs. 2019
比较了几种数据库持久化技术,很明显ORM中JPA比较受欢迎。
Is it worth to learn Java-Springboot even today?
Cloud Functions Using the New Java Runtime
额外:Java17
- 文本块,增加了一点parser解析json
- switch expression,parser解析->,yield
- record
- Sealed Classes(通过sealed和permit关键字限制继承权限)
- Pattern matching for instanceof
- NullPointerExceptions
- 压缩数字格式支持
- Day Period Support Added
- stringStream新增了tolist方法
C++
为optional<T>
赋值
一篇技术文章探讨了optional<T>
的赋值
它看起来是这样的…
template <typename T>
class Optional {
union {
T value_;
};
bool has_value_;
template <typename T>
auto Optional<T>::operator=(Optional<T> const& rhs) -> Optional<T>& {
if (this != &rhs) {
if (has_value_) {
value_.~T();
has_value_ = false;
}
if (rhs.has_value_) {
::new (&value_) T(rhs.value_);
has_value_ = true;
}
}
return *this;
else if (has_value_ and not rhs.has_value_) {
value_.~T();
has_value_ = false;
}
else if (not has_value_ and rhs.has_value_) {
::new (&value_) T(rhs.value_);
has_value_ = true;
}
else {
// nothing
}
return *this;
}
};
C++03中,union可以含有不具有构造析构函数和赋值运算符的静态类成员,C++11中限制被移除。C++17中std::variant
是union的类型安全替代。此处使用union是为了满足constexpr的需求。除此之外,可以使用construct_at和destroy_at替代new和delete(C++程序员认为这是所谓的entirely-natural placement,但是好像只是能够满足constant expression而已)
总之这篇文章讲述了拷贝构造和拷贝赋值在optional中的n个问题(这怎么受得了的)。
有时,这确实是一个编译器错误
My journey in finding and fixing a bug in a C++ toolchain.
这篇文章分析了VSCode编辑器在高亮代码时出现的一个bug,原因是GCC的dlltool在windows x64上链接dll时没有保存xmml这个immutable寄存器。
作者用gdb的watch register找到了这个问题并且修复了,这个确实挺困难的。
关于C++依赖关系管理
这篇文章介绍了C++的依赖管理工具
Java流行的版本管理工具由Maven和Gradle,Python有pip,nodejs使用npm和yarn,php使用composer,而Rust使用cargo。那么C++呢?
因为C++没有标准库或者主要的包管理器,所以依赖管理要么是微不足道,要么依赖于平台特定工具类似APT。C++大量的开源社区和库已经形成了支离破碎的生态,维护跨平台库时因为架构很多将产生大量的ABI兼容问题。
Conan采用分散系统来维护多种二进制包文件,
cargo则从crates.io中检索依赖项,这是社区维护的中央包注册中心。
最常用的工具是Conan和vcpkg。vcpkg由微软开源,vs和vsc集成。让人诟病的是vcpkg检索方式比较困难。
Branch/cmove和编译器优化
停下愚蠢的C++20特性,这篇文章讲了分支和cmove指令分别在什么时候生成。
如果预测率高于75%,那么branch比cmove更快
常用的技巧:使用__builtin_expect_with_probability指示编译器使用branch替换cmove(更有用的是使用godbolt看看编译器做了什么)
#define LIKELY(x) (__builtin_expect(!!(x), 1))
#define VERY_LIKELY(x) (__builtin_expect_with_probability(!!(x), 1, 0.999))
int foo1(int a, int b, int c)
{
if (a == b)
a &= c;
return a;
}
int foo2(int a, int b, int c)
{
if (LIKELY(a == b))
a &= c;
return a;
}
int foo3(int a, int b, int c)
{
if (VERY_LIKELY(a == b))
a &= c;
return a;
}
汇编结果如下:
foo1:
and edx, edi
mov eax, edi
cmp edi, esi
cmove eax, edx
ret
foo2:
and edx, edi
mov eax, edi
cmp edi, esi
cmove eax, edx
ret
foo3:
mov eax, edi
cmp edi, esi
jne .L7
and eax, edx
.L7:
ret
llvm优化趟在修改分支代码使用select IR指令(根据状况改变值,并非IR级别分支)上十分激进,select经常使用cmove指令,但是cmove往往会比分支更慢,所以后端往往会改为分支指令。
Clang使用 __builtin_unpredictable告诉编译器分支无法预测(因此应当使用cmove),但是只在IR生成前有效,所以对于select指令无效。
编译器会在straight-line代码中插入分支。
五月份标准委员会的动态
看看委员会干了啥
N4912 2022-11 Kona hybrid meeting information
N4913 PL22.16/WG21 agenda: 25 July 2022, Virtual Meeting
一个会议邀请
P0543R1 Saturation arithmetic
饱和算法,模2^n的算法
P0792R9 function_ref: a non-owning reference to a Callable
对callable对象的非所有权引用
ADL
argument depent lookup
C++11
如果在函数的命名空间中定义了一个或多个参数类型,则不必限定函数的命名空间。
You don’t have to qualify the namespace for functions if one or more argument types are defined in the namespace of the function.
额外:C++20 约束和概念
概念(concept):
类模板,函数模板,以及非模板函数(通常是类模板的成员),可以关联到约束(constraint),它指定了对模板实参的一些要求,这些要求可以被用于选择最恰当的函数重载和模板特化,这种要求的具名集合称为concept,在编译时求值,并在自己被用作约束时成为模板接口的一部分
约束:
约束是逻辑操作和操作数的序列,它了指定对模板实参的要求。它们可以在 requires 表达式中出现,也可以直接作为概念的主体。
有三种类型的约束:
- 合取(conjunction)
- 析取(disjunction)
- 不可分割约束(atomic constraint)
requires 子句:
关键词 requires 用来引入 requires 子句,它指定对各模板实参,或对函数声明的约束。