当前位置: 首页 > news >正文

网站开发及设计演讲海报台州品牌网站建设

网站开发及设计演讲海报,台州品牌网站建设,apmserv wordpress,WordPress赞赏代码1. 前言 之前在设计一个兼容函数的时候,使用了sjson动态设入参数,从而实现一些参数的兼容。大致的逻辑如下所示: // 有一堆不规则的json数据 {"a":"aaa","b":"bbb","any_key1":{"k…

1. 前言

之前在设计一个兼容函数的时候,使用了sjson动态设入参数,从而实现一些参数的兼容。大致的逻辑如下所示:

// 有一堆不规则的json数据
{"a":"aaa","b":"bbb","any_key1":{"key":"value"},"any_key2":{"key":"value"}
}
// 因为any_key1和any_key2这样的数字字符串的key还会有新增,所以这个是无法固定的,没有办法给到一个具体的结构体解析,于是就人为的兼容,给它们在处理的时候包一个外层的key
{"a":"aaa","b":"bbb","number_key_data":{"any_key1":{"key":"value"},"any_key2":{"key":"value"}}
}
// 这样处理之后,我只要定义number_key_data,我就可以获取到具体的字符串数字为key的数据

2. 实现

采用sjson对对应的非特定key进行新的结构值设入,然后做一个兼容即可实现上面的逻辑,于是有这段代码出来了。

