程序员面试试题深刻剖析.docx

上传人:b****5 文档编号:6850559 上传时间:2023-01-11 格式:DOCX 页数:11 大小:20.49KB
下载 相关 举报
程序员面试试题深刻剖析.docx_第1页
第1页 / 共11页
程序员面试试题深刻剖析.docx_第2页
第2页 / 共11页
程序员面试试题深刻剖析.docx_第3页
第3页 / 共11页
程序员面试试题深刻剖析.docx_第4页
第4页 / 共11页
程序员面试试题深刻剖析.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

程序员面试试题深刻剖析.docx

《程序员面试试题深刻剖析.docx》由会员分享,可在线阅读,更多相关《程序员面试试题深刻剖析.docx(11页珍藏版)》请在冰豆网上搜索。

程序员面试试题深刻剖析.docx

程序员面试试题深刻剖析

程序员面试试题

面试例题1:

如果鸟是可以飞的,那么鸵鸟是鸟么?

鸵鸟如何继承鸟类?

[美国某著名分析软件公司2005年面试题]

  解析:

如果所有鸟都能飞,那鸵鸟就不是鸟!

回答这种问题时,不要相信自己的直觉!

将直觉和合适的继承联系起来还需要一段时间。

  根据题干可以得知:

鸟是可以飞的。

也就是说,当鸟飞行时,它的高度是大于0的。

鸵鸟是鸟类(生物学上)的一种。

但它的飞行高度为0(鸵鸟不能飞)。

  不要把可替代性和子集相混淆。

即使鸵鸟集是鸟集的一个子集(每个驼鸟集都在鸟集内),但并不意味着鸵鸟的行为能够代替鸟的行为。

可替代性与行为有关,与子集没有关系。

当评价一个潜在的继承关系时,重要的因素是可替代的行为,而不是子集。

  答案:

如果一定要让鸵鸟来继承鸟类,可以采取组合的办法,把鸟类中的可以被鸵鸟继承的函数挑选出来,这样鸵鸟就不是“akindof”鸟了,而是“hassomekindof”鸟的属性而已。

代码如下:

#include

#include

usingnamespacestd;

classbird

{

 public:

  voideat();

  voidsleep();

  voidfly();

};

classostrich

{

 public:

  birdeat(){cout<<"ostricheat";};

  birdsleep(){cout<<"ostrichsleep";};

};

intmain()

{

 ostrichxiaoq;

 xiaoq.eat();

 xiaoq.sleep();

 return0;

}

面试例题2:

Findthedefectsineachofthefollowingprograms,andexplainwhyitisincorrect.(找出下面程序的错误,并解释它为什么是错的。

)[中国台湾某著名杀毒软件公司2005年面试题]

#include

usingnamespacestd;

classBase{

 public:

  intval;

  Base(){val=1;};

};

classDerive:

Base{

 public:

  intval;

  Derive(inti){val=Base:

:

val+i;};

};

intmain(int,char**,char**){

 Derived(10);

 cout<<d.Base:

:

val<<endl<<d.val<<endl;

 return0;

}

  答案:

把classDerive:

Base改成classDerive:

publicBase。

  解析:

这是个类继承问题。

如果不指定public,C++默认的是私有继承。

私有继承是无法继承并使用父类函数中的公有变量的。

  扩展知识(组合)

  若在逻辑上A是B的“一部分”(apartof),则不允许B从A派生,而是要用A和其他东西组合出B。

  例如眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head应该由类Eye、Nose、Mouth、Ear组合而成,而不是派生而成。

程序如下:

classEye

{

 public:

  voidLook(void);

};

classNose

{

 public:

  voidSmell(void);

};

classMouth

{

 public:

  voidEat(void);

};

classEar

{

 public:

  voidListen(void);

};

classHead

{

 public:

  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:

Findthedefectsineachofthefollowingprograms,andexplainwhyitisincorrect.(找出下面程序的错误,并解释它为什么是错的。

)[德国某著名软件咨询企业2005年面试题]

classbase{

 private:

inti;

 public:

base(intx){i=x;}

};

classderived:

publicbase{

 private:

inti;

 public:

derived(intx,inty){i=x;}

 voidprintTotal(){inttotal=i+base:

:

i;}

};

  解析:

要在子类中设定初始成员变量,把derived(intx,inty)改成derived(intx,inty):

base(x)。

  答案:

  代码如下:

classbase

{

 protected:

//这里的访问属性需要改变

  inti;

 public:

  base(intx){i=x;}

};

classderived:

publicbase

{

 private:

  inti;

 public:

  derived(intx,inty):

base(x)//以前没有初始化基类的成员变量

  {

   i=y;

  }

  voidprintTotal()

  {

   inttotal=i+base:

:

i;

  }

 };

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<

cout<

计算数组和指针的内存容量

voidFunc(chara[100])

{

cout<

}

34.类成员函数的重载、覆盖和隐藏区别?

答案:

a.成员函数被重载的特征:

(1)相同的范围(在同一个类中);

(2)函数名字相同;

(3)参数不同;

(4)virtual关键字可有可无。

b.覆盖是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);

