嵌入式軟件實習生面試總結

     記第一次面試,面的CTVE嵌入式應用開發崗位,之前一直沒有給面試通知,上課到半突然來了一個廣州的電話一開始以爲是騷擾電話沒接,掛了之後又打過來覺得有些不對勁,匆匆忙忙跑出教室接了電話,便收到通知問我下午有沒有空面試。於是下午就開始面試了

     一開始因爲沒有經驗略顯尷尬,簡單的做了一下自我介紹,因爲第一次面試自我介紹也說得卡卡殼殼不流暢,看到牛客面試網站旁邊有上傳文件的功能,就把個人簡歷上傳了給面試官看,簡單的介紹了一下做的項目之後,面試官就開始就着我的簡歷問問題,後來問的問題基本上都是根據簡歷來問的

上面部分是我簡歷上面寫的,這些東西都用過但是都沒深入的去了解過,問些淺的還能回答出來,再問深一點就回答不上來了。面試官問的問題問深一點我也只能尷尬的說不太瞭解帶過了...

具體問的問題大概如下:

1.(1)makefile語法規則是什麼,(2)如果修改了文件,輸入make會更新文件嗎(3)makefile問怎麼進入下一個文件夾  

2.git用法 除了git外還知道什麼版本控制

3.c語言中幾個關鍵字的作用,如const和static作用   static函數是什麼.

4.sizeof和strlen的區別,sizeof是一個函數嗎

5.對進程和線程瞭解多少,線程間的通信  

6.對操作系統有沒有了解,死鎖怎麼產生  

7.自己做過覺得最滿意的項目,用了哪些知識

8.寫一道十進制的整數轉進制的題  

9.對公司的瞭解

回去總結了一下這些問題的回答:

 

1.Makefile目標加上依賴,第一條目標爲總的目標依賴可以是文件(目錄)或爲其他目標命令或動作可以是Linux命令那一行必須以TAB鍵開頭僞目標沒有依賴文件的目標,只會執行命令。make會在當前目錄下找名字叫”Makefile”或”makefile”的文件。如果找到,它會找文件中的第一個目標文件(target)並把這個文件作爲最終的目標文件。根據時間戳生成目標文件。遞歸去尋找目標文件依賴文件,並且遞歸生成(同樣有時間戳問題)。(2)makefile會存在時間戳的問題,只要目標文件比依賴文件(源文件)新,那麼就不會重新編譯。(3)makefile嵌套:-C dir 讀入指定目錄下面的makefile,-f file 讀入當前目錄下的file文件爲makefile

 

2.git colone, git add然後git commit -m提交信息提交新的代碼給git管理 恢復:git checkout.從本地硬盤掩藏的.git文件夾中檢出代碼,git log查看每次提交的版本號,git reset --hard (版本號)就可以實現版本回退;除此之外還有svn(之後他還問知道怎麼用嗎....我覺得現在很少用SVN了吧,這裏也不去做了解了)

 

3.static作用於變量時,變量地址存儲在數據段中,初始化過的靜態變量位於.data區未初始化的靜態變量位於.bss區,編譯時就爲變量分配內存,直到程序退出才釋放存儲單元。這樣,使得該局部變量有記憶功能,可以記憶上次的數據,不過由於仍是局部變量,因而只能在代碼塊內部使用。用static聲明全局變量時,編譯時分配內存,程序結束時釋放內存單元。同時其作用域很廣,整個文件都有效甚至別的文件也能引用它。static作用於函數時,使得函數只在本文件內部有效,對其他文件是不可見的。這樣的函數又叫作靜態函數。使用靜態函數的好處是,不用擔心與其他文件的同名函數產生干擾。const作用: 只讀,修飾變量時,定義的變量只能讀取不能更改,且只能在定義時初始化。定義指針時:

const int * p;    //指向整形常量 的指針,它指向的值不能修改

int * const p;    //指向整形的常量指針 ,它不能在指向別的變量,但指向(變量)的值可以修改。

