教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 golang key map 所有_Golang面试知识点总结

golang key map 所有_Golang面试知识点总结

发布时间:2021-04-13   编辑:jiaochengji.com
教程集为您提供golang key map 所有,Golang面试知识点总结等资源,欢迎您收藏本站,我们将为您提供最新的golang key map 所有,Golang面试知识点总结资源

根据多次面试经历,总结下golang开发需要掌握的知识点

1.slice和数组的区别

slice是数组的快照,slice底层数据是一个结构体,包含三个元素,长度、容量和数组指针。所以slice的赋值就如同结构体的赋值一样,slice的应用其实都是对数组指针的操作。注意点:对slice的操作会影响到所有引用到底层数组的slice。

func sliceModify(slice []int) {
    newSlice := slice
    newSlice[0] = 88
}
func main() {
    array := [5]int{1, 2, 3, 4, 5}
    slice := []int{1, 2, 3, 4, 5}
    arrayModify(array)
    sliceModify(slice)
    fmt.Println(array)
    fmt.Println(slice)
}

在这个例子中在函数中切片的更改会影响到函数外的切片,数组不会。

2.slice扩容

  • 如果切片的容量小于1024个元素,那么扩容的时候slice的cap就翻番,乘以2;一旦元素个数超过1024个元素,增长因子就变成1.25,即每次增加原来容量的四分之一。
  • 如果扩容之后,还没有触及原数组的容量,那么,切片中的指针指向的位置,就还是原数组,如果扩容之后,超过了原数组的容量,那么,Go就会开辟一块新的内存,把原来的值拷贝过来,这种情况丝毫不会影响到原数组。

3.append方法

在slice末尾添加元素,且长度加1,如果长度没有超过原数组的容量,则返回的还是指向原数组的slice,否则就是指向新数组的slice。

4.defer的实现原理

简述下defer实现原理,G1.13及以前都通过编译器将defer转化成汇编语言的函数调用,将方法名及参数入栈(其实是个链表),每有一个defer都会在头部插入链表结构体,结构里存有方法名和入参参数,如果不是defer后面是个表达式或者其他,编译器也是把它变成一个函数。多个defer的执行是跟defer所在位置正好相反的,越靠前越后面执行,在函数return的时候,编译器在return的汇编语言中插入代码,做如下操作。

1.保存返回值

2.将defer的栈链表取出,出栈执行defer方法。

3.将返回值返回。

package main
func main() {    
    println(DeferFunc1(1))  
    println(DeferFunc2(1))  
    println(DeferFunc3(1))
}
func DeferFunc1(i int) (t int) {
    t = i   
    defer func() {
        t  = 3
    }() 
    return t
}
func DeferFunc2(i int) int {
    t := i  
    defer func() {
        t  = 3
    }() 
    return t
}
func DeferFunc3(i int) (t int) {    
    defer func() {
        t  = i
    }() 
    return 2
}

这道的输出非常有意思,首先DeferFunc1的返回是t,return的时候先保存t,然后执行deferfunc(){ t =3}(),t的值为i,i为1,t最后是4,最后将返回值t返回,输出4。

DeferFunc2的返回值式匿名的,所以return的时候保存匿名变量,值为t,也就是1,然后执行函数,t为4,返回匿名变量值为1,输出1。

DeferFunc3同样保存t,值为2,执行defer函数后,t的值为3,返回t,输出3。

值得一提的是Go1.14对defer进行了优化,defer不再编译成入栈操作的函数,而是直接整块移动到return操作的第二步,执行defer方法。这一编译器的实现大大提高了defer执行效率。

局限性在于defer操作是可以在编译时预知一定会执行的话,才会被优化,将defer操作放到if和for下,只有执行时才知道defer会不会执行的话,就不会优化。

https://blog.csdn.net/u010853261/article/details/102692305 golang defer原理

http://xiaorui.cc/archives/6579 go1.14实现defer性能大幅度提升原理

5.简述map的结构

map是由桶数组组成,map会把key通过hash得到的字符串分成两部分,一部分第八位作为数组的下标,一部分作为桶内高八位hash数组的值 ,桶外通过数组映射,桶内通过遍历数组元素总数为8的hash数组。map除此之外还有B扩容次数,溢出桶、及哈希种子等比较重要的结构。

6.为什么桶内的元素要用遍历而不用映射呢?

在数量较小的情况下,遍历的效率比映射快,所以go的map采用了这个设计。

7.map如果遇到hash冲突,怎么处理?

map查找元素,除了要匹配桶中高八位hash外,还会通过指针位移找到存储的原始key,如果再次匹配key才会取value,当hash冲突,桶内还有位置,只会把冲突hash放到空位上,虽然桶内有两个一模一样的hash,但因为要进行key的比较才会取value,所以不会有任何问题。当桶内位置不够时,会再取一个溢出桶,放到当前桶的后面,就像链表的结构。遍历完当前桶,再遍历溢出桶。

到此这篇关于“golang key map 所有_Golang面试知识点总结”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
golang key map 所有_Golang面试知识点总结
golang map 锁_Golang线程安全的map
golang map 锁_golang中线程安全的map
golang map多层嵌套使用及遍历方法汇总
Golang从入门到放弃200618--Map(1)Map的初始化和基本操作
golang map key 正则表达_Golang中的Map
golang key map 所有_Golang基础教程——map篇
golang key map 所有_golang系列——高级语法之map
golang key map 所有_golang推断map中指定key是不是存在_后端开发
golang 初始化并赋值_golang语言中map的初始化及使用示范

[关闭]
~ ~