likes
comments
collection
share

AI编码工具:JAVA朋友发的简单需求引起的国内AI血战

作者站长头像
站长
· 阅读数 6

前言

国内IT行业面临裁员压力,但AI技术的兴起为企业带来了转型机遇。AI可以提高生产效率,降低成本,并助力企业做出更精准的决策。特别是在编程领域,AI编码工具能够提升开发速度和代码质量,帮助程序员高效完成复杂任务。尽管AI可能替代某些岗位,但它也为技术人才创造了新的职业机会,要求他们不断学习新技能以适应变化。

哼哈:文章结尾有彩蛋!。。。ojbk!

需求背景

2024年4月22日清晨,滴答滴答滴哒哒哒。。。滴答滴答滴哒哒哒。。。滴答滴答滴哒哒哒。。。键盘声不断,勤劳的小蜜蜂开始上班啦。突然一位重量级9年JAVA资深大佬发了一段简单的需求给我简单探讨下需求是否清晰?基于平时有使用AI工具的习惯,于是乎用了几款AI工具做下效果测试。需求如下:

@Override 
public String getSuppliercode(string orderNo, string productId, string channelId){ 
 // 根据orderNo查询多个List结果 
 //如不存记录,suppliercode = orderNo
 //如存在productId和channelId都相同的记录,则返回此suppliercode 
 //如不存在productId和channelId都相同的记录,则返回uuid
}
以上需求表对象为OrderDetail,请用Mybatis Plus补充以上解释代码,使用LambdaQueryWrapper查询数据,另外注意代码严谨需要预判OrderDetail获取属性时是否需要判空

国内AI PK对象

  1. 讯飞星火(科大讯飞):文本对话
  2. 通义灵码(阿里巴巴):文本对话,支持开发工具idea、vscode插件使用
  3. 文心一言(百度):文本对话
  4. CodeGeeX(智谱华章科技):文本对话,支持开发工具idea、vscode插件使用

AI编码实现效果对比

直接发送以上需求描述给AI生成代码,代码效果如下:

一、讯飞星火

效果描述:代码相对严谨,使用常规写法实现,但是没有提前判断传参是否为空

@Autowired  
private OrderDetailMapper orderDetailMapper; 

@Override
public String getSuppliercode(String orderNo, String productId, String channelId) {
    // 根据orderNo查询多个List结果
    LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(OrderDetail::getOrderNo, orderNo);
    List<OrderDetail> orderDetailList = orderDetailMapper.selectList(queryWrapper);

    // 如果不存在记录,返回orderNo作为suppliercode
    if (orderDetailList.isEmpty()) {
        return orderNo;
    }

    // 遍历查询结果,查找是否存在productId和channelId都相同的记录
    for (OrderDetail orderDetail : orderDetailList) {
        if (orderDetail.getProductId() != null && orderDetail.getChannelId() != null) {
            if (orderDetail.getProductId().equals(productId) && orderDetail.getChannelId().equals(channelId)) {
                return orderDetail.getSuppliercode();
            }
        }
    }

    // 如果不存在productId和channelId都相同的记录,则返回uuid
    return UUID.randomUUID().toString();
}

二、通义灵码

效果描述:代码相对严谨,使用常规写法实现,且有提前判断传参是否为空

@Autowired  
private OrderDetailMapper orderDetailMapper; 

@Override
public String getSuppliercode(String orderNo, String productId, String channelId) {

    // 预判输入参数是否为空
    if (StringUtils.isAnyBlank(orderNo, productId, channelId)) {
        throw new IllegalArgumentException("orderNo, productId, and channelId must not be blank");
    }

    // 根据orderNo查询多个OrderDetail记录
    LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(OrderDetail::getOrderNo, orderNo);

    List<OrderDetail> orderDetailList = orderDetailMapper.selectList(queryWrapper);

    // 处理查询结果
    if (orderDetailList.isEmpty()) {
        return orderNo; // 如不存在记录,返回orderNo作为suppliercode
    } else {
        for (OrderDetail orderDetail : orderDetailList) {
            if (StringUtils.equals(orderDetail.getProductId(), productId)
                    && StringUtils.equals(orderDetail.getChannelId(), channelId)) {
                return orderDetail.getSuppliercode(); // 如存在productId和channelId都相同的记录,返回此suppliercode
            }
        }
    }

    // 如不存在productId和channelId都相同的记录,生成并返回UUID作为suppliercode
    return UUID.randomUUID().toString();
}

三、文心一言

效果描述:

  1. 代码相对严谨,使用常规写法实现,且使用JDK1.8 Stream API写法
  2. 存在部分代码不严谨:没有提前判断传参是否为空
  3. 存在需求理解误差1:orderDetail.getProductId().equals(productId) && orderDetail.getChannelId().equals(channelId)前置参数没有判空,可能导致空指针异常;
  4. 存在需求理解误差2: 以下原需求是直接返回匹配成功的matchedOrderDetail.getSuppliercode(),预判suppliercode属性是否需要判空则指的是3对应空指针问题

