让我们来看看下面的Go代码:
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex
func main() {
m = make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68433, 74.39967,
}
m["test"] = Vertex{
12.0, 100,
}
fmt.Println(m["Bell Labs"])
fmt.Println(m)
}
它输出这样的:
{40.68433 74.39967}
map[Bell Labs:{40.68433 74.39967} test:{12 100}]
但是,如果我改变测试顶点声明中的一个小部分,通过移动右“ }
” 4个空格,就像这样:
m["test"] = Vertex{
12.0, 100,
}
..然后输出更改为:
{40.68433 74.39967}
map[test:{12 100} Bell Labs:{40.68433 74.39967}]
见鬼,为什么不说小的修改会影响我的地图的顺序?
地图“命令”取决于所使用的哈希函数。 哈希函数是随机的,以防止使用哈希碰撞拒绝服务攻击。 详情请参见问题跟踪:
http://code.google.com/p/go/issues/detail?id=2630
地图顺序是根据规范不能保证。 虽然在目前的去实现不这样做,未来的实现可能GC或其他操作,改变地图的没有地图的顺序由代码被修改过程中做一些压缩。 这是不明智的假设在规范中没有定义的属性。
地图是无序的组中的一个类型的元素的,称为元素类型,由一组另一种类型的唯一的密钥的索引,称为键类型。
一个地图不应该总是打印其关键元件的任何固定的顺序:
请参阅“ 去:什么决定了迭代顺序在地图键 ”
然而,在最新进入每周发布(在GO1可以预计将于本月底发布),迭代顺序是随机的(它开始于一个伪随机选择键,哈希码计算种植有伪随机数)。
如果您有每周发布(与GO1)编译你的程序,迭代顺序将在每次运行程序的时间是不同的。
据不完全阐明一样,在规范,但( 参考地图类型 ):
地图是无序的组中的一个类型的元素的,称为元素类型,由一组另一种类型的唯一的密钥的索引,称为键类型。
实际上,规格都拼出来,但对于语句部分 :
迭代顺序在地图未指定,并且不保证是从一次迭代到下一个相同的 。
- 如果尚未达到映射条目迭代过程中被删除,相应的迭代值将不会产生。
- 如果迭代过程中插入映射条目,该行为是依赖于实现的,但每个条目的迭代值将最多一次生产。
- 如果地图是nil,迭代次数为0。
这已经介绍了代码审查5285042 2011年10月:
运行时间:在地图迭代随机偏移
在去螺母螺纹指出:
“它的存在阻止人们做坏事的东西”的原因似乎特别弱。
避免恶意的哈希冲突使得很多更有意义 。
此外,该指针的代码能够在发展中恢复的存在是一个间歇性错误,很难通过工作的情况下的行为。
到帕特里克Mylund尼尔森回复:
丹注竟是为什么Python的开发者都不愿意采用哈希IV随机化的主要论点 - 它打破了他们的单元测试! PHP最终选择了不这样做的所有,而是限制了大小http.Request
头,和甲骨文等公司并不认为这是一个语言的问题都没有。
Perl中看到的问题和应用类似Go的修复,其于2003年列入的Perl 5.8.1。
我可能是错的,但我认为他们是唯一真正关心那么当本文提出:“ 通过算法复杂度攻击拒绝服务 ”攻击哈希表。
(最坏情况下的哈希表碰撞)
对于其他人,这一点,这变得非常流行大约一年前,是一个很好的激励:
“ 28c3:针对Web应用程序平台服务攻击有效的拒绝(YouTube影片,2011年12月) ”,它展示了如何在最流行的Web编程语言和平台(包括PHP,ASP.NET,Java的执行一个共同的缺陷,等)可以是(AB)用于迫使Web应用程序服务器使用CPU的99%,持续几分钟到几小时单个HTTP请求。
这种攻击主要是独立于底层的网络应用程序的,只是依赖于Web应用程序服务器通常是如何工作的一个共同的事实..