總體而言,這份筆試題還比較正常,只是這次做題采取的方式不對,最后的綜合題有20分但是沒仔細看就沒時間了, 還是要總結經驗教訓。就其它題目而言,這次倒都沒什么難度,有些可以預料的會考的是排序、多線程、操作系統、概率問題和C的基本知識。趁着腦袋里面還記着一些題目,我把一些我有印象的記錄下來供各位參考。 阿里筆試竟然沒考大數據,神奇!
一、單項選擇題
1.下列說法錯誤的是:
A.SATA硬盤的速度大約為500Mbps
B.讀取18XDVD光盤數據的速度為1Gbps
C.千兆以太網的數據讀取速度為1Gpbs
D.讀取DDR3內存數據的速度為100Gbps
思路:這種題目看似要是記住了就好了,其實記住常識就好了, 首先,C肯定是對的,因為就是定義嘛,內存比較快比較正常,所以D應該是對的,500Mbps大概就是62.5M/s的傳輸速度,顯然符合我們對硬盤的預期,於是B顯然是錯的,光盤怎么可能有硬盤快。
如果要嚴格意義上分析這個題目的意思的話,SATA 3.0的速度約為600Mbps,18XDVD前面的18X是倍速的意思,1X約為150KB/s(1.2288Mbps),18X最多不過24Mbps,所以說B太離譜了,至於DDR3,可以看到,DDR3-2133的極限傳輸速度大概150Gbps。
2.()不能用於Linux中的進程通信
A.共享內存
B.命名管道
C.信號量
D.臨界區
思路:見深刻理解Linux進程間通信,需要注意的是,這個題目要是概念清楚點就沒啥問題了,臨界區是保證在某一時刻只有一個線程能訪問數據的方法,也就是說它是實現進程同步互斥的控制機制,信號量雖然也能用來控制進程線程的同步互斥,但是~
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
完成三道程序比單道運行節省的時間是()
A.80ms
B.120ms
C.160ms
D.200ms
思路:沒什么好解釋的
4. 兩個等價線程並發的執行下列程序,a為全局變量,初始為0,假設printf、++、--操作都是原子性的,則輸出不可能是()
void foo() {
if(a <= 0) {
a++;}else{
a--;}printf("%d", a);}A.01
B.10
C.12
D.22
思路:當時我的直覺告訴我應該選奇數,回來想了一下,好像得到了答案:看答案可知每個線程進foo函數不止一次,那么我們暫且假設兩個線程分別進入foo函數X次,假設給線程編號,線程1有m次被堵在a++,線程2有n次被堵在a++處,那么線程1必然會執行(X-m)次a- -,線程2必然會執行(X-n)次a- -,那么最終a的值為(m+n)-((X-m)+(X-n))=2(m+n)-2X,也就是說a最后的值必然是偶數
5.給定fun函數如下,那么fun(10)的輸出結果是()
int fun(intx)
{return(x==1)? 1 : (x + fun(x-1));
}A.0
B.10
C.55
D.3628800
思路:10+9+…+1=55
6.在c++程序中,如果一個整型變量頻繁使用,最好將他定義為()
A.auto
B.extern
C.static
D.register
思路:寄存器快嘛,而且整型也正好能放進寄存器,詳見變量的存儲類型
7.長為n的字符串中匹配長度為m的子串的復雜度最短為()
A.O(N)
B.O(M+N)
C.O(N+LOGM)
D.O(M+LOGN)思路:KMP算法的時間復雜度是O(M+N),但是BM算法會相對而言更快,但是也是O(M+N)。當時選的是B,但是加個“最”總讓人不放心,回來查看資料,用后綴數組的方法可以在O(M+LOGN)時間內完成,但是這沒有包含后綴數組預處理所需的時間(一般為NLOGN)。(ps:以后如果不確定還是跟着直覺走吧)
8.判斷一包含n個整數a[]中是否存在i、j、k滿足a[i] + a[j] = a[k]的最小的時間復雜度為()
A. O(n3) B.O(n2lgn) C.O(n2) D.O(nlgn)
思路:O(N2)的算法能想一大堆,雖然最終我選的C,比如說用hash的話,三維遍歷可以輕松編程二維遍歷,但是總感覺是不是應該有nlgn的算法。
9.三次射擊至少能中一次的概率是0.95,請問一次射擊能中的概率是多少?
A.0.63B.0.5
C.**
D.0.85
思路:簡單的概率計算,1-(1-P)3 =0.95
10.下列序排算法中最壞復雜度不是n(n-1)/2的是_
A.快速排序 B.冒泡排序 C.直接插入排序 D.堆排序
思路:由堆排序的過程可知堆排序最好最壞的時間復雜度都是O(NlgN)
二、不定項選擇題
1.阻塞、就緒、運行的三態轉換
2.一個棧的入棧序列是:1,2,3,4,5,6,問下面的答案哪個是可能的出棧順序?
思路:入棧出棧,沒什么好說的。但是從這個題目就可以知道阿里這次出題的水平一般,好多題目給的條件都不嚴謹,比如說這題,棧大小限定不限定也不說。
3.不用中間變量交換兩個整型數字的值
4.無聊的人數星星
A和B很無聊,然后數天上的星星(所以還真是無聊),然后每個人能力有限,每次只能數K顆星星,其中20<=K<=30,A先數,B接着數,誰先數完最后一批誰贏,問星星有多少顆的時候能保證A先數總是能贏。答案有五個選項。
A.2013 B.2886 C.4026 D......E.....
思路:排除法就好了,如果天上有x顆星星,必定有2n*k<x<=(2n+1)*k,先用k=20排除幾個答案,然后用21排除就只剩一個答案了。貌似我當時排除完之后只剩下E了。
三、填空問答題
1.整型數組的就地逆置:給你一個整型數組A[N],完成一個小程序代碼(20行之內),使得A[N]逆向,即原數組為1,2,3,4,逆向之后為4,3,2,1
void reverse(int * a,int n) {assert(a!=NULL);//當時寫了這么一句,貌似有點畫蛇添足了,因為要求不要用到任何庫
for(int i=0;i<n/2;++i){//swap
a[i]=a[i]+a[n-1-i];a[n-1-i]=a[i]-a[n-1-i];a[i]=a[i]-a[n-1-i];}}
2.多道程序設計與作業調度--先來先服務與短作業優先算法的比較,給定了三個作業,已知三個作業的進入時間,處理時間,作業一旦進入不會被打斷,求周轉時間。
思路:沒啥特別的
3.有個苦逼的上班族,他每天忘記定鬧鍾的概率為0.2,上班堵車的概率為0.5,如果他既沒定鬧鍾上班又堵車那他遲到的概率為1.0,如果他定了鬧鍾但是上班堵車那他遲到的概率為0.9,如果他沒定鬧鍾但是上班不堵車他遲到的概率為0.8,如果他既定了鬧鍾上班又不堵車那他遲到的概率為0.0,那么求出他在60天里上班遲到的期望。
思路:按照概率一步步算就好了,先求出每天遲到的概率。
4.士兵戰報交換:有n個士兵,每個士兵知道一些不同的戰報,n>4,每個戰士都知道一些不同的戰報,戰士之間可以通過比如說打電話互相交流,交流完成之后二者信息匯總,且兩人都知道所有信息,設計一種交流次數最少的交流算法,使得最后每個士兵都知道所有信息
思路:我當時給出的答案是將n個士兵兩個一組,組內交換信息,然后每組任意選一個出來得到(n+1)/2個士兵,其中每個士兵知道的信息是交換前的2倍,然后將這些士兵再兩兩分組,以此類推,這樣的話,最終會有一個人知道所有的信息,然后依次分發給其余n-1個人即可,需要通話的次數是
+n-1,但是我不確定這樣是不是最快,這篇文章給出了解答,稍微看了一下,思路跟我差不多,只是匯總人的個數作為變量,據說有證明,對這一題不感興趣,最終答案是2n-4.
5.明星和群眾問題:有N個人,其中一個明星和n-1個群眾,群眾都認識明星,明星不認識任何群眾,群眾和群眾之間的認識關系不知道,現在如果你是機器人R2T2,你每次問一個人是否認識另外一個人的代價為O(1),試設計一種算法找出明星,並給出時間復雜度(沒有復雜度不得分)。
思路:從第一個人開始問,問他是不是認識旁邊的人,如果他認識,那么他肯定不是明星,直接把這個人去掉,如果他不認識,那么被問的人肯定不是明星,被問的人從集合中去掉,這樣問一次就可以刪掉一個人,最后剩下的就是明星了,時間復雜度O(N)
四、綜合問題
皇冠用戶倉庫開銷:某淘寶金冠用戶在多個城市有倉庫,每個倉庫的儲貨量不同,現在要通過貨物運輸,將每次倉庫的儲貨量變成一致的,n個倉庫之間的運輸線路圍城一個圈,運輸只能在相鄰的倉庫之間進行,設計最小的運送成本(運貨量*路程)
思路:這個在各種online-judge平台上都有答案,純粹的數學問題,
如圖,這是一個倉庫分布的模擬,假設從第i個倉庫向第i+1個倉庫轉移的物品為Pi個單位,其中Pi為負表示思是從i+1個倉庫轉移到第i個倉庫,第n個倉庫轉移到第一個倉庫即為Pn,設最后每個倉庫平均后的貨物為ave個單位,則有要最小化|P1|+|P2|+…+|Pi|+…+|Pn|
ave[i]=ave=A[i]-Pi+Pi-1
ave[1]=A[1]-P1+Pn
然后設W[i]=ave[i]-A[i]=-Pi+Pi-1
於是S[i]=W[1]+W[2]+….W[i]=Pn-Pi
即Pi=Pn-S[i] ,所以問題歸結到最小化|Pn-S[1]|+|Pn-S[2]|+…+|Pn-S[n]|
所以Pn是S中位數的時候最小
目前能記起來的就這么多了,后面再查吧