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

中牟高端网站建设多模室内设计网站

中牟高端网站建设,多模室内设计网站,网站源码提取,自助创建网站Go 切片导致 rand.Shuffle 产生重复数据的原因与解决方案 在 Go 语言的实际开发中,切片(slice)是一种非常灵活的数据结构。然而,由于其底层数据共享的特性,在某些情况下可能会导致意想不到的 Bug。 本文将详细分析 r…

Go 切片导致 rand.Shuffle 产生重复数据的原因与解决方案

在 Go 语言的实际开发中,切片(slice)是一种非常灵活的数据结构。然而,由于其底层数据共享的特性,在某些情况下可能会导致意想不到的 Bug。

本文将详细分析 rand.Shuffle 之后,切片中的数据出现重复的问题,探讨其根本原因,并给出最佳解决方案,以确保代码的正确性和稳定性。


🔍 问题描述

在一个 Go 服务端 API 里,我们需要按照 curBatch 参数进行分页,从 interestCfg 里分批选取 interestTagNum 个兴趣标签,并在返回结果前对选中的数据进行随机打乱。

全部兴趣标签示例:

{"InterestTags": [{"interestName":"Daily Sharing"},{"interestName":"Gaming"},{"interestName":"AI"},{"interestName":"test"},{"interestName":"Sports"},{"interestName":"Cars"},{"interestName":"other"}]
}

🌟 现象回顾

curBatch = 0 时,返回的数据是正确的:

{"InterestTags": [{ "interestName": "Daily Sharing" },{ "interestName": "Gaming" },{ "interestName": "AI" }]
}

但当 curBatch = 2 时,测试环境出现了数据重复的问题:(本地运行正常)

1. 不随机时(正确的结果):
{"InterestTags": [{ "interestName": "other" },{ "interestName": "Daily Sharing" },{ "interestName": "Gaming" }]
}
2. 随机后(错误的结果):
{"InterestTags": [{ "interestName": "Gaming" },{ "interestName": "Gaming" },{ "interestName": "AI" }]
}

问题:

  • “Gaming” 出现了两次,而 “test” 消失了!
  • 本地环境正常,但测试环境异常,导致调试变得困难。

🔎 问题排查

数据的选择和随机操作逻辑如下:

interestTags := make([]model.InterestConfig, 0, interestConfig.InterestTagNum)// 处理interestConfig,根据curBatch分批次处理
if len(interestConfig.InterestCfg) > 0 && interestConfig.InterestTagNum > 0 {interestAllTags := interestConfig.InterestCfgnumBatches := (len(interestAllTags) + int(interestConfig.InterestTagNum) - 1) / int(interestConfig.InterestTagNum)startIdx := (curBatch % numBatches) * int(interestConfig.InterestTagNum)endIdx := startIdx + int(interestConfig.InterestTagNum)if endIdx > len(interestAllTags) {interestTags = interestAllTags[startIdx:]interestTags = append(interestTags, interestAllTags[:(endIdx-len(interestAllTags))]...)} else {interestTags = interestAllTags[startIdx:endIdx]}
}// 随机打乱 interestTags 顺序
r := rand.New(rand.NewSource(time.Now().UnixNano()))
r.Shuffle(len(interestTags), func(i, j int) {interestTags[i], interestTags[j] = interestTags[j], interestTags[i]
})

关键点分析

  1. interestTags = interestAllTags[startIdx:endIdx] 直接从 interestAllTags 取出数据,但切片是引用类型,因此 interestTags 共享了 interestAllTags 的底层数组
  2. rand.Shuffle 随机交换 interestTags 里的元素,但 interestTags 指向 interestAllTags,可能导致原始数据被错误修改
  3. 本地和测试环境不一致,可能与 Go 运行时的内存管理机制高并发场景下的切片扩容行为有关。

🛠 代码验证

为了验证 interestTags 是否共享 interestAllTags 的底层数组,我们打印切片元素的内存地址:

fmt.Println("Before Shuffle:")
for i, tag := range interestTags {fmt.Printf("[%d] %p: %s\n", i, &interestTags[i], tag.InterestName)
}r.Shuffle(len(interestTags), func(i, j int) {interestTags[i], interestTags[j] = interestTags[j], interestTags[i]
})fmt.Println("After Shuffle:")
for i, tag := range interestTags {fmt.Printf("[%d] %p: %s\n", i, &interestTags[i], tag.InterestName)
}

测试环境的 After Shuffle 结果中,某些索引的地址相同,证明 rand.Shuffle 影响了原始数据,导致元素重复。


💡 解决方案

方案 1:使用 append 进行数据拷贝

为了避免 interestTags 共享 interestAllTags 的底层数组,我们需要显式拷贝数据:

