1:go同步锁有什么特点,作用是什么?
当一个goroutine获得同步锁时,其他的只能等待。如果该gouroutine释放了读,其他可以读不可以写,但是在写占用时,其他不可读和写。作用是保证资源在使用时的独有性,不会因为并发而导致数据错乱,保证系统的稳定性。
2:go语言中channel有什么特点,需要注意什么,数据结构怎样?
先进先出,分为有缓存和无缓冲
给nil发或者从nil的channel接收都会永久阻塞。给已经关闭的channel发会Panic,从关闭的channel取,如果缓冲区中为空则会返回零值
无缓冲的channel是同步的,有缓存的是非同步的
参考于:百度安全验证https://baijiahao.baidu.com/s?id=1637513659872023994&wfr=spider&for=pc
lock:互斥锁,加锁-》把数据cpoy到队列(获取取出),修改sendx或者recvx的值对应buf的位置-》释放锁
sendq和recvq是双向链表:原因:在send和recv过程中获取当我位置比较方便,一直循环就行。依靠链表自身特性也符合先进先出。
buf:有缓存的才有,环形链表
sendx和recvx:记录buf中发送或者接收的可写的index
缓存满了存或者没有取就会阻塞goroutine,G1满了会主动调用GO的调度器,让出M给其他G使用,G1会被抽象成含有G1指针和send元素sudog结构体,保存到hchan的sendq中等待被唤醒。这是G2recv数据,channel会将等待队列中的G1推出,将G1send的数据推到缓存中,然后调用GO的schedule唤醒G1,把G1放到可以允许的gouroutine队列中。如果是取的过程阻塞,就是当G1推数据时,不会有锁操作,G1直接copy到G2栈中,减少了内存copy。
3:go的new和make有什么区别?
new : 分配空间,传递给new函数的是一个类型而不是值,返回的是新分配的地址的指针
make:为slice, map 或者chan初始化,返回引用。make函数目的和new不同,用于创建上面三类,返回的是类的实例
4:打印函数?
printf:标准化输出到屏幕,sprintf:格式化输出到字符串中,fsprintf:格式化字符串到文件中
5:数组和切片的区别?
数组的长度是数组类型的一部分,通过值传递
切片:指针,长度,容量三部分组成,地址传递通过数组或者make初始化,存在扩容
6:defer?
程序结束执行,return,panic都会执行,多个最后的先执行。
用于:打开释放锁,打开关闭连接
7:slice的底层实现?
基于数组实现,是底层数组的抽象,底层内存是连续分配的,效率很高,通过索引获取数据,可以迭代和垃圾回收优化。通过指针引用底层数组,切片本身非常小,只有三个字段:指向底层数组的指针,切片长度,切片容量。
切片的扩容策略:
1:新申请的大于2倍的旧容量,选择