程序员面试试题深刻剖析文档格式.docx
《程序员面试试题深刻剖析文档格式.docx》由会员分享,可在线阅读,更多相关《程序员面试试题深刻剖析文档格式.docx(11页珍藏版)》请在冰豆网上搜索。
![程序员面试试题深刻剖析文档格式.docx](https://file1.bdocx.com/fileroot1/2023-1/10/6648374e-69ed-4efd-80d4-755b4ef2cc9a/6648374e-69ed-4efd-80d4-755b4ef2cc9a1.gif)
xiaoq.eat();
xiaoq.sleep();
return0;
}
面试例题2:
Findthedefectsineachofthefollowingprograms,andexplainwhyitisincorrect.(找出下面程序的错误,并解释它为什么是错的。
)[中国台湾某著名杀毒软件公司2005年面试题]
#include
classBase{
intval;
Base(){val=1;
classDerive:
Base{
Derive(inti){val=Base:
:
val+i;
};
intmain(int,char**,char**){
Derived(10);
cout<
<d.Base:
val<<endl<<d.val<<endl;
把classDerive:
Base改成classDerive:
publicBase。
这是个类继承问题。
如果不指定public,C++默认的是私有继承。
私有继承是无法继承并使用父类函数中的公有变量的。
扩展知识(组合)
若在逻辑上A是B的“一部分”(apartof),则不允许B从A派生,而是要用A和其他东西组合出B。
例如眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head应该由类Eye、Nose、Mouth、Ear组合而成,而不是派生而成。
程序如下:
classEye
voidLook(void);
classNose
voidSmell(void);
classMouth
voidEat(void);
classEar
voidListen(void);
classHead
voidLook(void){m_eye.Look();
}
voidSmell(void){m_nose.Smell();
voidEat(void){m_mouth.Eat();
voidListen(void){m_ear.Listen();
private:
Eyem_eye;
Nosem_nose;
Mouthm_mouth;
Earm_ear;
Head由Eye、Nose、Mouth、Ear组合而成。
如果允许Head从Eye、Nose、Mouth、Ear派生而成,那么Head将自动具有Look、Smell、Eat、Listen这些功能。
程序十分简短并且运行正确,但是下面这种设计方法却是不对的。
classHead:
publicEye,publicNose,publicMouth,publicEar
面试例题3:
)[德国某著名软件咨询企业2005年面试题]
classbase{
inti;
base(intx){i=x;
}
classderived:
publicbase{
derived(intx,inty){i=x;
voidprintTotal(){inttotal=i+base:
i;
要在子类中设定初始成员变量,把derived(intx,inty)改成derived(intx,inty):
base(x)。
代码如下:
classbase
protected:
//这里的访问属性需要改变
inti;
base(intx){i=x;
publicbase
derived(intx,inty):
base(x)//以前没有初始化基类的成员变量
{
i=y;
}
voidprintTotal()
inttotal=i+base:
};
32.请说出const与#define相比,有何优点?
答案:
1)const常量有数据类型,而宏常量没有数据类型。
编译器可以对前者进行类型安全检查。
而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。
33.简述数组与指针的区别?
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。
指针可以随时指向任意类型的内存块。
(1)修改内容上的差别
chara[]=“hello”;
a[0]=‘X’;
char*p=“world”;
//注意p指向常量字符串
p[0]=‘X’;
//编译器不能发现该错误,运行时错误
(2)用运算符sizeof可以计算出数组的容量(字节数)。
sizeof(p),p为指针得到的是一个指针变量的字节数,而不是p所指的内存容量。
C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。
注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
chara[]="
helloworld"
char*p=a;
cout<
sizeof(a)<
endl;
//12字节
sizeof(p)<
//4字节
计算数组和指针的内存容量
voidFunc(chara[100])
//4字节而不是100字节
34.类成员函数的重载、覆盖和隐藏区别?
a.成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(3)参数相同;
(4)基类函数必须有virtual关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。
此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。
此时,基类的函数被隐藏(注意别与覆盖混淆)
35.Therearetwointvariables:
aandb,don’tuse“if”,“?
:
”,“switch”orotherjudgementstatements,findoutthebiggestoneofthetwonumbers.
((a+b)+abs(a-b))/2
36.如何打印出当前源文件的文件名以及源文件的当前行号?
cout<
__FILE__;
__LINE__;
__FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。
37.main主函数执行完毕后,是否可能会再执行一段代码,给出说明?
可以,可以用_onexit注册一个函数,它会在main之后执行intfn1(void),fn2(void),fn3(void),fn4(void);
voidmain(void)
Stringstr("
zhanglin"
);
_onexit(fn1);
_onexit(fn2);
_onexit(fn3);
_onexit(fn4);
printf("
Thisisexecutedfirst.\n"
);
intfn1()
next.\n"
return0;
intfn2()
executed"
intfn3()
is"
intfn4()
This"
The_onexitfunctionispassedtheaddressofafunction(func)tobecalledwhentheprogramterminatesnormally.Successivecallsto_onexitcreatearegisteroffunctionsthatareexecutedinLIFO(last-in-first-out)order.Thefunctionspassedto_onexitcannottakeparameters.
38.如何判断一段程序是由C编译程序还是由C++编译程序编译的?
#ifdef__cplusplus
c++"
#else
c"
#endif
39.文件中有一组整数,要求排序后输出到另一个文件中
#include
voidOrder(vector&
data)//bubblesort
intcount=data.size();
inttag=false;
//设置是否需要继续冒泡的标志位
for(inti=0;
i<
count;
i++)
for(intj=0;
j<
count-i-1;
j++)
if(data[j]>
data[j+1])
tag=true;
inttemp=data[j];
data[j]=data[j+1];
data[j+1]=temp;
if(!
tag)
break;
vectordata;
ifstreamin("
c:
\\data.txt"
in)
fileerror!
exit
(1);
inttemp;
while(!
in.eof())
in>
>
temp;
data.push_back(temp);
in.close();
//关闭输入文件流
Order(data);
ofstreamout("
\\result.txt"
out)
for(i=0;
data.size();
out<
40.链表题:
一个链表的结点结构
structNode
intdata;
Node*next;
typedefstructNodeNode;
(1)已知链表的头结点head,写一个函数把这个链表逆序(Intel)
Node*ReverseList(Node*head)//链表逆序
if(head==NULL||head->
next==NULL)
returnhead;
Node*p1=head;
Node*p2=p1->
next;
Node*p3=p2->
p1->
next=NULL;
while(p3!
=NULL)
p2->
next=p1;
p1=p2;
p2=p3;
p3=p3->
head=p2;
returnhead;
(2)已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序。
(保留所有结点,即便大小相同)
Node*Merge(Node*head1,Node*head2)
if(head1==NULL)
returnhead2;
if(head2==NULL)
returnhead1;
Node*head=NULL;
Node*p1=NULL;
Node*p2=NULL;
if(head1->
data<
head2->
data)
head=head1;
p1=head1->
next;
p2=head2;
else
head=head2;
p2=head2->
p1=head1;
Node*pcurrent=head;
while(p1!
=NULL&
&
p2!
=NULL)
if(p1->
=p2->
pcurrent->
pcurrent=p1;
p1=p1->
next=p2;
pcurrent=p2;
p2=p2->
if(p1!
if(p2!
(3)已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。
(Autodesk)
Node*MergeRecursive(Node*head1,Node*head2)
if(head1==NULL)
head->
next=MergeRecursive(head1->
next,head2);
next=MergeRecursive(head1,head2->
next);
[C/C++]C/C++笔试、面试题目大汇总[41-45]
bioeconomy发表于2006-3-2220:
28:
00
41.分析一下这段程序的输出(Autodesk)
classB
public:
B()
defaultconstructor"
~B()
destructed"
B(inti):
data(i)//B(int)worksasaconverter(int->
instanceofB)
constructedbyparameter"
<
data<
private:
intdata;
BPlay(Bb)
returnb;
(1)results:
intmain(intargc,char*argv[])constructedbyparameter5
{destructedB(5)形参析构
Bt1=Play(5);
Bt2=Play(t1);
destructedt1形参析构
destructedt2 注意顺序!
}destructedt1
(2)results:
Bt2=Play(10);
constructedbyparameter10
destructedB(10)形参析构
}destructedt2 注意顺序!
destructedt1
42.写一个函数找出一个整数数组中,第二大的数(microsoft)
constintMINNUMBER=-32767;
intfind_sec_max(intdata[],intcount)
intmaxnumber=data[0];
intsec_max=MINNUMBER;
for(inti=1;
if(data[i]>
maxnumber)
sec_max=maxnumber;
maxnumber=data[i];
sec_max)
sec_max=data[i];
returnsec_max;
43.写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数。
KMP算法效率最好,时间复杂度是O(n+m),详见:
44.多重继承的内存分配问题:
比如有classA:
publicclassB,publicclassC{}
那么A的内存结构大致是怎么样的?
这个是compiler-dependent的,不同的实现其细节可能不同。
如果不考虑有虚函数、虚继承的话就相当简单;
否则的话,相当复杂。
可以参考《深入探索C++对象模型》,或者:
45.如何判断一个单链表是有环的?
(注意不能用标志位,最多只能用两个额外指针)
structnode{charval;
node*next;
boolcheck(constnode*head){}//returnfalse:
无环;
true:
有环
一种O(n)的办法就是(搞两个指针,一个每次递增一步,一个每次递增两步,如果有环的话两者必然重合,反之亦然):
boolcheck(constnode*head)
if(head==NULL)returnfalse;
node*low=head,*fast=head->
while(fast!
=NULL&
fast->
next!
=NULL)
low=low->
fast=fast->
next->
if(low==fast)returntrue;
returnfalse;