20道嵌入式工程師面試題(附答案)

近期,正逢畢業求職季,我們根據以往的學員的面試經歷,為大家整理了一些面試經常會遇到的題目,希望這些乾貨對大家面試有所幫助。

更多相關資料下載,技術文章請關注公眾號:

自動化部落

,獲取

20道嵌入式工程師面試題(附答案)

1。嵌入式系統中經常要用到無限迴圈,如何用C編寫死迴圈

答:while(1){}或者for(;;)

2。程式的區域性變數存在於哪裡,全域性變數存在於哪裡,動態申請資料存在於哪裡。

答:程式的區域性變數存在於棧區;全域性變數存在於靜態區;動態申請資料存在於堆區。

3。關鍵字const有什麼含義?

答:1)只讀。2)使用關鍵字const也許能產生更緊湊的程式碼。3)使編譯器很自然地保護那些不希望被改變的引數,防止其被無意的程式碼修改。

4。請問以下程式碼有什麼問題:

int main() {

char a;

char *str=&a;

strcpy(str,“hello”);

printf(str);

return 0;

}

答:沒有為str分配記憶體空間,將會發生異常,問題出在將一個字串複製進一個字元變數指標所指地址。雖然可以正確輸出結果,但因為越界進行內在讀寫而導致程式崩潰。

5。已知一個數組table,用一個宏定義,求出資料的元素個數

答: #define NTBL (sizeof(table)/sizeof(table[0]))

6。寫一個“標準”宏MIN ,這個宏輸入兩個引數並返回較小的一個。

答:#define MIN(A,B) ((A) <= (B) ? (A) : (B))

考點:

1) 標識#define在宏中應用的基本知識。這是很重要的。因為在 嵌入(inline)運算子 變為標準C的一部分之前,宏是方便產生嵌入程式碼的唯一方法,對於嵌入式系統來說,為了能達到要求的效能,嵌入程式碼經常是必須的方法。

2) 三重條件運算子的知識。這個運算子存在C語言中的原因是它使得編譯器能產生比if-then-else更優的程式碼,瞭解這個用法是很重要的。

3) 懂得在宏中小心地把引數用括號括起來。

7。do……while和while有什麼區別?

答:前一個迴圈一遍再判斷,後一個判斷以後再迴圈。

8。什麼是預編譯,何時需要預編譯?

答:

1、總是使用不經常改動的大型程式碼體。

2、程式由多個模組組成,所有模組都使用一組標準的包含檔案和相同的編譯選項。在這種情況下,可以將所有包含檔案預編譯為一個預編譯頭。

預編譯指令指示了在程式正式編譯前就由編譯器進行的操作,可以放在程式中的任何位置。

9。一個32位的機器,該機器的指標是多少位?

答:指標是多少位只要看地址匯流排的位數就行了。80386以後的機子都是32的資料匯流排。所以指標的位數就是4個位元組了。

10。區域性變數能否和全域性變數重名?

答:能,區域性會遮蔽全域性。

區域性變數可以與全域性變數同名,在函式內引用這個變數時,會用到同名的區域性變數,而不會用到全域性變數。

對於有些編譯器而言,在同一個函式內可以定義多個同名的區域性變數,比如在兩個迴圈體內都定義一個同名的區域性變數,而那個區域性變數的作用域就在那個迴圈體內。

11。引用與指標有什麼區別?

答:

1) 引用必須被初始化,指標不必。

2) 引用初始化以後不能被改變,指標可以改變所指的物件。

3) 不存在指向空值的引用,但是存在指向空值的指標。

12。關鍵字static的作用是什麼?

答:在C語言中,關鍵字static有三個明顯的作用:

1) 在函式體,一個被宣告為靜態的變數在這一函式被呼叫過程中維持其值不變。

2) 在模組內(但在函式體外),一個被宣告為靜態的變數可以被模組內所用函式訪問,但不能被模組外其它函式訪問。它是一個本地的全域性變數。

3) 在模組內,一個被宣告為靜態的函式只可被這一模組內的其它函式呼叫。那就是,這個函式被限制在宣告它的模組的本地範圍內使用。

13。static全域性變數與普通的全域性變數有什麼區別?static函式與普通函式有什麼區別?

答:全域性變數(外部變數)的說明之前再冠以static 就構成了靜態的全域性變數。

全域性變數本身就是靜態儲存方式,靜態全域性變數當然也是靜態儲存方式。這兩者在儲存方式上並無不同。

