day5 高质量编程 | 青训营笔记

109 阅读4分钟

题记

这是我参与「第五届青训营 」伴学笔记创作活动的第 5天,本文用于记录在青训营的学习笔记和一些心得。

day5 1月19日

今日学习目标

  • 如何编写更简洁清晰的代码
  • 常用Go语言程序优化手段
  • 熟悉Go程序性能分析工具
  • 了解工程中性能优化的原则和流程

高质量编程

简介

什么是高质量:编写的代码能够达到正确可靠,简洁清晰的目标可称之为高质量代码。

  • 各种边界是否考虑完备
  • 异常情况处理,稳定性保证
  • 易读易维护

编程原则 实际应用场景千变万化,各种语言的特性和语法各不相同,但是高质量编程遵循的原则是相通的

  • 简单性 消除“多余的复杂性”,以简单清晰的逻辑编写代码 不理解的代码无法修复改进
  • 可读性 代码是写给人看的,而不是机器 编写可维护代码的第一步是确保代码可读
  • 生产力 团队整体工作效率非常重要

编码规范

如何编写高质量的Go 代码

  • 代码格式
  • 注释
  • 命名规范
  • 控制流程
  • 错误和异常处理
编码规范-代码格式

image-20230117142728171

编码规范-注释

注释应该做的:

  • 注释应该解释代码作用
  • 注释应该解释代码如何做的
  • 注释应该解释代码实现的原因
  • 注释应该解释代码什么情况会出错

image-20230117142901575

image-20230117143500791

image-20230117143511510

image-20230117143520166

image-20230117143538900

公共符号始终要注释

  • 包中声明的每个公共的符号
  • 变量、常量、函数以及结构都需要添加注释
  • 任何既不明显也不简短的公共功能必须予以注释
  • 无论长度或复杂程度如何,对库中的任何函数都必须进行注释
  • 不需要注释实现接口的方法

小结:

  • 代码是最好的注释
  • 注释应该提供代码为表达出的上下文信息
编码规范-命名规范

image-20230117144332648

image-20230117144342861

image-20230117144350428

image-20230117144708615

image-20230117144832472

小结:

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

image-20230117145542045

image-20230117145603336

image-20230117145611667

小结

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

image-20230117152352026

image-20230117152759812

image-20230117152853747

image-20230117152905941

image-20230117152913747

image-20230117152924035

image-20230117153315390

image-20230117153606121

小结

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

image-20230117153627371

image-20230117153634228

性能优化建议

简介

  • 性能优化的前提是满足正确可靠、简洁清晰等质量因素
  • 性能优化是综合评估,有时候时间效率和空间效率可能对立。
  • 针对Go语言特性,介绍Go 相关的性能优化建

image-20230117163058150

image-20230117163037692

-benchmem表示打印函数执行过程中的内存分配,你可以根据下图分析上图的内容。

image-20230117163149519

image-20230117164030450

image-20230117164041230

image-20230117164051436

image-20230117164107374

image-20230117164118761

编程过程中除了slice和map,平时很多编码功能都和字符串处理相关的,字符串处理也是高频操作,那么不同字符串处理方式的性能表现会有什么差异吗?

image-20230117165005239

image-20230117165022042

当使用+拼接2个字符用时,生成一个斩的字符串,那么就需要开辟–段新的空间、新空间的大小是原来两个字符审的大小之和,拼接第三个字符期时,再开辟-段新空间,新空间大小是三个字符串大小之和,以此类推

image-20230117165107705

为什么stringbuilder会比bytebuffer更快一些,可以看看实际的代码 注意注释里也提到如果想用更高效的字符串构造方法,可以使用string builder联系刚刚之前讲到的内容,有没有办法再次提升字符串拼接的效率? 关键字是什么?预分配

image-20230117165204505

image-20230117165345052

性能优化有时是时间和空间的平衡,之前提到的都是提高时间效率的点,对于空间上是否有优化的手段呢?空结构体是节省内存空间的一个手段。

image-20230117170111959

image-20230117170300785

在工作中迟早会遇到多线程编程的场景,比如实现一个多线程共用的计数器,如何保证计数准确,线程安全,有不同的方式。

image-20230117171516023

这部分内容涉及较深,先有个概念,实际使用时可以详细了解。

image-20230117171545555

image-20230117171626232