C++面试整理

目录

写在前面

操作系统

计算机网络

数据库

C++

算法

面试

其它

分布式

hr面


写在前面

最近开始准备找实习了,收到某位大佬的指导,说可以上牛客网把相关的面经都刷一遍,记录下考点各个击破。大佬是搞java的,已经把java的刷完了,看了一下觉得很受用,因此也准备刷下c++的。顺带附上大佬的java总结:java实习&秋招面经整理 - 知乎

面经整理:

c++面经:2021 秋招面经总结 —— C++ 篇(六) - 力扣(LeetCode)

基础知识:阿里、腾讯、字节、快手、美团| JAVA 开发岗|2020 春招、2021 秋招面试高频问题总结 - 力扣(LeetCode)

argue薪资:如何跟hr聊薪资,argue薪资的技巧全在这里

算法题汇总:GitHub - afatcoder/LeetcodeTop: 汇总各大互联网公司容易考察的高频leetcode题🔥

逆袭进大厂:《InterviewGuide》第一弹之C++篇49问49答_笔经面经_牛客网

八股文汇总:https://www.notion.so/a8209820a2524d91858e14824cb60037

八股文汇总2:CS-Notes

蒋豆芽面试总结:C++开发面经与嵌入式软件面经(蒋豆芽面试题总结)_牛客博客

C语言学习网:C++ stable_sort()用法详解

智力题汇总:blog.csdn.net/basycia/article/details/52138129

题目库:CodeTop企业题库

海量数据场景解题方法:秒杀99%的海量数据处理面试题 - sunsky303 - 博客园

操作系统

1.如何查看系统中的内存状态

2.Linux指令:查看进程状态?查看文件信息?查看内存使用?查看磁盘占有量?Grep指令的原理;

top命令:Linux top命令小结 - 简书

grep命令:Linux下的grep命令详解_学如逆水行舟的技术博客_51CTO博客_grep命令详解_linux grep命令详解

查看磁盘:linux查看磁盘使用情况命令_陈袁的博客-CSDN博客_linux 查看磁盘

3.操作系统:进程与线程的区别?Linux系统中两者有区别吗?软链接与硬链接的区别(不会)?用户态与内核态的区别(用读文件举例说明)?

4.死锁的原因

操作系统------死锁的条件和解决方法_ZJE-CSDN博客

面试问题之操作系统:死锁的四个必要条件和解决办法 - 知了会爬树 - 博客园

5.虚拟内存

在现代操作系统中,进程之间共享使用cpu和内存,但是内存资源有限,为了更加高效地使用内存,现代操作系统提供一个内存抽象—虚拟内存。虚拟内存巧妙地利用内存,地址转换,磁盘文件和操作系统内核来为每一个进程提供足够大的统一的私有地址空间。虚拟内存提供三个重要的能力:1)将内存当作磁盘的缓存,在内存中只保留常用数据,必要时从内存和磁盘之间交换数据。2)简化内存管理,为每个进程提供统一的地址空间。3)保护进程的内存空间不受其他进程影响。

6.常见排序算法排序算法稳定的意思,快排的复杂度什么时候退化,基本有序用什么

7.进程线程,虚拟内存,页面置换

8.内存访问磁盘数据

9.epoll

10.内核态用户态的区别

用户态(user mode) : 用户态运行的进程或可以直接读取用户程序的数据。
内核态(kernel mode):可以简单的理解系统态运行的进程或程序几乎可以访问计算机的任何资源,不受限制。

用户态到内核态具体的切换步骤:

(1)从当前进程的描述符中提取其内核栈的ss0及esp0信息。

(2)使用ss0和esp0指向的内核栈将当前进程的cs,eip,eflags,ss,esp信息保存起来,这个过程也完成了由用户栈到内核栈的切换过程,同时保存了被暂停执行的程序的下一条指令。

(3)将先前由中断向量检索得到的中断处理程序的cs,eip信息装入相应的寄存器,开始执行中断处理程序,这时就转到了内核态的程序执行了。

ss0是任务内核态堆栈的段选择符,esp0是堆栈栈底指针

11.描述并写一下LRU

12.进程间通信的共享内存,如何保证安全性,结合epoll讲讲共享内存;共享内存通信方式

用信号量来实现使用共享内存的不同进程间的同步工作。

(1)锁。操作系统为我们提供了多种类型的锁,诸如互斥锁、读写锁、自旋锁等。互斥锁(pthread_mutex_t)可以保证线程间的互斥锁,通过设置互斥锁的进程间共享属性,可以实现进程间共用互斥锁。相应地,我们可以将读写锁、自旋锁改造为多进程共享的。这种方式有一个隐患:当加锁进程异常退出时,其他进程可能永远无法抢到锁。

