?? c語言常見筆試題.txt
字號:
三次握手,確定是哪個應用程序使用該協議
3.1號信令和7號信令有什么區別,我國某前廣泛使用的是那一種?
4.列舉5種以上的電話新業務?
微軟亞洲技術中心的面試題!!!
1.進程和線程的差別。
線程是指進程內的一個執行單元,也是進程內的可調度實體.
與進程的區別:
(1)調度:線程作為調度和分配的基本單位,進程作為擁有資源的基本單位
(2)并發性:不僅進程之間可以并發執行,同一個進程的多個線程之間也可并發執行
(3)擁有資源:進程是擁有資源的一個獨立單位,線程不擁有系統資源,但可以訪問隸屬于進程的資源.
(4)系統開銷:在創建或撤消進程時,由于系統都要為之分配和回收資源,導致系統的開銷明顯大于創建或撤消線程時的開銷。
2.測試方法
人工測試:個人復查、抽查和會審
機器測試:黑盒測試和白盒測試
2.Heap與stack的差別。
Heap是堆,stack是棧。
Stack的空間由操作系統自動分配/釋放,Heap上的空間手動分配/釋放。
Stack空間有限,Heap是很大的自由存儲區
C中的malloc函數分配的內存空間即在堆上,C++中對應的是new操作符。
程序在編譯期對變量和函數分配內存都在棧上進行,且程序運行過程中函數調用時參數的傳遞也在棧上進行
3.Windows下的內存是如何管理的?
4.介紹.Net和.Net的安全性。
5.客戶端如何訪問.Net組件實現Web Service?
6.C/C++編譯器中虛表是如何完成的?
7.談談COM的線程模型。然后討論進程內/外組件的差別。
8.談談IA32下的分頁機制
小頁(4K)兩級分頁模式,大頁(4M)一級
9.給兩個變量,如何找出一個帶環單鏈表中是什么地方出現環的?
一個遞增一,一個遞增二,他們指向同一個接點時就是環出現的地方
10.在IA32中一共有多少種辦法從用戶態跳到內核態?
通過調用門,從ring3到ring0,中斷從ring3到ring0,進入vm86等等
11.如果只想讓程序有一個實例運行,不能運行兩個。像winamp一樣,只能開一個窗口,怎樣實現?
用內存映射或全局原子(互斥變量)、查找窗口句柄..
FindWindow,互斥,寫標志到文件或注冊表,共享內存。.
12.如何截取鍵盤的響應,讓所有的‘a’變成‘b’?
鍵盤鉤子SetWindowsHookEx
13.Apartment在COM中有什么用?為什么要引入?
14.存儲過程是什么?有什么用?有什么優點?
我的理解就是一堆sql的集合,可以建立非常復雜的查詢,編譯運行,所以運行一次后,以后再運行速度比單獨執行SQL快很多
15.Template有什么特點?什么時候用?
16.談談Windows DNA結構的特點和優點。
網絡編程中設計并發服務器,使用多進程 與 多線程 ,請問有什么區別?
1,進程:子進程是父進程的復制品。子進程獲得父進程數據空間、堆和棧的復制品。
2,線程:相對與進程而言,線程是一個更加接近與執行體的概念,它可以與同進程的其他線程共享數據,但擁有自己的棧空間,擁有獨立的執行序列。
兩者都可以提高程序的并發度,提高程序運行效率和響應時間。
線程和進程在使用上各有優缺點:線程執行開銷小,但不利于資源管理和保護;而進程正相反。同時,線程適合于在SMP機器上運行,而進程則可以跨機器遷移。
思科
1. 用宏定義寫出swap(x,y)
#define swap(x, y)\
x = x + y;\
y = x - y;\
x = x - y;
2.數組a[N],存放了1至N-1個數,其中某個數重復一次。寫一個函數,找出被重復的數字.時間復雜度必須為o(N)函數原型:
int do_dup(int a[],int N)
3 一語句實現x是否為2的若干次冪的判斷
int i = 512;
cout << boolalpha << ((i & (i - 1)) ? false : true) << endl;
4.unsigned int intvert(unsigned int x,int p,int n)實現對x的進行轉換,p為起始轉化位,n為需要轉換的長度,假設起始點在右邊.如x=0b0001 0001,p=4,n=3轉換后x=0b0110 0001
unsigned int intvert(unsigned int x,int p,int n){
unsigned int _t = 0;
unsigned int _a = 1;
for(int i = 0; i < n; ++i){
_t |= _a;
_a = _a << 1;
}
_t = _t << p;
x ^= _t;
return x;
}
慧通:
什么是預編譯
何時需要預編譯:
1、總是使用不經常改動的大型代碼體。
2、程序由多個模塊組成,所有模塊都使用一組標準的包含文件和相同的編譯選項。在這種情況下,可以將所有包含文件預編譯為一個預編譯頭。
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是指針,它們指向相同的常量區域。
12. 以下代碼中的兩個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。
一個32位的機器,該機器的指針是多少位
指針是多少位只要看地址總線的位數就行了。80386以后的機子都是32的數據總線。所以指針的位數就是4個字節了。
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].
1.請問以下代碼有什么問題:
int main()
{
char a;
char *str=&a;
strcpy(str,"hello");
printf(str);
return 0;
}
沒有為str分配內存空間,將會發生異常
問題出在將一個字符串復制進一個字符變量指針所指地址。雖然可以正確輸出結果,但因為越界進行內在讀寫而導致程序崩潰。
char* s="AAA";
printf("%s",s);
s[0]='B';
printf("%s",s);
有什么錯?
"AAA"是字符串常量。s是指針,指向這個字符串常量,所以聲明s的時候就有問題。
cosnt char* s="AAA";
然后又因為是常量,所以對是s[0]的賦值操作是不合法的。
1、寫一個“標準”宏,這個宏輸入兩個參數并返回較小的一個。
.#define Min(X, Y) ((X)>(Y)?(Y):(X))//結尾沒有;
2、嵌入式系統中經常要用到無限循環,你怎么用C編寫死循環。
while(1){}或者for(;;)
3、關鍵字static的作用是什么?
定義靜態變量
4、關鍵字const有什么含意?
表示常量不可以修改的變量。
5、關鍵字volatile有什么含意?并舉出三個不同的例子?
提示編譯器對象的值可能在編譯器未監測到的情況下改變。
int (*s[10])(int) 表示的是什么啊
int (*s[10])(int) 函數指針數組,每個指針指向一個int func(int param)的函數。
1.有以下表達式:
int a=248; b=4;int const c=21;const int *d=&a;
int *const e=&b;int const *f const =&a;
請問下列表達式哪些會被編譯器禁止?為什么?
*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;
*c 這是個什么東東,禁止
*d 說了是const, 禁止
e = &a 說了是const 禁止
const *f const =&a; 禁止
2.交換兩個變量的值,不使用第三個變量。即a=3,b=5,交換之后a=5,b=3;
有兩種解法, 一種用算術算法, 一種用^(異或)
a = a + b;
b = a - b;
a = a - b;
or
a = a^b;// 只能對int,char..
b = a^b;
a = a^b;
or
a ^= b ^= a;
3.c和c++中的struct有什么不同?
c和c++中struct的主要區別是c中的struct不可以含有成員函數,而c++中的struct可以。c++中struct和class的主要區別在于默認的存取權限不同,struct默認為public,而class默認為private
4.#include
#include
void getmemory(char *p)
{
p=(char *) malloc(100);
strcpy(p,"hello world");
}
int main( )
{
char *str=NULL;
getmemory(str);
printf("%s/n",str);
free(str);
return 0;
}
程序崩潰,getmemory中的malloc 不能返回動態內存, free()對str操作很危險
5.char szstr[10];
strcpy(szstr,"0123456789");
產生什么結果?為什么?
長度不一樣,會造成非法的OS
6.列舉幾種進程的同步機制,并比較其優缺點。
原子操作
信號量機制
自旋鎖
管程,會合,分布式系統
7.進程之間通信的途徑
共享存儲系統
消息傳遞系統
管道:以文件系統為基礎
11.進程死鎖的原因
資源競爭及進程推進順序非法
12.死鎖的4個必要條件
互斥、請求保持、不可剝奪、環路
13.死鎖的處理
鴕鳥策略、預防策略、避免策略、檢測與解除死鎖
15. 操作系統中進程調度策略有哪幾種?
FCFS(先來先服務),優先級,時間片輪轉,多級反饋
8.類的靜態成員和非靜態成員有何區別?
類的靜態成員每個類只有一個,非靜態成員每個對象一個
9.純虛函數如何定義?使用時應注意什么?
virtual void f()=0;
是接口,子類必須要實現
10.數組和鏈表的區別
數組:數據順序存儲,固定大小
連表:數據可以隨機存儲,大小可動態改變
12.ISO的七層模型是什么?tcp/udp是屬于哪一層?tcp/udp有何優缺點?
應用層
表示層
會話層
運輸層
網絡層
物理鏈路層
物理層
tcp /udp屬于運輸層
TCP 服務提供了數據流傳輸、可靠性、有效流控制、全雙工操作和多路復用技術等。
與 TCP 不同, UDP 并不提供對 IP 協議的可靠機制、流控制以及錯誤恢復功能等。由于 UDP 比較簡單, UDP 頭包含很少的字節,比 TCP 負載消耗少。
tcp: 提供穩定的傳輸服務,有流量控制,缺點是包頭大,冗余性不好
udp: 不提供穩定的服務,包頭小,開銷小
1:(void *)ptr 和 (*(void**))ptr的結果是否相同?其中ptr為同一個指針
.(void *)ptr 和 (*(void**))ptr值是相同的
2:int main()
{
int x=3;
printf("%d",x);
return 1;
}
問函數既然不會被其它函數調用,為什么要返回1?
mian中,c標準認為0表示成功,非0表示錯誤。具體的值是某中具體出錯信息
1,要對絕對地址0x100000賦值,我們可以用
(unsigned int*)0x100000 = 1234;
那么要是想讓程序跳轉到絕對地址是0x100000去執行,應該怎么做?
*((void (*)( ))0x100000 ) ( );
首先要將0x100000強制轉換成函數指針,即:
(void (*)())0x100000
然后再調用它:
*((void (*)())0x100000)();
用typedef可以看得更直觀些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0x100000)();
2,已知一個數組table,用一個宏定義,求出數據的元素個數
#define NTBL
#define NTBL (sizeof(table)/sizeof(table[0]))
面試題: 線程與進程的區別和聯系? 線程是否具有相同的堆棧? dll是否有獨立的堆棧?
進程是死的,只是一些資源的集合,真正的程序執行都是線程來完成的,程序啟動的時候操作系統就幫你創建了一個主線程。
每個線程有自己的堆棧。
DLL 中有沒有獨立的堆棧,這個問題不好回答,或者說這個問題本身是否有問題。因為DLL中的代碼是被某些線程所執行,只有線程擁有堆棧,如果DLL中的代碼是 EXE中的線程所調用,那么這個時候是不是說這個DLL沒有自己獨立的堆棧?如果DLL中的代碼是由DLL自己創建的線程所執行,那么是不是說DLL有獨立的堆棧?
以上講的是堆棧,如果對于堆來說,每個DLL有自己的堆,所以如果是從DLL中動態分配的內存,最好是從DLL中刪除,如果你從DLL中分配內存,然后在EXE中,或者另外一個DLL中刪除,很有可能導致程序崩潰
unsigned short A = 10;
printf("~A = %u\n", ~A);
char c=128;
printf("c=%d\n",c);
輸出多少?并分析過程
第一題,~A =0xfffffff5,int值 為-11,但輸出的是uint。所以輸出4294967285
第二題,c=0x10,輸出的是int,最高位為1,是負數,所以它的值就是0x00的補碼就是128,所以輸出-128。
這兩道題都是在考察二進制向int或uint轉換時的最高位處理。
分析下面的程序:
void GetMemory(char **p,int num)
{
*p=(char *)malloc(num);
}
int main()
{
char *str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
free(str);
if(str!=NULL)
{
strcpy(str,"world");
}
printf("\n str is %s",str);
getchar();
}
問輸出結果是什么?希望大家能說說原因,先謝謝了
輸出str is world。
free 只是釋放的str指向的內存空間,它本身的值還是存在的.
所以free之后,有一個好的習慣就是將str=NULL.
此時str指向空間的內存已被回收,如果輸出語句之前還存在分配空間的操作的話,這段存儲空間是可能被重新分配給其他變量的,
盡管這段程序確實是存在大大的問題(上面各位已經說得很清楚了),但是通常會打印出world來。
這是因為,進程中的內存管理一般不是由操作系統完成的,而是由庫函數自己完成的。
當你malloc一塊內存的時候,管理庫向操作系統申請一塊空間(可能會比你申請的大一些),然后在這塊空間中記錄一些管理信息(一般是在你申請的內存前面一點),并將可用內存的地址返回。但是釋放內存的時候,管理庫通常都不會將內存還給操作系統,因此你是可以繼續訪問這塊地址的,只不過。。。。。。。。樓上都說過了,最好別這么干。
char a[10],strlen(a)為什么等于15?運行的結果
#include "stdio.h"
#include "string.h"
void main()
{
char aa[10];
printf("%d",strlen(aa));
}
sizeof()和初不初始化,沒有關系;
strlen()和初始化有關。
char (*str)[20];/*str是一個數組指針,即指向數組的指針.*/
char *str[20];/*str是一個指針數組,其元素為指針型數據.*/
long a=0x801010;
a+5=?
0x801010用二進制表示為:“1000 0000 0001 0000 0001 0000”,十進制的值為8392720,再加上5就是8392725羅
1)給定結構struct A
{
char t:4;
char k:4;
unsigned short i:8;
unsigned long m;
};問sizeof(A) = ?
給定結構struct A
{
char t:4; 4位
char k:4; 4位
unsigned short i:8; 8位
unsigned long m; // 偏移2字節保證4字節對齊
}; // 共8字節
2)下面的函數實現在一個數上加一個數,有什么錯誤?請改正。
int add_n ( int n )
{
static int i = 100;
i += n;
return i;
}
當你第二次調用時得不到正確的結果,難道你寫個函數就是為了調用一次?問題就出在 static上?
// 幫忙分析一下
#include
#include
#include
#include
#include
#include
typedef struct AA
{
int b1:5;
int b2:2;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -