GO语言类问题:

  1. GMP模型是如何实现的

    虽然都说是GMP 但是我一般叫GPM ,因为G要进入P的队列,然后P和M进行绑定

能在适当的时机将合适的协程分配到合适的位置,保证公平和效率
G(Goroutine)
G的数量无限制,理论上只受内存的影响,创建一个 G 的初始栈大小为2-4K
M(Machine)Go 对操作系统线程(OS thread)的封装
可以看作操作系统内核线程,想要在 CPU 上执行代码必须有线程
M 并不保留 G 状态,这是 G 可以跨 M 调度的基础

M在绑定有效的 P 后,进入一个调度循环
P(Processor)虚拟处理器
https://blog.csdn.net/csdnnews/article/details/118005372

之前是非抢占式的,会造成饥饿的情况

  1. 进程,线程,协程联系和区别

    别的语言有协程嘛

  2. 一颗CPU,两个协程,其中一个协程在死循环,会发生什么

https://baijiahao.baidu.com/s?id=1716954431373910202&wfr=spider&for=pc
涉及到GMP以及go版本
P和计算机核数相关

那为什么主协程(Main Goroutine)会无法运行呢,其实原因是会优先调用休眠,但由于单核 CPU,其只有唯一的 P。唯一的 P 又一直在打工不愿意下班(执行 for 死循环,被迫无限加班)。

  1. GC垃圾回收机制

    说白了就是自动内存管理机制

方案:
手动: C、C++
自动:Java 和 Go
GC负责回收堆内存,而不负责回收栈中的内存
调用栈,函数执行完后,编译器可以将栈上分配的内存可以直接释放

主流:引用计数、分代收集、标记-清除

引用计数:为每个对象维护一个引用计数,为0时回收(缺点:循环引用)
分代收集:按照对象生命周期长短划分不同的代空间,生命周期长的放入老年代,短的放入新生代,不同代有不同的回收算法和回收频率。

标记:从根变量开始遍历所有引用的对象,标记引用的对象,没有被标记的进行回收
Golang:
image.png
缺点:需要stw

创建:白、灰、黑 三个集合

白——>灰——>黑
全部放到白
root放到灰
root的引用放到灰
root自身放到黑

写屏障:STW 的目的是防止 GC 扫描时内存变化引起的混乱,而写屏障就是让 goroutine 与 GC 同时运行的手段,虽然不能完全消除 STW,但是可以大大减少 STW 的时间

触发:

  • 调用 runtime.GC() 方法,触发 GC
  • 定时或者达到阈值

调优:

  • 增大 GOGC 的值,降低 GC 的运行频率
  • 变量复用,减少对象分配,例如使用 sync.Pool 来复用需要频繁创建临时对象、使用全局变量等
  • slice提前分配足够的内存来降低扩容带来的拷贝
  • 减少字符+拼接(字符串在内存中不可变,拼接字符串可能出现的性能问题就是频繁的内存分配)
  1. 和JAVA垃圾回收机制有啥区别

Java之前了解的之分代的策略

  1. Channel底层原理

是个先进先出的队列,负责协程通信

  1. 用Channel和两个协程实现数组相加
  1. 用协程实现顺序打印123

  2. 切片原理 和数组的区别

  3. 切片初始化问题

  4. map什么内容不能成为key

在golang规范中,可比较的类型都可以作为map key;这个问题又延伸到在:golang规范中,哪些数据类型可以比较?
不能作为map key 的类型包括:

  • slices
  • maps
  • functions



map和sync map(读写问题)
看过啥底层包(net,sync等等)
懂不懂RPC。
项目怎么实现高并发高性能(我的项目内容就实现了个读写分离,协程池)