MST

星途 面试题库

面试题:Go语言中JSON序列化反序列化时struct标签的性能优化与自定义行为

对于一个频繁进行JSON序列化和反序列化的大型复杂结构体,如包含嵌套结构体、切片、映射等多种数据结构的`type BigData struct { A int `, ` B string `, ` C []SubData `, ` D map[string]interface{} } type SubData struct { E float64 `, ` F bool `}`。请从struct标签角度出发,讨论如何优化性能,例如减少内存分配和提高序列化反序列化速度。同时,假设在反序列化时,对于`SubData`中的`E`字段,若其值小于0,需要将其设置为0,阐述如何通过自定义反序列化函数结合struct标签实现该功能。
38.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

优化性能 - 减少内存分配和提高序列化反序列化速度

  1. 标签命名优化:在BigDataSubData结构体的字段上设置合适的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字符串的长度,从而减少内存占用,提高序列化和反序列化速度。

  1. 减少空值序列化:如果某些字段在空值时不需要序列化,可以使用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标签实现特定功能

  1. 实现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
}
  1. 使用自定义反序列化:在对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标签实现了对SubDataE字段的特殊处理。