【C 語言】1、 C 和 C++有什么不同?
1)C語言面向過程編程,重程序的實現(xiàn);C++面向?qū)ο缶幊蹋爻绦虻脑O(shè)計;
2)C是C++的一個子集;C++全面兼容C;
3)C++相對于C引入了重載、內(nèi)聯(lián)函數(shù)、異常處理、類的封裝/繼承/多態(tài)、以及STL/容器類等…
2、進程和線程的異同、關(guān)系?
1)進程:是系統(tǒng)資源分配和調(diào)度的基本單位,有自己的pid;
線程:是運行的基本單位,有自己的tid。
2)進程:一個進程至少擁有1個線程,為主線程;
線程:同一個進程中的線程可以并發(fā),且共享進程的資源,擁有自己獨立的棧空間和執(zhí)行序列。
3)進程有獨立的地址空間,多進程程序要比多線程程序健壯,但進程切換時,需要復(fù)制PCB,資源開銷大,效率稍低;
線程沒有獨立地址空間,必須依賴具體的進程才能執(zhí)行,線程的切換不需要復(fù)制PCB資源開銷小,效率比進程高;
4)進程能實現(xiàn)跨機器遷移;
線程適合于SMP(對稱多處理器)機器上運行。
3、進程間通信都有哪幾種機制?其中最快的機制為哪種?
1)管道(pipe):
管道用于具有親緣關(guān)系的進程間通信,其中有名管道可實現(xiàn)無親緣關(guān)系的進程間通信;
2)信號(signal):
軟中斷機制,進程收到信號相當(dāng)于處理器收到中斷請求,用于通知進程對應(yīng)的事件處理;
IPC通信>>
3)消息隊列(message queue)
克服了管道和信號中量有限的缺點,利用內(nèi)存中公共消息緩沖區(qū)實現(xiàn)進程間通信;
4)共享內(nèi)存(shared memory)——【最快的IPC通信形式】因為進程可以直接讀寫內(nèi)存,不需要數(shù)據(jù)的拷貝。
內(nèi)核維護一塊由多個進程均可訪問的內(nèi)存,實現(xiàn)進程通信,需要互斥鎖或信號量集配合實現(xiàn)同步;
5)信號量集(semaphore)
多進程之間或同一進程內(nèi)的多線程之間實現(xiàn)同步和互斥的手段;
socket網(wǎng)絡(luò)通信>>
6)套接字(socket):
實現(xiàn)網(wǎng)絡(luò)中不同機器之間的進程間通信,應(yīng)用廣泛。
4、請簡述 socket 編程中 client 和 server 的大致步驟?
以基于TCP的編程模型為例。
server:
1) 創(chuàng)建通訊端(套接字) - socket
2) 初始化服務(wù)器的地址空間 - sockaddr_in成員
3) 將套接字和服務(wù)器地址空間綁定 - bind
4) 監(jiān)聽通訊端- listen
5) 等待客戶端連接的到來,到來返回連接描述符 - accept
6) 通過連接描述符進行讀取客戶端數(shù)據(jù) - read //data
7) 通過連接描述符給客戶端響應(yīng) - write
8) 關(guān)閉連接描述符 – close
client:
1) 創(chuàng)建通訊端(套接字) - socket
2) 初始化服務(wù)器的地址空間(ip轉(zhuǎn)換) - sockaddr_in成員/inet_pton
3) 連接服務(wù)器,成功返回即連接成功 - connect
4) 向服務(wù)器發(fā)送請求信息 - write
5) 從服務(wù)器獲取響應(yīng)信息 - read
6) 對響應(yīng)信息做相關(guān)的數(shù)據(jù)處理 - //data
7) 關(guān)閉通訊端(套接字) – close
5、進程之間通信的途徑?進程死鎖的原因?死鎖的 4 個必要條件?
進程通信途徑:管道、信號、消息隊列、共享內(nèi)存、信號量集、套接字。
死鎖:多個進程循環(huán)等待它方占有的資源而無限期地僵持下去的一種程序運行情況。
進程死鎖原因:
1)系統(tǒng)提供資源有限;
2)系統(tǒng)資源分配不當(dāng);
3)多進程中進程運行推進順序不合理;
解除死鎖條件:
1)互斥條件:1個資源每次只能被1個進程使用。
2)請求與保持條件:1個進程因請求資源阻塞時,對已獲得的資源保持不放。
3)不搶占條件:進程已獲得的資源在未使用完之前,不能強行搶占。
4)循環(huán)等待條件:多進程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
6、死鎖的處理?操作系統(tǒng)中進程調(diào)度策略有哪幾種?
死鎖的處理方法:
1)最簡單最常用的是:系統(tǒng)重新啟動。但代價大,進程已完成的運算都付之東流。
2)撤銷進程,剝奪資源。一次性終止參與死鎖的進程,或者逆序逐步撤銷參與死鎖的進程,需考慮優(yōu)先級及代價。
進程調(diào)度的策略:
1)先來先服務(wù)(FCFS)
2)優(yōu)先級
3)時間片輪轉(zhuǎn)
4)分級調(diào)度
5)多級反饋輪轉(zhuǎn)
【區(qū)別于】常用的作業(yè)調(diào)度算法有:先來先服務(wù)算法(FCFS)、最短作業(yè)優(yōu)先算法(SJF)、最高響應(yīng)比優(yōu)先算法(HRRN)、優(yōu)先級調(diào)度算法、均衡調(diào)度算法等。
7、 TCP 和 UDP 的區(qū)別?簡述 3 次握手協(xié)議?
TCP和UDP的區(qū)別:
1)TCP面向連接;UDP面向無連接;
2)TCP傳輸無差錯不丟失,安全可靠,效率不如UDP;UDP傳輸容易丟包,安全性較差,傳輸效率高于TCP;
3)TCP連接點對點;UDP支持多對多交互通信;
4)TCP首部開銷20字節(jié);UDP首部開銷8字節(jié);
5)TCP是全雙工可靠信道;UDP是不可靠信道。
8、什么是字節(jié)對齊,為什么要對齊?怎么樣實現(xiàn)字節(jié)對齊?
字節(jié)對齊概念:
各種類型數(shù)據(jù)按照一定的規(guī)則在空間上排列,而不是順序的一個接一個的排放。
字節(jié)對齊原因:
1)減少CPU訪存次數(shù),提高CPU的訪問效率;
2)提高對于不同硬件平臺下代碼的可移植性;
3)合理利用可以有效節(jié)省存儲空間。
字節(jié)對齊方法:
C編譯器默認(rèn)為每個變量或數(shù)據(jù)單元按其自然對界條件分配空間。也可以通過以下2中方式改變對齊方式:
1)#PRagma pack
· 使用偽指令#pragma pack (n),C編譯器將按照n個字節(jié)對齊。
· 使用偽指令#pragma pack ( ),取消自定義字節(jié)對齊方式。
2)__attribute( )
· __attribute((aligned (n))),讓所作用的結(jié)構(gòu)成員對齊在n字節(jié)自然邊界上。如果結(jié)構(gòu)中有成員的長度大于n,則按照最大成員的長度來對齊。
· __attribute__ ((packed)),取消結(jié)構(gòu)在編譯過程中的優(yōu)化對齊,按照實際占用字節(jié)數(shù)進行對齊。
9、多線程編程中要注意什么問題 ?
1)明確使用線程的目的。是對不同的資源(例如SOCKET連接)進行管理,考慮多個線程;
2)控制線程的調(diào)度和阻塞。如利用事件的觸發(fā)來控制線程的調(diào)度和阻塞,也有用消息來控制的;
3)不能出現(xiàn)死鎖問題。線程中如果用到公共資源,要考慮公共資源的線程安全。一般用互斥鎖機制來控制。
4)合理使用sleep。何時Sleep,Sleep的大小要根據(jù)具體項目,做出合理安排。一般原則非阻塞狀態(tài)下每個循環(huán)都要有SLeep,這樣保證減少線程對CPU的搶奪。
5)線程的終止。一般要使線程體在完成一件工作的情況下終止,一般不要直接使用拋出線程異常的方式終止線程。
6)線程的優(yōu)先級。一定根據(jù)程序的需要要有整體的規(guī)劃。
10、什么是預(yù)編譯,何時需要預(yù)編譯?
預(yù)編譯又稱為預(yù)處理,是做些代碼文本的替換工作。
處理以# 開頭的指令,比如拷貝#include包含的文件代碼,#define宏定義的替換,條件編譯等,就是為編譯做的預(yù)備工作的階段。
何時需要預(yù)編譯:
總是使用不經(jīng)常改動的大型代碼體。
11、 typedef 和 #define 有什么區(qū)別?
1)作用不同:
typedef:給已有的類型起一個類型別名。
#define:宏定義,給使用到定義的標(biāo)識符進行替換。
2)執(zhí)行時間不同:
typedef在編譯階段,具有類型檢查動能;#define在預(yù)處理階段,不做類型檢查。
3)作用域不同:
typedef有自己的作用域;#define沒有作用域限制。
4)修飾指針有差異:
typedef定義指針可以同時定義多個指針;#define宏定義的指針只能對第一個變量定義為指針。
13、談?wù)剝?nèi)存分配方式?
物理內(nèi)存映射到CPU虛擬地址空間分配方式:
內(nèi)核空間1G(3G ~ 4G-1)
用戶空間3G(0 ~ 3G-1):
棧stack:臨時局部變量存放區(qū)。棧幀數(shù)據(jù)歲函數(shù)結(jié)束而消失。——后進先出
堆heap:動態(tài)內(nèi)存區(qū)。程序運行時malloc和new動態(tài)申請的區(qū)域。——手動申請/釋放
BSS:靜態(tài)內(nèi)存分配區(qū)。存放未初始化的全局變量。——可讀可寫
數(shù)據(jù)段data:靜態(tài)內(nèi)存分配區(qū)。存放已初始化的全局變量、靜態(tài)局部變量。——可讀可寫
代碼段text:存放程序執(zhí)行代碼、只讀常量區(qū)域。——只讀
14、Unix 中進程間通信,資源的共享,加鎖機制?
進程間通信:
管道、信號、消息隊列、共享內(nèi)存、信號量集、套接字。
共享資源:
硬件(如uart)、文件、共享內(nèi)存、線程見可見的全局變量等...
加鎖機制:
多進程或多線程在同一時刻訪問相同的共享資源時,需要加鎖。
內(nèi)核的驅(qū)動模塊在運行時訪問相同的共享資源時,需要加鎖。
15、全局變量和局部有什么區(qū)別?是怎樣實現(xiàn)的?操作系統(tǒng)和編譯器是怎樣知道的?
1)作用域不同:全局變量為整個程序;局部變量為當(dāng)前函數(shù)或者循環(huán);
2)生命周期不同:全局變量隨程序的結(jié)束而結(jié)束,局部變量隨函數(shù)或者循環(huán)的退出而釋放;
3)存儲方式不同:全局變量在數(shù)據(jù)段;局部變量在棧區(qū);
4)使用方式不同:函數(shù)內(nèi)部會優(yōu)先使用與全局變量同名的局部變量。
怎樣實現(xiàn):
全局變量在編譯時,由編譯器分配了虛擬地址在數(shù)據(jù)段。
局部變量在程序運行時,對應(yīng)使用該局部變量的函數(shù)被調(diào)用時才真正分配虛擬地址在棧區(qū)。
操作系統(tǒng)和編譯器怎么知道:
操作系統(tǒng)和編譯器從變量地址所屬的存放區(qū)域分辨局部變量和全局變量。
16、談?wù)勀銓Υ蠖四J剑《四J降睦斫?/strong>
1)大小端是數(shù)據(jù)在內(nèi)存中的存儲方式。
大端:數(shù)據(jù)的高字節(jié)存放在內(nèi)存的低地址,低字節(jié)存放在內(nèi)存的高地址。
小端:數(shù)據(jù)的高低字節(jié)與內(nèi)存的高低地址存放一致。
2)因為數(shù)據(jù)類型所占的bit位不同,在16bit、32bit、64位這樣不同的處理器上,寄存器寬度已經(jīng)大于1個字節(jié),就要考慮如何去將多個字節(jié)安排存放的問題,因此有了大小端模式。
3)目前intel的x86平臺是小端模式;
ARM平臺默認(rèn)是小端模式,可切換為大端;
在C語言中一般都默認(rèn)是小端;
在網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)統(tǒng)一是大端模式。
17、static的作用? const 作用?volatile含義?
static:
1)修飾局部變量。生命周期:當(dāng)前文件<也有限定當(dāng)前文件可用的效果>,作用域:當(dāng)前函數(shù)
2)修飾全局變量。生命周期和作用域:當(dāng)前文件 <該變量只能在本文件使用>
3)修飾函數(shù)。生命周期和作用域:當(dāng)前文件 <限制函數(shù)為本模塊可用>
const:
1)被const修飾的變量或者函數(shù)等,使其變?yōu)橹蛔x屬性,其內(nèi)容會被放在內(nèi)存的代碼段區(qū)域;
2)修飾指針的時候稍有不同,*號前代表指針指向的內(nèi)容為只讀,*號后面代表指針本身只讀,不可改變指向;
3)const合理使用可以保護不希望被修改的參數(shù),一定程度減少bug的出現(xiàn)。
volatile:
表示一個變量也許會被后臺程序意想不到的修改。
變量如果加了volatile修飾,則會從內(nèi)存重新裝載內(nèi)容,而不是直接從寄存器拷貝內(nèi)容。
volatile可以保證對特殊地址的穩(wěn)定訪問。
寄存器地址要加volatile修飾,主要是因為寄存器里面的值是隨時變化的。
主要用在3種情況:
1) 并行設(shè)備的硬件寄存器;
2) 中斷服務(wù)子程序中會訪問到的非自動變量;
3) 多線程應(yīng)用中被幾個任務(wù)共享的變量;
18、鏈表和數(shù)組有什么區(qū)別?數(shù)組與指針的區(qū)別?
數(shù)組 vs 鏈表:
數(shù)組的數(shù)據(jù)是順序存儲的,存儲大小固定。
鏈表的數(shù)據(jù)可以隨機存儲,存儲大小可以動態(tài)的改變。
數(shù)組 vs 指針:(以字符型指針變量和字符數(shù)組最能說明問題)
1)分配內(nèi)存數(shù)
數(shù)組:<數(shù)據(jù)類型所占內(nèi)存×下標(biāo)>的字節(jié)數(shù)。指針:32bit系統(tǒng),默認(rèn)分配4字節(jié)存放內(nèi)存地址。
2)初始化賦值
數(shù)組:將字符串放到數(shù)組分配的存儲空間去。指針:先將字符串放到內(nèi)存,再將該內(nèi)存首地址放到指針里。
3)賦值方式
數(shù)組:數(shù)組名不能用字符串字面值直接賦值。指針:可以直接用字符串字面值賦值。
4)輸入方式
數(shù)組:字符串可以直接輸入到字符數(shù)組中。指針:不能將字符串直接輸入指針變量,需要指針指向1塊內(nèi)存。
5)值的改變
數(shù)組:數(shù)組名代表的數(shù)組首地址不能改變。指針:指針變量的值可以改變,即指針改變指向。
19、隊列和棧的異同?
相同點:只允許在端點處插入和刪除元素的數(shù)據(jù)結(jié)構(gòu)。
不同點:棧遵循后進先出原則(LIFO),隊列遵循先進先出原則(FIFO)。
20、談?wù)勀銓Χ褩5睦斫猓?/p>
1)堆棧是兩種數(shù)據(jù)結(jié)構(gòu)。
2)堆棧都是一種數(shù)據(jù)項按序排列的數(shù)據(jù)結(jié)構(gòu),只能在一端對數(shù)據(jù)項進行插入和刪除。
3)堆:是共有的空間,全局堆和局部堆,由程序員手動分配和釋放,程序結(jié)束時由系統(tǒng)回收。
棧:是線程獨有的,保存其運行狀態(tài)和局部變量的區(qū)域,由編譯器自動分配和釋放。
21、簡述 BSS段,數(shù)據(jù)段,代碼段,堆,棧中分別存儲的是什么數(shù)據(jù)?
棧(stack):是用戶存放程序臨時創(chuàng)建的非靜態(tài)局部變量。
堆(heap):堆是用于存放進程運行中被動態(tài)分配的內(nèi)存段,它的大小并不固定,可動態(tài)擴張或縮減。
BSS段:BSS段通常是用來存放程序中未初始化的全局變量。
數(shù)據(jù)段(data):通常是用來存放程序中已初始化的全局變量。
代碼段(text):通常是用來存放程序執(zhí)行代碼、只讀常量。
22、所有的程序都要系統(tǒng)調(diào)用嗎?不系統(tǒng)調(diào)用可以實現(xiàn)程序運行嗎?
不是。如ARM裸板開發(fā)。
不系統(tǒng)調(diào)用可以實現(xiàn)系統(tǒng)運行,如ARM裸板下的shell程序,使用無限循環(huán)的方式實現(xiàn)指令輸入對應(yīng)調(diào)用獨立實現(xiàn)的函數(shù)功能。
24、創(chuàng)建子進程的函數(shù)是什么?談?wù)勀銓Ω高M程和子進程間的理解?
pid_t fork (void);
成功:在父進程里子進程的pid==0被返回;
失敗:在父進程里返回pid==-1,子進程沒有被創(chuàng)建,errno被設(shè)置。
父子進程的理解:
1)【ID】父子進程ID不同;
2)【異步】子進程創(chuàng)建后,父子進程的執(zhí)行是異步的,即調(diào)度先后順序并不確定;
3)【代碼區(qū)共享】子進程是父進程的不完全副本,代碼區(qū)與父進程共享,其他數(shù)據(jù)從父進程拷貝;
4)【孤兒進程】父進程退出,但子進程還在,子進程為孤兒進程,就被1號進程收養(yǎng)。如系統(tǒng)的一些守護進程;
5)【僵尸進城】子進程結(jié)束,父進程還沒來收尸,子進程就成僵尸進程,占用系統(tǒng)資源,直到父進程回收才釋放;
25、談?wù)勀銓ε判蛩惴ǖ恼J(rèn)識?你接觸過那些排序算法?
排序算法認(rèn)識:
即把一組數(shù)字按照某種重復(fù)執(zhí)行的代碼算法進行順序排列的解決方法。
冒泡排序,快速排序。目前已掌握冒泡排序。
【嵌入式】0、你為什么學(xué)習(xí)嵌入式?嵌入式軟件開發(fā)的基本模式?談?wù)剬η度胧?a href="http://www.survivalescaperooms.com/article.asp?typeid=60">linux 系統(tǒng)的認(rèn)識?
為什么學(xué)習(xí):
從小喜歡四驅(qū)車之類的帶電的小玩具,到如今社會的發(fā)展讓智能硬件開始進入個人消費者,才真正接觸到這些智能硬件的讓我熱血的初衷,沒有什么比“使用軟件來控制一個硬件”的感覺更讓我有成就感。
1、系統(tǒng)調(diào)用與 API的區(qū)別?2、簡單說一下對嵌入式的理解?對嵌入式軟件開發(fā)的理解?3、簡單說一下移植的流程?4、簡單說一下驅(qū)動的框架結(jié)構(gòu)?5、什么是中斷?中斷發(fā)生時 CPU做什么工作?6、簡述 UART協(xié)議?7、簡述 IIC協(xié)議?8、簡述 1-wire協(xié)議?9、談?wù)剬?GPIO的認(rèn)識?10、簡述同步通信和異步通信?11、中斷(interrupt,如鍵盤中斷)與異常(exception,如除零異常)有何區(qū)別?12、中斷和輪詢哪個效率高?怎樣決定是采用中斷方式還是采用輪詢方式去實現(xiàn)驅(qū)動?13、 U-boot的啟動過程?14、簡述 ARM-linux啟動過程?15、在 linux內(nèi)核中希望你的中斷處理程序執(zhí)行時間越短越好,但是中斷處理程序要完成的功能不變,內(nèi)核是通過什么機制解決矛盾?16、 Linux設(shè)備中字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)設(shè)備有什么主要的區(qū)別?17、請簡述主設(shè)備號和次設(shè)備號的用途?19、驅(qū)動里面為什么要有并發(fā)、互斥的控制?如何實現(xiàn)?20、 Linux內(nèi)核互斥機制都有哪些?21、裸版的中斷和 Linux系統(tǒng)下的中斷以及 UC 所講的中斷的異同?22、 CISC體系與 RISC 體系分別指什么?23、談?wù)剬χ袛嗟捻敯氩康装氩繖C制的理解?24、 談?wù)?ARM裸板程序怎么編程?25、 談?wù)?NorFlash和 Nandflash 的區(qū)別?26、 談?wù)剬?ARM處理器的理解?27、 linux內(nèi)核分離思想?【C++】1、談?wù)勀銓γ嫦驅(qū)ο蟮恼J(rèn)識 ?2、指針和引用的區(qū)別?談?wù)勀銓χ羔樅鸵玫睦斫猓砍R糜惺裁醋饔茫?、 C++中的 class和 struct 的區(qū)別?4、類成員函數(shù)的重載、覆蓋和隱藏區(qū)別?5、面向?qū)ο蟮娜齻€基本特征,并簡單敘述乊?6、談?wù)剬υO(shè)計模式的理解?7、關(guān)聯(lián)、聚合(Aggregation)以及組合(Composition)的區(qū)別?8、談?wù)勀銓截悩?gòu)造函數(shù)和賦值運算符的認(rèn)識?9、什么是淺拷貝?什么是深拷貝?10、 C++容器的分類及各自的特性?
新聞熱點
疑難解答
圖片精選