操作系统|其他

综合

01 delete和delete[]区别?

  • delete只会调用一次析构函数。

  • delete[]会调用数组中每个元素的析构函数。

02 为什么C++没有垃圾回收机制?这点跟Java不太一样。

首先,实现一个垃圾回收器会带来额外的空间和时间开销。

你需要开辟一定的空间保存指针的引用计数和对他们进行标记mark。然后需要单独开辟一个线程在空闲的时候进行free操作。

垃圾回收会使得C++不适合进行很多底层的操作。

03 局部性原理你知道吗?主要有哪两大局部性原理?各自是什么?

主要分为时间局部性和空间局部性

时间局部性

如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(因为程序中存在大量的循环) 空间局部性

一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。(因为很多数据在内存中都是连续存放的,并且程序的指令也是顺序地在内存中存放的)

04 共享是什么?

共享是指系统中的资源可以被多个并发进程共同使用。

有两种共享方式:互斥共享和同时共享。

互斥共享的资源称为临界资源,例如打印机等,在同一时刻只允许一个进程访问,需要用同步机制来实现互斥访问。

05 并发和并行是什么?

并发

指宏观上在一段时间内能同时运行多个程序,而并行则指同一时刻能运行多个指令。

并行

需要硬件支持,如多流水线、多核处理器或者分布式计算系统。

操作系统通过引入进程和线程,使得程序能够并发运行。

06 原子操作的是如何实现的

处理器使用基于对缓存加锁或总线加锁的方式来实现多处理器之间的原子操作。

首先处理器会自动保证基本的内存操作的原子性。处理器保证从系统内存中读取或者写入一个字节是原子的,意思是当一个处理器读取一个字节时,其他处理器不能访问这个字节的内存地址。

Pentium 6和最新的处理器能自动保证单处理器对同一个缓存行里进行16/32/64位的操作是原子的,但是复杂的内存操作处理器是不能自动保证其原子性的,比如跨总线宽度、跨多个缓存行和跨页表的访问。但是,处理器提供总线锁定和缓存锁定两个机制来保证复杂内存操作的原子性。

(1)使用总线锁保证原子性 第一个机制是通过总线锁保证原子性。如果多个处理器同时对共享变量进行读改写操作(i++就是经典的读改写操作),那么共享变量就会被多个处理器同时进行操作,这样读改写操作就不是原子的,操作完之后共享变量的值会和期望的不一致。举个例子,如果i=1,我们进行两次i++操作,我们期望的结果是3,但是有可能结果是2,如图下图所示。

CPU1    CPU2
 i=1     i=1
 i+1     i+1
 i=2     i=2

原因可能是多个处理器同时从各自的缓存中读取变量i,分别进行加1操作,然后分别写入系统内存中。那么,想要保证读改写共享变量的操作是原子的,就必须保证CPU1读改写共享变量的时候,CPU2不能操作缓存了该共享变量内存地址的缓存。

处理器使用总线锁就是来解决这个问题的。所谓总线锁就是使用处理器提供的一个LOCK#信号,当一个处理器在总线上输出此信号时,其他处理器的请求将被阻塞住,那么该处理器可以独占共享内存。

2)使用缓存锁保证原子性

第二个机制是通过缓存锁定来保证原子性。在同一时刻,我们只需保证对某个内存地址的操作是原子性即可,但总线锁定把CPU和内存之间的通信锁住了,这使得锁定期间,其他处理器不能操作其他内存地址的数据,所以总线锁定的开销比较大,目前处理器在某些场合下使用缓存锁定代替总线锁定来进行优化。

频繁使用的内存会缓存在处理器的L1、L2和L3高速缓存里,那么原子操作就可以直接在处理器内部缓存中进行,并不需要声明总线锁,在Pentium 6和目前的处理器中可以使用“缓存锁定”的方式来实现复杂的原子性。

所谓“缓存锁定”是指内存区域如果被缓存在处理器的缓存行中,并且在Lock操作期间被锁定,那么当它执行锁操作回写到内存时,处理器不在总线上声言LOCK#信号,而是修改内部的内存地址,并允许它的缓存一致性机制来保证操作的原子性。

因为缓存一致性机制会阻止同时修改由两个以上处理器缓存的内存区域数据,当其他处理器回写已被锁定的缓存行的数据时,会使缓存行无效,在如上图所示的例子中,当CPU1修改缓存行中的i时使用了缓存锁定,那么CPU2就不能使用同时缓存i的缓存行。

但是有两种情况下处理器不会使用缓存锁定。 第一种情况是:当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行(cache line)时,则处理器会调用总线锁定。 第二种情况是:有些处理器不支持缓存锁定。对于Intel 486和Pentium处理器,就算锁定的内存区域在处理器的缓存行中也会调用总线锁定。

07 操作系统保护模式和实模式可以大致说说区别吗?

原回答 实模式 实模式早期的那种处理器的一个工作模式,然后他只能使用一些低端的中断处理方式,很难实现一些复杂的功能。 保护模式 保护模式的话它是相对于那个实模式来说它是一种更高级别的工作模式,它能访问的内存也更多,然后它也支持一些就是什么特权就是权限的一些东西比方说内、内核态和用户态的一些东西,更加灵活和安全吧。

补充

其实问这个问题的目的,是为了引出虚拟内存,所以他后面都往虚拟内存方向问了。 实模式 实模式将整个物理内存看成分段的区域,程序代码和数据位于不同区域,系统程序和用户程序并没有区别对待,而且每一个指针都是指向实际的物理地址。这样一来,用户程序的一个指针如果指向了系统程序区域或其他用户程序区域,并修改了内容,那么对于这个被修改的系统程序或用户程序,其后果就很可能是灾难性的。再者,随着软件的发展,1M的寻址空间已经远远不能满足实际的需求了。最后,对处理器多任务支持需求也日益紧迫,所有这些都促使新技术的出现。 保护模式 为了克服实模式下的内存非法访问问题,并满足飞速发展的内存寻址和多任务需求,处理器厂商开发出保护模式。在保护模式中,除了内存寻址空间大大提高;提供了硬件对多任务的支持;物理内存地址也不能直接被程序访问,程序内部的地址(虚拟地址)要由操作系统转化为物理地址去访问,程序对此一无所知。

至此,进程(程序的运行态)有了严格的边界,任何其他进程根本没有办法访问不属于自己的物理内存区域,甚至在自己的虚拟地址范围内也不是可以任意访问的,因为有一些虚拟区域已经被放进一些公共系统运行库。这些区域也不能随便修改,若修改就会有出现linux中的段错误,或Windows中的非法内存访问对话框。

08 操作系统的目标和功能是什么?

处理机管理:

处理机的运行以进程(或线程)为基本单位,对处理机的管理可归结为对进程的管理。

管理进程的资源共享:进程控制、进程同步、进程通信、死锁处理、处理机调度

存储器管理:

给多道程序的运行提供良好环境,方便用户使用+提高内存利用率

内存分配、地址映射、内存保护与共享、内存扩充

文件管理:

计算机中的信息以文件形式存在。

文件存储空间管理、目录管理、文件读写管理和保护

设备管理:

完成用户的I/O请求,方便用户使用各种设备,并提高设备利用率

缓冲管理、设备分配、设备处理、虚拟设备

09 用户态和内核态是什么?有什么区别?

内核态

cpu可以访问内存的所有数据,包括外围设备,例如硬盘,网卡,cpu也可以将自己从一个程序切换到另一个程序。

用户态

只能受限的访问内存,且不允许访问外围设备,占用cpu的能力被剥夺,cpu资源可以被其他程序获取。

最大的区别就是权限不同,在运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。

为什么要有这两态

需要限制不同的程序之间的访问能力,防止他们获取别的程序的内存数据,或者获取外围设备的数据,并发送到网络,CPU划分出两个权限等级 -- 用户态和内核态。

10 描述符是什么?如何创建的?

定义

在操作系统中,描述符是一种数据结构,用于表示和管理文件、设备、进程等资源。每个描述符都包含了资源的一些属性和操作方法。

创建

