面试题答案
一键面试内存管理方面
- 减少内存分配:
- 在匿名函数内部,如果有频繁创建临时变量的情况,尝试复用已有变量。例如,对于需要频繁拼接字符串的场景,使用
strings.Builder
替代+
操作符。strings.Builder
预先分配一定内存,减少每次拼接时的内存重新分配。示例代码如下:
package main import ( "fmt" "strings" ) func main() { var sb strings.Builder for i := 0; i < 100; i++ { sb.WriteString(fmt.Sprintf("%d", i)) } result := sb.String() fmt.Println(result) }
- 如果匿名函数中使用切片,预先分配足够的容量,避免在循环中动态扩容。例如:
package main import "fmt" func main() { slice := make([]int, 0, 100) for i := 0; i < 100; i++ { slice = append(slice, i) } fmt.Println(slice) }
- 在匿名函数内部,如果有频繁创建临时变量的情况,尝试复用已有变量。例如,对于需要频繁拼接字符串的场景,使用
- 及时释放内存:
- 如果匿名函数持有对大对象的引用,在不再需要该对象时,将引用设置为
nil
,以便垃圾回收器(GC)能够及时回收内存。例如:
package main import "fmt" func main() { var largeObj []byte largeObj = make([]byte, 1024*1024) // 模拟大对象 func() { // 使用largeObj fmt.Println(len(largeObj)) largeObj = nil // 不再使用时设置为nil,利于GC回收 }() }
- 如果匿名函数持有对大对象的引用,在不再需要该对象时,将引用设置为
资源竞争方面
- 使用互斥锁(Mutex):
- 如果匿名函数需要访问共享资源,使用
sync.Mutex
来保护共享资源。例如,多个匿名函数可能需要修改同一个全局变量:
package main import ( "fmt" "sync" ) var ( counter int mu sync.Mutex ) func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() mu.Lock() counter++ mu.Unlock() }() } wg.Wait() fmt.Println("Final counter:", counter) }
- 如果匿名函数需要访问共享资源,使用
- 使用读写锁(RWMutex):
- 当有多个匿名函数频繁读取共享资源,同时偶尔有匿名函数进行写操作时,使用
sync.RWMutex
可以提高并发性能。读操作时使用RLock
,写操作时使用Lock
。示例如下:
package main import ( "fmt" "sync" ) var ( data int rwmu sync.RWMutex ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() rwmu.RLock() fmt.Println("Read data:", data) rwmu.RUnlock() }() } for i := 0; i < 2; i++ { wg.Add(1) go func() { defer wg.Done() rwmu.Lock() data++ rwmu.Unlock() }() } wg.Wait() }
- 当有多个匿名函数频繁读取共享资源,同时偶尔有匿名函数进行写操作时,使用
- 使用通道(Channel):
- 可以使用通道在匿名函数之间传递数据,避免共享资源竞争。例如,将计算结果通过通道传递给其他匿名函数或主函数:
package main import ( "fmt" ) func main() { resultChan := make(chan int) go func() { sum := 0 for i := 0; i < 10; i++ { sum += i } resultChan <- sum close(resultChan) }() for result := range resultChan { fmt.Println("Result:", result) } }
算法和代码结构优化方面
- 优化算法复杂度:
- 检查匿名函数内的算法,尝试使用更高效的算法。例如,如果是查找操作,从线性查找改为二分查找(适用于有序数据)。
- 代码结构调整:
- 将匿名函数中重复的代码提取成独立的函数,减少冗余代码,提高代码可读性和可维护性,也可能会提升性能。例如:
package main import "fmt" func commonCalculation(a, b int) int { return a + b } func main() { func() { result := commonCalculation(1, 2) fmt.Println(result) }() }