面试题答案
一键面试优化性能 - 减少内存分配和提高序列化反序列化速度
- 标签命名优化:在
BigData
和SubData
结构体的字段上设置合适的JSON标签,使用简短且有意义的名字。例如:
type BigData struct {
A int `json:"a"`
B string `json:"b"`
C []SubData `json:"c"`
D map[string]interface{} `json:"d"`
}
type SubData struct {
E float64 `json:"e"`
F bool `json:"f"`
}
这样可以减少序列化后JSON字符串的长度,从而减少内存占用,提高序列化和反序列化速度。
- 减少空值序列化:如果某些字段在空值时不需要序列化,可以使用
omitempty
标签。例如,若D
字段在空的map
时不需要序列化,可以这样设置标签:
type BigData struct {
A int `json:"a"`
B string `json:"b"`
C []SubData `json:"c"`
D map[string]interface{} `json:"d,omitempty"`
}
这样在D
为空map
时,序列化结果中不会包含d
字段,减少序列化后的数据量。
自定义反序列化函数结合struct标签实现特定功能
- 实现
json.Unmarshaler
接口:在SubData
结构体上实现json.Unmarshaler
接口。
package main
import (
"encoding/json"
"fmt"
)
type BigData struct {
A int `json:"a"`
B string `json:"b"`
C []SubData `json:"c"`
D map[string]interface{} `json:"d"`
}
type SubData struct {
E float64 `json:"e"`
F bool `json:"f"`
}
func (s *SubData) UnmarshalJSON(data []byte) error {
type Alias SubData
var alias Alias
err := json.Unmarshal(data, &alias)
if err != nil {
return err
}
if alias.E < 0 {
alias.E = 0
}
*s = SubData(alias)
return nil
}
- 使用自定义反序列化:在对
BigData
进行反序列化时,SubData
类型的字段会自动调用我们定义的UnmarshalJSON
函数。
func main() {
jsonStr := `{"a": 1, "b": "test", "c": [{"e": -1.5, "f": true}], "d": {"key": "value"}}`
var bd BigData
err := json.Unmarshal([]byte(jsonStr), &bd)
if err != nil {
fmt.Println("反序列化错误:", err)
return
}
fmt.Printf("反序列化结果: %+v\n", bd)
}
这样就通过自定义反序列化函数结合struct标签实现了对SubData
中E
字段的特殊处理。