面经准备(一)

打算按照牛客的经验帖查漏补缺。

百度实习虚拟化研发实习生一面

● 进程与线程的区别

进程:程序的一次执行;线程:CPU调度的基本单位。

调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。

资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源

系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。

说一下你对Linux内存管理的了解

内存管理的主要工作就是对物理内存进行组织,然后对物理内存的分配和回收。但是Linux引入了虚拟地址的概念。

● 页表的实现机制

页表是操作系统管理虚拟内存的一种数据结构,它用于将虚拟地址映射到物理地址。每个进程都有自己的页表,它记录了进程的虚拟地址空间中每一页(通常是4KB或者8KB)对应的物理页框。

页表中的每个页表项记录了虚拟页和物理页之间的映射关系,通常包含以下几个字段:

  • 有效位:用于表示当前页表项是否有效。如果无效,说明当前的虚拟页还没有被分配物理页。
  • 物理页框号:指示虚拟页映射到的物理页框的编号。
  • 访问权限:指示进程可以对该页进行何种访问(读、写、执行)。
  • 脏页标志:表示这个页是否被修改过,如果被修改过,那么在将其写回到磁盘时需要进行同步。
  • 访问位:表示这个页是否被访问过,如果访问过,那么在将其写回到磁盘时需要进行同步。
  • 保留位:用于操作系统内部使用。

当一个进程访问内存时,操作系统会根据虚拟地址查找对应的页表项,并计算出物理地址,然后再进行实际的内存读写操作。如果需要访问的虚拟页对应的物理页不在内存中,操作系统需要将其从磁盘中读取到内存中,并更新页表项。

为了提高页表的查找效率,操作系统通常采用多级页表的方式来组织页表。例如,Linux采用了两级页表,每个进程有一个页目录表和若干个页表。在访问内存时,操作系统先根据虚拟地址的高位找到页目录表,然后再根据页目录表中的一个页表项找到对应的页表,最终找到对应的页表项,计算出物理地址。

总之,页表是操作系统实现虚拟内存的一种关键机制,它将虚拟地址映射到物理地址上,可以使得多个进程共享物理内存,并且可以使得进程的地址空间不必连续,从而更加灵活地利用内存资源

● 说一下epoll

几种常见的IO模型——BIO(同步阻塞IO),NIO(同步非阻塞IO),IO多路复用(阻塞IO),信号驱动IO,异步IO(异步非阻塞IO)。

是一种IO多路复用技术(IO多路复用是一种同步机制,通过复用机制实现一个线程监视多个文件描述符,能够提高程序的性能。IO指的是把文件写到内存中或者从内存中写到文件;多路是指网络连接,复用指的是同一个线程/进程。)。

Linux下实现IO多路复用的系统调用主要有select,poll,epoll。

● 为什么epoll底层要使红黑树,有什么好处

查询和添加的时间复杂度是O(logn),在内核查询其中的文件描述符状态(是否有事件发生时)时,更快捷有效。

● reactor模式和proactor模式的区别

Reactor模式是一种同步I/O模型,其中一个线程(通常称为事件循环线程)负责监视所有I/O事件,当事件发生时,它将其分派到注册了该事件的处理程序进行处理。这个模式通常用于处理客户端连接请求,即当一个客户端连接时,事件循环线程会接受并将连接请求分发到一个新的线程或进程中处理。

Proactor模式是一种异步I/O模型,其中一个线程(通常称为完成处理线程)负责监视所有I/O操作的完成情况,并在完成时通知相关的处理程序。这个模式通常用于处理大量的I/O操作,比如文件或网络传输,因为它可以在操作完成之前允许应用程序继续处理其他任务。

因此,Reactor模式主要用于处理少量的I/O事件,而Proactor模式则适用于处理大量的I/O操作。

● 两个模式下调用read()时有什么不一样

在Reactor模式中,当调用read()方法时,线程会阻塞,直到有数据可读。当有数据可读时,线程将从操作系统内核中读取数据,并将其传递给处理程序进行处理。这个过程是同步的,即在read()方法返回之前,线程将一直阻塞。

在Proactor模式中,当调用read()方法时,线程将不会阻塞,而是立即返回。然后,一个异步操作被启动,在数据可读时将会通知一个完成处理线程,并将数据传递给处理程序进行处理。这个过程是异步的,即在read()方法返回之前,数据并没有被读取,而是在之后通过回调函数异步处理。

因此,Reactor模式中的read()方法是同步阻塞的,而Proactor模式中的read()方法是异步非阻塞的。在Proactor模式中,由于read()方法立即返回,应用程序可以继续执行其他任务,而不必等待数据读取完成。这使得Proactor模式更适合处理大量的I/O操作,因为它可以充分利用处理器的并发能力。

● 同步IO与异步IO区别

同步和异步最大的区别就是被调用方的执行方式返回时机。同步指的是被调用方做完事情之后再返回,异步指的是被调用方先返回,然后再做事情,做完之后再想办法通知调用方。

● 阻塞lo与非阻塞IO的区别

阻塞和非阻塞最大的区别就是在被调用方返回结果之前的这段时间内,调用方是否一直等待。阻塞指的是调用方一直等待别的事情什么都不做。非阻塞指的是调用方先去忙别的事情。

● 说一下惊群现象,怎么解决

多进程(多线程)在同时阻塞等待同一个事件的时候(休眠状态),如果等待的这个事件发生,那么他就会唤醒等待的所有进程(或者线程),但是最终却只能有一个进程(线程)获得这个时间的“控制权”,对该事件进行处理,而其他进程(线程)获取“控制权”失败,只能重新进入休眠状态,这种现象和性能浪费就叫做惊群效应。

● TCP与UDP最大的区别

可靠交付,基于数据报还是字节流,是否建立连接,首部字节数,首部多了哪些信息,信息都有什么作用。

●四次挥手中TIME WAIT的作用是什么

在TCP连接关闭时,四次挥手中的TIME_WAIT状态是为了确保连接的完全关闭,避免新的连接使用已经失效的连接标识符。

具体来说,当主动关闭方发送最后一个ACK报文后,它会进入TIME_WAIT状态。在这个状态下,它将继续等待一段时间(通常是2倍的最大段生存时间MSL),以确保所有的ACK报文都能到达被动关闭方。如果有任何遗漏的ACK报文,被动关闭方会重新发送FIN报文,主动关闭方可以通过已经存在的连接标识符来区分这个新的FIN报文和之前的连接。

如果主动关闭方没有进入TIME_WAIT状态,而是立即释放连接标识符,那么可能会发生一些问题。例如,如果之前的连接标识符被重用,新的连接可能会收到之前的遗留数据或ACK报文,从而导致混淆或错误。通过等待一段时间,TIME_WAIT状态可以确保新的连接不会混淆或受到错误的影响。

●算法题:二叉树的前序遍历,非递归形式

二叉树的遍历——深度:前中后,方法——递归和迭代

                             广度:层次遍历,方法——队列(非常好用)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值