筆試面試總結(1)

1、TCP三次握手

2、堆排序的實現

3、memcpy

4、數據庫DB、數據庫系統DBS、數據庫管理系統DBMS三者之間的關係是?
數據庫系統DBS包括數據庫DB和數據庫管理系統DBMS!!

5、產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關係。

6、缺頁中斷:FIFO和LRU最近最久
計算個數的時候,一定要將開始爲空填滿的時候,也要算進去

7、廣度優先遍歷的實現

8、結構體所佔內存大小的計算
 使用gcc默認對齊規則的情況下,下列兩個數據結構的sizeof各是多少?()
struct FirstStruct{
char a;
uint64_t b;
uint32_t c;
uint32_t d;
};
struct SecondStruct{
char a;
uint32_t b;
uint32_t c;
};
A、17,13 B、24,16 C、24,24 D、32,16

9、將數學表達式轉化爲後綴形式

10、在操作系統的生產者消費者問題中,能否將生產者進程wait(empty)和wait(mutex)語句交換?爲什麼?

11、請指出二叉樹後序遍歷棧操作算法的關鍵,並給出最簡單的算法思路。

12、C語言的數據在內存中以補碼形式存放,根據題目的條件,可將x、y、z的值由十進制轉爲二進制補碼。
  x爲int型,且在32位的機器上運行,因此x字長爲32位,轉換成二進制爲0000 0000 0000 0000 0000 0000 0111 1111,再轉換成十六進制爲0000007FH。
  y爲short型,且在32位的機器上運行,因此y字長爲16位,轉換成二進制爲1111 1111 1111 0111(取反加1),再轉換成十六進制爲FFF7H。
  z爲int型,且在32位的機器上運行,因此z字長爲32位,z=x+y=127-9=118,轉換成二進制爲0000 0000 0000 0000 0000 0000 0111 0110,再轉換成十六進制爲00000076H。
 



13、

每增加一個度爲 4的結點,葉子增加3個,

每增加一個度爲 3的結點,葉子增加2個,

每增加一個度爲 2的結點,葉子增加1個,

每增加一個度爲 1的結點,葉子數不變。

原來只有一個根。所以 1 + 3*20+2*10+1=82

13、

最大流最小割定理:最大流等於最小割容量;

如圖最小割容量爲 15+19+12=46


14、跳躍鏈表

15、在計算機系統中,數值一律用補碼來表示(存儲)

16、孤兒進程和殭屍進程

17、linux內存屏障淺析

18、圖的算法,哪些採用貪心算法

19、ACID,指數據庫事務正確執行的四個基本要素的縮寫。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。一個支持事務(Transaction)的數據庫系統,必需要具有這四種特性,否則在事務過程(Transaction processing)當中無法保證數據的正確性,交易過程極可能達不到交易方的要求。

20、一個無規律的數組,只允許遍歷一遍,求方差
設最終的和爲T,平均值爲m,各個數爲X0到XN方差的公式是:
((m - x0)^2 +……+(m - xN)^2) / N
= ((T/N - x0) ^2 +……+(T/N - xN) ^2)/N
= ((T - N*x0)^2/N^2+……+(T - N * xN)^2/N^2)/N
= ((T^2 - 2N * x0 + N^2 * x0^2) +……+ (T^2 - 2N * xN + N^2 * xN^2))/N^3
= (N*T^2 - 2N * T + N^2 * (x0^2 + ……+ xN^2))/N^3
顯然一次循環可以搞定,循環中計算T 和 x[i]的平方和即可,循環結束後
即可完成整個算式的計算了。

21、進程的掛起與阻塞
阻塞是由於進程所需資源得不到滿足,並會最終導致進程被掛起
 
進程掛起的原因並不一定是由於阻塞,也有可能是時間片得不到滿足,掛起狀態是進程從內存調度到外存中的一種狀態,若在就緒態時,從內存調出到外存中,就是就緒掛起態,若在阻塞態時,從內存調出到外存中,就轉換成了阻塞掛起態

22、10G個數找中位數

23、海量數據找中位數:

24、



25、求最大流