(2)信号量也是一个常见的多进程同步方式。通过semget或者sem_open打开一个信号量,然后通过PV操作来达到进程间互斥的效果。但是信号量也存在加锁进程异常退出时,不能自动解锁的问题。

(3)文件记录锁可以锁定文件的一部分或者全部。假设我们将文件与共享内存中的数据块对应起来,则可以通过文件锁来同步共享内存的读写操作。值得说明的时,当进程异常退出时,该进程持有的文件锁会自动释放。相对于信号量,文件锁的效率稍差。

共享内存的数据同步 - 程序园

linux实现共享内存同步的四种方法_sunxiaopengsun的专栏-CSDN博客_共享内存同步机制

13.Pipe和fifo的区别

14.硬连接/软连接

硬链接: 硬连接指通过索引节点 inode 来进行的连接,即每一个硬链接都是一个指向对应区域的文件。

软链接: 保存了其代表的文件的绝对路径,是另外一种文件,在硬盘上有独立的区块, 访问时替换自身路径。

Linux硬链接和软连接的区别与总结 - Hsia的博客 | Hsia Blog

Linux软连接和硬链接 - iTech - 博客园

15.查看文件指定某一行。

sed -n '10p' test_classification.py

sed -n '10,20p' test_classification.py

16.查看端口占用

lsof -i:端口号 用于查看某一端口的占用情况,比如查看8000端口使用情况,lsof -i:8000

netstat -tunlp |grep 端口号,用于查看指定的端口号的进程情况,如查看8000端口的情况,netstat -tunlp |grep 8000

Linux 查看端口占用情况 - 菜鸟++ - 博客园

17.如何查看日志

head\tail\cat\less\more

18.什么是线程不安全

19.什么是IO复用,什么是非阻塞IO

20.select\poll\epoll

Netty——(3)高并发编程必备知识IO多路复用技术select、poll、epoll分析_探索的小白-CSDN博客

IO多路复用之select、poll、epoll - Yungyu - 博客园

21.线程共享进程的资源里的局部变量等属于堆还是栈

22.linux怎么查看内存泄漏

使用mtrace命令:利用linux的mtrace命令定位内存泄露(Memory Leak)_zpznba的博客-CSDN博客

使用 Valgrind工具:linux下内存泄露查找、BUG调试 | 学步园

感觉两个工具一样的,都是编译的时候加上-g参数,然后调用工具进行查看

23.如何清除已出现的僵尸进程?

用ps 命令和 grep命令寻找僵尸进程:

ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'

命令注解:
-A 参数列出所有进程
-o 自定义输出字段,我们设定显示字段为stat(状态),ppid(父进程pid),pid(进程pid),cmd(命令行)这四个参数

因为状态为 z 或者 Z的进程为僵尸进程,所以我们使用grep 抓取stat 状态为zZ进程;

清除僵尸进程的话可以kill掉僵尸进程的父进程。

24.线程、进程上下文切换;为什么线程切换比进程快

  • 操作系统保持跟踪进程运行所需的所有状态信息,这种状态,也就是上下文,它包括许多信息,例如PC和寄存器文件的当前值,以及主存的内容。
  • 操作系统实现这种交错执行的机制称为上下文切换。
  • 当操作系统决定要把控制权从当前进程转移到某个新进程时,就会进行上下文切换,即保存当前进程的上下文,恢复新进程的上下文,然后将控制权传递到新进程,新进程就会从上次停止的地方开始

进程切换分两步:

1.切换页目录以使用新的地址空间

2.切换内核栈和硬件上下文

对于linux来说,线程和进程的最大区别就在于地址空间,对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的。

切换的性能消耗:

1、线程上下文切换和进程上下问切换一个最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。这两种上下文切换的处理都是通过操作系统内核来完成的。内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。

2、另外一个隐藏的损耗是上下文的切换会扰乱处理器的缓存机制。简单的说,一旦去切换上下文,处理器中所有已经缓存的内存地址一瞬间都作废了。还有一个显著的区别是当你改变虚拟内存空间的时候,处理的页表缓冲(processor’s Translation Lookaside Buffer (TLB))或者相当的神马东西会被全部刷新,这将导致内存的访问在一段时间内相当的低效。但是在线程的切换中,不会出现这个问题。

上下文就是内核重新启动一个被抢占的进程所需的状态。包括一下内容:

  • 通用目的寄存器
  • 浮点寄存器
  • 程序计数器
  • 用户栈
  • 状态寄存器
  • 内核栈
  • 各种内核数据结构:比如描绘地址空间的页表,包含有关当前进程信息的进程表,以及包含进程已打开文件的信息的文件表。

