看了这么多名校面试题,你对自己有信心吗?
go面试题整理(附带部分自己的解答)原文:【】
如果有解答的不对的 , 麻烦各位在评论写出来~
go的调度原理是基于GMP模型,G代表一个goroutine,不限制数量;M=machine , 代表一个线程,最大1万 , 所有G任务还是在M上执行;P=processor代表一个处理器 , 每一个允许的M都会绑定一个G,默认与逻辑CPU数量相等(通过runtime.GOMAXPROCS(runtime.NumCPU())设置) 。
go调用过程:
可以能,也可以不能 。
因为go存在不能使用==判断类型:map、slice,如果struct包含这些类型的字段,则不能比较 。
这两种类型也不能作为map的key 。
类似栈操作 , 后进先出 。
因为go的return是一个非原子性操作 , 比如语句return i ,实际上分两步进行,即将i值存入栈中作为返回值,然后执行跳转,而defer的执行时机正是跳转前,所以说defer执行时还是有机会操作返回值的 。
select的case的表达式必须是一个channel类型,所有case都会被求值 , 求值顺序自上而下,从左至右 。如果多个case可以完成 , 则会随机执行一个case,如果有default分支,则执行default分支语句 。如果连default都没有 , 则select语句会一直阻塞,直到至少有一个IO操作可以进行 。
break关键字可跳出select的执行 。
goroutine管理、信息传递 。context的意思是上下文,在线程、协程中都有这个概念,它指的是程序单元的一个运行状态、现场、快照,包含 。context在多个goroutine中是并发安全的 。
应用场景:
例子参考:
waitgroup
channel
len:切片的长度,访问时间复杂度为O(1),go的slice底层是对数组的引用 。
cap:切片的容量,扩容是以这个值为标准 。默认扩容是2倍,当达到1024的长度后,按1.25倍 。
扩容:每次扩容slice底层都将先分配新的容量的内存空间,再将老的数组拷贝到新的内存空间,因为这个操作不是并发安全的 。所以并发进行append操作,读到内存中的老数组可能为同一个,最终导致append的数据丢失 。
共享:slice的底层是对数组的引用,因此如果两个切片引用了同一个数组片段 , 就会形成共享底层数组 。当sliec发生内存的重新分配(如扩容)时,会对共享进行隔断 。详细见下面例子:
make([]Type,len,cap)
map的底层是hash table(hmap类型) , 对key值进行了hash , 并将结果的低八位用于确定key/value存在于哪个bucket(bmap类型) 。再将高八位与bucket的tophash进行依次比较 , 确定是否存在 。出现hash冲撞时,会通过bucket的overflow指向另一个bucket , 形成一个单向链表 。每个bucket存储8个键值对 。
如果要实现map的顺序读?。?需要使用一个slice来存储map的key并按照顺序进行排序 。
利用map , 如果要求并发安全,就用sync.map
要注意下set中的delete函数需要使用delete(map) 来实现,但是这个并不会释放内存,除非value也是一个子map 。当进行多次delete后,可以使用make来重建map 。
使用sync.Map来管理topic,用channel来做队列 。
参考:
多路归并法:
pre class="vditor-reset" placeholder="" contenteditable="true" spellcheck="false"p data-block="0"(1)假设有K路a href=""数据流/a , 流内部是有序的,且流间同为升序或降序;
/pp data-block="0"(2)首先读取每个流的第一个数,如果已经EOF,pass;
/pp data-block="0"(3)将有效的k(k可能小于K)个数比较,选出最小的那路mink,输出,读取mink的下一个;
推荐阅读
- java源代码成绩管理,java编写成绩管理系统
- 营销环境如何变化,营销环境的变化
- 虚拟主机欠费,虚拟主机不续费会怎样
- 直播运营与主播话术的区别,直播运营与主播话术的区别和联系
- 关于vb.nethwnd的信息
- 视频号推广健康产品怎么做,视频号推广给客户带来哪些好处?
- nba游戏篮网即时策略,nba游戏篮网即时策略网站
- 微信小程序外卖会员立减,微信小程序里的外卖券真的可以免费领吗?
- clean命令linux clean命令后找不到硬盘