26、從一道百度面試題到分析輸入url到頁面返回的過程(或者查詢返回過程)

27、內存訪問速度通常在50ns到80ns範圍內,SSD硬盤的訪問速度一般是SATA硬盤的一千多倍
幾十納秒,幾十微秒,幾十毫秒

28:筆試面試(3)阿里巴巴2014筆試題詳解(9月22北京)

29、某網絡的IP地址空間爲192.168.5.0/24,採用定長子網劃分,子網掩碼爲255.255.255.248,則該網絡的最大子網個數、每個子網內最大可分配地址個數各位(C)
   A、8,32   B、32,8    C、32,6    D、8,30 
192.168.5.0/24 表示24位是掩碼每個網中,第一個IP地址(即主機部分全部爲0的IP)和最後一個IP(即主機部分全部爲1的IP)不能分配給主機使用,所以每個子網的可用IP地址數爲總IP地址數量減2;

30、如何判斷一個圖中是否存在迴路 

31、判斷有向圖是否存在迴路,利用(A)方法最佳
   A、拓撲排序                    B、求最短路徑
   C、求關鍵路徑                  D、廣度優先遍歷 
知識點:拓撲排序 

32、阿里巴巴有相距1500km的機房A和B,現有100GB數據需要通過一條FTP連接在100s的時間內從A傳輸到B。已知FTP連接建立在TCP協議之上,而TCP協議通過ACK來確認每個數據包是否正確傳送。網絡信號傳輸速度2*108m/s,假設機房間帶寬足夠高,那麼A節點的發送緩衝區可以設置爲最小(A)
   A、18M         B、12M        C、6M        D、24M 
解析: 
   TCP協議原理:TCP每發送一個報文段,就啓動一個定時器,如果在定時器超時之後還沒有收到ACK確認,就重傳該報文。 
   如圖所示,數據包由A的緩衝區發往B,B在收到數據包以後,回發一個ACK確認包給A,之後A將該數據包從緩衝區釋放。因此,該數據包會一直緩存在A的緩衝區,直到一個ACK確認爲止。題目要求在100s內發送100GB數據,網絡的傳輸速率至少是1G/s,某個數據包n在A中緩存的時間就是數據包n從A到B,再加上該數據包的ACK從B到A的時間:2*1500km/(2*108m/s)=1.5*10-2s,該段時間A中緩存的數據量至少是1G/s*1.5*10-2s約爲15M 

33、設某文件經內排序後得到100個初始歸併段(初始順串),若使用多路歸併排序算法,且要求三趟歸併完成排序,問歸併路數最少爲(D)
   A、8           B、7           C、6          D、5 
解析:m個元素k路歸併的歸併趟數s=logk(m),代入數據:logk(100)≦3 

34、文件分配表FAT是管理磁盤空間的一種數據結構,用在以鏈接方式存儲文件的系統中記錄磁盤分配和追蹤空白磁盤塊,整個磁盤僅設一張FAT表,其結構如下所示,如果文件塊號爲2,查找FAT序號爲2的內容得知物理塊2的後繼物理塊是5,再查FAT序號爲5的內容得知物理塊5的後繼物理塊是7,接着繼續查FAT序號爲7的內容爲“Λ”,即該文件結束標誌,


假設磁盤物理塊大小爲1KB,並且FAT序號以4bits爲單位向上擴充空間。請計算下列兩塊磁盤的FAT最少需要佔用多大的存儲空間?
(1)一塊540MB的硬盤                 (2)一塊1.2GB的硬盤 

解析:(1)磁盤塊大小爲1KB,540MB的硬盤可以分成540MB/1KB=5.4*105個磁盤塊,因此至少需要5.4*105<220個編號,需要20bit存儲空間
         (2)同理,1.2G至少需要1.2*106<221個編號,爲21bit,由於FAT序號以4bits爲單位向上擴充,因此需要24bit存儲空間


