写点什么

谁说 AI 编程工具缺乏记忆和联想能力,简单琐碎的需求完全可以交给它

  • 2023-08-23
    北京
  • 本文字数:5298 字

    阅读完需:约 17 分钟

谁说 AI 编程工具缺乏记忆和联想能力,简单琐碎的需求完全可以交给它

活动推荐: #生成式 AI 先锋开发者集结令 #

免费体验编程神器,丰厚大奖等你来拿!👉🏻👉🏻https://jinshuju.net/f/rVuKYa


今年算是 AI 正式破圈的一年,无数的工具,产品横空出世。无论在面向企业的大语言模型,还是帮助个人的 AI 工具,数不胜数。其中关于 AI 编程助手领域,近年来也涌现了很多不错的产品,例如 Copilot, Cursor, 还是我们今天要体验的 CodeWhisperer。已经在潜移默化中改变了程序员们的生产和解决问题的方式,传统解决问题往往依靠的是谷歌等搜索引擎,找到对应的官网和知名的论坛查找问题。而如今,我们仅仅依靠 AI 编程助手就能解决很多问题。


回到 CodeWhisperer 上来,它的出生还是带着许多光环的。首先来自著名的大厂 Amazon, 他们在 AI 领域有足够多的积累,在面向开发者方面有足够多的经验和产品用户体验来反馈用户感受,不断迭代相关产品,而且还有一个相当强大的优势,借助亚马逊云的力量,能够将 AI 和云打通,这在当前云原生时代是必不可少的能力。


目标及前期准备


先给大家讲讲今天我们希望实现的目标,基于 Spring Boot 框架,简单实现用户登陆,。我们使用的是 IntelliJ 开发工具,选用 Maven 进行管理依赖管理,用到的依赖如下。


  • Web

  • JPA

  • H2


我们首先尝试安装 CodeWhisperer 插件,在 Plugins 中搜索 AWS Toolkit 下载即可。



下载完成后绑定自己的亚马逊账号即可开始使用,默认开启自动建议。


项目结构如图所示


pom.xml 文件如下

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">	<modelVersion>4.0.0</modelVersion>	<parent>		<groupId>org.springframework.boot</groupId>		<artifactId>spring-boot-starter-parent</artifactId>		<version>3.1.0</version>		<relativePath/> <!-- lookup parent from repository -->	</parent>	<groupId>com.example</groupId>	<artifactId>demo</artifactId>	<version>0.0.1-SNAPSHOT</version>	<name>demo</name>	<description>demo</description>	<properties>		<java.version>17</java.version>	</properties>	<dependencies>		<dependency>			<groupId>org.springframework.boot</groupId>			<artifactId>spring-boot-starter-data-jpa</artifactId>		</dependency>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</project>
复制代码


开始


  • 健康检查

我们先实现一个最简单的 Controller,请求 /ping 返回 pong 即可。


package com.example.demo.controller;
import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;
@Controllerpublic class PingController {
@RequestMapping("/ping") public @ResponseBody String greeting() { return "pong"; }
}
复制代码


测试用例是检验代码正确性必不可少的一环,我们来写个简单的测试用例。这时 CodeWhisperer 已经开始展示它的实力了,只是写了一行 @Test 注解,它将我们想要做的测试代码完整提示出来。



下面是完整的测试代码。

package com.example.demo;
import com.example.demo.controller.PingController;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@AutoConfigureMockMvc@WebMvcTest(PingController.class)public class TestWebApplication { @Autowired private MockMvc mockMvc;
@Test public void shouldReturnDefaultMessage() throws Exception { this.mockMvc.perform(get("/ping")).andDo(print()).andExpect(status().isOk()) .andExpect(content().string("pong")); }}
复制代码


运行一下测试用例,很顺利的通过🎉。



  • 用户类设计


我们来定一个 User 模型,发现它在 Table To Class 的实现中具备一定的表设计能力,以及字段关联联想,约束设计能力。




能推测我想要的表字段,索引约束建议。这对于新手来说是莫大的帮助,想象有一位功力深厚的同伴在旁指点你设计表结构,那么表结构的设计就能相对合理一些。

package com.example.demo.model;

