从现在开始对你认知过时的八股文迭代更新吧

背景

随着时代的变迁,科技的进步,技术的不断更新迭代,一些曾经被认为是“标准答案”的观点和认知,已经不再适应当前的需求,甚至被视为过时的做法。时间在流逝,技术也在不断推陈革新,先有区块链成为虚拟货币的导火索,又有AR、VR等软硬件技术推波助澜元宇宙,使虚拟和现实的连接有望在不久的将来成为可能,近几年又爆火的大模型,如同雨后春笋在各个领域都在积极探索落地。

Java语言诞生至今已有近30年的时间,这段历史长河中java也在不断自我完善和融入新的技术,在新版JDK中,许多新的特性、工具和方法被引入,使得Java编程变得更加简洁、高效和强大。作为有着匠心和追求极致的开发者们也需要对新技术的原理有了解,以应对新需求的挑战和保持竞争力,所以,coder们是时候对你认知的技术进行一次清理和更新了。

版本RoadMap

官方地址:https://www.oracle.com/java/technologies/java-se-support-roadmap.html

从上图可以很清晰地看出,JDK7,JDK8,JDK11,JDK17,JDK21是长期维护的版本。从目前来看,JDK8到2023年已经有将近10年的历史了,JDK8的相关技术内容已经很成熟了,但是JAVA作为包容性很强的语言,也在不断吸收新的语言优势和适应新的技术,所以JDK在不断地迭代,JDK有很多的新特性,而且能够对开发及系统性能有很大帮助。现在很多公司在建新系统的时候,也在考虑新的JDK。再加上重要的一点是新的spring boot3及对应的spring cloud 2022.X及以上版本,最低支持的JDK也需要JDK17了。所以要想跟上技术迭代,还需我们自己对于JDK进行了解,然后根据自己的实际选择相应的版本。

一、Lambda表达式

它是 Java 8 发布的最为重要的新特性之一,跟上了目前语言发展的趋势,是继泛型(Generics)和注解(Annotation)以来最大的突破。Lambda 表达式简单来讲是一个匿名函数,Java 8 允许将函数作为参数传递到方法之中。

采用 Lambda 表达式可以大幅简化代码的编写,开发人员在熟练之后,可以很简单的书写相关的功能,并且提升了相应的效率,这就是函数式编程。

Java底层将Lambda编译成一个私有方法,并通过invokedynamic指令调用,具体细节不展开了。

二、interface

Interface 的初始设计目的是面向抽象,而不是实现方法细节。但这也带来了一个不足之处,即当 Interface 进行修改时,实现它的类也必须相应地进行修改。为了解决 Interface 该问题提升便捷性,JDK8中支持default 或 static 关键词修饰 interface 的方法,这样就可以给方法提供一个默认实现,而实现类无需重写此方法。

 Interface 中可以有多个方法被这两种关键词所修饰。二者的区别在于,default 方法是普通实例方法,可以使用 this 关键词调用,可以被子类继承和重写;而 static 方法与一般类的静态方法类似,无法被子类继承,只能通过 Interface 调用。但让开发者头疼的是,接口的方法都是公开的,暴露风险不可避免。