34、開放地扯法: 公式 Hi=(H(key)+di) MOD m i=1,2,...,k(k<=m-1)  其中,m爲哈希表的表長。di 是產生衝突的時候的增量序列 
再哈希法:設計二種甚至多種哈希函數,可以避免衝突,但是衝突機率還是有的。
鏈地址法:拉出一個動態鏈表代替靜態順序存儲結構,可以避免哈希函數的衝突,不過缺點就是鏈表的設計過於麻煩,增加了編程複雜度。此法可以完全避免哈希函數的衝突。 
建立一個公共溢出區

35、下面說法錯誤的是: 
         A: CISC計算機比RISC計算機指令多 
        B: 在指令格式中,採用擴展操作碼設計方案的目的是爲了保持指令字長不變而增加尋址空間 
        C:增加流水線段數理論上可以提高CPU頻率 
        D:馮諾依曼體系結構的主要特徵是存儲程序的工作方式 
解析:  
A:RISC設計原則:指令條數儘可能少,一般爲幾十條指令;尋址方式儘可能少;採用等長指令,不管功能複雜的還是簡單的指令,均用同一長度;設計儘可能多的通用寄存器 
B:在指令格式中,採用擴展操作碼設計方案的目的是爲了保持指令字長不變而增加指令操作的數量 
C:流水線設計可最大限度地利用了CPU資源,使每個部件在每個時鐘週期都在工作,從而提高了CPU的運算頻率。CPU採用級數更多的流水線設計可使它在同一時間段內chǔ理更多的指令,有效提高其運行頻率。 
答案:B 

36、不屬於馮諾依曼體系結構必要組成部分是: 
        A:CPU B: Cache C:RAM D:ROM 
解析: 
    馮諾依曼體系結構: 

37、你認爲可以完成編寫一個C語言編譯器的語言是: 
A:彙編 B:C語言 C:VB D:以上全可以 
解析:彙編肯定的可以的;任何語言都是可以自解釋的,也就是可以用自己編寫編譯器解釋自己,所以B也是對的;C應該也可以,不過答案已經出來了。 
答案:D 

38、關於C++/JAVA類中的static成員和對象成員的說法正確的是: 
A:static成員變量在對象構造時候生成 
B: static成員函數在對象成員函數中無法調用 
C: 虛成員函數不可能是static成員函數 
D: static成員函數不能訪問static成員變量 
解析: 
    A:static成員變量在類的定義時初始化,不可以在對象的構造函數中初始化 
    B:static成員函數在對象成員函數中可以調用,同屬於一個類作用域 
    C:static成員函數不可以聲明爲const和virtual 
    D:static成員函數只能訪問static成員變量 
答案:C 

39、袋中有紅球,黃球,白球各一個,每次任意取一個放回,如此連續3次,則下列事件中概率是8/9的是:
A: 顏色不全相同     B:顏色全不相同    C:顏色全相同    D:顏色無紅色
解析:
顏色不全相同:1 - ( 1/3 * 1/3 * 1/3 ) * 3 = 8/9
顏色全不相同:1/3 * ( 1 - 1/3 ) * ( 1 - 1/3 - 1/3 ) = 2/9
顏色全相同:    ( 1/3 * 1/3 * 1/3 ) * 3 = 1 /9
顏色無紅色:    ( 1 - 1/3 ) * ( 1 - 1/3 ) * ( 1 - 1/3 ) = 8/27
答案:A

40、關於排序算法的以下說法,錯誤的是:
A: 快速排序的平均時間複雜度O(nlogn),最壞O(N^2)
B:堆排序平均時間複雜度O(nlogn),最壞O(nlogn)
C:冒泡排序平均時間複雜度O(n^2),最壞O(n^2)
D:歸併排序的平均時間複雜度O(nlogn),最壞O(n^2)
答案:D
解釋:歸併排序的平均時間複雜度O(nlogn),最壞O(nlogn)


41、已知二叉樹前序遍歷和後序遍歷如何求中序遍歷?
這樣的題是不能得到唯一的二叉樹來的!
如: 
樹A:有結點1,2,3,2是1的左孩子,3是2的右孩子 
樹B:有結點1,2,3,2是1的右孩子,3是2的左孩子 

則A,B的前序都是123,後序都是321,但A的中序是231,B的中序是132
前序遍歷和後序遍歷是不能確定唯一的二叉樹

42、宿舍內5個同學一起玩對戰遊戲。每場比賽有一些人作爲紅方,另一些人作爲藍方。請問至少需要多少場比賽,才能使任意兩個人之間有一場紅方對藍方和藍方對紅方的比賽? 
解析:
一次劃分中,某方可以有1人,另一方有4人或某方有2人,另一人有3人。
要使任意兩個人之間有一場紅方對藍方和藍方對紅方的比賽,假設5個同學爲A,B,C,D,E,相當有有向圖的5個節點,任意兩個節點間有兩個方向的邊連接。
即總的節點關係有(5個節點中選取兩個節點)A(5,2)=5*4=20個關係。
而一次比賽(一次劃分)能夠生成的關係(一方兩人一方三人的劃分)c(2,1)*c(3,1)=2*3=6或者(一方四人一方一人的劃分)c(4,1)*(c(1,1)=4*1=4,
所以一場比賽(一次劃分)最多生成的關係次數爲6
所以需要20/6=3.33..即至少需要4場比賽
答案:4場,分別是AB-CDE、ACD-BE、BCE-AD、DE-ABC

43、一個有10億條記錄的文本文件,已按照關鍵字排好序存儲。請設計算法,可以快速的從文件中查找指字關鍵字的記錄
答案:建立B/B+樹,通過指針指向偏移量,快速定位。


44、兩顆二叉樹T1和T2,T1的節點數是百萬數量級,T2的節點數一千以內,請給出判斷T2是否是T1子樹的可行算法。
首先想到的是遞歸,但是T1的數量級太大,遞歸會導致棧溢出,於是以非遞歸實現。


45、字符串 alibaba 有多少個不同的排列
思路:先有序排列:aaabbli。首先遞歸a(aabbli), b(aaabli), l(aaabbli) ,i(aaabbl)...依次交換不相同的。
只計算個數的話,就用:A(7,7) / (A(3,3)*A(2,2)) = 420

46、 某校園網用戶無法訪問外部站點210.102.58.74,管理人員在windows 操作系統下可以使用(       )判斷故障發生在校園網內還是校園網外。
  A. ping 210.102.58.74            B. tracert 210.102.58.74
  C. netstat 210.102.58.74          D. arp 210.102.58.74 


47、 第一題:7公斤米,50克砝碼,200克砝碼各一個,稱1350克米問最少要多少次,並編程回答。
我答,6次,可能一開始會想到 1350/250 + 2 = 7次,說明貪心無效。我不知道我的方法是不是很笨,用了遞推,或者你可以看成是動態規劃。轉化一下題目的意思就是1克和4克砝碼,問多少次稱出27克大米,F[N]代表N克大米最少需要多少次。
則有:
F[N]=min{F[N-1],F[N-4],F[N-5]}+1
代碼如下:
intfindmin(int weight)
{
         int v= weight/50;
         int f[150];
         f[0]=0;f[1]=1;f[2]=2;f[3]=3;f[4]=1;
         if (v<5) return f[v];
         int i;
         for (i=5;i<=v;i++)
                   f[i]=min(f[i-1]+1,f[i-4]+1,f[i-5]+1);
         return f[v];
}
 
注:我一開始愣了很久,我在想,稱好的大米可以作爲砝碼來用嗎??這樣就是另一種問題了吧。
附加:
如果天平能做爲平衡工具的話,兩次平分到1750克,然後兩次量出200克,1750-400就是1350克了。。。四次。。。。

解答題第一題: 
第一次:200+50,稱出250g 第二次:200+250,稱出450 第三次:200+450,稱出650 
共稱出1350g

48、sizeof()那點事

49、內存分配


50、OSI的七層模型



51、請列舉下不同進程之間共享數據的方式(至少舉出三種)
    1、文件映射(Memory-Mapped Files)能使進程把文件內容當作進程地址間一塊內存那樣來對待
    2、共享內存(Shared Memory)實際就是文件映射的一種特殊情況
    3、命名管道(Named Pipe)是服務器進程和一個或多個客戶進程之間通信的單向或雙向管道
    4、郵件槽(Mailslots)提供進程間單向通信能力,任何進程都能建立郵件槽成爲郵件槽服務器
    5、剪貼板(Clipped Board)爲不同應用程序之間共享不同格式數據提供了一條捷徑
    6、動態連接庫(DLL)中的全局數據可以被調用DLL的所有進程共享


52、請描述下TCP和UDP的差別,並且各列舉出一個上層協議。
     TCP---傳輸控制協議,提供的是面向連接、可靠的字節流服務。當客戶和服務器彼此交換數據前,必須先在雙方之間建立一個TCP連接,之後才能傳輸數據。TCP提供超時重發,丟棄重複數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另一端。
 
    UDP---用戶數據報協議,是一個簡單的面向數據報的運輸層協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,但是並不能保證它們能到達目的地。由於UDP在傳輸數據報前不用在客戶和服務器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度很快。
 
    經常使用“ping”命令的原理就是向對方主機發送UDP數據包,ftp等就是使用到的TCP協議


53、寫出new和malloc、delete和free的區別
從面向對象來說,new/delete和malloc/free的區別是:malloc/free只是單純的進行內存空間的分配和釋放,而使用new/delete時,不僅分配了內存空間,若new/delete的是一個類,還會調用類(經測試,基本類型好像不會進行默認初始化)的構造函數或析構函數。
  簡單來說,兩者的區別主要有:
  1. malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符,與”+“、”-“、”*“、”/“有一樣的地位。
  2. new/delete是可以重載的,而重載之後,就成爲了函數。
  3. malloc在申請內存的時候,必須要提供申請的長度,而且返回的指針是void*型,必須要強轉成需要的類型。
  4. 當new/delete在類中被重載的時候,可以自定義申請過程,比如記錄所申請內存的總長度,以及跟蹤每個對象的指針。
  5. new/delete,其實內部也調用了malloc/free。
  兩者的共同點有:
  1. 都必須配對使用,防止內存泄露。
  2. 都可用於申請動態內存和釋放內存,都是在堆中分配內存。
  3. free和delete可以釋放NULL指針。


54、寫兩個繼承類,解釋虛表指針和虛表的作用
每一個類都有虛表。
  虛表可以繼承,如果子類沒有重寫虛函數,那麼子類虛表中仍然會有該函數的地址,只不過這個地址指向的是基類的虛函數實現。如果基類有3個虛函數,那麼基類的虛表中就有三項(虛函數地址),派生類也會有虛表,至少有三項,如果重寫了相應的虛函數,那麼虛表中的地址就會改變,指向自身的虛函數實現。如果派生類有自己的虛函數,那麼虛表中就會添加該項。
  派生類的虛表中虛函數地址的排列順序和基類的虛表中虛函數地址排列順序相同。

55、寫出static的用法和作用
static 是C++中很常用的修飾符,它被用來控制變量的存儲方式和可見性。函數內部定義的變量,在程序執行到它的定義處時,編譯器爲它在
  棧上分配空間,大家知道,函數在棧上分配的空間在此函數執行結束時會釋放掉,這樣就產生了一個問題: 如果想將函數中此變量的值保存至
  下一次調用時,如何實現? 最容易想到的方法是定義一個全局的變量,但定義爲一個全局變量有許多缺點,最明顯的缺點是破壞了此變量的
  訪問範圍(使得在此函數中定義的變量,不僅僅受此函數控制)。 需要一個數據對象爲整個類而非某個對象服務,同時又力求不破壞類的封裝
  性,即要求此成員隱藏在類的內部,對外不可見

56、寫出計算機的存儲器層次,及原因
     以處理器爲中心,計算機系統的存儲依次爲寄存器、高速緩存、主存儲器、磁盤緩存、磁盤和可移動存儲介質等7個層次。距離處理器越近的存儲工作速度越高,容量越小。其中,寄存器、高速緩存、主存儲器爲操作系統存儲管理的管轄範圍,磁盤和可移動存儲介質屬於操作系統設備管理的管轄範圍。

57、寫出對windows中的句柄的理解
     所謂句柄實際上是一個數據,是一個Long (整長型)的數據。
   句柄是WONDOWS用來標識被應用程序所建立或使用的對象的唯一整數,WINDOWS使用各種各樣的句柄標識諸如應用程序實例,窗口,控制,位圖,GDI對象等等。WINDOWS句柄有點象C語言中的文件句柄。

58、當前計算機系統一般會採用層次結構存儲數據,請介紹下典型計算機存儲系統一般分爲哪幾個層次,爲什麼採用分層存儲數據能有效提高程序的執行效率?
     所謂存儲系統的層次結構,就是把各種不同存儲容量、存取速度和價格的存儲器按層次結構組成多層存儲器,並通過管理軟件和輔助硬件有機組合成統一的整體,使所存放的程序和數據按層次分佈在各種存儲器中。目前,在計算機系統中通常採用三級層次結構來構成存儲系統,主要由高速緩衝存儲器Cache、主存儲器和輔助存儲器組成。
     存儲系統多級層次結構中,由上向下分三級,其容量逐漸增大,速度逐級降低,成本則逐次減少。整個結構又可以看成兩個層次:它們分別是主存一輔存層次和cache一主存層次。這個層次系統中的每一種存儲器都不再是孤立的存儲器,而是一個有機的整體。它們在輔助硬件和計算機操作系統的管理下,可把主存一輔存層次作爲一個存儲整體,形成的可尋址存儲空間比主存儲器空間大得多。由於輔存容量大,價格低,使得存儲系統的整體平均價格降低。由於Cache的存取速度可以和CPU的工作速度相媲美,故cache一主存層次可以縮小主存和cPu之間的速度差距,從整體上提高存儲器系統的存取速度。儘管Cache成本高,但由於容量較小,故不會使存儲系統的整體價格增加很多。
     綜上所述,一個較大的存儲系統是由各種不同類型的存儲設備構成,是一個具有多級層次結構的存儲系統。該系統既有與CPU相近的速度,又有極大的容量,而成本又是較低的。其中高速緩存解決了存儲系統的速度問題,輔助存儲器則解決了存儲系統的容量問題。採用多級層次結構的存儲器系統可以有效的解決存儲器的速度、容量和價格之間的矛盾。

59、Unix/Linux系統中殭屍進程是如何產生的?有什麼危害?如何避免?
     一個進程在調用exit命令結束自己的生命的時候,其實它並沒有真正的被銷燬,而是留下一個稱爲殭屍進程(Zombie)的數據結構(系統調用exit,它的作用是使進程退出,但也僅僅限於將一個正常的進程變成一個殭屍進程,並不能將其完全銷燬)。
     在Linux進程的狀態中,殭屍進程是非常特殊的一種,它已經放棄了幾乎所有內存空間,沒有任何可執行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態等信息供其他進程收集,除此之外,殭屍進程不再佔有任何內存空間。它需要它的父進程來爲它收屍,如果他的父進程沒安裝SIGCHLD信號處理函數調用wait或waitpid()等待子進程結束,又沒有顯式忽略該信號,那麼它就一直保持殭屍狀態,如果這時父進程結束了,那麼init進程自動會接手這個子進程,爲它收屍,它還是能被清除的。但是如果如果父進程是一個循環,不會結束,那麼子進程就會一直保持殭屍狀態,這就是爲什麼系統中有時會有很多的殭屍進程。

  避免zombie的方法: 
      1)在SVR4中,如果調用signal或sigset將SIGCHLD的配置設置爲忽略,則不會產生僵死子進程。另外,使用SVR4版的sigaction,則可設置SA_NOCLDWAIT標誌以避免子進程僵死。 
      Linux中也可使用這個,在一個程序的開始調用這個函數 signal(SIGCHLD,SIG_IGN);  
      2)調用fork兩次。
      3)用waitpid等待子進程返回.

60、簡述Unix/Linux系統中使用socket庫編寫服務器端程序的流程,請分別用對應的socket通信函數表示
  TCP socket通信
服務器端流程如下:
1.創建serverSocket
2.初始化 serverAddr(服務器地址)
3.將socket和serverAddr 綁定 bind
4.開始監聽 listen
5.進入while循環,不斷的accept接入的客戶端socket,進行讀寫操作write和read
6.關閉serverSocket
客戶端流程:
1.創建clientSocket
2.初始化 serverAddr
3.鏈接到服務器 connect
4.利用write和read 進行讀寫操作
5.關閉clientSocket
這個列表是一個Berkeley套接字API庫提供的函數或者方法的概要:
     socket() 創建一個新的確定類型的套接字,類型用一個整型數值標識,併爲它分配系統資源。
     bind() 一般用於服務器端,將一個套接字與一個套接字地址結構相關聯,比如,一個指定的本地端口和IP地址。
     listen() 用於服務器端,使一個綁定的TCP套接字進入監聽狀態。
     connect() 用於客戶端,爲一個套接字分配一個自由的本地端口號。 如果是TCP套接字的話,它會試圖獲得一個新的TCP連接。
     accept() 用於服務器端。 它接受一個從遠端客戶端發出的創建一個新的TCP連接的接入請求,創建一個新的套接字,與該連接相應的套接字地址相關聯。
     send()和recv(),或者write()和read(),或者recvfrom()和sendto(), 用於往/從遠程套接字發送和接受數據。
     close() 用於系統釋放分配給一個套接字的資源。 如果是TCP,連接會被中斷。
     gethostbyname()和gethostbyaddr() 用於解析主機名和地址。
     select() 用於修整有如下情況的套接字列表: 準備讀,準備寫或者是有錯誤。
     poll() 用於檢查套接字的狀態。 套接字可以被測試,看是否可以寫入、讀取或是有錯誤。
     getsockopt() 用於查詢指定的套接字一個特定的套接字選項的當前值。
     setsockopt() 用於爲指定的套接字設定一個特定的套接字選項。


