1. 程式人生 > >搜狗2012 9 23校園招聘會筆試題

搜狗2012 9 23校園招聘會筆試題

               
class Base{public: Base(int j) : i(j) {  }  virtual ~Base() {  } void func1() {  i *= 10;  func2(); } int getValue() {  return i; }protectedvirtual void func2() {  i++; }protectedint i;};class Child : public Base{public: Child(int j) : Base(j) {  } void func1() {  i *= 100;  func2(); }protectedvoid
func2() 
{  i += 2; }};int main(void){ Base *pb = new Child(1); pb->func1(); cout<<pb->getValue()<<endldelete pb;  return 0;}
2、請問程式的輸出結果是(30)#define DOUBLE(x) x+x // x*2int i = DOUBLE(5)*5;cout<<i<<endl;3、寫出一下程式的輸出(死迴圈
int main(void)char num; for(num = 0; num < 255; )  num += num; printf
("%d\n",num); return 0;}
4、程式出錯在什麼階段?()
int main(void){ http://www.sogou.com cout<<"welcome to sogou"<<endl;  return 0;}
A、編譯階段出錯     B、執行階段出錯     C、編譯和執行都出錯    D、程式執行正常因為http://www.sogou.com中//後面是註釋,前面的http:是標籤(類似於goto語句中的標籤)。(這個題目碉堡了)5、下面程式執行結果為【說明:X86_64環境】(D)
int main(void)int a[4][4] = {            {1
,2,3,4},      {50,60,70,80},      {900,1000,1100,1200},      {13000,14000,15000,16000} }; int (*p1)[4] = a; int (*p2)[4] = &a[0]; int *p3 = &a[0][0]; printf("%d %d %d %d\n",*(*(a+1)-1),*(*(p1+3)-2)+1,*(*(p2-1)+16)+2,*(p3+sizeof(p1)-3));  return 0;}
A、16000 1101  13002 2B、4  2  3  60C、16000  2  3  2D、4  1101  13002  60p1為指向一維陣列的指標,所以a + 1指向{50,60,70,80}這一維的地址。減一則為4的地址;同理第二個輸出1101。同理,由於陣列的列是4,所以*(p2 - 1) + 16就相當於*(p2) + 12,所以第三個輸出13002。第四個由於p1是指標,所以sizeof(p1)為8(68位的系統),所以第四個輸出60。6、在32位作業系統gcc編譯器環境下,下面的程式的執行結果是(A)
class A{publicint b; char c; virtual void print() {  cout<<"this is father's function!"<<endl; }};class B : A{publicvirtual void print() {  cout<<"this is children's function!"<<endl; }};int main(void)cout<<sizeof(A)<<"  "<<sizeof(A)<<endl;  return 0;}
A、12  12B、8  8C、9  9D、12  167、以下哪些做法是不正確或者應該極力避免的:【多選】(ACD)A、建構函式宣告為虛擬函式B、派生關係中的基類解構函式宣告為虛擬函式C、建構函式呼叫虛擬函式D、解構函式呼叫虛擬函式8、關於C++標準模板庫,下列說法錯誤的有哪些:【多選】(AD)A、std::auto_ptr<Class A>型別的物件,可以放到std::vector<std::auto_ptr<Class A>>容器中B、std::shared_ptr<Class A>型別的物件,可以放到std::vector<std::shared_ptr<Class A>>容器中C、對於複雜型別T的物件tObj,++tObj和tObj++的執行效率相比,前者更高D、採用new操作符建立物件時,如果沒有足夠記憶體空間而導致建立失敗,則new操作符會返回NULLA中auto是給別人東西而自己沒有了。所以不符合vector的要求。而B可以。C不解釋。new在失敗後丟擲標準異常std::bad_alloc而不是返回NULL。9、有如下幾個類和函式定義,選項中描述正確的是:【多選】(B)
class A{publicvirtual void foo()   { }};class B{publicvirtual void foo()   { }};class C : public A , public B{publicvirtual void foo()   { }};void bar1(A *pa){ B *pc = dynamic_cast<B*>(pa);}void bar2(A *pa){ B *pc = static_cast<B*>(pa);}void bar3(){ C c; A *pa = &c; B *pb = static_cast<B*>(static_cast<C*>(pa));}
A、bar1無法通過編譯B、bar2無法通過編譯C、bar3無法通過編譯D、bar1可以正常執行,但是採用了錯誤的cast方法選B。dynamic_cast是在執行時遍歷繼承樹,所以,在編譯時不會報錯。但是因為A和B沒啥關係,所以執行時報錯(所以A和D都是錯誤的)。static_cast:編譯器隱式執行的任何型別轉換都可由它顯示完成。其中對於:(1)基本型別。如可以將int轉換為double(編譯器會執行隱式轉換),但是不能將int*用它轉換到double*(沒有此隱式轉換)。(2)對於使用者自定義型別,如果兩個類無關,則會出錯(所以B正確),如果存在繼承關係,則可以在基類和派生類之間進行任何轉型,在編譯期間不會出錯。所以bar3可以通過編譯(C選項是錯誤的)。10、在Intel CPU上,以下多執行緒對int型變數x的操作,哪幾個不是原子操作,假定變數的地址都是對齊的。【多選】(ABC)A、x = y   B、x++     C、++x     D、x = 1看下在VC++6.0下的彙編命令即可:從圖可以看出本題只有D選項才是原子操作。11、一般情況下,下面哪些操作會執行失敗?【多選】(BCD)
class A{publicstring a; void f1() {  printf("Hello World"); } void f2() {  a = "Hello World";  printf("%s",a.c_str()); } virtual void f3() {  printf("Hello World"); } virtual void f4() {  a = "Hello World";  printf("%s",a.c_str()); }};
A、A *aptr = NULL;  aptr->f1();B、A *aptr = NULL;  aptr->f2();C、A *aptr = NULL;  aptr->f3();D、A *aptr = NULL;  aptr->f4();至於A為什麼正確,因為A沒有使用任何成員變數,而成員函式是不屬於物件的,所以A正確。其實,A* aptr = NULL;aptr->f5();也是正確的,因為靜態成員也是不屬於任何物件的。至於BCD,在B中使用了成員變數,而成員變數只能存在於物件,C有虛表指標,所以也只存在於物件中。D就更是一樣了。但是,如果在Class A中沒有寫public,那麼就全都是private,以至於所有的選項都將會失敗。12、C++下,下面哪些template例項化使用,會引起編譯錯誤?【多選】(CEF)
template<class Type> class stack;void fi(stack<char>);      //Aclass Ex{ stack<double> &rs;    //B stack<int> si;        //C};int main(void)stack<char> *sc;      //D fi(*sc);              //E int i = sizeof(stack<string>);    //F  return 0;}
選C E F;  請注意stack和fi都只是宣告不是定義。我還以為在此處申明後,會在其他地方定義呢,坑爹啊。由於stack只是宣告,所以C是錯誤的,stack不能定義物件。E也是一樣,stack只是申明,所以不能執行拷貝建構函式,至於F,由於stack只是宣告,不知道stack的大小,所以錯誤。如果stack定義了,將全是正確的。13、以下哪個說法正確()
int func()char b[2]={0}; strcpy(b,"aaa");}
A、Debug版崩潰,Release版正常B、Debug版正常,Release版崩潰C、Debug版崩潰,Release版崩潰D、Debug版正常,Release版正常選A。因為在Debug中有ASSERT斷言保護,所以要崩潰,而在Release中就會刪掉ASSERT,所以會出現正常執行。但是不推薦如此做,因為這樣會覆蓋不屬於自己的記憶體,這是搭上了程式崩潰的列車。資料結構類37、每份考卷都有一個8位二進位制序列號,當且僅當一個序列號含有偶數個1時,它才是有效的。例如:00000000 01010011 都是有效的序列號,而11111110不是,那麼有效的序列號共有(128)個。38、對初始狀態為遞增序列的陣列按遞增順序排序,最省時間的是插入排序演算法,最費時間的演算法(B)A、堆排序  B、快速排序   C、插入排序   D、歸併排序39、下圖為一個二叉樹,請選出以下不是遍歷二叉樹產生的順序序列的選項【多選】(BD)A、ABCDEFIGJHB、BDCAIJGHFEC、BDCAIFJGHED、DCBJHGIFEA40、在有序雙向連結串列中定位刪除一個元素的平均時間複雜度為()A、O(1)   B、O(N)   C、O(logN)      D、O(N*logN) 41、將10階對稱矩陣壓縮儲存到一維陣列A中,則陣列A的長度最少為()A、100     B、40     C、55      D、8042、將陣列a[]作為迴圈佇列SQ的儲存空間,f為隊頭指示,r為隊尾指示,則執行出隊操作的語句為(B)A、f = f+1     B、f = (f+1)%m      C、r = (r+1)%m     D、f = (f+1)%(m+1)43、以下哪種操作最適合先進行排序處理?A、找最大、最小值   B、計算算出平均值   C、找中間值  D、找出現次數最多的值44、設有一個二維陣列A[m][n],假設A[0][0]存放位置在644(10),A[2][2]存放位置在676(10),每個元元素佔一個空間,問A[3][3]存放在什麼位置?(C)腳註(10)表示用10進製表示A、688     B、678     C、692     D、69645、使用下列二維圖形變換矩陣A=T*a,將產生的變換結果為(D)A、圖形放大2倍B、圖形放大2倍,同時沿X、Y座標軸方向各移動一個單位C、沿X座標軸方向各移動2個單位D、沿X座標軸放大2倍,同時沿X、Y座標軸方向各移動一個單位46、體育課的鈴聲響了,同學們都陸續地奔向操場,按老師的要求從高到矮站成一排。每個同學按順序來到操場時,都從排尾走向排頭,找到第一個比自己高的同學,並站到他的後面,這種站隊的方法類似於()演算法。A、快速排序      B、插入排序      C、氣泡排序    D、歸併排序47、處理a.html檔案時,以下哪行虛擬碼可能導致記憶體越界或者丟擲異常(B)         int totalBlank = 0;         int blankNum = 0;         int taglen = page.taglst.size();A       for(int i = 1; i < taglen-1; ++i)        {                 //check blankB             while(page.taglst[i] == "<br>" && i < taglen)               {C                       ++totalBlank;D                       ++i;               }E             if(totalBlank > 10)F                      blankNum += totalBlank;G             totalBlank = 0;        }注意:以下程式碼中taglen是html檔案中存在元素的個數,a.html中taglen的值是15,page.taglst[i]取的是a.html中的元素,例如page.taglst[1]的值是<html>a.html的檔案如下:<html><title>test</title><body><div>aaaaaaa</div></body></html><br><br><br><br><br>48、對一個有向圖而言,如果每個節點都存在到達其他任何節點的路徑,那麼就稱它是強連通的。例如,右圖就是一個強連通圖,事實上,在刪掉哪幾條邊後,它依然是強連通的。(A)A、a       B、b        C、c             D、d100、一種計算機,其有如下原子功能:1、賦值   a=b2、+1操作,++a; a+1;3、迴圈,但是隻支援按次數的迴圈   for(變數名){/*迴圈裡面對變數的修改不影響迴圈次數*/}4、只能處理0和正整數5、函式呼叫    fun(引數列表)請用虛擬碼的形式分別在這個計算機上程式設計實現變數的加法、減法、乘法。fun_add(a , b){}fun_multi(a , b){}fun_minus(a , b){}問題的關鍵在於如何實現自減一操作。本來讓-1自增n次即可實現n的自減的,但系統偏偏又不支援負數。
fun_add(a , b){ result = a; for(b)  ++result; return result;}fun_muti(a , b){ result = 0for(b)  result = fun_add(result , a); return result;}dec(int n){ temp = 0; result = 0for(n) {  result = temp;   //result永遠比temp少1,巧妙地減少了一次自增  ++temp; } return result;}/*上面的dec這段函式程式碼執行後,result的值將變為n-1。注意到這段程式碼在自增時是如何巧妙地延遲了一步的。現在,我們相當於有了自減一的函式dec。實現a-b只需要令a自減b次即可*/fun_minus(a , b){ result = a; for(b)  result = dec(result);}
101、實現一個隊連結串列排序的演算法,C/C++可以使用std::list<int>,Java使用LinkedList<Integer>要求先描述演算法,然後再實現,演算法效率儘可能高效。主要考察連結串列的歸併排序。要點:需要使用快、慢指標的方法,找到連結串列的的中間節點,然後進行二路歸併排序
typedef struct LNode{ int data; struct LNode *next;}LNode , *LinkList;// 對兩個有序的連結串列進行遞迴的歸併LinkList MergeList_recursive(LinkList head1 , LinkList head2){ LinkList result; if(head1 == NULL)  return head2; if(head2 == NULL)  return head1; if(head1->data < head2->data) {  result = head1;  result->next = MergeList_recursive(head1->next , head2); } else {  result = head2;  result->next = MergeList_recursive(head1 , head2->next); } return result;}// 對兩個有序的連結串列進行非遞迴的歸併LinkList MergeList(LinkList head1 , LinkList head2){ LinkList head , result = NULLif(head1 == NULL)  return head2; if(head2 == NULL)  return head1; while(head1 && head2) {  if(head1->data < head2->data)  {   if(result == NULL)   {    head = result = head1;    head1 = head1->next;   }   else   {    result->next = head1;    result = head1;    head1 = head1->next;   }  }  else  {   if(result == NULL)   {    head = result = head2;    head2 = head2->next;   }   else   {    result->next = head2;    result = head2;    head2 = head2->next;   }  } } if(head1)  result->next = head1; if(head2)  result->next = head2; return head;}// 歸併排序,引數為要排序的連結串列的頭結點,函式返回值為排序後的連結串列的頭結點LinkList MergeSort(LinkList head)if(head == NULL)  return NULL; LinkList r_head , slow , fast; r_head = slow = fast = head; // 找連結串列中間節點的兩種方法 /* while(fast->next != NULL) {  if(fast->next->next != NULL)  {   slow = slow->next;   fast = fast->next->next;  }  else   fast = fast->next; }*/ while(fast->next != NULL && fast->next->next != NULL) {  slow = slow->next;  fast = fast->next->next; }  if(slow->next == NULL)    // 連結串列中只有一個節點  return r_head; fast = slow->next; slow->next = NULL; slow = head; // 函式MergeList是對兩個有序連結串列進行歸併,返回值是歸併後的連結串列的頭結點 //r_head = MergeList_recursive(MergeSort(slow) , MergeSort(fast)); r_head = MergeList(MergeSort(slow) , MergeSort(fast)); return r_head;}