const int *const p;  //指向整形常量 的常量指針 。它既不能再指向別的常量,指向的值也不能修改。

 

4.sizeof()是運算符,其值在編譯時即計算好了,因此sizeof不能用來返回動態分配的內存空間的大小,strlen()是函數,作用是返回字符串的長度,碰到/0就會返回。


5.(1)多進程,子進程從父進程中繼承了進程的資格(真實(real)/有效(effective)/已保存(saved)用戶號(UIDs)和組號(GIDs))、環境(environment)變量堆棧內存打開文件的描述符,採用copy-on-write寫時複製,即再數據更改之後,再進行拷貝。具體實現:當子進程創建的時候,子進程的正文段,數據段,堆,棧都只有虛擬地址指向父進程的物理地址。即開始並不爲子進程分配物理空間。當數據改變之後,子進程會先開闢自己的物理空間,將父進程的數據拷貝一份到自己的物理空間。注意:當改變數據之後其值會改變,但是其虛擬地址沒改變。父子進程的虛擬地址都一樣。

(2)多線程所有的線程都是在同一進程空間運行,這也意味着多條線程將共享該進程中的全部系統資源,如虛擬地址空間,文件描述符和信號處理等等。但同一進程中的多個線程有各自的調用棧(call stack),自己的寄存器環境(register context),自己的線程本地存儲(thread-local storage)。但是線程會存在對臨界區資源的訪問問題,這就需要互斥鎖。

(3)線程間通信:1.信號用 pthread_kill 對線程發信號或設置信號singal

2.互斥鎖

int pthread_mutex_lock(pthread_mutex_t* mutex); //上鎖

int pthread_mutex_trylock(pthread_mutex_t* mutex); //只有在互斥被鎖住的情況下才阻塞

int pthread_mutex_unlock (pthread_mutex_t* mutex); //解鎖

int pthread_mutex_destroy (pthread_mutex_t* mutex); //清除互斥鎖

3.條件變量、4.信號量

 

 

6.操作系統五大功能:1、處理機管理:主要控制和管理CPU的工作。2、存儲管理:主要進行內存的分配和管理3、設備管理:主要管理基本的輸入輸出設備4、文件管理:負責對計算機文件的組織、存儲、操作和保護等。5、進程管理:也稱爲作業管理,是指對計算機所進行的操作進行管理,三態:就緒態(只差時間片的到來)、等待態(除了時間片外還需要等待別的事件滿足)、運行態,五態:創建態、就緒態、等待態、運行態和終止態。

死鎖產生的4個必要條件:

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

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

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

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

當以上四個條件均滿足,必然會造成死鎖,發生死鎖的進程無法進行下去,它們所持有的資源也無法釋放。這樣會導致CPU的吞吐量下降。所以死鎖情況是會浪費系統資源和影響計算機的使用性能的。那麼,解決死鎖問題就是相當有必要的了產生死鎖需要四個條件,那麼,只要這四個條件中至少有一個條件得不到滿足,就不可能發生死鎖了。由於互斥條件是非共享資源所必須的,不僅不能改變,還應加以保證,所以,主要是破壞產生死鎖的其他三個條件。

a、破壞“佔有且等待”條件

方法1:所有的進程在開始運行之前,必須一次性地申請其在整個運行過程中所需要的全部資源。

優點:簡單易實施且安全。

缺點:因爲某項資源不滿足,進程無法啓動,而其他已經滿足了的資源也不會得到利用,嚴重降低了資源的利用率,造成資源浪費。使進程經常發生飢餓現象。

方法2:該方法是對第一種方法的改進,允許進程只獲得運行初期需要的資源,便開始運行,在運行過程中逐步釋放掉分配到的已經使用完畢的資源,然後再去請求新的資源。這樣的話,資源的利用率會得到提高,也會減少進程的飢餓問題。

b、破壞“不可搶佔”條件

