高质量编程与性能调优实战 |青训营

79 阅读6分钟

在学习完对应字节后端基础课程后,我从三方面进行相对总结地归纳一下学习内容

1. 编码规范与准则

  • 代码格式

    使用gofmt格式化代码,使用goimports工具进行包导入管理(可以自动导入包,去除不适用的包,并按字典序排列,节省时间)

  • 注释

    • 注释赋予代码新生命
    • 注释应该提供代码未表达出的上下文信息
  • 命名规范

    • 核心目标是降低阅读理解代码的成本
    • 重点考虑上下文信息,设计简洁清晰的名称
  • 控制流程

    • 线性原理,处理逻辑尽量走直线,避免复杂的嵌套分支
    • 正常流程代码沿着屏幕向下移动
    • 提升代码可维护性和可读性
    • 故障问题多出在复杂的循环语句和条件语句中
  • 错误和异常处理

    • error尽可能提供简明的上下文信息链,方便定位问题
    • panic用于真正异常的情况
    • recover生效范围,在当前goroutine的被defer函数中生效
  • 常见细节罗列

    • 用完整的句子写注释方便自动化展示,句子开头为所注释的东西,多句的话第一句作为摘要

    • 不要引用其他包的内存(防御式编程)

    • 使用crypto/rand替代math/rand,更加安全

    • 错误信息不大写,不要句号,因为错误信息一般都被包括在上下文中

    • 接口放在使用方的package中而不是实现方的package,简单来说在接口只有在被使用的地方才定义

    • 行的长度应该根据语义而定,不要死守80字符的“规矩”,现在的显示设备已经很先进了,但是一样要避免过长的行

    • go中返回值可以有名字,但是要注意不要添加冗余的名字,例如err error就毫无意义,如果有多个同类型返回值加个名字会好很多

    • 不要用this,me,self给某个类型方法的接收方对象命名(就像这样func (this Hello) hello()

小结:这些原理规范,每一门语言都有每一门语言的特色,但大体相通,故在理解时要理性地理解,而非强行记忆等,同时去遵从大厂基本原则,形成合理规范的代码编码体系

2.性能优化建议

  • 使用Benchmark来衡量性能表现

  • Slice预分配内存以减少内存申请,提高运行速度

  • Slice使用copy替代re-slice来减少内存占用,节省内存空间

  • Map预分配内存

  • 字符串处理使用strings.Builder

  • 空结构体节约内存,利用其语义特征,同时不耗费资源(利用map实现set)

  • atomic包原子化操作提高性能

等等,具体的例子,在不同的开发功能中会有所具体体现,这里就不做更多的赘述,在上面提到的许多建议在这本Go语言高性能编程中都有所涉及,感兴趣可以仔细阅读。

3. 优化实践举例

3.1 Go语言编程进行图片优化中的常见操作

1.使用第三方库: Go拥有一些强大的第三方库,可以帮助你处理图片。其中最流行的包括github.com/nfnt/resizegithub.com/disintegration/imaging。这些库可以用来压缩、调整尺寸、裁剪、旋转、格式转换等操作。

例如,使用github.com/nfnt/resize库进行图片缩放:

goCopy code
package main

import (
    "image"
    "image/jpeg"
    "os"

    "github.com/nfnt/resize"
)

func main() {
    inputFile, _ := os.Open("input.jpg")
    defer inputFile.Close()

    img, _, _ := image.Decode(inputFile)

    newImg := resize.Resize(300, 0, img, resize.Lanczos3)

    outputFile, _ := os.Create("output.jpg")
    defer outputFile.Close()

    jpeg.Encode(outputFile, newImg, nil)
}

2.使用原生库:  Go标准库中的imageimage/jpeg等包也提供了基本的图片处理功能,可以进行图片解码、编码、调整大小等操作。

3.使用图形处理软件的命令行工具:  如果你希望进行更复杂的图片优化,例如批量处理,可以结合Go的os/exec包来调用图形处理软件的命令行工具,如ImageMagick或GraphicsMagick。

在开始之前需确保已经安装了相关的第三方库或者图形处理软件,并且对于图像处理任务有一定的基础理解。无论选择哪种方法,记得在实际应用中处理错误和异常情况,以确保程序的稳定性。

3.2 Go语言编程进行数据请求优化中的常见操作

  • 涉及到减少网络延迟、优化并发请求、实现缓存等方面

1.使用并发请求:  Go天生支持并发,你可以使用goroutines和channels来实现并发请求,从而提高数据获取的效率。可以使用sync.WaitGroup来等待所有goroutines完成。

goCopy code
package main

import (
    "fmt"
    "net/http"
    "sync"
)

func fetchData(url string, wg *sync.WaitGroup) {
    defer wg.Done()

    resp, err := http.Get(url)
    if err != nil {
        fmt.Println("Error fetching data:", err)
        return
    }
    defer resp.Body.Close()

    // Process the response
}

func main() {
    urls := []string{"url1", "url2", "url3"}
    var wg sync.WaitGroup

    for _, url := range urls {
        wg.Add(1)
        go fetchData(url, &wg)
    }

    wg.Wait()
}

2.连接复用:  使用HTTP/2或者Keep-Alive可以重用TCP连接,减少每次请求的连接建立和断开所带来的开销。

3.设置超时时间:  为HTTP请求设置适当的超时时间,防止请求因为网络问题而阻塞太久。 4.使用HTTP连接池: Go的net/http包已经内置了HTTP连接池,可以减少连接的重复创建和关闭。

5.数据缓存: 对于频繁请求的数据,可以将其缓存在内存中,避免重复请求,提高响应速度。

6.分页和批量请求: 如果请求的数据量较大,可以考虑分页加载,或者使用批量请求来获取更多的数据。

7.压缩和优化数据: 对于响应数据,可以启用服务器端的Gzip压缩,减小数据传输量,提高响应速度。

8.使用CDN: 如果你的数据请求主要是静态资源,可以使用内容分发网络(CDN)来加速资源的传输,降低服务器负担。

9.使用优化的HTTP库: 除了标准库的net/http,还有一些优化过的HTTP库,如github.com/valyala/fasthttp,可以在性能上提供更好的效果

以上这些方法可以在Go语言中优化数据请求,提高系统的性能和响应速度。根据具体的场景和需求,要结合不同的方法来实现最佳的优化策略。

4. 性能优化测试

进行性能测试,以验证我们的优化是否有效。在Go语言中,我们可以使用testing包来进行基准测试。例:

css
复制代码
func BenchmarkFunc(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Func()
    }
}

然后,我们可以通过go tool pprof命令来分析性能数据,并进行相应的优化。

$ go tool pprof http://localhost:6060/debug/pprof/profile

性能测试和调优是对我们优化的确保。