由于本人在准备找golang的春招实习,所以开此贴方便记录
golang 1.简述go语言GMP调度模型G:一个G代表一个goroutine,协程的本质是用户态的线程,用户对其有控制权限,内存占用少,切换代价低。
M:内核态线程,一个M代表了一个内核线程,等同于系统线程,所有的G都要放在M上才能运行。
P:处理器,用来管理和执行goroutine,一个P代表了M所需的上下文环境。P的个数取决于设置的GOMAXPROCS,go新版本默认使用最大内核数,比如你有8核处理器,那么P的数量就是8
三者关系:G需要绑定在M上才能运行,M需要绑定P才能运行。
M的数量和P不一定匹配,可以设置很多M,M和P绑定后才可运行,多余的M处于休眠状态。
系统会通过调度器从全局队列找到G分配给空闲的M,P会选择一个M来运行,M和G的数量不等,P会有一个本地队列表示M未处理的G,M本身有一个正在处理的G,M每次处理完一个G就从本地队列里取一个G,并且更新P的schedtick字段,如果本地队列没有G,则从全局队列一次性取走G/P个数的G,如果全局队列里也没有,就从其他的P的本地队列取走一半。
2.Goroutine 阻塞的话,是不是对应的M也会阻塞这要分为以下四种情况
1、由于原子、互斥量或通道操作调用导致 Goroutine 阻塞
该情况的G阻塞不会阻塞内核线程M,因此不会导致M的上下文切换而只涉及到G的切换。
2、由于网络请求和文件IO 操作导致 Goroutine 阻塞
该情况的G阻塞不会阻塞内核线程M,因此不会导致M的上下文切换而只涉及到G的切换。
3、由于调用time.Sleep或者ticker计时器会导致Goroutine阻塞
这种情况和情况2相似,不会阻塞当前M。
4、由于调用阻塞的系统调用时导致的goroutine阻塞
这种情况会导致当前M阻塞,内核会进行M的切换。而与当前M关联的当前P不会等待M的阻塞,因为这意味当前P下的所有G都无法执行,所以此时P会与当前M解除关联,转而关联到另一个内核线程M2,M2可能时新创建的内核线程,也可能时之前空闲的内核线程被唤醒来执行P的G。
对应问题如何阻塞一个goroutine?
方法1:从一个不发送数据channel中接收数据
方法2:向不接收数据的channel中发送数据
方法3:从空的channel中接收数据
方法4:向空channel中发送数据
方法5:使用select
make: 返回类型是引用类型,只用于slice、map以及channel的初始化, 无可替代
new: 返回类型是指针,用于类型内存分配(初始化值为0), 不常用
4.谈谈你对defer的理解 5.Golang 的协程与 Java 线程的区别?协程是轻量级线程,多个协程可以由一个或多个线程管理。 协程无需上下文切换,没有线程之间切换的开销。 协程的调度不需要多线程的锁机制,因为只有一个线程,不存在同时写变量冲突,执行效率比多线程高很多。
6.go数组和slice的区别1.数组定长,定义的时候就需要确定。切片长度不定,append时会自动扩容
2.相同大小数组可以赋值,会拷贝全部内容。slice赋值和指针一样。数组和slice之间不能相互赋值。当然slice有自己的copy函数
3.数组也可以进行切片,返回值是一个slice,改变slice时会同步修改数组内容,相当于取得了这个数组的指针
4.slice 的底层数据是数组,slice 是对数组的封装,它描述一个数组的片段。两者都可以通过下标来访问单个元素。
5.切片的类型和长度无关,而数组的长度是数组类型的一部分。
结构体比较时
1 如果两个结构体内部成员类型不同,则不能比较
2 如果两个结构体内部成员类型相同,但是顺序不同,则不能比较
3 如果两个结构体内含有无法比较类型,则无法比较
4 如果两个结构体类型,顺序相同,且不含有无法比较类型(slice, map) 则可以进行比较
1、Go V1.3之前的标记-清除(mark and sweep)算法
三色标记法
go采用三色标记法回收内存,程序开始创建的对象全部为白色,gc扫描后将可到达的对象标记为灰色,再从灰色对象中找到其引用的其他对象,将其标记为灰色,将自身标记为黑色,重复上述步骤,直到找不到灰色对象为止。最后对所有白色对象清除。
当一个程序启动的时候,只有一个goroutine来调用main函数,称它为主goroutine,新的goroutine通过go语句进行创建。
12.go常见占位符1、普通占位符
2、整数占位符
3、字符串与切片
1、原子性(Atomicity)
整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。
例如:银行转账,从A账户转100元至B账户:
A、从A账户取100元
B、存入100元至B账户。 这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。
2、一致性(Consistency)
在事务开始之前和事务结束以后,数据库数据的一致性约束没有被破坏。
例如:现有完整性约束A+B=100,如果一个事务改变了A,那么必须得改变B,使得事务结束后依然满足A+B=100,否则事务失败。参考上面账户A、B。
3、隔离性(Isolation)
数据库允许多个并发事务同时对数据进行读写和修改的能力,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
例如:现有有个交易是从A账户转100元至B账户,在这个交易事务还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。
4、持久性(Durability)
事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
注:分布式事务不能实现这种ACID。因为有CAP理论约束。
3.谈谈MVCC即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。
操作系统 数据结构 1.LRU缓存机制 2.树的层序遍历 3.反转链表


