一、單項選擇題
1.下列說法不正確的是:(B)
A.SATA硬盤的速度速度大約為500Mbps/s
B.讀取18XDVD光盤數據的速度為1Gbps
C.前兆以太網的數據讀取速度為1Gpbs
D.讀取DDR3內存數據的速度為100Gbps
解析:有說B的,有說D的,B肯定是不對的吧。
關於B選項:
理論上講:DVD的1倍速是1350KB/s,CD是150KB/s,DVD的1倍速等於CD的9倍速。
因為CD容量是700MB左右,DVD單面單層(DVD-5)是4.7GB(實際為4.37GB),DVD單面單層的容量是CD的6.4倍左右,所以,1倍速的播放器在80分鍾內把一張700MB的CD讀取出來(700MB*1024/150KB/s/60=79.6min),1倍速的播放器在60分鍾內把一張4.7GB的DVD讀出來(4.37GB*1024*1024、1350KB/s/60=56.6min)
DVD的倍速:
1x:(1倍速)基本傳輸速率為1350KB/s。
2x:(2倍速)基本傳輸速率為2700KB/s。
4x:(4倍速)基本傳輸速率為5400KB/s。
18x:(18倍速)基本傳輸速率為24300KB/s=23M。
CD的倍速:
1x(1倍速)基本傳輸速率為150KB/s。
2x(2倍速)基本傳輸速率為300KB/s
4x(4倍速)基本傳輸速率為600KB/s。
8x(8倍速)基本傳輸速率為1200KB/s。
2.(D)不能用於Linux中的進程通信
A.共享內存
B.命名管道
C.信號量
D.臨界區(每個進程訪問臨界資源的那段代碼稱為臨界區;臨界資源就是每次只允許一個進程訪問的共享資源)
解析:
Linux進程間通信的幾種主要手段簡介:
(1)管道及有名管道:管道可用於具有親緣關系的進程間通信;有名管道克服了管道沒有名字的限制,因此,除了具有管道所具有的功能外,它還允許無親緣關系進程間通信;
(2)信號:信號是比較復雜的通信方式,用於通知接收有某種事件發生,除了用於進程間通信外,進程還可以發送信號給進程本身;linux除了支持Unix早期信號語義函數signal外,還支持語義符合Posix標准的信號函數sigaction(實際上,該函數是基於BSD的,BSD為了實現可靠信號機制,又能夠統一對外接口,用sigaction函數重新實現了signal函數);
(3)消息隊列:消息隊列是消息的鏈接表,包括Posix消息隊列和system V消息隊列。有足夠權限的進程可以向隊列中添加消息,被賦予讀權限的進程則可以讀走隊列中的消息。消息隊列客服了信號承載信息量少,管道只能承載無格式字節流以及緩沖區大小受限等缺點;
(4)共享內存:使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。是針對其他通信機制運行效率較低而設計的。往往與其他通信機制,如信息量結合使用,來達到進程間的同步及互斥;
(5)信息量:主要作為進程間以及同一進程不同線程之間的同步手段;
(6)套接口:更為一般的進程間通信機制,可用於不同機器之間的進程間通信。
Linux線程間通信幾種主要通信手段簡介:
(1)鎖機制:包括互斥鎖、條件變量、讀寫鎖,互斥鎖提供了以排他方式防止數據結構被並發修改的方法,使用條件變量可以以原子的方式阻塞線程,直到某個特定條件為真為止。對條件的測試是在互斥鎖的保護下進行的,條件變量始終與互斥鎖一起使用。讀寫鎖運行多個線程同時讀共享數據,而對寫操作是互斥的;
(2)信號量機制:包括無名線程信號量和命名線程信號量;
(3)信號機制:類似於進程間的信號處理;
進程與線程的區別:
進程概念:
進程是表示資源分配的基本單位,又是調度運行的基本單位。例如,用戶運行自己的程序,系統就創建一個進程,並為它分配資源。然后,把該進程放入進程的就緒隊列。進程調度程序選中它,為它分配CPU以及其他有關子亞U年,該進程才真正運行。所以,進程是系統中並發執行的單位。
線程的概念:
線程是進程中執行運算的最小單位,亦即執行處理機調度的基本單位。如果把進程理解為在邏輯上操作系統所完成的任務,那么線程表示完成該任務的許多子任務之一。線程可以在處理器上獨立調度執行,這樣,在多處理器環境下就允許幾個線程各自在單獨處理器上進行。
引入線程的好處:
(1)易於調度。
(2)提高並發性。通過線程可方便有效地實現並發性。進程可創建多個線程來執行同一程序的不同部分。
(3)開銷少。創建線程比創建進程要快,所需開銷很少。
(4)利於充分發揮多處理器的功能。通過創建多線程進程(即一個進程可具有兩個或更多個線程),每個線程在一個處理器上運行,從而實現應用程序的並發性,使每個處理器都得到充分運行。
進程和線程的關系:
(1)一個線程只能屬於一個進程,而一個進程可以有多個線程,但至少有一個線程。
(2)資源分配給進程,同一進程的所有線程共享該進程的所有資源。
(3)處理機分給線程,即真正在處理機上運行的是線程。
(4)線程在執行過程中,需要協作同步。不同進程的線程間要利用消息通信的辦法實現同步。
3.設在內存中有P1,P2,P3三道程序,並按照P1,P2,P3的優先級次序運行,其中內部計算和IO操作時間由下表給出(CPU計算和IO資源都只能同時由一個程序占用):
P1:計算60ms---》IO 80ms---》計算20ms
P2:計算120ms---》IO 40ms---》計算40ms
P3:計算40ms---》IO 80ms---》計算40ms
完成三道程序比單道運行節省的時間是(C)
A.80ms B.120ms C.160ms D.200ms
解析:
單道運行的總時間為:60+80+20+120+40+40+40+80+40=520ms
4.兩個等價線程並發的執行下列程序,a為全局變量,初始為0,假設printf、++、--操作都是原子性的,則輸出不肯哪個是(A)
1 void foo() { 2 3 if(a <= 0) { 4 5 a++; 6 7 } 8 9 else { 10 11 a--; 12 13 } 14 15 printf("%d", a); 16 17 }
A.01 B.10 C.12 D.22
解析:
對於B選項:P1執行程序,輸入1,P2執行程序,輸出0;
對於C選項:初始為0,P1執行完判斷語句,決定要執行a++,中斷,P2進行判斷,此時a仍然等於0,執行判斷語句,並執行輸入,得到1,P1然后繼續執行,此時它該執行a++,這時a=1,執行並輸出,結果為2;
對於D答案:初始為0,P1執行完判斷語句,決定要執行a++,中斷,P2進行判斷,此時a仍然等於0,執行a++,得到a=1,中斷,P1繼續執行a++,a=2,P1輸出,得到2,P1結束,P2繼續執行輸出語句,得到2;
5.給定fun函數如下,那么fun(10)的輸出結果是(C)
int fun(int x)
{
return (x==1) ? 1 : (x + fun(x-1));
}
A.0 B.10 C.55 D.3628800
6.在c++程序中,如果一個整型變量頻繁使用,最好將他定義為(D)
A.auto B.extern C.static D.register
解析:
C語言提供了四種類型修飾符:auto、register、extern、static。
auto修飾僅在語句塊內使用,初始化可為任何表達式,其特定是當執行流程進入該語句塊的時候執行初始化操作,沒有默認值;
使用register修飾符修飾變量,將暗示編譯程序相應的變量被頻繁地使用,如果可能的話,應將其保存到CPU的寄存器,以加快其存儲速度;
static靜態變量聲明符。在聲明它的語句塊、子程序塊或函數內部有效,值保持,在整個程序期間分配存儲器空間,編譯器默認值為0,。是C/C++中很常用的修飾符,它被用來控制變量的存儲方式和可見性。Static被引入以告知編譯器,將變量存儲在程序的靜態存儲區而非棧上空間。
extern可以置於變量或者函數前,以表示變量或者函數的定義在別的文件中,提示編譯器遇到此變量或函數時,在其他模塊中尋找其定義。另外,extern也可用來進行鏈接指定。
7.長為n的字符串中匹配長度為m的子串的復雜度為(B)
A.O(N) B.O(M+N) C.O(N+LOGM) D.O(M+LOGN)
解析:有選B的,也有選C的。
這道題目首先想到的是KMP算法,時間復雜度為O(m+n)。但是還有的選擇C選項,貌似是Sunday算法。
8.判斷一包含n個整數a[]中是否存在i、j、k滿足a[i] + a[j] = a[k]的時間復雜度為(B)
A.O(n) B.O(n^2) C.O(nlog(n)) D.O(n^2log(n))
解析:
對於B選項,可以這樣實現。
(1)先對數組進行排序,時間為O(nlogn),然后從大往小取a[k],n次
然后在0到k-1之間夾出i,j來...每次K操作...若存在負數,則需要在0到n-1之間夾出i,j;
(2)先對數組進行排序,時間為O(nlogn),然后兩次for循環嵌套,進行hash查找;
對於D選項,可以這樣實現。
(1)先對數組進行排序,時間為O(nlogn),然后兩個for循環嵌套,二分查找a[i]+a[j]是否在數組中;
9.三次射擊能中一次的概率是0.95,請問一次射擊能中的概率是多少?(C)
A.0.32 B.0.5 C.0.63 D.0.85
解析:
公式很簡單,1-(1-p)^3=0.95。接下來需要有一定的估算技巧。A選項可以看作1/3,C選項可以看作2/3,D選項可以看作4/5.
10.下列序排算法中最壞復雜度不是n(n-1)/2的是(D)
A.快速序排 B.冒泡序排 C.直接插入序排 D.堆序排
解析:
各種排序算法的時間復雜度:
插入排序思想:
將n個元素的數列分為已有序和無序兩個部分,每次處理就是講無序數列中的第一個元素與有序數列的元素從后往前逐個進行比較,找到插入位置,將該元素插入到有序數列的合適位置。
希爾排序思想:
希爾排序,也稱為遞減增量排序算法,是插入排序的一種高速而穩定的改進版本。
希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
(1)插入排序在對幾乎已經排好序的數據操作時,效率高,即可達到線性排序的效率;
(2)但插入排序一般來說是低效的,因為插入排序每次只能將數據移動一位;
選擇排序思想:
首先在未排序的序列中找到最大(小)元素,存放到排序序列的起始位置,然后再從剩余未排序元素中繼續尋找最大(小)元素,然后放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。
二、不定向選擇題
1.以下哪些進程狀態轉換是正確的(ABCE)
A.就緒到運行 B.運行到就緒 C.運行到阻塞 D.阻塞到運行 E.阻塞到就緒
解析:
進程調度:
四種進程間的狀態轉換:
就緒—>執行 執行—>阻塞 阻塞—>就緒 執行—>就緒
1)進程的三種基本狀態
進程在運行中不斷地改變其運行狀態。通常,一個進程必須具有以下三種基本狀態:
就緒狀態:
當進程已分配到除CPU以外的所有必要的資源,只要獲得處理機便可立即執行,這時的進程狀態就稱為就緒狀態;
執行狀態:
當進程已獲得處理機,其程序正在處理機上執行,此時的進程狀態稱為執行狀態;
阻塞狀態:
正在執行的進程,由於等待某個事件發生而無法執行時,便放棄處理機而進入阻塞狀態。引起進程阻塞的事件有很多種,例如,等待I/O完成、申請緩沖區不能滿足、等待信號等。
2)進程三種狀態間的轉換
一個進程在運行期間,不斷地從一種狀態轉換到另一種狀態,它可以多次處於就緒狀態和執行狀態,也可以多次處於阻塞狀態。
A. 就緒—>執行
處於就緒狀態的進程,當進程調度程序為之分配好了處理機后,該進程便由就緒狀態轉換為執行狀態;
B. 執行—>就緒
處於執行狀態的進程在其執行過程中,因分配給它的一個時間片已經用完而不得不讓出處理機,於是進程從執行狀態轉換為就緒狀態;
C. 執行—>阻塞
正在執行的進程因等待某種事件發生而無法繼續執行時,便從執行狀態變成阻塞狀態;
D. 阻塞—>就緒
處於阻塞狀態的進程,若其等待的事件已經發生,於是進程便從阻塞狀態轉變為就緒狀態。
4.A和B晚上無聊就開始數星星。每次只能數K個(20<=k<=30)A和B輪流數。最后誰把星星數完誰就獲勝,那么當星星數量為多少時候A必勝?()
A、2013 B、2888 C、4062 D、*** E、****
解析:不懂
對於上述答案,A有必勝的策略,A、B、C、D、E都應該選擇。首先,A選取,使剩余的星星為50的倍數。然后數星星的順序為B、A、B、A......。B數k個星星,則A就數50-k個,使剩余星星始終剩余為50的倍數,最后,一定是A數最后的星星。A必勝。
三、填空問答題
1.給你一個整型數組A[N],完成一個小程序代碼(20行之內),使得A[N]逆向,即原數組為1,2,3,4,逆向之后為4,3,2,1。
3.有個苦逼的上班族,他每天忘記定鬧鍾的概率為0.2,上班堵車的概率為0.5,如果他既沒定鬧鍾上班又堵車那他遲到的概率為1.0,如果他定了鬧鍾但是上班堵車那他遲到的概率為0.9,如果他沒定鬧鍾但是上班不堵車他遲到的概率為0.8,如果他既定了鬧鍾上班又不堵車那他遲到的概率為0.0,那么求出他在60天里上班遲到的期望。
解析:概率為0.54 (說明:先前此處寫的是0.51,若帶來誤導,這里對各位說聲抱歉,對不起)
4.戰報交流:戰場上不同的位置有N個戰士(n>4),每個戰士知道當前的一些戰況,現在需要這n個戰士通過通話交流,互相傳達自己知道的戰況信息,每次通話,可以讓通話的雙方知道對方的所有情報,設計算法,使用最少的通話次數,是的戰場上的n個士兵知道所有的戰況信息,不需要寫程序代碼,得出最少的通話次數。
解析:
筆試的時候是這樣想的:N-1個人圍成一個環,將知道的消息都告訴第N個人,需要N-1次,同時第N-1個人與第N個人交流時,兩人互相交流消息,這樣子第N-1個人與第N個人都知道了所有人的信息,接下來第N-1人沿着環將消息傳遞下去,需要N-2次,所以需要N-1+(N-2)=2N-3。
但是實際上這個問題有着更優的解法。
擴展的一類問題:
題目:假如我們班有n個MM,每一個MM都有一個獨家的八卦消息。兩個MM可以通過電話聯系,一通電話將使得雙方都獲知對方目前已經知道的全部消息。要想所有n個MM都知道所有n條八卦消息,最少需要多少通電話?請給出通話方案。
來自:http://www.matrix67.com/blog/archives/1078
解答:
(1)分析情況
當n很小時我們很容易通過枚舉的方法找出最佳通話方案:
A1=0 A2=1 A3=3 A4=4 A5=6 A6=8
(2)基於中間消息傳遞人的思想建模
可以先把所有消息集中於一個或幾個人,然后再由這些消息匯總人把消息傳給所有人。設n個MM中有m個消息匯總人,她們共享所有消息需要打An通電話。
通話方案如下:
第一、剩下的n-m個MM每個人從m個消息匯總人中隨機選擇一個通話。這樣一來m個消息匯總人就掌握所有n條八卦消息,並且她們每個人所掌握的消息互不重疊,是互補的;
第二、m個消息匯總人通過打電話共享所有八卦消息;
第三、作為消息匯總人的m個MM再通過電話將自己新得到八卦新聞告知最開始打電話給自己的MM,使得她們也掌握所有n條消息;
模型如下:
(3)模型分析
按照上面的通話方案,第一步需要n-m通電話,第二步需要Am通電話,第三步需要n-m通電話,故有An=2*(n-m)+Am,進一步化簡得
An=2*n - (2*m - Am)
即當MM的個數為n時,共享所有八卦消息共需要2*n - (2*m - Am)通電話。若要使得通話次數最小,就要求(2*m - Am)最大。因此,取多少個MM作為消息匯總人使得(2*m - Am)最大成為了解決這個問題的關鍵,它反映了MM們之間通話的效率。記Em=(2*m - Am)。
當有一個消息匯總人即m=1時,E1=2*1 - A1=2;
當有兩個消息匯總人即m=2時,E2=2*2 - A2=3;
m=3時,E3=2*3 - A3=3;
m=4時,E4=2*4 - A4=4;
m=5時,E5=2*5 - A5=4;
m=6時,E6=2*6 - A6=4;
.......
由歸納法可知,當m>=4時,Em有最大值4,An有最小值2*n - 4,即當有大於或等於4個消息匯總人時可通過上述通話方案使得n個MM通過最小的電話數共享所有八卦消息。此時共需要2*n - 4次電話。
(4)模型證明
http://blog.csdn.net/linygood/article/details/8898844
(5)模型結果
題目中如果告訴n大於4,那么結果就是2n-4。
5.有N個人,其中一個明星和n-1個群眾,群眾都認識明星,明星不認識任何群眾,群眾和群眾之間的認識關系不知道,現在如果你是機器人R2T2,你每次問一個人是否認識另外一個人的代價為O(1),試設計一種算法找出明星,並給出時間復雜度(沒有復雜度不得分)。
解答:
這個問題等價於找未知序列數中的最小數,我們將reg這個函數等價為以下過程:如果i認識j,記作i大於等於j,同樣j不一定大於等於i,滿足要求,i不認識j記作i<j,對明星k,他不認識所有人,則k是其中最小的數,且滿足其余的人都認識他,也就是其余的人都大於等於k.這樣問題就被轉換了。就拿N=5來說,首先有數組S[5]={A,B,C,D,E}這5個變量,里邊存放着隨機數,求是否存在唯一最小數,如果存在位置在S中的哪里。(樓主這里是這個意思,按我的理解題中這個最小數一定是存在且唯一的)。
另外一種思路:
四、綜合題
有一個淘寶商戶,在某城市有n個倉庫,每個倉庫的儲貨量不同,現在要通過貨物運輸,將每次倉庫的儲貨量變成一致的,n個倉庫之間的運輸線路圍城一個圈,即1->2->3->4->...->n->1->...,貨物只能通過連接的倉庫運輸,設計最小的運送成本(運貨量*路程)達到淘寶商戶的要求,並寫出代碼。
解答:
這個題目類似的題目有:
題目:http://www.lydsy.com/JudgeOnline/problem.php?id=1045
有n個小朋友坐成一圈,每人有ai個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞一個糖果代價為1,求使所有人獲得均等糖果的最小代價。
分析:
假設a1分給an的糖果數為k,則可以得到以下的信息:
a1 a2 a3 an-1 an
當前數目:a1-k a2 a3 an-1 an+k
所需代價:|a1-k-ave| |a1+a2-k-2*ave| |a1+a2+a3-k-3*ave||a1+..+a(n-1)-k-(n-1)*ave| |k|
以sum[i]表示從a1加到ai減掉i*ave的和值,這以上可以化簡為
總代價 = |s1-k|+|s2-k|+...+|s(n-1)-k|+|k|
不難看出:當k為s1...s(n-1)中的中位數的時候,所需的代價最小