Golang八股文面试题

2023-12-16 13:41:14

1、golang 中 make 和 new 的区别?(基本必问)

1.make和new都是golang用来分配内存的內建函
数,且在堆上分配内存,
2.make 即分配内存,也初始化内存。
3.new只是将内存清零,并没有初始化内存。
4.make返回的还是引用类型本身,make只能用来
分配及初始化类型为slice,map,channel的数据
5.new可以分配任意类型的数据
6.而new返回的是指向类型的指针。

2、数组和切片的区别 (基本必问)

1.内部结构
数组在内存中是一段连续的内存空间,元素的类型
和长度都是固定的。切片在内存中由一个指向底层
数组的指针、长度和容量组成,长度表示切片当前
包含的元素个数,容量表示切片可以扩展的最大元
素个数
2.长度
数组的长度在创建时指定,不能更改。切片的长度
可以动态扩展或收缩,可以根据需要自由调整。
3.使用方式
数组在使用时需要明确指定下标访问元素,不能动
态生成。切片可以使用 append 函数向其末尾添
加元素,可以使用 copy 函数复制切片,也可以
使用 make 函数创建指定长度和容量的切片

3、for range 的时候它的地址会发生变化么?for 循环遍历 slice 有什么问题?

1.地址没有发生变化
2.在使用 for range 语句遍历切片或数组时,
每次迭代都会返回该元素的副本,而不是该元素
的地址。这意味着,每次循环完成后,该元素所
对应的地址都是相同的(最后一个),并不会改变
3.for range循环的工作方式是为了优化性能和
降低内存分配。在for range中,迭代变量会被
重复使用,而不是在每次迭代中创建一个新的变量
这个设计选择有助于减少内存分配和提高性能。在
这种情况下,如果你尝试在循环中保存迭代变量的
地址,实际上保存的是同一个地址。因此,在循环
结束后,你可能会遇到保存的值都是最后一次迭代
的值的情况。这是Go语言中的一个设计决策,旨在
提高程序的性能。如果你需要在循环中保存每次迭
代的值,可以考虑在每次迭代中创建一个新的变量
来保存值,而不是直接使用迭代变量。这样可以确
保你在集合或数组中保存的是不同的地址而不是同
一个地址

package main
import "fmt"
type girl struct {
	Name string
	Age int
}
func main() {
	gl := make(map[string]*girl)
	studs := []girl{
		{Name: "Lili", Age: 23},
		{Name: "Lucy", Age: 24},
		{Name: "Han Mei", Age: 21},
	}
//错误的写法	
	for _, v := range studs {
		gl[v.Name] = &v
	}
//正确的写法
for _, v := range studs {
	temp := v
	gl[v.Name] = &temp
}	
	for mk, mv := range gl {
		fmt.Println(mk, "=>", mv.Age)
	}
}

4、go defer,多个 defer 的顺序,defer 在什么时机会修改返回值?(for defer)defer recover 的问题?(主要是能不能捕获)

1.在Go语言中,defer关键字用于延迟执行一个
函数调用,通常用于确保在函数执行结束后释放
资源或执行一些清理操作。关于defer的几个问题:
多个 defer 的顺序: 多个defer语句按照后进
先出(Last In, First Out,LIFO)的顺序
执行,即最后一个defer语句会最先执行,倒数
第二个会在倒数第一个之后执行,以此类推。
2.defer 在何时修改返回值: defer语句中
的函数调用是在包含它的函数执行完毕之后才执
行的。如果包含defer的函数有命名的返回值,
并且在defer语句执行时修改了这个返回值,那
么最终的返回值将是defer语句中修改后的值。

func example() (result int) {
    defer func() {
        result += 10
    }()
    return 5
}
在这个例子中,尽管return 5语句执行时返回
的是5,但由于defer中修改了result,实际上
最终的返回值是15。
3.defer与recover通常一起使用,用于处理
函数中的错误。recover只能捕获在同一个
goroutine中发生的panic,而且必须在defer
中调用。如果recover在没有发生panic的情况
下调用,它会返回nil
4.defer和recover是Go语言中用于处理资源
释放和错误恢复的重要机制。

5、 uint 类型溢出

Golang的uint类型溢出问题通常会在大量运算
中发生,特别是在涉及到大量循环或者大数运算时
当uint类型的值超过其最大值时,它会发生溢出,
然后从该类型的最小值开始循环,解决方案:
1.使用更大的数据类型:例如,如果你正在使用
uint32,你可以尝试升级到uint64。这将提供
更大的值范围,从而减少溢出的可能性。
2.添加溢出检查:在每次运算之后,你可以检查
结果是否小于任一操作数(假设我们只在正数上
进行操作)。如果是这样,那么就发生了溢出。
3.使用 math/big 包:对于非常大的数值,你
也可以考虑使用 math/big 包中的 Int 类型
这个类型可以处理任意大小的数值,但是运算速
度会慢一些。

文章来源:https://blog.csdn.net/weixin_38385580/article/details/135031009
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。