某公司2012实习生招聘笔试题
一、单项选择题(40分)
1. https协议常用的端口(A)
A.443 B.80 C.8080 D.22
答案选A,其中80端口是http协议所用端口,8080端口是web服务,22端口是ftp协议端口;https服务器端口号位443tcp/443udp;
比较常见的端口号:
远程登录Telnet:23;简单邮件传输协议(SMTP):25;邮件协议2(pop2):109;
邮件协议3(pop3):收取邮件的协议:110;远程过程调用RPC:135;简单网络管理协议SNMP:161端口;DNS:53端口;
在命令行中可以输入“-netstat –a -n”查看TCP和UDP连接的端口号和状态;
2. 以下哪些协议不是应用层通信协议(D)
A.HTTP,TELENT//超文本传输协议,远程登录都是应用层协议;
B.FTP,SMTP//文件传输协议,简单邮件传输协议属于应用层协议;
C.SNMP,NBNS//简单网络管理协议,网络基本输入/输出系统(NetBIOS)名称服务器
D.ICMP,ARP//Internet控制报文协议,地址解析协议都属于网络层协议
分析:网络层协议包括:ICMP(Internet控制报文协议),IP协议,ARP(地址解析协议),RARP(反向地址解析协议);
传输层协议:TCP协议(传输控制协议),UDP(UserDatagram Protocol用户数据协议);
应用层协议:FTP(文件传输协议),Telnet(远程登录),SMTP(简单邮件传输协议),Http(超文本传输协议),DNS(域名服务器),RIP(Routinginformation Protocol一种内部网关协议),NFS(网络文件系统);
3. Ping命令式使用以下哪个协议实现的(D)
A.UDP
B.ARP
C.IGMP
D.ICMP
E.SMTP
分析:ping命令主要是发送一个ICMP,并通过回声请求消息给目的地并报告是否收到;
4. 以下哪个协议通常用来收取邮件(C)
A. SMTP B.MAIL C.POP3 D.SNMP E.ICMP
5. CSMA/CD发生在OSI模型中的哪一层(B)
A.物理层 B.数据链路层 C.网络层 D.传输层 E.会话层
分析:CSMA/CD表示的是载波监听多路访问/冲突检测方法;
6. 语言
#include<stdio.h>
Void Test(int* a,int* b)
{
int* temp;
tmp=a;
a=b;
b=temp;
}
void main()
{
int a=1,b=2;
Test(&a,&b);
printf(“%d,%d”,a,b);
}
程序在VS2005下编译通过,程序打印结果是(D)
A.2,1 B.2,2 C.1,1 D.1,2
//这题是一个陷阱,根本不是通过指针来传值,没有对实参进行交换;
7. 多线程同步一般用到什么机制(D)
A.事件 B.临界区 C.信号量 D.以上都是
分析:主要有临界区,互斥量,事件,信号量
8. 白盒测试主要用于测试?(C)
A.软件界面 B.软件基本功能 C.软件内部逻辑 D.软件外部结构的合理性
9. 有以下程序
main()
{
int m=0256,n=256;
printf(“%o %o\n”,m,n)
}
程序运行后的输出结果是(C)
A.0256 0400 B.0256 256 C.256 400 D.400400
//分析:数字前面加个零表示八进制数;
10. 拷贝构造函数的参数一般是?(C)
A. 某对象名
B. 某对象成员名
C. 某对象引用名
D. 指向对象的指针名
//拷贝构造函数的形式:A(const A &a );
11. 判断主机存活的扫描方法有:(A)
A. ICMP扫描
B. TCP扫描
C. UDP扫描
D. A、B和C
分析:主机扫描的目的是确定在目标网络上的主机是否可达。这是信息收集的初级阶段,其效果直接影响到后续的扫描。Ping就是最原始的主机存活扫描技术,利用icmp的echo字段,发出的请求如果收到回应的话代表主机存活。传统的扫描手段有:1. ICMP Echo扫描 精度相对较高。通过简单地向目标主机发送ICMP Echo Request 数据包,并等待回复的ICMP Echo Reply 包,如Ping。2. ICMP Sweep 扫描:sweep这个词的动作很像机枪扫射,icmp进行扫射式的扫描,就是并发性扫描,使用ICMP Echo Request一次探测多个目标主机。通常这种探测包会并行发送,以提高探测效率,适用于大范围的评估。3. Broadcast ICMP扫描:广播型icmp扫描,利用了一些主机在icmp实现上的差异,设置ICMP请求包的目标地址为广播地址或网络地址,则可以探测广播域或整个网络范围内的主机,子网内所有存活主机都会给以回应。但这种情况只适合于UNIX/Linux系统。4. Non-Echo ICMP扫描:在ICMP协议中不光光只有ICMP ECHO的ICMP查询信息类型,在ICMP扫描 技术中也用到Non-ECHO ICMP技术(不仅仅能探测主机,也可以探测网络设备如路由)。利用了ICMP的服务类型(Timestamp和Timestamp Reply 、Information Request和Information Reply 、Address Mask Request 和Address Mask Reply)。
12. Alice与Bob用RSA加密方式进行通信,当Bob向Alice发送数据时,他需要用什么密钥来加密要发送的数据(A)
A. Alice的公钥
B. Bob的公钥
C. Alice的私钥
D. Bob的私钥
13. 下面哪些不属于跨站脚本攻击的直接危害(C)
A. 窃取用户信息
B. 挂马
C. 钓鱼
D. 攻击其他站点
分析:跨站脚本攻击也叫XSS,可以盗取用户的session信息,向其它网站发起攻击,强制发送电子邮件,挂马等。
14. 表单登录中用到的图形验证码的实现原理是:(C)
A. 返回给浏览器的html代码中同时包含图形验证码和文本字符串,登录前客户端判断输入内容与页面中保存内容是否一致
B. 服务器端在返回的如片和cookie中同时包含图形验证码,登录前客户端判断输入内容和cookie中保存的内容是否一致
C. 服务器端生成验证码后一方面通过图片将验证码返回给客户端,同时在服务器端保存文本的验证码,由服务器端验证输入内容是否正确
D. 浏览器通过识别图形验证码中的内容合并和用户输入的内容判断是否一致
15. 下列排序算法中,其中(D)是稳定的
A. 堆排序,冒泡排序
B. 快速排序,堆排序
C. 直接选择排序,归并排序
D. 归并排序,冒泡排序
16. 在循环双链表中的P所指节点之后插入s所指节点的操作是:(C)
A. p->next=s;
s->prior=p;
p->nest->prior=s;
s->next=p->next;
B. p->next=s;
p->next->prior=s;
s->prior=p;
s->next=p->next;
C. s->prior=p;
s->next=p->next;
p->next=s;
p->next->prior=s;
D. s->prior=p;
s->next=p->next;
p->next->prior=s;
p->next=s;
17. 一个指向整形数组的指针的定义为(D)
A.int *ptr[]//指针数组
B.int *(ptr[])//指针数组
C.int ptr[]//整形数组;
D.int (*ptr)[]
18. 关于字符设备和块设备的说法正确的是:()
A. 字符设备只能存储字符类型的数据//以字符为单位,不是只能存储字符类型的数据
B. 硬盘是一种字符设备//硬盘是块设备;
C. 字符设备只能按顺序进行访问
D. 字符设备也需要进行操作系统缓存//字符设备直接从物理磁盘读取,不需要缓存;
分析:字符设备是指在I/O传输过程中以字符为单位进行传输的设备,例如键盘,打印机等I/O设备大致分为两类:块设备和字符设备。块设备将信息存储在固定大小的块中,每个块都有自己的地址。数据块的大小通常在512字节到32768字节之间。块设备的基本特征是每个块都能独立于其它块而读写。磁盘是最常见的块设备。块设备通过系统缓存进行读取,不是直接和物理磁盘读取。字符设备可以直接物理磁盘读取,不经过系统缓存
19. 在最坏的情况下,快速排序运行时间复杂度是:(C)//平均时间复杂度选A
A. O(nlogn)
B. O(n)
C. O(n2)
D. O(n3)
20. 以下程序的功能是将字符串s中所有字符c删除,那么空白处缺少语句为:(A)
#include
int main(void)
{
char s[80];
int I,j;
gets(s);
for(i=j=0;s[i]!=’\0’;i++)
if(s[i]!=’c’)
s[j++]=s[i]_______;
s[j]=’\0’;
puts(s);
return 0;
}
A. s[j++]=s[i]
B. s[++j]=s[i]
C. s[j]=s[i];j++
D. s[j]=s[i]
二、多项选择(12分)
1.下面哪些IPv6地址可用于表示localhost(BC)
A. : :FF:127:0:0:1
B. : :1
C.0:0:0:0:0:0:0:0:1
D.: :
2.以下关于堆栈的说法正确的是(AD)
A. 在栈上分配的内存被破坏,容易损坏函数调用信息;
B. 在堆上分配的内存被破坏,容易损坏函数调用信息;
C. Malloc调用的内存分配是在栈上进行内存分配;
D. Malloc调用的内存分配是在堆上进行内存分配;
3.什么函数不能声明为虚函数(AD)
A.构造函数
B.析构函数
C.成员函数
D.友元函数
分析:一般情况下,在c++中不能声明为虚函数的:普通函数,静态成员函数,内联函数,友元函数,构造函数。
普通函数:因为普通函数只能被重载,不能被重写,声明为虚函数没有什么意义;
静态成员函数:静态成员函数对于每个类来说只有一份拷贝,类的对象共享这份代码,没有动态绑定的必要;
内联函数:内联函数在编译时展开,为了减小开销,而虚函数(多态)是在运行时绑定,两个不同的概念,不能声明内联函数为虚函数;
友元函数:c++不支持友元函数的继承,没有继承特性的就无从谈起虚函数的概念;
构造函数:构造函数是为了初始化对象,虚函数是在运行时根据对象的不同类型产生不同动作,如果将构造函数设置成虚函数,这时对象还没有产生,如何用虚函数完成特定的动作。
4.以下代码
class department
{
public:
department();
~department();
…
private:
stringname,address;
};
class develop_center:public department
{
public:
develop_center();//为简化,省略参数
~develop_center();
…
private:
stringcenter_name,center_address;
};
现在定义一个简单的函数return_develop_center,它取一个研发中心参数(通过值)然后立即返回它(也通过值)。如:
develop_centerreturn_develop_center(develop_center a){return a;}
这个函数调用过程,以下正确的是:(BDF)有待进一步探讨!
A. 调用这个函数过程中进行了1次develop_center的构造函数和析构函数。
B. 调用这个函数过程中进行了2次develop_center的构造函数和析构函数。
C. 调用这个函数过程中进行了1次department的构造函数和析构函数。
D. 调用这个函数过程中进行了2次department的构造函数和析构函数。
E. 调用这个函数过程中总共调用了6个构造函数和6个析构函数。
F. 调用这个函数过程中总共调用了12个构造函数和12个析构函数。
三、填空题(20分)
1. 定义一个有10个指针的数组tmp,该指针是指向一个整型数____int *temp[10]_____;
2. 一个指向有10个整型数数组的指针tmp__int (*temp)[10]______;
3. 一个指向函数的指针,该函数有一个整型参数并返回一个整型数___int (*a)(int )_____;
4. 一个有10个指针的数组,该指针指向一个函数该函数有一个整型参数并返回一个整整型数________________int (*temp[10])(int)_____;
5. 请给出程序输出
#define MUL(A,B) A*B
void main(int argc,char** argv)
{
int a,b;
a=10,b=20;
printf(“%d,%d”,MUL(a,b),MUL(a+b,b));
}
//注意宏展开就可以了,500
6. 以下程序中,函数sumColumMin的功能是:求出M行N列二维数组每列元素中的最小值,并计算他们的和值。和值通过形参传回给主函数输出。请填空。
#define M 2
#define N 4
void SumColumMin(int a[M][N],int*sum)
{
int i,j,k,s=0;
for(i=0;i<N;i++)
{
k=0;
for(j=1;j<M;j++)
if(a[k][i]>a[j][i])
k=j;
s+=___a[k][i]____;
}
__*sum____=s;
}
main()
{
intx[M][N]={3,2,5,1,4,1,8,3},s;
SumColumMin(_x,&s_______);
printf(“%d\n”,s);
}
7. 某32位系统下,C++程序,请计算sizeof的值
char str[]=”nsfocus”
char* p=str;
void* ptr=malloc(100);
请计算
sizeof(str)=__8___;
sizeof(p)=____4_;
sizeof(ptr)=__4___;
四、问答题(38分)
(一) 运行下述Test函数会得到后果,并简单描述原因:
1. void GetMemory(char* p)
{
p=(char*)malloc(100);
}
void Test(void)
{
char *str=NULL;
GetMemory(str);//在函数内部修改了形参,但是没有真正的传给实参,str为NULL
strcpy(str,”hello world”);//将字符串赋值给一个空指针,程序崩溃
printf(str);
}
2. char* GetMemory(void)
{
char p[]=”hello world”;
return p;//局部变量,在栈中分配,函数结束,栈空间销毁;
}
void Test(void)
{
char *str=NULL;
str=GetMemory();//该函数返回值是随机的地址值
//一些其他语句
printf(str);
}
3. void GetMemory(char **p,int num)
{
*p=(char*)malloc(num);
}
void Test(void)
{
*str=NULL;
GetMemory(&str,100);
strcpy(str,”hello”);
printf(str);
}
//第三种情况可以运行,输出正常的结果,但是需要考虑内存分配是否成功,并且在test函数中需要释放内存;
4. char* GetMemory(void)
{
char* p=”hello”;
return p;
}
void Test(void)
{
char *str=NULL;
str=GetMemory();
strcpy(str,”abc”);
printf(str);
}
程序崩溃
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
//第一种情况,采用在函数内部修改形参,形参为字符串指针,在test函数中去调用该函数,并不能改变实参的值;
void getMemory1(char *p)
{
p=(char*)malloc(sizeof(char));
}
void test1()
{
char*str=NULL;
getMemory1(str);
strcpy(str,"hello");
printf("%s\n",str);
}
//第二种情况,通过在函数内定义数组,并返回的形式,数组为局部变量,函数返回时,内存被释放;
char *getMemory2()
{
charp[]="hello,world";
returnp;
}
void test2()
{
char*str=NULL;
str=getMemory2();
printf("%s\n",str);
}
//第三种情况,采用指针的指针;
void getMemory3(char **p,int num)
{
*p=(char*)malloc(sizeof(char)*num);
if(*p==NULL)//对于失败情况进行处理;
{
cout<<"申请失败!"<<endl;
return;
}
}
void test3()
{
char*str=NULL;
getMemory3(&str,100);
strcpy(str,"hello,world!");
printf("%s\n",str);
free(str);//应该释放申请的内存;
}
//第四种情况,将第二种情况中的字符数组改成了字符指针;
char *getMemory4()
{
char*p="hello,world";
returnp;
}
void test4()
{
char*str=NULL;
str=getMemory4();
strcpy(str,"abc");
printf("%s\n",str);
}
int main(int argc, char* argv[])
{
// test1();//调用第一个测试函数;出现内存不可读,程序崩溃;
test2();//test2函数里面的str指向的是垃圾;
test3();//这个函数能够正常输出想要的结果,但是存在不足;
test4();//程序崩溃;
return0;
}
(二) 编写程序实现长度为M的数组,将该数组前面的N个数字循环右移到数组末尾。例子:长度M=8的数组{1,2,3,4,5,6,7,8},要求移动前面N=3个数字到末尾,移动后得到的数组是{4,5,6,7,8,9,1,2,3}。要求时间复杂度和空间复杂度尽量低。
见博客地址:http://blog.youkuaiyun.com/useforwebgis/article/details/8854151
(三) 分析如下的C语言代码中错误说明原因,并判断是否存在可利用的漏洞,如果有指出原因及利用思路?
typedef unsigned char u_int8_t
void test(u_int8_t len,char* s)
{
char a[20];//6+14,ftp://
u_int8_t len2;
len2=len+6;
if(len2>20)
{
printf(“thehost is so long\n”);
}
else
{
strncpy(a,”ftp://”,6);
strncpy(a+6,s,len);
a[len]=’\0’;//此处应该是a[len+6]='\0';
printf(“host:%s\n”,a);
}
}
int main(int argc,char** argv)
{
if(argc>2)
{
printf(“pleaseinput the host\n”);
return 1;
}
u_int8_t len;
len=strlen(argv[1]);
printf(“len:%d\n”,len);
test(len,argv[1]);
return 1;
}
运行结果: