2.Go 语法背后的秘密

  1. 可以讲一下 「一个无聊的输出顺序的问题」吗?
  2. 老师可以推荐适合小白的, 编译原理方面的入门书籍吗?
  3. SSA的static赋值有作用域一说吗
  4. 老师能讲下逃逸分析吗?还有逃逸分析是在编译阶段发生的吗?
  5. 看到汇编中有SB和SP,这两是指啥?SP好像是栈寄存器,SB是什么?
  6. spec 里面东西随着版本的变动大吗?
  7. new 的时候的 zero 地址在什么样的情况下会发生, zero地址是什么?
  8. 编译后的地址就是虚拟内存的地址么?
  9. runext是有什么优先级吗?chan,timer这种和平常的goroutine优先级一致吗?
  10. 接3.无聊的输出顺序,左边那个为什么条件是i<258的时候,第一个输出的就是0了,而不是257。 (别忘记魔数61)
  11. 可以直接用goland工具debug底层实现吗?
  12. 从全局队列里取goroutine时候,全局加锁是为了避免其他p也从全局队列获取吗?
  13. 通过函数初始化多了一个步骤,也就多注册了一个函数,编译时还能优化掉这个函数还是会给它分配资源?
  14. quintptr、mintptr、puintptr、guintptr这个结构是干啥的?
  15. 为什么findrunnable要分为top和stop?
  16. time.Sleep 1.14 后不会创建 goroutine,那执行完输出后就会全局阻塞一个 g 阻塞在 sleep,但是为啥不会被 syncmon checkdead 触发 panic
  17. new(T) 是否可以参考src/cmd/compile/internal/gc/walk.go func walkexpr 下的case ONEW
  18. go tool compile 和go tool objdump的区别
  19. go里面的反射是否能拿到代码里面的注释部分,比如函数上面的注释部分。
  20. 为啥说rpc性能慢? rpc和grpc 是一会事么? grpc也是类似编译为二进制传输? 性能慢么?
  21. g.m.spinning中的spinning是什么
  22. runtime.getg()的实现在ssa里面好像不是全平台代码都能对应的上,其他架构的对应函数实现怎么看得到呢?
  23. ppt上的代码comment和swagger json是对应的吗?看不出来规律呀?
  24. 函数栈那部分没听懂,能再讲一下么?
  25. 理解函数调用规约需要哪些预备知识? 老师有什么函数规约方面的入门书推荐?
  26. 1.17版本的函数参数传递会发生什么变化呢?
  27. es的那个词法分析转换的工具有地址啥的吗?
  28. 进不去,直接把这个https:/golang.org/doc/manage-install下下来放coding
  29. 用Go实现类似Lua的语言动态拓展,技术上可行吗?
  30. 这个场景 封装统一的数据查询服务,是不是没有说
  31. return addr 和 parent return addr 是同一个值吗?指的下一条指令的地址吗?
  32. 问一下 为什么go的默认开启p的数量是cpu核数相同?
  33. 当一个协程变成runable的时候 会给放在全局的协程队列还是 那个p的本地队列?
  34. 语法糖是什么,为什么map[string]string能返回一个参数也能返回两个,其他的不行
  35. 如何对 Go 程序绑核?

可以讲一下 「一个无聊的输出顺序的问题」吗?

  • runnext 优先级 > local run queue > global run queue,后创建的 goroutine 优先进 runnext,并且会把之前的踢进 local run queuetime.Sleep 是否会创建 goroutine,在 1.13(包括)之前,
  • time.Sleep 内部会创建 goroutine,从 1.14 以后,time.Sleep 不会创建 goroutine 了

老师可以推荐适合小白的, 编译原理方面的入门书籍吗?

SSA的static赋值有作用域一说吗

  • 静态单赋值(Static Single Assignment、SSA)是中间代码的特性,如果中间代码具有静态单赋值的特性,那么每个变量就只会被赋值一次
  • 这个 static 和 C 一类的语言中的 static 不是一回事

老师能讲下逃逸分析吗?还有逃逸分析是在编译阶段发生的吗?

  • runtime.newobject 表示堆上分配对象,可以在 go tool compile -S 中看到调用这个函数
  • 逃逸分析是在编译阶段做的,因为生成出来的代码已经要决定好对象是在栈上还是在堆上分配了
  • 逃逸分析的具体原理和过程会在内存分配这一节讲的老师

看到汇编中有SB和SP,这两是指啥?SP好像是栈寄存器,SB是什么?

  • SB static base 静态基地址寄存器,runtime.g0(SB),类似这样的全局变量,在汇编代码中都有 SB 标记 SP 指向当前函数栈顶

spec 里面东西随着版本的变动大吗?

  • sl := make([]int, 10); ssl := sl[10:] 为什么不会 panic 呢,类似这样的用法,在 spec 里就会和你说,这样写是合法的spec
  • 修改一般不大,在加新功能,或者是老的功能描述不清,有人提 issue 的话,会做澄清和修改,大部分情况下都不怎么变

new 的时候的 zero 地址在什么样的情况下会发生, zero地址是什么?

  • 所有堆上分配的,大小为 0 的对象,都会复用一个 runtime 内部的全局变量,叫做 runtime.zerobase
  • zerobase 场景: m := map[int]struct{}{}
    1
    2
    // base address for all 0-byte allocations
    var zerobase uintptr