进程切换与线程切换的一个最主要区别就在于进程切换涉及到虚拟地址空间的切换而线程切换则不会。因为每个进程都有自己的虚拟地址空间,而线程是共享所在进程的虚拟地址空间的,因此同一个进程中的线程进行线程切换时不涉及虚拟地址空间的转换。

为什么虚拟地址切换很慢

现在我们已经知道了进程都有自己的虚拟地址空间,把虚拟地址转换为物理地址需要查找页表,页表查找是一个很慢的过程,因此通常使用Cache来缓存常用的地址映射,这样可以加速页表查找,这个cache就是TLB,Translation Lookaside Buffer,我们不需要关心这个名字只需要知道TLB本质上就是一个cache,是用来加速页表查找的。由于每个进程都有自己的虚拟地址空间,那么显然每个进程都有自己的页表,那么当进程切换后页表也要进行切换,页表切换后TLB就失效了,cache失效导致命中率降低,那么虚拟地址转换为物理地址就会变慢,表现出来的就是程序运行会变慢,而线程切换则不会导致TLB失效,因为线程线程无需切换地址空间,因此我们通常说线程切换要比较进程切换块,原因就在这里。

https://segmentfault.com/a/1190000019750164

25.操作系统进程状态有哪些

状态 说明
R running or runnable (on run queue)
正在执行或者可执行,此时进程位于执行队列中。
D uninterruptible sleep (usually I/O)
不可中断阻塞,通常为 IO 阻塞。
S interruptible sleep (waiting for an event to complete)
可中断阻塞,此时进程正在等待某个事件完成。
Z zombie (terminated but not reaped by its parent)
僵死,进程已经终止但是尚未被其父进程获取信息。
T

stopped (either by a job control signal or because it is being traced)
结束,进程既可以被作业控制信号结束,也可能是正在被追踪。

D和S的区别是:

进程处于睡眠状态,但是此刻进程是不可中断的。不可中断,指的并不是CPU不响应外部硬件的中断,而是指进程不响应异步信号。绝大多数情况下,进程处在睡眠状态时,总是应该能够响应异步信号的。 而TASK_UNINTERRUPTIBLE状态存在的意义就在于,内核的某些处理流程是不能被打断的。如果响应异步信号,程序的执行流程中就会被插入一段用于处理异步信号的流程(这个插入的流程可能只存在于内核态,也可能延伸到用户态),于是原有的流程就被中断了。在进程对某些硬件进行操作时(比如进程调用read系统调用对某个设备文件进行读操作,而read系统调用最终执行到对应设备驱动的代码,并与对应的物理设备进行交互),可能需要使用TASK_UNINTERRUPTIBLE状态对进程进行保护,以避免进程与设备交互的过程被打断,造成设备陷入不可控的状态。

Linux进程状态解析 之 R、S、D、T、Z、X (主要有三个状态)_sdkdlwk的博客-CSDN博客_进程状态

26.进程、线程调度算法

1.先来先服务 first-come first-serverd(FCFS)

2.短作业优先 shortest job first(SJF)

3.最短剩余时间优先 shortest remaining time next(SRTN)

4. 时间片轮转

5.优先级调度

6.多级反馈队列

计算机操作系统 - 进程管理 | CS-Notes

27.线程同步方式、线程通信

线程同步方式:互斥量、信号量、临界区、事件

用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。

内核模式下的方法有:事件,信号量,互斥量。

临界区

保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么 在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操 作共享资源的目的。 仅能在同一进程内使用

互斥量 Mutex

互斥量跟临界区很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。 

信号量 

信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源 ,这与操作系统中的PV操作相同。

事件(Event) 

事件机制,则允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。

线程同步方式比较 - 王小北 - 博客园

28.为什么会发生进程切换,为什么不让一个进程跑下去

29.为什么cpu调度进程要用时间片轮转

30.linux用什么调度算法

完全公平调度算法CFS

进程管理笔记三、完全公平调度算法CFS_邓博学习笔记-CSDN博客

31.字节序

32.同步、异步;阻塞、非阻塞;区别

同步/异步关注的是消息通信机制 (synchronous communication/ asynchronous communication) 。

所谓同步,就是在发出一个调用时,在没有得到结果之前, 该调用就不返回。
异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果
阻塞/非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

33.实现memcpy

34.内存管理,虚拟内存

内存管理方式主要分为:页式管理、段式管理和段页式管理。