這兩者的區別雖在於非靜態全域性變數的作用域是整個源程式, 當一個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是有效的。而靜態全域性變數則限制了其作用域,即只在定義該變數的原始檔內有效, 在同一源程式的其它原始檔中不能使用它。

由於靜態全域性變數的作用域侷限於一個原始檔內,只能為該原始檔內的函式公用,因此可以避免在其它原始檔中引起錯誤。

從以上分析可以看出,把區域性變數改變為靜態變數後是改變了它的儲存方式即改變了它的生存期。把全域性變數改變為靜態變數後是改變了它的作用域,限制了它的使用範圍。

static函式與普通函式作用域不同。僅在本檔案。只在當前原始檔中使用的函式應該說明為內部函式(static),內部函式應該在當前原始檔中說明和定義。

對於可在當前原始檔以外使用的函式,應該在一個頭檔案中說明,要使用這些函式的原始檔要包含這個標頭檔案。

14。程序之間通訊的途徑有哪些?

答:程序間通訊主要透過管道、訊息、訊號等途徑進行。

1、無名管道( pipe ):管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。

2、高階管道(popen):將另一個程式當做一個新的程序在當前程式程序中啟動,則它算是當前程式的子程序,這種方式我們成為高階管道方式。

3、有名管道 (named pipe) :有名管道也是半雙工的通訊方式,但是它允許無親緣關係程序間的通訊。

4、訊息佇列( message queue ) :訊息佇列是由訊息的連結串列,存放在核心中並由訊息佇列識別符號標識。訊息佇列克服了訊號傳遞資訊少、管道只能承載無格式位元組流以及緩衝區大小受限等缺點。

5、訊號量( semophore ) :訊號量是一個計數器,可以用來控制多個程序對共享資源的訪問。它常作為一種鎖機制,防止某程序正在訪問共享資源時,其他程序也訪問該資源。因此,主要作為程序間以及同一程序內不同執行緒之間的同步手段。

6、訊號 ( sinal ) :訊號是一種比較複雜的通訊方式,用於通知接收程序某個事件已經發生。

7、共享記憶體( shared memory ) :共享記憶體就是對映一段能被其他程序所訪問的記憶體,這段共享記憶體由一個程序建立,但多個程序都可以訪問。共享記憶體是最快的 IPC 方式,它是針對其他程序間通訊方式執行效率低而專門設計的。它往往與其他通訊機制,如訊號兩,配合使用,來實現程序間的同步和通訊。

8、套接字( socket ) :套解口也是一種程序間通訊機制,與其他通訊機制不同的是,它可用於不同機器間的程序通訊。

15。產生死鎖的原因是什麼?

答:多個併發程序因爭奪系統資源而產生相互等待的現象。即:一組程序中的每個程序都在等待某個事件發生,而只有這組程序中的其他程序才能觸發該事件,這就稱這組程序發生了死鎖。

產生死鎖的本質原因為:

1)、系統資源有限。

2)、程序推進順序不合理。

16。死鎖的4個必要條件

答:

1、互斥:某種資源一次只允許一個程序訪問,即該資源一旦分配給某個程序,其他程序就不能再訪問,直到該程序訪問結束。

2、佔有且等待:一個程序本身佔有資源(一種或多種),同時還有資源未得到滿足,正在等待其他程序釋放該資源。

3、不可搶佔:別人已經佔有了某項資源,你不能因為自己也需要該資源,就去把別人的資源搶過來。

4、迴圈等待:存在一個程序鏈,使得每個程序都佔有下一個程序所需的至少一種資源。

當以上四個條件均滿足,必然會造成死鎖,發生死鎖的程序無法進行下去,它們所持有的資源也無法釋放。這樣會導致CPU的吞吐量下降。所以死鎖情況是會浪費系統資源和影響計算機的使用效能的。那麼,解決死鎖問題就是相當有必要的了。

17。死鎖的處理方式有哪些?

答:死鎖的處理方式主要從預防死鎖、避免死鎖、檢測與解除死鎖這四個方面來進行處理。

預防死鎖:

1、資源一次性分配:(破壞請求和保持條件)

2、可剝奪資源:即當某程序新的資源未滿足時,釋放已佔有的資源(破壞不可剝奪條件)

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

避免死鎖:

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

檢測死鎖:

首先為每個程序和每個資源指定一個唯一的號碼;

