😥 整理不易,此资源只针对正式星主开放,
还请入驻星球后再来观看。

GOLANG ROADMAP

阅读模式

  • 沉浸
  • 自动
  • 日常
首页
Go学习
  • Go学院

    • Go小课
    • Go视界
    • Go小考
    • Go实战
  • Go资源

    • 优质课程
    • 在线宝典
    • 资源下载
    • 帮找资源
训练营 🔥
  • Go体系课&实战训练营
  • 升值加薪陪跑训练营
Go求职
  • 求职刷题

    • 企业题库
    • 面试宝典
    • 求职面经
  • 求职服务

    • 内推互助
    • 求职助力
    • 内推公司
Go友会
  • 城市
  • 校园
推广返佣
  • 返佣排行
  • 返佣规则
  • 推广学院
实验区
  • Go周边
  • Go宝典

    • 推荐图书
    • 精品博文
  • Go开源

    • Go仓库
    • Go月刊
更多
  • 用户中心

    • 我的信息
    • 我的返佣
    • 我的消息
  • 玩转星球

    • 星球介绍
    • 星主权益
    • 吐槽专区
    • 成长记录
  • 合作交流

    • 商务合作
    • 讲师招募
    • 生态伙伴
author-avatar

GOLANG ROADMAP


首页
Go学习
  • Go学院

    • Go小课
    • Go视界
    • Go小考
    • Go实战
  • Go资源

    • 优质课程
    • 在线宝典
    • 资源下载
    • 帮找资源
训练营 🔥
  • Go体系课&实战训练营
  • 升值加薪陪跑训练营
Go求职
  • 求职刷题

    • 企业题库
    • 面试宝典
    • 求职面经
  • 求职服务

    • 内推互助
    • 求职助力
    • 内推公司
Go友会
  • 城市
  • 校园
推广返佣
  • 返佣排行
  • 返佣规则
  • 推广学院
实验区
  • Go周边
  • Go宝典

    • 推荐图书
    • 精品博文
  • Go开源

    • Go仓库
    • Go月刊
更多
  • 用户中心

    • 我的信息
    • 我的返佣
    • 我的消息
  • 玩转星球

    • 星球介绍
    • 星主权益
    • 吐槽专区
    • 成长记录
  • 合作交流

    • 商务合作
    • 讲师招募
    • 生态伙伴
  • Go真实面试题汇总系列

    • 《其他篇》
  • 宝典内容

    • 6. Go和java比有什么不同?
    • 17. go 实现不重启热部署
    • 23.了解的gc算法有哪些?
    • 50. 怎么用go实现一个栈
    • 60. Kratos 框架的特性
    • 82. 信令用wss还是ws?
    • 111. 有对项目和系统做性能测试吗?(benchmark 和 pprodf)
    • 140. cgo了解过引入的风险点吗?
    • 142. go使用中遇到的问题
    • 143. go的profile工具
    • 161. Go 性能分析工具
    • 172. go里面比较成熟的日志框架了解过没有
    • 181. golang 性能问题怎么排查
    • 193. RR是如何实现的
    • 194. RR级别下能否读取事务ID靠后且尚未提交的记录?
    • 197. java和golang的一些共同点以及区别
    • 205. client如何实现长连接?
    • 207. Go语言实现set
    • 211. 有缓冲和无缓冲的区别?
    • 213. 怎么做服务注册发现的
    • 214. 服务发现有哪些机制
    • 215. 当go服务部署到线上了,发现有内存泄露,该怎么处理
    • 221. 堆的结构,堆的创建,节点添加与删除
    • 232. 线程yield(),sleep(), wait()的区别
    • 233. 如何让拥有GC的情况下产生OOM
    • 244. go 建堆过程
    • 246. golang的一些常用工具库
    • 247. 谈谈go语言和其他语言的区别
    • 258. go常用的第三方库
    • 270. 网络连接的各层的状态
    • 271. 了解中间件吗?有什么好处?
    • 280. 看过啥底层包?
    • 281. RPC基础
    • 291. 内存对其了解吗?
    • 292. Go中struct组合与Java继承的区别
    • 299. Go依赖管理历史有几次方式
    • 301. 对比下node和go
    • 303. 说说火焰图?如何分析的?
    • 316. 可以从多个角度来讲比如面向对象来说,多态继承等等
    • 318. 从包管理来讲,gomod包括之前的dep等等
    • 320. 用go写rpc框架的具体功能细节
    • 323. CAS
    • 328. GO语言中的协程与Python中的协程的区别?
    • 335. 如果项目里api耗时过久,你会怎么去排查
    • 336. 对比 Go 语言和 Java 语言
    • 342. golang:pprof使用
    • 343. 性能调优怎么做
    • 347. 如何排查线上程序问题
    • 356. java 实例放在哪个区,常量放在哪个区
    • 358. java内存模型,方法区,堆栈的区别
    • 359. go web项目的部署,后台持续运行与优雅退出
    • 360. golang的defer,channel,reflect,多线程 panic recover
    • 361. 使用interface的好处
    • 362. Gin框架的特点和源码问题
    • 363. close-wait作用
    • 372. golang开发用什么框架
    • 378. python、go 语言特点
    • 387. select、poll、epoll说下详情和各自优缺点
    • 388. delete new和malloc free关系
    • 392. 重载和重写的概念辨析?
    • 393. 在继承里,子类能重载父类方法吗?
    • 400. 值溢出(usignedchar最大255)
    • 415. django与其他框架的区别
    • 433. gin框架的路由是怎么处理的?
    • 435. go性能分析工具
    • 438. 比较 gin 框架和其它框架
    • 446. 如果一个包要依赖另一个包,这个时候如何写单元测试
    • 447. micro怎么用
    • 448. micro服务发现
    • 449. 如何通过goclient写代码获取
    • 460. 使用 database/sql 和 使用 gorm 的区别
    • 467. c 与go的区别优劣

😥 整理不易,此资源只针对正式星主开放,
还请入驻星球后再来观看。

387. select、poll、epoll说下详情和各自优缺点


企业题库解析小组

题目来源:字节跳动

作者:ORVR

select、poll、epoll说下详情和各自优缺点

这三个是目前常用的io复用模型,他们可以监视多个描述符,一旦某个描述符就绪(读或写就绪),能够通知程序进行相应的读写操作,但他们三个本质上都是同步io,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步io则无需自己负责进行读写,异步io的实现会负责把数据从内核拷贝到用户空间

select和poll类型,都是基于轮询机制,只不过select数据结构存放fd的数量有限制,一般默认不超过1024个,而poll的是一个链表结构,它没有最大文件描述符数量的限制

他们的缺点有

1.轮询的效率很低,每次都会都会有很多没有意义的遍历

2.内核需要将消息传递到用户空间,都需要内核拷贝动作,都需要维护一个用来存放大量fd的数据结构,使得用户空间和内核空间在传递该结构是复制开销大,这个开销会随着文件描述符的数量增加而线性增大

epoll基于操作系统支持的io通知机制,epoll支持水平触发和边沿触发两种模式

LT模式:当epoll_wait检测到描述符事件发生并将此事件通知应用程序,应用程序可以不立即处理该事件。下次调用epoll_wait时,会再次响应应用程序并通知此事件。

ET模式:当epoll_wait检测到描述符事件发生并将此事件通知应用程序,应用程序必须立即处理该事件。如果不处理,下次调用epoll_wait时,不会再次响应应用程序并通知此事件。

epolllt(水平触发)默认模式。只要该fd还有数据可读,每次epoll——wait都会返回它的事件,提醒用户程序去操作

epollet(边缘触发)

只会提示一次,直到下次再有数据流入之前都不会再提示,无论fd是否还有数据可读,所有在边缘模式下,read一个fd的时候一定要把它的buffer读完,即使读到read返回值小于请求值,或者遇到eagain错误,

epoll使用事件的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用内息回调机制激活该fd,epoll_wait便可以收到通知

EPOLLET触发模式的意义

若用EPOLLLT,系统中一旦有大量无需读写的就绪文件描述符,它们每次调用epoll_wait (opens new window)都会返回,这大大降低处理程序检索自己关心的就绪文件描述符的效率。 而采用EPOLLET,当被监控的文件描述符上有可读写事件发生时,epoll_wait会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll_wait时,它不会通知你,即只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你。这比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符。

优点

  • 没有最大并发连接的限制,能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口)
  • 效率提升,不是轮询,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数 (opens new window) 即Epoll最大的优点就在于它只关心“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,Epoll的效率就会远远高于select和poll
  • 内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销。
  • epoll通过内核和用户空间共享一块内存来实现的

总结

select,poll,epoll都是IO多路复用机制,即可以监视多个描述符,一旦某个描述符就绪(读或写就绪),能够通知程序进行相应读写操作。 但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。

  • select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。
  • select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。
  1. 连接数较少并且都很活跃,用select和poll效率更高
  2. 连接数较多并且都不很活跃,使用epoll效率更高