Go相较其他语言的优势

1
2
3
Golang在语言层次支持高并发
Golang的代码默认执行GoFmt格式化,保证代码风格统一
Golang的垃圾回收与程序可以同时进行,效率比Java、python更有效

Go的数据类型

1
2
3
4
5
6
7
8
9
10
11
12
1.布尔类型(bool
2.数值类型,包括整数(int,int8,int16,int32,int64)、无符号整数(uint,uint8,uint16,uint32,uint64,uintptr)、浮点数(float32, float64)
3.复数类型(complex64complex128)
4.字符串类型(string
5.数组类型(array)
6.切片类型(slice)
7.字典类型(map
8.通道(channel)
9.指针(pointer)
10.结构体类型(struct
11.接口类型(interface
12.函数类型(func

Go程序中的包

1
2
3
包(PKG)是Go工作区中包含Go源文件或其他包的目录,源文件的每个函数、变量、类型都存储在包中,每个源文件都属于一个包。
声明:package
导入:import

nil切片和空切片的区别

1
2
3
切片的底层数据结构是 SliceHeader,包含切片引用数组指针地址、切片长度、切片容量。
nil切片的引用数组指针地址为0(无指向实际地址)
空切片的引用数组指针地址为固定值

字符串转成[]byte数组,会发送内存拷贝吗?

1
2
3
正常类型强转都是会发送内存拷贝的
字符串的底层数据结构 StringHeader 切片的底层数据结构 SliceHeader
如果想要不发生内存拷贝,需要使用unsafe进行底层数据结构转换

拷贝大切片一定比小切片代价大吗?

1
2
切片底层数据结构 SliceHeader 包含切片引用数组指针地址、切片长度、切片容量
大切片和小切片的拷贝就是拷贝3个字段

reflect(反射包)如何获取字段tag?为什么json包不能导出私有变量的tag?

1
2
先使用TypeOf获取numfield成员数量信息,再遍历每个成员,使用.Tag().Get("")获取指定tag内容(可以获取私有字段内容)
json包认为私有字段是不可导出内容,直接忽略跳过

Struct可以比较吗

1
2
3
答:
1、结构体中包含不可比较字段(切片、mapfunc等),无法比较。
2、相同类型的结构体变量才可以比较,否则编译无法通过,类型不匹配

接口变量可以比较吗?

1
2
3
4
答:
1、通常情况下,接口变量可以比较,当接口的动态类型及动态值是相等的,则相等
2、当接口的动态类型为同一个不可比较类型(切片、mapfunc等),无法比较

Go ⽀持什么形式的类型转换?

1
go只支持显示类型转换,因为go的类型要求是严格的

Goroutine和线程的区别?

1
2
3
4
5
6
7
8
9
调度上:
- 线程由OS内核调度,线程切换需要完整的上下文切换,调度和切换成本高
- Goroutine由Go调度器调度,不需要切换内核态,调度开销小。
栈空间上:
- OS线程有一个固定大小的栈,通常为2MB
- Goroutine的栈空间更灵活,栈空间不固定,生命周期开始只是一个很小的栈,典型情况为2kb,所以go可以一次性创建百万级别的Goroutine,可以动态伸缩,最大限制可以1G。
标识上:
- 大部分线程都有一个独特的标识,通常为整数或指针,依赖这个特性可以实现线程局部性
- Goroutine没有特定的标识,是一种纯函数的理念。go官方是希望程序员不要依赖线程局部导致不健康的超距作用,为此,Go官方提高channel管道,推荐goroutine+channel实现go对goroutine的控制

进程、线程、协程的区别

1
2
3
4
答:
- 进程是系统资源分配的基本单位,拥有独立的内存空间,不同进程通过进程间通信,比较重量,上下文切换开销大,但是相较稳定
- 线程是进程的实体,CPU调度的基本单位,只拥有基本的资源(程序计数器、寄存器、栈),与同属一个进程的其他线程共享进程所拥有的资源。线程间通信主要靠共享内存,上下文切换开销小,但相较不稳定
- 协程是一种用户态的轻量级线程,完全由用户控制,拥有独立的寄存器上下文和栈。协程切换不涉及内核态,上下文切换非常快。