全近几年科大讯飞软件笔试题目.docx
《全近几年科大讯飞软件笔试题目.docx》由会员分享,可在线阅读,更多相关《全近几年科大讯飞软件笔试题目.docx(30页珍藏版)》请在冰豆网上搜索。
全近几年科大讯飞软件笔试题目
2009讯飞软件开发笔试题目(C++)A卷
1、(4分)用变量a给出下面的定义
a)一个整型数;
b)一个指向整型数的指针;
c)一个指向指针的指针,它指向的指针是指向一个整型数;
d)一个有10个整型的数组;
e)一个有10个指针的数组,该指针是指向一个整型数;
f)一个指向有10个整型数数组的指针;
g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数;
h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数
答案:
a)intab)int*a;c)int**a;d)inta[10];e)int*a[10];
f)inta[10],*p=a;g)int(*a)(int)h)int(*a[10])(int)
2、(4分)请写出以下语句的输出结果:
Inti=43;
Intj=5;
Doublef=25.45181;
a)printf(“i=%d,j=%d,f=%3.2f”,i,j,f);
b)printf(“i=%x,j=%06d,i/j=%d”,i,j,i/j);
答案:
A)i=43,j=5,f=25.45B)i=2b,j=00005,i/j=8(%x显示的是一个无符号的0x16进制的整数,%06d输出的是6位数,不够6位数,前面补0,i/j两个整数相除,只取商的整数值)
3、(2分)请完成以下宏定义:
a)用预处理指令#define声明一个常数,用以表明1年中有多少个秒(忽略闰年问题)
b)写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个
答案:
a)#defineseconds365*24*60*60
b)#defineMIN(a,b)((a)<(b)?
(a):
(b))
扩展:
MAX宏#defineMAX((a)>(b)(a):
(b))
ABS宏#defineABS(((x)>0)?
(x):
(-(x)))
4、(6分)以下为32为windows下的c++程序,请计算:
a)charstr[]=”hello”;
char*p=str;
请计算:
sizeof(str)=sizeof(p)=strlen(p)=
答案:
6,4,5
b)voidfunc(charstr[100])
{
Void*p=malloc(100);
}
请计算:
sizeof(str)=101sizeof(p)=4
c)inta[3]={1,2,3};
intb=sizeof(a)/sizeof(a[0]);
请计算:
b=3
5、(2分)设有定义:
intn=O,*p=&n,**q=&p;则以下选项中,正确的赋值语句是(d)
a)p=1;b)*q=2;c)q=p;d)*p=5;
6、(2分)const关键字的用途?
(至少说明两种)
答案:
(1)可以定义const常量
(2)const可以修饰函数的参数、返回值,甚至函数的定义体。
被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
7、(2分)typedef的c语言中频繁用以声明一个已经存在的数据类型的同义词。
也可以用以预处理器做类似的事情。
例如:
#definedpsstructs*
Typedefstructs*tps;
以上两种情况的意图都是要定义dps和tps作为一个指向结构s指针。
哪种方法更好一些
呢?
(如果有的话)为什么?
Typedef更好一些,因为define只是简单的替换,比如声明dpsa,b等价于struct*a,b;
所以这样声明是错误的,而Typedef却不会这样。
8、(8分)以下是一组有关内存知识的问题,请仔细看题,回答:
VoidGetMemory(char*p)
P=(char*)malloc(100);
VoidTest(void)
{
Char*str=Null;
GetMemory(str);
Strcpy(str,”helloworld”);
Printf(str);
}
请问运行Test函数会有什么样的结果?
a)_会出错,不能传递动态分配的内存,str一直为空
char*GetMemory(void)
{
Charp[]=”helloworld”);
Returnp;
}
VoidTest(void)
{
Char*str=NULL;
Str=GetMemory();
Printf(str);
请问运行Test函数会有什么结果?
b)—会产生错误,不能返回子函数的局部变量值,因为在函数退出时,局部变量的值也清空。
voidGetMemory2(char**p,intnum)
{
*p=(char*)malloc(num);
}
VoidTest(void)
{
Char*str=NULL;
GetMemory(&str,1OO);
Strcpy(str,”hello”);
Printf(str);
}
请问运行Test函数会有什么结果?
c)hello。
voidTest(void)
{
Char*str=(char*)malloc(100);
Strcpy(str,”hello”);
Free(str);
lf(str!
=NULL)
Strcpy(str,”world”);
Printf(str);
}
}
请问运行test函数会有什么样的结果?
虽然能拷贝成功,但是这样使用很不安全,free(str)后,str成为悬浮指针。
9、(6分)请写出以下程序的输出结果:
ClassA
{
Public:
A()
{Printf(“Aconstructed.\n”);}
Virtual~A()
{printf(“Adeconstructed.\n”);}
VirtualvoidFn()
{printf(“Afncalled.\n”);}
};
ClassB:
publicA
{
Public:
B()
{printf(“Bconstructed.\n”);}
Virtual~B()
{printf(“Bdeconstructed.\n”);}
VirtualvoidFn()
{printf(“Bfncalled.'n”);}
};
ClassC:
publicB
{
Public:
C()
{printf(“Cconstructed.\n”);}
Virtual~C()
{printf(“Cdeconstructed.\n”);}
VirtualvoidFn()
{printf("Cfncalled.\n”);}
};
Voidmain(intargc,char*grgv[])
{
A*pA=newB;
lf(pA!
=NULL)
pA->fn();
B*pB=static_cast(pA);
lf(pB!
=NULL)
pB->fn();
C*pC=static_cast(pA);
If(pC!
=NULL)
pC->fn();
deletepA;
Aconstructed.
Bconstructed
Bdeconstructed.
Adeconstructed.
A)指针和引用作为函数参数都可以改变实参
B)指针和引用都可以在定义后任意的改变指向
C)引用必须在创建的时候初始化,而指针则不需要
D)不能空引用,但是可以有空指针
11、(2分)下列关于多态的描述,错误的是(c)
A)C++语言的多态性分为编译时的多态和运行时的多态性
B)编译时的多态性可以通过函数重载来实现
C)运行时的多态性可以通过模板和虚函数来实现
D)实现运行时多态性的机制称动态绑定
12、(2分)运算符的重载形式有两种,重载为_类的成员函数_和_类的友元函数_
13、(2分)main主函数执行完毕后,是否可能会再执行一段代码?
请说明理由?
答:
可以,可以用_onexit()注册一个函数,在main结束之后调用f1,f2,f3,f4。
14、(2分)C++中的空类,默认产生那些类成员函数?
答:
默认构造函数、析构函数、默认拷贝函数和赋值操作符
15、(4分)简述STL库的功能,并给出遍历一个包含一组整型数的vector的代码。
答:
标准模板库是一个基于模板的容器类库,包括链表、列表、队列和堆栈。
标准模板库还包含许多常用的算法,包括排序和查找。
标准模板库的目的是提供对常用需求重新开发的一
种替代方法。
标准模板库已经经过测试和调试,具有很高的性能并且是免费的。
最重要的是,
标准模板库是可重用的,当你知道如何使用一个标准模板库的容器后,就可以在所有的程序
中使用它而不需要重新开发了。
容器是包容其他对象的对象。
标准C++库提供了一系列的容器类,它们都是强有力的工具,
可以帮助C++开发人员处理一些常见的编程任务。
标准模板库容器类有两种类型,分别为顺序和关联。
顺序容器可以提供对其成员的顺序访问和随机访问,关联容器则经过优化类的
键值访问它们的元素。
标准模板库在不同操作系统是可移植的。
#include
#include
usingnamespacestd;
intsum(vectorvec)
intresult=O;
vector:
:
iteratorp=vec.begin();while(p!
=vec.end())
{
cout<<*p<<"";result+=*p++;
}
returnresult;
}
intmain()
{
vectorv1(100);
cout<cout<v1[900]=900;
cout<cout<cout<v1.pop_back();
cout<16、(5分)请写出贝叶斯公式
若A1,A2,…,An构成完备事件组,且P(Ai)>0,(i=1,2,…,n),则对任一事件
p(A)p(b/a」
l1
17、(5分)进程和线程的区别和联系?
进程和线程的关系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。
不同进程的线程间要利用消息通信的办法实现同步。
线程是指进程内的一个执行单元,也是进程内的可调度实体.
与进程的区别:
(1)调度:
线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:
不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:
进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于
进程的资源⑷系统开销:
在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销
明显大于创建或撤消线程时的开销。
但是进程有独立的地址空间,一个进程崩溃后,在保护
模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。
线程有自己的堆
栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以
多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些
18、(10分)请不用任何cruntime函数实现以下函数:
Intertrim_str(char*pstr)
函数功能如下:
1)滤掉字符串头尾的空格、回车、tab
2)输出字符串通过输入字符串指针返回
3)如果成功则返回0否则返回非0
#include
usingnamespacestd;
#defineERR-1;
inttrim_str(char*pstr)
{
char*p=pstr;
char*m;
if(p==NULL)
returnERR;
while(*p!
='\O')
{
if((*p=='')|(*p=='\n')|(*p=='\t')){
m=p;
while(*m!
='\O')
{
*m=*(m+1);
m++;
}
}
else
{
p++;
}
}
return0;
}
intmain()
inti=trim_str(s);
if(i==O)
{
cout<<"成功"<}
else
{
cout<<"失败"<}
cout<
return0;
}
19、(10分)有N个大小不等的自然数(1,2,3,…..N)请将它们从小到大排列。
算法要求:
时间复杂度为O(n),空间复杂度为0
(1)。
请简要说明你采用的排序算法并写出c的伪代码。
#include
usingnamespacestd;
constintMAX=1000;
intdata[MAX];
voidpaixu(int*p,intm)
intk=0;
for(inti=O;i{
data[i]=O;
}
for(intj=O;j{
data[*(p+j)]++;
}
for(i=0;i{
if(data[i]!
=O)
{
for(j=0;j{
*(p+k)=i;
k++;
}
}
}
}
intmain()
inta[]={1,3,1,27,13,2,4,80,43,23,18,46};
intlen;
len=sizeof(a)/sizeof(int);
paixu(a,len);
for(inti=0;i{
cout<}
return0;
20、(10分)用文字和图示(类图)描述你所知道的除单件模式和简单工厂之外的一种设计模式,并用C++实现
单例模式:
类图:
Singleton
<Singleton*
<>GetInstance()Singleton()
classSingleton
{
public:
staticSingleton*Getlnstance();
private:
Singleton(){}
~Singleton(){}
staticSingleton*singleton;
}
Singleton*Singleton:
:
singleton=NULL;
Singleton*Singleton:
:
GetInstance()
{
if(singleton==NULL)
singleton=newSingleton();
returnsingleton;
}
21、(10分)请在下列三题中任选一题作答
A)什么是内存的垃圾回收集算法,其作用是什么?
据你所知,有那些开发语言中提供了垃
圾收集机制?
答:
一种自动内存管理的策略,就是自动垃圾回收机制。
既然是自动垃圾回收,那么平台肯定得采取一种方式发现垃圾,然后清除。
这就是垃圾收集算法所关注的问题。
垃圾收集算法的任务就是将活动的对象和已经死掉的对象分别岀来,然后将死掉的对象的内存回收,而且为了更好的利用内存,有的算法还会对内存碎片进行压缩。
JAVA,C#
B)现在非常多的用户都在谈SOA,根据Gartner的预测,2008年,企业80%应用都将通
过使用SOA来实现,你理解SOA是什么?
SOA的关键特点有哪些?
SOA带来什么?
答:
面向服务的体系结构面向服务的体系结构(Service-OrientedArchitecture,SOA)是一个组件模
型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。
接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。
这使得构建在各种这样的系统中的服务可以一种统一和通用的方式进行交互。
C)随着互联网的普及,很多新兴的、传统的软件厂商都在探讨SAAS的前景,甚至很多行
业观点认为SAAS是软件行业的未来趋势。
你是怎么理解SAAS的,你怎么看待这种趋
势?
SAAs和更早之前的ASP感念有什么异同?
答:
SaaS(Software-as-a-service)的意思是软件即服务,
SaaS的中文名称为软营或软件运营。
SaaS是基于互联网提供软件服务的软件应用模式。
作为一种在21
世纪开始兴起的创新的软件应用模式,SaaS是软件科技发展的最新趋势SaaS提供商为企业搭建信息化
所需要的所有网络基础设施及软件、硬件运作平台,并负责所有前期的实施、后期的维护等一系列服务,企业无需购买软硬件、建设机房、招聘IT人员,即可通过互联网使用信息系统。
就像打开自来水龙头就能
用水一样,企业根据实际需要,从SaaS提供商租赁软件服务。
13、指针和引用的相同点和不同点:
★相同点:
•都是地址的概念;
指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。
★不同点:
•指针是一个实体,而引用仅是个别名;
•引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;
•引用没有const,指针有const,const的指针不可变;
•引用不能为空,指针可以为空;
•“sizeof引用”得到的是所指向的变量(对象)的大小,而“sizeof指针”得到的是指针本身的大小;•指针和引用的自增什+)运算意义不一样;
•引用是类型安全的,而指针不是(引用比指针多了类型检查
14、多线程问题
为什么多线程会比单线程更耗时呢?
其原因就在于,线程启停以及线程上下文切换都会引起额外的开销,所以消耗的时间比单线程多。
为什么加锁后的三线程比两线程还慢呢?
其原因也很简单,那把读写锁就是罪魁祸首。
实际情况并不是并行执行,反而成了串行执行,
在采用多线程方法设计程序时,如果产生的额外开销大于线程的工作任务,就没有并行的必要。
线程并不是越多越好,软件线程的数量尽量能与硬件线程的数量相匹配。
最好根据实际的需要,通过不断的调优,来确定线程数量的最佳值。
15、什么是虚拟存储器?
虚拟存储器的特点是什么?
虚拟存储器:
在具有层次结构存储器的计算机系统中,自动实现部分装入和部分替换功能,能从逻辑上为用户提供一个比物理贮存容量大得多,可寻址的“主存储器”。
虚拟存储区的容量与物理主存大小无关,而受限于计算机的地址结构和可用磁盘容量。
特点:
多次性、对换性、虚拟性。
多次性是指一个作业被分成多次调入内存运行,亦即在作业运行时没有必要将其全部装入,只需将当前要运行的那部分程序和数据装入内存即可;以后每当要运行到尚未调入的那部分程序时,再将它调入。
对换性是指允许在作业的运行过程中进行换进、换出,亦即,在进程运行期间,允许将那些暂不使用的程序和数据,从内存调至外村的对换区(换岀),待以后需要时再将它们从外存调至内存(换进)。
虚拟性是指能够从逻辑上扩充内存容量,使用户所看到的内存容量远大于实际内存容量。
16、什么是this指针?
其主要功能是什么?
this指针是类的一个自动生成、自动隐藏的私有成员,它存在于类的非静态成员函数中,指向被调用函数所在的对象的地址。
全局仅有一个this指针,当一个对象被创建时,this指针就指向对象数据的首地址。
一种情况就是,在类的非静态成员函数中返回类对象本身的时候,直接使用
return*this;
另外一种情况是当参数与成员变量名相同时使用this指针,如this->n=n(不能写成n=n)
17、C++常见的内存错误:
1.内存泄露:
指应用程序未释放动态申请的且不再使用的内存,原因可能是程序员疏忽或者错误造成程序
异常。
在C/C++中,动态申请的内存是在堆上的。
如果发送此类的内存泄露,函数每执行一次就丢失一块内存。
长时间运行改程序可能引起系统”内存耗尽”。
2.野指针:
未初始化的指针称为野指针。
通常的避免方法就是在指针定义的时候就初始化,初始为NULL
或者一个有意义的内存地址。
对于动态申请的内存地址,在该内存释放之后,对应指针最好立即赋值为
NULL。
并在具体使用指针的时候判断指针的值是否为NULL。
3.内存越界访问:
内存越界访问通常发生在数组、字符串或者连续内存的访问。
有两种情况:
读越界,即读了非有效的数据。
如果所读的内存地址是无效的,程序会立即崩溃。
如果所读内存地址是有效的,读入的时候不会有错误,但是读入的数据是随机的,可能会产生不可控制的后果。
举个简单的例子,字符串输岀,如果没有结束符,会输岀一堆乱码也可能输岀正常,也就是说结果是不可控的。
写越界,亦称为缓冲区溢岀,通常写越界会发生错误。
内存写越界造成的后果是非常严重的。
例如访问数组越界可能会修改访问数组的循环变量,造成死循环。
4.返回指向临时变量的指针char*getString(){charb[]="Hello,Tocy!
";returnb;}
5.试图修改常量
6.内存未分配成功,但已经使用
7.内存分配成功,但没有初始化
附加:
goto语句有没有必要存在程序设计语言中
答案:
结构程序设计是避免使用GOTO语句的一种程序设计;结构程序设计是自顶向下的
程序设计;结构程序设计是一种组织和编制程序的方法,利用它编制的程序易于理解、易
于修改;程序结构化的一个主要功能是使程序正确性的证明容易实现;结构程序设计对设
计过程中的每一步去验证其正确性,这样便自动导致自我说明和自我捍卫的程序设计风格;
2012年科大讯飞软件笔试题
、单选题
1、64变形的外角和是多少(A)是360度
A、1*360B、1*180
C、64*360D、64*180
2、有一盆衣服(已经洗过了,需要漂