Linux C 面試題匯總(總有你不知道的知識點)


摘自:https://blog.csdn.net/chen1415886044/article/details/98891245

linux C


1.用變量a給出下面的定義.

 

a) 一個整型數
b) 一個指向整型數的指針
c) 一個指向指針的的指針,它指向的指針是指向一個整型數
d) 一個有10個整型數的數組
e) 一個有10個指針的數組,該指針是指向一個整型數的
f) 一個指向有10個整型數數組的指針
g) 一個指向函數的指針,該函數有一個整型參數並返回一個整型數
h) 一個有10個指針的數組,該指針指向一個函數,該函數有一個整型參數並返回一個整型數

答案是:
a) int a;
b) int *a;
c) int **a;
d) int a[10];
e) int *a[10];
f) int (*a)[10];
g) int (*a)(int);
h) int (*a[10])(int);

2.寫一個“標准”宏MIN,這個輸入兩個參數並返回較小的一個。
#define Min(a,b) ( ((a)>=(b))?(b):(a))

3.嵌入式經常用到死循環,你怎么樣用C來編寫死循環呢?
我的首選就是:
while(1){},一些有經驗的程序員喜歡用for( ; ; ){} ,還有一種是寫匯編語言的程序員常用的寫法:
Loop:

goto Loop;

4.引用和指針的區別?

答:1.引用必須要初始化,指針可以不用初始化;2.不存在指向空值的引用,但是存在指向空值的指針;3.引用初始化后不能改變,但存在指向空值的指針;4.引用是變量的別名,本身不單獨分配自己的內存空間,而指針有自己的內存空間;

5.關鍵字static的作用是什么?

在c語言中static有三個明顯的作用:
1)static在修飾局部變量的時候,其使得局部變量的生命周期發生改變,使得其放在data段,直到程序運行結束才結束。
2)static在修飾全局變量的時候,作用是改變其作用域,使得全局變量只能在定義的文件中使用。
3)static在修飾函數的時候,同樣也是只能時函數只能在當前的文件中使用。

6.請填寫bool , float, 指針變量 與“零值”比較的if語句。

1)if ( flag ) if ( !flag )
2)const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
3)if (p == NULL) if (p != NULL)

7.用預處理指令#define 聲明一個常數,用以表明1年中有多少秒(忽略閏年問題)

#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL

8.extern c 作用

告訴編譯器該段代碼以C語言進行編譯。

9.頭文件中的 ifndef/define/endif 干什么用?

預處理,防止頭文件被重復使用。

10.do……while和while……do有什么區別?

前一個循環一遍再判斷,后一個判斷以后再循環。

11.C語言鏈表與數組的區別?

鏈表跟數組都屬於一種數據結構。可以分為兩個點來看:
從邏輯結構來看
1)數組必須事先定義固定的長度,不能適應數據動態地增減的情況。當數據增加時,可能超出原先定義的元素個數;當數據減少時,造成內存浪費;數組可以根據下標直接存取。
2) 鏈表動態地進行存儲分配,可以適應數據動態地增減的情況,且可以方便地插入、刪除數據項。鏈表必須根據next指針找到下一個元素。
從內存存儲來看
1)(靜態)數組從棧中分配空間, 對於程序員方便快速,但是自由度小
2)鏈表從堆中分配空間, 自由度大但是申請管理比較麻煩

12.隊列和棧有什么區別?

隊列先進先出,棧后進先出。

13.const 有什么用途?

1)可以定義const常量。
2)修飾函數的返回值和形參。

14 . #include <…h> 和#include “…h” 有什么區別?

對於#include <…h> ,編譯器從標准庫路徑開始搜索.h
對於#include “…h” ,編譯器從用戶的工作路徑開始搜索.h

15.請寫出下列代碼的輸出內容

#include <stdio.h> int main() { int a,b,c,d; a=10; b=a++; c=++a; d=10*a++; printf("b,c ,d:%d,%d,%d",b,c,d ); return 0; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

10,12,120

16.關鍵字volatile有什么含意?

提示編譯對象的值可能在編譯器未檢測到的情況改變。

18.不用標准庫函數,寫一個字符串拷貝函數strcpy。

