开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第25天,点击查看活动详情 这也是第30篇文章
参考资料
字节内部课后端模块
错误和异常处理
简单错误 error
- 用errors.New()表示简单错误
- 用fmt.Errorf()格式化错误
panic
不建议在业务代码中使用panic,因为调用函数不包含recover时会造成程序崩溃。
使用场景:当程序启动阶段发生不可逆转的错误时, 可以在init或main函数中使用panic
recover
只能在当前协程的被defer函数中生效
- 嵌套无法生效
- defer是先进后出(栈)
性能优化建议
slice
- 尽可能在用make()初始化切片时提供容量信息
原因:创建一个新的切片会复用原来切片的底层数组
以切片的append为例,append时有两种场景:
当append之后的长度小于等于cap,将会直接利用原底层数组剩余的空间;
当append后的长度大于cap时,则会分配一块更大的区域来容纳新的底层数组。
因此先设置cap的值能够避免额外的内存分配,获得更好的性能
- 使用copy代替re-slice
原因:考虑如下情景:
原切片由大量的元素构成,但是是我们在原切片的基础上切片,虽然只使用了很小一 段,但底层数组在内存中仍然占据了大量空间,得不到释放。
通过copy,指向新的底层数组,当原始数组不再被引用后,内存会被垃圾回收。
Map
Map也被推荐使用预分配内存的形式(如果可以的话),以减少内存拷贝和rehash的消耗
字符串处理
和Java类似,builder buffer 直接+都可以,但是性能优劣也是按这个顺序。优先使用builder(更快)
原因:看一下builder和buffer的代码:
buffer返回时是新申请一块空间;而builder是直接进行类型转换
空结构体
空结构体不占据任何存储空间,可作为占位符。
Set的实现
Go语言中并没有标准的Set实现,可以用Map来自己实现一个Set,只用其键,不用其值
关于原子性的应用
以下内容涉及操作系统的理论知识:
性能优化原则
- 用数据和事实说话,不要主观臆断
- 抓住主要矛盾的主要方面
- 不要过早、过度优化
关于性能调优工具pprof,之前参考大佬们的青训营笔记之后自己也在示例项目中体验了用法(忘了有没有整理成文章了),之后有需要再更这一块的内容。