1.闭包
闭包浅显一些来说就是某个函数(包含某些变量)返回了一个函数。调用这个函数使得随时可以使用
每次调用都相当于创建了一个闭包环境
package main
import (
"fmt"
)
func a() func() int {
i := 0
b := func() int {
i++
fmt.Println(i)
return i
}
return b
}
func main() {
c := a()
c()
c()
c()
a() //不会输出i
}
2.接口
接口也是一种·type相当于java的object
package main
import "fmt"
// Sayer 接口
type Sayer interface {
say(content string)string
}
type dog struct {}
type cat struct {}
func (d *dog) say(content string)string {
fmt.Println(content)
return content
}
func (c *cat) say(content string)string {
fmt.Println(content)
return content
}
func main() {
var x Sayer // 声明一个Sayer类型的变量x
a := &cat{} // 实例化一个cat
b := &dog{} // 实例化一个dog
x = a // 可以把cat实例直接赋值给x
res1 := x.say("喵喵喵") // 喵喵喵
x = b // 可以把dog实例直接赋值给x
res2 := x.say("汪汪汪") // 汪汪汪
fmt.Println(res1,res2)
}
3.Raft算法
raft算法保证了分布式系统的 ap
主要两个功能:
1.leader election。
每个node有三种state: follower, candidate, leader
每个节点初始状态都是follower,一段时间之后(默认150-300mm)没有收到leader的心跳之后会变更为candidate,之后会给cluster中的全部node发送消息请求投票。票数过半,则变更为leader
2. log replication
一个集群中只有leader能change数据,当cliend有数据变更请求时,leader先做变更但是不提交事物,之后将变更伴随着下一次心跳同步给follower,follower收到变更之后变更数据但是不提交,返回给leader消息变更数据,leader等待回复的follower数量大于cluster中node数量的一半的时候则commit。最后发送给全部follower来commit。
想两个不好的场景:
1. 有两个follower同时变成candidate,如果这种现象发生那么会等下一轮投票。
2. 如果cluster集群无法通信会变成两个cluster,两个集群必然会导致数据不一致,raft无法保证数据的强consisitence,只能保证集群联通的时候数据一致。