嵌入式工程師對于工作來說最重要的就是面試+筆試了,作為一個面試過很多家的老鳥來說,總結了一些嵌入式工程師經典筆試題,而且也是很廠家的,快看看你都掌握了沒
1.給兩個變量,如何找出一個帶環單鏈表中是什么地方出現環的?
一個遞增一,一個遞增二,他們指向同一個接點時就是環出現的地方
1)。.堆棧溢出一般是由什么原因導致的?
沒有回收垃圾資源
3).不能做switch()的參數類型是:
switch的參數不能為實型。
4)、隊列和棧有什么區別?
隊列先進先出,棧后進先出
2.什么是引用,引用與指針有什么區別?
1) 引用必須被初始化,指針不必。
2) 引用初始化以后不能被改變,指針可以改變所指的對象。
3) 不存在指向空值的引用,但是存在指向空值的指針。
3.A.c 和B.c兩個c文件中使用了兩個相同名字的static變量,編譯的時候會不會有問題?這兩個static變量會保存到哪里(棧還是堆或者其他的)?
static的全局變量,表明這個變量僅在本模塊中有意義,不會影響其他模塊。
他們都放在數據區,但是編譯器對他們的命名是不同的。
如果要使變量在其他模塊也有意義的話,需要使用extern關鍵字。
4.什么是二叉樹,平衡二叉樹?
左右子樹都是平衡二叉樹 且左右子樹的深度差值的絕對值不大于1
5.internet采用哪種網絡協議,該協議的主要層次是什么?
Tcp/IP 主要層次有應用層 傳輸層 網絡層 數據鏈路層 物理層
ISO的七層模型是什么?
應用層 表示層 會話層 傳輸層 網絡層 物理鏈路層 物理層
Tcp udp屬于運輸層
Tcp服務提供了數據流傳輸,可靠性,有效流控制,全雙工操作和多路復用技術
Udp不提供可靠性,流控制以及錯誤恢復功能 udp頭包含少,負載消耗小。
優缺點:
Tcp提供可靠的傳輸服務,有流量控制。缺點是包頭大,冗余性不好。
Udp不提供穩定的服務 但包頭小 開銷小。
Internet物理地址和ip地址轉換采用什么協議?
ARP(地址解析協議)
IP地址的編碼分為那兩部分?
網絡號 和主機號 不過要與子網掩碼與之后才能區分哪是網絡號那是主機號。
6.用戶輸入M,N值,從1至N開始順序循環數數,每數到M輸出該數值,直至全部輸出。寫出C程序。
循環鏈表,用取余操作做
7..不能做switch()的參數類型是:
switch的參數不能為實型。
進程和線程的區別是什么?
進程是程序的一次執行
線程是進程內的一個執行單元,也是進程內的可調度實體。
與進程的區別:
調度:線程是可調度和分配的基本單元,進程是擁有資源的基本單位。
并發性:不同進程和同一個進程中的多個線程都可以并發。
擁有資源:進程是擁有資源的獨立單位,而線程不擁有資源,但它可以訪問屬于進程的資源。
系統開銷:由于創建進程和撤銷進程 系統都要為之分配和回收資源,所以系統的開銷明顯大于線程創建和撤銷時的開銷
8.談談COM的線程模型。然后討論進程內/外組件的差別。
1網絡編程中設計并發服務器,使用多進程 與 多線程 ,請問有什么區別?
1) 進程:子進程是父進程的復制,它獲得父進程數據空間,堆 棧的復制品。
2) 線程:相對于進程而言,線程更接近于一個執行體的概念,它可以與同進程的其他線程同享進程資源,但同時擁有自己的棧空間,寄存器,指針(獨立的執行序列)。
3) 兩者都可以提高程序的并發度,提高程序的運行效率和響應。
4) 線程和進程各有優缺點,線程開銷少,但不利于資源管理和保護。而進程恰恰相反,開銷大,但對資源有獨立掌控權,可更好地管理。
2.列舉幾種進程的同步機制
1)原子操作
2)信號量機制
3)自旋鎖
4)管程,會合,分布式系統
3 進程間的通訊的途徑
共享存儲系統
消息傳遞系統
管道:以文件系統為基礎
9.進程死鎖的原因
資源競爭及進程推進順序非法
10.死鎖的4個必要條件
互斥、請求保持、不可剝奪、環路
11.死鎖的處理
鴕鳥策略、預防策略、避免策略、檢測與解除死鎖
12. 操作系統中進程調度策略有哪幾種?
FCFS(先來先服務),優先級,時間片輪轉,多級反饋
13.數組和鏈表的區別
數組:數據順序存儲,固定大小
連表:數據可以隨機存儲,大小可動態改變
面試題: 線程與進程的區別和聯系? 線程是否具有相同的堆棧? dll是否有獨立的堆棧?
進程是死的,只是一些資源的集合,真正的程序執行都是線程來完成的,程序啟動的時候操作系統就幫你創建了一個主線程。
14.每個線程有自己的堆棧。
DLL中有沒有獨立的堆棧,這個問題不好回答,或者說這個問題本身是否有問題。因為DLL中的代碼是被某些線程所執行,只有線程擁有堆棧,如果DLL中的代碼是EXE中的線程所調用,那么這個時候是不是說這個DLL沒有自己獨立的堆棧?如果DLL中的代碼是由DLL自己創建的線程所執行,那么是不是說DLL有獨立的堆棧?
以上講的是堆棧,如果對于堆來說,每個DLL有自己的堆,所以如果是從DLL中動態分配的內存,最好是從DLL中刪除,如果你從DLL中分配內存,然后在EXE中,或者另外一個DLL中刪除,很有可能導致程序崩潰
用宏定義寫出swap(x,y)
#define swap(x,y) (x=x+y;y=x-y;x=x-y)
char * const p;
char const * p
const char *p
上述三個有什么區別?
char * const p; //常量指針,p的值不可以修改
char const * p;//指向常量的指針,指向的常量值不可以改
const char *p; //和char const *p
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char *str5 = "abc";
const char *str6 = "abc";
char *str7 = "abc";
char *str8 = "abc";
cout << ( str1 == str2 ) << endl;
cout << ( str3 == str4 ) << endl;
cout << ( str5 == str6 ) << endl;
cout << ( str7 == str8 ) << endl;
結果是:0 0 1 1
解答:str1,str2,str3,str4是數組變量,它們有各自的內存空間;
而str5,str6,str7,str8是指針,它們指向相同的常量區域。
15. 以下代碼中的兩個sizeof用法有問題嗎?[C易]
void UpperCase( char str[] ) // 將 str 中的小寫字母轉換成大寫字母
{
for( size_t i=0; i
if( 'a'<=str[i] && str[i]<='z' )
str[i] -= ('a'-'A' );
}
char str[] = "aBcDe";
cout << "str字符長度為: " << sizeof(str)/sizeof(str[0]) << endl;
UpperCase( str );
cout << str << endl;
答:函數內的sizeof有問題。根據語法,sizeof如用于數組,只能測出靜態數組的大小,無法檢測動態分配的或外部數組大小。函數外的str是一個靜態定義的數組,因此其大小為6,函數內的str實際只是一個指向字符串的指針,沒有任何額外的與數組相關的信息,因此sizeof作用于上只將其當指針看,一個指針為4個字節,因此返回4。
16.main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
輸出:2,5
*(a+1)就是a[1],*(ptr-1)就是a[4],執行結果是2,5
&a+1不是首地址+1,系統會認為加一個a數組的偏移,是偏移了一個數組的大小(本例是5個int)
int *ptr=(int *)(&a+1);
則ptr實際是&(a[5]),也就是a+5
原因如下:
&a是數組指針,其類型為 int (*)[5];
而指針加1要根據指針類型加上一定的值,
不同類型的指針+1之后增加的大小不同
a是長度為5的int數組指針,所以要加 5*sizeof(int)
所以ptr實際是a[5]
但是prt與(&a+1)類型是不一樣的(這點很重要)
所以prt-1只會減去sizeof(int*)
a,&a的地址是一樣的,但意思不一樣,a是數組首地址,也就是a[0]的地址,&a是對象(數組)首地址,a+1是數組下一元素的地址,即a[1],&a+1是下一個對象的地址,即a[5].