61、浮點數在計算中如何表示,如何對浮點數判等。
判斷兩個浮點數是否相等,不能簡單的用 == 表示。要自己定義一個精度,當兩個數的差的絕對值小於這個精度的時候,認爲相等。

62、TCP、UDP和HTTP

63、使用C語言實現htonl(將long性轉爲網絡字節碼),不使用系統自帶函數。
例如 int a = 0x12345678,b = htonl(a),那麼就應該是0x78563412
a) Little-Endian就是低位字節排放在內存的低地址端,高位字節排放在內存的高地址端。 
b) Big-Endian就是高位字節排放在內存的低地址端,低位字節排放在內存的高地址端。 
c) 網絡字節序:TCP/IP各層協議將字節序定義爲Big-Endian,因此TCP/IP協議中使用的字節序通常稱之爲網絡字節序。 
以上圖爲例如果我們在棧上分配一個unsigned char buf[4],那麼這個數組變量在棧上是如何佈局的呢?看下圖: 
棧底(高地址) 
---------- 
buf[3] 
buf[2] 
buf[1] 
buf[0] 
---------- 
棧頂(低地址) 

現在我們弄清了高低地址,接着我來弄清高/低字節,如果我們有一個32位無符號整型0x12345678(呵呵,恰好是把上面的那4個字節buf看成一個整型),那麼高位是什麼,低位又是什麼呢?其實很簡單。在十進制中我們都說靠左邊的是高位,靠右邊的是低位,在其他進制也是如此。就拿0x12345678來說,從高位到低位的字節依次是0x12、0x34、0x56和0x78。 
高低地址和高低字節都弄清了。我們再來回顧一下Big-Endian和Little-Endian的定義,並用圖示說明兩種字節序: 
以unsigned int value = 0x12345678爲例,分別看看在兩種字節序下其存儲情況,我們可以用unsigned char buf[4]來表示value: 
Big-Endian: 低地址存放高位,如下圖: 
棧底(高地址) 
--------------- 
buf[3] (0x78) -- 低位 
buf[2] (0x56) 
buf[1] (0x34) 
buf[0] (0x12) -- 高位 
--------------- 
棧頂(低地址) 
Little-Endian: 低地址存放低位,如下圖: 
棧底(高地址) 
--------------- 
buf[3] (0x12) -- 高位 
buf[2] (0x34) 
buf[1] (0x56) 
buf[0] (0x78) -- 低位 
--------------- 
棧頂(低地址) 

