[吐血整理]超全golang面试题合集+golang学习指南+golang知识图谱+成长路线 | Go 技术论坛 (learnku.com)
1.引用传递 ?值传递?
go语言没有引用传递,只有值传递。
和cpp不一样,cpp有值传递,指针传递,和引用传递;go只有前两种,但本质都是传值。
【Go 进阶】Go 语言到底是值传递,还是引用传递?(一)-阿里云开发者社区 (aliyun.com)
但是类型有引用类型和值类型。
- 值类型:变量直接存储值,内存通常在
栈上分配
,栈在函数调用完会被释放。比如:int
、float
、bool
、string
、array
、sturct
等。- 引用类型:变量存储的是一个地址,这个地址存储最终的值。内存通常在
堆上分配
,通过GC回收。比如:slice
,map
,channel
,interface
,func
等。
- 严格来说,Go 语言没有引用类型,但是我们可以把
map、chan、func、interface、slice
称为引用类型,这样便于理解。- 指针类型也可以理解为是一种引用类型
这里提到了堆和栈,简单介绍下内存分配中的堆和栈:
栈
(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。堆
(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
2.go的几种类型转换
「GO」关于Golang中的类型转换 (baidu.com)
golang强制类型转换和类型断言_Golang_脚本之家 (jb51.net)
3.Docker和K8s是什么
10分钟看懂Docker和K8S - 知乎 (zhihu.com)
Docker是一个轻量级容器,可以允许很多程序在隔离的容器内运行不会相互影响,代替以往在虚拟机上运行项目的做法。
大家需要注意,Docker本身并不是容器,它是创建容器的工具,是应用容器引擎。
就在Docker容器技术被炒得热火朝天之时,大家发现,如果想要将Docker应用于具体的业务实现,是存在困难的——编排、管理和调度等各个方面,都不容易。于是,人们迫切需要一套管理系统,对Docker及容器进行更高级更灵活的管理
K8S,就是基于容器的集群管理平台,它的全称,是kubernetes。
一个K8S系统,通常称为一个K8S集群(Cluster)。
这个集群主要包括两个部分:
- 一个Master节点(主节点)
- 一群Node节点(计算节点)
Master节点主要还是负责管理和控制。Node节点是工作负载节点,里面是具体的容器。
4.go语言定义变量时是否需要置0
go - Go语言中初始化和归零,new()和make()的区别 - IT工具网 (coder.work)
在C语言中,局部变量在声明时,并不会对变量对应内存区域进行清理操作。此时,变量值可能是完全不可预期的结果。开发者需要习惯在使用C语言进行声明时要初始化操作,稍有不慎,就会造成不可预知的后果。而全局变量会默认初始化。
go在声明变量时,自动对变量对应的内存区域进行初始化操作。每个变量会初始化其类型的默认值,例如:
- 整型和浮点型变量的默认值为 0 和 0.0。
- 字符串变量的默认值为空字符串。
- 布尔型变量默认为 bool。
- 切片、函数、指针变量的默认为 nil。
- 当然,依然可以在变量声明时赋予变量一个初始值。
5.context.Context
Golang context.Context 原理,实战用法,问题 - 掘金 (juejin.cn)
context 是 Golang 从 1.7 版本引入的一个标准库。
理解 context 提供的能力,关键记住三个词:deadline, cancellation, metadata。
// 一个 Context 对象包含了截止时间, 取消信号,以及请求级别的键值等属性 type Context interface { // 如果context可被cancel,返回一个chan,当context被cancel后,chan会被close // 如果context不能被cancel,则返nil Done() <-chan struct{} // 当 Done() 返回的channel被关闭后,Err 可以读取到这个 Context 被取消的原因 Err() error // 返回context被cancel的deadline,ok==false代表没有deadline Deadline() (deadline time.Time, ok bool) // Value 返回和 key 关联的值,若无此key则返回nil Value(key interface{}) interface{} }
Context 本质就是一个 interface,实现这四个方法的对象都可以理解为是一个 Context
GO 语言context.Context类型 - 简书 (jianshu.com)
6.nil切片和空切片区别
Go常见错误集锦之令人困惑的nil切片和空切片 - 知乎 (zhihu.com)
长度为0叫空切片
nil定义:nil是为pointer、channel、func、interface、map或slice类型预定义的标识符,代表这些类型的零值。
空切片只要长度为0,nil切片一定是空切片,但是他的ptr指针字段不指向任何数组。
- nil切片的长度和容量都是0,空切片的长度为0,容量由指向的底层数组决定
- 空切片 != nil切片
- nil切片的ptr指针是nil,而空切片的ptr指针指向底层数组的地址
- nil切片也切片,具有和普通切片相同的行为,所以nil切片具有切片同样的行为操作,可以放心使用。
json序列化时,nil切片会变成null,而空数组会变成[ ]
7.字符串和byte数组的转换发生拷贝?
只要强转都会发生拷贝
-
那么如果想要在底层转换二者,只需要把
StringHeader
的地址强转成SliceHeader
就行。那么go有个很强的包叫unsafe
。-
1.
unsafe.Pointer(&a)
方法可以得到变量a
的地址。 -
2.
(*reflect.StringHeader)(unsafe.Pointer(&a))
可以把字符串a转成底层结构的形式。 -
3.
(*[]byte)(unsafe.Pointer(&ssh))
可以把ssh底层结构体转成byte的切片的指针。 -
4.再通过
*
转为指针指向的实际内容。
-
8.含有中文的字符串能否用些类型切片强转
golang面试题:翻转含有中文、数字、英文字母的字符串 (qq.com)
只要类型表示范围能够表示中文即可
9.拷贝大切片一定比小切片代价大吗
都是一样的,因为一个切片只含有三个元素,一个uintptr和两个int,所以无论大小切片拷贝都只会拷贝这三个,和指针指向的数组大小无关
type SliceHeader struct {
Data uintptr
Len int
Cap int
}