然後建立資源分配表和程序等待表

解除死鎖:

當發現有程序死鎖後,便應立即把它從死鎖狀態中解脫出來,常採用的方法有:

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

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

18。程序和執行緒有什麼區別?

答:程序是併發執行的程式在執行過程中分配和管理資源的基本單位。執行緒是程序的一個執行單元,是比程序還要小的獨立執行的基本單位。一個程式至少有一個程序,一個程序至少有一個執行緒。兩者的區別主要有以下幾個方面:

1。 程序是資源分配的最小單位。

2。 執行緒是程式執行的最小單位,也是處理器排程的基本單位,但程序不是,兩者均可併發執行。

3。 程序有自己的獨立地址空間,每啟動一個程序,系統就會為它分配地址空間,建立資料表來維護程式碼段、堆疊段和資料段,這種操作非常昂貴。而執行緒是共享程序中的資料,使用相同的地址空間,因此,CPU切換一個執行緒的花費遠比程序小很多,同時建立一個執行緒的開銷也比程序小很多。

4。 執行緒之間的通訊更方便,同一程序下的執行緒共享全域性變數、靜態變數等資料,而程序之間的通訊需要以通訊的方式(IPC)進行。不過如何處理好同步與互斥是編寫多執行緒程式的難點。但是多程序程式更健壯,多執行緒程式只要有一個執行緒死掉,整個程序也跟著死掉了,而一個程序死掉並不會對另外一個程序造成影響,因為程序有自己獨立的地址空間。

5。 程序切換時,消耗的資源大,效率低。所以涉及到頻繁的切換時,使用執行緒要好於程序。同樣如果要求同時進行並且又要共享某些變數的併發操作,只能用執行緒不能用程序。

6。 執行過程:每個獨立的程序有一個程式執行的入口、順序執行序列和程式入口。但是執行緒不能獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。

優缺點:

執行緒執行開銷小,但是不利於資源的管理和保護。執行緒適合在SMP機器(雙CPU系統)上執行。

程序執行開銷大,但是能夠很好的進行資源管理和保護,可以跨機器遷移。

何時使用多程序,何時使用多執行緒?

對資源的管理和保護要求高,不限制開銷和效率時,使用多程序。

要求效率高,頻繁切換時,資源的保護管理要求不是很高時,使用多執行緒。

19。 執行緒是否具有相同的堆疊?

答:真正的程式執行都是執行緒來完成的,程式啟動的時候作業系統就幫你建立了一個主執行緒。

每個執行緒有自己的堆疊。

20。TCP與UDP有啥區別?

答:TCP和UDP是OSI模型中的運輸層中的協議。TCP提供可靠的通訊傳輸,而UDP則常被用於廣播和細節控制交給應用的通訊傳輸,兩者主要的不同體現在一下幾個方面:

1、TCP面向連線(如打電話要先撥號建立連線);UDP是無連線的,即傳送資料之前不需要建立連線

2、TCP提供可靠的服務。它透過校驗和,丟包時的重傳控制,序號標識,滑動視窗、確認應答,次序亂掉的分包進行順序控制實現可靠傳輸。即透過TCP連線傳送的資料,無差錯,不丟失,不重複,且按序到達; UDP盡最大努力交付,即不保證可靠交付。

3、UDP具有較好的實時性,工作效率比TCP高,適用於對高速傳輸和實時性有較高要求的通訊或廣播通訊場景。

4、每一條TCP連線只能是點到點的; UDP支援一對一,一對多,多對一和多對多的互動通訊方式。

5、TCP對系統資源要求較多,UDP對系統資源要求較少。

UDP有時比TCP更有優勢:

UDP以其簡單、傳輸快的優勢,在越來越多場景下取代了TCP, 如實時遊戲。

(1)網速的提升給UDP的穩定性提供可靠網路保障,丟包率很低,如果使用應用層重傳,能夠確保傳輸的可靠性。

(2)TCP為了實現網路通訊的可靠性,使用了複雜的擁塞控制演算法,建立了繁瑣的握手過程,由於TCP在內建的系統協議棧中,極難對其進行改進。

採用TCP,一旦發生丟包,TCP會將後續的包快取起來,等前面的包重傳並接收到後再繼續傳送,延時會越來越大。

基於UDP對實時性要求較為嚴格的情況下,採用自定義重傳機制,能夠把丟包產生的延遲降到最低,儘量減少網路問題造成的影響。