Giter Site home page Giter Site logo

golang-design / go-questions Goto Github PK

View Code? Open in Web Editor NEW
5.7K 5.7K 642.0 19.76 MB

📖 Go 程序员面试笔试宝典 | 从问题切入,串连 Go 语言相关的所有知识,融会贯通。 https://golang.design/go-questions

Home Page: https://golang.design/go-questions

License: GNU General Public License v3.0

Go 100.00% Makefile 0.01%
book golang interview interview-questions

go-questions's People

Contributors

alilestera avatar banbo avatar changkun avatar chanyang97 avatar crazywr avatar cuishuang avatar dagsi avatar decade613 avatar felixseptem avatar fennay avatar hawken94 avatar latavin243 avatar minoic avatar oiar avatar qcrao avatar shenbinzai avatar simonwei97 avatar yangchen97 avatar yangwenmai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-questions's Issues

9页

实际描述

  • 原文页码:9
  • 原文段落:倒数第二个代码块
func() {
    t = t + 5
}

预期描述

func() {
t = t + 5
}()

修改后的段落

附图

必要时,请附上相关页面的照片或者截图

关于map 的 key类型

原文中这段不准确吧:

k1 == k2 时,可认为 k1 和 k2 是同一个 key。如果是结构体,则需要它们的字段值都相等,才被认为是相同的 key。

应该是hash后的值相等和字面值相等才是同一个key,很多字面值相等的,hash出来的值不一定相等,比如引用

请问一个关于 m 和主线程绑定的问题。(顺便提个 typo)

问题描述

作者你好,想请问下,关于书中第 201 页以及其他一些函数中会用到一个 get_tls 方法。我能理解汇编可以通过 fs 段找到 m.tls,但是想问下这里为啥不能直接在 m 这个结构体上获取 g 呀?比如在这个 schedinit 函数中,m0 就是和他同一个包的全局变量,直接从它身上把 m0.tls 捞出来再去拿 g,这样会有什么问题么?
另外还想请问下,所谓的把 m 和主线程绑定,我理解本质上就是通过系统调用把 m.tls[1] 的地址存到 fs 段指向的内存,这个的目的除了是可以直接通过汇编的方式以 fs 寄存器找到当前的 m.tls(比如 get_tls)之外,还有其他的什么作用么?
另外有个 typo,在图片中的 “BX 存器里面现在放的是当前 g 结构体对象的地址”中的 BX 后边少了个寄存器的 “寄”。
WechatIMG33

第三章:数据容器3.1.2-Page22

实际描述

  • 原文页码:P22
  • 原文段落:从上至下第三段
再次向S2追加元素200:
`s2 = append(s2, 100)`

预期描述

再次向S2追加元素200:
`s2 = append(s2, 200)`这里应该是200不是100

附图

必要时,请附上相关页面的照片或者截图

关于`如何实现字符串和byte切片的零拷贝转换` 字符串转切片代码的问题

问题描述

在线文档中看到字符串转切片的代码

//方法一
func string2bytes(s string) []byte {
	return *(*[]byte)(unsafe.Pointer(&s))
}

运行后转出来的切片cap字段值是824634806128,并且append操作会报如下错误

unexpected fault address 0x10a4280
fatal error: fault
[signal SIGBUS: bus error code=0x2 addr=0x10a4280 pc=0x108b0b6]

网上另一种方案,转出来后的切片是可以像正常切片一样append,修改。

//方法二
func string2bytes(s string) []byte {
	stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))
	bh := reflect.SliceHeader{
		Data: stringHeader.Data,
		Len:  stringHeader.Len,
		Cap:  stringHeader.Len,
	}
	runtime.KeepAlive(&s)
	return *(*[]byte)(unsafe.Pointer(&bh))
}

StringHeader 比 SliceHeader 缺少cap字段的,方法一这样转是不是存在问题?请您解答一下

Page 288 (并发标记清除法的难点是什么)

Page 288 (并发标记清除法的难点是什么)

  • 原文页码:288
  • 原文段落:
A.ref1 = nil:移除灰色对象 A 对白色对象 B 的引用(ref2)

预期描述

A.ref1 = nil:移除灰色对象 A 对白色对象 B 的引用(ref1)

第4章节

实际描述

  • 原文页码:73
  • 原文段落:
复制原文段落

预期描述

代码示例与讲解中图4-14的不符

修改后的段落

附图

必要时,请附上相关页面的照片或者截图

Page 192 typo

实际描述

  • 原文页码:192
  • 原文段落:第一段
