golang深入理解

1、select是随机的还是顺序的?select的使用场景?

select会随机选择一个可用通道做收发操作.
常用语gorotine的完美退出
golang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作
每个case语句里必须是一个IO操作,确切的说,应该是一个面向channel的IO操作

2、Go语言局部变量分配在栈还是堆?深入分析

Go语言编译器会自动决定把一个变量放在栈还是放在堆.
编译器会做逃逸分析,当发现变量的作用域没有跑出函数范围,就可以在栈上,反之则必须分配在堆。

3、简述一下你对Go垃圾回收机制的理解?golang GC

v1.1 STW
v1.3 Mark STW, Sweep 并行【优化STW】
v1.5 三色标记法【初始白色--> 灰色待处理队列--> 标记为黑色--> STW(sweep黑色)】
v1.8 hybrid write barrier(混合写屏障:优化STW)

4、golang的协程调度GMP原理? 【线程模型 M:N】

  • M(machine): 代表着真正的执行计算资源,可以认为它就是os thread(系统线程)。
  • P(processor): 是协程调度器。P的数量可以通过GOMAXPROCS设置。
  • G(goroutine): 调度系统的最基本单位goroutine,存储了goroutine的执行stack信息、goroutine状态以及goroutine的任务函数等。相当于OS的进程控制块PCB;它包含:函数执行的指令和参数,任务对象,线程上下文切换,字段保护,和字段的寄存器

调度器设计策略

1.复用线程:

  • work stealing机制:当本线程无可运行的Goroutine时,尝试从其他线程绑定的P队列偷取G,而不是消毁线程。
  • hand off机制:当本线程因为Goroutine进行系统调用阻塞时,线程释放绑定的P,把P转移给其它空闲的线程执行。

2.抢占:在goroutine中要等待一个协程主动让出CPU才执行下一个协程;在GO中,一个goroutine最多占用CPU 10ms, 防止其他goroutine被锁死。
3.利用并行:利用GOMAXPROCS设置P数量,最多有GPMAXPROCS个线程分布在多个CPU上同时执行。
4.全局G队列:当M执行work stealing从其它P的本地队列中偷不到G时,它可以从全局列队获取G.
5.自旋线程:

5、介绍下 golang 的 runtime 机制?深入分析

Runtime 负责管理任务调度垃圾收集运行环境。同时,Go提供了一些高级的功能,如goroutine, channel, 以及GC。
这些高级功能需要一个runtime的支持. runtime和用户编译后的代码被linker静态链接起来,形成一个可执行文件
这个文件从操作系统角度来说是一个user space的独立的可执行文件。
从运行的角度来说,这个文件由2部分组成,一部分是用户的代码,另一部分就是runtime。
runtime通过接口函数调用来管理goroutine, channel及其他一些高级的功能。从用户代码发起的调用操作系统API的调用都会被runtime拦截并处理。
Go runtime的一个重要的组成部分是goroutine scheduler。他负责追踪,调度每个goroutine运行,实际上是从应用程序的process所属的thread pool中分配一个thread来执行这个goroutine。
因此,和java虚拟机中的Java thread和OS thread映射概念类似,每个goroutine只有分配到一个OS thread才能运行。

6、如何获取 go 程序运行时的协程数量, gc时间, 对象数, 堆栈信息?

调用接口runtime.ReadMemStats可以获取以上所有信息, 注意: 调用此接口会触发 STW(Stop The World)

7、介绍下你平时都是怎么调试 golang 的 bug 以及性能问题的?

panic 调用栈 GDB
pprof
火焰图(配合压测)
使用go run -race 或者 go build -race 来进行竞争检测
查看系统 磁盘IO/网络IO/内存占用/CPU 占用(配合压测)

8、make 和 new 的区别

  • make和new都是golang用来分配内存的內建函数,且在堆上分配内存.
  • make 即分配内存,也初始化内存。new只是将内存清零,并没有初始化内存。
  • new(T)是为一个T类型的新值分配空间, 并将此空间初始化为T的零值, 并返回这块内存空间的地址, 也就是T类型的指针T, 该指针指向T类型值占用的那块内存.
  • new 分配返回的是指针,即类型 *Type。make 返回引用,即 Type。
  • make(T)返回的是初始化之后的T, 且只能用于slice, map, channel三种类型.
  • make(T, args) 返回初始化之后T类型的值, 且此新值并不是T类型的零值, 也不是T类型的指针T, 而是T类型值经过初始化之后的引用.

9、主协程如何等其余协程完再操作

