写在前面
面试过程中经常会被问到有没有看过go的源码,如果没有看过那面试效果就大打折扣了,这个问题如何解决呢?
首先问有没有看过go的源码,一般就是想问有没有看过go的slice,map,channel的底层实现(当然还有其他的一些,比如singleflight, syncmap,sync包的WaitGroup,Mutex等等)。在面试过程中,只需要看过一个知识点的源码,是不是比说没看过强?
那看哪一个知识点呢?slice和map考察的最多,而且查考的点都是扩容。slice扩容最简单,那我们就看slice的底层源码。
slice 源码看什么
一般面试官问slice的源码是在问什么?除了扩容机制,它没有东西可问。go 1.22.1版本中的slcie实现,算上注释也才370行代码,而扩容函数只有算上注释只有30多行代码,所以我们只需要阅读这30多行的代码,就可以说看过go的源码了。
面试官:有没有看过go的源码。
答:看过一些,尤其是slice的源码,看过它的扩容机制。
这个时候面试官就会让你讲一下go slice的扩容机制了。
源码
func nextslicecap(newLen, oldCap int) int {
newcap := oldCap
doublecap := newcap + newcap
if newLen > doublecap {
return newLen
}
const threshold = 256
if oldCap < threshold {
return doublecap
}
for {
// Transition from growing 2x for small slices
// to growing 1.25x for large slices. This formula
// gives a smooth-ish transition between the two.
newcap += (newcap + 3*threshold) >> 2
// We need to check `newcap >= newLen` and whether `newcap` overflowed.
// newLen is guaranteed to be larger than zero, hence
// when newcap overflows then `uint(newcap) > uint(newLen)`.
// This allows to check for both with the same comparison.
if uint(newcap) >= uint(newLen) {
break
}
}
// Set newcap to the requested cap when
// the newcap calculation overflowed.
if newcap <= 0 {
return newLen
}
return newcap
}
这段代码逻辑非常简单,希望读者能仔细阅读一下,记住这段逻辑,面试的时候有大用。
下面画个图说明一下代码逻辑
结束语
��完这段slice扩容代码,你就可以有底气的跟面试后说你看过go的源代码了