页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页。把内存空间按页的大小划分为片或者页面,然后把页式虚拟地址与内存地址建立一一对应的页表,并用相应的硬件地址转换机构来解决离散地址变换问题。页式管理采用请求调页和预调页技术来实现内外存存储器的统一管理。

优点:没有外碎片,每个内碎片不超过页的大小。

缺点:程序全部装入内存,要求有相应的硬件支持,如地址变换机构缺页中断的产生和选择淘汰页面等都要求有相应的硬件支持。增加了机器成本和系统开销。

段式管理的基本思想是把程序按内容或过程函数关系分成段,每段有自己的名字。一个用户作业或者进程所包含的段对应一个二维线性虚拟空间,也就是一个二维虚拟存储器。段式管理程序以段为单位分配内存,然后通过地址映射机构把段式虚拟地址转换为实际内存物理地址。

优点:可以分别编写和编译,可以针对不同类型的段采取不同的保护,可以按段为单位来进行共享,包括通过动态链接进行代码共享。

缺点:会产生碎片。

段页式管理,系统必须为每个作业或者进程建立一张段表以管理内存分配与释放、缺段处理等。另外由于一个段又被划分为若干个页,每个段必须建立一张页表以把段中的虚页变换为内存中的实际页面。显然与页式管理时相同,页表也要有相应的实现缺页中断处理和页面保护等功能的表项。

段页式管理是段式管理和页式管理相结合而成,具有两者的优点。

由于管理软件的增加,复杂性和开销也增加。另外需要的硬件以及占用的内存也有所增加,使得执行速度下降。
 

虚拟内存是一种内存管理思想。

35.自旋锁,互斥锁的区别

  1. 互斥锁:线程会从sleep(加锁)——>running(解锁),过程中有上下文的切换,cpu的抢占,信号的发送等开销;
  2. 自旋锁:线程一直是running(加锁——>解锁),死循环检测锁的标志位,机制不复杂,主要用于SMP和内核可抢占下,因为在内核不可抢占下,cpu在执行空操作。
  3. 互斥锁的起始原始开销要高于自旋锁,但是基本是一劳永逸,临界区持锁时间的大小并不会对互斥锁的开销造成影响,而自旋锁是死循环检测,加锁全程消耗cpu,起始开销虽然低于互斥锁,但是随着持锁时间,加锁的开销是线性增长

36.进程退出,线程会怎么样

如果是主线程调用pthread_exit退出,则不会影响其它线程;如果调用return或者是exit函数,则会杀死其它线程。

主线程、子线程与进程的退出问题_qq_34352738的博客-CSDN博客_进程退出时线程退出吗

37.磁盘读写过程

磁盘读写过程_zhudinglym的博客-CSDN博客

38.限流算法

常用4种限流算法介绍及比较_Solin的博客-CSDN博客_限流算法

39.堆和栈的速度比较

     1.分配和释放,堆在分配和释放时都要调用函数(MALLOC,FREE),比如分配时会到堆空间去寻找足够大小的空间(因为多次分配释放后会造成空洞),这些都会花费一定的时间,具体可以看看MALLOC和FREE的源代码,他们做了很多额外的工作,而栈却不需要这些。

     2.访问时间,访问堆的一个具体单元,需要两次访问内存,第一次得取得指针,第二次才是真正得数据,而栈只需访问一次。另外,堆的内容被操作系统交换到外存的概率比栈大,栈一般是不会被交换出去的。

     综上所述,站在操作系统以上的层面来看,栈的效率比堆高,对于应用程序员,这些都是透明的,操作系统做了很多我们看不到的东西。

1、管理方式不同;

  2、空间大小不同;

  3、能否产生碎片不同;

  4、生长方向不同;

  5、分配方式不同;

  6、分配效率不同;

  管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。

  空间大小:一般来讲在 32 位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M(好像是,记不清楚了)。当然,我们可以修改:打开工程,依次操作菜单如下:Project->Setting->Link,在 Category 中选中 Output,然后在 Reserve 中设定堆栈的最大值和 commit。注意:reserve 最小值为 4Byte;commit 是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。

  碎片问题:对于堆来讲,频繁的 new/delete 势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出,详细的可以参考数据结构,这里我们就不再一一讨论了。

  生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。

  分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由 malloc 函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。

  分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是 C/C++ 函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。

C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区 - 盗艹人 - 博客园

40.awk命令

linux awk命令详解 - ggjucheng - 博客园

41.共享内存如何实现;共享内存为什么是IPC中最快的通讯方式