使用channel进行通信,context,select

10、实现set

type inter interface{}
type Set struct {
    m map[inter]bool
    sync.RWMutex
}
 
func New() *Set {
    return &Set{
    m: map[inter]bool{},
    }
}
func (s *Set) Add(item inter) {
    s.Lock()
    defer s.Unlock()
    s.m[item] = true
}

11、defer关键字 defer使用的一些坑

  1. defer在匿名返回值和命名返回值函数中的不同表现
func watShadowDefer(i int) (ret int) {
    ret = i * 2
    if ret > 10 {
        ret := 10          // 新初始化了一个局部变量
        defer func() {
            ret = ret + 1  // defer 将当前作用域相关信息压栈
        }()
    }
    return  //100。知识点:变量作用域和defer 返回值。
}

func main() {
    result := watShadowDefer(50)
    fmt.Println(result)
}

12、slice切片:是对数组一个连续片段的引用,是一种引用类型

  • 切片提供了一个与指向数组的动态窗口
  • Go 中数组赋值和函数传参都是值复制的,而切片是引用传递的
  • 使用make创建切片:实现运行期动态指定数组长度,绕开编译期常量的限制
  • 切片扩容策略:小于1024个元素,翻倍扩容。超过1024后1.25倍扩容。
// 切片定义
type slice struct {
    array unsafe.Pointer
    len int
    cap int       // cap一定要比len大
}

// 从 slice 中得到一块内存地址
s := make([]byte, 200)
ptr := unsafe.Pointer(s[0])

// 从go的内存地址中构造一个slice
var ptr unsafe.Pointer
var s1 = struct {       //初始化一个结构体
    addr unitptr
    len int
    cap int
}{ptr, length, length}
s := *(*[]byte)(unsafe.Pointer(s1))   // ptr 转 slice

13、go切片的排序与查找操作,排序操作在sort包中

sort.Ints对整数进行排序,
sort.Strings对字符串进行排序,
sort.Float64对浮点数进行排序
var a = [...]int{1,8,38,2,348,484}   //数组是值类型,不能直接排序,必须转为切片    
sort.Ints(a[:])                      //SearchInts默认排序后的位置,一定要排序后在查找   
index:=sort.SearchInts(a[:],348)  

// 排序二维切片
intervals := [][]int{}
sort.Slice(intervals, func(i, j int) bool {
    return intervals[i][0]<intervals[j][0]
})

14、go函数不支持默认参数,不支持重载,不支持命名函数嵌套,匿名函数可以嵌套

  • Go函数从实参到形参的传递永远是值拷贝,,有时函数调用后实参指向的值发生了变化,是因为参数传递的是指针的拷贝,实参是一个指针变量,传递给形参的是这个指针变量的副本,实质上仍然是值拷贝;
  • 闭包
package main
import "fmt"

func Accumulate(a int) func(b int) int {
    return func(b int) int {
        return a + b
    }
}

func main() {
    accAdd := Accumulate(1)
    fmt.Println(accAdd(2))    // 3
    fmt.Println(accAdd(4))    // 5
}

15、在golang中可以给任意类型(除指针)添加相应方法

type Interger int

func (i Interger) Less (j Interger) bool {
    return i < j
}

func main() {
    var i Interger = 1
    fmt.Print(i.Less(5))
}

17 json与golang类型对应关系

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null

http请求时需要注意【不要连接完,立马defer】

resp, err := http.Get(url)
// 先判断操作是否成功
if err != nil {
    return err
}
// 如果操作成功,再进行Close操作
defer resp.Body.Close()

fallthrough 关键字的作用?

执行完fallthrough后直接跳到下一个条件语句,本条件执行语句后面的语句不执行

go 中除了加 Mutex 锁以外还有哪些方式安全读写共享变量? chan CSP

函数式选项(Functional Options)

关于Goroutine的启动和退出

golang实现协程池

go复合数据类型struct和json互相转换

在for循环中使用defer可能导致的性能问题

调用os.Exit时defer不会被执行

判断执行没有err之后,再defer释放资源

goroutine泄漏有没有处理,设置timeout,select加定时器

go的锁如何实现,用了什么cpu指令go锁的实现

go什么情况下会发生内存泄漏?

用channel实现定时器?(实际上是两个协程同步)

go为什么高并发好

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,783评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,396评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,834评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,036评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,035评论 5 362
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,242评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,727评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,376评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,415评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,463评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,140评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,734评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,809评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,028评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,521评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,119评论 2 341

推荐阅读更多精彩内容