纯技术

关于 ChatGPT 辅助代码质量的那些事

最近 chatgpt 大火,加上最近几日使用chatgpt辅助阅读一些开源项目的源码参考此文章,体验很好,所以葫芦尝试下使用chatgpt来发现代码中的问题,提高代码质量 代码段一 下面是葫芦以前写极验sdk中的一段代码,功能很简单,就是一…

7 分钟阅读
精选技术记录
持续迭代更新
Share

背景

最近 chatgpt 大火,加上最近几日使用chatgpt辅助阅读一些开源项目的源码参考此文章,体验很好,所以葫芦尝试下使用chatgpt来发现代码中的问题,提高代码质量

操作一波

  • 代码段一

下面是葫芦以前写极验sdk中的一段代码,功能很简单,就是一个http.Get请求

/**
 * 发送GET请求,获取服务器返回结果
 */
func (g *GeeTestLib) httpGet(ctx context.Context, getURL string, params map[string]string) (string, error) {
   q := url.Values{}
   for key, val := range params {
      q.Add(key, val)
   }
   req, err := http.NewRequest(http.MethodGet, getURL, nil)
   if err != nil {
      return "", errors.New("NewRequest fail")
   }
   req.URL.RawQuery = q.Encode()
   res, err := g.Client.Do(ctx, req)
   if err != nil {
      return "", err
   }
   defer res.Body.Close()
   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      return "", err
   }
   if res.StatusCode == 200 {
      return string(body), nil
   }
   return "", nil
}

直接看下面其实是没什么问题的,下面上AI

这段代码没有显式地设置请求超时时间,可能会导致请求一直处于阻塞状态。可以在http.Client中设置超时时间来避免这种情况的发生。修改后的代码如下:

func (g *GeeTestLib) httpGet(ctx context.Context, getURL string, params map[string]string) (string, error) {
    q := url.Values{}
    for key, val := range params {
        q.Add(key, val)
    }
    req, err := http.NewRequest(http.MethodGet, getURL, nil)
    if err != nil {
        return "", errors.New("NewRequest fail")
    }
    req.URL.RawQuery = q.Encode()

    // 设置超时时间为5秒
    timeout := time.Duration(5 * time.Second)
    g.Client.Timeout = timeout

    res, err := g.Client.Do(ctx, req)
    if err != nil {
        return "", err
    }
    defer res.Body.Close()
    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return "", err
    }
    if res.StatusCode == 200 {
        return string(body), nil
    }
    return "", nil
}

是的了,chatgpt给我的代码提出需要增加超时时间的改进,默认设置为5s, 这个时间也是比较合理的,但葫芦仍不够满足

继续提问:还有什么其他的问题吗 或者提高可读性的方法

image.png

是的了,chatgpt 从可读性方面提出了建议,并给出了改进后的代码。不愧是新晋的葫芦代码小助手

  • 代码段二
/**
 * md5 加密
 */
func md5Encode(value string) string {
   h := md5.New()
   h.Write([]byte(value))
   return fmt.Sprintf("%x", h.Sum(nil))
}

说实话,这段代码,葫芦自己都认为没什么问题,毕竟就三行代码,简单的md5加密

上AI

这段代码没有问题,只是可以对其增加错误处理和参数校验。根据之前的建议,以下是修改建议:

  1. 增加错误处理
func md5Encode(value string) (string, error) {
    if value == "" {
        return "", errors.New("value is empty")
    }
    h := md5.New()
    if _, err := h.Write([]byte(value)); err != nil {
        return "", err
    }
    return fmt.Sprintf("%x", h.Sum(nil)), nil
}

  1. 增加参数校验
func md5Encode(value string) (string, error) {
    if value == "" {
        return "", errors.New("value is empty")
    }
    // 校验是否包含敏感信息
    if sensitive.Contains(value) {
        return "", errors.New("value contains sensitive information")
    }
    h := md5.New()
    if _, err := h.Write([]byte(value)); err != nil {
        return "", err
    }
    return fmt.Sprintf("%x", h.Sum(nil)), nil
}

如果需要实现流式读取,可以将 value 参数改为 io.Reader 类型:

func md5Encode(reader io.Reader) (string, error) {
    h := md5.New()
    if _, err := io.Copy(h, reader); err != nil {
        return "", err
    }
    return fmt.Sprintf("%x", h.Sum(nil)), nil
}

其中 io.Copy 函数实现了从 io.Reader 中读取数据并写入到 io.Writer 中的操作。

如果需要使用更安全的哈希算法,可以采用 SHA-256 或 SHA-512 等算法,例如:

func sha512Encode(value string) (string, error) {
    if value == "" {
        return "", errors.New("value is empty")
    }
    h := sha512.New()
    if _, err := h.Write([]byte(value)); err != nil {
        return "", err
    }
    return fmt.Sprintf("%x", h.Sum(nil)), nil
}

虽然没有什么问题,但chatgpt给出了更完善的方案,并给出了相应的修改后的代码

总结

牛Plus

chatgpt的出现让葫芦有危机感了,从之前辅助阅读源码,到提高代码质量这,使用下来都很便捷,正确性极高,这极有可能会淘汰大批的初中级程序员。坚持学习,保持竞争力,避免被取代


本文同步自掘金

如果发现内容有误或需要更新,请访问掘金原文进行查看。

Share

如果这类内容对你有帮助

这里放了一个阿里云 AIGC 活动入口。如果你本来就有相关需求,可以顺手了解;如果产生推广收益,我会优先用于支付服务器、域名和网站维护费用。

看看阿里云 AIGC 活动

相关文章

纯技术2025年8月21日

为什么有的人学了很多年的编程,还是只会【增删改查】?

为什么你写了多年代码,技术栈还停留在"增删改查"? 我们不妨从一个常见的开发者画像开始:工作数年,日常任务是理解需求、实现业务逻辑、提供数据接口。在熟悉的框架下,每天熟练地进行着数据库的增、删、改、查(CURD)操作,周而复始。 这套流程看…

纯技术2023年12月21日

Golang-常用限流算法实现

常用的限流算法有一下4中实现方式: 令牌桶 漏桶 计数器 滑动窗口 令牌桶以恒定的速度向桶里加入令牌,桶满了则不再加入令牌。当服务收到请求时尝试从桶中取出一个令牌,如果可以获取到令牌,则继续执行后续的业务,否则返回超限错误码或对应的错误页面…

纯技术2023年12月21日

go-zero 使用 Consul 作为注册中心

go-zero 默认使用etcd作为注册中心,如果我们的业务使用的consul, 可以使用zero-contrib中的consul包进行替代 文件位置:ect/**.yaml 增加consul配置 服务启动后即可在conusl/ui上查看到…