感谢支持
我们一直在努力

搜狗2012.9.23校园招聘会笔试题

C/C++类

1、以下程序的输出是(12

  1. class Base 
  2. public
  3.     Base(int j) : i(j) {  }   
  4.     virtual ~Base() {  } 
  5.     void func1() 
  6.     { 
  7.         i *= 10; 
  8.         func2(); 
  9.     } 
  10.     int getValue() 
  11.     { 
  12.         return i; 
  13.     } 
  14. protected
  15.     virtual void func2() 
  16.     { 
  17.         i++; 
  18.     } 
  19. protected
  20.     int i; 
  21. }; 
  22.  
  23. class Child : public Base 
  24. public
  25.     Child(int j) : Base(j) {  } 
  26.     void func1() 
  27.     { 
  28.         i *= 100; 
  29.         func2(); 
  30.     } 
  31. protected
  32.     void func2() 
  33.     { 
  34.         i += 2; 
  35.     } 
  36. }; 
  37.  
  38. int main(void
  39.     Base *pb = new Child(1); 
  40.     pb->func1(); 
  41.     cout<<pb->getValue()<<endl; 
  42.     delete pb; 
  43.      
  44.     return 0; 

2、请问程序的输出结果是(30)
#define DOUBLE(x) x+x // x*2
int i = DOUBLE(5)*5;
cout<<i<<endl;
3、写出一下程序的输出(死循环

  1. int main(void
  2.     char num; 
  3.     for(num = 0; num < 255; ) 
  4.         num += num; 
  5.     printf(“%d\n”,num); 
  6.     return 0; 

4、程序出错在什么阶段?()

  1. int main(void
  2.     http://www.sogou.com  
  3.     cout<<“welcome to sogou”<<endl; 
  4.      
  5.     return 0; 

A、编译阶段出错    B、运行阶段出错    C、编译和运行都出错    D、程序运行正常
因为http://www.sogou.com中//后面是注释,前面的http:是标签(类似于goto语句中的标签)。(这个题目碉堡了)

5、下面程序执行结果为【说明:X86_64环境】(D)

  1. int main(void
  2.     int a[4][4] = { 
  3.                   {1,2,3,4}, 
  4.                   {50,60,70,80}, 
  5.                   {900,1000,1100,1200}, 
  6.                   {13000,14000,15000,16000} }; 
  7.     int (*p1)[4] = a; 
  8.     int (*p2)[4] = &a[0]; 
  9.     int *p3 = &a[0][0]; 
  10.     printf(“%d %d %d %d\n”,*(*(a+1)-1),*(*(p1+3)-2)+1,*(*(p2-1)+16)+2,*(p3+sizeof(p1)-3)); 
  11.      
  12.     return 0; 

A、16000 1101  13002 2
B、4  2  3  60
C、16000  2  3  2
D、4  1101  13002  60
p1为指向一维数组的指针,所以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)

  1. class A 
  2. public
  3.     int b; 
  4.     char c; 
  5.     virtual void print() 
  6.     { 
  7.         cout<<“this is father’s function!”<<endl; 
  8.     } 
  9. }; 
  10.  
  11. class B : A 
  12. public
  13.     virtual void print() 
  14.     { 
  15.         cout<<“this is children’s function!”<<endl; 
  16.     } 
  17. }; 
  18. int main(void
  19.     cout<<sizeof(A)<<”  “<<sizeof(A)<<endl; 
  20.      
  21.     return 0; 

A、12  12
B、8  8
C、9  9
D、12  16
7、以下哪些做法是不正确或者应该极力避免的:【多选】(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操作符会返回NULL
A中auto是给别人东西而自己没有了。所以不符合vector的要求。而B可以。C不解释。new在失败后抛出标准异常std::bad_alloc而不是返回NULL。

9、有如下几个类和函数定义,选项中描述正确的是:【多选】(B)

  1. class A 
  2. public
  3.     virtual void foo()   {  } 
  4. }; 
  5.  
  6. class B 
  7. public
  8.     virtual void foo()   {  } 
  9. }; 
  10.  
  11. class C : public A , public B 
  12. public
  13.     virtual void foo()   {  } 
  14. }; 
  15.  
  16. void bar1(A *pa) 
  17.     B *pc = dynamic_cast<B*>(pa); 
  18.  
  19. void bar2(A *pa) 
  20.     B *pc = static_cast<B*>(pa); 
  21.  
  22. void bar3() 
  23.     C c; 
  24.     A *pa = &c; 
  25.     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)

  1. class A 
  2. public
  3.     string a; 
  4.     void f1() 
  5.     { 
  6.         printf(“Hello World”); 
  7.     } 
  8.     void f2() 
  9.     { 
  10.         a = “Hello World”
  11.         printf(“%s”,a.c_str()); 
  12.     } 
  13.     virtual void f3() 
  14.     { 
  15.         printf(“Hello World”); 
  16.     } 
  17.     virtual void f4() 
  18.     { 
  19.         a = “Hello World”
  20.         printf(“%s”,a.c_str()); 
  21.     } 
  22. }; 

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)

  1. template<class Type> class stack; 
  2. void fi(stack<char>);      //A  
  3. class Ex 
  4.     stack<double> &rs;    //B  
  5.     stack<int> si;        //C  
  6. }; 
  7.  
  8. int main(void
  9.     stack<char> *sc;      //D  
  10.     fi(*sc);              //E  
  11.     int i = sizeof(stack<string>);    //F  
  12.      
  13.     return 0; 

选C E F;  请注意stack和fi都只是声明不是定义。我还以为在此处申明后,会在其他地方定义呢,坑爹啊。
由于stack只是声明,所以C是错误的,stack不能定义对象。E也是一样,stack只是申明,所以不能执行拷贝构造函数,至于F,由于stack只是声明,不知道stack的大小,所以错误。如果stack定义了,将全是正确的。

13、以下哪个说法正确()

  1. int func() 
  2.     char b[2]={0}; 
  3.     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、ABCDEFIGJH
B、BDCAIJGHFE
C、BDCAIFJGHE
D、DCBJHGIFEA
40、在有序双向链表中定位删除一个元素的平均时间复杂度为()
A、O(1)  B、O(N)  C、O(logN)      D、O(N*logN)

41、将10阶对称矩阵压缩存储到一维数组A中,则数组A的长度最少为()
A、100    B、40    C、55     D、80
42、将数组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、696
45、使用下列二维图形变换矩阵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 blank
B            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、d

100、一种计算机,其有如下原子功能:
1、赋值  a=b
2、+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的自减的,但系统偏偏又不支持负数。

  1. fun_add(a , b) 
  2.     result = a; 
  3.     for(b) 
  4.         ++result; 
  5.     return result; 
  6.  
  7. fun_muti(a , b) 
  8.     result = 0; 
  9.     for(b) 
  10.         result = fun_add(result , a); 
  11.     return result; 
  12.  
  13. dec(int n) 
  14.     temp = 0; 
  15.     result = 0; 
  16.     for(n) 
  17.     { 
  18.         result = temp;   //result永远比temp少1,巧妙地减少了一次自增  
  19.         ++temp; 
  20.     } 
  21.     return result; 
  22. /* 
  23. 上面的dec这段函数代码执行后,result的值将变为n-1。注意到这段代码在自增时是如何巧妙地延迟了一步的。 
  24. 现在,我们相当于有了自减一的函数dec。实现a-b只需要令a自减b次即可 
  25. */ 
  26. fun_minus(a , b) 
  27.     result = a; 
  28.     for(b) 
  29.         result = dec(result); 

101、实现一个队链表排序的算法,C/C++可以使用std::list<int>,Java使用LinkedList<Integer>
要求先描述算法,然后再实现,算法效率尽可能高效。
主要考察链表的归并排序。
要点:需要使用快、慢指针的方法,找到链表的的中间节点,然后进行二路归并排序

  1. typedef struct LNode 
  2.     int data; 
  3.     struct LNode *next; 
  4. }LNode , *LinkList; 
  5.  
  6. // 对两个有序的链表进行递归的归并  
  7. LinkList MergeList_recursive(LinkList head1 , LinkList head2) 
  8.     LinkList result; 
  9.     if(head1 == NULL) 
  10.         return head2; 
  11.     if(head2 == NULL) 
  12.         return head1; 
  13.     if(head1->data < head2->data) 
  14.     { 
  15.         result = head1; 
  16.         result->next = MergeList_recursive(head1->next , head2); 
  17.     } 
  18.     else 
  19.     { 
  20.         result = head2; 
  21.         result->next = MergeList_recursive(head1 , head2->next); 
  22.     } 
  23.     return result; 
  24.  
  25. // 对两个有序的链表进行非递归的归并  
  26. LinkList MergeList(LinkList head1 , LinkList head2) 
  27.     LinkList head , result = NULL; 
  28.     if(head1 == NULL) 
  29.         return head2; 
  30.     if(head2 == NULL) 
  31.         return head1; 
  32.     while(head1 && head2) 
  33.     { 
  34.         if(head1->data < head2->data) 
  35.         { 
  36.             if(result == NULL) 
  37.             { 
  38.                 head = result = head1; 
  39.                 head1 = head1->next; 
  40.             } 
  41.             else 
  42.             { 
  43.                 result->next = head1; 
  44.                 result = head1; 
  45.                 head1 = head1->next; 
  46.             } 
  47.         } 
  48.         else 
  49.         { 
  50.             if(result == NULL) 
  51.             { 
  52.                 head = result = head2; 
  53.                 head2 = head2->next; 
  54.             } 
  55.             else 
  56.             { 
  57.                 result->next = head2; 
  58.                 result = head2; 
  59.                 head2 = head2->next; 
  60.             } 
  61.         } 
  62.     } 
  63.     if(head1) 
  64.         result->next = head1; 
  65.     if(head2) 
  66.         result->next = head2; 
  67.     return head; 
  68.  
  69. // 归并排序,参数为要排序的链表的头结点,函数返回值为排序后的链表的头结点  
  70. LinkList MergeSort(LinkList head) 
  71.     if(head == NULL) 
  72.         return NULL; 
  73.     LinkList r_head , slow , fast; 
  74.     r_head = slow = fast = head; 
  75.  
  76.     // 找链表中间节点的两种方法  
  77.     /* 
  78.     while(fast->next != NULL) 
  79.     { 
  80.         if(fast->next->next != NULL) 
  81.         { 
  82.             slow = slow->next; 
  83.             fast = fast->next->next; 
  84.         } 
  85.         else 
  86.             fast = fast->next; 
  87.     }*/ 
  88.  
  89.     while(fast->next != NULL && fast->next->next != NULL) 
  90.     { 
  91.         slow = slow->next; 
  92.         fast = fast->next->next; 
  93.     } 
  94.      
  95.     if(slow->next == NULL)    // 链表中只有一个节点  
  96.         return r_head; 
  97.     fast = slow->next; 
  98.     slow->next = NULL; 
  99.     slow = head; 
  100.  
  101.     // 函数MergeList是对两个有序链表进行归并,返回值是归并后的链表的头结点  
  102.     //r_head = MergeList_recursive(MergeSort(slow) , MergeSort(fast));  
  103.     r_head = MergeList(MergeSort(slow) , MergeSort(fast)); 
  104.     return r_head; 
赞(0) 打赏
转载请注明出处:服务器评测 » 搜狗2012.9.23校园招聘会笔试题
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