(2)函数名字相同;

(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__;

cout<<__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()

{

printf("next.\n");

return0;

}

intfn2()

{

printf("executed");

return0;

}

intfn3()

{

printf("is");

return0;

}

intfn4()

{

printf("This");

return0;

}

The_onexitfunctionispassedtheaddressofafunction(func)tobecalledwhentheprogramterminatesnormally.Successivecallsto_onexitcreatearegisteroffunctionsthatareexecutedinLIFO(last-in-first-out)order.Thefunctionspassedto_onexitcannottakeparameters.

38.如何判断一段程序是由C编译程序还是由C++编译程序编译的?

答案:

#ifdef__cplusplus

cout<<"c++";

#else

cout<<"c";

#endif

39.文件中有一组整数,要求排序后输出到另一个文件中

答案:

#include

#include

usingnamespacestd;

voidOrder(vector&data)//bubblesort

{

intcount=data.size();

inttag=false;//设置是否需要继续冒泡的标志位

for(inti=0;i

{

for(intj=0;j

{

if(data[j]>data[j+1])

{

tag=true;

inttemp=data[j];

data[j]=data[j+1];

data[j+1]=temp;

}

}

if(!

tag)

break;

}

}

voidmain(void)

{

vectordata;

ifstreamin("c:

\\data.txt");

if(!

in)

{

cout<<"fileerror!

";

exit

(1);

}

inttemp;

while(!

in.eof())

{

in>>temp;

data.push_back(temp);

}

in.close();//关闭输入文件流

Order(data);

ofstreamout("c:

\\result.txt");

if(!

out)

{

cout<<"fileerror!

";

exit

(1);

}

for(i=0;i

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->next;

p1->next=NULL;

while(p3!

=NULL)

{

p2->next=p1;

p1=p2;

p2=p3;

p3=p3->next;

}

p2->next=p1;

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->datadata)

{

head=head1;

p1=head1->next;

p2=head2;

}

else

{

head=head2;

p2=head2->next;

p1=head1;

}

Node*pcurrent=head;

while(p1!

=NULL&&p2!

=NULL)

{

if(p1->data<=p2->data)

{

pcurrent->next=p1;

pcurrent=p1;

p1=p1->next;

}

else

{

pcurrent->next=p2;

pcurrent=p2;

p2=p2->next;

}

}

if(p1!

=NULL)

pcurrent->next=p1;

if(p2!

=NULL)

pcurrent->next=p2;

returnhead;

}

(3)已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。

(Autodesk)

答案:

Node*MergeRecursive(Node*head1,Node*head2)

{

if(head1==NULL)

returnhead2;

if(head2==NULL)

returnhead1;

Node*head=NULL;

if(head1->datadata)

{

head=head1;

head->next=MergeRecursive(head1->next,head2);

}

else

{

head=head2;

head->next=MergeRecursive(head1,head2->next);

}

returnhead;

}

[C/C++]C/C++笔试、面试题目大汇总[41-45]

bioeconomy发表于2006-3-2220:

28:

00

41.分析一下这段程序的输出(Autodesk)

classB

{

public:

B()

{

cout<<"defaultconstructor"<}

~B()

{

cout<<"destructed"<}

B(inti):

data(i)//B(int)worksasaconverter(int->instanceofB)

{

cout<<"constructedbyparameter"<

private:

intdata;

};

BPlay(Bb)

{

returnb;

}

(1)results:

intmain(intargc,char*argv[])constructedbyparameter5

{destructedB(5)形参析构

Bt1=Play(5);Bt2=Play(t1); destructedt1形参析构

return0;              destructedt2 注意顺序!

}destructedt1

(2)results:

intmain(intargc,char*argv[])constructedbyparameter5

{destructedB(5)形参析构

Bt1=Play(5);Bt2=Play(10); constructedbyparameter10

return0;              destructedB(10)形参析构

}destructedt2 注意顺序!

destructedt1

42.写一个函数找出一个整数数组中,第二大的数(microsoft)

答案:

constintMINNUMBER=-32767;

intfind_sec_max(intdata[],intcount)

{

intmaxnumber=data[0];

intsec_max=MINNUMBER;

for(inti=1;i

{

if(data[i]>maxnumber)

{

sec_max=maxnumber;

maxnumber=data[i];

}

else

{

if(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->next;

while(fast!

=NULL&&fast->next!

=NULL)

{

low=low->next;

fast=fast->next->next;

if(low==fast)returntrue;

}

returnfalse;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1