1 : for {
select {
case <-chin:
......
case <-chout:
...
default:
如没必要请勿强行装逼、会导致CPU飙升
}
}
2 csv 导入
导入字段莫名其妙在开头增加\uFEFF
后面查询到 http://www.imooc.com/article/26166 ,是被上传方强制增加了bom头防止文件乱码
go 里面处理,直接将 string(\uFEFF) 替换掉即可
3 go mod 私有自建仓库
go env -w GOPROXY=https://goproxy.cn,direct
git config --global url."git.test.com:".insteadOf "https://git.test.com/"
export GOPRIVATE="git.test.com"
export GONOSUMDB=""
export GOSUMDB=off
第一次不知道版本或者版本拉不回来,给go.mod,go.sum 删了 重新 go mod init modname 生成下
4 docker 编译带CGO、
比如包含 github.com/confluentinc/confluent-kafka-go/kafka 的项目
新手一般建议不要使用alpine作为母包、缺少很多依赖、要么编译不过去、要么编译过去不能运行、要么找不到文件,
如果出现类似问题,直接上Ubuntu、debian 之类的高版本母包即可、
5 database/sql 包遇到 null 字段
a: 将接受对象类型设置为 、NullInt64/NullString ....
b: 将sql里头的字段设置为 IFNULL
6: 一个结构体或者interface不知道被谁实现了或者是实现了谁搞不清楚
有个 goplantuml 软件可以分析出UML图
7:定时器不执行
for {
select {
case <-time.After(time.Second * 1):
println("1s ")
case <-time.After(time.Second * 2): //这个定时器永远都不会执行
println("2s")
}
}
/**
select 每次执行都会重新执行 case 条件语句,
并重新注册到 select ,每次都会新构造一个 Timer 对象,
所以2秒的定时器永远不会执行。而且会造成内存的泄露
**/
//以下代码可正常之心
t1 := time.NewTicker(time.Second * 1)
t2 := time.NewTicker(time.Second * 2)
for {
select {
case <-t1.(*time.Ticker).C:
println("1s")
case <-t2.(*time.Ticker).C:
println("2s")
}
}
8: slice,切片的坑
网上很多资料都是说 切片是引用类型的,貌似说是作为形参传递会影响实参数值
实测中,当切片改变某一个元素的时候,确实会改变实参,但是appened,或者删除的时候则不影响原有切片
但是如果在make的时候给出足够的长度则会影响,append(*切片,值)也可以
比如
func main(){
var a = []int{1,2,4}
test(a)
fmt.Println(a)
}
func test(a int[]){
a[1] = 100 ,会影响
b:=[]int{5,6,7}
a =b 并不会影响
a = append(a,[]int{1,2,3}...) //不影响
a = append(a[0:1],a[2:]...) //不影响
// 删除切片也不会影响前面的,原因是长度不够扩充长度会重新生成切片,地址改变了
}
9 。 在高并发环境下、httpclient 会初始化连接失败、
- a: 修改 DisableKeepAlives 参数
- b: 使用全局连接、比如 sync.onece. ,比如 GetHttpClient(once.do(func(){ httpclient= ....,}))
10。 面试中的高频问题
- 协程实现顺序输出
- 实现控制并发的方法、
- make (chan type,num)、
- waitgroup
- sync.atomic 这个是去模拟锁定机制
- mutex