import jakarta.persistence.*;import lombok.AllArgsConstructor;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;import org.springframework.stereotype.Indexed;
@Entity@Getter@Setter@AllArgsConstructor@NoArgsConstructor@Table(name = "game_users")public class User { @Id private Long id; @Column(unique = true, nullable = false) private String username; @Column(nullable = false, length = 64) private String password; @Column(unique = true, nullable = false) private String email;}
复制代码


  • DAO 层实现


这时我灵光一现,根据官网的 GIF 图展示,可以通过注释进行代码推断,那好,DAO 层的实现就交给它啦。


哎哟,不错哦,根据我上面想要根据邮箱查询用户的注视,它已经给出了相应的提示,让我们再考考它,注释中进行多个方法的描述。



挺聪明呀,也很顺利的实现了。


package com.example.demo.dao;
import com.example.demo.model.User;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repositorypublic interface UserDao extends JpaRepository<User, Long> { // function to implement find user by email Optional<User> findByEmail(String email);
Optional<User> findByUsername(String username);
// two function to implement find user by id or email Optional<User> findById(Long id); Optional<User> findByEmailIgnoreCase(String email);
// function to implement check user is existed Boolean existsByEmail(String email);
}
复制代码


看来以后 CRUDDAO 层实现可以交给它来完成啦。我们希望能够预先插入一些数据便于测试,琐碎的日志测试对它来说轻轻松松。



