14.select和poll差异?Poll和epoll的差别?
(1)select和poll的差别:(參考:http://blog.csdn.net/mituan2008/article/details/6695177)
二者根本的不同是:select()的fd_set是一个位掩码(bit mask)。因此fd_set有固定的长度。内核在被编译的时候,能够不受这个长度的限制,由于select()同意应用程序自己定义FD_SETSIZE的大小,可是这会添加额外的支出。
在调用poll()时须要自己定义pollfd结构体数组而且须要指定数组的大小,所以呢这里原理上讲就是没有限制的。
(2)select和poll、epoll的差别(參考http://www.cnblogs.com/Anker/p/3265058.html)
A. select,poll实现须要自己不断轮询全部fd集合,直到设备就绪。期间可能要睡眠和唤醒多次交替。而epoll事实上也须要调用epoll_wait不断轮询就绪链表。期间也可能多次睡眠和唤醒交替。可是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中。并唤醒在epoll_wait中进入睡眠的进程。尽管都要睡眠和交替。可是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候仅仅要推断一下就绪链表是否为空即可了,这节省了大量的CPU时间。
这就是回调机制带来的性能提升。
B. select,poll每次调用都要把fd集合从用户态往内核态拷贝一次。并且要把current往设备等待队列中挂一次,而epoll仅仅要一次拷贝,并且把current往等待队列上挂也仅仅挂一次(在epoll_wait的開始,注意这里的等待队列并非设备等待队列,仅仅是一个epoll内部定义的等待队列)。
这也能节省不少的开销。
C. select的几大缺点:
每次调用select,都须要把fd集合从用户态复制到内核态。这个开销在fd非常多时会非常大;
同一时候每次调用select都须要在内核遍历传递进来的全部fd,这个开销在fd非常多时也非常大;
select支持的文件描写叙述符数量太小了,默认是1024.
D. poll的实现和select很相似。仅仅是描写叙述fd集合的方式不同,描写叙述符数量不受限制,poll使用pollfd结构而不是select的fd_set结构,其它的都差点儿相同。
15.谈谈对段页式管理的认识?什么时候会出现segment fault(段错误、缺页异常)?
什么是段页式管理?參考:http://blog.csdn.net/xiucaijiang/article/details/6818359
(http://zhan.renren.com/h5/entry/3602888497996214030
事实上更好的解说在ULK3 page376:缺页异常处理程序)
引入段页式管理的目的:为了获得分段在逻辑上的长处和分页在管理存储空间方面的长处。
(1)用分段方法来分配和管理虚拟存储器。把进程地址空间分成若干段,而每一段有自己的段名,把每一段分成若干页。
(2)用分页方法来分配和管理实存。
即把整个主存分成大小相等的存储块,可装入作业的不论什么一页。
(3)逻辑地址结构的表示:一个逻辑地址用三个參数表示:段号S;页号P;页内地址d。
(4)段表、页表、段表地址寄存器。为了进行地址转换,系统为每个进程建立一个段表,而且要为该进程段表中的每个段建立一个页表。系统中有一个段表地址寄存器来指出进程的段表起始地址和段表长度。
段页式管理的优缺点:
长处
(1)它提供了大量的虚拟存储空间。
(2)能有效地利用主存。为组织多道程序执行提供了方便。
缺点
(1)添加了硬件成本、系统的复杂性和管理上的开消。
(2)存在着系统发生抖动的危急。
(3)存在着内碎片。
(4)还有各种表格要占用主存空间。
段页式存储管理技术对当前的大、中型计算机系统来说。算是最通用、最灵活的一种方案。
什么时候会出现segment fault?内核中的机制是什么?
专业解释请參考ULK3 page376:缺页异常处理程序,哥如今还没怎么弄明确。
16.哈希表用来做什么?
哈希表也叫散列表,依据key value对数据进行分组,用于高速插入和查找
17.core文件的实现原理是什么?
请參考本博客:
http://blog.csdn.net/xu*/article/category/1322964
这哥儿们写了几十篇文章讲述core dump原理,我这里就不c-c,c-v了
假设面试官问道。就这么说吧(參考http://www.cnblogs.com/hazir/p/linxu_core_dump.html):
当程序执行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来。保存在一个文件里,这样的行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们能够觉得 core dump 是“内存快照”。但实际上,除了内存信息之外。还有些关键的程序执行状态也会同一时候 dump 下来,比如寄存器信息(包含程序指针、栈指针等)、内存管理信息、其它处理器和操作系统状态和信息。
core dump 对于编程人员诊断和调试程序是非常有帮助的,由于对于有些程序错误是非常难重现的。比如指针异常,而 core dump 文件能够再现程序出错时的情景。
18.fork返回0和大于0各自是进程?
返回值为0的是子进程。返回值大于0的是父进程,大于0的返回值为子进程的进程号,出错返回-1
函数说明:一个现有进程能够调用fork函数创建一个新进程。
由fork创建的新进程被称为子进程(child process)。
fork函数被调用一次但返回两次。两次返回的唯一差别是子进程中返回0值而父进程中返回子进程ID。子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”。这意味着父子进程间不共享这些存储空间。它们之间共享的存储空间仅仅有代码段。
19.程序运行时堆和栈用来做什么?
BSS段 data段 text段 堆heap 和 栈stack
BSS段:BSS段(bss segment)一般是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。
数据段:数据段(data segment)一般是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。
代码段:代码段(code segment/text segment)一般是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序执行前就已经确定,而且内存区域通常属于仅仅读, 某些架构也同意代码段为可写,即同意改动程序。在代码段中,也有可能包括一些仅仅读的常数变量。比如字符串常量等。
堆(heap):堆是用于存放进程执行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态加入到堆上(堆被扩张)。当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
栈(stack):栈又称堆栈,是用户存放程序暂时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包含static声明的变量,static意味着在数据段中存放变量)。
除此以外,在函数被调用时,其參数也会被压入发起调用的进程栈中。而且待到调用结束后,函数的返回值也会被存放回栈中。
因为栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。
从这个意义上讲,我们能够把堆栈看成一个寄存、交换暂时数据的内存区。
20. 线程和进程的差别?
(http://www.cnblogs.com/flashsky/articles/642720.html)
线程是指进程内的一个运行单元,也是进程内的可调度实体.
与进程的差别:
(1)地址空间:线程共享进程的地址空间;而进程有自己独立的地址空间;
(2)资源拥有:线程共享进程的资源,进程是资源分配和拥有的单位
(3)线程是处理器调度的基本单位,但进程不是.
4)二者均可并发运行.
进一步展开:
进程和线程都是由操作系统所体会的程序执行的基本单元,系统利用该基本单元实现系统相应用的并发性。进程和线程的差别在于:
简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程,使得多线程程序的并发性高。
另外。进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的执行效率。
线程在运行过程中与进程还是有差别的。每一个独立的线程有一个程序运行的入口、顺序运行序列和程序的出口。
可是线程不可以独立运行,必须依存在应用程序中,由应用程序提供多个线程运行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个运行部分能够同一时候运行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要差别。
进程是具有一定独立功能的程序关于某个数据集合上的一次执行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立执行的基本单位.线程自己基本上不拥有系统资源,仅仅拥有一点在执行中不可缺少的资源(如程序计数器,一组寄存器和栈),可是它可与同属一个进程的其它的线程共享进程所拥有的所有资源.
一个线程可以创建和销毁,以及线程;您可以在同一进程中的多个线程之间并发运行.
版权声明:本文博客原创文章,博客,未经同意,不得转载。