- 切片与数组的对比
- 在go语言中,new和make的区别
- Printf(),Sprintf(),Fprintf()函数的区别用法是什么
- Go语言中的引用类型包含哪些
- 解释以下命令的作用
- 说说go语言中的协程
- go语言中指针运算有哪些
- go语言中的for循环
- Go语言中共的switch语句
- go语言中没有隐藏的this指针,这句话是什么意思
- map如何顺序读取
- slice,len,cap,共享,扩容
- 说说go语言的main函数
- 说说go语言的同步锁
- 说说go语言的channel特性
- 说一说进程、线程、协程的区别
- Go struct能不能比较
- select可以用于什么
- context包的用途
- 主协程如何等待其余协程完成后再操作
- 实现消息队列
- select是随机的还是顺序的
- 介绍下平时怎么调试golang的bug以及性能问题的
- select的随机性
- 切片输出
切片与数组的对比
- 数组
- 数组是具有固定长度且拥有零个或者多个相同数据类型元素的序列
- 数组的长度是数组类型的一部分,所以
[3]int
和[4]int
是两种不同的数组类型 - 数组需要指定大小,不指定也会根据初始化自动推算出大小,不可改变
- 数组是值传递
- 数组是内置(build-in)类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值。在初始化后长度是固定的,无法修改其长度。当作为方法的参数传入时将复制一份数组而不是引用同一指针,数组的长度也是其类型的一部分,通过内置函数len(array)获取其长度
切片
- 切片表示一个拥有相同类型元素的可变长度的序列
- 切片是一种轻量级的数据结构,他有三个属性:指针、长度和容量
- 切片是地址传递
- 切片可以通过数组来初始化,也可以通过内置函数make()初始化,初始化时len=cap,在追加元素时如果容量cap不足时将按len的2倍扩容
- 切片的结构如下
type Slice struct {
ptr unsafe.Pointer
len int
cap int
}
关系
一个底层数组可以对应多个slice,这些slice可以引用数组的任何位置,彼此之间的元素还可以重叠。
在go语言中,new和make的区别
- New
- new的作用时初始化一个指向类型的指针(*T)
- new函数是内建函数,函数定义:func new(Type) *Type
- 使用new函数来分配空间。传递给new函数是一个类型,不是一个值。返回值是指向这个新分配的零值的指针。
- make
- Printf() 是把格式字符串输出到标准输出,是和标准输出文件(stdout)关联的,Fprintf则没有这个限制
- Sprintf() 是把格式字符串输出到指定字符串中,所以参数比printf多一个
char*
,那就是目标字符串地址 Fprintf() 是把格式字符串输出到指定文件设备中,所以参数比printf多一个文件指针
FILE*
,主要用于文件操作。Fprintf()是格式化输出到一个stream,通常是文件Go语言中的引用类型包含哪些
数组切片、字典(map)、通道(channel)、接口(interface),其他都是值类型
解释以下命令的作用
go env 用于查看go的环境变量
- go run 用于编译并运行go源码文件
- go build 用于编译源码文件、代码包、依赖包
- go get 用于动态获取远程代码包
- go install 用于编译go文件,并将编译结构安装到
bin
、pkg
目录 - go clean 用于清理工作目录,删除编译和安装遗留的目标文件
- go version 用于查看go的版本信息
说说go语言中的协程
是什么
进程和线程是操作系统内核实现的系统资源分配调度的单元(进程是资源分配和调度的基本单元,线程是处理器调度和分配的基本单元),相比而言,协程是一种程序自己实现的调度方式,它不是被操作系统内核所管理的,而是完全由程序所控制的。Go语言中的协程是由go实现的,用于实现程序并发执行的基本单元。
为什么
使用多线程和多进程总是存在一个问题,因为线程和进程是由内核实现的,在创建多线程和多进程的过程中难免需要成本进行创建和管理(系统调用开销,上下文切换开销,状态保存开销,在多线程中还有同步竞争的问题),会伴随着高CPU调度消耗和高内存占用(进程占用4GB,线程占用4MB)。因此,考虑在内核空间中建立一些线程,然后在用户空间中开辟一些协程去与其绑定以减少系统资源的开销。
怎么做
在go语言中,在函数调用前添加go关键字即可实现go的协程,创建并发任务。在协程运行的过程中,可以通过channel来进行协程间的通信(本质就是共享一块内存)
go语言中指针运算有哪些
&
取指针的地址-
go语言中的for循环
for循环支持
continue
和break
来控制循环,但是它提供了一个更高级的break,可以选择中断哪一个循环- for循环不支持以逗号为间隔的多个赋值语句,必须使用平行赋值的方式来初始化多个变量
Go语言中共的switch语句
- 单个case中,可以出现多结果选项
只有在case中明确添加
fallthrough
关键字,才会继续执行紧跟的下一个casego语言中没有隐藏的this指针,这句话是什么意思
方法施加的对象显式传递,没有被隐藏起来
- golang的面向对象表达更加直观,对于面向过程只是换了一种语法形式来表达
-
map如何顺序读取
map不能顺序读取,因为它是无序的,想要有序读取,首先解决的问题就是把key变为有序,所以可以把key放入切片,对切片进行排序,遍历切片,通过key取值
slice,len,cap,共享,扩容
append函数,因为slice底层数据结构是由数组、len、cap组成,所以,在使用append扩容时,会查看数组后面有没有连续内存块,有就在后面添加,没有就重新生成一个大的数组
说说go语言的main函数
main函数不能带参数
- main函数不能定义返回值
- main函数所在的包必须为main包
-
说说go语言的同步锁
当一个goroutine获得了Mutex后,其他goroutine就只能乖乖的等待,除非该goroutine释放了Mutex
- RWMutex读锁占用的情况下,会阻止写,但不阻止读
- RWMutex在写锁占用的情况下,会阻止任何其他goroutine(无论读和写)进来,整个锁相当于由该goroutine独占。
说说go语言的channel特性
- 给一个nil channel发送数据,造成永久阻塞
- 给一个nil channel接收数据,造成永久阻塞
- 给一个已经关闭的channel发送数据,引起panic
- 从一个已经关闭的channel接收数据,如果缓冲区中为空,则返回一个零值
- 无缓冲的channel是同步的,而由缓冲的channel是非同步的。 ```go c1:=make(chan int) 无缓冲
c2:=make(chan int,1) 有缓冲
<a name="IPCS8"></a>
# go语言触发异常的场景有哪些
1. 空指针解析
1. 下标越界
1. 除数为0
1. 调用panic函数
<a name="7Wvak"></a>
# 说说go语言的beego框架
1. beego是一个golang实现的轻量级HTTP框架
1. beego可以通过注释路由、正则路由等多种方式完成url路由注入
1. 可以使用bee new工具生成空工程,然后使用bee run命令自动热编译
> gin框架
1. gin 的orm
`gorm`是go语言中实现数据库访问的ORM(对象关系映射)库。使用这个库,我们可以利用面向对象的方法,更加方便地对数据库中地数据进行CRUD
<a name="NvyT1"></a>
# 说说go语言地goconvey框架(测试)
1. goconvey是一个支持golang的单元测试框架
1. gocenvey能够自动监控文件修改并启动测试,并可以将测试结果实时输出到web界面
1. goconvey提供了丰富的断言简化测试用例的编写
<a name="QjRBZ"></a>
# go语言中,gostub的作用是什么(测试)
1. gostub可以对全局变量打桩
1. gostub可以对函数打桩
1. gostub不可以对类成员方法打桩
1. gostub可以打动态桩,比如对一个函数打桩后,多次调用该函数会有不同的行为
<a name="V2jWX"></a>
# 说说go语言的select机制
1. select机制用来处理异步IO问题
1. select机制最大的一条限制就是每个case语句里必须是以一个IO操作
1. golang在语言级别支持select关键字
```go
//select基本用法
select {
case <- chan1:
// 如果chan1成功读到数据,则进行该case处理语句
case chan2 <- 1:
// 如果成功向chan2写入数据,则进行该case处理语句
default:
// 如果上面都没有成功,则进入default处理流程
说一说进程、线程、协程的区别
Go struct能不能比较
因为是强类型语言,所以不同类型的结构不能做比较,但同一类型的实例值是可以比较的,实例不可以比较,因为是指针类型。
select可以用于什么
常用于goroutine的完美退出,golang的select就是监听I/O操作,当IO发生时,触发相应的动作
每个case语句里必须是一个IO操作,确切的说,应该是一个面向channel的IO操作
context包的用途
context通常被译作上下文,它用于上下层的传递,可以用于goroutine间传递
主协程如何等待其余协程完成后再操作
使用channel进行通信、context、select,waitgroup
实现消息队列
select是随机的还是顺序的
select会随机选择一个可用通道做收发操作
介绍下平时怎么调试golang的bug以及性能问题的
panic调用栈,pprof,go run -race
,查看系统 磁盘IO/网络IO/内存占用/CPU占用
IO : pidstat -u 1
网络IO: netstat -antop |grep 1.1.1.1
内存: pidstat -r 1
上下文切换: pidstat -w -p 1234
select的随机性
select会随机选择一个可用通道做收发操作,所以代码是有可能触发异常,也可能不会。单个chan如果无缓冲时,将会阻塞,但结合select可以在多个chan间等待执行,有三点原则: