1. 程式人生 > >關於第一次面試總結(嵌入式軟體開發工程師)

關於第一次面試總結(嵌入式軟體開發工程師)

第一次面試總結

首先,筆試:

一、問死鎖是什麼,死鎖的原因有哪些?死鎖的四個必要條件是神馬?如何解開死鎖?

死鎖: 指多個程序在執行過程中因爭奪資源而造成的一種僵局,當程序處於這種僵持狀態時,若無外力作用,它們都將無法再向前推進。

死鎖的原因有兩個:

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) 請求與保持條件:一個程序因請求資源而阻塞時,對已獲得的資源保持不放。

(3) 不剝奪條件:程序已獲得的資源,在末使用完之前,不能強行剝奪。

(4) 迴圈等待條件:若干程序之間形成一種頭尾相接的迴圈等待資源關係。

如何解開死鎖??

1.剝奪資源:從其它程序剝奪足夠數量的資源給死鎖程序,以解除死鎖狀態;

2.撤消程序:可以直接撤消死鎖程序或撤消代價最小的程序,直至有足夠的資源可用,死鎖狀態.消除為止;所謂代價是指優先順序、執行代價、程序的重要性和價值等。

附加::

如何預防死鎖?

1)資源一次性分配:一次性分配所有資源,這樣就不會再有請求了:(破壞請求條件)

2)只要有一個資源得不到分配,也不給這個程序分配其他的資源:(破壞請保持條件)

3)可剝奪資源:即當某程序獲得了部分資源,但得不到其它資源,則釋放已佔有的資源(破壞不可剝奪條件)

4)資源有序分配法:系統給每類資源賦予一個編號,每一個程序按編號遞增的順序請求資源,釋放則相反(破壞環路等待條件)

避免死鎖:

預防死鎖的幾種策略,會嚴重地損害系統性能。因此在避免死鎖時,要施加較弱的限制,從而獲得 較滿意的系統性能。由於在避免死鎖的策略中,允許程序動態地申請資源。因而,系統在進行資源分配之前預先計算資源分配的安全性。若此次分配不會導致系統進入不安全的狀態,則將資源分配給程序;否則,程序等待。其中最具有代表性的避免死鎖演算法是銀行家演算法

銀行家演算法:首先需要定義狀態和安全狀態的概念。系統的狀態是當前給程序分配的資源情況。因此,狀態包含兩個向量Resource(系統中每種資源的總量)和Available(未分配給程序的每種資源的總量)及兩個矩陣Claim(表示程序對資源的需求)和Allocation(表示當前分配給程序的資源)。安全狀態是指至少有一個資源分配序列不會導致死鎖。當程序請求一組資源時,假設同意該請求,從而改變了系統的狀態,然後確定其結果是否還處於安全狀態。如果是,同意這個請求;如果不是,阻塞該程序知道同意該請求後系統狀態仍然是安全的。

二、計算下列程式一共有多少條執行緒:

int main()

{

    fork();

    fork() && fork() || fork();

    fork();

    return 0;

}

子程序有10個,父程序有10個  共20個。

三、寫一個函式找出陣列中第三大的數

#include <stdio.h>



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分鐘。