在現有的平臺上Intel的X86採用的是Little-Endian,而像Sun的SPARC採用的就是Big-Endian。 

64、堆和棧的區別

65、請說出static和const關鍵字儘可能多的作用
static關鍵字至少有下列n個作用:

  (1)函數體內static變量的作用範圍爲該函數體,不同於auto變量,該變量的內存只被分配一次,因此其值在下次調用時仍維持上次的值;

  (2)在模塊內的static全局變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問;

  (3)在模塊內的static函數只可被這一模塊內的其它函數調用,這個函數的使用範圍被限制在聲明它的模塊內;

  (4)在類中的static成員變量屬於整個類所擁有,對類的所有對象只有一份拷貝;

  (5)在類中的static成員函數屬於整個類所擁有,這個函數不接收this指針,因而只能訪問類的static成員變量。

  const關鍵字至少有下列n個作用:

  (1)欲阻止一個變量被改變,可以使用const關鍵字。在定義該const變量時,通常需要對它進行初始化,因爲以後就沒有機會再去改變它了;

  (2)對指針來說,可以指定指針本身爲const,也可以指定指針所指的數據爲const,或二者同時指定爲const;

  (3)在一個函數聲明中,const可以修飾形參,表明它是一個輸入參數,在函數內部不能改變其值;

  (4)對於類的成員函數,若指定其爲const類型,則表明其是一個常函數,不能修改類的成員變量;

  (5)對於類的成員函數,有時候必須指定其返回值爲const類型,以使得其返回值不爲“左值”。例如:

               const classA operator*(const classA& a1,const classA& a2);

  operator*的返回結果必須是一個const對象。如果不是,這樣的變態代碼也不會編譯出錯:
               classA a, b, c;
               (a * b) = c; // 對a*b的結果賦值

  操作(a * b) = c顯然不符合編程者的初衷,也沒有任何意義。

  剖析:

  驚訝嗎?小小的static和const居然有這麼多功能,我們能回答幾個?如果只能回答1~2個,那還真得閉關再好好修煉修煉。

  這個題可以考查面試者對程序設計知識的掌握程度是初級、中級還是比較深入,沒有一定的知識廣度和深度,不可能對這個問題給出全面的解答。大多數人只能回答出static和const關鍵字的部分功能。

