腾讯面试1

2016/05/25 C和C++基础

腾讯内推面试

1、结构体和共同体的区别

结构体是由不同数据类型组成的一个结构,存储空间是所有成员需要的空间的总和,结构成员是同时存在的;

共同体则是不同数据类型共享一个存储空间,空间的大小是能容纳共同体成员中的最大者。共同体成员的值不可能同时存在;

2、static和const分别怎么用,类里面static和const可以同时修饰成员函数吗

const就是只读,值传递,const对象、数据、成员函数;

static一般有2个作用,规定作用域和存储方式,static数据、成员函数;

static const 应该就是上面两者的合集;

是不可以同时修饰成员函数的。C++编译器在实现const的成员函数的时候为了确保该函数不能修改类的实例的状态,会在函数中添加一个隐式的参数const this*。但当一个成员为static的时候,该函数是没有this指针的。也就是说此时const的用法和static是冲突的。

3、指针和引用的区别,引用可以用常指针实现吗

引用:变量的另一个名字,声明的同时要初始化,运行过程不能再赋值,不需要检测

指针:地址变量,指向一个内存空间,可以指向空指针,不需要初始化,运行过程可以再赋值,需要检测是否为空指针

1)引用的内部实现为相当于一个指针变量,与指针的实现方式类似;

2)引用变量内存单元保存的指向变量地址(初始化时赋值),与指针不同地方时,引用变量在定义时必须初始化,而且使用过程中,引用变量保存的内存单元地址值是不能改变的(这一点通过编译器来实现保证);

3)引用也可以进行取地址操作,但是取地址操作返回的不是引用变量所在的内存单元地址,而是被引用变量本身所在的内存单元地址;

4)引用的使用,在源代码级相当于普通的变量一样使用,但在函数参数传递引用变量时,内部传递的实际是变量的地址值(这种机制的实现是通过编译器(编译手段)来实现的)

我觉得引用应该使用指针常量来实现比较合适:

#include <iostream>
using namespace std;
typedef int* const yy;

int main(){
	int a=2;
	yy v=&a;
	*v=4;
	cout<<a<<endl;
	system("pause");
}

4、什么是多态,多态有什么用途

多态:一个同名函数调用不同的内容。

函数重载,编译过程确定,静态多态;

动态多态,运行过程中确定,子类里实现了父类的虚函数,基类指针指向不同层的对象调用不同的虚函数,这就相当于你向不同的对象发出同一个命令,不同的对象会有不同的响应。

作用就是实现了动态联编,使程序运行效率更高,更容易维护和操作。封装可以使得代码模块化,继承可以扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用。也就是说,不论传递过来的究竟是那个类的对象,函数都能够通过同一个接口调用到适应各自对象的实现方法

5、各个排序算法的时间复杂度和稳定性,快排的原理。

冒泡(O(n*n),稳定)、选择(O(n*n),不稳定)、插入(O(n*n),稳定)、希尔(O(n3/2),不稳定)、堆排(O(nlogn),不稳定)、归并(O(nlogn),稳定)、快排(O(nlogn),不稳定)

6、vector中size()和capacity()的区别

size求元素的个数,capacity求最大的空间值

7、map和set的原理

Map是关联容器,以键值对的形式进行存储,方便进行查找。关键词起到索引的作用,值则表示与索引相关联的数据。以红黑树的结构实现,插入删除等操作都在O(logn)时间内完成

Set是关联容器,set中每个元素只包含一个关键字。set支持高效的关键字查询操作——检查一个给定的关键字是否在set中。set也是以红黑树的结构实现,支持高效插入、删除等操作。

8、tcp为什么要三次握手,tcp为什么可靠

传输数据之前必须先建立连接,通信完成后还需要释放连接。

服务器用到的函数:socket、bind、listen、accept、recv、send、closesocket

客户端用到的函数:socket、connect、recv、send、closesocket

建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。

如果采用两次的话,会出现下面这种情况:

比如是A机要连到B机,结果发送的连接信息由于某种原因没有到达B机;

于是,A机又发了一次,结果这次B收到了,于是就发信息回来,两机就连接。传完东西后,断开。

结果这时候,原先没有到达的连接信息突然又传到了B机,于是B机发信息给A,然后B机就以为和A连上了,这个时候B机就在等待A传东西过去,而A因为没有发送连接请求,会忽视B机发过来的信息,从而造成A机资源浪费。

9、函数调用和系统调用的区别

库函数是语言本身的一部分,而系统函数是内核提供给应用程序的接口,属于系统的一部分。

用户应用程序访问并使用内核所提供的各种服务的途径即是系统调用。在内核和用户应用程序相交界的地方,内核提供了一组系统调用接口,通过这组接口,应用程序可以访问系统硬件和各种操作系统资源。

1.系统调用是为了方便应用使用操作系统的接口,而库函数是为了方便人们编写应用程序而引出的,比如你自己编写一个函数其实也可以说就是一个库函数。

2.系统调用可以理解为内核提供给我们在用户态用的接口函数,可以认为是某种内核的库函数。

3.read就是系统调用,而fread就是C标准库函数

库函数调用通常比行内展开的代码慢,因为它需要付出函数调用的开销。但系统调用比库函数调用还要慢很多,因为它需要把上下文环境切换到内核模式

系统调用和函数库的关系:

系统调用通过软中断int 0x80从用户态进入内核态。

函数库中的某些函数调用了系统调用。

函数库中的函数可以没有调用系统调用,也可以调用多个系统调用。

编程人员可以通过函数库调用系统调用。

高级编程也可以直接采用int 0x80进入系统调用,而不必通过函数库作为中介。

如果是在核心编程,也可以通过int 0x80进入系统调用,此时不能使用函数库。因为函数库中的函数是内核访问不到的。

10、线程和进程,线程可以共享进程里的哪些东西。知道协程是什么吗

进程能访问到的内存,每个线程自然也能访问到,包括堆和栈。但是要说共享的话,每个线程拥有有各自的栈,还有寄存器中的内容,所以线程之间共享堆空间,加上部分段空间,比如代码段和全局数据空间。

线程共享的环境包括:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。

协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用:

一个程序可以包含多个协程,可以对比与一个进程包含多个线程,因而下面我们来比较协程和线程。我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。

11.mysql的数据库引擎有哪些,他们的区别

Search

    Post Directory