當一個已經持有了一些資源的進程在提出新的資源請求沒有得到滿足時,它必須釋放已經保持的所有資源,待以後需要使用的時候再重新申請。這就意味着進程已佔有的資源會被短暫地釋放或者說是被搶佔了。該種方法實現起來比較複雜,且代價也比較大。釋放已經保持的資源很有可能會導致進程之前的工作實效等,反覆的申請和釋放資源會導致進程的執行被無限的推遲,這不僅會延長進程的週轉週期,還會影響系統的吞吐量。

c、破壞“循環等待”條件

可以通過定義資源類型的線性順序來預防,可將每個資源編號,當一個進程佔有編號爲i的資源時,那麼它下一次申請資源只能申請編號大於i的資源。

 

8.這裏貼上一個大哥的博客裏面有怎麼實現轉進制的問題:

https://blog.csdn.net/Dian0dian0/article/details/89330972

視頻面對面敲給別人看還是有點緊張了,之前其實見過這題但是沒好好看,就現場發揮了一下,因爲也不能出去用別的編輯器,就只是在網上敲而已,大概寫了一下思路,寫的時候比較緊張一開始忘記倒序輸出,面試官提醒了一下應該倒序輸出,然後定義了個128大小的int型數組,倒序輸出,或許是空間複雜度的問題,最後寫完了他問你這裏定義了一個128大小的數組來處理嗎,他笑了一下就覺得自己做錯了QAQ. ,筆試題做完最後問了一下對公司的瞭解面試就結束了......

寫的時候思路大概還是對的,面試完之後,就複製下來改了幾個邏輯判斷,比如寫的時候寫了>10的情況下來改成>=10,下面還是貼上我的代碼

/*********************************************************************************

 *      Copyright:  (C) 2019 WuYujun<[email protected]>

 *                  All rights reserved.

 *

 *       Filename:  cover.c

 *    Description:  This file

 *                 

 *        Version:  1.0.0(25/04/19)

 *         Author:  WuYujun <[email protected]>

 *      ChangeLog:  1, Release initial version on "25/04/19 16:41:06"

 *                 

 ********************************************************************************/

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int cover(int M,int N) ;

int main(int argc, char **argv) {



    int M ,N ;

    if(argc != 3)

    {

        printf("Usage:%s [M] [N]\n",argv[0]) ;

        return 0 ;

    }

    M = atoi(argv[1]) ;

    N = atoi(argv[2]) ;

    printf("M=%d,N=%d\n",M,N) ;

    cover(M,N) ;

}



int cover(int M,int N)

{

    int i = 0,j ;

    int num ;

    int a[M] ;

    if(N<2||N>16)

    {

        return 0 ;

    }

    if(N<10)

    {

        while(M!= 0)

        {

            num=M%N ;

            M=M/N ;

            a[i] = num ;

            i++ ;

        }

        for(j=0;j<i;j++)

        {

            printf("%d",a[i-j-1]) ;

        }

    }

    if(N>=10)

    {

        while(M!=0)

        {

            num = M%N ;

            M=M/N ;

            a[i] = num ;

            i++ ;

        }

        for(j=0;j<i;j++)

        {

            if(a[i-j-1]<10)

            {

                printf("%d",a[i-j-1]);

            }

            if(a[i-j-1]>=10)

            {

                printf("%c",a[i-j-1]-10+'A') ;

            }

        }

    }

    printf("\n") ;

}

 

上面是我整理的答案,可能還是不夠好或不夠完整,而且面試的時候主要是看自己的理解的程度和隨機應變的能力,恩...面試官挺和藹的,沒開始前挺緊張面試交談中慢慢就好了一些,自己答不上來的時候也還是挺尷尬的哈哈哈,總的來說還是自己太菜了,很多時候覺得自己理解但是真正讓自己說出來的時候卻說不出來,理解得不夠透徹是一個原因,個人的表達能力我覺得也存在一些問題.....之後會好好加強自己這方面的鍛鍊,會做不算真本事,能理解透徹並能說給別人聽教會別人纔是真的大佬!經過這次教訓積攢經驗並提升自己~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章