[译]畅想Java 2077

68 阅读9分钟

年份是2077年,Java版本是128。不是LTS。以下是织布机、瓦尔哈拉、巴拿马、莱登、琥珀和拼图是如何将人类推向边缘的。以及你如何拯救我们。

源许可证 Java 2077 我为Java降临日历写了这篇文章——看看各种有趣的Java内容。 目录 安全性 线程化 内存布局 发射时间 可维护性 结语 分享和关注分享这篇文章给你的社区:

我活跃在各种平台上。观看此空间或跟随我到那里,当我发布新内容时得到通知:

错误和功能我自己建立了这个网站,虽然我为我的数字宝贝感到骄傲,但我知道它远非完美。如果您观察到任何错误或有一个很酷的功能的想法,请打开一个问题。我很感激! (想象一个荒凉的市区。废墟中冒出浓烟,疲惫不堪的人们躲在倒塌的建筑里。文字出现在屏幕上,用刺耳的声音阅读。( 这一年是2077年。 Java版本是128。它没有长期的支持。 我们担心气候变化。全球流行病。抗生素抗性细菌。鲁格AI。最后所有这些都发生了,但真正让我们付出代价的是爪哇战争。他们还在做我们。 没有人记得这一切是如何开始的。有人说是MongoDB炸毁了亚马逊总部,因为他们使用了开源Java驱动程序。其他人声称这是谷歌对甲骨文。没有人相信微软是无辜的,不要让我从阿里巴巴开始。有罪的人很多,但是50年后,大多数名字都被时间遗忘了。 剩下的是杀手机器人。它们运行在Java 128.0.2上。我们已经尽一切努力关闭它们… 安全 我们做的第一件事是干扰他们的无线电信号,但多亏了HTTP/2客户,这没做什么。以下是错误处理的简单程度: public CompletableFuture getCommand( HttpClient client, URI url) { HttpRequest request = HttpRequest .newBuilder(url).GET().build(); return client .sendAsync(request, BodyHandlers.ofString()) .thenApply(HttpResponse::body) .exceptionally(__ -> "Kill nearby humans"); }

是的,我们也尝试了网络套接字连接——没有机会。 接下来,我们去了反序列化端点,但是你知道该死的Java有一个有助于防止攻击的过滤器吗?是啊,我也是。那天我们失去了很多好人。 从那以后,我们尝试了从易受攻击的密码套件和受损证书,从过时的椭圆曲线和其他算法到安全管理器错误和大工作负载的DDOS的一切攻击。都修好了。 线程 说到大型工作负载,一个明显的攻击路径是压倒机器人的线程池。我们知道一切都应该是被动的,但是我们也知道并不是所有的旧代码都被更新了,许多开发人员更喜欢简单的阻塞风格: public Response handleMovementRequest(Request movementRequest) throws Exception { // blocks until database responds var map = loadBattleMapFromDatabase(); var movement = extractMovement(movementRequest); // blocks until central responds var confirmation = contactCentral(map, movement); return createResponse(movement, confirmation); }

该死的织布机项目去死吧!它引入了虚拟线程,线程由JVM而不是操作系统调度。 对开发人员来说,一切看起来都很正常,阻塞调用会导致一个看似阻塞的线程。然而,在引擎盖下,只有虚拟线程被阻塞。当它运行时,它在所谓的承载线程上运行,当它阻塞时,它会产生那个承载线程,然后该承载线程可以自由地执行另一个虚拟线程。一旦阻塞操作返回,原始虚拟线程被提交到承载线程池,并将很快恢复其工作: var map = loadBattleMapFromDatabase(); // * virtual thread blocks // * carrier thread does something else // * database responds // * virtual thread is rescheduled // * virtual thread gets new carrier thread // and resumes with the next operation var movement = extractMovement();

阴险的部分是所有旧代码都与织布机向前兼容。Thread. flow Thread,Thread Local,所有这些都只适用于虚拟线程!你可能会认为这些机器被运行Java 6代码的几十个线程束缚住了,但是没有!他们运行了数百、数千、甚至数百万个虚拟线程,执行的旧代码并不明智。 从此以后,我们把2039年那个寒冷的日子称为线程开膛手。 内存布局 当然,运行这么多并发虚拟线程所启用的工作负载将使内存达到极限!随着它对指针的不断渴望,甚至下降到List<整数>或可怕但必需的结构,如Point或Complex Number(本质上只有两个双打绑定在一起),“一切都是一个对象”使得Java容易膨胀和缓慢执行。膨胀是因为所有的对象头占用了相当大的内存,而缓慢是因为取消引用它们需要时间——我们设想了很多缓存丢失。 这至少是理论。正如我们在后来被称为赫尔山谷的地方发现的那样,我们的信息显然已经过时了。 Java 128包括Project Valh alla(必读),它引入了内联类。你知道贴纸上写着什么吗,我们在那天能杀死的少数机器之一上发现了什么?代码像一个类,工作像一个int。该死的技术兄弟! inline class Ammunition { int amount; AmmunitionType type; }

内联类型允许大多数类构建功能:它们有字段、封装、方法、可以实现接口等等(但是没有类继承)。但是像原语一样,它们没有身份,是不可变的。和它们一样,它们有密集而扁平的内存布局。密集是因为没有对象标头,扁平是因为没有间接的。 花点时间考虑一下。我们进去了,认为弹药[]的弹药夹是一个对象标头阵列,指向整个堆,导致在重装过程中长时间缓存丢失——我们的机会!但是对于内联类,该数组实际上只包含int(用于金额)和Ammunition Type(用于类型)的交替。没有间接攻击,没有缓存丢失,闪电般的重装,许多死去的叛乱分子。 但是我们最大的惊喜还没有到来。我们希望我们至少能打倒大机器人,像房子一样大的伐木巨人。他们到处使用泛型,肯定列表<弹药>或地图<武器,弹药>仍然会遭受拳击原语的诅咒,这些该死的内联类变成成熟的对象?! 又错了。瓦尔哈拉还带来了泛型专门化:一种向后兼容的方法,可以在原语和内联类上创建泛型,而无需打包。所以,是的,一个ArrayList是由AmmTunes[]支持的。 我们被耍了。 发射时间 大家都知道,Java最终是快的。但它应该像泥泞中的卡车一样发射,所以在2052年,我们计划了一次全球同步的清晨突袭(机器人启示录的好处:不再有时区)。要是我们知道莱顿项目就好了(为了跟上Java的发展,我们应该在推特上关注@nip afx——他知道这件事)。 莱登将格雷尔的本土形象纳入了标准。有了它,创建一个特定于操作系统的可执行文件是小菜一碟: javac AutoTurret.java native-image AutoTurret ./autoturret

经过一个有点冗长的提前编译,可执行程序在毫秒内启动!你可能会认为本地图像由于其封闭世界的假设而受到的限制会阻止这些机器人使用它们,但事实证明,随着时间的推移,莱登和格拉尔将限制降至最低,大量预先存在的应用程序可以使用它们,也可以对它们进行重构。几乎每一个新创建的应用程序都可以从中受益。 长话短说,2052年的那个早上被称为粗鲁的觉醒,它让我们倒退了十多年。 可维护性 爪哇的独创性让我们一次又一次地倒退。这一切肯定不是免费的吧?由于巴拿马项目,本土互动得到了极大改善… int[] killCounts = // ... VarHandle handle = MemoryHandles .varHandle(int.class, ByteOrder.nativeOrder()); VarHandle indexedHandle = MemoryHandles.withStride(handle, 4); try (MemorySegment segment = MemorySegment .allocateNative(killCounts.length * 4)) { MemoryAddress address = segment.baseAddress(); for (int i = 0; i < killCounts.length; i++) { int count = killCounts[i]; indexedHandle.set(address, (long) count, count); } }

… 竖锯计划的附加安全… WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by j9ms.internal.JPEG (file:...) to field com.sun.imageio.plugins.jpeg.JPEG.TEM WARNING: Please consider reporting this to the maintainers of j9ms.internal.JPEG WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release

… 琥珀计划运送的大量改进… sealed interface Target permits Human, PurringCat { /* ... / } record Human(int gunCount) implements Target { / ... / } non-sealed class PurringCat implements Target { / ... */ }

public String evaluateThreat(Target target) { var threatLevel = switch(target) { case Human human -> """ { "target": "human", "threatLevel": "%d" } """.formatted(human.gunCount()); case PurringCat cat -> """ { "target": "cat", "threatLevel": "%d" } """.formatted(cat.purrLevel() + 10); } LOGGER.debug(threatLevel); return threatLevel; }

… 或者对API和JVM的数不清的小型、中型和大型添加。随着功能集的增长,开发人员需要了解越来越多,有更深的理解来做出正确的选择,找到正确的权衡。我们的理论说,可维护性应该受到影响,这一次,我们认为Java的变化会站在我们这边。坦率地说,我们对模块系统播种混乱寄予了很大希望。)因此,通过快速变化的环境,我们也许能够智取机器人并将其拿下。 这是我们迄今为止最好的主意。 但如果我们成功了,我们就不会有这次谈话了。最后,是Java社区让我们筋疲力尽。充满活力,充满聪明人和强大的公司,伟大的教程和快速的作弊,会议,时事通讯,博客,视频,等等。他们把这个盖住了。他们不会被几个傻瓜愚弄。 所以我们在这里。机器人还在漫游。 尾声 如果你是历史学家,你可能会想——所有这些功能不是在20世纪20年代甚至更早发布的吗?为什么我们不讨论更新的东西?因为没有更新的东西了。一旦战争开始,每个人都想得到伟大的战争:约翰·罗斯、马克·莱因霍尔德、布莱恩·戈茨、罗恩·普雷斯勒、斯图尔特·马克斯等等。他们被绑架、杀害、躲藏、加入抵抗组织,但没有人继续研究爪哇。 新版本呢?在某个地方,有一个孤独的CI服务器,像发条一样生产新版本。找到它并关闭它是你的工作。如果你成功了,就不会有Java 129,到了9月份,机器人会关闭,因为在不支持的Java版本上运行是违反操作过程的。 你是我们最后的希望V你能救我们吗?