// 预判suppliercode属性是否需要判空,如果suppliercode字段在数据库中允许为null,则需要进行判空 return matchedOrderDetail.getSuppliercode() != null ? matchedOrderDetail.getSuppliercode() : orderNo; // 或者选择其他默认值


@Autowired  
private OrderDetailMapper orderDetailMapper; 

public String getSuppliercode(String orderNo, String productId, String channelId) {  
        // 创建LambdaQueryWrapper进行条件查询  
        LambdaQueryWrapper<OrderDetail> queryWrapper = Wrappers.<OrderDetail>lambdaQuery()  
                .eq(OrderDetail::getOrderNo, orderNo); // 根据orderNo查询  
  
        // 查询满足条件的所有记录  
        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(queryWrapper);  
  
        // 如果没有记录,返回orderNo作为suppliercode  
        if (orderDetailList == null || orderDetailList.isEmpty()) {  
            return orderNo;  
        }  
  
        // 尝试找到productId和channelId都相同的记录  
        Optional<OrderDetail> optionalOrderDetail = orderDetailList.stream()  
                .filter(orderDetail -> orderDetail.getProductId().equals(productId) && orderDetail.getChannelId().equals(channelId))  
                .findFirst();  
  
        // 如果找到了符合条件的记录,返回其suppliercode  
        if (optionalOrderDetail.isPresent()) {  
            OrderDetail matchedOrderDetail = optionalOrderDetail.get();  
            // 预判suppliercode属性是否需要判空,如果suppliercode字段在数据库中允许为null,则需要进行判空  
            return matchedOrderDetail.getSuppliercode() != null ? matchedOrderDetail.getSuppliercode() : orderNo; // 或者选择其他默认值  
        }  
  
        // 如果没有找到符合条件的记录,生成UUID并返回  
        return UUID.randomUUID().toString();  
    } 

四、CodeGeeX

效果描述:

  1. 代码不够严谨,有明显bug;
  2. bug1:查询时多带了productId、channelId作为查询条件;
  3. bug2:getList(queryWrapper)没有输出这个方法的实现;
  4. bug3:如存在productId和channelId都相同的记录,则返回此suppliercode,判断条件不准确;
  5. 访问多次后出现网络中断情况,体验感不佳
@Override  
public String getSuppliercode(String orderNo, String warehouseld, String binld) {  
    // 根据orderNo查询多个List结果  
    LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();  
    queryWrapper.eq(OrderDetail::getOrderNo, orderNo);  
    queryWrapper.eq(OrderDetail::getProductId, productId);  
    queryWrapper.eq(OrderDetail::getChannelId, channelId);  
    List<OrderDetail> orderDetailList = getList(queryWrapper);  

    // 如不存在记录,suppliercode=orderNo  
    if (orderDetailList.isEmpty()) {  
        return orderNo;  
    }  

    // 如存在productId和channelId都相同的记录,则返回此suppliercode  
    for (OrderDetail orderDetail : orderDetailList) {  
     if (orderDetail.getProductId() != null && orderDetail.getChannelId() != null) { 
            return orderDetail.getSuppliercode();  
        }  
    }  

    // 如不存在warehouselD和binld都相同的记录,则返回uuid  
    return UUID.randomUUID().toString();  
}

效果总结:

本人目前使用通义灵码+讯飞星火多一些

  1. 通义灵码:效果最佳,需求理解到位,且代码有做前置校验,较为严谨
  2. 讯飞星火:效果较好,需求理解到位,整体较为不错
  3. 文心一言:效果一般,需求理解有误差
  4. CodeGeeX:效果较差,需求理解有误差,且有明显bug,代码无法使用,且使用调用失败率较高

补充:

  1. 以上测试的都是本人经常使用的AI工具,国内的AI工具能力及准确性良莠不齐,需要靠自己去不断测试摸索;
  2. AI工具使用效果除了跟AI工具自身模型算法能力有关,还与需求者的需求描述是否精准有关,日常工作中我们需要提高自身语言描述能力及需求输出能力,以适应以后AI盛行的市场环境,提高效率及实现创意思路;
  3. 国外penAI GPT、New Bing、GitHub Copilot、Google Colab Copilot等AI工具能力也特别强,有兴趣可以多测试、多学习。

彩蛋:

当当。。当当。。。彩蛋来啦,AI工具集在此,赶紧收藏。

biu...biu...biu...biu,觉得文章对您有帮助的话一键三连,点赞点拨关注点评一下呗!^_^

AI工具集

AI编码工具:JAVA朋友发的简单需求引起的国内AI血战