1)不考慮重疊問題:

	char* strcpy(char* dst, const char* src) { assert((dst != NULL )&&(src != NULL)); char * ret = dst; while ((*dst ++ = *src ++) != '\0'); return ret; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2)strcpy考慮重疊與不重疊問題:

	char *strcpy(char *dst, const char *src) { assert((dst != NULL) && (src != NULL)); char *ret = dst; int size = strlen(src) + 1; if (dst > src || dst < src + szie) { dst = dst + size -1; src = src + size -1; while (size -- ) { *dst ++ = *src ++; } } else { while (size --) { *dst ++ = *src ++; } } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

19.在下面語句中,fd的具體含義?

void ((*fp)(int))[10];
1).()的優先級最高所以先看(*fp),fp是個指針;
2). 假設 func=(*fp); func(void ) 是個指針函數返回值是個指針,參數是(void),所以fp是指向指針函數的函數指針;

20.有一個16位整數,每4位為一個數,寫函數求他們的和。

解析:
整數1101010110110111
和 1101+0101+1011+0111

char SumOfQuaters(unsigned short n) { char c = 0; int i = 4; do { c += n & 15; n = n >>4; }while(--i); return c; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

21.用c語言寫一個冒泡排序函數。

/* 冒泡排序: 比較相鄰的元素,如果第一個比第二個大,交換他們兩個; */ void BubbleSort(int *arr,int size) { int i,j,temp; for (i = 0; i < size - 1; i++) { for (j = 0; j <size -i -1; j++) { if (arr[j] > arr[j+1]) { temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] =temp; } } } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

22.堆棧溢出一般是由什么原因導致的?

1).內存泄露,比如某一數組原先已定義好大小,但是在后續操作中存放的個數超出這一既定長度,會導致堆棧溢出。
2).由於程序員動態申請的內存塊使用后未立即釋放,導致內存區不夠用,也會導致堆棧溢出 。

23.請用指針實現一個函數,函數的功能是交換2個整數,並要求寫出如何調用這個函數。

#include "stdio.h" void fun(int *x,int *y) { int t; t=*x; *x=*y; *y=t; } int main(int argc, char **argv) { int a,b; printf("請輸入a和b:"); scanf("%d%d",&a,&b); fun(&a,&b); printf("\n = %d ,b = %d\n",a,b); return 0; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

24.c語言程序運行的時候內存分布?

1).堆區:在動態申請內存的時候,在堆里開辟內存。
2).棧區: 主要存放局部變量(在函數內部,或復合語句內部定義的變量)。
3).靜態/全局區
3.1):未初始化的靜態全局區 (bss區):
靜態變量(定義的時候,前面加 static 修飾),或全局變量 ,沒有初始化的。
3.2):初始化的靜態全局區 全局變量、靜態變量,賦過初值的,存放在此區 。

4.代碼區:存放咱們的程序代碼
5.文字常量區 :存放常量的。

25.寫一個鏈表逆序?

struct link
{
int data;
link* next;

};

link* reverse(link *head)
{
link *p,*q,*r;
if (head ==NULL ||head ->next ==NULL)
return head;
p = head;
q = head->next;
while(q != NULL)
{
r = q ->next;
q->next = p;
p = q;
q = r;
}
head ->next =NULL;
head = p;
return head;
}

26.怎么判斷鏈表中是否有環?

/* 分析:用兩個指針來遍歷這個單向鏈表,第 一個指針p1,每次走一步;第二個指針p2,每次走兩 步;當p2 指針追上p1的時候,就表明鏈表當中有環 路了。 */ struct link { int data; link* next; }; bool Isloop(link* head) { link *p1; link *p2; p1 = head; p2 = head; if (head == NULL || head -> next == NULL) return false; do { p1 = p1 ->next; p2 = p2 ->next->next; }while(p2&&p2->next&&p1!=p2); if (p1 == p2) { return true; } else { return false; } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

27.什么是守護進程?

守護進程:是指在UNIX或其他多任務操作系統中在后台執行的電腦程序,並不會接受電腦用戶的直接操控。此類程序會被以進程的形式初始化。守護進程程序的名稱通常以字母“d”結尾:例如,syslogd就是指管理系統日志的守護進程。通常,守護進程沒有任何存在的父進程(即PPID=1),且在UNIX系統進程層級中直接位於init之下。守護進程程序通常通過如下方法使自己成為守護進程:對一個子進程調用fork,然后使其父進程立即終止,使得這個子進程能在init下運行。這種方法通常被稱為“脫殼”

28.描述一下進程與線程的區別?

1)調度:線程作為調度和分配的基本單元,進程作為擁有資源的基本單位;
2)並發性:不僅進程可以並發執行,同一進程內的線程也可以並發執行。
3)擁有資源:進程是擁有資源的基本獨立單元,線程不擁有資源,但可以訪問進程內的資源;
4)在創建或撤銷線程時,由於系統都要為之分配和回收內存資源,導致系統的開銷明顯大於創建或撤銷線程時的開銷。

