2017阿里實習生筆試題(二)
下面哪一個不是動態鏈接庫的優點?
A.共享
B.裝載速度快
C.開發模式好
D.減少頁面交換
靜態鏈接與動態鏈接:
1 靜態鏈接庫的優點
(1) 代碼裝載速度快,執行速度略比動態鏈接庫快;
(2) 只需保證在開發者的計算機中有正確的.LIB文件,在以二進制形式發布程序時不需考慮在用戶的計算機上.LIB文件是否存在及版本問題,可避免DLL地獄等問題。
2 動態鏈接庫的優點
(1) 更加節省內存並減少頁面交換(靜態庫把所有的文件都裝入了,而動態庫只是裝入了部分需要的);
(2) DLL文件與EXE文件獨立,只要輸出接口不變(即名稱、參數、返回值類型和調用約定不變),更換DLL文件不會對EXE文件造成任何影響,因而極大地提高了可維護性和可擴展性;
(3) 不同編程語言編寫的程序只要按照函數調用約定就可以調用同一個DLL函數;
(4)適用於大規模的軟件開發,使開發過程獨立、耦合度小,便於不同開發者和開發組織之間進行開發和測試。
3 不足之處
(1) 使用靜態鏈接生成的可執行文件體積較大,包含相同的公共代碼,造成浪費;
(2) 使用動態鏈接庫的應用程序不是自完備的,它依賴的DLL模塊也要存在,如果使用載入時動態鏈接,程序啟動時發現DLL不存在,系統將終止程序並給出錯誤信 息。而使用運行時動態鏈接,系統不會終止,但由於DLL中的導出函數不可用,程序會加載失敗;速度比靜態鏈接慢。當某個模塊更新后,如果新模塊與舊的模塊 不兼容,那么那些需要該模塊才能運行的軟件,統統撕掉。這在早期Windows中很常見。
由權值分別為1、12、13、4、8的葉子節點生成一顆哈夫曼樹,它的帶權路徑長度為()

哈弗曼樹:哈夫曼樹是一種帶權路徑長度最短的二叉樹,也稱為最優二叉樹。