G 变成 _Grunnale 状态之后

预期描述

G 变成 _Grunnable 状态之后

错误处理的As 和 Is 函数有误

实际描述

As 应该是判断是否为同一个类型,Is 是判断是否为同一个值

  • 原文页码:132
  • 原文段落:As 从 err 错误链里找到第一个和 target 相等的值并且设置为 target 。。。
复制原文段落

预期描述

修改后的段落

附图

必要时,请附上相关页面的照片或者截图

调度时机章节有误

实际描述

https://golang.design/go-questions/sched/when/

  • 原文页码:
  • 原文段落:
复制原文段落

image

预期描述

还包括 “函数调用”的时候,每个函数头都有一行栈检查代码。会有一个背景程序(来达到抢占式调度的目的)定时污染这个栈limit,导致程序进入runtime,
触发调度

参考 https://www.youtube.com/watch?v=-K11rY57K7k
52:24 function prologue
image

52:41 spoof stack limit

或者也可以参考 https://golangbyexample.com/goroutines-golang/
image

修改后的段落

附图

必要时,请附上相关页面的照片或者截图

关于Yuasa屏障的疑问

欧神好, 按照yuasa写屏障的图示, 当C作为黑色对象去引用白色对象B, Yuasa屏障将C变为灰色, B颜色不变. 这不是避免满足了条件1吗. 不允许黑色对象去引用白色对象..

切片作为函数参数这一章节,倒数第三段描述应该不准确

问题描述

请在此描述你的问题,提问前请参考提问的智慧

原文是这么说的:

myAppend 函数里,虽然改变了 s,但它只是一个值传递,并不会影响外层的 s,因此第一行打印出来的结果仍然是 [1 1 1]。

这个地方我在第一次看到的时候有点歧义,虽说slice是一个值传递,但是slice中是包含是指向数组的指针的。按理说,值传递的也是数组的指针。

经过验证,不影响的准确原因应该是append触发了slice的扩容,扩容会导致copy,也就是说slice结构体中指向数组的指针发生了变化。因此外层的s不会发生变化。
如果是直接修改slice元素,内外层都会改变

func myAppend(s []int) []int {
	//s = append(s, 100)
	s[0] = 100
	fmt.Printf("s point out func: %p, %p\n", s, &s)
	return s
}

我个人的理解,如有不对,欢迎讨论~

Page 289 关于写屏障

问题描述

原文

“因此我们所说的 Go 中的写屏障、混合写屏障,其实是指赋值器的写屏障,赋值器的写屏障作为一种同步机制,使赋值器在进行指针写操作时,能够“通知”回收器,进而不会破坏弱三色不变性。”

写屏障这样描述似乎有些容易和 memory barrier 混淆呢,gc barrier 只是插入的一些代码片段,而 memory barrier 则是一种并发同步操作。

14.1.8 节

实际描述

  • 原文页码:288
  • 原文段落:A.ref1 = nil: 移除灰色对象 A 对白色对象 B 的引用 (ref2);
A.ref1 = nil: 移除灰色对象 A 对白色对象 B 的引用 (ref2);

预期描述

根据第389页顶部的图 14-5 来看,A.ref1 = B,所以原句里括号的部分是 ref1 吧

A.ref1 = nil: 移除灰色对象 A 对白色对象 B 的引用 (ref1);

附图

必要时,请附上相关页面的照片或者截图

关于 Golang 内存分配机制 的延伸问题

问题描述

Golang 的内存分配机制有两大策略
顺序分配 (sequential allocation) 和
自由表分配 (free-list allocation)

其中,顺序分配比较迎合 Go Routine 的执行栈,因为一次可以分配整块内存空间

但是问题来了,Go Routine 的执行栈要扩容,如果用 自由表分配 扩容时,就不需要重新复制整个 Go Routine 的执行栈
所以 Golang 应是以 自由表分配 为主比较合理?

我的观点正确吗?谢谢

零拷贝实现string 和bytes的转换疑问

func string2bytes(s string) []byte {
	stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))

	bh := reflect.SliceHeader{
		Data: stringHeader.Data,
		Len:  stringHeader.Len,
		Cap:  stringHeader.Len,
	}

	return *(*[]byte)(unsafe.Pointer(&bh))
}

1,这里的Data 是一个uintptr整型,把stringHeader.Data作为值拷贝,后面gc不会移动或者回收该uintptr指向的内存吗?

2,在官方文档里面的描述是这样的:

// In general, reflect.SliceHeader and reflect.StringHeader should be used
// only as *reflect.SliceHeader and *reflect.StringHeader pointing at actual
// slices or strings, never as plain structs.
// A program should not declare or allocate variables of these struct types.
//	// INVALID: a directly-declared header will not hold Data as a reference.
//	var hdr reflect.StringHeader
//	hdr.Data = uintptr(unsafe.Pointer(p))
//	hdr.Len = n
//	s := *(*string)(unsafe.Pointer(&hdr)) // p possibly already lost

你的转换函数是不是换成下面的更好?

func string2bytes(s string) []byte {
	stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))

        var b []byte
        pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
        pbytes.Data = stringHeader.Data
        pbytes.Len = stringHeader.Len
        pbytes.Cap = stringHeader.Cap

	return b
}

1-map B=5时 bucket num 由 hash 的低 5 位决定

实际描述

B=5时 bucket num 由 hash 的低 5 位决定

  • 原文页码:1-map
  • 原文段落:310-313 行
	// 比如 B=5,那 m 就是31,二进制是全 1
	// 求 bucket num 时,将 hash 与 m 相与,
	// 达到 bucket num 由 hash 的低 8 位决定的效果
	m := uintptr(1)<<h.B - 1

预期描述

B为5时 bucket num 由 hash 的低 5 位决定

	// 比如 B=5,那 m 就是31,二进制是全 1
	// 求 bucket num 时,将 hash 与 m 相与,
	// 达到 bucket num 由 hash 的低 5 位决定的效果
	m := uintptr(1)<<h.B - 1

"GC 的认识" 文中写屏障部分有误

dijkstra style barrier 需要栈重扫,不是因为文中说的原因,而是因为 Go 中出于性能考虑不对栈上保存的指针加 barrier。这一点在 proposal 17503 中讲的很清楚:“However, it also has disadvantages. In particular, it presents a trade-off for pointers on stacks: either writes to pointers on the stack must have write barriers, which is prohibitively expensive, or stacks must be permagrey. Go chooses the later, which means that many stacks must be re-scanned during STW. ”

对于文中的 case,并不影响 GC 的正确性,只是让 GC 更加保守。即使没有栈重扫,那个被错误染黑的 A 在下次 GC 也会被回收掉。

Map 扩容过程描述错误

原文

搬迁的目的就是将老的 buckets 搬迁到新的 buckets。而通过前面的说明我们知道,应对条件 1,新的 buckets 数量是之前的一倍,应对条件 2,新的 buckets 数量和之前相等。

对于条件 1,从老的 buckets 搬迁到新的 buckets,由于 bucktes 数量不变,因此可以按序号来搬,比如原来在 0 号 bucktes,到新的地方后,仍然放在 0 号 buckets。

对于条件 2,就没这么简单了。要重新计算 key 的哈希,才能决定它到底落在哪个 bucket。例如,原来 B = 5,计算出 key 的哈希后,只用看它的低 5 位,就能决定它落在哪个 bucket。扩容后,B 变成了 6,因此需要多看一位,它的低 6 位决定 key 落在哪个 bucket。这称为 rehash。

条件1是buckets数量翻倍,条件2是sizeSameGrow,下面描述错误,与上下文不一致。

Page 64 4-3 recv workflow graph

实际描述

  • 原文页码:64
  • 原文段落:图 4-3
 缓冲区是否有数据?
- 是 ...
- 否 -> (返回true, true) -> 复制缓冲区元素

预期描述

 缓冲区是否有数据?
- 是 -> (返回true, true) -> 复制缓冲区元素
- 否 ...

所以如果没理解错的话,这好像是个比较大的错误了?

步调算法下界描述有误

从 Go 1.14 开始时 $h_t$ 增加了下界 0.6)

  • 原文页码:292
  • 原文段落:
计算 $H_T$ 的最终结论(从 Go 1.10 时开始 $h_t$ 增加了上界 $0.95 \rho$,从 Go 1.14 开始时 $h_t$ 增加了下界 0.6)

从 Go 1.14 开始时 $h_t$ 增加了下界 $0.6 \rho$

计算 $H_T$ 的最终结论(从 Go 1.10 时开始 $h_t$ 增加了上界 $0.95 \rho$,从 Go 1.14 时开始 $h_t$ 增加了下界 $0.6 \rho$)

附图

src code

image

纸质版印刷图片展示不友好

纸质版印刷图片展示不友好

  • 原文页码:P278/P306
  • 原文段落:书中的一些图片或图例使用不同颜色划分不同部分,在纸质版书中肉眼较难区分,阅读体验不好

