3 位 Java Champion 如何使用 GitHub Copilot 提升效率
How 3 Java Champions are using GitHub Copilot for increased productivity
3 位 Java Champion 分享了在生产项目和开源工作中使用 GitHub Copilot 的经验,重点是把执行交给智能体,同时由开发者负责方案、验证和最终结果。他们介绍了迁移约 900 张教学幻灯片、排查 Pi4J 按钮故障等案例,并建议先澄清需求、制定计划、设置任务专属验证关卡,再将经验整理为可复用技能。
三位 Java Champion 的案例展示了如何通过明确任务、设置可验证的完成标准并保留人工审查,让 Copilot 承担执行而不转移工程责任。
AI 编码工具可以快速生成代码,但仅凭速度并不能解决最棘手的软件工程问题。开发者仍需提供上下文、验证结果、保障可维护性,并对最终交付的内容负责。
为了了解经验丰富的开发者如何把握这种平衡,我们采访了三位 Java Champion,他们使用 Java 的经验都超过十年。他们分享了在生产环境和开源项目中使用 GitHub Copilot 的具体案例,以及如何将 AI 生成的内容转化为可靠软件的实践经验。
以下是他们分享给我们的建议。
认识 Java Champions
- Vlad Mihalcea,Hypersistence 创始人,以及《High-Performance Java Persistence》一书的作者
- Patrick Baumgartner,42talents 软件工匠,拥有 20 多年 Java 经验
- Frank Delporte,Azul 高级技术撰稿人、Foojay.io 维护者,拥有 15 年以上 Java 经验
Vlad Mihalcea
GitHub 个人资料:@vladmihalcea
GitHub Copilot 最近如何帮助了你?
我一直在使用它来分析、设计和实现 Hypersistence Utils 与 Hypersistence Optimizer 中的各种功能。
例如,我很早就想开发一个 Web 应用,用来提供 Optimizer 事件历史记录,让我们能够了解性能改进工作如何体现为应用性能的提升。在 AI 出现之前,我一直把这项任务往后拖,因为开发它需要好几周。但使用 Copilot 就像有了一位新团队成员,所以我用它创建了一个应用,该应用将在 Hypersistence Optimizer 的下一个版本中发布。这项任务只花了两天就完成了,而不是几周。
你通常如何使用它?你是把 GitHub Copilot 当作 IDE 插件使用,还是使用 GitHub Copilot 应用?
我在 IntelliJ IDEA 中使用 GitHub Copilot,因为无论是在审查源代码时,还是在调试过程中运行它,都很方便。
它是非常实用的代码助手,能帮助我加快调查问题的速度,也能加快构建待验证功能原型的速度。
我仍会审查 AI 生成的计划和代码,因为它们的目的是提高我的工作效率,而不是完全取代我。虽然 AI 在许多情况下都能给出正确答案,但有时它的回复仍不尽如人意,需要我介入处理。
你能分享一些技巧和最佳实践吗?例如,你使用了哪些技能?
我创建了自己的技能,让 Copilot 生成的文本看起来就像是我亲手写的一样。
这项技能从我已发表的 65 篇文章中提取了我的表达风格,因此生成的草稿读起来像我的博客,而不是语言模型的产物。在为这个项目编写文档时,这非常有用,因为它能让 LLM 从我 12 年的博客写作中学习,并提供遵循相同原则的示例,例如表达清晰、易于测试和简洁。
在整个软件工程师生涯中,我逐渐认识到,我们花在代码维护上的时间远多于创建代码。因此,考虑到维护和稳定性对现有产品至关重要,我开发了一些技能,帮助 AI 遵循最小惊讶原则,模仿现有的代码实践。
一个建议是根据操作类型更换模型类型。对于需要深入思考的任务,我会使用 Opus,搭配 100 万上下文窗口以及 Extra High 或 Max 推理能力。不过,对于较简单的任务,例如生成报告、发布说明或核对文档,我会使用消耗 token 更少的轻量级模型。
Patrick Baumgartner
GitHub 个人主页:@patbaumgartner
你的工作涉及指导团队。你采用什么方法?
我的很多工作都是在业务仍须照常运转的情况下开展的。你不可能让一切停摆六个月来进行“转型”。我们通常会从一起解决眼前的问题入手,了解团队目前的状况,明确我们想要达到的目标以及如何判断是否有所进步,然后一步步向目标迈进。
根据具体情况,这可能意味着践行软件工艺,例如 TDD、重构、持续交付和 XP;使用 Spring Boot、Spring Modulith 进行架构设计和模块化;采用 Spring Security;优化 Java 和 Spring Boot 应用以适用于容器;或者越来越多地开展智能体工程。
对我来说,重要的是我与团队一起工作。我们共同做决定。我不希望团队变得依赖我。理想情况下,过一段时间后,除非他们需要一位切磋伙伴,否则就不再需要我了。
这或许也解释了为什么我觉得新一代 AI 工具如此有趣:我喜欢与人合作、学习、尝试和解决问题。AI 为我们提供了另一个非常强大的工具,让我们能够做到这些。
能否分享一个 GitHub Copilot 最近给你带来帮助的精彩案例?
实际上,有三个截然不同的例子改变了我对使用 GitHub Copilot 工作的看法。
先从第一个例子说起吧。
其中一个例子是将 15 份演示文稿中约 900 张教学幻灯片从 Reveal.js 迁移到 Marp。这些幻灯片并不简单。许多都包含代码、动画,甚至有互动示例,我可以在授课时实时修改 JavaScript。更重要的是,这些演示文稿已经在学生面前反复检验过。整个流程行之有效。哪怕丢失一个小细节,都可能破坏我在课堂上讲述的内容。
手动完成这项迁移可能要花我一周或更长时间,而且说实话,这项工作太枯燥了,我可能干脆就不做了。
借助 Copilot,我采取了不同的方法。我们先分析现有材料,明确目标,制定迁移计划,设定约束条件,提供示例,并明确哪些内容必须保持不变。然后,我们从大的结构性改动入手,再逐步处理细节。
真正重要的是验证。
我们生成了 Reveal.js 和 Marp 版本的截图,并通过视觉和算法进行比较。我们还开发了一个小应用,可以并排运行两套幻灯片,手动验证动画效果。我们甚至比较了生成的 PDF。
这意味着智能体不会只是说:“迁移完成。”我们有证据为凭。
整个迁移大约花了我八到十个小时。内容、教学意图以及每一处有意义的改动仍由我负责。Copilot 可以自动修正拼写错误,但如果内容、版本、日期或含义发生变化,那就是需要我们讨论的事情。
对我来说,这段经历再次印证了一条重要原则:委派执行,而非责任。我对结果负责。
能否分享第二个例子?
另一个例子是使用 Tamboui 构建终端 UI 应用。它最初在 WSL 的 Linux 中运行得非常完美,我完全忘了有人可能会直接在 Windows CMD 或 PowerShell 中运行它。
然后,真的有用户这么做了。
他们发现,在某些表单中,Enter 键会被直接忽略。这也体现了我坚信的另一个原则:尽早发布软件,因为你能从人们的实际使用方式中学到东西。
我们使用 Copilot 将这些反馈转化为可复现的 UI 测试。在 Linux 上,Copilot 通过 tmux 操作应用。通过与它协作,我了解了 psmux,并能在 PowerShell 中执行类似流程。我们复现了问题,创建了本地修复,追溯发现问题实际出在 Tamboui 中,随后我提交了上游修复,并且该修复已被合并。
在这项工作中,测试描述本身变得过于庞大,超出了可用上下文的容量。因此,我请 Copilot 帮我重新设计测试的表示方式。它没有使用包含标识符、名称和重复描述的冗长表格,而是提出了一种紧凑得多的箭头表示法:步骤 → 步骤 → 输入,只在至关重要的地方补充信息。
这让我很意外。我们不只是在用 AI 执行信息;我们还在共同探讨应该如何表示信息以便执行。表示方式不必尽可能方便人类阅读,只要保留语义,同时让智能体能够高效处理即可。
第三个例子呢?
第三个例子又完全不同。
我身边有个人需要练习数学,我就想:为什么不做一个小型学习应用呢?
它涵盖一年级到四年级的加法、减法、乘法、除法和有余数的除法。但我不想再做一个简单的测验应用。我和 Copilot 一起研究了间隔重复、即时反馈、自适应难度、激励、合作学习以及避免黑暗模式的游戏化等学习方法。
有意思的是,在这番研究中,Copilot 对我最初的一个假设提出了质疑。我一开始想让这个应用适用于世界各地的儿童。研究让我们转而关注实际的学校课程。我意识到,各地引入知识点的顺序、运算内容和数值范围差异足够大,因此一开始就追求“通用”并无必要。
于是我们先专注于瑞士,并据此调整了学习进度。由于瑞士是多语言国家,这款应用提供德语、法语、意大利语和英语版本。
它还设有合作和竞技两种双人模式;如果有人答错,应用会讲解一种解题方法,并通过间隔重复再次呈现类似的问题。
我特意选择了不带后端的架构。我没有理由在服务器上收集儿童的个人数据,因此数据会保留在设备上,而应用只需托管在 GitHub Pages 上即可。
最初的小实验如今已在朋友间使用和分享,意外地成了一个小产品。
这段经历让我看到了 Copilot 的另一种用法:不要只用它来实现你的方案。把它当作一个切磋对象,在开始构建之前,拓展并审视方案空间。
你通常如何使用 Copilot?
实际上,我已经不再使用经典的 Copilot 自动补全功能了。
我的工作几乎已经完全转向了智能体工作流。
当我需要紧密的可视化反馈循环时,我会使用 VS Code——比如想仔细查看文档、代码、演示文稿或中间结果,并在过程中调整流程。
对于规模较大、以执行为导向的任务,我通常会在终端中使用编码智能体。在那里,我更乐于委派一项工作,让它执行,然后检查完整结果。我选择哪种界面,主要取决于我需要怎样的反馈循环。
前往 JavaLand 途中,我还通过 GitHub 使用编码智能体工作流,获得了一次很有意思的体验。当时我刚开始探索一个想法:开发一个 Maven 插件,用来优化加载哪些 Spring Boot 自动配置。在大约四个小时的旅途中,我用手机指挥智能体:给它分配任务,检查它的工作,思考下一步,然后发送下一条指令。
到达时,我已经有了一个可用的 Maven 插件、一条 CI 流水线、针对示例应用的性能测试,以及能够展示优化是否真正奏效的报告。
那是我第一次用这种方式工作,我很惊讶它居然真的行得通。我并不是想用手机写 Java。我是在审查、决策并引导智能体执行。
我也会在 MCP 服务器能提供实用能力或上下文时使用它们。例如,我用过 Context7 查阅文档、与我的 Logseq 知识库集成,也试验过 Adobe Premiere Pro 的 MCP 集成。
但我不会仅仅因为能用就使用 MCP。如果有好用的 CLI,我通常更喜欢 CLI,因为对我来说它感觉更直接、更快。
在我的认知里,智能体也不是“初级开发人员”。我更愿意把它看作一个切磋交流的伙伴。不过,就像任何加入项目的人一样,它首先需要熟悉项目情况。
上下文为王。
你能分享一些技巧和最佳实践吗?
我最想建议的一点是:别再用一次性提示词了。
对于任何并非简单的任务,我都希望在开始执行前先弄清楚问题。很多时候,我会明确要求智能体先采访我。采访的目的是找出仍未明说的假设和预期。
优秀的智能体可以极快地执行一个错误的想法,但这并不意味着绕路的成本更低。
我在开发 Spring Boot 自动配置优化器时就亲身经历过这一点。起初,我想同时支持 Spring Boot 3.5 和 4.x。由于两者存在架构差异,我们实现了两种方案。后来我意识到自己不再需要 3.5 方案,而移除它却很费劲。
教训很简单:绕路代价高昂。加速之前,先把需求弄清楚。
明确目标后,我会要求制定计划。审查计划时,有四件事对我尤其重要:假设是否清晰可见,是否定义了验证关卡,方案是否符合架构,以及是否避免了不必要的工作?
第二条原则是定义针对具体任务的验证关卡。
“完成”不应该仅仅意味着模型说它完成了。
对于重构,关卡可能包括:测试通过、证明所有目标文件均已处理、更新文档,并且不留下任何 TODO。对于幻灯片迁移,关卡包括截图、视觉差异对比、动画、PDF 输出和内容完整性。
门槛取决于任务,但原则不变:智能体应该能够提供证据,证明工作符合完成定义。
我最近发现了一项名为 unlazy 的技能,它遵循类似的理念:设定明确的门槛,有条理地逐一完成,并证明这些门槛已经达成,而不是走捷径。
第三个原则是把经验教训转化为可复用的技能。
我已经开始编写和维护自己的 Agent Skills。每当我从一次执行中学到一些东西——比如智能体误解了某种约定、缺少一项有用的检查,或者我找到了更好的任务处理方式——我就会更新相应的技能。
下次执行该任务时,这些经验就已经融入其中了。
举个例子,我有一项名为 maintainer-audit 的技能,灵感来自开放的智能体技能社区中的工作。我会在自己的各个代码仓库中使用它。它会检查并在适当情况下修复我认为一个维护良好的项目应具备的内容:代码仓库文档、CI 流水线、Dependabot 配置、CodeQL、一致的清理工作以及其他项目规范。
目标不是再生成一份审计报告让我阅读,而是自动让代码仓库回归我希望达到的基线。这样一来,我的项目会更加一致,也更容易维护。
我认为这些技能是不断演进的工程知识,而不是静态提示词。
第四个原则是围绕概率模型配备确定性的工程工具。
我有自己的质量检查工具链,它封装了 Checkstyle、PMD 和 Spring Modulith 架构检查等工具,并生成一份智能体可以使用的汇总报告。我可以通过钩子运行它,让智能体反复迭代:
修改 → 执行检查 → 阅读结果 → 修复 → 再次执行。
它会持续运行,直到不再发现问题。
这并不意味着我不再检查软件。我仍然会运行应用、与之交互,并判断它的行为和外观是否符合预期。有时我会刻意逐个功能地实现,因为这样反馈循环会紧密得多。
我发现,因为“AI 能做到”就一次性提出所有要求,通常不是好主意。宽泛而笼统的规格会造就宽泛而笼统的实现,而事后清理它们,可能比正确地分小步构建还要困难。
更广泛地说,我认为开发者需要更多地交流如何使用这些工具。分享奏效的实验,也分享没奏效的。相互借鉴,并根据自己的情境加以调整,而不是寻找一种放之四海而皆准的 AI 开发流程。
这也是我喜欢把 AI 看作陪练伙伴的原因。周五晚上,当我想尝试一些东西,却找不到人类搭档时,我突然有了某个人——或者某种东西——可以一起探讨想法、审视方案,或者充当一只非常智能的橡皮鸭。
但我仍会把这些想法带回现实中与人交流。人类的反馈、对产品的理解以及现实世界的情境依然至关重要。
你认为 AI 正在如何改变我们的职业?
我认为,软件工程专业的学生不应该主要以成为代码生产机器为目标。他们需要成为出色的问题解决者。他们需要理解用户和利益相关者,发现需求背后的真正问题,质疑假设,了解产品和市场,权衡架构取舍,进行批判性思考,有条理地工作,并将有用的解决方案从一种情境迁移到另一种情境。
该模型非常擅长生成各种可能方案并执行任务。但作为人类,我通常更了解实际情况——包括那些从未被记录下来的信息。
所以我希望继续负责塑造解决方案,并让智能体承担更多执行工作。
从这个意义上说,我认为AI 正在让软件工程重新回归工程本质。
而我喜欢这一点。
Frank Delporte
GitHub 个人资料:@FDelporte
你是如何开始接触科技领域的?
我 11 岁时得到了一台 Commodore 64,从那时起就对计算机着迷。毕业后,我曾暂时转向视频制作和电视工作,但后来又回到了编程领域,因为当时需要把视频刻录到 DVD 上,还要制作最早的那些网站……没错,我就是这么老 ;-)。
最近 GitHub Copilot 如何帮助了你?
它是评估拉取请求和调查错误报告的完美搭档。
有个值得一提的案例,涉及 Pi4J 库,它让你能够构建 Java 应用程序,与 Raspberry Pi 上的电子元件进行交互。2026 年 2 月,我们发布了 V4,其中包含一个使用 Foreign Function & Memory API 的新插件。发布前我们进行了全面测试,但即便如此,发布后不久,还是有人报告说,使用 5 个输入按钮时无法正常工作。按下配置的前四个按钮之一时,会像预期那样触发代码执行,而按下第五个按钮则毫无反应。
这类报告最让人不愿看到。没有任何明显的故障。没有异常,日志里没有警告,第五个按钮只是毫无反应。更糟的是:使用较早的 gpiod 插件时,同一硬件和同一应用程序都能正常工作。因此,问题出在我们的新 FFM 代码中。它构建于 Linux 内核的 GPIO 字符设备之上,并通过本机调用与之通信。这可不是那种能轻易找到答案的代码库部分。
于是我把这个问题分配给 Copilot 编码智能体,并提供了两个文件路径作为起点:提供程序类和 FFMDigitalInput。大约半小时后,它提交了一个拉取请求,还附上了一段我完全没料到的解释。
每个输入都会运行一个事件监视器,它会阻塞在本机 poll() 调用中,等待内核报告 GPIO 线路上的变化。这些监视器运行在虚拟线程中。而在本机调用中阻塞的虚拟线程,无法从其载体线程上卸载。在整个调用期间,它都会被固定在那里。Raspberry Pi 4 有四个核心,因此虚拟线程调度器有四个载体线程。注册四个输入后,四个载体线程就会全部停在 poll() 中,永远无法继续。第五个监视器虽然创建了,却永远不会被调度。这正是报告中描述的错误。不是“事件时灵时不灵”,而是“第五个完全没反应”。
我最喜欢的并不是代码差异,而是评审过程中接下来的对话。我留了一条评论,请 Copilot 更详细地解释:
我以为虚拟线程的目标恰恰是摆脱平台线程数量的限制?那么,四个虚拟线程阻塞了四核处理器(比如 Raspberry Pi)的四个线程,为什么会成为问题?
请查看拉取请求,了解完整对话。Copilot 能够将 Raspberry Pi 拥有四个 CPU 核心这一点与报告的问题联系起来。它不仅提出了一个简单的修复方案,还给出了调查过程中发现的一些额外改进建议。
你能分享一些技巧和最佳实践吗?
- 告诉它该看哪里:针对 Pi4J 问题 #622,我添加了两个文件路径。这只需花费一点点精力,却能省去在大型代码库中大量搜索的工作。即使你完全不知道 bug 出在哪里,通常也会对问题所在的代码区域有些头绪。把这些信息告诉工具,这样它就不必检查整个代码库。
- 要求提供证据并编写测试:“添加一个单元测试来验证这项更改”是我最近常提的要求。准确地说,我以前常提,因为现在这已经成为我指令文件中的一条规则。这样也能避免误诊,因为如果诊断有误,测试在旧代码上就不会失败。
- 问清原因:如果你不理解某项修复,就直说并提出疑问。解释本身也是交付成果,应该添加到项目文档中,或写进工单或拉取请求里。这样能让之后阅读相关信息的每个人都学到东西。例如,这也促使 Pi4J 团队进一步讨论了原生调用中的虚拟线程固定问题。
- 保持掌控:这些 Pi4J 拉取请求在合并前都经过了维护者的审查和批准。这是最适合这个项目的模式:由智能体负责调查,人类则对最终发布的内容负责。不过,在我的其他项目中,我也总会审查工具生成的代码。我始终希望代码易于阅读和维护。工具经常会创建重复的方法,或者重新实现其他地方已经有的功能,而这些本应合并起来。这是你的责任。如今,借助 AI 辅助编程,你可以写得非常快,这也意味着你可能很快就会把代码弄得一团糟。别这么做,要让代码保持易于管理;如果同事或未来的你之后需要排查 bug 或改进代码,他们会感谢你的。
这篇文章《3 位 Java Champions 如何使用 GitHub Copilot 提高工作效率》最初发表于GitHub 博客。
来源:GitHub Blog · AI & ML · github.blog