Go学习日记12

1.gorilla/websocket
解析:go get github.com/gorilla/websocket
[1]open Socket.onopen:连接建立时触发
[2]message Socket.onmessage:客户端接收服务端数据时触发
[3]error Socket.onerror:通信发生错误时触发
[4]close Socket.onclose:连接关闭时触发

2.Gorilla mux
解析:实现Request的router和dispatch功能。

3.协程
解析:协程在有的资料中称为微线程或者用户态轻量级线程,协程调度不需要内核参与而是完全由用户态程序来决定,因此协程对于系统而言是无感知的。协程由用户态控制就不存在抢占式调度那样强制的CPU控制权切换到其他进线程,多个协程进行协作式调度,协程自己主动把控制权转让出去之后,其他协程才能被执行到,这样就避免了系统切换开销提高了CPU的使用效率。

4.抢占式调度和协作式调度
解析:
[1]抢占式调度:用于进程/线程,系统内核调度,特点是数量有限、成本大、效率低。
[2]协作式调度:用于协程,用户态调度,特点是数量达、成本低、效率高。

5.同步和异步
解析:同步是指应用程序发起I/O请求后需要等待或者轮询内核I/O操作完成后才能继续执行,异步是指应用程序发起I/O请求后仍继续执行,当内核I/O操作完成后会通知应用程序或者调用应用程序注册的回调函数。

6.Go调度器的GPM模型
解析:GPM模型使用一种M:N的调度器来调度任意数量的协程运行于任意数量的系统线程中,从而保证了上下文切换的速度并且利用多核,但是增加了调度器的复杂度。
[1]逻辑处理器:执行创建的goroutine,绑定一个线程
[2]调度器:Go运行时中的,分配goroutine给不同的逻辑处理器
[3]全局运行队列:所有刚创建的goroutine都会放到这里
[4]本地运行队列:逻辑处理器的goroutine队列

7.Goroutine整个生存期不同状态切换
解析:
[1]_Gidle:刚刚被分配并且还没有被初始化
[2]_Grunnable:没有执行代码、没有栈的所有权、存储在运行队列中
[3]_Grunning:可以执行代码、拥有栈的所有权,被赋予了内核线程M和处理器P
[4]_Gsyscall:正在执行系统调用、拥有栈的所有权、没有执行用户代码,被赋予了内核线程M但是不在运行队列上
[5]_Gwaiting:由于运行时而被阻塞,没有执行用户代码并且不在运行队列上,但是可能存在于Channel的等待队列上
[6]_Gdead:没有被使用,没有执行代码,可能有分配的栈
[7]_Gcopystack:栈正在被拷贝、没有执行代码、不在运行队列上

8.new()和make区别
解析:
[1]*func new(Type) Type:new(T)为每个新的类型T分配一片内存,初始化为0并且返回类型为*T的内存地址:这种方法返回一个指向类型为T值为0的地址的指针,它适用于值类型如数组和结构体;它相当于&T{}。
[2]func make(t Type, size …IntegerType) Type:make(T)返回一个类型为T的初始值,它只适用于3种内建的引用类型:切片、map和channel

9.Delve
解析:Delve is a debugger for the Go programming language.

10.标准库encoding/json
解析:实现了json对象的编解码。

11.协程和线程之间的关系
解析:
[1]协程:独立的栈空间,共享堆空间,调度由用户自己控制,本质上有点类似于用户级线程,这些用户级线程的调度也是自己实现的。
[2]线程:一个线程上可以跑多个协程,协程是轻量级的线程。

12.读写锁与互斥锁
解析:读写锁与互斥锁最大的不同就是可以分别对读、写进行锁定。一般用在大量读操作、少量写操作的情况。
说明:互斥锁sync.Mutex用在写多、读少的情况。

13.testing包
解析:它要求以*_test.go新建文件,并在文件中以TestXxx命名函数。然后再通过go test [flags] [packages]执行函数。它也提供了三种类型的函数:测试函数T、基准测试函数B、实例函数Example。除此之外,Go的标准库提供了一个httptest的库,通过它就能够轻松的完成HTTP的测试。

14.sync包
解析:
[1]Mutex:互斥锁
[2]RWMutex:读写锁
[3]WaitGroup:并发等待组
[4]Once:执行一次
[5]Cond:信号量
[6]Pool:临时对象池
[7]Map:自带锁的map

15.sync.Mutex
解析:sync.Mutex是一个互斥锁,它的作用是守护在临界区入口来确保同一时间只能有一个线程进入临界区。假设info是一个需要上锁的放在共享内存中的变量。通过包含Mutex来实现的一个典型例子如下:

import "sync"
type Info struct {
    mu sync.Mutex
    // ... other fields, e.g.: Str string
}

如果一个函数想要改变这个变量可以这样写:

func Update(info *Info) {
    info.mu.Lock()
    // critical section:
    info.Str = // new value
    // end critical section
    info.mu.Unlock()
}

16.container/list包
解析:list包实现了一个双链表[doubly linked list]。如下所示:

package main
import (
	"container/list"
	"fmt"
)
func main() {
    // 创建一个新的链表,并向链表里面添加几个数字
	l := list.New()
	e4 := l.PushBack(4)
	e1 := l.PushFront(1)
	l.InsertBefore(3, e4)
	l.InsertAfter(2, e1)
    // 遍历链表并打印它包含的元素
	for e := l.Front(); e != nil; e = e.Next() {
		fmt.Println(e.Value)
	}
}

17.Go同步原语与锁
解析:锁是一种并发编程中的同步原语[Synchronization Primitives],它能保证多个Goroutine在访问同一片内存时不会出现竞争条件[Race condition]等问题。
[1]常见同步原语sync.Mutex、sync.RWMutex、sync.WaitGroup、sync.Once和sync.Cond
[2]常见扩展原语errgroup.Group、semaphore.Weighted和singleflight.Group的实现原理,同时也会涉及互斥锁、信号量等并发编程中的常见概念。

18.运行时异常和panic
解析:
[1]panic可以直接从代码初始化:当错误条件很严苛且不可恢复,程序不能继续运行时,可以使用panic函数产生一个中止程序的运行时错误。panic接收一个做任意类型的参数,通常是字符串,在程序死亡时被打印出来。
[2]标准库中有许多包含Must前缀的函数,像regexp.MustComplie和template.Must,当正则表达式或模板中转入的转换字符串导致错误时,这些函数会panic。

参考文献:
[1]delve:https://github.com/go-delve/delve
[2]Golang Sync包:https://studygolang.com/articles/23697
[3]
[4]

你可能感兴趣的:(大数据和云计算)