本教材由知了传课辛苦制作而成,仅供学习使用,请勿用于商业用途!如进行转载请务必注明出处!谢谢!

面试题

一、选择题

1.关于协程,下面说法正确是?

A. 协程和线程都可以实现程序的并发执行
B. 线程比协程更轻量级
C. 协程不存在死锁问题
D. 通过channel来进行协程间的通信

参考答案:AD

2.关于channel,下面语法正确的是()

A. var ch chan int B. ch := make(chan int) C. <- ch D. ch <- 参考答案:ABC D答案少了写入的数据:ch <- 3

3.关于同步锁,下面说法正确的是()

A. 当一个goroutine获得了Mutex后,其他goroutine就只能乖乖的等待,除非该goroutine释放这个Mutex
B. RWMutex在读锁占用的情况下,会阻止写,但不阻止读
C. RWMutex在写锁占用情况下,会阻止任何其他goroutine(无论读和写)进来,整个锁相当于由该goroutine独占
D. Lock()操作需要保证有Unlock()或RUnlock()调用与之对应

参考答案:ABC。Lock对应Unlock,RLock对应RUnlock

读写锁:
写锁:写写互斥,写读互斥
读锁:读读不互斥,读写互斥

4.关于channel的特性,下面说法正确的是()

A. 给一个 nil channel 发送数据,造成永远阻塞
B. 从一个 nil channel 接收数据,造成永远阻塞
C. 给一个已经关闭的 channel 发送数据,引起 panic
D. 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值

参考答案:ABCD

5.关于 channel 下面描述正确的是?

A. 向已关闭的通道发送数据会引发 panic;

B. 从已关闭的缓冲通道接收数据,返回已缓冲数据或者零值;

C. 无论接收还是发送,nil 通道都会阻塞;

参考答案及解析:ABC。

6.关于无缓冲和有冲突的channel,下面说法正确的是()

A. 无缓冲的channel是默认的缓冲为1的channel // 默认位0
B. 无缓冲的channel和有缓冲的channel都是同步的
C. 无缓冲的channel和有缓冲的channel都是非同步的
D. 无缓冲的channel是同步的,而有缓冲的channel是非同步的

参考答案:D。

7.关于select机制,下面说法正确的是()

A. select机制用来处理异步IO问题
B. select机制最大的一条限制就是每个case语句里必须是一个IO操作
C. golang在语言级别支持select关键字
D. select关键字的用法与switch语句非常类似,后面要带判断条件

参考答案:ABC

8下面代码输出什么?请简要说明。

type MyMutex struct { count int sync.Mutex } func main() { var mu MyMutex mu.Lock() var mu1 = mu mu.count++ mu.Unlock() mu1.Lock() mu1.count++ mu1.Unlock() fmt.Println(mu.count, mu1.count) } A. 不能编译; B. 输出 1, 1; C. 输出 1, 2; D. fatal error; 参考答案及解析:D。加锁后复制变量,会将锁的状态也复制,所以 mu1 其实是已经加锁状态,再加锁会死锁。 代码优化后的: func main() { var mu MyMutex mu.Lock() mu.count++ mu.Unlock() var mu1 = mu mu1.Lock() mu1.count++ mu1.Unlock() fmt.Println(mu.count, mu1.count) }

二、简答题

1.select是随机的还是顺序的?

随机的

2.协程,线程,进程的区别?

进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元;

同一个进程中可以包括多个线程;

进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束;

线程共享整个进程的资源(寄存器、堆栈、上下文),一个进程至少包括一个线程;


线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源;

进程是资源分配的单位

线程是操作系统调度的单位

进程切换需要的资源很最大,效率很低 线程切换需要的资源一般,效率一般 协程切换任务资源很小,效率高 多进程、多线程根据cpu核数不一样可能是并行的 也可能是并发的。协程的本质就是使用当前进程在不同的函数代码中切换执行,可以理解为并行。 协程是一个用户层面的概念,不同协程的模型实现可能是单线程,也可能是多线程。

进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。(全局变量保存在堆中,局部变量及函数保存在栈中)

线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是这样的)。

协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。

一个应用程序一般对应一个进程,一个进程一般有一个主线程,还有若干个辅助线程,线程之间是平行运行的,在线程里面可以开启协程,让程序在特定的时间内运行。

协程和线程的区别是:协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力。

3.说说go语言中的协程?

协程和线程都可以实现程序的并发执行;

通过channel来进行协程间的通信;

只需要在函数调用前添加go关键字即可实现go的协程,创建并发任务;

关键字go并非执行并发任务,而是创建一个并发任务单元;

4.说说go语言的channel特性?

给一个 nil channel 发送数据,造成永远阻塞

从一个 nil channel 接收数据,造成永远阻塞

给一个已经关闭的 channel 发送数据,引起 panic

从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值

无缓冲的channel是同步的,而有缓冲的channel是非同步的

5.说说go语言的select机制?

A. select机制用来处理异步IO问题

B. select机制最大的一条限制就是每个case语句里必须是一个IO操作

C. golang在语言级别支持select关键字

6.select可以用于什么?

常用于gorotine的完美退出
golang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作
每个case语句里必须是一个IO操作,确切的说,应该是一个面向channel的IO操作

7.主协程如何等其余协程完再操作

sync.WiteGroup

Add() 指定计数器
Done() 计数器减1
Wite() 等待计数器减为0,结束

8.sync.Once的作用?实现一个单例

sync.Once 是 Golang package 中使方法只执行一次的对象实现,作用与 init 函数类似。但也有所不同。

init 函数是在文件包首次被加载的时候执行,且只执行一次
sync.Onc 是在代码运行中需要的时候执行,且只执行一次
当一个函数不希望程序在一开始的时候就被执行的时候,我们可以使用 sync.Once 。

9.死锁条件,如何避免?

死锁产生的原因
1.系统资源的竞争导致系统资源不足,以及资源分配不当,导致死锁
2.请求和释放资源的顺序不当,会导致死锁
如何避免:
channel推送和读取同时存在时才不会发生死锁,而且需要注意channel读写的顺序,只读或只推都会发生死锁

1559人已阅读,今天你学习了吗?

添加新回复