(四) 通用试题——进程线程相关

进程线程相关

1. 说一说你对进程和线程的认识?

  1. 进程隔离内存,线程共享内存。调度是以线程为单位。
    现代操作系统上能同时执行多个任务。为了能方便的管理这些任务,引入了进程的概念。
  2. 每个进程拥有独立的内存,这样写代码不需要关心内存保护。
    另一个是进程的运行是被操作系统调度的,写代码的时候不需要担心什么时候让出控制权。这一套机制让代码写起来更方便高效。因为写代码的时候不用关心其他进程是怎么运行的。随着cpu技术的发展,出现了多核。那么为了充分利用这些多核心计算资源,就需要用多个进程。
    但是因为进程之间内存是隔离的,那么多进程之间进行数据通信和同步就非常复杂。为了能方便的利用多核心 cpu,引入了线程的概念。
  3. 一个进程可以拥有多个线程,内存的隔离单元还是进程,但是操作系统的调度单元变成了线程。
  4. 线程间通信就非常方便,因为共享内存,可以直接调用函数或共享全局变量。但是事物总是有利有弊的,随意共享全局变量会导致数据不一致的问题。(如同一账户的存钱取钱问题)那就需要引入锁来进行数据同步/原子性操作。
    后续可继续按解决问题这个思路继续往下说线程、线程池、协程、io 多路复用等。

扩展: 多线程技术是实现并发访问的方案之一,但是随着网络的发展,多线程又出现了一些缺陷。
比如多线程中,如果并发量较大,每个请求分配一个线程,面对大量的线程操作系统根本调度不过来,
其次本身线程的切换又涉及到上下文保存与重建工作,也有一定的开销,
此外频繁的线程创建、初始化、销毁也会有性能损耗。
针对第三点有线程池技术可以解决,但是前两点仍然是多线程的缺陷。
后来诞生了IO多路复用技术来解决并发访问问题。

2. IO多路复用是如何解决并发访问问题的?

我先说明一下什么是IO,我们的应用程序是运行在内存中的,内存又分为用户态和内核态,内核态是由操作系统管理的,一次IO就是数据从硬件设备如网卡、磁盘到程序内存的传输过程,包括读和写,但通常我们的应用程序是没有面向硬件的接口的,所以中间又会有操作系统内核进行缓冲。所以一个IO过程可以分为两个阶段,第一阶段是IO的就绪过程,比如一次网络通信,数据从发送方物理设备根据相应的网络协议,传输到接收端物理设备也就是网卡,然后操作系统将数据从硬件读取到内核buffer中;
第二阶段是真正的读写过程,由我们的程序线程执行,将数据从内核buffer读取到程序内存中,这一步是CPU操作,是非常快的,而第一步就绪过程则可能涉及到网络通信,或磁盘读写等,相比于CPU操作是非常慢的,也就是说第一阶段就绪阶段是耗时的瓶颈。
那么如何监控一个IO流呢,我们可以一个IO流分配一个线程,在IO的两个阶段我的工作线程都处于阻塞状态,线程在第一个IO就绪阶段不执行任何操作,直到IO就绪后进行数据的读写;我们前面说过第一阶段是非常长的,长时间的阻塞无疑是一种浪费,那么又有了非阻塞型方案,我的工作线程在IO就绪过程中仍然可以执行一些其他的CPU操作,但为了保证IO处理的及时性,工作线程需要频繁的查看IO是否就绪,虽然这是我们已经利用了第一阶段执行了一些CPU任务,但在真正处理IO之前必然会有很多次无效的轮询操作,仍然有性能浪费。
后来诞生了IO多路复用技术,将多个IO流的监听工作委托给操作系统内核进行,我们的工作线程只需将读或写操作注册为回调函数绑定到对应的IO流即可。内核监听到某个IO就绪后,将这个IO流提呈给操作线程,触发相应读与写的回调函数,执行IO读写即可。此时我们的工作线程不需要再关心IO的第一阶段,只需要专注于IO的读写阶段的CPU操作即可,效率有很大提升。

...

全部评论

相关推荐

上周组里招人,我面了六个候选人,回来跟同事吃饭的时候聊起一个让我挺感慨的现象。前三个候选人,算法题写得都不错。第一道二分查找,五分钟之内给出解法,边界条件也处理得干净。第二道动态规划,状态转移方程写对了,空间复杂度也优化了一版。我翻他们的简历,力扣刷题量都在300以上。后三个呢,就有点参差不齐了。有的边界条件没处理好,有的直接说这道题没刷过能不能换个思路讲讲。其中有一个女生,我印象特别深——她拿到题之后没有马上写,而是先问我:“面试官,我能先跟你确认一下我对题目的理解吗?”然后她把自己的思路讲了一遍,虽然最后代码写得不是最优解,但整个沟通过程非常顺畅。这个女生的代码不是最优的,但当我问她“如果这里是线上环境,你会怎么设计’的时候,她给我讲了一套完整的方案——异常怎么处理、日志怎么打、怎么平滑发布。她对这是之前在实习的时候踩过的坑。”我在想LeetCode到底在筛选什么?我自己的经历可能有点代表性。我当年校招的时候,也是刷了三百多道题才敢去面试。那时候大家都刷,你不刷就过不了笔试关。后来工作了,前三年基本没再打开过力扣。真正干活的时候,没人让你写反转链表,也没人让你手撕红黑树。更多的是:这个接口为什么慢了、那个服务为什么OOM了、线上数据对不上了得排查一下。所以后来我当面试官,慢慢调整了自己的评判标准。算法题我还会出,但目的变了。我出算法题,不是想看你能不能背出最优解。而是想看你拿到一个陌生问题的时候,是怎么思考的。你会先理清题意吗?你会主动问边界条件吗?你想不出来的时候会怎么办?你写出来的代码,变量命名乱不乱、结构清不清楚?这些才是工作中真正用得到的能力。LeetCode是一个工具,不是目的。它帮你熟悉数据结构和常见算法思路,这没问题。但如果你刷了三百道题,却说不清楚自己的项目解决了什么问题、遇到了什么困难、你是怎么解决的,那这三百道题可能真的白刷了。所以还要不要刷LeetCode?要刷,但别只刷题。刷题的时候,多问自己几个为什么:为什么用这个数据结构?为什么这个解法比那个好?如果换个条件,解法还成立吗?把刷题当成锻炼思维的方式,而不是背答案的任务。毕竟面试官想看到的,从来不是一台背题机器,而是一个能解决问题的人。
牛客51274894...:意思是光刷力扣还不够卷
AI时代还有必要刷lee...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务