public interface InterfaceTest{    static void staticInterfaceTest{() {        System.out.println("InterfaceTest 的 静态 staticInterfaceTest");    }     static void staticInterfaceTestA() {        System.out.println("InterfaceTest 的 静态 staticInterfaceTestA");     }     default void defaultInterfaceTest() {        System.out.println("InterfaceTest 的 默认 defaultInterfaceTest");     }     default void defaultInterfaceTestA() {        System.out.println("InterfaceTest 的 默认 defaultInterfaceTestA");    }}

JDK9允许了开发者在接口中定义私有方法,从而提取和封装默认方法中的公共代码,减少代码的冗余。

public interface InterfaceTest{        private void interfaceTest() { }    }
三、快速创建不可变集合

JDK9 增加了List.of()、Set.of()、Map.of() 和 Map.ofEntries()等工厂方法来创建不可变集合。使用 of() 创建的集合为不可变集合,不能进行添加、删除、替换、 排序等操作,不然会报 java.lang.UnsupportedOperationException 异常。关于List.of返回空数组的问题,在不同的序列化器下会返回非预期的结果(带有tag字段的对象,这个和其内部实现有关)

四、String 存储结构优化

Java 8及以前版本,String 一直是用 char[] 存储。在 Java 9 之后,String 的实现改用 byte[] 数组存储字符串,这样做的主要原因是节省内存空间。对于大量的拉丁文系列字符(如英文、数字、常见的标点符号等),使用byte数组存储会节省一半的空间。

同时,String类的内部还引入了一个名为coder的byte类型的字段。这个字段是用来标识存储在byte数组中的数据是何种字符编码的。在新的String类的实现中,存在两种可能的字符编码:ISO-8859-1(一个字符占用一个字节)和UTF-16(一个字符占用两个字节)。对于ISO-8859-1编码的字符串,coder的值为0,而对于UTF-16编码的字符串,coder的值为1。这样,通过检查coder字段的值,就可以知道存储在byte数组中的数据应该使用什么样的编码方式进行处理,从而避免了因为字符编码不同而导致的处理错误。

五、G1成为默认的垃圾回收器

在 Java 8 中,默认使用的垃圾回收器为 Parallel Scavenge(新生代)+Parallel Old(老年代)。但到了 Java 9,CMS 垃圾回收器被弃用,取而代之的是 G1(Garbage-First Garbage Collector),成为新的默认垃圾回收器。实际上,G1 垃圾回收器在 Java 7 中就已经被引入,而经过两个版本的表现表现优异后,它于 Java 9 才被正式上位。

在G1中,没有严格的年轻代和老年代的划分,而是分为多个大小相同的独立区域,每个区域在不同的时间点可能会扮演不同的角色。

G1 是以一种低延时的垃圾回收器来设计的,旨在避免进行 Full GC,但是 Java9 的 G1 的 FullGC 依然是使用单线程去完成标记清除算法,这可能会导致垃圾回收期内,无法回收内存的时候触发 Full GC。为了最大限度地减少 Full GC 造成的应用停顿的影响,从 Java10 开始,G1 的 FullGC 改为并行的标记清除算法,同时会使用与年轻代回收和混合回收相同的并行工作线程数量,从而减少了 Full GC 的发生,以带来更好的性能提升、更大的吞吐量。

后续的版本G1也是不断被迭代,而且也是官方默认的垃圾回收器,但ZGC已可以在新版本中开启并使用,至于G1和ZGC实现原理本文不再展开细述。

六、synchronized偏向锁被废弃

提到偏向锁,不得不提Synchronized的锁升级过程,1.7java进行了优化,根据不同场景使用不同的锁状态,无锁、偏向锁、轻量级锁、重量级锁。

偏向锁基本思想是同一个线程的反复访问无需加锁,主要目标是消除数据在没有竞争的情况下的同步操作,提高运行时性能。

但在Java 15中 ,偏向锁被取消了 ,根本原因是偏向锁状态在现代的应用场景下已经不再有明显的性能优势,反而会增加虚拟机的复杂度和维护成本。尤其是偏向锁的撤销代码非常昂贵,需要进入全局安全点(即safepoint,虚拟机将所有的线程暂停执行),会带来比较长的停顿时间。

七、虚拟线程

虚拟线程(Virtual Thread-)是 JDK 而不是 OS 实现的轻量级线程,众所周知Java世界里的普通线程和OS系统的平台线程是一一对应的关系,所以导致普通线程耗资源且受平台资源限制,在多线程情况下上下文切换也是极重的操作,所以一般都通过池化、升配扩容大法解决。

虚拟线程是JVM管理的,多个虚拟线程可共享同一个平台线程,虚拟线程的数量可以远大于平台线程的数量。虚拟线程避免了上下文切换的额外耗费,兼顾了多线程的优点,简化了高并发程序的复杂,可以有效减少编写、维护和观察高吞吐量并发应用程序的工作量。

虚拟线程在其他多线程语言中已经被证实是十分有用的,比如 Go 中的 Goroutine、Erlang 中的进程。该技术点也是点到为止,后续有机会细述。

总结

​新技术的推出是为了更好地利用现代硬件技术的优势和满足当下以及未来的用户需求,所以作为追求卓越的我们应该积极拥抱变化,而不是固步自封,这样难免会被市场淘汰。当然我们亦不可对新技术趋之若鹜,要理性客观地对待新技术,需要结合自己的需求场景并对其内部实现有一定的了解,确保线上的稳定性,防止给自己挖坑。比如某些现代语言的高级语法糖对开发者是友好了,但是底层​实现的代价是昂贵的。

本文只是作为抛砖引玉,有些技术点是可以单独成文的,如果后续有机会再介绍。

路漫漫其修远兮,吾将上下而求索。给努力的自己加油。

微信公众号首发,欢迎关注,帮忙一键三连,感谢支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值