某公司笔试(8)

一、选择题(每题3分,10题,共30分) #

  1. 某32位系统下,下面两个sizeof的结果分别是?( A )
char str1[] = http://www.nd.com.cn/”;
sizeofstr1;
void Foochar str2[100]
{
    sizeofstr2;
};
  • A. 4、4
  • B. 22、100
  • C. 22、4
  • D. 4、100
  1. C++编译器区分重载函数的可能方式中,不能作为依据的是(D)
  • A. 参数个数
  • B. 参数类型
  • C. 函数名
  • D. 函数返回值类型
  1. 设栈最大长度为3,入栈序列为1.2.3.4.5.6,则不可能得出栈序列是?( D )
  • A.1.2.3.4.5.6
  • B.2.1.3.4.5.6
  • C.3.4.2.1.5.6
  • D.4.3.2.1.5.6
  1. 对于派生类的构造函数,在定义对象时构造函数的执行顺序为?1.成员对象的构造函数2.基类的构造函数3.派生类本身的构造函数( D )
  • A.123
  • B.231
  • C.321
  • D.213
  1. 如何减少换页错误?( B )
  • A. 进程倾向于占用CPU
  • B. 访问局部性(locality of reference)满足进程要求
  • C. 进程倾向于占用I/O
  • D. 使用基于最短剩余时间(shortest remaining time)的调度机制
  1. foo.GetI()的值是?( C )
class Foo
{
public:
    Fooint i : m_ii {}
    Foo() { Foo1 }
    int GetIvoid { return m_i; }
private:
  int m_i;
};

Foo foo;
  • A.0
  • B.-1
  • C.1
  • D.不可预知
  1. 下列程序的输出结果是?( C )
int i = 8;
switchi
{
    case 9: i = i+1;
	default: i = i+1;
	case 10: i = i+1;
	case 11: i = i+1;
}
cout << i << endl;
  • A.9
  • B.10
  • C.11
  • D.12
  1. float a=2,b=4,h=3;以下C语言表达式与代数式计算结果不相符的是?( B )
  • A.(a+b)*h/2
  • B.(1/2)*(a+b)*h
  • C.(a+b)h1/2
  • D. h/2*(a+b)
  1. 设有98个已排序列元素,采用二分法查找时,最大比较次数是?( D )
  • A.49
  • B.8
  • C.20
  • D.7
  1. 下面哪种情况下,B不能隐式转换为A?( B )
  • A.class B:public A{}
  • B.class A:public B{}
  • C.class B{operator A();}
  • D.class A{A(const B&);}

二、简答题(每题5分,12题,共60分) #

  1. #include<head.h>和#include”head.h”有什么区别? 尖括号<head.h> 表明这是一个工程或者标准的头文件,在预处理过程中会首先检查系统预定义的目录,如果没有找到就报错。

引号”head.h” 表明这是一个用户自定义的头文件,查找文件的时候,会优先在当前文件目录中查找,如果没找到,会再去系统预定义的目录中查找,如果再没找到,则报错。

  1. 指针和引用有什么区别? 指针是一块内存地址,引用则是指针的别名。 指针可以为空,引用不能为空。 引用的创建和销毁,不会调用类的拷贝构造函数和析构函数

  2. C++类中,默认情况下会产生哪些类成员函数? 默认构造函数 拷贝构造函数 默认赋值函数 析构函数

  3. C++中 const的用法? 定义常量及数组 修饰指针和引用 函数中的参数和返回值 修饰对象

  4. Static的用法? 静态变量 静态函数 静态代码块 静态内部类

  5. Strcpy 和 memcpy有什么区别? 复制的内容不同 复制的方法不同 用途不同

  6. Vector和deque有什么区别?在应用时该如何选择? 都是连续储存结构 Vector支持高效的随机访问,在尾端插入或删除的操作 Deque提供了俩级数组结构,支持头尾两端的插入删除操作 如果需要高效的随机存取,而不在乎插入和删除的效率,用Vector 如果需要随机存取,还需要两端数据的插入删除,用Deque

  7. 虚函数和纯虚函数有什么区别? 虚函数:抽象出一种方法,自己可以实现该方法,子类可以不重写。 纯虚函数:抽象出一种方法,自己不能实现该方法,强制子类重写

  8. 有了malloc/free,为什么还要new/delete? malloc/free是c/c++中的标准库函数,new/delete是c++中的运算符。它们都用于申请动态内存和释放内存。

对于非内部数据对象(eg:类对象),只用malloc/free无法满足动态对象的要求。这是因为对象在创建的同时需要自动执行构造函数,对象在消亡之前要自动执行析构函数,而由于malloc/free是库函数而不是运算符,不在编译器的控制权限内,也就不能自动执行构造函数和析构函数。因此,不能将执行构造函数和析构函数的任务强加给malloc/free。所以,在c++中需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理和释放内存工作的运算符delete。

new建立的是一个对象,malloc分配的是一块内存区域,用指针来访问,并且可以在区域里面移动指针;

对于内部数据类型,由于其没有构造函数和析构函数的要求,对于内部数据类型来讲,malloc/free和new/delete的作用是等价的,都是用来申请动态内存和释放内存。

  1. 怎样预防内存泄漏,有哪些检测方法? 养成良好习惯,保证malloc/new和free/delete匹配。 检查malloc/new和free/delete是否匹配,一些工具也就是这个原理。 利用宏或者钩子,在用户程序与运行库之间加了一层,用于记录内存分配情况。

  2. 请简述TCP/IP、HTTP、Socket这几个概念的区别和联系?

TCP/IP协议:Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,是一组协议族。TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构(应用层、传输层、网络层、网络接口层),每一层都呼叫它的下一层所提供的协议来完成自己的需求。通俗而言:TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台联网设备规定一个地址。

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

Socket是一个针对TCP和UDP编程的接口,你可以借助它建立TCP连接等等。而TCP和UDP协议属于传输层 。而http是个应用层的协议,它实际上也建立在TCP协议之上。

Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们使用TCP/IP协议。Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已, 是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口。

  1. 请列举出三个用于线程间同步的Windows内核对象,简述它们的基本概念及其适用环境?
  • 事件内核对象 在所有的内核对象中,事件内核对象是个最基本的对象。它们包含一个使用计数(与所有内核对象一样),一个用于指明该事件是个自动重置的事件还是一个人工重置的事件的布尔值,另一个用于指明该事件处于已通知状态还是未通知状态的布尔值。

事件能够通知一个操作已经完成。有两种不同类型的事件对象。一种是人工重置的事件,另一种是自动重置的事件。当人工重置的事件得到通知时,等待该事件的所有线程均变为可调度线程。

  • 等待定时器内核对象 等待定时器是在某个时间或按规定的间隔时间发出自己的信号通知的内核对象。它们通常用来在某个时间执行某个操作。若要创建等待定时器,只需要调用 C r e a t e Wa i t a b l e Ti m e r函数 3.信标内核对象 信标内核对象用于对资源进行计数。它们与所有内核对象一样,包含一个使用数量,但是它们也包含另外两个带符号的 3 2位值,一个是最大资源数量,一个是当前资源数量。 最大资源数量用于标识信标能够控制的资源的最大数量,而当前资源数量则用于标识当前可以使用的资源的数量。

三、编程题(1题,共10分) #

  1. 写出int strlen(const char *str)方法,要求方法中不能有局部或者全局变量
Int strlen(const char *str)
{
		If(‘\0 == *str)
		{
			return 0;
        }
        else{
	        return strlen(str+1) +1
        }
}