面试题答案
一键面试- 尽量在循环外声明变量:
- 在循环内声明变量会导致每次循环都创建新的变量实例,增加内存分配开销。例如:
package main import "fmt" func main() { var num int for i := 0; i < 10; i++ { num = i * 2 fmt.Println(num) } }
- 这样
num
只在循环外分配一次内存,而不是每次循环都分配。
- 使用对象池(sync.Pool):
- 对于一些创建开销较大的对象,如结构体等,可以使用
sync.Pool
。例如:
package main import ( "fmt" "sync" ) type MyStruct struct { Data [1024]byte } var myPool = sync.Pool{ New: func() interface{} { return &MyStruct{} }, } func main() { for i := 0; i < 10; i++ { obj := myPool.Get().(*MyStruct) // 使用obj fmt.Println(obj) myPool.Put(obj) } }
sync.Pool
提供了一种缓存和复用对象的机制,减少了频繁创建和销毁对象带来的内存开销。
- 对于一些创建开销较大的对象,如结构体等,可以使用
- 使用栈分配:
- Go编译器会尽量将局部变量分配在栈上,因为栈分配和释放的速度比堆分配快。要让变量在栈上分配,尽量避免变量的逃逸分析导致变量被分配到堆上。例如,尽量避免返回局部变量的指针等操作。如果函数返回一个局部变量的指针,该变量很可能会被分配到堆上。如下代码:
package main func createString() *string { s := "hello" return &s }
- 在这个例子中,
s
原本可能在栈上分配,但由于返回了它的指针,可能会被分配到堆上。而下面的代码:
package main func createString() string { s := "hello" return s }
- 这样
string
类型的s
更有可能在栈上分配。
- 合理选择数据类型:
- 选择合适的数据类型可以减少内存占用。例如,如果数值范围确定,使用占用空间小的数据类型。如果只需要表示0或1,可以使用
bool
类型,而不是使用int
类型。如果数值范围在0 - 255之间,可以使用uint8
类型而不是int
类型。例如:
package main func main() { var status bool // 而不是 var status int var age uint8 // 而不是 var age int }
- 选择合适的数据类型可以减少内存占用。例如,如果数值范围确定,使用占用空间小的数据类型。如果只需要表示0或1,可以使用