16、CSingleLock是干什么的。
正确答案:
同步多个线程对一个数据类的同时访问
17、 C++中引用和指针的区别?
正确答案:
引用是对象的别名, 操作引用就是操作这个对象, 必须在创建的同时有效得初始化(引用一个有效的对象, 不可为NULL), 初始化完毕就再也不可改变, 引用具有指针的效率, 又具有变量使用的方便性和直观性, 在语言层面上引用和对象的用法一样, 在二进制层面上引用一般都是通过指针来实现的, 只是编译器帮我们完成了转换。 之所以使用引用是为了用适当的工具做恰如其分的事, 体现了最小特权原则。
18、 C与C++各自是如何定义常量的?有什么不同?
正确答案:
C中是使用宏#define定义, C++使用更好的const来定义。 区别: 1)const是有数据类型的常量,而宏常量没有,编译器可以对前者进行静态类型安全检查,对后者仅是字符替换,没有类型安全检查,而且在字符替换时可能会产生意料不到的错误(边际效应)。 2)有些编译器可以对const常量进行调试, 不能对宏调试。
19、 C++函数中值的传递方式有哪几种?
正确答案:
C++函数的三种传递方式为:值传递、指针传递和引用传递。
20、一般数据库若出现日志满了,会出现什么情况,是否还能使用?
正确答案:
只能执行查询等读操作,不能执行更改,备份等写操作,原因是任何写操作都要记录日志。也就是说基本上处于不能使用的状态。
三、【腾讯C++面试题】
1、.C++里面如何声明constvoidf(void)函数为C程序中的库函数?
正确答案:
在该函数前添加extern “C”声明。由于编译后的名字不同,C++程序不能直接调用C 函数。
2、c++中类和c语言中struct的区别(至少两点)
正确答案:
(1)c++中的类默认的成员是私有的,struct默认的是共有的。
(2)c++中的类可以定义成员函数,struct只能定义成员变量。
(3)C++中的类有继承、多态的特性,struct没有。
3、IP组播有那些好处?
正确答案:
Internet上产生的许多新的应用,特别是高带宽的多媒体应用,带来了带宽的急剧消耗和网络拥挤问题。组播是一种允许一个或多个发送者(组播源)发送单一的数据包到多个接收者(一次的,同时的)的网络技术。组播可以大大的节省网络带宽,因为无论有多少个目标地址,在整个网络的任何一条链路上只传送单一的数据包。所以说组播技术的核心就是针对如何节约网络资源的前提下保证服务质量。
4、变量的声明和定义有什么区别?
正确答案:
声明变量不分配空间,定义变量要分配空间。声明主要是告诉编译器,后面的引用都按声明的格式。定义其实包含了声明的意思,同时要分配内存空间。
5、程序什么时候应该使用线程,什么时候单线程效率高。
正确答案:
1 耗时的操作使用线程,提高应用程序响应
2 并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求。
3 多CPU系统中,使用线程提高CPU利用率
4 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
其他情况都使用单线程。
6、介绍一下模板和容器。如何实现?(也许会让你当场举例实现)
正确答案:
模板可以说比较古老了,但是当前的泛型编程实质上就是模板编程。 它体现了一种通用和泛化的思想。 STL有7种主要容器:vector,list,deque,map,multimap,set,multiset.
7、以下为WindowsNT下的32位C++程序,请计算sizeof的值
charstr[]=“Hello”; charp=str; intn=10; //请计算 sizeof(str)=? sizeof§=? sizeof(n)=? voidFunc(charstr[100]) { //请计算 sizeof(str)=? } voidp=malloc(100); //请计算 sizeof§=?
正确答案:
sizeof (str ) = 6 sizeof ( p ) = 4 sizeof ( n ) =4 void Func ( char str[100]) { sizeof( str ) = 4 } void *p = malloc( 100 ); sizeof ( p ) =4
8、C语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么?inta=5,b=7,c;c=a+++b;
正确答案:
这个问题将做为这个测验的一个愉快的结尾。不管你相不相信,上面的例子是完全合乎语法的。问题是编译器如何处理它?水平不高的编译作者实际上会争论这个问题,根据最处理原则,编译器应当能处理尽可能所有合法的用法。因此,上面的代码被处理成: c = a++ + b; 因此, 这段代码持行后a = 6, b = 7, c = 12。 如果你知道答案,或猜出正确答案,做得好。如果你不知道答案,我也不把这个当作问题。我发现这个问题的最大好处是:这是一个关于代码编写风格,代码的可读性,代码的可修改性的好的话题
9、#include与#include“file.h”的区别?
正确答案:
前者是从Standard Library的路径寻找和引用file.h,而后者是从当前工作路径搜寻并引用file.h。
10、如何在C中初始化一个字符数组。
正确答案:
这个问题看似很简单,但是我们要将最简单的问题用最严谨的态度来对待。关键的地方:初始化、字符型、数组。最简单的方法是char array[];。这个问题看似解决了,但是在初始化上好像还欠缺点什么,个人认为:char array[5]={’1′,’2′,’3′,’4′,’5′};或者char array[5]={“12345″};或者char array[2][10]={“China”,”Beijing”};也许更符合“初始化”的意思。
11、在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”?
正确答案:
extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,其声明的函数和变量可以在本模块或其它模块中使用。 通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。
12、内存的分配方式的分配方式有几种?
正确答案:
1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。
2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
13、在C++程序中调用被C编译器编译后的函数,为什么要加extern"C"?
正确答案:
C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为: void foo(int x, int y);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern"C"来解决名字匹配问题。
14、如何让局部变量具有全局生命期。
正确答案:
具体的生命期的概念我觉得我还要好好深入的学习一下,但是这个题目还算比较简单,即用static修饰就可以了,但是只是生命期延长,范围并没有扩大,除非把这个变量定义在函数体外的静态区,不过那样就变成全局变量了,仿佛不符合题目要求。
15、解释堆和栈的区别。
正确答案:
具体的生命期的概念我觉得我还要好好深入的学习一下,但是这个题目还算比较简单,即用static修饰就可以了,但是只是生命期延长,范围并没有扩大,除非把这个变量定义在函数体外的静态区,不过那样就变成全局变量了,仿佛不符合题目要求。
16、在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”声明?
正确答案:
函数和变量被C++编译后在符号库中的名字与C语言的不同,被extern “C”修饰的变量和函数是按照C语言方式编译和连接的。由于编译后的名字不同,C++程序不能直接调用C 函数。C++提供了一个C 连接交换指定符号extern“C”来解决这个问题。
17、strtok函数在使用上要注意什么问题。
正确答案:
这个问题我不知道能不能回答全面,因为实在是用的很少。这个函数的作用是分割字符串,但是要分割的字符串不能是常量,这是要注意的。比如先定义一个字符串:char array[]=”part1,part2″;,strtok的原形是char *strtok(char *string, char *delim);,我们将”,”作为分隔符,先用pt=strtok(array,”,”);,得到的结果print出来就是”part1″,那后面的呢,要写成pt=strtok(NULL,”,”);,注意,要用NULL,如果被分割的字符串会被分成N段,那从第二次开始就一直要用NULL。总结起来,需要注意的是:被分割的字符串和分隔符都要使用变量;除第一次使用指向字符串的指针外,之后的都要使用NULL;注意使用这个函数的时候千万别把指针跟丢了,不然就全乱了。
18、用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
正确答案:
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情:
1). #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)
2). 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
3). 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
4). 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。
19、说一说C与C++的内存分配方式?
正确答案:
1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,如全局变量,static变量。
2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
3)从堆上分配(动态内存分配)程序在运行的时候用malloc或new申请任意多少的内存,程序员负责在何时用free或delete释放内存。动态内存的生存期自己决定,使用非常灵活。
20、你如何理解MVC。简单举例来说明其应用。
正确答案:
MVC模式是observer 模式的一个特例,典型的有MFC里面的文档视图架构。
四、【华为C++面试题】
1、在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”声明?
正确答案:
二者的编译器不同
2、inti=(j=4,k=8,l=16,m=32);printf(“%d”,i);输出是多少?
正确答案:
相当于i=j=4;i=k=8;i=l=16;i=m=32;故最后i=32;
3、#include与#include“file.h”的区别?
正确答案:
相当于i=j=4;i=k=8;i=l=16;i=m=32;故最后i=32;
4、既然C++中有更好的const为什么还要使用宏?
正确答案:
相当于i=j=4;i=k=8;i=l=16;i=m=32;故最后i=32;
5、重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?
正确答案:
从定义上来说:重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。重写:是指子类重新定义复类虚函数的方法。从实现原理上来说:重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数。重写:当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。
6、C++和C定义结构的分别是什么。
正确答案:
Clanguage的结构仅仅是数据的结合Cplusplus的struct和class其实具备几乎一样的功能,只是默认的访问属性不一样而已。
7、#include和#include"a.h"有什么区别?
正确答案:
对于#include,编译器从标准库路径开始搜索a.h对于#include"a.h",编译器从用户的工作路径开始搜索a.h
8、#include和#include“filename.h”有什么区别?
正确答案:
前者用来包含开发环境提供的库头文件,后者用来包含自己编写的头文件。
9、C函数可否单独编译?
正确答案:
外部函数,可以在开始引进来
10、请简述以下两个for循环的优缺点
1)
for(i=0;i<n;i++) { if(condition) DoSomething(); else DoOtherthing(); }
2)
if(condition) { for(i=0;i<n;i++) DoSomething(); } else { for(i=0;i<n;i++)=““dootherthing();=””}=“”
正确答案:
1)优点:程序简洁。缺点:多执行了n-1次逻辑判断,并且打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。
2)优点:循环的效率高。缺点:程序不简洁。
11、完成程序,实现对数组的降序排序
#include voidsort(intarray[]); intmain() { intarray[]={45,56,76,234,1,34,23,2,3};//数字任//意给出 sort(array); return0; } voidsort(intarray[]) {____________________________________ inti,j,k; for(i=1;i<=7;i++){if(array[i]>array[i-1]) { k=ARRAY[i]; j=i-1; do { array[j+1]=array[j]; j–; } while(k>array[j]&&j>=0); array[j+1]=k; } } —————————————————– }
12、delete[]arry和deletearry一样吗?不一样请说明;
正确答案:
delete[]arry释放的是多个同一类型的地址空间Delete[]arry释放的是一个某种类型的地址空间
13、结合1个你认为比较能体现OOP思想的项目,用UML来描述。
正确答案:
(最好这个项目继承,多态,虚函数都有体现)这个问题大概会占面试时间的一半,并且会问很多问题,一不小心可能会被问住)
14、C与C++各自是如何定义常量的?有什么不同?
正确答案:
C中是使用宏#define定义,C++使用更好的const来定义。区别:1)const是有数据类型的常量,而宏常量没有,编译器可以对前者进行静态类型安全检查,对后者仅是字符替换,没有类型安全检查,而且在字符替换时可能会产生意料不到的错误(边际效应)。2)有些编译器可以对const常量进行调试,不能对宏调试。
15、头文件中的ifndef/define/endif干什么用?
正确答案:
防止重复定义
16、C++中为什么用模板类。
正确答案:
(1)可用来创建动态增长和减小的数据结构
(2)它是类型无关的,因此具有很高的可复用性。
(3)它在编译时而不是运行时检查数据类型,保证了类型安全
(4)它是平台无关的,可移植性
(5)可用于基本数据类型
17、动态连接库的两种方式?
正确答案:
调用一个DLL中的函数有两种方法:1载入时动态链接(load-timedynamiclinking),模块非常明确调用某个导出函数,使得他们就像本地函数一样。这需要链接时链接那些函数所在DLL的导入库,导入库向系统提供了载入DLL时所需的信息及DLL函数定位。2运行时动态链接(run-timedynamiclinking),运行时可以通过LoadLibrary或LoadLibraryEx函数载入DLL。DLL载入后,模块可以通过调用GetProcAddress获取DLL函数的出口地址,然后就可以通过返回的函数指针调用DLL函数了。如此即可避免导入库文件了。
18、在什么时候需要使用“常引用”?
正确答案:
如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:const类型标识符&引用名=目标变量名;
19、预处理器标识#error的目的是什么?
正确答案:
如果你不知道答案,请看参考文献1。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种问题的答案。当然如果你不是在找一个书呆子,那么应试者最好希望自己不要知道答案。
20、GCC3.2.2版本中支持哪几种编程语言。
正确答案:
这个问题实在变态,就像问你#error的作用是什么一样。不可否认,gcc是linux下一个亮点,是一个备受无数程序员推崇的编译器,其优点省略1000字,有兴趣可以自己查,我翻了翻书,书上曰:支持C,C++,Java,Obj-C,Ada,Fortran,Pascal,Modula-3等语言,这个“等”比较要命,不过我认为已经很全了,如果认为还是不全,干脆把ASM也加上算了,不过那已经不算是编译了。
五、【小米C++面试题】
1、已知strcpy的函数原型:charstrcpy(charstrDest,constchar*strSrc)其中strDest是目的字符串,strSrc是源字符串。不调用C++/C的字符串库函数,请编写函数strcpy。
正确答案:
charstrcpy(charstrDest,constcharstrSrc) { if(strDestNULL||strSrcNULL) returnNULL; if(strDest==strSrc) returnstrDest; chartempptr=strDest; while((*strDest++=*strSrc++)!=‘\0’) ; returntempptr; }
2.请问运行Test函数会有什么样的结果?
charGetMemory(void) { charp[]=“helloworld”; returnp; } voidTest(void) { charstr=NULL; str=GetMemory(); printf(str); }
正确答案:乱码
3、重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?
正确答案:
从定义上来说:重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。重写:是指子类重新定义复类虚函数的方法。从实现原理上来说:重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数。重写:当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。
4、多重继承如何消除向上继承的二义性。
正确答案:
使用虚拟继承即可.
5、#include与#include“file.h”的区别?
正确答案:
前者是从StandardLibrary的路径寻找和引用file.h,而后者是从当前工作路径搜寻并引用file.h。
6、对数据库的一张表进行操作,同时要对另一张表进行操作,如何实现?
正确答案:
将操作多个表的操作放入到事务中进行处理
7、#include<filename.h>和#include“filename.h”有什么区别?
正确答案:
查找范围不同,后者先查找工作路径,再查找VC标准路径;前者只查工作路径。
8、预处理器标识#error的目的是什么?
正确答案:
如果你不知道答案,请看参考文献1。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种问题的答案。当然如果你不是在找一个书呆子,那么应试者最好希望自己不要知道答案。
9、头文件的作用是什么?
正确答案:
1)通过头文件来调用库功能。
2)头文件能加强类型安全检查。
10、请问运行Test函数会有什么样的结果?
voidGetMemory(charp) { p=(char)malloc(100); } voidTest(void) { char*str=NULL; GetMemory(str); strcpy(str,“helloworld”); printf(str); }
正确答案:
程序崩溃了
11、delete[]arry和deletearry一样吗?不一样请说明;
正确答案:
delete[]arry释放的是多个同一类型的地址空间Delete[]arry释放的是一个某种类型的地址空间
12、请问运行Test函数会有什么样的结果?
VoidGetMemory(char**p,intnum){ p=(char)malloc(num); } voidTest(void){ char*str=NULL; GetMemory(&str,100); strcpy(str,“hello”); printf(str); }
正确答案:
输出“hello”
13、请简述以下两个for循环的优缺点
//第一个 for(i=0;i<N;i++) { if(condition) DoSomething(); else DoOtherthing(); } //第二个 if(condition) { for(i=0;i<N;i++) DoSomething(); } else { for(i=0;i<N;i++) DoOtherthing(); }
正确答案:
先循环再判断,先判断再循环第一个优点:每个循环都先判断,再执行第二个优点:条件判断,只发生其中一个行为
14、构造函数可否是虚汗数,为什么?析构函数呢,可否是纯虚的呢?
正确答案:
错题解析:构造函数不能为虚函数,要构造一个对象,必须清楚地知道要构造什么,否则无法构造一个对象。析构函数可以为纯虚函数。
15、在C++程序中调用被C编译器编译后的函数,为什么要加extern"C"?
正确答案:
C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为:voidfoo(intx,inty);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern"C"来解决名字匹配问题。
16、请写出下面代码在32位平台上的运行结果,并说明sizeof的性质:
#include #include intmain(void) { chara[30]; charb=(char)malloc(20sizeof(char)); printf(“%d\n”,sizeof(a)); printf(“%d\n”,sizeof(b)); printf(“%d\n”,sizeof(a[3])); printf(“%d\n”,sizeof(b+3)); printf(“%d\n”,sizeof((b+4))); return0; }
正确答案:
在32位系统下(如WIN32),指针长度为32位。a是一个有30个元素的字符型数组;b是一个字符串指针;a[3]是字符型;b+3是指针;*(b+4)是字符型。因此输出:30、4、1、4、1
17、高级通信包括信号量,——-,——–
正确答案:
通常把信号、信号量通信称为低级通信,而把管道、消息队列、共享存储区通信称为高级通信,这个题目我也不知道怎么填了,。。。。。。
18、关联、聚合(Aggregation)以及组合(Composition)的区别?
正确答案:
涉及到UML中的一些概念:关联是表示两个类的一般性联系,比如“学生”和“老师”就是一种关联关系;聚合表示has-a的关系,是一种相对松散的关系,聚合类不需要对被聚合类负责,如下图所示,用空的菱形表示聚合关系:从实现的角度讲,聚合可以表示为:classA{…}classB{A*a;……}而组合表示contains-a的关系,关联性强于聚合:组合类与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表示组合关系:实现的形式是:classA{…}classB{Aa;…}
19、尽管不像非嵌入式计算机那么常见,嵌入式系统还是有从堆(heap)中动态分配内存的过程的。那么嵌入式系统中,动态分配内存可能发生的问题是什么?
正确答案:
这里,我期望应试者能提到内存碎片,碎片收集的问题,变量的持行时间等等。这个主题已经在ESP杂志中被广泛地讨论过了(主要是选项:J.Plauger,他的解释远远超过我这里能提到的任何解释),所有回过头看一下这些杂志吧!让应试者进入一种虚假的安全感觉后,我拿出这么一个小节目:下面的代码片段的输出是什么,为什么?
charptr; if((ptr=(char)malloc(0))==NULL) puts(“Gotanullpointer”); else puts(“Gotavalidpointer”);
这是一个有趣的问题。最近在我的一个同事不经意把0值传给了函数malloc,得到了一个合法的指针之后,我才想到这个问题。这就是上面的代码,该代码的输出是“Gotavalidpointer”。
20、请问运行Test函数会有什么样的结果?
voidTest(void){ charstr=(char)malloc(100); strcpy(str,“hello”); free(str); if(str!=NULL){ strcpy(str,“world”); printf(str); } }
正确答案:
错题解析:输出“world”