硬核观察 #1204 Chrome 还有打击广告拦截器的下一个武器
1 Chrome 还有打击广告拦截器的下一个武器为了打击浏览器上的广告拦截器，Chrome 不但计划在 2024 年 6 月推出限制广告拦截的 Manifest V3 扩展平台，而且还会限制扩展更新过滤规则的方式，以延迟扩展开发者快速响应变化的能力。YouTube 可以立即更换广告投放系统，但一旦 Manifest V3 成为强制规定，扩展开发者就无法立即做出响应。如今，广告拦截器和隐私应用可以自行更新过滤列表，通常使用的是巨大的开源社区的列表。Manifest V3 将通过限制谷歌所说的 “远程托管代码” 来阻止这种情况。所有更新，即使是像过滤列表这样的良性更新，都需要通过 Chrome 商店进行全面的扩展更新。这些更新都需要经过 Chrome 网上应用商店的审核过程，而这将带来很大的时间延迟。消息来源：Ars Technica老王点评：对谷歌的反垄断审查更严厉些吧。2 Java 尝试使用多线程的新方法在 Java 21 的预览版本中，Java 尝试了多线程的新方法：结构化并发。该方法允许开发者使用结构化编程语法来使用多个线程。从本质上讲，它提供了一种使用熟悉的程序流程和结构编写并发软件的方法。这样，开发人员就可以专注于手头的业务，而不是线程的协调。虚拟线程现已成为 Java 的一项正式功能，它为廉价生成线程以获得并发性能提供了可能。结构化并发为此提供了简单的语法。因此，Java 现在拥有了一个独特的、高度优化的、易于理解的线程系统。消息来源：Info World老王点评：这是一个很好的消息，值得关注。3 研究称 GPT-4 没有通过图灵测试在一篇题为 《GPT-4 通过图灵测试了吗？》的预印本研究论文中，研究人员将 GPT-4 人工智能语言模型与人类参与者、GPT-3.5 和 ELIZA 进行了对比。其中，ELIZA 是一个上世纪 60 年代开发的基于规则的对话程序。研究人员建立了一个名为 turingtest.live 的网站，他们在该网站上通过互联网举办了一场双人图灵测试。通过该网站，人类审讯者与代表其他人类或人工智能模型的各种 “人工智能证人” 进行互动。令人惊讶的是，ELIZA 在研究中得分相对较高，成功率达到 27%，超过了 GPT-3.5 的 14% 成功率。GPT-4 的成功率为 41%，但就连 GPT-4 也不符合图灵测试的成功标准，既没有达到 50% 的成功率，也没有超过人类参与者的成功率。消息来源：Ars Technica老王点评：虽然这个结果令人吃惊，但是我倾向于研究方法有误，比如没有很好地设计符合 GPT 方式的提示语。
硬核观察 #1074 甲骨文的新 Java 许可条款将增加 2-5 倍费用
甲骨文的新 Java 许可条款将增加 2-5 倍费用据 Gartner 公司估计，大多数企业在接受甲骨文公司新的 Java 许可条款时，预计按员工订阅模式的成本将是传统模式的两到五倍。新模式以每个员工的消耗量为基础，而不是以前的每个处理器或每个用户的消耗量。这同时意味着到 2026 年，80% 以上的 Java 应用程序将部署在第三方 Java 运行时上，而 2023 年这一比例仅为 65%。Gartner 还警告说，甲骨文公司已经准备好测试用户是否遵守它所认为的 Java 许可条款，预计 1/5 的 Java 用户会在未来三年内接受甲骨文的审计。消息来源：The Register老王点评：Java 真是一只下金蛋的鸡，但是现在它一天要下一只是不行的了。FCC 建议新的宽带标准美国联邦通信委员会（FCC）主席提出了一项新的宽带标准，即下载速度为 100Mbps，上传速度为 20Mbps，以取代 2015 年的 25Mbps/3Mbps 标准。根据她的计划，FCC 将评估宽带的可用性、速度和价格，以决定是否采取监管措施来促进网络部署和竞争。FCC 还将为未来设定一个 1Gbps/500Mbps 的目标。消息来源：Ars Technica老王点评：新的带宽目标，将带来新的基础设施，而新的基础设施是更多应用的基础，比如 AR/VR/XR 等，以及 AI。OpenAI 悄然关闭其人工智能检测工具今年 1 月，人工智能巨头 OpenAI 发布了一款工具，它可以通过检测内容是否使用了生成式人工智能工具（比如它自己的 ChatGPT）来创建。半年后，这个工具死了，原因是 “它的准确率很低”，但这一解释并没有出现在新的公告中，而是添加到了首次发布该工具的博客文章的注释中。消息来源：Decrypt老王点评：AI 工具无法识别 AI 输出的内容。还有什么能束缚 AI 的发展？
Auto-GPT 将人工智能“套娃”最近，一个名为 AutoGPT 的新人工智能工具发布了，它比 ChatGPT 更有潜力。它可以执行人类级别的任务，并利用 GPT-4 的能力来开发一个可以独立运作而不受用户干扰的 AI 代理。它是一个实验性的、开源的 Python 应用程序，它使用 ChatGPT/GPT-4 来自主地行动。AutoGPT 使用“套娃”的概念来递归地调用自己，这是一种让 AI 模型使用其他模型作为工具或媒介来完成任务的方法。AutoGPT 使用这种方法，并在 ChatGPT 和 GPT-4 的帮助下，通过迭代自己的提示创建完整的项目。人们称，Auto-GPT 是通用人工智能（AGI）的第一个真正的缩影。消息来源：Mark Tech Post老王点评：虽然距离 AGI 还有距离，但是能“自动”解决问题的 AI，距离下一步可以自主运行的 AI 又有多远呢？Java 21 的一个提案将使它更容易学习计划在 9 月发布的 JDK 21 中有一个默认禁用的预览语言功能，它提议在 Java 中引入灵活的 main 方法和匿名 main 类，这将使 Java 变得更容易被学习。根据该提案，它将允许省略 main 方法的 String[] 参数，并允许 main 方法既不公开也不静态；引入匿名 main 类，声明隐含 main 类。比如 Hello World 程序只需要这样一行：void main() { System.out.println("Hello, World!");}。消息来源：Info World老王点评：这样的 Java 是不是看起来平易近人多了？西部数据被窃取到了 10 TB 数据西部数据本月初证实它在 3 月 26 日遭到入侵，但没有透露更多信息。参与此次攻击的一名黑客公开接受采访，披露了更多相关信息。黑客称他们从西部数据窃取到了大约 10 TB 数据，正在谈判索要至少八位数的赎金。作为证据，黑客分享了一份使用西数证书签名的文件，以证明他们已经获取到了该证书。黑客表示他们入侵的目的是获利，因此没有用勒索软件加密西数的文件，如果西数拒绝或不理睬他们的要求，他们将会公开西数的数据。消息来源：Tech Crunch老王点评：根据另外一份报告，83% 的企业被勒索后都会先期支付部分赎金。
硬核观察 #948 俄罗斯开发者被阻止向“自由及开源软件”贡献
俄罗斯开发者被阻止向“自由及开源软件”贡献最近有两起俄罗斯开发者被阻止贡献 FOSS 代码的事件。在 Linux 内核邮件列表上，俄罗斯芯片制造商贝加尔电子公司的 Sergey Semin 的贡献被拒绝了，“我们对接受来自贵组织生产的硬件或与之相关的补丁感到不舒服。”另外一件也是针对俄罗斯开发者的，他的 GitHub 账户已被封锁。他开发的 “一个管理和配置支持智能平台管理界面的设备的工具”，ipmitool，被标记为只读“存档”。原因是他为俄罗斯芯片制造商 Yadro 工作，该公司正在研发 RISC-V 芯片，被列入了乌克兰的战争与制裁数据库。消息来源：The Register老王点评：GitHub 倒也罢了，那毕竟是一家美国公司。Linux 内核，FOSS ？！呵呵。现代汽车承诺在汽车中保留实体按钮这是一个源于安全考虑的决定，现代汽车公司的设计主管说，“对我来说，与安全有关的按钮必须是一个硬键，……很容易感知和感觉到它”。但未来的情况可能会发生变化。特别是，当自动驾驶成为主流时，该公司可能会更多地考虑使用触摸控制。“当涉及到 4 级自动驾驶时，那么我们将拥有一切软键。”消息来源：The Drive老王点评：现在有些汽车你都找不到什么按键和旋钮，真当自己的软件系统万无一失吗？甲骨文公司宣布推出 Java 20这个有 27 年历史的语言的最新版本包括数以千计的性能、稳定性和安全性方面的改进，并对 Java 开发工具包提出了 7 项增强建议。甲骨文公司在过去的五年中，每六个月推出一个新的 Java 版本，并说它是这个开源项目的最大贡献者，在 Java 开发组织中排名第一。Java 的开发分为六个项目，分别针对性能和功能的不同方面，如使其更加简洁和不容易出错、改善启动时间和性能、实现大规模并行等等。今年 9 月将发布的 Java 21 将是每两年一个的 LTS 版本。消息来源：Silicon Angle老王点评：Java 是不错，就是被当成下金蛋的母鸡了。
硬核观察 #897 甲骨文新的授权模式导致 Java 使用成本激增
甲骨文新的授权模式导致 Java 使用成本激增甲骨文公司修改了 Oracle Java SE 订阅模式，在新的模式下，Java 将按每个员工授权，而不是像旧模式允许的那样按每个用户或每个处理器授权。尽管甲骨文公司承诺允许用户可以根据他们目前的订阅模式进行续约，但随着时间的推移，它可能会对用户施加压力，让他们采用新的模式。这种转变将惩罚那些花了多年时间尽量减少 Java 使用量的公司，因为他们发现无论他们使用多少Java，都要按员工收费。有分析称，有的公司的 Java 成本上升了 10 倍，平均在 2 到 4 倍的增长。消息来源：The Register老王点评：是时候抛弃甲骨文的 Java 了。GitHub 用户数突破 1 亿成立于 2008 年的 GitHub 宣布，现在有 1 亿名开发者在使用该平台。与 GitHub 十年前的 300 万用户、五年前微软以 75 亿美元收购它时声称的 2800 万用户，以及三个月前透露的 9000 多万用户相比，这一数字有了大幅提升。在 2019 年的一次主题演讲中，其前 CEO 说，该公司的目标是到 2025 年达到 1 亿名开发者，所以实际上是提前两年达成了目标。消息来源：Tech Crunch老王点评：要不是在某些地方访问 GitHub 经常性抽风，可能 GitHub 能更快完成这一目标吧。ChatGPT 在寻找和解决程序错误方面表现优异研究人员将 40 段有错误的代码交给四个不同的代码修复系统：ChatGPT、Codex、CoCoNut 和标准 APR（自动程序修复）。在第一轮测试中，ChatGPT 解决了 19 个问题，Codex 解决了 21 个，CoCoNut 解决了 19 个，而标准 APR 方法则解决了 7 个。然而，通过和 ChatGPT 对话，提供了有关问题和错误的更多信息后，最终 ChatGPT 解决了 31 个问题。消息来源：《PC 杂志》老王点评：看看，不仅仅能写程序，还能替你挑错，甚至修改错误，所以，程序员们可能真的快被淘汰了。
在这个简便的教程中，我们可以了解到 Java 中方法的定义，如何使用方法，以及何时使用方法。Java 中的方法（在许多其他编程语言中称为“函数”）是被组合在一起并标记为可重用的一块代码。方法很有用，因为它们允许你在不重写相同代码的情况下，执行相同的操作或一系列操作，这不仅意味着你的工作量减少，还意味着出现问题时需要维护和调试的代码减少。方法存在于类中，因此标准 Java 样板代码适用：package com.opensource.example; public class Example { // 在此写代码 } 在这样一个简单的单文件应用程序中，包定义并不是绝对必要的，但它是一个很好的习惯，而且大多数 IDE 都强制执行它。默认情况下，Java 会寻找在类中运行的 main 方法。方法可以是公有的或私有的，也可以是静态的或非静态的，但 main 方法必须是公有的、静态的，Java 编译器才能识别和使用它。当方法是公有的时，它可以从类外部执行。要在程序启动时调用 Example 类，其 main 方法必须是可访问的，因此将其设置为 public。下面是两个方法的简单演示：一个 main 方法在调用 Example 类时默认执行，另一个 report 方法接受 main 的输入并执行简单操作。为了模拟任意数据输入，我使用了 if-then 语句，该语句根据你启动应用程序的时间在两个字符串之间进行选择。换句话说，main 方法首先设置一些数据（在现实生活中，这些数据可以来自用户输入，也可以来自应用程序其他地方的其他方法），然后 “调用” report方法，将处理后的数据作为输入提供：package com.opensource.example; public class Example { public static void main(String[] args) { // 生成一些数据 long myTime = System.currentTimeMillis(); String weather; if ( myTime%2 == 0 ) { weather = "party"; } else { weather = "apocalypse"; } // 调用其他方法 report(weather); } private static void report(String day) { System.out.printf("Welcome to the zombie %s\n", day); } } 运行代码：$ java ./Example.java Welcome to the zombie apocalypse $ java ./Example.java Welcome to the zombie party 请注意，同一 report 方法有两个不同的结果。当然，在这个简单的演示中，不需要第二种方法。模拟数据生成的 if-then 语句可能生成了相同的结果。但是，当一个方法执行一项复杂的任务时，比如将图像调整为缩略图，然后使用调整后的图像在屏幕上生成小部件，那么附加组件的“费用”就很有意义了。何时使用 Java 方法很难知道何时使用方法，何时只将数据发送到 Java 流 或循环中。如果你面临这个决定，答案通常是使用一种方法。原因如下：方法开销少。它们不会给代码增加处理开销。方法减少代码的行数。方法是特定的。查找名为 resizeImage 的方法通常比查找隐藏在从驱动器加载图像的函数中某个循环中的代码更容易。方法是可重用的。当你第一次编写方法时，你可能会 认为 它只对应用程序中的一个任务有用。然而，随着应用程序的编写，你可能会发现自己正在使用一种你认为“已完成”的方法。函数式编程与面向对象编程函数式编程利用方法作为执行任务的主要构造。创建一个方法，该方法接受一种数据，处理该数据，并输出新数据。将许多方法串在一起，你就拥有了一个动态且功能强大的应用程序。像 C 和 Lua 这样的编程语言就是这种编码风格的例子。用代码完成任务的另一种方式是 Java 使用的面向对象模型。在面向对象编程中，方法是模板的组成部分。你可以创建对象，而不是将数据从一个方法发送到另一个方法，并可以通过使用它们的方法来更改它们。从面向对象的角度来看，这是一个简单的 “僵尸末日” 演示程序。在函数方法中，我使用一种方法生成数据，另一种方法使用该数据执行操作。面向对象的等价物是具有表示工作单元的类。这个示例应用程序向用户显示一条当天的消息，宣布这一天会有僵尸派对或是僵尸末日。编写一个“天”对象，然后查询该对象以了解其特性是有意义的。作为演示面向对象构造的不同方面的借口，新的示例应用程序还将统计有多少僵尸出现在派对上（或末日）。Java 为每个类使用一个文件，因此要创建的第一个文件是 Day.Java，它用作 Day 对象：package com.opensource.example; import java.util.Random; // 类 public class Day { public static String weather; public int count; // 构造方法 public Day() { long myTime = System.currentTimeMillis(); if ( myTime%2 == 0 ) { weather = "paradise"; } else { weather = "apocalypse"; } } // 方法 public String report() { return weather; } public int counter() { Random rand = new Random(); count = count + rand.nextInt(100); return(count); } } 在“类”部分中，创建了两个域：天象 weather 和计数 count。weather 是静态的。在一天的过程中（在这种假想的情况下），weather 不会改变。要么是派对 paradise，要么是末日 apocalypse，持续了一整天。然而，僵尸的数量在一天中会增加。在“构造方法”部分，确定当天的天象。它是作为一个 构造方法 完成的，因为它只在类最初被调用时发生一次。在“方法”部分，report 方法只返回由构造方法确定和设置的天象报告。然而，counter 方法生成一个随机数，并将其添加到当前僵尸计数中。换句话说，这个类做了三件不同的事情：表示应用程序定义的“天”。设置当天不变的天气报告。设置一天中不断增加的僵尸数量。要使用这所有，请创建第二个文件：package com.opensource.example; public class Example { public static void main(String[] args) { Day myDay = new Day(); String foo = myDay.report(); String bar = myDay.report(); System.out.printf("Welcome to a zombie %s\n", foo); System.out.printf("Welcome to a zombie %s\n", bar); System.out.printf("There are %d zombies out today.\n", myDay.counter()); System.out.printf("UPDATE: %d zombies. ", myDay.counter()); System.out.printf("UPDATE: %d zombies. ", myDay.counter()); } } 因为现在有两个文件，所以使用 Java IDE 运行代码是最简单的，但是如果不想使用 IDE，可以创建自己的 JAR 文件。运行代码以查看结果：Welcome to a zombie apocalypse Welcome to a zombie apocalypse There are 35 zombies out today. UPDATE: 67 zombies. UPDATE: 149 zombies. 无论调用 report 方法多少次，weather 都保持不变，但调用 counter 方法的次数越多，僵尸的数量就会增加。Java 方法方法（或函数）是编程中的重要组成。在 Java 中，你可以将它们作为函数式编程的单个类的一部分使用，也可以在面向对象编程的类之间使用它们。两种类型的编程对于解决同一个问题有不同的视角，因此没有对与错之分。通过反复尝试，积累一点经验，你会知道哪一个最适合某个特定的问题。via: https://opensource.com/article/23/1/java-methods作者：Seth Kenlon 选题：lkxed 译者：ZhangZhanhaoxiang 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
硬核观察 #847 Java 不再是最受欢迎的三大编程语言之一
Java 不再是最受欢迎的三大编程语言之一根据最新的 TIOBE 指数，现在的排名是：Python 排名第一，C 第二，C++ 第三，Java 第四。2001 年以来，TIOBE 指数历史上 C++ 第一次超过了 Java。C++ 的激增，部分原因可能要归功于 2020 年 12 月发布的 C++ 20 稳定版。但在其它排行榜和调查中，Java 的表现更好。比如 Slashdata 数据显示，Java 在过去两年中以全球开发者社区两倍的速度增长，在社区规模中排名第三，超过了 C/C++，仅次于 Python 和 JavaScript。消息来源：The Register老王点评：我觉得语言排行榜的每次变化，除了给我添加一些话题之外，没啥意义。谷歌再次推迟淘汰 MV2 扩展谷歌推行的 Manifest V3 浏览器扩展规范，相比 V2 扩展，新版本增加了很多有利于谷歌的限制，比如限制广告屏蔽扩展。谷歌 原计划 在明年 1 月淘汰 MV3 扩展，但 MV3 仍存在一些问题，导致一些扩展没法迁移。这一期限被延迟到明年 6 月后，谷歌再次宣布推迟淘汰 MV2 扩展，但没有确定具体时间，谷歌表示要在 2023 年 3 月前听取开发者的更多反馈。消息来源：谷歌老王点评：谷歌审慎的态度很好，但是其本质上还是希望推进 MV3 的实施。Adobe 公开发布 PostScript 源代码Adobe 公司成立之初，他们就着手设计一种打印机无关的排版语言 PostScript，并于 1984 年发布。PostScript 本质上是一种数字化的印刷系统，它提供了其他任何地方都无法提供的能力，如文字和图像可以随意缩放、旋转和移动。如今大多数打印机都直接依赖 PostScript 技术，或者通过从它发展出来的 PDF 技术。而在它诞生近 40 年后，Adobe 公司通过计算机历史博物馆首次公开了 PostScript 的源代码。消息来源：计算机历史博物馆老王点评：这是印刷史上的一个里程碑，只是我没想到使用这么广泛的系统，源代码现在才公开。
Quarkus 令你可以使用类似 Java 的技术开发无服务器的工作负载。对 无服务器 Java 的研究始于函数 —— 就是按需求运行的一小段代码。这一阶段并没有持续很长时间。虽然在 1.0 阶段，基于虚拟机架构的函数使这种范式变得很流行，但它仍然有局限性，例如执行时间、协议和糟糕的本地开发体验，都不太理想，如下图所示。开发者随后意识到，可以把同样的无服务器特性应用于微服务和 Linux 容器，带来的好处也是一样的。由此进入 1.5 阶段，在这个阶段，一些无服务器容器完全抽象化了 Kubernetes，通过 Knative 或其它位于它之上的抽象层来提供无服务器的体验。在 2.0 阶段，无服务器开始处理更复杂的编排和集成模式，并结合某些层级的状态管理。更重要的是，开发者关注的是能否在旧的系统中使用熟悉的 Java 应用程序运行时来组合运行无服务器和非无服务器的工作负载。Java 开发者开始进行无服务器函数开发之前，第一步是要选择一种新的云原生 Java 框架，从而能够以快于传统单体应用程序的速度和较小的内存占用运行 Java 函数。这在各种基础设施环境中，包括物理服务器、虚拟机、多云或混合云环境中的容器，都是适用的。开发者也有可能固执地选择 Spring 框架中的 Spring 云函数 来进行命令式和反应式函数的开发。Spring 也支持将 Java 函数部署到可安装的无服务器平台，比如 Kubeless、Apache OpenWhisk、Fission 和 Project Riff。然而，人们担心 Spring 的启动慢、响应时间长以及内存占用大的问题。在诸如 Kubernetes 这种可扩展的容器环境中运行 Java 函数，这些问题可能会更严重。Quarkus 是一个新推出的开源云原生 Java 框架，它有助于解决这些问题。它的作用是设计无服务器应用程序，以及编写运行于云基础设施（例如 Kubernetes）的云原生微服务。Quarkus 重新审视了 Java，它使用了封闭的方法构建和运行 Java 程序。它把 Java 转变为一种可与 Go 相媲美的运行时。Quarkus 也包含 100 多种扩展功能，集成了企业级能力，例如数据库访问、无服务器集成、消息、安全、可观察性和业务自动化。这里有一个简单例子，展现如何使用 Quarkus 创建一个 Java 无服务器项目的框架。1、基于 Maven 创建一个 Quarkus 无服务器项目安装一个本地 Kubernetes 集群，开发者有多种选择，包括 Minikube 和 OKD。因为使用 OKD 在 Knative 和 DevOps 工具上安装无服务器相关功能较方便，本文使用 OKD 安装集群。这些关于 OKD 安装 和 Knative 操作员安装 的相关指南中提供了更多的设置资料。下面的命令创建了一个 Quarkus 项目（例如 quarkus-serverless-restapi），对外暴露一个简单的 REST API，并下载 quarkus-openshift 扩展，用于 Knative 服务的部署：$ mvn io.quarkus:quarkus-maven-plugin:1.13.4.Final:create \ -DprojectGroupId=org.acme \ -DprojectArtifactId=quarkus-serverless-restapi \ -Dextensions="openshift" \ -DclassName="org.acme.getting.started.GreetingResource" 2、在本地运行无服务器功能使用 Quarkus 开发模式运行程序，检查 REST API 是否有效，稍稍调整一下代码：$ ./mvnw quarkus:dev 输出如下内容：__ ____ __ _____ ___ __ ____ ______ --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ INFO [io.quarkus] (Quarkus Main Thread) quarkus-serverless-restapi 1.0.0-SNAPSHOT on JVM (powered by Quarkus xx.xx.xx.) started in 2.386s. Listening on: http://localhost:8080 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated. INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, kubernetes, resteasy] 注意: 保持 Quarkus 应用程序运行，需要使用 热部署 Live Coding 。这样，当代码修改后，你就不必重新构建、重新部署以及重启运行时。现在，你可以使用一个 curl 命令快速访问 REST API。输出结果应当是 Hello RESTEasy:$ curl localhost:8080/hello Hello RESTEasy 在 GreetingResource.java 中修改返回值：public String hello() { return "Quarkus Function on Kubernetes"; } 再次访问 REST API，输出信息也会相应更新：$ curl localhost:8080/hello Quarkus Function on Kubernetes 普通的微服务跟无服务器函数之间的差别并不大。使用 Quarkus 的好处在于：开发者可以使用任何微服务，将 Kubernetes 部署为无服务器函数。3、在 Knative 服务中部署相关的函数如果你还没有创建命名空间，就在你的 OKD 集群上 创建命名空间（例如 quarkus-serverless-restapi），用来部署 Java 无服务器函数。Quarkus 令开发者可以通过在 src/main/resources/application.properties 中添加以下变量，创建 Knative 和 Kubernetes 资源：quarkus.container-image.group=quarkus-serverless-restapi <1> quarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000 <2> quarkus.kubernetes-client.trust-certs=true <3> quarkus.kubernetes.deployment-target=knative <4> quarkus.kubernetes.deploy=true <5> quarkus.openshift.build-strategy=docker <6> 说明: 在你部署无服务器应用程序的位置定义项目名 使用容器注册中心 在这个简单例子中，使用自签名证书，以便通过相关信任机制 允许创建 Knative 资源 指示在构建容器映像之后将扩展部署到 OpenShift 设置 Docker 构建策略执行以下命令，构建应用程序，并直接部署到 OKD 集群：$ ./mvnw clean package -DskipTests 注意: 应该提前使用 oc login 命令，确保登录到正确的项目（例如quarkus-serverless-restapi）。输出结果应该以 BUILD SUCCESS 结束。在对于 Knative 服务执行的 oc 命令中，加上标签:$ oc label rev/quarkus-serverless-restapi-00001 app.openshift.io/runtime=quarkus --overwrite 然后访问 OKD 网页控制台，就能进入 开发人员透视图中的拓扑视图。你可能会看到你的 容器荚 Pod （无服务器函数）已经缩小为零（白线圈）。4、在 Kubernetes 环境下测试函数运行如下 oc 命令，搜索含有无服务器函数的路由：$ oc get rt/quarkus-serverless-restapi [...] NAME URL READY REASON quarkus-serverless[...] http://quarkus[...].SUBDOMAIN True 使用 curl 命令访问搜索到的路由：$ curl http://quarkus-serverless-restapi-quarkus-serverless-restapi.SUBDOMAIN/hello 过几秒钟，你可以得到跟在本地相同的结果：Quarkus Function on Kubernetes 当你回到 OKD 集群内的拓扑图，Knative 服务会自动扩展。由于 Knative 服务的默认设置，其 pod 在 30 秒后会再次下降至零。下一步呢？无服务器不断地在演变，始于运行于虚拟机的函数，到后来的无服务器容器，并与企业原有系统集成。在此过程中，企业开发者借助 Quarkus，仍然可以使用自己熟悉的技术（比如 Java）创建一个项目，然后构建并部署到 Kubernetes。本系列的下一篇文章将指导你优化 Kubernetes 中的 Java 无服务器函数，从而令程序启动更快，内存占用更小。文内图像来自：Daniel Oh, CC BY-SA 4.0via: https://opensource.com/article/21/6/java-serverless-functions作者：Daniel Oh 选题：lkxed 译者：cool-summer-021 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
安装 Java，使用 Maven 安装 JDBC，并安装数据库。然后，你就可以在 Java 代码中与数据库进行交互了。当你编写一个应用时，需要数据存储是很常见的。有时你要存储你的应用需要的素材数据，其他时候你要存储用户数据，包括偏好和保存的数据。存储数据的一种方式是在数据库中，为了在你的代码和数据库之间进行通信，你需要为你的语言提供一个数据库绑定或连接器。对于 Java 来说，一个常见的数据库连接器是 JDBC（ Java 数据库连接 Java database connectivity ）。1、安装 Java当然，要使用 Java 进行开发，你还必须安装 Java。对于 Linux、macOS 和 WSL 或 Cygwin，我推荐 SDKman。对于 Windows，你可以从 developers.redhat.com 下载 OpenJDK。2、使用 Maven 安装 JDBCJDBC 是一种 API，通过语句 import java.sql.* 导入到你的代码中，但要使其有用，你必须安装数据库驱动和数据库以与之交互。你使用的数据库驱动和要通信的数据库必须匹配：要与 MySQL 交互，你需要 MySQL 驱动，要与 SQLite3 交互，你必须具有 SQLite3 驱动等等。在本文中，我使用 PostgreSQL，但所有主流数据库，包括 MariaDB 和 SQLite3，都有 JDBC 驱动程序。你可以从 jdbc.postgresql.org 下载 JDBC for PostgreSQL。我使用 Maven 来管理 Java 依赖项，因此我将它包含在 pom.xml 中（调整 Maven Central 上的当前版本号）： org.postgresql postgresql 42.5.0 3、安装数据库你必须安装要通过 JDBC 连接的数据库。有几个非常好的开源数据库，但是我只能为这篇文章选择一个，所以我选择了 PostgreSQL。要在 Linux 上安装 PostgreSQL，请使用你的软件仓库。在 Fedora、CentOS、Mageia 和类似设备上：$ sudo dnf install postgresql postgresql-server 在 Debian、Linux Mint、Elementary 和类似平台上：$ sudo apt install postgresql postgresql-contrib 数据库连接如果你不使用 PostgreSQL，同样的一般过程也适用：安装 Java。为你选择的数据库找到 JDBC 驱动，并将其包含在你的 pom.xml 文件中。在你的开发系统上安装数据库（服务器和客户端）。三个步骤，你就可以开始编写代码了。via: https://opensource.com/article/22/9/install-jdbc-linux作者：Seth Kenlon 选题：lkxed 译者：geekpi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
了解 Java 中的内存管理。用 C 或 C++ 这样的编程语言写一个应用时，需要编写代码来销毁内存中不再需要的对象。当应用程序扩展得越来越复杂时，未使用对象被忽略释放的可能性就越大。这会导致内存泄露，最终内存耗尽，在某个时刻将没有更多的内存可以分配。结果就是应用程序运行失败并出现 OutOfMemoryError 错误。但在 Java 中， 垃圾收集器 Garbage Collection （GC）会在程序执行过程中自动运行，减轻了手动分配内存和可能的内存泄漏的任务。垃圾收集器并不只有一种，Java 虚拟机（JVM）有七种不同的垃圾收集器，了解每种垃圾收集器的目的和优点是很有用的。1、Serial 收集器垃圾收集器的原始实现，使用单线程。当垃圾收集器运行时，会停止应用程序（通常称为“stop the world”事件）。适用于能够承受短暂停顿的应用程序。该垃圾收集器占用内存空间比较小，因此这是嵌入式应用程序的首选垃圾收集器类型。在运行时使用以下命令启用该垃圾收集器：$ java -XX:+UseSerialGC 2、Parallel 收集器像 Serial 收集器一样，Parallel 收集器也使用“stop the world”方法。这意味着，当垃圾收集器运行时，应用程序线程会停止。但是不同的是，Parallel 收集器运行时有多个线程执行垃圾收集操作。这种类型的垃圾收集器适用于在多线程和多处理器环境中运行中到大型数据集的应用程序。这是 JVM 中的默认垃圾收集器，也被称为吞吐量收集器。使用该垃圾收集器时可以通过使用各种合适的 JVM 参数进行调优，例如吞吐量、暂停时间、线程数和内存占用。如下：线程数：-XX:ParallelGCThreads=<N>暂停时间：-XX:MaxGCPauseMillis=<N>吞吐量（垃圾收集花费的时间与实际应用程序执行的时间相比）：-XX:GCTimeRatio=<N>最大堆内存：-Xmx<N>Parallel 收集器可以使用该命令显式启用：java -XX:+UseParallelGC 。使用这个命令，指定在新生代中通过多个线程进行垃圾回收，而老年代中的垃圾收集和内存压缩仍使用单个线程完成的。还有一个版本的的 Parallel 收集器叫做 “Parallel Old GC”，它对新生代和老年代都使用多线程，启用命令如下：$ java -XX:+UseParallelOldGC 3、Concurrent Mark Sweep（CMS）收集器Concurrent Mark Sweep（CMS）垃圾收集器与应用程序并行运行。对于新生代和老年代都使用了多线程。在 CMS 垃圾收集器删除无用对象后，不会对存活对象进行内存压缩。该垃圾收集器和应用程序并行运行，会降低应用程序的响应时间，适用于停顿时间较短的应用程序。这个收集器在 Java8 已过时，并在 Java14 中被移除。如果你仍在使用有这个垃圾收集器的 Java 版本，可以使用如下命令启用：$ java -XX:+UseConcMarkSweepGC 在 CMS 垃圾收集器使用过程中，应用程序将暂停两次。首次暂停发生在标记可直接访问的存活对象时，这个暂停被称为初始标记。第二次暂停发生在 CMS 收集器结束时期，来修正在并发标记过程中，应用程序线程在 CMS 垃圾回收完成后更新对象时被遗漏的对象。这就是所谓的重新标记。4、G1 收集器G1 垃圾收集器旨在替代 GMS。G1 垃圾收集器具备并行、并发以及增量压缩，且暂停时间较短。与 CMS 收集器使用的内存布局不同，G1 收集器将堆内存划分为大小相同的区域，通过多个线程触发全局标记阶段。标记阶段完成后，G1 知道哪个区域可能大部分是空的，并首选该区域作为清除/删除阶段。在 G1 收集器中，一个对象如果大小超过半个区域容量会被认为是一个“大对象” 。这些对象被放置在老年代中，在一个被称为“humongous region”的区域中。 启用 G1 收集器的命令如下：$ java -XX:+UseG1GC 5、Epsilon 收集器该垃圾收集器是在 Java11 中引入的，是一个 no-op（无操作）收集器。它不做任何实际的内存回收，只负责管理内存分配。Epsilon 只在当你知道应用程序的确切内存占用情况并且不需要垃圾回收时使用。启用命令如下：$ java -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC 6、Shenandoah 收集器Shenandoah 是在 JDK12 中引入的，是一种 CPU 密集型垃圾收集器。它会进行内存压缩，立即删除无用对象并释放操作系统的空间。所有的这一切与应用程序线程并行发生。启用命令如下：$ java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC 7、ZGC 收集器ZGC 为低延迟需要和大量堆空间使用而设计，允许当垃圾回收器运行时 Java 应用程序继续运行。ZGC 收集器在 JDK11 引入，在 JDK12 改进。在 JDK15，ZGC 和 Shenandoah 都被移出了实验阶段。启用 ZGC 收集器使用如下命令：$ java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC 灵活的垃圾收集器Java 为我们提供了灵活的内存管理方式，熟悉不同的可用方法有助于为正在开发或运行的应用程序选择最合适的内存管理方式。via: https://opensource.com/article/22/7/garbage-collection-java作者：Jayashree Huttanagoudar 选题：lkxed 译者：Veryzzj 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出