Community Over Code(北美)2023
发布时间:2023-10-26 下午 05:00
今年的北美版 ASF 会议 Community Over Code 在哈利法克斯会议中心举行了四天的现场会议(10 月 7 日至 10 日)。
注意
|
演示文稿幻灯片和音频/视频(如有)仍在添加到会议网站。如果提供更多资料,此帖子将更新链接到额外内容。 |
这篇帖子提供了会议的最新情况。它主要关注 Groovy 专题,但也有关于其他专题和会议许多其他方面的内容。特别是,希望这篇帖子能让您对参加会议,特别是 ASF 会议,为何会是一次有益的体验有所了解。我希望在未来的会议中见到您。
抵达
在进入正式的会议报告之前,对于那些从几个时区之外旅行参加会议的人来说,一个小贴士是:如果您只是通过社交媒体来了解情况,那么经常在会议上发言可能看起来是一种迷人的生活,但如果没有一点计划,您可能看到的只是飞机、酒店和会议室的内部。花一些时间去看看主办城市/国家是值得的。如果您在抵达的第一天(如果晚上抵达,则在抵达后的第一个完整天)也能晒到太阳,这似乎有助于克服时差。就我而言,我借此机会在哈利法克斯东部骑了一段自行车,大部分路程都是沿着适合骑行者的自行车道。
这条路线 90% 都在废弃的铁轨上修建的小径上,这些小径是 Trans Canada Trail 的一部分。它进一步细分为更小的部分,包括 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 已经支持类和脚本,但随着 JEP 445 脚本在 Java 中即将推出(JDK21 中的预览版),Groovy 5 支持额外的形式,以便 JEP 445 代码示例可以直接在 Groovy 中运行(适用于 JDK11+)。
def main() { println 'Hello world!' }
有一些变体严格保持与 JEP 445 兼容(以获得相同的字节码简化),还有一些变体保留了 Groovy 的额外功能,例如访问脚本绑定和上下文。使用 `run` 方法而不是 `main` 方法来获得传统的 Groovy 脚本功能。一个额外的好处是,在类似 JEP 445 的脚本中,不需要 Groovy 的 `@Field` 注解来指定字段。这是另一个例子,这个例子使用 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?这讨论了使 Groovy 成为一个引人注目的语言选择的功能,即使考虑到 JDK 生态系统中其他语言正在取得的巨大进步。
一些亮点
-
如果您需要其动态特性,例如运行时元编程、生命周期钩子和动态构建器,那么 Groovy 是一个引人注目的选择。
-
Groovy 还提供了范围、默认参数、命名参数、命令链、运算符重载、可扩展工具(包括可扩展类型检查器)等功能。
-
除了它自己的原生特性之外,Groovy 5 为大约 150 个 Java 类提供了大约 2000 个扩展方法。
-
特质(Traits)提供与接口中的默认方法类似的功能,但特质不仅仅解决 API 演进问题,它们是更具雄心和强大的面向对象特性。Groovy 提供有状态特质、更强大的方法选择选项、支持运行时特质应用(动态特质),并支持像 Scala 那样的可堆叠特质模式。
-
Groovy 的闭包(Closure)抽象提供了比 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 最新版本中开关表达式的许多激动人心的变化,但 Groovy 仍然提供了许多额外的选项(适用于 JDK8+):
-
Groovy 为 JDK8+ 提供模拟记录,为 JDK16+ 提供原生记录,并有许多记录增强功能:
除了内置增强功能之外,Groovy 的 AST 转换也使得记录开发变得更容易。幻灯片中提供了将记录与以下 AST 转换结合使用的示例:`@PropertyOptions`、`@ToString`、`@Memoized`、`@Builder`、`@Requires`、`@Sortable`、`@Newify` 和 `@OperatorRename`。当然,您不仅限于此列表。
面向 Java 开发人员的 Groovy
接下来的两场讲座面向 Java 开发人员,旨在帮助他们了解如何将 Groovy 用于开发或测试需求。
下一场讲座由 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 会修改您的生产代码,然后重新运行您的测试套件。如果测试套件仍然通过,即变异体存活下来,这可能表明存在代码异味。
通常这意味着您的测试套件不够完整,无法杀死变异体,您应该添加更多的测试用例。但变异测试并非一门精确的科学,如果一个变异体存活下来,可能意味着缺少测试用例,可能意味着现有测试用例存在缺陷,可能意味着实现代码中存在 bug,也可能是误报。
当我们有 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 应用程序时繁琐的手动步骤。该 operator 监控我们的服务,并在需要时重写 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-Means 算法,乍一看它似乎不适合分布式。要对点进行聚类,您需要计算**所有**点到质心的距离。幸运的是,该算法的各种分布式版本已经被设计出来,这就是 `ignite-ml` 库中包含的内容。我们只需像使用非分布式版本一样使用该库,Ignite 会为您完成繁重的工作。这是结果:
我们有各种选项来调整算法和可视化结果的不同方式。
顺便说一句,据说额外的关于这个主题的深入研究可能(也可能不)与会议一起进行。这无疑是因为会议在(新斯科舍)!
第二场讲座由 Jeremy Meyer 主讲,讨论了 使用 Apache Ignite 通过 Groovy 实现可扩展分布式计算。
在这次演讲中,杰里米提出了一个问题:
如果我们利用 Groovy 的动态、易于编写和原型化的特性……
……结合 Apache Ignite 计算网格卓越的可伸缩计算能力和巧妙的对等类加载呢?
对于了解 Ignite 的人来说,它可以通过多种方式使用
在这种情况下,它将用于分布式计算,手头的任务是解决魔方。具体来说,是一个 3x3x2 魔方不破坏性的角块移动。
首先是创建一个小的领域模型来表示立方体
然后将不同技能的计算机集群组合成计算网格。
或者如果您不是《银河护卫队》的粉丝,可以选择机器的不同可视化效果。
然后编写角交换算法
最后得到结果
我不会抢 Jeremy 的风头。请查看链接获取详细信息。但一个经验是,天真地将工作分配给能力不同的机器有时会产生令人惊讶的结果。幸运的是,有多种方法可以使计算网格作业分配考虑这些差异。
杂项
Jeff 做了另一个演讲,这次是关于《GORM 数据服务》。首先涵盖了传统的 GORM 功能,包括动态查找器、Criteria API、Where 查询和 HQL。
然后他介绍了 GORM 数据服务
Jeff 还为该专题做了最后一场演讲:《开源软件与你》。在这次演讲中,Jeff 分享了他自己的开源之旅。他涵盖了他在开源领域工作 30 多年的一些见解。讨论了为什么您可能想为开源做贡献,以及如何做贡献。他的旅程为所有开始或继续自己开源之旅的人提供了灵感。
Jeff 介绍了他的早期项目。他接着讨论了 Grails,这是 Groovy 早期发展中的一个关键驱动力。他还重申了 Unity Foundation 对 Grails 基金会和 Micronaut 基金会的持续投资——这两个技术是许多 Groovy 用户非常熟悉的。他还讨论了 Unity Foundation 最近的一些项目,这些项目旨在应用开源来帮助服务不足的社区。
其他专题
除了 Groovy 专题,会议还充满了其他引人入胜的内容,分为以下几个专题:
-
API/微服务专题
-
大数据:计算专题
-
大数据:存储专题
-
云和运行时专题
-
社区专题
-
内容整理专题
-
数据工程专题
-
金融科技专题
-
框架专题
-
地理空间专题
-
亮点专题
-
孵化器专题
-
物联网专题
-
性能工程专题
-
搜索专题
-
与 ASF Infra 的服务器端聊天
-
流媒体专题
-
可持续性专题
-
Tomcat 和 httpd 专题
我确实看了不少来自其他专题的讲座,但与其尝试总结我看到的一切,不如直接将您指向会议 日程 中的在线内容。
在城堡的夜晚
会议的与会者活动是在哈利法克斯城堡国家历史遗址的夜晚。城堡是一座为保护城市而建造(并多次重建)的防御工事。它高高地矗立在俯瞰港口的山顶上,有时也是重要的通讯枢纽。
如果您在哈利法克斯,城堡是值得一游的地方。他们提供历史游览、幽灵游览、每日炮火表演以及偶尔的行军和乐队演练。我只想指出导游中提到的一个特点。在电子通信出现之前,旗杆兼具军事和商业信号的双重目的。即使在电报发明之后,旗帜仍然作为一种传统被使用,以纪念早期的时代。
商业信号桅杆曾被英军用来向公众通报港口内的海上交通情况。不同的旗帜会指示进港船只的数量和国籍(以及其他信息)。军事信号桅杆使用基于旗帜和圆盘的代码。信息可以传递到其他信号站,从而使信息能够快速远距离发送。通过信号桅杆和代码,原本可能需要半天才能通过骑马传递的信息可以在 30 分钟内完成。
但等等,还有更多……
当然,ASF 会议远不止我所能表达的那些。这里有很棒的人,很棒的食物,大厅里的对话,还有机会与出色的 Infra 同事们聊天。我有没有说很棒的人和很棒的食物?
希望在未来的 ASF 会议中见到您。
回家
旅行归来后,务必与家人朋友叙旧。就我而言,这包括在海滩度过一个周末。
如果您访问澳大利亚,请务必过来看看。
其他信息
2023 年哈利法克斯社区代码大会其他旅行报告
另请参阅
-
其他照片,大致按天和每天的会话分组。
-
官方日程包括所有专题,并将包含讲座幻灯片的链接(如果/何时可用)。
-
明年 Community over Code 欧盟 的详情。