小米外包(柯莱特)面试问题

小米外包(柯莱特)面试问题

讲述一下Golang的GMP模型

G(Goroutine)M(Machine)P(Processor)

  • 模型组件

    • G
      • 轻量化的用户态线程,由Go程序运行时管理,可以动态扩容
      • 创建和切换成本低,高并发场景非常适用
    • M
      • 对应操作系统线程,由内核调度,执行go代码时一定会绑定一个P
      • 数量多于P,Go在运行时动态创建销毁M
    • P
      • 虚拟处理器,管理着本地G队列,数量由配置决定,默认为CPU核心
      • 调度上下文,协调GM资源分配,减少全局锁竞争
  • 调度机制

    • 队列结构
      • 本地队列:每个P会维持一个256的本地队列,新G优先加入当前P队列,如果满了转移一半到全局队列
      • 全局队列:所有P共享,用于平衡负载,优先级低于本地队列
    • 执行流程
      • M绑定P执行G,优先从本地队列、全局队列、网络轮询器及工作窃取来从其他P获取G
      • 工作窃取:P的本地队列为空时,随机选择其他P窃取一半G,提高资源利用率
    • 阻塞处理
      • 系统调用阻塞:M与P解绑,P被其他M获取继续执行。阻塞结束后,G重新加入队列,M缓存备用或者销毁
      • 网络IO操作:使用netpoller异步处理,G挂起,IO就绪后由空闲M执行,避免线程阻塞
    • 抢占调度
      • Go 1.2引入协作式抢占(函数调用时触发),1.14后支持基于信号的抢占式调度,防止G长时间占用CPU。
  • 模型优势

    • 资源高利用性:P数量限制为CPU核心数,减少线程竞争;M动态调整应对阻塞
    • 低延迟切换:本地队列减少锁竞争,工作窃取和全局队列平衡负载
    • 高并发支持:轻量级Goroutine和高效调度机制支持数十万并发
  • 总结

    GMP模型通过层级化的调度设计,p管理队列,m动态绑定,g灵活切换,结合工作窃取及异步IO处理,实现了高效并发。核心在于减少锁竞争、优化资源利用,并通过抢占机制确保公平性。

什么时候使用线程和协程

  1. 线程使用场景

    • 适用场景
      1. CPU密集任务:并行计算时,利用多核性能
      2. 依赖线程的生态: 比如传统的多线程代码
      3. 低延迟响应:需要操作系统级的优先级调度
    • 缺点
      • 创建销毁成本高
      • 大量线程容易内存耗尽或者竞争问题
  2. 协程使用场景

    • 适用情况
      • I/O密集型任务:高并发网络请求、文件读写或者数据库访问=》web服务器
      • 高并发轻量级任务: 需同时处理数千个任务=》聊天服务器、微服务网关
      • 资源敏感型应用:内存有限,需避免线程过多=》嵌入式
    • 优点
      • 创建销毁成本低,用户态调度,栈动态调整
      • 天然避免锁竞争,适合异步编程模型
  3. 关键对比

    特性 线程 协程
    调度 操作系统内核调度 用户态调度(由语言运行时管理)
    内存占用 较大(默认MB级栈) 极小(默认KB级栈,可动态扩容)
    切换开销 高(需内核介入) 极低(无系统调用)
    并发规模 数百到数千 数十万到百万级
    适用任务 CPU密集型、需并行 I/O密集型、高并发
    开发复杂度 高(需处理锁、竞态)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值