您的位置:首页 > 编程语言 > C语言/C++

C/C++校招笔试面试经典题目总结四

2015-07-14 20:33 706 查看
今天阿里电话面试了,感觉自己答得不算好,没别的办法,好好学习....重要的事情说三遍,基础,基础,基础...

题目31:下列代码编译时会产生错误的是()?

#include <iostream>using namespace std;struct Foo{Foo() {  }Foo(int) {  }void fun()   {  }};int main(void){Foo a(10);    //语句1a.fun();      //语句2Foo b();      //语句3b.fun();      //语句4return 0;}
解析:答案应该是语句4,因为语句3没有声明一个b的Foo类型,而是定义了一个无参数的返回类型为Foo的函数b。如果要声明一个Foo,并调用默认构造函数,那么应该是这样的:Foo b;

题目32:下列代码中sizeof(a)的值是()

<h1><span style="background-color: rgb(240, 240, 240); font-family: 'microsoft yahei'; font-weight: normal;"><span style="font-size:10px;">class A  </span></span></h1>{  int i;union U{char buff[13];int i;}u;void foo() {    }typedef char* (*f)(void*);enum{red, green, blue} color;}a;
解析:这里有union和enum类型,分别有对象u和color,还有int型的i,这时要算大小的话,union的大小根据其中最大的数据类型的大小决定,而enum的大小是4,所以这个题目的答案是24。但是如果enum的语句是这样的:enumcolor{red, green, blue};那么这只是声明了一个enum,没有对象,则不占空间。

[b]题目33[/b]下列代码的输出结果是什么?

#include<iostream>using namespace std;class A{public:A()  {    cout<<"A"<<endl;    }//A(A&a) {  cout<<"A"<<endl;  }~A() {    cout<<"~A"<<endl;   }};class B:public A{public:B(A &a):_a(a){cout<<"B"<<endl;}B(){cout<<"B"<<endl;}~B(){cout<<"~B"<<endl;}private:A _a;};int main(void){A a;B b(a);system("pause");}
解析:这里构造了两个对象a和b,对于“Aa;”显然会调用A的构造函数输出“A”,对于“B b(a);”会在初始化b之前,先调用基类构造函数,即输出“A”,然后在初始化列表里调用A的copy构造函数给b中的对象_a初始化,那么A的copy构造函数是没有输出语句的,除非也自己重新写,然后再执行B的构造函数代码,则输出“B”,在main函数结束后,会调用析构函数,析构函数调用顺序为(1)b. ~B()  (2)_a.~A() (3)b.~A() ,当然还有a.~A()。最终的输出为:AAB~B~A~A~A。这里有一个要注意的:要审题清楚,如果这个B类是不继承A类的话,那么这个输出的时候再构造和析构都要减少一次A的输出,答案会是AB~B~A~A

题目34:进程和线程的区别?

解析:简而言之,一个程序至少有一个进程,一个进程至少有一个线程。线程的划分尺度小于进程,使得多线程程序的并发性高。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

题目35:设计模式:工厂模式和单例模式介绍一下?

解析:工程模式即将对象创建过程封装即为工厂模式。单例模式即整个类只有一个对象,并且不允许显示创建。Java中生成单例模式如下:

public class Singleton{   private static Singleton instance = null;  private Singleton(){   //do something  }  public static Singleton getInstance(){  if(instance==null){  instance = new Singleton();  }      return instance;   }}

题目36:虚函数是怎样实现的?在编译原理上讲一下?

解析:在类内部添加一个虚拟函数表指针,该指针指向一个虚拟函数表,该虚拟函数表包含了所有的虚拟函数的入口地址,每个类的虚拟函数表都不一样,在运行阶段可以循此脉络找到自己的函数入口。

题目37: 请问下列语句会调用几次A的构造函数?

A a[4],b,*p;

解析:这里对于数组a,有4个A的对象,那么会调用4次构造函数,对象b显然也会调用一次,但是对于p只是一个对象的指针,并没有指向一个对象的内存空间,所以没有调用构造函数,一共是5次。(如果这里语句是A*p = new A();//此时就指定了实际的对象,那么就调用了一次构造函数)

题目38:进程间的通信方式

解析:1) 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。2) 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。3) 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。4) 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。5) 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。6) 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。7) 套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同主机及其间的进程通信。

题目39:动态连接库的两种方式

解析:调用一个DLL中的函数有两种方法:1) 载入时动态链接(load-time dynamic linking),模块非常明确调用某个导出函数,使得他们就像本地函数一样。这需要链接时链接那些函数所在DLL的导入库,导入库向系统提供了载入DLL时所需的信息及DLL函数定位。2) 运行时动态链接(run-time dynamic linking),运行时可以通过LoadLibrary或LoadLibraryEx 数载入DLL。DLL载入后,模块可以通过调用GetProcAddress获取DLL函数的出口地址,然后就可以通过返回的函数指针调用DLL函数了。如此即可避免导入库文件了。

题目40: 求二叉树中两个节点的最低公共祖先节点

解析:方法一:递归解法(1)如果两个节点分别在根节点的左子树和右子树,则返回根节点(2)如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树
bool FindNode(BinaryTreeNode * pRoot, BinaryTreeNode * pNode){if(pRoot == NULL || pNode == NULL)return false;if(pRoot == pNode)return true;bool found = FindNode(pRoot->m_pLeft, pNode);if(!found)found = FindNode(pRoot->m_pRight, pNode);return found;}BinaryTreeNode * GetLastCommonParent(BinaryTreeNode * pRoot,BinaryTreeNode * pNode1,BinaryTreeNode * pNode2){if(FindNode(pRoot->m_pLeft, pNode1)){if(FindNode(pRoot->m_pRight, pNode2))return pRoot;elsereturn GetLastCommonParent(pRoot->m_pLeft, pNode1, pNode2);}else{if(FindNode(pRoot->m_pLeft, pNode2))return pRoot;elsereturn GetLastCommonParent(pRoot->m_pRight, pNode1, pNode2);}}
方法二:非递归解法:先求从根节点到两个节点的路径,然后再比较对应路径的节点就行,最后一个相同的节点也就是他们在二叉树中的最低公共祖先节点。
bool GetNodePath(BinaryTreeNode * pRoot, BinaryTreeNode * pNode,<span style="font-family: Arial, Helvetica, sans-serif;">list<BinaryTreeNode *> & path) </span>{if(pRoot == pNode)return true;if(pRoot == NULL)return false;path.push_back(pRoot);bool found = false;found = GetNodePath(pRoot->m_pLeft, pNode, path);if(!found)found = GetNodePath(pRoot->m_pRight, pNode, path);if(!found)path.pop_back();return found;}BinaryTreeNode * GetLastCommonParent(BinaryTreeNode * pRoot,BinaryTreeNode * pNode1,BinaryTreeNode * pNode2){if(pRoot == NULL || pNode1 == NULL || pNode2 == NULL)return NULL;list<BinaryTreeNode*> path1;GetNodePath(pRoot, pNode1, path1);list<BinaryTreeNode*> path2;GetNodePath(pRoot, pNode2, path2);BinaryTreeNode * pLast = NULL;list<BinaryTreeNode*>::const_iterator iter1 = path1.begin();list<BinaryTreeNode*>::const_iterator iter2 = path2.begin();while(iter1 != path1.end() && iter2 != path2.end()){if(*iter1 == *iter2)pLast = *iter1;elsebreak;iter1++;iter2++;}return pLast;}
今天先到这儿哦,未完待续。。。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: