第一次面试总结
首先,笔试:
一、问死锁是什么,死锁的原因有哪些?死锁的四个必要条件是神马?如何解开死锁?
死锁: 指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。
死锁的原因有两个:
a. 竞争资源
系统中的资源可以分为两类:
(1)可剥夺资源,是指某进程在获得这类资源后,该资源可以再被其他进程或系统剥夺,CPU和主存均属于可剥夺性资源;
(2)不可剥夺资源,当系统把这类资源分配给某进程后,再不能强行收回,只能在进程用完后自行释放,如磁带机、打印机等。
产生死锁中的竞争资源之一指的是竞争不可剥夺资源(例如:系统中只有一台打印机,可供进程P1使用,假定P1已占用了打印机,若P2继续要求打印机打印将阻塞)
产生死锁中的竞争资源另外一种资源指的是竞争临时资源(临时资源包括硬件中断、信号、消息、缓冲区内的消息等),通常消息通信顺序进行不当,则会产生死锁
b. 进程间推进顺序非法
若P1保持了资源R1,P2保持了资源R2,系统处于不安全状态,因为这两个进程再向前推进,便可能发生死锁
例如,当P1运行到P1:Request(R2)时,将因R2已被P2占用而阻塞;当P2运行到P2:Request(R1)时,也将因R1已被P1占用而阻塞,于是发生进程死锁
死锁的四个必要条件
如何解开死锁??
1.剥夺资源:从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态;
2.撤消进程:可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,死锁状态.消除为止;所谓代价是指优先级、运行代价、进程的重要性和价值等。
附加::
如何预防死锁?
1)资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件)
2)只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件)
3)可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
4)资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)
避免死锁:
预防死锁的几种策略,会严重地损害系统性能。因此在避免死锁时,要施加较弱的限制,从而获得 较满意的系统性能。由于在避免死锁的策略中,允许进程动态地申请资源。因而,系统在进行资源分配之前预先计算资源分配的安全性。若此次分配不会导致系统进入不安全的状态,则将资源分配给进程;否则,进程等待。其中最具有代表性的避免死锁算法是银行家算法。
银行家算法:首先需要定义状态和安全状态的概念。系统的状态是当前给进程分配的资源情况。因此,状态包含两个向量Resource(系统中每种资源的总量)和Available(未分配给进程的每种资源的总量)及两个矩阵Claim(表示进程对资源的需求)和Allocation(表示当前分配给进程的资源)。安全状态是指至少有一个资源分配序列不会导致死锁。当进程请求一组资源时,假设同意该请求,从而改变了系统的状态,然后确定其结果是否还处于安全状态。如果是,同意这个请求;如果不是,阻塞该进程知道同意该请求后系统状态仍然是安全的。
二、计算下列程序一共有多少条进程:
int main()
{
fork();
fork() && fork() || fork();
fork();
return 0;
}
子进程有10个,父进程有10个 共20个。
三、写一个函数找出数组中第三大的数
#include
int find(int max, int n, int num[])
{
int i = 0,max_t = 0;
while(i < n){
if(max_t < num[i] && num[i] < max)
max_t = num[i];
i++;
}
return max_t;
}
int main(int argc, char *argv[])
{
int i,x,n;
int max = 0;
int num[] = {1,4,2,5,6,3,9,8};
n = sizeof(num)/sizeof(int);
printf("一共有%d个数\n",n);
printf("请输入第几大的数:");
scanf("%d",&x);
for(i = 0; i < sizeof(num)/sizeof(int); i++)
if(max < num[i])
max = num[i];
if(1 == x)
printf("第%d大的数是:%d\n",x,max);
else if(x > 1){
for(i = 1; i < x; i++)
max = find(max,n,num);
printf("第%d大的数是:%d\n",x,max);
}
return 0;
}
四、有1-10000个连续的整数,现从中删除两个数然后打乱,如何快速的找到删除的这两个数是什么?
::使用二分法,把>5000的数分一组,计算是否有5000个数,如果没有取中间数接着划分比较,如果有则在1-5000中继续取中计算大小是否有相应的大小,可以很快的找到这两个数。
五、有1000瓶药水,其中有一瓶有毒,小鼠喝一点就会在24小时毒发,问至少需要多少只老鼠才能在24时找到哪瓶是毒药?(喂药时间不计)。
::10只
1 = 0000 0000 01
2 = 0000 0000 10
3 = 0000 0000 11
4 = 0000 0001 00
5 = 0000 0001 01……
1000 = 1111 1010 00
从前之后代表从10号---1号的老鼠,为1的就喂,那样最后哪些老鼠死了,哪些也为1,转成十进制就可以知道是哪瓶了。
六、有粗细不同的绳子,假设每根绳子烧完的时间都是一个小时,至少需要几根绳子才能计算45分钟?(只允许做点燃操作)
::两根
将1号两头同时点燃同时把2号一头点燃,当1号烧完时点燃2号的另一头,等2号烧完就是45分钟。