预期描述

图片不同区域使用不同样式的点划线作为背景可以较好地在纸质书上实现区分效果,类似这样
image

go-questions/channel/graceful-close 文章内容疑似有误

实际描述

对 “IsClosed函数返回的结果仅代表那个瞬间” 的解释可能有笔下误。“IsClosed函数返回true,但这时有另一个goroutine关闭了channel” 应改为 “IsClosed函数返回false,但这时有另一个goroutine关闭了channel”

其次,IsClosed 函数返回的结果仅代表调用那个瞬间,并不能保证调用之后会不会有其他 goroutine 对它进行了一些操作,改变了它的这种状态。例如,IsClosed 函数返回 true,但这时有另一个 goroutine 关闭了 channel,而你还拿着这个过时的 “channel 未关闭”的信息,向其发送数据,就会导致 panic 的发生。当然,一个 channel 不会被重复关闭两次,如果 IsClosed 函数返回的结果是 true,说明 channel 是真的关闭了。

预期描述

其次,IsClosed 函数返回的结果仅代表调用那个瞬间,并不能保证调用之后会不会有其他 goroutine 对它进行了一些操作,改变了它的这种状态。例如,IsClosed 函数返回 false,但这时有另一个 goroutine 关闭了 channel,而你还拿着这个过时的 “channel 未关闭”的信息,向其发送数据,就会导致 panic 的发生。当然,一个 channel 不会被重复关闭两次,如果 IsClosed 函数返回的结果是 true,说明 channel 是真的关闭了。

哈希表的遍历顺序是否有问题?

原文中提到

这样,遍历结果集变成:
遍历结果

按照文中描述,从3号桶的2号cell开始往后顺序遍历。但我翻看了一下文中所使用的1.9.2的源码以及最新的go1.17.5的源码,发现不管哪个Go版本,桶的遍历顺序是3->0->1->2,但每个桶内都要从offset处开始遍历,而不是前后首尾相接的遍历。所以最终的遍历顺序应该是egfcbhda,而不是efgbchad

不知道我是否理解错误,欢迎讨论。

关于 P 的状态流转

问题描述

image

请问这个 P 的状态流转图中:_Prunning -> _Pidle 由 retake 方法触发是否准确呢(图中红色线框)?

我猜测指的是:随着 preempt 发生,G 解绑后,进入新的调度,此时发现该 P 没有可运行的 G 了,然后还是调用的 releasep 方法将 P 的状态由 _Prunning 改为 _Pidle 的?

垃圾回收机制图片错误

实际描述

  • 原文页码:
  • p290 p291
  • 原文段落:
    图14-16和图14-7
    图14-16的Dijxxxx(C.ref3, C.ref2,ref1)的逗号应该变成点Dijxxxx(C.ref3, C.ref2.ref1)
    图14-7的Yuasaxx(A.ref3,B)应该变成Yuasaxx(C.ref3,B)
    还有这两幅图和你博客上的出入非常大,你可以仔细对比下,希望尽快纠正

图片

图片

【数组和切片】关于超过数组的上限赋值给新对象不会panic的讨论

不会Panic的写法

testSlice := [...]int{1, 2}
newTestSlice := testSlice[2:]
for _, v := range newTestSlice {
	log.Print(v)
}

会Panic的写法

testSlice := [...]int{1, 2}
newTestSlice := testSlice[3:]
for _, v := range newTestSlice {
	log.Print(v)
}

output:

invalid slice index 3 (out of bounds for 2-element array)

直接取 testSlice[2] 也会报panic。


以上情况能加到数组和切片中去说明一下吗?

第12章节

实际描述

  • 原文页码:240
  • 原文段落:
    12.14.1
复制原文段落

这时和P绑定的G正在进行系统调用,无法执行其他的G

预期描述

应该是P绑定的M正在进行系统调用?

修改后的段落

附图

必要时,请附上相关页面的照片或者截图

Page 32 annotation typo

实际描述

  • 原文页码:32
  • 原文段落:第 2 个代码块
// 初始化 hamp

预期描述

// 初始化 hmap

有关优雅关闭channel的问题

问题描述

尊敬的作者您好, 请问在书中78页提供的“有关优雅关闭channel的样例代码“中,假如sender向中间人(toStop)发起关闭的dataCh的信号时,不会出现dataCh无法被完全消费,从而导致内存泄漏的风险吗?

目录中文章顺序有误

”调度器“一章中,“描述scheduler的初始化过程”和“主goroutine如何创建“两节顺序颠倒了

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.