描述符的创建通常是通过系统调用来完成,具体的操作系统和编程语言可能有所不同。一般而言,创建描述符的步骤如下:

  • 打开资源:首先需要打开需要操作的资源,例如文件、设备等。在大多数操作系统中,可以使用open()或者类似的函数来打开资源,并返回一个文件描述符。

  • 分配描述符:系统会为每个打开的资源分配一个唯一的描述符。描述符一般是一个整数值,可以用来识别和访问对应的资源。

  • 操作资源:通过描述符可以对资源执行各种操作,例如读写文件、发送数据等。操作资源时,可以使用描述符作为参数来指定要操作的资源。

  • 关闭资源:当不再需要使用资源时,需要关闭对应的描述符,释放资源并清理相关的数据结构。一般可以使用close()函数来关闭描述符。

需要注意的是,描述符是操作系统内部使用的一种抽象,通常不直接暴露给应用程序。应用程序可以通过高级的接口(例如文件操作、网络操作等)来间接操作资源,而无需直接处理描述符。

11 阻塞和非阻塞是什么意思?

在操作系统中,阻塞和非阻塞是指进程在执行某个操作时是否会等待操作的完成。

阻塞是指当一个进程执行某个操作时,如果该操作没有完成,进程会被挂起,等待操作完成后再继续执行。在阻塞状态下,进程无法进行其他的操作,直到阻塞的操作完成或者被取消。

非阻塞是指当一个进程执行某个操作时,如果该操作没有完成,进程不会被挂起,而是立即返回一个错误码或者一个特殊的值,继续执行其他的操作。在非阻塞状态下,进程可以进行其他的操作,无需等待阻塞的操作完成。

阻塞和非阻塞的选择取决于应用程序的需求和设计。阻塞操作可以保证操作的正确性和一致性,但可能会导致应用程序的响应时间延长。非阻塞操作可以提高应用程序的响应速度,但可能需要额外的处理逻辑来处理未完成的操作。

12 程序中局部变量,全局变量和动态申请的数据都存放在哪里?

局部变量存放在栈中,全局变量存放在静态数据区或全局数据区,动态申请的数据存放在堆中。

13 Linux中异常和中断的区别/键盘敲击发生的中断是怎么回事?

中断

大家都知道,当我们在敲击键盘的同时就会产生中断,当硬盘读写完数据之后也会产生中断,所以,我们需要知道,中断是由硬件设备产生的,而它们从物理上说就是电信号。

之后,它们通过中断控制器发送给CPU,接着CPU判断收到的中断来自于哪个硬件设备(这定义在内核中)。

最后,由CPU发送给内核,有内核处理中断。下面这张图显示了中断处理的流程:

异常

我们在学习《计算机组成原理》的时候会知道两个概念,CPU处理程序的时候一旦程序不在内存中,会产生缺页异常;当运行除法程序时,当除数为0时,又会产生除0异常。

所以,大家也需要记住的是,异常是由CPU产生的,同时,它会发送给内核,要求内核处理这些异常,下面这张图显示了异常处理的流程:

相同点

  • 最后都是由CPU发送给内核,由内核去处理

  • 处理程序的流程设计上是相似的

不同点

  • 产生源不相同,异常是由CPU产生的,而中断是由硬件设备产生的
  • 内核需要根据是异常还是中断调用不同的处理程序
  • 中断不是时钟同步的,这意味着中断可能随时到来;异常由于是CPU产生的,所以它是时钟同步的
  • 当处理中断时,处于中断上下文中;处理异常时,处于进程上下文中。

14 外中断和异常有什么区别?

外中断是指由 CPU 执行指令以外的事件引起,如 I/O 完成中断,表示设备输入/输出处理已经完成,处理器能够发送下一个输入/输出请求。此外还有时钟中断、控制台中断等。

而异常时由 CPU 执行指令的内部事件引起,如非法操作码、地址越界、算术溢出等。

Job-Hunter 文章被收录于专栏

2024年最新整理的八股文。 包括计算机网络,操作系统,MySQL,linux,设计模式,数据结构和算法,等等。 题目来源于网友爆料,GZH摘录,CSDN等等。 根据考察知识点,将题目进行分类,方便背诵。

全部评论

相关推荐

投递大华股份等公司10个岗位
点赞 评论 收藏
分享
评论
1
5
分享
牛客网
牛客企业服务