1. 禁止
1.1 禁止使用递归(包括间接递归)
//请评估以下函数的执行时间
package main
import "time"
func fibonacci(n uint64) uint64 {
if n > 2 {
return fibonacci(n-1) + fibonacci(n-2)
}
return 1
}
func main() {
start := time.Now()
f60 := fibonacci(60)
dur := time.Now().Sub(start)
println("f60=", f60, "cost=", dur.String())
}
1.2 禁止对range变量取地址
//请判断以下代码的输出?
var ary []struct{
Name string
}
var names []*string
for _,v:=range ary{
names=append(names, &v.Name)
}
1. 3 高频函数禁止使用cgo
1.4 禁止在循环里使用go,defer关键字
1.5 禁止遍历数组查找元素
2. 通用
2.1 命名
2.1.1 package name使用与目录同名的小写字母
2.1.2 文件名、目录名全部用英文小写,下划线分隔,如hash_map.go
2.1.3 变量,类型,函数名采用驼峰/匈牙利命名法,如hashMap, MerkleTree
2.2 并发
2.2.1 用通信共享内存,不要用共享内存通信
2.2.2 DataRace在多线程中的危害:脏读
2.2.3 优先考虑atomic,其次才使用锁
2.2.4 从函数名区分内部是否使用锁,如lockGet,nolockGet
2.2.5 死锁产生原因
-
线程内死锁
//以下代码多在什么时候出现?
lock.Lock()
lock.Lock()
lock.Unlock()
lock.Unlock()
//----------------------
func A(){
lock.Lock()
B()
lock.Unlock()
}
func B(){
lock.Lock()
lock.Unlock()
}
-
线程间死锁
//以下代码有什么问题?
//thread A
lockA.Lock()
lockB.Lock()
// do something
lockA.Unlock()
lockB.Unlock()
//thread B
lockB.Lock()
lockA.Lock()
// do something
lockB.Unlock()
lockA.Unlock()
-
锁的效率问题
Mutex与RWMutex
-
Mutex独占锁,读和写都是独占的
-
RWMutex读写锁,写独占,多个读可以并行
锁的粒度
-
对数组的元素加锁,不要对整个数组加锁
-
不要持有锁做网络,文件等IO操作
3. 建议
3.1 面向对象的思维方式
3.2 函数不要有记忆性
3.3 一个函数只做一件事
3.4 函数不要超过50行
3.5 代码行不要超过120列
3.6 如需要else if,尽量换成switch
if a == 1 || a == 3 {
//do something
} else if a == 2 || a == 4 {
//do something
} else {
//do something
}
//-----------------------
switch {
case a == 1 || a == 3:
//do something
case a == 2 || a == 4:
//do something
default:
//do something
}