届校招C++大游戏方向.docx
《届校招C++大游戏方向.docx》由会员分享,可在线阅读,更多相关《届校招C++大游戏方向.docx(12页珍藏版)》请在冰豆网上搜索。
![届校招C++大游戏方向.docx](https://file1.bdocx.com/fileroot1/2022-11/25/72b99d27-09e3-4399-b02f-956f753f326f/72b99d27-09e3-4399-b02f-956f753f326f1.gif)
届校招C++大游戏方向
2014届校园招聘C++开发程序员(大游戏方向)
专业知识笔试试题A卷
得
分
姓名:
移动电话:
QQ:
紧急联系电话:
Email:
籍贯:
学校:
专业:
学历:
请您答题时注意如下事项:
一、本测试限时60分钟。
请您务必抓紧时间,在规定的时间内完成答卷。
二、在未宣布开始之前,不能提前回答问题,在开始答题后,请先完成综合素质测试试卷后再完成本试卷。
三、请将所有题目统一在答题纸上作答,不要在测评试题卷子上作任何记号。
四、请您按正确答案的题号和字母顺序,将客观题在答题卡上相应位置作答,以免错行。
五、切记不要把试题卷带出试场
请您务必遵守上述事项,确保考试结果为您真实水平!
注意:
请认真阅读考试诚信书内容,慎重签字
一单选题(每题3分,共5题,共15分)
1下面有关函数调用的说法错误的是(A)。
A.实参与形参的数目要求必须是相同的。
(带默认参数的可以不用传实参)
B.实参与形参的对应关系取决于位置而不是名字。
C.实参与对应的形参应类型匹配,即实参的类型可以转化为形参类型。
D.C++有两种调用方式:
传值与引用。
2已知char*constnode="ABC",下列语句合法的是(A)。
A.node[2]='k'B.*node[2]='k'
C.*node="xyz"D.node="xyz"
常量指针,其指针不能改变,但其指向的值可以发生改变,所以选A
3设有98个已排序列元素,采用二分法查找时,最大比较次数是(D)。
A.49B.8C.20D.7
4请写出enumColor{Red=5,Green,Yellow,Blue=20,Orange}中Yellow的值(B)
A.3B.7C.15D.19
5SQL语言中,删除一个表的命令是(B)。
A.CLEARTABLEB.DROPTABLE
C.DELETETABLED.REMOVETABL
二问答题(每题6分,共5题,共30分)
1TCP/IP建立连接的过程
三次握手
1.客户端向服务器发送SYN(syn=j),进入SYN_SEND状态,等待服务器的确定
2.服务器收到客户端发来的SYN包,确认客户端的syn(ack=j+1),即SYN+ACK包,服务器也发送SYN(syn=k),此时服务器进入SYN_RECV_状态
3.客户端收到服务器发来的SYN+ACK包,并向服务器发送确认包ACK(ack=k+1),发送成功,完成连接。
2程序什么时候应该使用线程,什么时候单线程效率高
1.耗时的操作使用线程,提高应用程序响应 2.并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求。
3.多CPU系统中,使用线程提高CPU利用率 4.改善程序结构。
一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
其他情况都使用单线程。
3C++中为什么用模板类
A.它是平台无关的,可移植性
B.可用来创建动态增长和减小的数据结构
C.它在编译时而不是运行时检查数据类型,保证了类型安全
D.它是类型无关的,因此具有很高的可复用性
E.可用于基本数据类型
4static有什么用途(请至少说明两种)
1.限制变量的作用域。
例如定义了一个全局变量,在全局变量前加上static,就表示这个变量只能在当前文档中使用。
2.设置变量的存储域
3.定义静态函数,该函数只能在该当前文件中使用
1.限制变量的作用域
2.设置变量的存储域
5怎样预防内存泄漏,有哪些检测方法?
首先要养成良好的编程规范
其次,一旦泄漏发生,要在已发现内存泄漏的基础上如何找到内存泄漏的现场。
另外,在Windows平台下,检测内存泄漏的工具也是调试与防范内存泄漏的常用方法
编写应用程序时,要养成一个良好的编程习惯,注意对于动态分配的内存不用时要及时释放,合理的使用异常处理方法,在技术上避免内存泄漏的发生,在调试程序时,一旦发现内存泄漏,可以使用相应的监测工具找到泄漏处并消除。
三代码题
1以下3段代码分别输出什么结果(每个5分,共15分)
VoidGetMemory(char**p,intnum)
{
*p=(char*)malloc(num);
}
voidTest(void)
{
char*str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
printf(str);
}
请问运行Test函数会有什么样的结果?
输出的结果是:
hello;
Str有得到分配的内存地址值
不过最后没有对str进行内存释放
voidTest(void)
{
char*str=(char*)malloc(100);
strcpy(str,“hello”);
free(str);//////////这里没有对str进行处理,str=NULL,这样会导致str是个野指针
if(str!
=NULL)
{
strcpy(str,“world”);
printf(str);
}
}
请问运行Test函数会有什么样的结果?
//str为野指针,打印的结果不得而知
char*GetMemory(void)
{
charp[]="helloworld";
returnp;
}
voidTest(void)
{
char*str=NULL;
str=GetMemory();
printf(str);
}
请问运行Test函数会有什么样的结果?
不能正常打印出helloworld,因为指向的是栈,p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。
2某32位系统下,C++程序,请计算sizeof的值(每个1分,共5分).
charstr[]=“
char*p=str;
intn=10;
请计算
sizeof(str)=25?
(1)
sizeof(p)=4?
(2)
sizeof(n)=4?
(3)
voidFoo(charstr[100]){
请计算
sizeof(str)=4?
(4)
}
void*p=malloc(100);
请计算
sizeof(p)=4?
(5)
3写一个函数找出一个整数数组中,第二大的数(15分)
constintMIN=-32767;
intfind_sec_max(intdata[],intcount)
{
intmaxnumber=data[0];
intsec_max=MIN;
inti;
for(i=1;i{
if(data[i]>maxnumber)
{
sec_max=maxnumber;
maxnumber=data[i];
}
elseif(data[i]{
if(data[i]>sec_max)
sec_max=data[i];
}
}
returnsec_max;
}
4写出字符串类String的默认构造函数、析构函数和重载赋值运算符。
(20分)
已知类String的原型为:
classString
{
public:
String(constchar*pStr=NULL);//默认构造函数
~String(void);//析构函数
String&operate=(constString&Source);//重载赋值运算符
private:
char*m_pData;//指向字符串的指针
};
String:
:
String(constchar*pStr=NULL)
{
If(pStr==NULL)
m_pData=NULL;
Else
{
m_pData=(char*)malloc(sizeof(pStr));
Strcpy(m_pData,pStr);
}
}
String:
:
~String()
{
Free(m_pData);
m_pDada=NULL;
}
//String的默认构造函数
String:
:
String(constchar*str){
if(str==NULL){
m_data=newchar[1];
*m_data='\0';
m_size=0;
}else{
intlength=strlen(str);
m_data=newchar[length+1];
strcpy(m_data,str);
m_size=length;
}
}
//赋值函数
String&String:
:
operator=(constString&other){
//检查自赋值
if(this!
=&other){
//分配新的内存资源
char*temp=newchar[strlen(other.m_data)+1];
strcpy(temp,other.m_data);//copy'\0'
//释放原有的内存资源
delete[]m_data;
m_data=temp;
m_size=strlen(other.m_data);
}
return*this;
}
//String的析构函数
String:
:
~String(void){
delete[]m_data;
M_data=NULL:
}
文件的读取:
容器的种类和作用:
栈:
进程和线程的区别:
进程是表示资源分配的基本单位,
又是调度运行的基本单位。
线程是进程中执行运算的最小单位,亦即执行处理机调度的基本单位
进程和线程的关系
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。
不同进程的线程间要利用消息通信的办法实现同步。
二叉树的深度:
typedefstructtree//二叉树的定义
{chardata;structtree*lchild,*rchild;}TREE,*Tree;
voidcreate(Treet)//创建一棵二叉树
{charch;scanf("%c",&ch);if(ch=='#')t=NULL;
else{t->data=ch;create(t->lchild);create(t->rchild);}
}
intdeep(Treet)//深度算法
{if(!
t)return0;else{ld=deep(t->lchild);rd=deep(t->rchild);
if(ld>rd)returnrd+1;elsereturnld+1;
}
voidmain()//主函数
{Treet;create(t);printf("%d\n",deep(t));}
GetMemory函数详解
#include
#include
#include
usingnamespacestd;
char*GetMemory(char*&p,intnum)
{
p=(char*)malloc(sizeof(char)*num);
//p=newchar[num];
returnp;
}
intmain(void)
{
char*str;
GetMemory(str,100);
strcpy(str,"hello");
cout<return0;
}
//上面是一个正确的程序,下面是转载的一些相关的知识
GetMemory错误讲解(指针练习)错误程序:
voidGetMemory(char*p)
{
p=(char*)malloc(100);
}
voidTest(void)
{
char*str=NULL;
GetMemory(str);
strcpy(str,"helloworld");
printf(“%s”,str);
}
这个一个考验对指针理解的题目,上面程序在运行之后:
1,调用GetMemory(str)后,str并未产生变化,依然是NULL.只是改变的str的一个拷贝的内存的变化
2,strcpy(str,"helloworld");程序运行到这将产生错误。
3,new的时候有可能内存出错,应该在*p=(char*)malloc(num);后判断内存是否申请成功,应加上:
if(*p==NULL)
{
...//进行申请内存失败处理
}
4,动态创建的内存没释放。
错误分析:
错认为GetMemory(char*p)中的p“就是”GetMemory(str)中的str。
但p“不是”str,它只是“等于”str。
就象:
inta=100;
intb=a;//现在b等于a
b=500;//现在能认为a=500?
显然不能认为a=500,因为b只是等于a,但不是a!
当b改变的时候,a并不会改变,b就不等于a了。
因此,虽然p已经有new的内存,但str仍然是null
GetMemory(str);//把str传进去,str是一个指针,而他实际上是一个int
voidGetMemory(char*p)//p是str的一个副本
{
p=(char*)newchar[100];//p的值改变,但是str的值并没有改变。
}
而双重指针为什么就可以了呢:
GetMemory(&str);//把str的地址传进去
voidGetMemory(char**p)//p是str地址的一个副本
{
*p=(char*)newchar[100];//p指向的值改变,也就是str的值改变。
}
修改方法1:
(推荐使用这种方法)
voidGetMemory2(char**p)变为二级指针.
voidGetMemory2(char**p,intnum)
{
*p=(char*)malloc(sizeof(char)*num);
}
voidTest(void)
{
char*str=NULL;
GetMemory=(&str);
strcpy(str,"helloworld");
printf(str);
}
修改方法2:
char*GetMemory()
{
char*p=(char*)malloc(100);
returnp;
}
voidTest(void){
char*str=NULL;
str=GetMemory();
strcpy(str,"helloworld");
printf(str);
}
附录A(相关资料)
试题5:
char*GetMemory(void)
{
charp[]="helloworld";
returnp;
}
voidTest(void)
{
char*str=NULL;
str=GetMemory();
printf(str);
}
试题6:
voidGetMemory(char**p,intnum)
{
*p=(char*)malloc(num);
}
voidTest(void)
{
char*str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
printf(str);
}
试题7:
voidTest(void)
{
char*str=(char*)malloc(100);
strcpy(str,"hello");
free(str);
...//省略的其它语句
}
解答:
试题5中
charp[]="helloworld";
returnp;
的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。
这是许多程序员常犯的错误,其根源在于不理解变量的生存期。
试题6中
1、GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句
*p=(char*)malloc(num);
后未判断内存是否申请成功,应加上:
if(*p==NULL)
{
...//进行申请内存失败处理
}
2、试题6的Test函数中也未对malloc的内存进行释放。
试题7中
存在与试题6同样的问题,在执行
char*str=(char*)malloc(100);后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:
str=NULL;
剖析:
试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。
但是要完全解答正确,却也绝非易事。
对内存操作的考查主要集中在:
(1)指针的理解;
(2)变量的生存期及作用范围;
(3)良好的动态内存申请和释放习惯。
再看看下面的一段程序有什么错误:
swap(int*p1,int*p2)
{
int*p;
*p=*p1;
*p1=*p2;
*p2=*p;
}
在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。
在VC++中DEBUG运行时提示错误“AccessViolation”。
该程序应该改为:
swap(int*p1,int*p2)
{
intp;
p=*p1;
*p1=*p2;
*p2=p;
}