相比较其他的进程通信方式,共享内存确实是最快的,比如说,管道通信,管道通信需要两次数据拷贝的过程.以进程1 和进程2实现进程间通信为例,进程1 和进程2 要想进行进程间通信,首先进程1 需要将数据从用户态空间拷贝到,内核态空间,接着进程2 从内核态空间中将数据拷贝到进程2中,于是进程间通信完成了.,然而共享内存就没有数据的拷贝过程,因此效率最高.

共享内存-------进程间最快的通信方式_zwq68的博客-CSDN博客

45.一个进程启动时的内存管理是怎样的?

46.开机过程

① 开机访问0xFFFF0地址

② 跳转到BIOS ROM的初始化程序

③ 把BIOS ROM中的初始化程序复制到内存中执行

④ 初始化程序 首先初始化硬件,然后在硬盘中找到 引导程序。

⑤ 将引导程序复制到 内存的 0x07c00,并执行

⑥ 引导程序 将硬盘的内容复制到内存中。

⑦ 跳到内存中操作系统的开始地址,

⑧ 开始执行操作系统。

47.ctrl+c,发生了什么

我们平时在程序运行的时候按下ctrl-c、ctrl-z或者kill一个进程的时候其实都等效于向这个进程发送了一个特定信号,当进程捕获到信号后,进程会被中断并立即跳转到信号处理函数。默认情况下一个程序对ctrl-c发出的信号(SIGINT)的处理方式是退出进程,所以当我们按下ctrl-c的时候就可以终止一个进程的运行。

48.零拷贝原理

原来 8 张图,就可以搞懂「零拷贝」了 - 小林coding - 博客园

浅析Linux中的零拷贝技术 - 简书

49.程序用户空间中虚拟内存地址怎么映射到物理内存地址的

程序产生虚拟地址(由段选择符和段内偏移地址组成的地址),CPU要利用其段式内存管理单元,先将为逻辑地址转换成一个线性地址,再利用其页式内存管理单元,转换为最终物理地址。MMU就是内存管理单元。

  • 虚拟地址指由程序产生的由段选择符和段内偏移地址组成的地址。
  • 逻辑地址指由程序产生的段内偏移。有时候直接把逻辑地址当做虚拟地址。
  • 线性地址指虚拟地址到物理地址变换的中间层,是处理器可寻址的内存空间中的地址。程序代码会产生逻辑地址,也就是段中的偏移地址,加上相应的段基址就成了线性地址。如果开启了分页机制,那么线性地址需要再经过变换,转为为物理地址。如果无分页机制,那么线性地址就是物理地址。

  • 物理地址指CPU外部地址总线上寻址物理内存的地址信号,是地址变换的最终结果。

虚拟地址到物理地址的转化是体系结构相关的,一般由分段和分页两种方式。以X86CPU为例,分段和分页都是支持的。内存管理单元负责从虚拟地址到物理地址的转化。逻辑地址是段标识+段内偏移的形式。MMU通过查询段表,可以将逻辑地址转化为线性地址。无分页机制时,线性地址就是物理地址,有分页时,MMU还需要查询页表来将线性地址转化为物理地址:逻辑地址(段表)->线性地址(页表)->物理地址。

映射是一种多对一的关系,即不同的逻辑地址可以映射到同一个线性地址上;不同的线性地址也可以映射到同一个物理地址上。而且,同一个线性地址在换页之后,可能被装载到另一个物理地址上,所以这种多对一的映射关系会随时间发生变化

段表+单层页表

进程的内存先分成多个段,每个段再按照页来分配。地址分三个部分:段号+页号+页内偏移,根据段号去段表里面找对应的页表地址,得到页表的地址后,根据页号找到对应的物理内存的Page Frame地址,最后再结合页内偏移计算得到实际地址,其中段表中的Size是指某一段对应的页表的长度,即物理页的数目。以32位虚拟地址空间,4KB大小的Page为例,前10bit用于段号,中间10位用于页号,后12位用于页内偏移,假设页表的每一行的大小是4个字节,则一个物理Page Frame正好可以容下每个段的页表。

详解内存虚拟地址到物理地址的转换过程以及对应的应用场景 - 知乎

50.io密集型、cpu密集型任务分别用多进程、多线程、多协程?

对于IO密集型任务,由于CPU经常需要等待IO操作完成,因此,在等待过程中,CPU可以去做其他事情,因此采用多线程可以提高程序执行效率,这实质是并发处理。当然,由于多进程可以利用多核CPU真正实现并行处理,所以,采用多进程也可以提高IO密集型任务的执行效率。但是考虑到多线程是共享资源的,因此通信更方便,而多进程之间的资源相互独立,通信不是很方便,因此,综合来看,IO密集型任务,采用python多线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值