百度2015简答题

来源:互联网 发布:网络励志名言 编辑:程序博客网 时间:2024/05/01 09:49
1.当前计算机系统一般会采用层次结构来存储数据,请介绍下典型的计算机存储系统一般分为哪几个层次,为什么采用分层存储数据能有效提高程序的执行效率?
计算机系统中存储层次可分为高速缓冲存储器(cache)、主存储器、辅助存储器三级。
高速缓冲存储器用来改善主存储器与中央处理器的速度匹配问题。
辅助存储器用于扩大存储空,即硬盘,光盘等,容量大,但存取数据慢,计算机都是先把辅存中要读的东西放到主存后处理,然后在依据情况是否写回。
主存即为内存,断电信息丢失,但存取数据块,它的容量大小直接影响计算机运行速度。
可把主存一辅存层次作为一个存储整体,形成的可寻址存储空间比主存储器空间大得多。由于辅存容量大,价格低,使得存储系统的整体平均价格降低。
由于Cache的存取速度可以和CPU的工作速度相媲美,故cache一主存层次可以缩小主存和CPU之间的速度差距,从整体上提高存储器系统的存取速度。尽管Cache成本高,但由于容量较小,故不会使存储系统的整体价格增加很多
其中高速缓存解决了存储系统的速度问题,辅助存储器则解决了存储系统的容量问题。

采用多级层次结构的存储器系统可以有效的解决存储器的速度、容量和价格之间的矛盾。

2.Unix/Linux系统中僵尸进程是如何产生的?有什么危害?为何避免?
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
如果进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。
孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上,因此孤儿进程并不会有什么危害。
任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理

3.请简述Tcp-ip的3次握手以及4次挥手过程?并解释为何关闭连接需要4次挥手
三次挥手
(1)服务器必须准备好接受外来的连接。这通常通过调用socket,bind和listen这三个函数来完成。我们称之为被动打开
(2)客户端通过调用connect发起主动打开。这导致客户tcp发送一个syn(同步)分节,他告诉服务器客户在连接中发送的数据的初始序列号。通常syn分节不携带数据,其所在ip数据报只含有一个ip首部,一个tcp首部及可能有的tcp选项
(3)服务器必须确认ack客户的syn,同时自己也得发送一个syn分节,它含有服务器在同一连接中发送的数据的初始序列号。服务器在单个分节中发送syn和对客户syn的ack确认
(4)客户必须确认服务器的syn
注:客户的初始序列号为J,服务器的初始序列号为K,ack中的确认号是发送这个ack的一端所期待的下一个序列号
4次挥手
(1)某个应用进程首先调用close,我们称该端执行主动关闭。该端的tcp于是发送一个fin分节,表示数据发送完毕
(2)接受到这个fin的对端执行被动关闭。这个fin由tcp确认。他的接收也作为一个文件描述符传递给接收端应用程序。
(3)一段时间后,接收到这个文件描述符的应用进程将调用close关闭它的套接字。这导致它的tcp也发送一个fin
(4)接受这个最终fin的原发送端tcp,确认这个fin

这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。

如果采用二次握手,主机A向主机B发送连接请求,B接到A的请求后并应答,如果B的应答由于网络原因未到达A,主机B认为链接已经建立,而A则认为连接没有建立,此时B向A发数据,A在收到B的应答前不予理会,B却等待A发送数据造成资源浪费

4.操作系统的内存管理淘汰算法有哪些,请列出并简要说明?
最佳(OPT)置换算法是理论算法,它将不再使用的页面换出,而实际中不能预知哪个页面不再使用,但是这个算法是最优算法,可以作为评测其他算法的性能。
先进先出(FIFO)置换算法
最近最少(LRU)使用置换算法:发生缺页时计算距离上次使用的时间差,找最大值,替换该页
最近最不经常(NRU)使用算法:最近未被修改r =0&&m=0
该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如,含有全局变量、常用函数、例程等的页面,FIFO 算法并不能保证这些页面不被淘汰。FIFO 置换算法性能之所以较差,是因为它所依据的条件是各个页面调入内存的时间,而页面调入的先后并不能反映页面的使用情况。LRU 算法是较好的一种算法,但由于它要求有较多的硬件支持,故在实际应用中,大多采用LRU的近似算法。Clock(NRU)算法就是用得较多的一种LRU近似算法。FIFO会出现belady异常,即当所分配的物理块(页框)增大而页故障数不减反增的现象,LRU是堆栈类算法需要寄存器和栈的支持不会出现异常
5.动态链接库和静态链接库的优缺点
静态库是目标文件.a的归档文件(格式为libname.a)。如果在编译某个程序时链接静态库,则链接器将会搜索静态库并直接拷贝到该程序的可执行二进制文件到当前文件中
创建静态库
$ gcc  -c  add.c    //编译add.c源文件生成add.o目标文件
$ ar  crsv  libadd.a  add.o
动态库(格式为libname.so)在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入。
创建动态库
$ gcc  -fPIC  -Wall  -c  add.c
$ gcc  -shared  -o  libadd.so  add.o
静态库与动态库的比较:
动态库只在执行时才被链接使用,不是直接编译为可执行文件,并且一个动态库可以被多个程序使用故可称为共享库。
静态库将会整合到程序中,在程序执行时不用加载静态库。 因此,静态库会使你的程序臃肿并且难以升级,但比较容易部署。而动态库会使你的程序轻便易于升级但难以部署。 
6.轮询任务调度和可抢占式调度有什么区别?

(1)轮询调度的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。只有在当前任务主动放弃CPU控制权的情况下(比如任务挂起),才允许其他任务(包括高优先级的任务)控制CPU。其优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。但不利于后面的请求及时得到响应。
(2)抢占式调度允许高优先级的任务打断当前执行的任务,抢占CPU的控制权。这有利于后面的高优先级的任务也能及时得到响应。但实现相对较复杂且可能出现低优先级的任务长期得不到调度。












0 0