Blog

从源码理解Go:map

2016-11-15
Go

map的内部结构 #

Go中的map使用哈希表实现的,在源码go runtime/hashmap.go中可以看到对应实现。

 1// A header for a Go map.
 2type hmap struct {
 3	// Note: the format of the Hmap is encoded in ../../cmd/internal/gc/reflect.go and
 4	// ../reflect/type.go. Don't change this structure without also changing that code!
 5	count     int // # live cells == size of map.  Must be first (used by len() builtin)
 6	flags     uint8
 7	B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
 8	noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
 9	hash0     uint32 // hash seed
10
11	buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
12	oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
13	nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)
14
15	// If both key and value do not contain pointers and are inline, then we mark bucket
16	// type as containing no pointers. This avoids scanning such maps.
17	// However, bmap.overflow is a pointer. In order to keep overflow buckets
18	// alive, we store pointers to all overflow buckets in hmap.overflow.
19	// Overflow is used only if key and value do not contain pointers.
20	// overflow[0] contains overflow buckets for hmap.buckets.
21	// overflow[1] contains overflow buckets for hmap.oldbuckets.
22	// The first indirection allows us to reduce static size of hmap.
23	// The second indirection allows to store a pointer to the slice in hiter.
24	overflow *[2]*[]*bmap
25}
26
27// A bucket for a Go map.
28type bmap struct {
29	// tophash generally contains the top byte of the hash value
30	// for each key in this bucket. If tophash[0] < minTopHash,
31	// tophash[0] is a bucket evacuation state instead.
32	tophash [bucketCnt]uint8
33	// Followed by bucketCnt keys and then bucketCnt values.
34	// NOTE: packing all the keys together and then all the values together makes the
35	// code a bit more complicated than alternating key/value/key/value/... but it allows
36	// us to eliminate padding which would be needed for, e.g., map[int64]int8.
37	// Followed by an overflow pointer.
38}

先删掉代码原有注释,以便于查看:

...

从源码理解Go:slice

2016-11-15
Go

slice的内部结构 #

一个slice本质上是一个数组的某个部分的引用。在go runtime/slice.go源码中定义了slice的结构:

1type slice struct {
2	array unsafe.Pointer
3	len   int
4	cap   int
5}

可以看到在Go的内部,slice是一个包含3个字段的结构体:

...

iptables入门:iptables的状态

2016-10-21
Iptables, Linux

iptables是带有状态机制的防火墙,可以跟踪连接状态,我们可以根据状态编写更细致的规则。 iptables可以跟踪一下四种状态:

  • NEW 客户端向服务端主机发出一个连接请求,该数据包的状态就是NEW
  • ESTABLISHED 连接建立后,使用该连接通信的数据包的状态就是ESTABLISHED
  • RELATED: 该数据包正在启动新的连接,它还和某个已经处于ESTABLISHED状态的连接有关系
  • INVALID 表示该数据包与任何已知的连接都不关联,数据包可能包含错误的头和数据,即无效的数据包,通常这种状态的数据包会被丢弃

例如:

...

iptables入门:iptables简介和命令

2016-10-20
Iptables, Linux

iptables是Linux中基于内核的防火墙,功能十分强大。 iptables工作在网络层,不需要把数据发送到用户空间,在系统内核空间中进行数据过滤可以保证数据处理效率。 当数据包到达iptables之后,如果MAC地址相符,就会由内核中的相应驱动程序接收,通过一系列操作决定将数据包发送给本地程序或转发到其他主机,或进行其他操作。 iptables由一系列表(table)组成,表再由一系列链(chain)组成,当数据包到达iptables之后,就会基于规则按一定顺序穿越不同的表和链。

...

简单理解Linux Swap Space

2016-10-20
Linux

理解Swap Space #

对服务器进行性能监控,除了CPU, 内存, 磁盘IO,网络外,Swap Space也是值得关注的关键项。

用户进程在内存空间中数据有以下形式:

  • 程序代码和共享库
  • 文件内容的缓存数据
  • 程序使用的堆栈空间

其中前两项都是从文件系统中读取进来的。

Linux本身是一个分页请求系统,用户进程使用的内存需要映射到物理内存。为了更好的使用内存,Linux会对物理内存中的页面进行回收:

...

配置MySQL多源复制

2016-10-14
Mysql

MySQL的多源复制(multi-source replication)允许将一个MySQL从库连接到多个主库,并从每个主库获取和复制数据更改。这种复制拓扑结构可以实现在多个数据库服务器之间进行数据同步和复制。

传统的MySQL复制是单源复制,其中一个主库(也称为主服务器或主节点)将其数据更新记录在二进制日志中,并将这些日志传播给一个或多个从库(也称为从服务器或从节点)。每个从库通过读取主库的二进制日志并应用这些更新来保持与主库的数据同步。

...

使用Docker快速搭建MySQL主从复制环境

2016-10-13
Mysql

MySQL常见复制模式 #

MySQL的常见复制模式(假设有DB1,DB2,DB3三个MySQL实例):

  • 主从复制 DB1 -> DB2
  • 主主复制 DB1 <- -> DB2
  • 链式复制 DB1 -> DB2 -> DB3
  • 环形复制 DB1 -> DB2 -> DB3 -> DB1

生产环境常见主从复制,这是最稳健的一种方式;为了切换方便也可选择主主模式,但要注意主主复制必须确保在任何时刻只有一个数据库是master写入状态,否则可能导致数据异常。 链式和环形复制在生产环境很少使用,主要的缺点是随着节点的增加整个复制系统的稳健性会下降。

...

Go编程的三十六个套路: int与[]byte互转用于数据传输

2016-03-01
Go

1. encoding/binary包简介 #

在用Go进行数据传输的场景下,例如文件传输或文件存储时,需要将Go的数据例如int转换为[]byte。 得到的[]byte可以进一步在网络上传输或写入到文件中。这个场景需要借助go标准库中的encoding/binary包来实现。

encoding/binary包实现了简单的数字与字节序列的转换以及变长值的编解码。 一个定长值是指要么是固定长度的数字类型(int8, uint8, int16, float32, complex64, …)或者只包含定长值的结构体或者数组。

...

Docker的资源限制

2016-02-07
Docker

Docker使用Linux Cgroups限制容器对CPU、内存等资源的使用,防止由于某个容器对资源的过度使用而导致主机上其他容器无法正常运行。 Cgroup是control group的简称,是Linux内核提供的一个特性,用于限制和隔离一组进程对系统资源的使用,包括CPU、内存、block I/O、网络带宽。

...

分布式跟踪系统Dapper的简单理解

2016-01-15
Tracing

现在一些开源的分布式调用跟踪系统大多都参考了Google的论文《Dapper,大规模分布式系统的跟踪系统》。 这里我们简单学习一下Dapper的基本概念。

分布式调用跟踪系统实际上是随着微服务才火起来的一个概念,当然Google在很多年前已经微服务化了,所以他的分布式跟踪理论应该是最成熟的。 分布式跟踪系统出现的原因简单的说是因为在分布式系统中一次请求中会包含很多的RPC,迫切需要一些可以帮助理解系统行为和分析性能问题的工具,需要断定具体哪个服务拖了后腿。

...

© 2024 青蛙小白