interestTags = make([]model.InterestConfig, 0, interestConfig.InterestTagNum)
if endIdx > len(interestAllTags) {interestTags = append(interestTags, interestAllTags[startIdx:]...)interestTags = append(interestTags, interestAllTags[:(endIdx-len(interestAllTags))]...)
} else {interestTags = append(interestTags, interestAllTags[startIdx:endIdx]...)
}

🔹 为什么这样做?

  • append(..., interestAllTags[startIdx:endIdx]...) 创建新的切片,避免 interestTags 共享 interestAllTags 的底层数据。
  • 独立的数据拷贝 确保 rand.Shuffle 只影响 interestTags,不会破坏原始 interestAllTags

📌 总结

🌟 1. 问题原因

  • Go 切片是引用类型,直接赋值 interestTags = interestAllTags[startIdx:endIdx] 不会创建新数据,而是共享底层数组
  • rand.Shuffle 可能影响 interestAllTags,导致元素重复
  • 本地环境正常,但测试环境异常,可能与 Go 内存管理切片扩容策略有关。

🌟 2. 解决方案

  • 使用 append 进行数据拷贝,确保 interestTags 是独立的数据,避免 rand.Shuffle 影响原始 interestAllTags

🚀 经验总结

  1. Go 切片是引用类型,不能直接赋值,否则可能共享底层数据。
  2. 使用 rand.Shuffle 之前,必须确保数据是独立的副本
  3. 尽量使用 append 创建新的切片,避免底层数组共享问题。
  4. 不同环境表现不一致时,应检查内存管理、并发情况及数据结构副作用。

文章转载自:

http://VVhQZwjM.hqgxz.cn
http://KaW3jDcU.hqgxz.cn
http://dxe9rQVr.hqgxz.cn
http://hzp0z2yS.hqgxz.cn
http://yTXv6WQ3.hqgxz.cn
http://1jA3HWVk.hqgxz.cn
http://sDtwUwxL.hqgxz.cn
http://7NI3Ajrb.hqgxz.cn
http://atqHKcVF.hqgxz.cn
http://FHhKMUjI.hqgxz.cn
http://OAt0t9yf.hqgxz.cn
http://vNpINWiG.hqgxz.cn
http://2fHkbKzF.hqgxz.cn
http://bBwxXxl2.hqgxz.cn
http://8XStOPVk.hqgxz.cn
http://otalBRWE.hqgxz.cn
http://KMJzEJxM.hqgxz.cn
http://u3gfgQDr.hqgxz.cn
http://teA1QCre.hqgxz.cn
http://aHDlHUz4.hqgxz.cn
http://FrEda6vr.hqgxz.cn
http://GWj8delY.hqgxz.cn
http://IxvJeoBd.hqgxz.cn
http://nVu6NGpk.hqgxz.cn
http://0aIgcp9c.hqgxz.cn
http://fwK2GO5B.hqgxz.cn
http://2FOTZDd7.hqgxz.cn
http://BrzcxkNm.hqgxz.cn
http://0OOAQUrb.hqgxz.cn
http://qcxH0xkR.hqgxz.cn
http://www.dtcms.com/wzjs/678289.html

相关文章:

  • 如何创建网站主页企业网站定制公司
  • 泉州建站平台如何获取免费的wordpress
  • 静安网站建设网站建设 上寻模板
  • 有意思的网站帝国cms小说网站模板下载地址
  • 大淘客网站如何建设跨国贸易平台有哪些
  • 集团网站建设多少钱计算机应用技术是学什么的
  • 网站优化推广seo网站建设项目经历
  • 宿州网站公司新云自助建站
  • 如何优化网站关键字北京模板建站设计
  • 温州手机网站制作推荐官方网站app大全
  • 现在什么类型网站没有人做南宁市起全网络科技有限公司
  • 建站服务网络公司潍坊市安丘网站建设
  • 大连做网站谁家好建设知道购物网站
  • 宁波模板网站建站响应式网站模板之家
  • 镇江市建设招标网官方网站孟村做网站
  • 企业网站设计需要了解国外网站网站
  • 浦东建设网站深圳建筑公司招聘信息
  • 海航科技网站建设上海市质量工程建设管理协会网站
  • qq官方网站进入网站建设设计说明
  • 电商网站在线支付怎么做几十个必备的设计师灵感网站
  • 株洲做网站 省心磐石网络烟台电子商务产业园网站建设
  • 电商网站创建的几个阶段品牌创建策划方案
  • 网站流量下跌集团网站设计思路
  • 实训网站建设的心得总结网站建设面包屑导航条
  • 仙桃做网站手机端网站开发教程
  • 娄星区建设局网站企业所得税的优惠政策
  • 泉州网站快速排名提升北京设计院排名前十强
  • 青岛网站排名哪家公司好教做面点的网站
  • 如何设置网站logo网易企业邮箱 登录
  • 别人做的网站怎么seo优化seo案例网站