66、請寫一個C函數,若處理器是Big_endian的,則返回0;若是Little_endian的,則返回1
int checkCPU()
{
 {
  union w
  { 
   int a;
   char b;
  } c;
  c.a = 1;
  return (c.b == 1);
 }
}

剖析:

     嵌入式系統開發者應該對Little-endian和Big-endian模式非常瞭解。採用Little-endian模式的CPU對操作數的存放方式是從低字節到高字節,而Big-endian模式對操作數的存放方式是從高字節到低字節。例如,16bit寬的數0x1234在Little-endian模式CPU內存中的存放方式(假設從地址0x4000開始存放)爲:
內存地址 存放內容
0x4000 0x34
0x4001 0x12

  而在Big-endian模式CPU內存中的存放方式則爲:

內存地址 存放內容
0x4000 0x12
0x4001 0x34

  32bit寬的數0x12345678在Little-endian模式CPU內存中的存放方式(假設從地址0x4000開始存放)爲:

內存地址 存放內容
0x4000 0x78
0x4001 0x56
0x4002 0x34
0x4003 0x12

  而在Big-endian模式CPU內存中的存放方式則爲:

內存地址 存放內容
0x4000 0x12
0x4001 0x34
0x4002 0x56
0x4003 0x78

     聯合體union的存放順序是所有成員都從低地址開始存放,面試者的解答利用該特性,輕鬆地獲得了CPU對內存採用Little-endian還是Big-endian模式讀寫。如果誰能當場給出這個解答,那簡直就是一個天才的程序員。




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