29.進程之間通信有哪些?

1) 管道(pipe):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有血緣關系的進程間使用。進程的血緣關系通常指父子進程關系。
2)有名管道(named pipe):有名管道也是半雙工的通信方式,但是它允許無親緣關系進程間通信。
3)信號量(semophore):信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它通常作為一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段。
4)消息隊列(message queue):消息隊列是由消息組成的鏈表,存放在內核中 並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少,管道只能承載無格式字節流以及緩沖區大小受限等缺點。
5)信號處理機制(signal):信號是一種比較復雜的通信方式,用於通知接收進程某一事件已經發生。
6)共享內存(shared memory):共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問,共享內存是最快的IPC方式,它是針對其他進程間的通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號量配合使用,來實現進程間的同步和通信。
7)套接字(socket):套接字也是一種進程間的通信機制,與其他通信機制不同的是它可以用於不同及其間的進程通信。

30.exit()、_exit()和return()的區別?

exit():結束當前的進程,並且會刷新緩存區,關閉沒有關閉的文件等。
_exit():結束當前的進程,不對緩存區刷新。
return:
1)在main函數中會結束當前進程。
2)在子函數中,會返回調用當前函數的調用位置,進程從下個C語句開始執行。

31.fork與vfork區別?

fork和vfork都用於創建子進程。但是vfork創建子進程后,父進程阻塞,直到子進程調用exit()或者excle()。
對於內核中過程fork通過調用clone函數,然后clone函數調用do_fork()。do_fork()中調用copy_process()函數先復制task_struct結構體,然后復制其他關於內存,文件,寄存器等信息。fork采用寫時拷貝技術,因此子進程和父進程的頁表指向相同的頁框。但是vfork不需要拷貝頁表,因為父進程會一直阻塞,直接使用父進程頁表。

32.路由器工作在哪一層(B)

A:鏈路層 B:網絡層 C:傳輸層 D:應用層

33.網絡192.168.220.0/24 定向廣播地址是(192.168.220.255),受限的廣播地址為(255.255.255.255);

34.簡述TCP/IP協議中三次握手的過程及涵義?

第一次握手:建立連接時,客戶端發送syn包(syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確認;
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手

35.簡述一下TCP 、UDP 的區別?

TCP:TCP 則提供面向連接的服務。在傳輸數據前必須先建立連接,數據傳輸完畢后要釋放連接。
UDP:UDP協議是面向無連接的用戶數據報協議,在傳輸數據之前不需要先建立連接。遠地主機的運輸層收到UDP報文后,不需要給出任何確認。

區別:
是否面向連接:Tcp面向連接 ,udp是面向無連接
是否可靠: Tcp可靠 ,udp不可靠
應用場合: Tcp應用於傳輸大量數據 ,udp用於傳輸少量數據
速度: Tcp的速度慢 ,udp的速度快
是否能夠廣播:tcp不能 ,udp能廣播
tcp是基於連接的,速度慢,有校驗等,所以傳送相同的數據,要比UDP發送的包多很多。

36.請說明信號量與互斥量的區別?

答:互斥量用於線程的互斥,信號量用於線程的同步。其根本區別在於互斥和同步之間的區別。
互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。
同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源。

37.socket什么情況下可讀?

1)socket接收緩沖區中已經接收的數據的字節數大於等於socket接收緩沖區低潮限度的當前值;對這樣的socket的讀操作不會阻塞,並返回一個大於0的值(准備好讀入的數據的字節數)。
2)連接的讀一半關閉(即:接收到對方發過來的FIN的TCP連接),並且返回0;
3)socket收到了對方的connect請求已經完成的連接數為非0.這樣的soocket處於可讀狀態。
4)異常的情況下socket的讀操作將不會阻塞,並且返回一個錯誤(-1)。

38.socket編程,如果client斷電了,服務器如何快速知道?

使用定時器(適合有數據流動的情況);使用socket選項SO_KEEPALIVE(適合沒有數據流動的情況);

1)、自己編寫心跳包程序,簡單的說就是自己的程序加入一條線程,定時向對端發送數據包,查看是否有ACK,根據ACK的返回情況來管理連接。此方法比較通用,一般使用業務層心跳處理,靈活可控,但改變了現有的協議;
2)、使用TCP的keepalive機制,UNIX網絡編程不推薦使用SO_KEEPALIVE來做心)跳檢測。

39.https與http的區別?如何實現加密傳輸?

1)https就是在http與傳輸層之間加上了一個SSL。
2)對稱加密與非對稱加密。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM