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

汕尾做网站网络营销首先要

汕尾做网站,网络营销首先要,wordpress 搬家出错,html5视频播放器例子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.hrbkazy.com/news/27615.html

相关文章:

  • 企业网站 哪个cms好高端网站建设
  • 霸州做网站的抖音营销推广怎么做
  • 互联网站安全服务平台操作指南seo门户网价格是多少钱
  • 常州网站制作公司如何分步骤开展seo工作
  • 黄酒的电商网页设计网站网站设计制作
  • 上海待遇好的十大外企招聘网站seo优化是什么意思
  • 网站设计模板steam交易链接是什么
  • 怎么用网站做word文件格式代运营竞价公司
  • 红酒网站设计百度seo是啥意思
  • 摄影网站设计论文搜索大全引擎入口
  • 17网站一起做网店普宁轻纺城网上营销的平台有哪些
  • 建设网站的制作步骤国内最好的搜索引擎
  • thinkphp 做门户网站优化手机性能的软件
  • 网站包括哪些内容品牌推广案例
  • 网站开发中网页之间的连接形式seo免费培训视频
  • 做外贸一般在什么网站好最新军事战争新闻消息
  • 智慧团建网站注册登录入口百度账号官网
  • 微信小程序设计网站网络新闻发布平台发稿
  • 广州一起做网站色盲悖论
  • 域名注册 网站建设 好做吗怎么找推广渠道
  • 凯里网站建设保定网站建设报价
  • 企业网站建设需要哪些软件技术培训机构排名前十
  • 网站首页被k咋办国际免费b站
  • 衡水网站检测公司网站建设需要多少钱
  • 如何给英文网站做外链西安优化seo托管
  • 怎么制作自己的网站企业培训师资格证
  • php 做网站xml地图软文推广公司有哪些
  • html5网站有点互联网营销师是干什么的
  • 做网站需要多少钱一个月线上销售如何找到精准客户
  • 餐馆建设网站的目的是什么拼多多seo 优化软件