编译后的地址就是虚拟内存的地址么?

  • 是的

runext是有什么优先级吗?chan,timer这种和平常的goroutine优先级一致吗?

  • runnext -> local -> global 优先级降低。
  • 如果在 runtime 内部,比如 timer 实现中创建了额外的 goroutine,它们和用户创建的优先级是一致的(所以有时候会有一些问题)

接3.无聊的输出顺序,左边那个为什么条件是i<258的时候,第一个输出的就是0了,而不是257。 (别忘记魔数61)

可以直接用goland工具debug底层实现吗?

  • 可以的,不过可以会碰到被优化的函数跳转有点失灵的情况
  • 实在不行可以自己加 println,观察并发执行结果的时候加额外的打印信息比较方便

从全局队列里取goroutine时候,全局加锁是为了避免其他p也从全局队列获取吗?

  • 加锁保证并发安全这里
  • 可以思考一下为什么没有像局部队列那样用无锁队列

通过函数初始化多了一个步骤,也就多注册了一个函数,编译时还能优化掉这个函数还是会给它分配资源?

  • 优化掉了
  • 优化过程可以通过 SSAFUNC=xxx go build 生成 ssa.html
  • 在生成的网页中寻找优化操作

quintptr、mintptr、puintptr、guintptr这个结构是干啥的?

  • 都是对应的一个结构的指针,开头字母感觉是助记的。。

为什么findrunnable要分为top和stop?

  • 这么长的函数。。不分没法看了。就是简单逻辑分块
  • stop 过程最后是要让 m 去休眠,但在休眠前要做一些“垂死挣扎”,尝试找找能执行的 g,再找不到就去休眠了

time.Sleep 1.14 后不会创建 goroutine,那执行完输出后就会全局阻塞一个 g 阻塞在 sleep,但是为啥不会被 syncmon checkdead 触发 panic

  • 因为 time.Sleep 逻辑上会结束的啊,time.Sleep(time.Second),从逻辑上来讲它就不是一个死锁场景
  • 下面是我们学员在阅读 checkdead 代码后的补充:
    图片

new(T) 是否可以参考src/cmd/compile/internal/gc/walk.go func walkexpr 下的case ONEW

  • 是要去读编译器的代码,这个对新人比较劝退,等熟悉了以后再说
  • 想知道详情的同学可以在慕课问答区问这个问题,可以做一些说明

go tool compile 和go tool objdump的区别

  • compile 把 go -> 编译 -> .o 文件, .o -> link -> 可执行文件
  • objdump 把可执行文件 -> 反编译 -> 汇编

go里面的反射是否能拿到代码里面的注释部分,比如函数上面的注释部分。

为啥说rpc性能慢? rpc和grpc 是一会事么? grpc也是类似编译为二进制传输? 性能慢么?

  • 乙方卖一个 api gateway 的产品,假如设计类似 nginx,把流程拆成多个 phases,用户想扩展 router phase,需要写代码
  • 几万 QPS, RPC slow
  • encode,compile
  • single process vs process <-rpc-> process

g.m.spinning中的spinning是什么

  • 线程自旋状态
  • 自旋一般都是认为自己短时间能够获取到任务,所以执行循环以等待任务 ready 的一种逻辑

runtime.getg()的实现在ssa里面好像不是全平台代码都能对应的上,其他架构的对应函数实现怎么看得到呢?

  • amd64,慕课问答区问吧,这个还是有点难的

ppt上的代码comment和swagger json是对应的吗?看不出来规律呀?

  • ppt 不是对应的。。
  • 写 ppt 的时候没来得及搞个 demo,这个可以自己探索一下~

函数栈那部分没听懂,能再讲一下么?

理解函数调用规约需要哪些预备知识? 老师有什么函数规约方面的入门书推荐?

1.17版本的函数参数传递会发生什么变化呢?

es的那个词法分析转换的工具有地址啥的吗?

进不去,直接把这个https:/golang.org/doc/manage-install下下来放coding

用Go实现类似Lua的语言动态拓展,技术上可行吗?

这个场景 封装统一的数据查询服务,是不是没有说

图片

return addr 和 parent return addr 是同一个值吗?指的下一条指令的地址吗?

问一下 为什么go的默认开启p的数量是cpu核数相同?

  • 利用多核优势,让每个核心都有活干
  • 大多数生产消费程序,worker 数都 = 核心数,比如 nginx

当一个协程变成runable的时候 会给放在全局的协程队列还是 那个p的本地队列?

  • 比如:M 从 syscall,看身上绑定的 P 是不是已经没了,没了的话就进全局
  • 其它场景可以按我们第一课的 PPT 里的例子,看一下对应的 goready 流程

语法糖是什么,为什么map[string]string能返回一个参数也能返回两个,其他的不行

  • 语法糖:糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。比如 ch <- 1 就是典型的语法糖。
  • 能返回一个,也能返回两个,是在编译器中做了特殊处理,最终会被翻译成不同的 runtime 函数:v, ok := m[“a”]. =>. mapaccess2v := m[“a”] => mapaccess

如何对 Go 程序绑核?

  • 研究一下 linux 下的 taskset 工具

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 lihuanjie113@gmail.com

×

喜欢就点赞,疼爱就打赏