文章目录
- 实验内容
- 实验概要
- 环境准备
- 设置 Builder ID
- 基于 Amazon Q协助梳理项目逻辑,快速掌握项目全貌
- 快速分析 pom,xml 内容
- 利用 Amazon Q 梳理控制器逻辑
- 利用 Amazon Q 梳理代码片段
- 利用 Amazon Q 生成项目摘要
- 基于 Amazon Q 修复程序逻辑问题,实现正确运行效果
- 启动 Q-Words 应用
- 使用 Amazon Q 识别并修复错误
- 基于 Amazon Q 项目review、单元测试、文档生成
- 使用 Amazon Q 进行代码审核(项目全局与细节代码)
- 对 Review 后的代码生成单元测试
- 实验链接
- ✨活动上新
实验内容
近年来,人们对使用人工智能改进软件开发越来越感兴趣,生成式人工智能编码助手和聊天机器人该领域最有前途的新发展之一。这些工具使用机器学习来生成代码并以自然语言格式回答有关代的问题。这使得所有技能水平的开发人员都可以轻松使用它们。
Amazon Q Developer 作为一款生成式人工智能 (AI)支持的对话助理,正在重新定义项目开发的边界,2024年亚马逊云科技 re:Invent 最新发布 Amazon Q Developer 的一系列开发工具与运维辅助功能将带您穿越传统开发的局限,进入生成式 AI 驱动的智能开发与运维时代。通过实践,将深入了解生成式 AI 如何实现代码智能生成、代码审核优化、智能重构、跨语言代码升级、自动化单元测试生成以及项目文档精准生成。
实验概要
- 云上实验环境准备
- 基于 Amazon Q 协助梳理项目逻辑,快速掌握项目全貌
- 基于 Amazon Q 修复程序逻辑问题,实现正确运行效果
- 基于 Amazon Q 项目review、单元测试、文档生成
环境准备
Amazon Q 与多个 IDE 集成,包括 JetBrains、Visual Studio Code、Amazon Cloud9 等。在本次动手实验中,我们将使用 Visual Studio Code。为了尽快进入实践部分,我们使用托管在 Amazon EC2 实例上的 Visual Studio Code Server。
访问 Visual Studio Code Server
- 进入控制台后,请在上方的 Search 中搜索 CloudFormation ,并点击搜索结果中的链接。
- 选择 CloudLabCampaignInfraStack-amazon-q-new-launch-reinvent2024
- 选择 Outputs,记录输出中的 URL 和 Password
- 选择 URL 打开 Visual Studio Code Server。
- 在对话框中,粘贴您之前复制的密码,然后选择提交。
- 现在应该可以看到 Visual Studio Code IDE,如下所示。
Visual Studio Code Server 已安装的组件
以下项目已经在您的 VS Code Server 实例上安装:
- Amamzon CLI
- https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/q-in-IDE-setup.html
- Git
- Java - Amazon Corretto – 版本 8 和17
- Maven
我们将在本次动手实验中使用的代码存储库已下载到文件夹中。
设置 Builder ID
在本次实验中,您将使用 Builder ID 连接到 Amazon Q,这将允许从 Amazon 访问某些开发人员工具和服务,Builder ID 可免费使用。
- Amazon Q 对话测试
基于 Amazon Q协助梳理项目逻辑,快速掌握项目全貌
快速分析 pom,xml 内容
Amazon Q 可以快速帮助我们梳理项目逻辑,从而快速掌握项目全貌,我们可以打开项目根目录的 pom.xml 文件,在 Amazon Q Chat 面板中,询问:
Can you tell me the artifactId, modelVersion and other relevant information in the pom file ?
我们将看到文件的简短描述,pom.xml 展示 Amazon Q 对当前文件的感知。在构建聊天历史记录时,在问题中包含文件名会有所帮助,因为这将成为上下文的一部分。
利用 Amazon Q 梳理控制器逻辑
Amazon Q 会使用聊天历史记录作为上下文的一部分。如果您发现 Q 没有做出适当的反应,则可能是由于当前上下文所致。在这些情况下,通常最好清除聊天或打开新的聊天选项卡,您可以通过键入 /clear 来清除聊天。
现在我们知道如何询问特定文件了。让我们看看 Amazon Q 如何开始理解应用程序功能。
在不清除聊天的情况下,让我们打开位于 src/main/java/com/example/qwords/controller/ 目录下的 GameController.java 文件
同样我们在 Chat 页面中进行对话,对话内容如下:
What does this GameController class do?
利用 Amazon Q 梳理代码片段
除了了解 IDE 中的当前文件之外,还可以要求 Amazon Q 使用选定的代码片段。有两种方法可以做到这一点:
- 向 Q Chat 询问有关选中的代码,然后在 Chat 页面中输入以下内容:
explain what the selected code does
- 我们还可以在选择代码块后,使用右键单击上下文菜单来解释代码
Amazon Q → explain
。
另外,我们还可以要求 Amazon Q 为选定的代码片段添加注释。可以使用 Amazon Q inline chat 功能来做到这一点:
- 先选中要增加 comments 的代码片段,按⌘+I (Mac)或 Ctrl+I (Windows),然后在输入框中对选中的代码进行提问,例如:
add comments to this function
- 接受 Amazon Q Developer 给出的 Comments 建议
利用 Amazon Q 生成项目摘要
为了快速了解项目全貌,我们还可以针对相关希望梳理的文件利用 Amazon Q 进行摘要生成,首先打开位于项目根目录 README.md 的文件。
现在,要求 Amazon Q chat 为 “Getting Started” 部分生成格式化的 Markdown 。我们将在 README.md 的 “Getting Started” 部分应描述 pom.xml 文件的结构、GameController、Word class 的用途和方法,以及游戏逻辑所在位置的摘要。
- GameController.java
- Word.java
- pom.xml
Can you create introductory content in Markdown format and help me insert it into a [readme.md](http://readme.md/) file? Please use code snippets to wrap all the content:Structure of pom.xml fileThe purpose and methods/functions of GameController classThe purpose and methods/functions of Word classOverview of the Position of Game Logic
基于 Amazon Q 修复程序逻辑问题,实现正确运行效果
启动 Q-Words 应用
在 VS Code IDE 的 终端 中,执行下面命令:
mvn verify
代码打包后运行 jar 文件。默认情况下,应用程序将绑定到 TCP 端口 8090,执行下面命令启动项目。
java -jar target/QWordsService-0.0.1.jar
运行上述命令后,默认情况下,应用程序将绑定到 TCP 端口 8090,VSCode 服务器将代理此端口,因此您可以在本地访问应用程序。运行上述命令后,您应该会看到一个弹出窗口,询问您是否要在浏览器中打开应用程序。选择 Open in Browser。如果弹窗已经关闭,您可以通过 TERMINAL 窗口右侧 PORTS 里找到应用主页。
这个游戏的目标是猜测一个单词,并使用每次尝试的响应信息来正确猜测正确的答案。在游戏重置之前您将有 5 次尝试机会。
要开始游戏,请输入您的名字并开始第一个猜测。
玩游戏几次后,您应该注意到这个词总是相同的,并且猜测 animal 这个词总是会成功。
使用 Amazon Q 识别并修复错误
首先我们在项目中的 controller 目录中找到 GameController.java 并打开,把整个文件的内容选中然后先按 ⌘+I (Mac)或 Ctrl+I (Windows),然后在输入框中对选中的代码进行提问,从而了解如何为游戏选择单词,具体添加的提示如下:
How is the word selected for the game?
从 services 目录中打开 WordSelectionService.java 并将其发送到 Amazon Q ,就像在上一步骤中所做的那样,看看是否可以确定如何选择单词并将其返回到控制器。同样我们为代码增加相关的描述:
How does the WordSelectionService select and return a word for the GameController?
现在我们已经确定了游戏的单词选择涉及哪个代码路径,让我们使用 Amazon Q 通过 WordList.getRandomWord 函数修复逻辑错误。打开 repository 目录中的 WordList.java 并找到 getRandomWord 函数。
我们看到它只从构造函数中定义的数组列表返回 index:0
我们选中这个函数,然后先按⌘+I (Mac)或 Ctrl+I (Windows),然后在输入框中对选中的代码进行提问,并增加以下描述:
My words are not selected in a random fashion. Can you troubleshoot and fix the code?
如上图所示,Amazon Q 应该建议使用 Math.random() 实现。在 Amazon Q 的响应中,有一个在光标处插入选项,单击此选项以替换原始方法。如果这是我们选择这个,我们还需要将 import java.lang.Math; 加入到文件头部中。
文件代码如下所示:
package com.example.qwords.repository;
import java.util.ArrayList;
import java.util.Random;public class WordList {private ArrayList<String> wordlist;private Random random;public WordList() {this.wordlist = new ArrayList<String>();this.wordlist.add("animal"); this.wordlist.add("bakery");this.wordlist.add("cracks");this.random = new Random();}public String getRandomWord() {int randomIndex = this.random.nextInt(this.wordlist.size());return this.wordlist.get(randomIndex);}}
在对代码进行任何更改后,我们需要重建并重新启动应用程序以测试更改
mvn -U clean verify
java -jar target/QWordsService-0.0.1.jar
这个时候我们在去猜单词的时候会发现,已经不总是 animal 了
总结
在此任务中,您使用 Amazon Q Developer 启动了安全扫描。安全扫描发现问题,识别出导致这些问题的源代码,并提供相关的代码建议来解决该问题。
基于 Amazon Q 项目review、单元测试、文档生成
使用 Amazon Q 进行代码审核(项目全局与细节代码)
对 Review 后的代码生成单元测试
在代码审查完成并进行必要的修改后,下一步是为修改后的代码生成单元测试,以确保代码的正确性和稳定性。
package com.example.qwords.controller;import com.example.qwords.model.GameStatus;
import com.example.qwords.service.WordSelectionService;
import org.junit.jupiter.api.Test;
import org.springframework.ui.Model;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.RequestParam;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;public class GameControllerTest {/*** Tests the behavior of the index method when the user parameter is an empty string.* This scenario should still process the request but log an empty user.*/@Testpublic void test_index_empty_user_parameter() {GameController controller = new GameController();Model model = mock(Model.class);String result = controller.index("", model);assertEquals("game", result);verify(model, times(1)).addAttribute(eq("message"), eq("Make your first guess!"));}/*** Test case for the index method of GameController.* This test verifies that the index method correctly initializes the game,* sets the appropriate attributes in the model, and returns the "game" view.*/@Testpublic void test_index_initializes_game_and_returns_game_view() {// ArrangeGameController controller = new GameController();String user = "testUser";Model model = mock(Model.class);WordSelectionService mockWordBank = mock(WordSelectionService.class);when(mockWordBank.getWord()).thenReturn("testword");// ActString result = controller.index(user, model);// AssertassertEquals("game", result);verify(model).addAttribute("word", "testword");verify(model).addAttribute("message", "Make your first guess!");verify(model).addAttribute("attempts", 0);verify(model).addAttribute("result", "");verify(model).addAttribute("status", GameStatus.INPROGRESS);}/*** Tests the behavior of the index method when the user parameter is missing.* This scenario should result in a MissingServletRequestParameterException.*/@Testpublic void test_index_missing_user_parameter() {GameController controller = new GameController();Model model = mock(Model.class);assertThrows(MissingServletRequestParameterException.class, () -> {controller.index(null, model);});}/*** Tests the behavior of the index method when the Model object is null.* This scenario should result in a NullPointerException.*/@Testpublic void test_index_null_model() {GameController controller = new GameController();assertThrows(NullPointerException.class, () -> {controller.index("testUser", null);});}/*** Tests the behavior of the index method when the WordSelectionService returns null.* This scenario simulates a failure in word selection and should result in a NullPointerException.*/@Testpublic void test_index_null_word_selection() {GameController controller = new GameController();Model model = mock(Model.class);// Use reflection to set wordBank to nulltry {java.lang.reflect.Field field = GameController.class.getDeclaredField("wordBank");field.setAccessible(true);field.set(controller, null);} catch (Exception e) {fail("Failed to set wordBank to null");}assertThrows(NullPointerException.class, () -> {controller.index("testUser", model);});}}
运行单元测试
在终端中执行以下命令以运行所有单元测试:
mvn test
实验链接
定义开发新范式 —— Amazon Q Developer 的极简开发工坊
✨活动上新
【活动邀请·上海】re:Invent reCap 全国巡演上海场:云端新春-引领技术新浪潮 |GenAI 斜杠计划第三期
2025 全球开发者先锋大会将于2月21日至23日在上海徐汇西岸和漕河泾举行,本次大会以“模塑全球 无限可能”为主题,汇聚全球开发者,共探大模型产业化解决方案与创新应用。
作为大会的重要分会场,我们特别策划了 2025 年首场线下技术分享会,聚焦亚马逊云科技 re:Invent 2024 的关键技术发布,并结合 DeepSeek 模型的智能能力,深入解读亚马逊云最新技术的核心价值与落地应用。现场将有亚马逊云技术专家带来前沿解析与案例分享,帮助开发者掌握新技术、提升项目创新力。
欢迎加入本次分享会,与业内专家深度交流,共同探索亚马逊云与大模型的无限可能!
