Weekly 5.28

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.propertiesapplication.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的特点如下:

扫描二维码关注公众号,回复: 15949486 查看本文章
  • 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 表达式中出现,也可以直接作为概念的主体。
有三种类型的约束:

  1. 合取(conjunction)
  2. 析取(disjunction)
  3. 不可分割约束(atomic constraint)
    requires 子句:
    关键词 requires 用来引入 requires 子句,它指定对各模板实参,或对函数声明的约束。

猜你喜欢

转载自blog.csdn.net/treblez/article/details/125013453