面试题:
性能优化
以下代码如何优化内存分配?
go
func concat(strs []string) string {
var s string
for _, str := range strs {
s += str
}
return s
}
考察点:字符串拼接的不可变性,strings.Builder 预分配内存。
如何通过 sync.Pool 优化高频创建的对象?
考察点:对象池的生命周期管理、减少 GC 压力。
解答:
在 Go 语言中,字符串拼接有多种实现方式,每种方式都有其优缺点。以下是常见的几种方式及其特点:
1. 使用 +
操作符
go
s1 := "Hello"
s2 := "World"
result := s1 + " " + s2
优点:
- 简单直观,适合少量字符串拼接。
缺点:
- 每次拼接都会生成新的字符串,产生额外的内存分配和复制,性能较差,尤其在大量拼接时。
2. 使用 fmt.Sprintf
go
s1 := "Hello"
s2 := "World"
result := fmt.Sprintf("%s %s", s1, s2)
优点:
- 支持格式化,适合需要格式化的字符串拼接。
缺点:
- 性能较差,因为涉及格式化处理,适合少量拼接。
3. 使用 strings.Join
go
s := []string{"Hello", "World"}
result := strings.Join(s, " ")
优点:
- 高效,适合拼接字符串切片,尤其是大量字符串时。
缺点:
- 需要先将字符串放入切片,适合已知所有字符串的场景。
4. 使用 bytes.Buffer
go
var buffer bytes.Buffer
buffer.WriteString("Hello")
buffer.WriteString(" ")
buffer.WriteString("World")
result := buffer.String()
优点:
- 高效,适合频繁拼接,内存分配较少。
缺点:
- 代码稍显冗长。
5. 使用 strings.Builder
(Go 1.10+)
go
var builder strings.Builder
builder.WriteString("Hello")
builder.WriteString(" ")
builder.WriteString("World")
result := builder.String()
优点:
- 高效,适合频繁拼接,内存分配较少,比
bytes.Buffer
更高效。
缺点:
- 仅适用于 Go 1.10 及以上版本。
6. 使用 []byte
和 append
go
var b []byte
b = append(b, "Hello"...)
b = append(b, " "...)
b = append(b, "World"...)
result := string(b)
优点:
- 高效,适合频繁拼接,内存分配较少。
缺点:
- 代码稍显复杂。
总结
- 少量拼接 :使用
+
或fmt.Sprintf
,简单直观。 - 大量拼接 :使用
strings.Join
、bytes.Buffer
或strings.Builder
,性能更好。 - 频繁拼接 :推荐
strings.Builder
,性能最佳。
选择合适的方式可以提升代码性能和可读性。