package gjson_set_studyimport ("encoding/json""fmt""github.com/tidwall/sjson""testing"
)func TestGjsonSet(t *testing.T) {data := `{"a":"aaa","b":"bbb","any_key1":{"key":"value"},"any_key2":{"key":"value"}}`dataMap := map[string]interface{}{}err := json.Unmarshal([]byte(data), &dataMap)if err != nil {panic(err)}fmt.Println(adaptNumberKey(data, dataMap))// output// {"a":"aaa","b":"bbb","number_key_data":{"any_key1":{"key":"value"},"any_key2":{"key":"value"}}} <nil>
}type Data struct {A             string `json:"a"`B             string `json:"b"`NumberKeyData map[string]struct {Key   string `json:"key"`Value string `json:"value"`} `json:"number_key_data"`
}var specificKeys = map[string]bool{"a": true,"b": true,
}func adaptNumberKey(data string, dataMap map[string]interface{}) (string, error) {var err errorfor k, v := range dataMap {if _, ok := specificKeys[k]; ok {continue}data, err = sjson.Delete(data, k) // remove firstif err != nil {return "", fmt.Errorf("delete key data error, key=%s, err=%w", k, err)}data, err = sjson.Set(data, "number_key_data."+k, v)if err != nil {// log...return "", fmt.Errorf("set number_key_data error, key=%s, err=%w", k, err)}}return data, nil
}

上面的实现,不出意外的话是不会有任何的问题,但是不出意外的意外出现了,当类似的逻辑代码上线之后,我们发现一个问题:容器会爆内存。这代码也实现了自测,也过了QA的测试,为什么会突然爆内存呢?

3. 问题

容器爆内存的问题出现了,但并不是所有的数据都爆内存,有一组数据100%会爆内存,它们的数据类似:

{"a":"aaa","b":"bbb","1000000":{"key":"value"},"50000000":{"key":"value"}}

比较明显的是出现了数字字符串的key,然后结合代码看了一下,刚开始也没看出啥异常,觉得这个修改后的数据应该是:

{"a":"aaa","b":"bbb","number_key_data":{"1000000":{"key":"value"},"50000000":{"key":"value"}}}

但后面发现爆内存的问题,又想起了设置数组的方式,当前的代码逻辑如果遇到数字key,就会被认为是在设置数组,开辟几百万甚至上千万长度的数组?(细思极恐) 于是就发现了爆内存的问题所在:数字key在未经特殊标识的情况下,会被认定为数组,于是这个设置key的过程,就变成了对一个key的长为1000000的数组设置值(后者是50000000),可怕

4. 解决方法

于是参看源码,照着sjson的set方法一路向下看,可以发现如果在parsePath 中我们对路径添加了: 的前缀,sjson会强制把这个key当做string key,而在atoui中不会将其解析为一个具体的数字,进而导致对字符串key的设置,变成对数组的设值。

func parsePath(path string) (res pathResult, simple bool) {var r pathResultif len(path) > 0 && path[0] == ':' { // 如果含有:符号,这个key会被强制认定为keyr.force = truepath = path[1:]}for i := 0; i < len(path); i++ { // 对path进行分解if path[i] == '.' {r.part = path[:i]r.gpart = path[:i]r.path = path[i+1:]r.more = truereturn r, true}if !isSimpleChar(path[i]) {return r, false}if path[i] == '\\' {// go into escape mode. this is a slower path that// strips off the escape character from the part.// ...}return r, true
}// atoui does a rip conversion of string -> unigned int.
func atoui(r pathResult) (n int, ok bool) {if r.force {return 0, false}for i := 0; i < len(r.part); i++ {if r.part[i] < '0' || r.part[i] > '9' {return 0, false}n = n*10 + int(r.part[i]-'0')}return n, true
}

于是修改代码逻辑,将所有key的前缀都加上:的标识。

func adaptNumberKey(data string, dataMap map[string]interface{}) (string, error) {var err errorfor k, v := range dataMap {if _, ok := specificKeys[k]; ok {continue}data, err = sjson.Delete(data, k) // remove firstif err != nil {return "", fmt.Errorf("delete key data error, key=%s, err=%w", k, err)}data, err = sjson.Set(data, "number_key_data."+":"+k, v)if err != nil {// log...return "", fmt.Errorf("set number_key_data error, key=%s, err=%w", k, err)}}return data, nil
}
// Output: {"a":"aaa","b":"bbb","number_key_data":{"1000000":{"key":"value"},"50000000":{"key":"value"}}} <nil>

5. 小结

忽然想到遇到的这个小问题,当时就觉得还是自己单测的场景不够全面,导致了这次爆内存的问题发生,还好有临时解决方案,不然对线上服务造成的影响还真不小。通过这个事例,再一次告诫自己在后续的代码编写中,对于通用功能的逻辑代码,要尽可能的思考一些边缘case,从而避免在上线后边缘case导致代码崩溃的现象出现。

http://www.yayakq.cn/news/186134/

相关文章:

  • 网页制作模板的网站element怎么建网站赚钱
  • 网站版式设计说明数商云价格
  • 伍佰亿网站建设查询学校信息的网站
  • 大学生网站开发总结报告建房的网站
  • 网站建设与用户需求分析银川网站建设多少钱
  • 做一家拍卖网站需要什么资质冬奥会网页设计素材
  • 网站建设倒计时单页源码南昌专业网站设计
  • 网站备案核验单2017网站建设方案
  • 网站开发网络结构图网站制作 flash 修改
  • 找人网站 优帮云做挂件像网站
  • 163建筑网站定制公交app下载
  • 网站轮播效果怎么做郑州网站制作郑州网站制作案例
  • 做知识产权相关的网站做营销型网站公司
  • 网站策划建设阶段的推广佛山顺德做网站
  • 监控做直播网站企业网站和官网的区别
  • 有哪些设计网站app网站建设找宙斯站长工具
  • html代码是什么意思搜狗首页排名优化
  • 企业顺德网站建设福建省建设工程信息网站
  • 备案需要网站吗市场部网页设计西安
  • 软文网站名称推广策略怎么写
  • 教育行业建设网站不属于网络虚拟财产
  • 高埗做网站wordpress python插件
  • 口碑好的赣州网站建设吕梁推广型网站建设
  • 网站 建设原则龙南县建设局网站
  • 佛山市网站建设平台上海公司法人落户条件
  • 福州模板做网站163企业邮箱登录
  • 做网站找哪个部门景安服务器安装wordpress
  • 大良网站公司加盟招商网站建设方案书
  • 网站开发李沛杰h5营销型网站功能
  • 国内做的比较好的网站如何做照片ppt模板下载网站