package com.example.demo;
import com.example.demo.dao.UserDao;import com.example.demo.model.User;import org.slf4j.Logger;import org.springframework.boot.CommandLineRunner;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;
@Configurationclass LoadDatabase { public static final Logger log = org.slf4j.LoggerFactory.getLogger(LoadDatabase.class);
// this is Bean is loaded once in the application context // it is used to load the data into the database @Bean public CommandLineRunner initDatabase(UserDao dao) { return args -> { log.info("Preloading " + dao.save(new User(1L, "test1", "111111", "abc@gmail.com"))); log.info("Preloading " + dao.save(new User(2L, "test2", "222222", "123@gmail.com"))); }; }}
复制代码


  • Service 层实现


轮到 Service 层了,让我们看看它的表现,在这里我们简单的根据用户名查询用户,返回对应的数据即可。当我方法签名写一半时,它给我的建议让我停下继续敲击的手指,因为基本符合我的预期,而且具备一定的记忆联想能力,在 DAO 层定义的 Optional<User>,这里也能找到对应的方法进行处理。



package com.example.demo.service;
import com.example.demo.dao.UserDao;import com.example.demo.model.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;
import java.util.Optional;
@Servicepublic class UserDetailServiceImpl { private final UserDao userdao;
@Autowired public UserDetailServiceImpl(UserDao userdao) { this.userdao = userdao; }
public User getUserByUsername(String username) throws Exception { Optional<User> user = userdao.findByUsername(username); if (user.isPresent()) { return user.get(); } else { throw new Exception("User not found"); } }}
复制代码


  • Controller 层实现


最后我们来实现最外层入口,简单的进行相关业务校验,用户名是否为空,密码是否正确,在这里用于演示。



用户不存在相关处理,密码正确性验证,基本符合我们的要求。


package com.example.demo.controller;
import com.example.demo.model.User;import com.example.demo.service.UserDetailServiceImpl;import org.apache.coyote.Response;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.*;
@RestController@RequestMapping("/api/auth")public class UserController { private final UserDetailServiceImpl userDetailService;
@Autowired public UserController(UserDetailServiceImpl userDetailService) { this.userDetailService = userDetailService; }
@PostMapping("/login") public ResponseEntity<?> login(@RequestBody User user) { try { if (user.getUsername().isEmpty()) { return ResponseEntity.badRequest().body("user name is empty"); }
User res; res = userDetailService.getUserByUsername(user.getUsername()); if (res == null) { return ResponseEntity.badRequest().body("user not found"); }
if (res.getPassword().equals(user.getPassword())) { return ResponseEntity.ok(res); } return new ResponseEntity<>("user password invalid", HttpStatus.BAD_REQUEST); } catch (Exception e) { return ResponseEntity.notFound().build(); } }}
复制代码


最后我们来测试一下,格式错误和用户密码错误的情况。



与预期一致,撒花。

总结


CodeWhisperer 就我今天的使用而言,还是有些出乎我的意料,之前的一些 AI 编程工具并不具备记忆和联想能力,今天 CodeWhisperer 展示的记忆联想效果不错,并且具备一定的表结构设计能力,一些简单的测试用例完成度也不错,我想未来一些简单琐碎的需求,测试用例也可以交给它了。但是今天在体验的过程中还是发现了一些不足,插件 UI 会出现挡住建议的情况,这样我需要再次触发建议才行,目前阶段可以使用它来投入生产,在一些复杂的场景还是需要谨慎,会出现胡言乱语的情况,跟上下文关联性不强的建议。


当然,这些问题相信随着模型的数据量级和质量不断优化能够慢慢解决🎉。


版权声明: 本文为 InfoQ 作者【天黑黑】的原创文章。

原文链接:【https://xie.infoq.cn/article/179127e04fff483aac667444d】。文章转载请联系作者。

公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2023-08-23 10:563909

评论

发布
暂无评论
发现更多内容

几个非常有用的 Flutter 技巧,你可以立即使用!

坚果

6月月更

Linux开发_Makefile规则与Shell脚本语言

DS小龙哥

6月月更

企业知识管理就是信息化建设吗?

小炮

云原生技术 - 如何从代码到制作并发布一个 Helm 包?

孙健波

云原生 Helm

Paper Reading 预告 | Volcano-An Extensible and Parallel Query Evaluation System(众神推荐的 Paper 下载合集)

TiDB 社区干货传送门

TiDB Paper Reading

测试流程如何落地?

老张

软件测试 质量保障

MySQL索引

龙空白白

索引 MySQL InnoDB

【直播回顾】Hello HarmonyOS系列应用篇完美收官!

HarmonyOS开发者

HarmonyOS

6大优势、2种类型,一文吃透动态应用安全测试(DAST)

SEAL安全

DevOps 网络安全 DevSecOps 软件安全

用 Golang 重写 rsync(3):C里面的谜之指针

百家饭隐私计算平台创业者

c

JavaScript异步函数async/await

大熊G

JavaScript 前端 6月月更

使用 Prometheus 监控 SAP ABAP 应用程序

Jerry Wang

云计算 Kubernetes 云原生 abap 6月月更

Vone观点说|用DAO打造人类协作新形态

旺链科技

区块链 产业区块链 自组织协作

摆脱五彩斑斓的黑,成为七彩程序员!

禅道项目管理

面试突击57:聚簇索引=主键索引吗?

王磊

Java MySQL 面试

测试开发【Mock平台】05开发:项目管理(一)后端接口

MegaQi

测试平台开发教程 6月月更 测试技术干货

InfoQ 极客传媒 15 周年庆征文|uni-app 路由传参参数丢失问题解决方案探究

No Silver Bullet

前端 6月月更 InfoQ极客传媒15周年庆 路由传参

四次蝉联中国容器云市场TOP5!为应用赋能

BoCloud博云

云原生 容器技术 容器云 博云

spring4.1.8扩展实战之五:改变bean的定义(BeanFactoryPostProcessor接口)

程序员欣宸

Java spring Spring Framework 6月月更

实战 | Kibana面板使用

写程序的小王叔叔

Kibana ELK Stack 6月月更

助力直播平台源码脱颖而出,要完成哪些关键功能?

开源直播系统源码

软件开发 直播源码

【Python技能树共建】pyspider框架的使用

梦想橡皮擦

Python 6月月更

手把手教学直播:如何提交 PR 成为龙蜥社区贡献者? | 第 23 期

OpenAnolis小助手

开源 PR 龙蜥社区 龙蜥大讲堂 社区贡献

C#入门系列(十六) -- 类及其成员介绍

陈言必行

C# 6月月更

纯CSS 毛玻璃效果 💎

德育处主任

CSS 纯CSS 6月月更

NFT链游系统开发|NFT卡牌盲盒游戏

薇電13242772558

NFT 链游

一个 Angular 程序员两年多的远程办公经验分享 | 社区征文

Jerry Wang

程序员 远程办公 Slack 6月月更 初夏征文

Django 中的视图 | Python

海拥(haiyong.site)

Python django 6月月更

docker和docker compose安装使用、入门进阶案例

偶尔善良

Docker docker-co

大数据培训Flink 简介与认知

@零度

flink 大数据开发

安全服务厂商安全狗加入龙蜥社区

OpenAnolis小助手

开源 网络安全 龙蜥社区 龙腾计划 安全狗

谁说 AI 编程工具缺乏记忆和联想能力,简单琐碎的需求完全可以交给它_亚马逊云科技_天黑黑_InfoQ精选文章