go调度器:GMP模型,线程运行是goroutine的实体,调度器的功能是把可运行的goroutine分配到工作线程上。
(1)我们通过go func()来创建一个goroutine
(2)有两个存储G的队列,局部调度器P的本地队列,一个是全局G队列。新建的G会保留在P的本地队列,如果P的本地队列满了就保留在全局中。
(3)G只能运行在M中,一个M必须有一个P,M与P是1:1的关系。
(4)一个M调度G的过程,必须是一个循环机制;
(5)当M执行一个G如果发送syscall和阻塞,M会阻塞,如果当前有一部分G,runtime把M从P中摘除,再新建服务这些P;
(6)当M系统调用结束时候,这个G会尝试获取一个空闲的P执行,并放入到这个P的本地队列。
TCP协议之握手和挥手:TCP是一种面向连接的,可靠的,基于字节流的传输层通信协议,是端到端的传输,TCP提供稳定的链接服务,连接三次握手进行初始化的,又因TCP是双工模式,所以需要四次挥手关闭连接。
第一次握手:建立连接时,由客户端发送Sync包到服务端,并进入SYN_SEN状态,等待服务端确认;
第二次握手:服务端收到Sync包,确认客户端的Sync包,再给客户发送一个Sync包,进入SYN_RECV状态,等待客户端接受确认;
第三次握手:客户端接到服务端的Syn+ack包,向服务端发送确认包ack,之后客户端和服务端都进入ESTABLISH状态,表示TCP连接成功,即完成三次握手。
四次挥手,终止TCP连接,就是指断开一个TCP连接时需要客户端和服务端一共4个包确认链接的断开,双端都发送Fin包,首先关闭一方主动关闭,另一方则被动关闭。
第一次挥手:客户端发出连接释放报文Fin包,并停止发送数据,客户端进入FIN-WAIT-1状态。
第二次挥手:服务端接收到释放报文,发出确认ACK包,服务端进入CLOSE-WAIT。
第三次挥手:服务端将最后的数据发送完毕,向客户端发送释放报文Fin包,服务端进入LAST-ACK状态。
第四次挥手:客户端接收到服务端的连接释放报文,必须发出确认,客户端进入TIME-WAIT状态。此时TCP链接还没有释放,需经过2*MSL(最长报文寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
服务端收到客户端的确认即进入CLOSED状态。
切片:是数组连续片段的引用,结构体包含数组的指针,数组的量和容量。
切片的扩容就是append,如果在容量之内就append;超过了容量底层数组会复制到新的数组上去,容量扩充2倍,再append。
锁:保证线程安全,主要针对多个线程对一个全局变量修改,如果涉及读写用读写锁更好。
make和new的区别:new是golang的内建函数,用于分配内存,其中,第一个参数是类型,返回是类型的执政,其值被初始化为“零”;make是Golang的内建函数,仅用于分配和初始化slice、map以及channel类型的对象;返回具体类型,而不是指针。
Mysql索引底层原理:B+树存储的是数据的地址,一个节点可以存很多个数据,算法复杂度O(h*logn),大大减少了磁盘IO的读写次数。
go struct能不能比较:结构体里面有没有不可以比较的类型,切片类型不可以比较;譬如slice和map。
defer:defer调用链会在函数返回中增加一个函数调用,这个函数不是普通的函数,是在函数返回之后执行的。defer一般用来释放内存变量,遵循先进后出的原则。
select的作用:一个select语句用来选择哪个case中的发送或接收 *** 作可以被立即执行。他的case涉及到channel有关I/O *** 作,当I/O *** 作发生时,除非相应的 *** 作。如果有一个或者多个I/O *** 作,select会随机选择一个,否则会选择default;没有default,会阻塞。
context包的用途:context包提供上下文机制,在gourtine之间传递dealine,timeout,或者其他值请求信息。创建根 Context:context,backgroud;
channel无缓存和有缓存的区别:无缓存是来了个,消费一个;无缓存是未消费也可以继续入值,除非队列满了。
如何获取长连接:主要依赖Transport,Transport缓存了长连接,在大量请求http的场景;对连接的限制,譬如最大连接数,每个连接的超时时间。
map如何顺序读取:map不能顺序读取,因为他无序,想要有序就是把key放入切片,对切片排序。
实现set:Set主要是元素不能重复,和map的key一样。
var Exists = struct{}{}
//set类型
type Set struct {
m map[interface{}]struct{}
}
//返回一个set
func New(items ...interface{}) *Set {
s := &Set{}
s.m = make(map[interface{}]struct{})
_ = s.Add(items...)
return s
}
func (s *Set) Size() int {
return len(s.m)
}
// 添加元素
func (s *Set) Add(items ...interface{}) error {
for _, item := range items {
s.m[item] = Exists
}
return nil
}
//删除元素
func (s *Set) Remove(val int) {
delete(s.m, val)
}
//获取长度
func (s *Set) Len() int {
return len(s.m)
}
// 清空Set
func (s *Set) Clear() {
s.m = map[interface{}]struct{}
}
// 遍历set
func (s *Set) Traverse() {
for v := range s.m {
fmt.Println(v)
}
}
// 包含
func (s *Set) Contains(item interface{}) bool {
_, ok := s.m[item]
return ok
}
实现消息队列(多生产者,多消费者):可以用channel,ch <- x ;用range和select遍历channel。大文件排序:利用堆实现优先队列,head底层是树pop算法复杂度是O(log(n))。
type InitHeap []int
func (h InitHeap) Len() int { return len(h) }
func (h InitHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h InitHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *InitHeap) Push(x interface {}) {
*h = append(*h, x.(int))
}
func (h *InitHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n - 1]
*h = old[0: n - 1]
return x
}
Golang内存分配:golang的内存分配源自Google的tcmalloc算法,核心思想是内存的多级管理,进而降低锁的粒度;将内存按需划成大小不一的块,减少内存的碎片化。为每个p,也就是go协程调度模型了里面的逻辑处理器维护一个mcache结构体的独立内存池,只有当该内存池不足时,才会向全局mcentral和mheap结构体管理的内存池申请。为每一个P维持一个私有的本地内存池,从而不用加锁,加快了内存分配速度。只有在本地P的内存池被消耗完,或者申请的内存太大时,才会访问全局的内存池,大大减少了多线程下对全局内存池访问带来的竞争系统消耗。
Golang垃圾回收:GC机制三色标记,遍历根对象的第一层标记为灰色,不可达标记为白色;将灰色对象的下一层可达对象标记为灰色,自身标记为黑色;多次重复步骤2,直到灰色对象为0,只剩下白色对象和黑色对象;sweep白色对象。
Golang实现单例模式:懒汉模式(加锁)、或者用Once:
懒汉模式:
type Singleton struct {
num int
}
var ins *Singleton
var mu sync.Mutex
func GetInstance() *Singleton {
if ins == nil{
mu.Lock()
defer mu.Unlock()
ins = &Singleton{}
}
return ins
}
Once:
type Singleton struct {
num int
}
var ins *Singleton
var once sync.Once
func GetInstance() *Singleton {
once.Do(func() {
ins = &Singleton{}
})
return ins
}
基本排序,哪些是稳定的:插入排序,稳定;选择排序,不稳定;堆排序,不稳定;冒泡排序,稳定;快速排序,不稳定;归并排序,稳定。Get和Head:都是请求资源,get方法会获取实际的资源,而head方法只返回响应头,属于Get请求的轻量版,避免传输body的浪费。401/403: 401是未授权,403是服务器禁止。http能不能一次链接屡次请求,不等后端返回:http本质上是使用socket连接,因此发送请求,接写入tcp缓冲,是可以多次进行的,这也是http是无状态的原因。TCP和UDP的区别和优缺点:TCP是面向连接的,UDP是面向无连接的;TCP提供可靠的服务,也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按需到达;UDP尽最大努力交付,即不保证可靠交付,适用于高速传输和实时性要求较高的通信和广播领域。time-wait:就是tcp释放连接的四次挥手后的主动关闭连接方的状态。time-wait的持续时间是2MSL,MSL是Maximum Segment Lifetime,译为报文最大生存时间;原因1:保证客服端发送的最后一个ack报文段送达服务器,断开不能按正常步骤进入close状态导致服务器资源的浪费。原因2:2MSL时间足以让报文段从网络消失,不然对面可能会收到异常的SYNC包。数据库创建索引:CREATE INDEX myIndex ON db(keyname);
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)