需求
一次性获取多个不重复的数字
go实现
尴尬的是,golang只能同一个种子取一个数。想了个笨办法 for循环。但是紧接着又有问题了,N次请求返回的是同一组。难道 随机种子 ? 思路上死循环了。
func GetRandNodes(getAmount int, totalAmount int) []int {
// 取节点
var nodes []int
for i := 1; i <= getAmount; i++ {
s := rand.NewSource(int64(i))
r := rand .New(s)
println(i, "ttttt", totalAmount, r.Intn(totalAmount))
nodes = append(nodes, r.Intn(totalAmount))
}
return nodes
}
#第一次输出
01 15 04 11
#第二次依旧
01 15 04 11
看了一下rand的实现,同一个种子且Intn同一个数字,他们的算法是一致的,并不是新的随机,可能跟phper的理解不太一样。
更换实现方式
nano timestamp as seed
func GetRandNodes(getAmount int, totalAmount int) []int {
// 取节点
var nodes []int
for i := 1; i <= getAmount; i++ {
nanoSecs := time.Now().UnixNano()
s := rand.NewSource(nanoSecs)
r := rand.New(s)
println(i, "ttttt", totalAmount, r.Intn(totalAmount))
nodes = append(nodes, r.Intn(totalAmount))
}
return nodes
}
结果比较理想,go routine并发执行可能会有问题,实际需求也达不到这个量级。
redis 随机获取元素
127.0.0.1:6379> sadd test1 01 02 03 04 05 06
(integer) 6
127.0.0.1:6379> SRANDMEMBER test1 1
1) "05"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "02"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "04"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "03"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "03"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "04"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "04"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "06"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "05"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "01"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "02"
127.0.0.1:6379> SRANDMEMBER test1 1
1) "03"
重复的概率有点大,如果结合代码逻辑,剔除掉存在的数字还是勉强可以实现,目测存在递归调用。