阿里2013筆試

1.

同一進程的線程共享:

1.進程代碼段

2.進程的公有數據(利用這些共享的數據,線程很容易的實現相互之間的通訊)

3.進程打開的文件描述符、

4.信號的處理器、

5.進程的當前目錄和

6.進程用戶ID與進程組ID

線程獨有的內容包括:

1.線程ID

2.寄存器組的值

3.線程的堆棧

4.錯誤返回碼

5.線程的信號屏蔽碼

2

Tcp雖然面向字節,但是有流控

3

在數據庫系統中,導致數據不一致的根本原因是:數據冗餘

4

考慮左遞歸文法S->Aa|b

               A->Ac|Sd|e,消除左遞歸後應該爲( )

S->Aa | b

A->Ac | Sd | e

S帶入A

A->Ac | Aad | bd | e

直接消除左遞歸:

A->bdA' | A'

A'->cA' | adA'|e

5

UNIX系統中,目錄結構採用( )

帶鏈接樹形目錄結構

6

請問下面的程序一共輸出多少個“-”

1

2

3

4

5

6

7

8

9

int main(void)

{

    int i;

    for (i = 0; i < 2; i++) { 

        fork(); 

        printf("-"); 

    } 

    return 0

 

這是因爲printf("-");語句有buffer,所以,對於上述程序,如果沒有\n則不會刷新緩存區。printf("-");“-”放到了緩存中,並沒有真正的輸出。所以答案是8次。,如果有\n則刷新緩存區,6次。

7

分派延遲指分派程序停止一個進程的執行到啓動另一個執行所花費的時間。

8

假定我們有3個程序,每個程序花費80%的時間進行I/O20%的時間使用CPU。每個程序啓動時間和其需要使用進行計算的分鐘數如下,不考慮進程切換時間:
程序編號 啓動時間 需要CPU時間(分鐘) 
1                0000      3.5 
2                0010      2 
3                0015     1.5
請問,在多線程/進程環境下,系統的總響應時間爲( )

0~10分鐘內,只有一個進程在跑,進程1總共使用了10*0.2=2分鐘的CPU10*0.8=8分鐘的IO,還剩下1.5分鐘的CPU要使用;

10~155分鐘內,有進程1和進程2兩個進程,CPU利用率爲1-0.8*0.8=0.36,所以CPU一共跑了5*0.36=1.8分鐘,假定兩個進程完全平等,CPU使用時間平分,則每個進程使用了1.8/2=0.9分鐘的CPU時間,這樣進程1剩下1.5-0.9=0.6分鐘的CPU,進程2剩下2-0.9=1.1分鐘的CPU

15開始,有3個進程, CPU利用率爲1-0.8*0.8*0.8=0.488,此時X分鐘之內,CPU總共執行了0.488*X分鐘,由於三個進程平分,所以每個進程的CPU使用時間爲0.488*X/3, 所以進程10.6*3/0.488=3.69分鐘之後,也就是15+3.69=18.69分完成;
之後CPU利用率又爲0.36(兩個進程),此時進程2剩下1.1-0.6=0.5分鐘的CPU,進程3剩下1.5-0.6=0.9分鐘的CPU, 之後進程2在在0.5*2/0.36=2.78分鐘之後也就是2.78+18.69=21.46時候進程2結束;
之後進程3開始單跑,此時進程3還剩下 0.9-0.5=0.4CPU時間,此時的CPU利用率爲0.20.4/0.2=2, 2分鐘之後進程3結束,也就是21.46+2=23.46≈23.5 所以答案應該選B

9

面向對象的三個基本元素,五個基本原則:封裝、繼承、多態

原則:

單一職責原則(Single-Resposibility Principle:一個類,最好只做一件事,只有一個引起它的變化。單一職責原則可以看做是低耦合、高內聚在面向對象原則上的引申,將職責定義爲引起變化的原因,以提高內聚性來減少引起變化的原因。

開放封閉原則(Open-Closed principle:軟件實體應該是可擴展的,而不可修改的。也就是,對擴展開放,對修改封閉的。

Liskov替換原則(Liskov-Substituion Principle:子類必須能夠替換其基類。這一思想體現爲對繼承機制的約束規範,只有子類能夠替換基類時,才能保證系統在運行期內識別子類,這是保證繼承複用的基礎。

依賴倒置原則(Dependecy-Inversion Principle:依賴於抽象。具體而言就是高層模塊不依賴於底層模塊,二者都同依賴於抽象;抽象不依賴於具體,具體依賴於抽象。

接口隔離原則(Interface-Segregation Principle:使用多個小的專門的接口,而不要使用一個大的總接口。

10

1

void *pszStringRotate(char *pszString, intnCharsRotate)

比如ABCDEFG,移3位變DEFGABC,要求空間複雜度O1),時間複雜度On)。

void Rorder(char *pF, char *pE)

{

    char temp;

    while (pF <= pE)

    {

        temp = *pF;

        *pF = *pE;

        *pE = temp;

    }

}

 

void *pszStringRotate(char *pszString, int nCharsRotate)

{

    char *pR = pszString;

    int n = 0;

    while (pszString + n++ = ‘\n’); //得到字符串長度

    if (n < nCharsRotate) return pR; //入口參數檢測

 

    Rorder(pszString, pszString + nCharsRotate ); //C B A

    pszString = pR;//歸位

    Rorder( pszString + nCharsRotate, pszString + n - 1); //GFED

    pszString = pR;

    Rorder(pszString, pszString + n - 1); //DEFGABC

    return pR;

}

大致過程如下:
ABCDEFG
第一步:局部翻轉
ABC DEFG == = CBA GFED
第二步:整體翻轉
CBA GFED    == = DEFGABC

11

windows內存管理的機制以及優缺點

分頁存儲管理基本思想:

用戶程序的地址空間被劃分成若干固定大小的區域,稱爲,相應地,內存空間分成若干個物理塊,頁和塊的大小相等。可將用戶程序的任一頁放在內存的任一塊中,實現了離散分配。

分段存儲管理基本思想:

將用戶程序地址空間分成若干個大小不等的段,每段可以定義一組相對完整的邏輯信息。存儲分配時,以段爲單位,段與段在內存中可以不相鄰接,也實現了離散分配。

段頁式存儲管理基本思想:

分頁系統能有效地提高內存的利用率,而分段系統能反映程序的邏輯結構,便於段的共享與保護,將分頁與分段兩種存儲方式結合起來,就形成了段頁式存儲管理方式。

在段頁式存儲管理系統中,作業的地址空間首先被分成若干個邏輯分段,每段都有自己的段號,然後再將每段分成若干個大小相等的頁。對於主存空間也分成大小相等的頁,主存的分配以頁爲單位。

段頁式系統中,作業的地址結構包含三部分的內容:段號 頁號 頁內位移量

程序員按照分段系統的地址結構將地址分爲段號與段內位移量,地址變換機構將段內位移量分解爲頁號和頁內位移量。

爲實現段頁式存儲管理,系統應爲每個進程設置一個段表,包括每段的段號,該段的頁表始址和頁表長度。每個段有自己的頁表,記錄段中的每一頁的頁號和存放在主存中的物理塊號。

12

設只含根節點的二叉樹高度爲1,現有一顆高度爲h(h>1)的二叉樹上只有出度爲0和出度爲2的結點,則此二叉樹中所包含的結點數至少爲________個。

分析:由於都是出度爲02,所以要有左子樹,就必須存在右子樹。所以節點最少的情況如圖:

所以答案爲2h+1

13

某地電信局要對業務號碼進行梳理,需要檢測開通的市話號碼是否存在某一個是另一個的前綴的情況,以簡化電話交換機的邏輯。例如:某用戶號碼是11001100”,但與"110"報警電話產生前綴配對。已知市話號碼最長8位,最短3位,並且所有3位的電話號碼都以1開頭。由於市話號碼衆多,長度也未必一直,高效的算法可以用O(n)的時間複雜度完成檢測(n爲開通市話號碼個數,數量是千萬級的)。那麼,該算法最壞情況下需要耗費大約________內存空間。

分析:最長 8 , 最短 3 6種情況:

三位都是 1 開頭 ,因此有 10^2=100 

四位: 10^4=10000

五位: 10^5=100000 

六位: 10^6=1000000 

七位: 10^7=10000000

八位: 10^8=100000000

相加一共爲111110100種,因爲電話號碼唯一,所有號碼最後1位不用判斷,總數除以10  = 11,111,010

 一位號碼  4bit(號碼   0-9  ,所以至少用  4    bit 位才能表示 ),8位的號碼佔 32bit 4字節/byte(其實可以只存前7,3.5byte

最後:11,111,010 * 4 / 1024 / 1024 = 42.4 Mb

14

甲乙兩人撿到一個價值10元的購物卡。協商後打算通過這樣的拍賣規則來確定歸屬:兩人單獨出價(可以出0元),出價高者得到購物卡同時將與出價相同數量的前給對方。如果兩人出價相同,則通過擲硬幣來決定購物卡的歸屬。例如:甲和乙都出價1元,他們通過擲硬幣來決定購物卡的歸屬。此時,得到購物卡的人賺9元,另一人賺1元。兩人都同意用手頭的現金來進行出價。甲和乙都知道甲有6元、乙有8元,兩人都期望自己儘可能多賺。那麼________

分析:甲乙兩人賺的一樣多

明顯甲乙兩人如果都想要獲得最多的利益,那麼就會互相揣摩對方是怎麼想的,會出多少錢。

首先,由於獲得價值10元購物卡的一方需要付出與出價相同數量的錢給對方,那麼如果出價高於5元,獲得購物卡的一方將收益少於(10-55元,很明顯不划算,所以

1.雙方都不會出價5元以上。

2.任一方都不會出價5元以下。

我們可以假設有一方出價4.9,那麼如果另一方出價4.91呢?那另一方就獲益5.09

因爲雙方都不知道對方到底會出多少元,都只能猜測,或者去推出對方想獲益最多應該出多少元,但不能保證對方一定會出那麼多錢,所以任何一方都不會出5元以下,除非確定對方一定會出5元,可是對方不一定會出5元,萬一對方是傻子。。

所以如一方0元,一方5元這種組合雖然雙方利益相等,但不太現實。

 

所以,結果應該是雙方都出價5元,扔硬幣決定購物卡歸屬,最終得到購物卡的要付出5元,雙方收益相等。

15

TCP斷開時四次揮手

 

16

某公司有這麼一個規定:只要有一個員工過生日,當天所有員工全部放假一天。但在其餘時候,所有員工都沒有假期,必須正常上班。假設一年有365天,每個員工的生日都概率均等地分佈在這365天裏。那麼,這個公司需要僱用多少員工,才能讓公司一年內所有員工的總工作時間期望值最大?

由於期望值滿足線性關係(即對於隨機變量 X Y E(X) + E(Y) = E(X+Y) ),因此我們只需要讓每一天員工總工作時間的期望值最大就可以了。假設公司裏有 n 個人,那麼在特定的一天裏,沒有人過生日的概率是 (364/365) n  。因此,這一天的期望總工作時間就是 n · (364/365) n 個工作日。爲了考察函數 n · (364/365) n  的增減性,我們來看一下 ((n+1) · (364/365) n+1 ) / (n · (364/365) n ) 的值,它等於 (364 · (n+1)) / (365 · n) 。如果分子比分母小,解得 n > 364 。可見,要到 n = 365 以後,函數纔是遞減的。

答案:365

17

給定一個排好升序的數組A[1]A[2]、……、A[n],其元素的值都兩兩不相等。請設計一高效的算法找出中間所有A[i] = i的下標。並分析其複雜度。(不分析複雜度不得分)

解析:

用二分法來找。

解題時需要注意三點:

1.A[i]=i的位置一定是連着的,前面的是A[i]<i,後面是A[i]>i。轉換成前面A[i]-i<0,A[i]-i=0,A[i]-i>0;

2.採用二分查找確定A[i]-i=0的位置

3.如何確定最左邊的A[i]-i=0的位置,在進行二分查找時進行判斷if(A[mid]-mid<0&&A[mid+1]-(mid+1)==0)return mid+1;

那就可以利用分治思想,進行二分一般的情況O(logn); 最差情況0(n);

public static int search(int[] A) {  

    int len = A.length;  

    int start = 0;  

    int end = len;  

    while (start <= end) {  

        int j = (start + end) / 2;  

        if (A[j] == j) {  

            return j;  

        }  

        if (A[j] > j) {  

            end = j - 1;  

        } else if (A[j] < j) {  

            start = j + 1;  

        }  

    }  

    return -1;  

}  

18

某怪物被海水衝上一個孤島。醒來時他發現自己處於險境。周圍有N條鱷魚都虎視眈眈的盯着他。每條鱷魚看上去都餓得足以把他吞下去。不過,事情也未必真的那麼糟糕。鱷魚吞下他是要花費體力的。這些鱷魚現在的體力都相當,由於獵食需要花費體力,所以吞下怪物的鱷魚會由於體力下降而可能被周圍的某條鱷魚吞了。類似的,吞鱷魚的這條鱷魚也可能被其他鱷魚吞了。因此,雖然有食物可獵,但他們自己並不想成爲其他鱷魚的獵食對象。正所謂,螳螂捕蟬,黃雀在後。所以鱷魚們在確保自己生命安全的情況下才會發動進攻。那麼,怪物到底安全麼?爲什麼?

解析:當鱷魚爲偶數的時候,鱷魚們兩兩相互制約,只要誰先吃了怪物,那這條鱷魚就會被吃掉,所以這個時候怪物是安全的。當鱷魚爲奇數的時候,當第一條鱷魚吃掉了怪物而變得虛弱時,剩下的鱷魚們爲偶數,兩兩相互制約,誰也不能吃這個吃了怪物的鱷魚,所以第一個動手的是安全的,既然這樣誰都想第一個動手,所以這個時候怪物就完蛋了。

19

當你在瀏覽器輸入一個網址,如http://www.taobao.com,按回車之後發生了什麼?請從技術的角度描述,如瀏覽器、網絡(UDPTCPHTTP等),以及服務器等各種參與對象上由此引發的一系列活動,請儘可能的涉及到所有的關鍵技術點。

 

首先是查找瀏覽器緩存,瀏覽器會保存一段時間你之前訪問過的一些網址的DNS信息,不同瀏覽器保存的時常不等。

如果沒有找到對應的記錄,這個時候瀏覽器會嘗試調用系統緩存來繼續查找這個網址的對應DNS信息。

如果還是沒找到對應的IP,那麼接着會發送一個請求到路由器上,然後路由器在自己的路由器緩存上查找記錄,路由器一般也存有DNS信息。

如果還是沒有,這個請求就會被髮送到ISP(注:Internet Service Provider,互聯網服務提供商,就是那些拉網線到你家裏的運營商,中國電信中國移動什麼的),ISP也會有相應的ISP DNS服務器,一聽中國電信就知道這個DNS服務器的規模肯定不會小,所以基本上都能在這裏找得到。題外話:會跑到這裏進行查詢是因爲你沒有改動過"網絡中心""ipv4"DNS地址,萬惡的電信聯通可以改動了這個DNS服務器,換句話說他們可以讓你的瀏覽器跳轉到他們設定的頁面上,這也就是人盡皆知的DNSHTTP劫持,ISP們還美名曰免費推送服務。強烈鄙視這種霸王行爲。我們也可以自行修改DNS服務器來防止DNSISP污染。

如果還是沒有的話, 你的ISPDNS服務器會將請求發向根域名服務器進行搜索。根域名服務器就是面向全球的頂級DNS服務器,共有13臺邏輯上的服務器,從AM命名,真正的實體服務器則有幾百臺,分佈於全球各大洲。所以這些服務器有真正完整的DNS數據庫。如果到了這裏還是找不到域名的對應信息,那隻能說明一個問題:這個域名本來就不存在,它沒有在網上正式註冊過。或者賣域名的把它回收掉了(通常是因爲欠費)。

這也就是爲什麼打開一個新頁面會有點慢,因爲本地沒什麼緩存,要這樣遞歸地查詢下去。

多說一句,例如"mp3.baidu.com",域名先是解析出這是個.com的域名,然後跑到管理.com域名的服務器上進行進一步查詢,然後是.baidu,最後是mp3

所以域名結構爲:三級域名.二級域名.一級域名。

瀏覽器終於得到了IP以後,瀏覽器接着給這個IP的服務器發送了一個http請求,方式爲get,例如訪問nbut.cn

這個get請求包含了主機(host)、用戶代理(User-Agent),用戶代理就是自己的瀏覽器,它是你的"代理人"Connection(連接屬性)中的keep-alive表示瀏覽器告訴對方服務器在傳輸完現在請求的內容後不要斷開連接,不斷開的話下次繼續連接速度就很快了。其他的顧名思義就行了。還有一個重點是CookiesCookies保存了用戶的登陸信息,在每次向服務器發送請求的時候會重複發送給服務器。Corome上的F12Firefox上的firebug(快捷鍵shift+F5)均可查看這些信息。

發送完請求接下來就是等待迴應了,如下圖:

當然了,服務器收到瀏覽器的請求以後(其實是WEB服務器接收到了這個請求,WEB服務器有iisapache等),它會解析這個請求(讀請求頭),然後生成一個響應頭和具體響應內容。接着服務器會傳回來一個響應頭和一個響應,響應頭告訴了瀏覽器一些必要的信息,例如重要的Status Code2開頭如200表示一切正常,3開頭表示重定向,4開頭,如404,呵呵。響應就是具體的頁面編碼,就是那個<html>......</html>,瀏覽器先讀了關於這個響應的說明書(響應頭),然後開始解析這個響應並在頁面上顯示出來。在下一次CF的時候(不是穿越火線,是http://codeforces.com/),由於經常難以承受幾千人的同時訪問,所以CF頁面經常會出現崩潰頁面,到時候可以點開火狐的firebug或是ChromeF12看看狀態,不過這時候一般都急着看題和提交代碼,似乎根本就沒心情理會這個狀態吧-.-

如果是個靜態頁面,那麼基本上到這一步就沒了,但是如今的網站幾乎沒有靜態的了吧,基本全是動態的。所以這時候事情還沒完,根據我們的經驗,瀏覽器打開一個網址的時候會慢慢加載這個頁面,一部分一部分的顯示,直到完全顯示,最後標籤欄上的圈圈就不轉了。

這是因爲,主頁(index)頁面框架傳送過來以後,瀏覽器還要繼續向服務器發送請求,請求的內容是主頁裏面包含的一些資源,如圖片,視頻,css樣式等等。這些"非靜態"的東西要一點點地請求過來,所以標籤欄轉啊轉,內容刷啊刷,最後全部請求並加載好了就終於好了。

需要說明的是,對於靜態的頁面內容,瀏覽器通常會進行緩存,而對於動態的內容,瀏覽器通常不會進行緩存。緩存的內容通常也不會保存很久,因爲難保網站不會被改動。

 

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