就拿上圖例子來說:
A,B,C,D對應的哈夫曼編碼分別為:111,10,110,0
假設從上至下地址遞增,則 PowerPC(大): Intel X86(小): 04 01 低 03 02 | 02 03 | 01 04 高
a+3指向最大的地址,所以分別為1 4
經歷SYN_RECV狀態
經歷SYN_SEND狀態
經歷ESTABLISHED狀態
經歷TIME_WAIT狀態
服務器在收到syn包時將加入半連接隊列
服務器收到客戶端的ack包后將從半連接隊列刪除
問題描述:
#pragma pack(2) class BU { int number; union UBffer { char buffer[13]; int number; }ubuf; void foo(){} typedef char*(*f)(void*); enum{hdd,ssd,blueray}disk; }bu;
sizeof(bu)的值是()
第一行的使得對齊的補齊字節為2。
因此union的大小為13+1=14.
void foo(){} 不占 ——函數不占用sizeof的內存。
typedef char*(*f)(void*); 不占——聲明不占用內存
enum{hdd,ssd,blueray}disk; 4個字節—— -- 實質上就是整型,所以 size 是 4
在動態分區分配方案中,系統回收主存,合並空閑空間時需修改空閑區表,以下哪種情況空閑區會減1?
A.只要回收主存,空閑區數就會減一
B.空閑區數和主存回收無關
C.無上鄰空閑區,也無下鄰空閑區
D.有上鄰空閑區,但無下鄰空閑區
E.有下鄰空閑區,但無上鄰空閑區
F.有上鄰空閑區,也有下鄰空閑區
int* pint = 0; pint += 6; cout << pint << endl;
以上程序的運行結果是: 24
首先如果直接cout一個指針,打印的是其所村春的變量的地址。
這個指針+6,一個指針的大小是4,加4*6就是24.
下面哪種協議在數據鏈路層?
ARP
ICMP
FTP
UDP
HTTP
VPN
ICMP是網絡層,UDP是傳輸層,FTP和HTTP是應用層
目前VPN隧道協議主要有4種:點到點隧道協議PPTP、第二層隧道協議L2TP、網絡層隧道協議IPSec以及SOCKS v5協議。其中,PPTP和L2TP工作在數據鏈路層,IPSec工作在網絡層,SOCK v5工作在會話層。
TCP/IP模型中,ARP協議屬於網絡層,在OSI參考模型中,ARP屬於數據鏈路層
以下哪種方式,在讀取磁盤上多個順序數據塊時的效率最高?
中斷控制方式
DMA方式
通道方式
程序直接訪問方式
循環檢查I/O方式
以上訪問方式都一樣
C/C++工程師能力評估
以下prim函數的功能是分解質因數。括號內的內容應該為?
void prim(int m, int n) { if (m >= n) { while ( ) n++; ( ); prim(m, n); cout << n << endl; } }
m/=n m%=n
分解質因數:從n=2開始,找到第一個m的質因子,因此需要m&n==0,然后繼續找剩下的質因子,此時m=m/n。也可以用循環法做,此處不再贅述。
補充一下判斷是否為質數的代碼:
int isPrime(int n) { int flag = 1; for(int i = 2; i*i <= n; i++) if(n%i == 0) flag = 0; return flag; }
補充一下最大公約數的代碼:(輾轉相除法)
int gcd(int x,int y) //用輾轉相除法,求兩數的最大公約數 { int r; while(y>0) { r=x%y; x=y; y=r; } return x; }
求兩數的最大公約數,可采用歐幾里得方法:只要兩數不相等,就反復用大數減小數,直到相等為止,此相等的數就是兩數的最大公約數。
int gcd(int x,int y) { while(x!=y) { if(x>y) x=x-y; else y=y-x; } return x; }
補充一下最小公倍數的代碼:先求出最大公約數,用x*y/gcd(x,y)就可以得到最小公倍數。
enum string{ x1, x2, x3=10, x4, x5, } x;
函數外部問x等於什么?0
- 數組在當做參數傳給函數的時候,會被退化為普通指針,因此,sizeof還是4字節。
- 指針在做加減的時候,是根據其所指的類型進行加減的,因此加減sizeof(type)。
- 靜態局部變量要比全局變量先銷毀。
- 重載和重寫的一些要求:
char
(* ss)[N]表示是一個指向一個數組(字符串數組),這個數組存的類型是——char[N],即又是一個一位數組。
- 類的大小注意點:
1 先找有沒有virtual 有的話就要建立虛函數表,+4
2 static的成員變量屬於類域,不算入對象中,成員函數也不占空間 +0
3 神馬成員都沒有的類,或者只有成員函數 +1
4 對齊法則,對大家都沒有問題,看看有沒有被#pragma pack(n)設置大小
int main() { MyClass obj1(1), obj2(2); MyClass obj3 = obj1; return 0; }
關於拷貝構造和賦值的問題:以上例子中obj3調用的是拷貝構造函數,因為obj3還未存在,需要調用拷貝構造函數。
假如obj3已經存在,才會調用賦值函數。
數組全排列:
void perm(int list[], int k, int m) { if (k==m) { copy(list,list+m,ostream_iterator<int>(cout," ")); cout<<endl; return; } for (int i=k; i<=m; i++) { swap(&list[k],&list[i]); perm(list,k+1,m); swap(&list[k],&list[i]); } }
騰訊2016研發工程師在線模擬筆試題
1、 32位系統中,定義**a[3][4],則變量占用內存空間為()。
解析:**a[3][4]表示a存儲的地址,指向一個大小為3*4的數組,這個數組里存儲的是指針。指針大小為4,4*3*4=48。
2、有36輛自動賽車和6條跑道,沒有計時器的前提下,最少用幾次比賽可以篩選出最快的三輛賽車?
解析:6次得到小組第一,a1 b1 c1 d1 e1 f1,def所在的小組的二三名舍棄。
第七次,a1,b1,c1,d1,e1,f1進行比賽。得到前三,假設為b1,d1,e1。則a1,c1,f1被舍棄。
第八次,在b2,b3,d1,d2,e1種得到第二名和第三名。
3、下列哪些http方法對於服務端和用戶端一定是安全的?()
解析:
Get:通過請求URI得到資源。
Post:不僅可以查詢也可以添加新的內容,請求放在Body里。
Head:類似於Get,但是不返回body,獲得請求uri的響應報頭,用於檢查對象是否存在。
Trace:用於遠程診斷服務器。
Options:列出請求的資源支持的所有方法。
Head、Get、Options和Trace視為安全的方法,因為它們只是從服務器獲得資源,而不對服務器做任何修改,但對於用戶端未必安全。例如get容易將敏感信息暴露在uri中。
4、一個系統,提供多個http協議的接口,返回的結果Y有json格式和jsonp格式。Json的格式為 {"code":100,"msg":"aaa"},為了保證該協議變更之后更好的應用到多個接口,為了保證修改協議不影響到原先邏輯的代碼,以下哪些設 計模式是需要的?協議的變更指的是日后可能返回xml格式,或者是根據需求統一對返回的消息進行過濾。()
解析:裝飾者模式:動態添加功能,例如過濾功能,並不修改原來的邏輯。
proxy模式:為類提供代理,使得代理類可以控制對 對象的訪問,例如實現延遲實例化,控制訪問等。
composite模式:組合模式,將對象組合成樹形結構以表示"部分-整體"的層次結構。使得用戶對單個對象和組合對象的使用具有一致性。
5、對於定義"int *p",下列哪些說明可能是正確的?()
int (*p)「10」才表示一個指向一位數組的指針。
int * (*p)「10」表示一個指向二位數組的指針。
int arr「10」;
int *p=arr;此時p保存的是第一個元素的地址。
6、十字鏈表是無向圖的一種存儲結構()是
解析:
圖的存儲結構:
鄰接矩陣,也成為數組表示法。用一個一維數組存儲圖中頂點的信息,用一個二維數組存儲邊的信息。
鄰接表:是一種順序存儲和鏈式存儲結合的存儲方法。
十字鏈表:即把每一條邊的邊結點分別組織到以弧尾頂點為頭結點的鏈表和以弧頭頂點為頭頂點的鏈表中。在十字鏈表表示中,頂點表和邊表的結點結構分別如圖8.13 的(a)和(b)所示。
7、在一個元素個數為N的數組里,找到升序排在N/5位置的元素的最優算法時間復雜度是 O(n)
解析:算法課上講過的,線性復雜度的找第K大的元素的算法。
BFPRT算法解決的問題十分經典,即從某n個元素的序列中選出第k大(第k小)的元素,通過巧妙的分 析,BFPRT可以保證在最壞情況下仍為線性時間復雜度。
該算法的思想與快速排序思想相似,當然,為使得算法在最壞情況下,依然能達到o(n)的時間復雜 度,五位算法作者做了精妙的處理。
算法步驟:
1. 將n個元素每5個一組,分成n/5(上界)組。
2. 取出每一組的中位數,任意排序方法,比如插入排序。
3. 遞歸的調用selection算法查找上一步中所有中位數的中位數,設為x,偶數個中位數的情況下設定為選取中間小的一個。
4. 用x來分割數組,設小於等於x的個數為k,大於x的個數即為n-k。
5. 若i==k,返回x;(i就是中位數)
若i<k,在小於x的元素中遞歸查找第i小的元素;
若i>k,在大於x的元素中遞歸查找第i-k小的元素。
終止條件:n=1時,返回的即是i小元素。
8、下面的程序輸出可能是什么?一直是“ab”
class Printer{ public: Printer(std::string name) {std::cout << name;} }; class Container{ public: Container() : b("b"), a("a") {} Printer a; Printer b; }; int main(){ Container c; return 0; }
初始化列表的初始化順序 與在列表中的順序無關,由變量在類中定義的先后順序決定.
因此先初始化a,然后再初始化b。
還有一種題目:
class A { private: int n1; int n2; public: A():n2(0),n1(n2+2){} void Print(){ cout << "n1:" << n1 << ", n2: " << n2 <<endl; } }; int main() { A a; a.Print(); return 1; }
這個題目,因為先初始化n1,此時n2還未初始化,所以是未定義值。后來n2才被初始化為0.因此結果是下圖:
9、下面程序段包含4個函數,其中具有隱含this指針的是() f4
int f1(); class T { public:static int f2(); private:friend int f3(); protect:int f4(); };
解析:
10、如果在一個排序算法的執行過程中,沒有一對元素被比較過兩次或以上,則稱該排序算法為節儉排序算法,以下算法中是節儉排序算法的有________。插入排序,歸並排序
解析:
A。插入排序的思想是對第i+1位置上的數,將其插入前i個有序數組中。插入以后形成新的有序數組,根據排序數組不會在比較的原則,該元素不可能再次比較了。
結點的帶權路徑長度:結點到樹根之間的路徑長度與該結點上權的乘積。
哈夫曼編碼:(左1右0/左0右1)。得到碼表,根據出現的概率乘以碼長可以得到平均碼長。平均碼長/等長編碼=壓縮率。
哈夫曼編碼步驟:(找最小權值的節點拿出來構成一顆二叉樹,生成一個中間節點,再重復)
一、對給定的n個權值{W1,W2,W3,...,Wi,...,Wn}構成n棵二叉樹的初始集合F= {T1,T2,T3,...,Ti,...,Tn},其中每棵二叉樹Ti中只有一個權值為Wi的根結點,它的左右子樹均為空。(為方便在計算機上實現算 法,一般還要求以Ti的權值Wi的升序排列。)
二、在F中選取兩棵根結點權值最小的樹作為新構造的二叉樹的左右子樹,新二叉樹的根結點的權值為其左右子樹的根結點的權值之和。
三、從F中刪除這兩棵樹,並把這棵新的二叉樹同樣以升序排列加入到集合F中。
四、重復二和三兩步,直到集合F中只有一棵二叉樹為止。
12、若以下程序
#include <stdio.h> main() { FILE *fp; int i,a[ 6]={1,2,3,4,5,6},k; fp = fopen ("data.dat", "w+b"); for (i=0;i<6;i+ +) { fseek(fp,0L,0); fwrite(&a[5—i],sizeof(int),1,fp); } rewind(fp); fread(&k,sizeof(int),1,fp); fclose(fp); printf("%d",k); }
解析:
C的關於文件I/O的函數庫,首先定義了一個文件流fp。然后以w+b的方式打開data文件。下圖是open的mode選項:r讀w寫a追加 加b表示binary二進制模式然后fseek 用於二進制方式打開的文件,移動文件讀寫指針位置。最后開頭只有1。將文件內部的位置指針重新指向一個流(數據流/文件)的開頭。654321,每次都寫開頭,都覆蓋模式。
rewind(fp);也是將讀寫指針移到開頭。最后讀入k只有1.
13.對{05,46,13,55,94,17,42}進行基數排序,一趟排序的結果是:()42,13,94,05,55,46,17
解析:
14、下列關於bool,int,float,指針類型的變量a 與“零”的比較語句正確的有?
bool : if(!a)
int : if(a == 0)
float: if(a == 0.0) 錯誤:
指針: if(a == NULL)