社区重于代码 (北美) 2023
作者:Paul King
发布时间:2023-10-26 05:00PM
今年的 ASF 会议 - 社区重于代码 - 北美版,在哈利法克斯会议中心举行了为期四天的面对面会议(10 月 7 日至 10 日)。
注意
|
演示文稿幻灯片和音频/视频(如有)仍在添加到会议网站上。如果出现更多材料,本帖将更新,提供指向这些额外内容的链接。 |
这篇文章介绍了会议的更新。它主要关注 Groovy 轨道,但也包含了有关其他轨道和会议的许多其他方面的材料。特别是,我希望这篇文章能让你了解参加会议,特别是 ASF 会议,为什么是一次有意义的体验。我希望在未来的会议上见到你。
抵达后
在进入会议报告之前,给那些从多个时区旅行到会议的人提个建议。如果你只根据社交媒体上的信息来判断,经常在会议上发言看起来可能像是一种光鲜亮丽的生活,但如果没有一点计划,你可能看到的只是飞机、酒店和会议室的内部。分配一些时间去看看举办会议的城市/国家是值得的。如果你在抵达的第一天(或者如果晚上抵达的话,在抵达后的第一个完整日)也能晒晒太阳,这似乎有助于克服时差。就我而言,我利用了这个机会,骑着自行车在哈利法克斯以东的地区骑行,主要沿着一些适合骑自行车的自行车道骑行。
这条路线 90% 在现已废弃的铁路轨道上修建的小径上,这些轨道是 加拿大横贯路 的一部分。它进一步细分为更小的部分,包括 Shearwater Flyer Trail,Salt Marsh Trail,Atlantic View Trail 和 Dartmouth Waterfront Trail。我租自行车的店建议骑到 Lawrencetown Beach,但我多骑了一点。景色非常壮观。我特别喜欢一些秋季色彩的景色,这在我的居住地很少见到。
Groovy 轨道
Groovy 轨道分布在会议的前两天,包含十个会议,以及第一天结束后的一场“自由讨论”会议。这些会议通常都有迷你主题:Groovy 更新、面向 Java 开发人员、Kubernetes 和 Groovy、Groovy 和数据科学(今年以 Apache Ignite 为特色)等等。这里我们只看看每个演讲的一些亮点。如果你想了解更多细节,建议你浏览幻灯片和其他内容。
Groovy 更新
前两个演讲涵盖了 Groovy 项目的现状,以及来自更广泛的 Groovy 生态系统的更新。
第一个演讲是 Groovy 和 Groovy 生态系统更新。它介绍了 Groovy 项目本身的状态,以及更广泛的 Groovy 生态系统中的一些重要项目。
一些亮点
-
Groovy 下载量最近突破了 30 亿大关,目前平均每天的下载量略高于 300 万次。
-
Groovy 已经支持类和脚本,但随着 Java 中的 JEP 445 脚本即将发布(JDK21 中的预览版),Groovy 5 支持其他形式,以便 JEP 445 代码示例可以直接在 Groovy 中运行(适用于 JDK11+)。
def main() { println 'Hello world!' }
有一些变体严格兼容 JEP 445(以获得相同的字节码简化),还有一些变体保留了 Groovy 的额外功能,例如访问脚本绑定和上下文。
run
方法用于代替main
方法,以获得传统的 Groovy 脚本功能。另外一个好处是,Groovy 的@Field
注解不再需要用于指定 JEP 445 类脚本中的字段。以下是一个使用 Jackson 数据绑定将自身序列化为 JSON 文件的示例@JsonIgnoreProperties(["binding"]) def run() { var mapper = new ObjectMapper() assert mapper.writeValueAsString(this) == '{"pets":["cat","dog"]}' } public pets = ['cat', 'dog']
-
Groovy 添加了对“下划线作为占位符”功能的支持。这类似于 JEP 443(JDK21 中的预览版),但 Groovy 还为闭包和多赋值表达式添加了此功能。
var (_, y, m, _, _, d) = Calendar.instance println "Today is $y-${m+1}-$d" // Today is 2023-8-23
-
现在提供了一个额外的
@OperatorRename
AST 变换,它使使用 Groovy 的运算符重载与大量库更容易。当处理可能操作复数、矩阵或分数的库时,这非常有用(如以下使用 Apache Commons Numbers Fraction 库的示例所示)。以前,你可能不会使用运算符重载快捷方式,或者你(或其他人)可能已经编写了一些 Groovy 特定的扩展方法,为特定感兴趣的库提供更漂亮的运算符重载语法糖。现在,这些库可以使用运算符重载功能直接开箱即用。@OperatorRename(plus='add') def testAddOfTwoFractions() { var half = Fraction.of(1, 2) var third = Fraction.of(1, 3) assert half.add(third) == Fraction.of(5, 6) // old style still works assert half + third == Fraction.of(5, 6) // fraction '+' operator! }
-
Grails 6 最近发布,支持 Groovy 3 的最新版本。
-
Micronaut 4 最近发布,支持 Groovy 4 的最新版本。
-
Geb 7 和 Spock 测试框架的几个版本也支持 Groovy 4。
-
Deep Netts 深度学习库的最新版本在使用 Groovy 5 与 GraalVM 时效果很好。
-
Apache Ignite 的最新版本在扩展分布式数据、分布式计算和分布式数据科学应用程序时,与 Groovy 5 配合良好。
第二个演讲是 2023 年为什么使用 Groovy?它讨论了即使考虑到 JDK 生态系统中其他语言的巨大进步,Groovy 仍然是一个引人注目的语言选择的功能。
一些亮点
-
如果你需要 Groovy 的动态功能,如运行时元编程、生命周期钩子和动态构建器,Groovy 非常引人注目。
-
Groovy 还提供了一些功能,例如范围、默认参数、命名参数、命令链、运算符重载、可扩展的工具,包括可扩展的类型检查器。
-
除了自己的原生功能外,Groovy 5 还为大约 150 个 Java 类提供了大约 2000 个扩展方法。
-
特质提供了类似于接口中默认方法的功能,但它们不仅解决了 API 演进的问题,而是更雄心勃勃、更强大的面向对象功能。Groovy 提供了有状态特质,更强大的方法选择选项,在运行时提供特质应用(动态特质),并支持像 Scala 一样的可堆叠特质模式。
-
Groovy 的闭包抽象提供了比 lambda 提供的更强大的机制,包括记忆化和尾递归处理。你可以用更自然的递归形式编写阶乘(避免显式命令式算法),并且不会出现堆栈溢出问题。你可以编写递归斐波那契算法,这些算法只需几毫秒就可以执行,而不是天真的递归算法需要数万亿年才能执行。
-
AST 变换(基于注解)和宏方法(类似但看起来像方法调用)允许使用声明式编程风格,其中几行代码可以替换成数百行或数千行等效代码。生成的代码遵循最佳实践,并且错误更少。Groovy 5 有 80 多个 AST 变换。
-
语言集成查询允许使用类似 SQL 的风格查询数据。
GQ { from fruit in ['Apple', 'Apricot', 'Banana', 'Cantaloupe'] groupby fruit[0] as firstChar select firstChar, list(fruit.toUpperCase()) as fruit_list }
这将产生
+-----------+------------------+ | firstChar | fruit_list | +-----------+------------------+ | A | [APPLE, APRICOT] | | B | [BANANA] | | C | [CANTALOUPE] | +-----------+------------------+
-
虽然我们喜欢随着最新 Java 版本一起发布的 switch 表达式的许多激动人心的变化,但 Groovy 仍然提供了许多其他选项(适用于 JDK8+):
-
Groovy 让你可以选择 JDK8+ 的模拟记录或 JDK16+ 的原生记录,并且有很多记录增强功能: 除了内置增强功能外,Groovy 的 AST 变换使记录开发更容易。幻灯片中包含将记录与以下 AST 变换结合使用的示例:
@PropertyOptions
、@ToString
、@Memoized
、@Builder
、@Requires
、@Sortable
、@Newify
和@OperatorRename
。当然,你不必局限于此列表。
面向 Java 开发人员的 Groovy
接下来的两个演讲针对的是想要了解如何在开发或测试工作中使用 Groovy 的 Java 开发人员。
下一个演讲是由 Jeff Scott Brown 做的,主题是“面向 Java 开发人员的 Groovy”。Jeff 涵盖了一系列主题,包括
-
Groovy 可选类型
-
Groovy 属性
-
Groovy 脚本语法
-
将 Java 源代码演变为 Groovy
-
Groovy 的特殊功能
-
Groovy 和 Java 类 的 Groovy 扩展方法
下一个演讲是 使用 Groovy、Spock、JUnit5、Jacoco、Jqwik 和 Pitest 测试你的 Java 代码。这个演讲涵盖了使用 Groovy 测试 Java 生产代码的常见场景,尽管大部分内容也适用于其他 JVM 语言(包括 Groovy!)的生产代码。它还展示了一些高级工具的示例,你可能希望在你的测试工具包中考虑使用它们。
演讲的中心示例基于一个最初看起来非常简单的数学计算,最初使用以下 Java 代码实现
我们使用 Spock 测试框架编写了一个 Groovy 测试,乍一看似乎表明我们的初始实现是正确的,因为所有测试都通过了,并且我们的代码覆盖率达到了 100%。
但这是 100% 的行和分支覆盖率,并不反映 100% 的状态覆盖率。我们可以通过添加一个额外的测试用例来说明这一点,现在它失败了
事实证明,初始实现没有处理一个边缘情况,但它很容易修复
现在我们所有的测试用例都通过了,并且仍然有 100% 的覆盖率。
这个故事的寓意是,100% 的行和分支覆盖率不足以确保实现正确。你应该尝试添加测试用例,直到你认为问题域已被完全测试。演讲的其余部分探讨了两个高级工具,它们可以帮助你找到测试用例的缺陷。
Pitest 工具 是一个变异测试工具。一开始理解它的工作原理以及它如何提供帮助有点令人费解。Pitest 会变异你的生产代码,然后重新运行你的测试套件。如果测试套件仍然通过,即变异体存活下来,它就代表一个可能的代码异味。
通常这意味着您的测试套件不够完整,无法杀死变异体,您应该添加更多测试用例。 但是变异测试不是一门精确的科学,如果变异体存活,可能意味着缺少测试用例,也可能意味着现有测试用例存在缺陷,也可能意味着实现代码中存在错误,或者可能是误报。
当我们有 3 个测试用例时,在有缺陷的实现上运行该工具,确实会发现一些存活的变异体,并且分析表明这些变异体确实对应于有缺陷的边缘情况
这应该引导我们添加额外的测试用例,就像我们之前手动添加的那样,这有望迫使我们发现错误。
在修复后的实现上运行该工具显示出改进,但仍然表明存在潜在的代码异味。 这一发现反映了对于我们的修复后的实现,c > Math.min(a, b)
和 c >= Math.min(a, b)
是等效的,即使在一般情况下,它可能意味着没有测试边缘情况。 所以变异测试当然很有用,但通常需要人工分析来排除任何误报。
另一个检查的工具是 Jqwik,这是一种基于属性的测试工具。 这些工具检查在使用随机数据对被测试实现进行练习时,某些属性是否成立。 事实上,这种测试也揭示了原始代码中的缺陷,而修复后的代码中没有发现缺陷。
Kubernetes 和 Groovy
Groovy 轨道中的下一个迷你主题是 Kubernetes 和 Groovy。
第一个演讲是由 Jorge Aguilera 做的:它在我的集群上运行。 将一个 Groovy Kubernetes 应用程序部署到 Okteto。 幻灯片
在这个演讲中,Jorge 展示了一个 Groovy Micronaut Kubernetes (k8s) 应用程序部署到云中。 它被部署到 Okteto 平台,因此实际上大多数 k8s 细节都由平台处理。
示例应用程序是针对 Collatz 猜想 的一个简单解决方案。 我记得在我的大学时代学习过这个,但我忘记了细节。 基本上,给定一个起始数字,将执行两种计算之一,具体取决于当前数字是偶数还是奇数。 奇数乘以 3,然后加 1,偶数除以 2。 如果结果变为数字 1,则停止,否则继续。 猜想是,最终,计算将终止,即最终总是等于 1。
有趣的是到达 1 所需的循环次数。 这是一个返回循环次数的算法
class Collatz {
static long getAt(BigInteger n) {
var result = n
var count = 0L
while (result != 1G) {
if (result % 2G == 0G) {
result /= 2G
} else {
result *= 3G
result++
}
count++
}
count
}
}
我们使用了一个静态 getAt
方法来为我们提供一个简洁的速记,用于获取结果。 我们可以测试 维基百科页面 中提到的示例序列中的一些。
assert Collatz[12] == 9
assert Collatz[19] == 20
assert Collatz[27] == 111
现在,要创建基于此算法的微服务。 我们可以通过多种方式创建 Micronaut 的完整工作(但骨架)项目。 以下是命令行需要的内容
mn create-app \
--features kubernetes \
--features postgres \
--features jdbc-data \
--lang groovy collatz
我们已经展示了一些您可能想要使用的示例功能。 您可以根据应用程序的需要添加更多功能。
我们可以更改骨架控制器以具有我们需要的功能
@Controller
...
@Get('{n}')
Map index(BigInteger n) {
[n: n, count: Collatz[n]]
}
...
然后,Jorge 继续解释了 k8s 配置细节,并演示了如何部署应用程序。
Jorge 还介绍了下一个演讲:让 Groovy 操作您的 k8s 集群。 这是深入研究更多 k8s 细节。 他展示了如何用 Groovy 编写一个 swagger-operator,它消除了在部署 k8s 应用程序时执行繁琐的手动步骤的需要。 该操作员监视我们的服务,在需要时重写 configmap 并重新启动 pod。
该操作员本身是用 Micronaut 编写的
@Operator(
informer = @Informer(
apiType = V1Swagger,
apiListType = V1SwaggerList,
apiGroup = V1SwaggerWrapper.GROUP,
resourcePlural = V1SwaggerWrapper.PLURAL,
resyncCheckPeriod = 10000L)
)
class SwaggerOperator implements ResourceReconciler<V1Swagger>{
}
Apache Groovy 和 Apache Ignite
下一个迷你主题是 Groovy 和数据科学。 Groovy 被描述为 JVM 的 Python 等效物,Groovy 与许多 ASF 框架和技术配合良好,这些框架和技术与数据科学和一般意义上的大数据相关。
今年的 Groovy 轨道数据科学内容特别关注如何使用 Apache Ignite 扩展您的数据科学应用程序以及您的数据和计算应用程序。
第一个演讲是 用 Apache Groovy 和 Apache Ignite 进行威士忌聚类。 这是一个案例研究,研究如何对 86 种单一麦芽苏格兰威士忌进行聚类。
有不同的算法可以用来进行聚类。 这里使用的是 K 均值聚类。
对于这个特定数据集,数据点的数量相对较小,因此扩展不是至关重要的。 但是较大的数据集将以相同的方式分割,因此我们将看看如何扩展它。 首先,我们读取数据
Apache Ignite 具有在集群环境中读取数据的特殊功能,但是我们可以使用 Apache Commons CSV 来进行我们的示例。
如果您了解 K 均值算法,乍一看,它似乎不适合分布式。 要对点进行聚类,您需要计算所有点到质心的距离。 幸运的是,已经设计出了各种分布式版本的算法,这就是 ignite-ml
库中包含的内容。 我们只是像使用非分布式版本一样使用库,Ignite 会为您完成艰苦的工作。 结果如下
我们有各种选择可以调整算法,以及各种方法可以可视化结果。
顺便说一句,有传言说,可能(也可能没有)与会议同时进行了关于这个主题的额外深入研究。 当然,仅仅因为会议是在(新斯科舍省的)哈利法克斯举行!
第二个演讲是由 Jeremy Meyer 做的,讨论了 使用 Apache Ignite 进行可扩展的分布式计算。
在这个演讲中,Jeremy 提出了一个问题
如果我们使用 Groovy 的动态、易于编码和原型化方面...
...与 Apache Ignite 计算网格的强大可扩展计算能力以及巧妙的同级类加载相结合呢?
对于那些了解 Ignite 的人来说,它可以以多种方式使用
在这种情况下,它将用于分布式计算,手头的任务是解决魔方。 在这种情况下,3x3x2 立方体的特定非破坏性角部移动。
首先是创建一个小型领域模型来表示立方体
然后将一组具有不同技能的计算机拼凑在一起,以形成计算网格
或者,如果您不是银河护卫队的粉丝,则可以选择另一种机器可视化
然后编写角部交换算法
最后获取结果
我不会抢走杰里米的风头。 查看链接获取详细信息。 但是一个教训是,将工作简单地分配给具有不同能力的机器有时会产生令人惊讶的结果。 幸运的是,计算网格作业分配有多种方法可以解释这种差异。
杂项
Jeff 做了另一个演讲,这次是关于GORM 数据服务。 首先介绍了传统的 GORM 功能,包括动态查找器、Criteria API、Where 查询和 HQL
然后他介绍了 GORM 数据服务
Jeff 还做了该轨道上的最后一个演讲:开源软件与你。 在这个演讲中,Jeff 详细介绍了自己的开源之旅。 他分享了自己 30 多年来在开源领域工作的一些见解。 讨论了您可能想要为开源做出贡献的原因,以及如何做出贡献。 他的旅程为所有开始或继续自己的开源旅程的人提供了灵感。
Jeff 涵盖了一些他早期的项目。 他继续讨论了 Grails,Grails 是 Groovy 早期发展过程中的一个关键驱动因素。 他还重申了 Unity 基金会对 Grails 基金会和 Micronaut 基金会持续的投资 - 这两种技术为许多 Groovy 用户所熟知。 他还讨论了 Unity 基金会最近的一些项目,这些项目旨在将开源应用于帮助服务不足的社区。
其他轨道
除了 Groovy 轨道之外,这次会议还充满了其他引人入胜的内容,这些内容被分组到以下轨道中
-
API/微服务轨道
-
大数据:计算轨道
-
大数据:存储轨道
-
云和运行时轨道
-
社区轨道
-
内容整理轨道
-
数据工程轨道
-
金融科技轨道
-
框架轨道
-
地理空间轨道
-
亮点轨道
-
孵化器轨道
-
物联网轨道
-
性能工程轨道
-
搜索轨道
-
与 ASF 基础设施的服务器端聊天
-
流媒体轨道
-
可持续发展轨道
-
Tomcat 和 httpd 轨道
我确实设法观看了其他一些轨道的演讲,但与其试图总结我所看到的一切,不如将您指向与会议相关的在线内容 日程安排。
在城堡里度过一个晚上
会议参加者活动是在哈利法克斯城堡国家历史遗址举行的一个夜晚。 城堡是一个要塞,它被建造(并重建了几次)来保护这座城市。 它矗立在一座俯瞰海港的山丘上,在某些时候也一直是一个重要的通信枢纽。
如果您在哈利法克斯,城堡值得一游。 他们有历史游览、鬼魂游览、每日大炮射击,以及偶尔的游行和乐队训练。 我只想指出游览中提到的一个特点。 在电子电信出现之前,旗杆兼具军事和商业信号的作用。 即使在电报发明之后,旗帜仍然作为对早期的传统被使用。
商业信号桅杆由英国军队用来将港口中的海上交通信息传递给公众。 不同的旗帜表示正在接近的船只的数量和国籍(以及其他事物)。 军事信号桅杆使用基于旗帜和圆盘的代码。 消息可以传递到其他信号站,并允许快速发送很远距离的消息。 骑马可能需要半天才能送达的消息,可以使用信号桅杆和代码在 30 分钟内完成。
等等,还有更多…
当然,ASF 会议远不止我所能描述的。 会议中有很棒的人、很棒的食物、走廊里的对话、与很棒的基础设施人员聊天,我是不是说很棒的人和很棒的食物?
希望在未来的 ASF 会议上见到您。
回家
旅行回来后,一定要与家人和朋友联系。 在我的情况下,这包括在海边度过的周末。
如果您访问澳大利亚,一定要去看看。
其他信息
2023 年哈利法克斯 Community over Code 会议的其他旅行报告
另请参见
-
其他照片 大致按天和每天的各个会议分组。
-
官方日程安排 包含所有轨道,并将包括演讲幻灯片的链接(如果/何时可用)。
-
明年 Community over Code EU 的详细信息。