海格面试题总结

一、选择题

1,下面关于关键字的描述及使用中,错误的是(  )

A, volatile可用于定义多线程应用中的共享变量         B,const可用于定义全局变量

C,一个变量既可以是const,同时也是volatitle          D,register static int i=0

答案:B

      int b=i,volatile 指出 i 是随时可能发生变化的,每次使用它的时候必须从 i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在 b 中。而优化做法是,由于编译器发现两次从 i读数据的代码之间的代码没有对 i 进行过操作,它会自动把上次读的数据放在 b 中。而不是重新从 i 里面读。这样以来,如果 i是一个寄存器变量或者表示一个端口数据就容易出错,所以说 volatile 可以保证对特殊地址的稳定访问。
       
register变量是直接放在寄存器中的,这样就大大提高了变量存取的速度,但是静态变量不能定义为register


2,假设有10个记录,它的初始关键字序列为{55,2,6,4,32,12,9,73,26,37},用插入排序对改关键字序列排序,则第5次排序结果为()

答案是2,4,6,12,32,55,9,73,26,37

       插入排序概念:有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。


       插入排序包括:直接插入排序,二分插入排序(又称折半插入排序),链表插入排序,希尔排序(又称缩小增量排序)。

这里只讲下直接插入排序。先附上一张图

再附上C++代码:

void zjinsert (int arr[],int n)
{
int i,j;temp;
for (i=1;i<n;i++)
{
temp = arr[i];
j=i-1;
while (j>-1 &&temp<arr[j])
{
arr[j+1]=arr[j];
j--;
}
arr[j+1]=temp;
}
}

3,中断响应时间是指()

A,从中断处理开始到中断处理结束            B,从发出中断请求到中断处理结束

C,从发出中断请求到进入中断处理            D,从进入中断处理到中断处理结束

答案:C


4,ftp及http协议使用的默认端口号是()

答案是21 8080


FTP协议代理服务器常用端口号:21 

HTTP协议代理服务器常用端口号:80/8080/3128/8081/9080


5,SQL语言具有()功能

A,关系规范化 数据操纵 数据控制           B,数据定义 数据操纵 数据控制

C,数据定义 关系规范化  数据控制          D,数据定义 关系规范化  数据操纵

答案:B

       SQL语言集数据查询(data query)、数据操纵(data manipulation)、数据定义(data definition)和数据控制(data control)功能于一体,充分体现了关系数据语言的特点和优点。


6,下面代码完成两个值互换,空白处填写代码正确的是()

void swap(int *a, int *b)
{
	*a = *a^*b;
	______________
}
A,*a = *a^*b; *a = *b^*a;       B,*a = *b^*a; *b =*a ^*b; 

C,*b = *a^*a; *a = *b^*a;       D,*b = *a^*b; *a = *a^*b;

答案:D


7,同一进程内的所有线程除了共享全局变量外还共享() 

A,程序计数器     B,堆内存

C,errno              D,以上皆是 

答案:A 

       堆栈是保证线程独立运行所必须的。线程函数可以调用函数,而被调用函数中又是可以层层嵌套的,所以线程   必须拥有自己的函数堆栈,使得函数调用可以正常执行,而不受其他线程的影响。

       由于同一个进程中有很多个线程在同时运行,可能某个线程进行系统调用   后设置了errno值,而在该线程还没有处理这个错误,另外一个线程就在此时被调度器投入运行,这样错误值就有可能被修改。       所以,不同的线程应该拥有自己的错误返回码变量。


9,在ANSIC标准中,signal函数的声明如下void(*signal(int sig,void (*func)(int)))(int),则下面描述正确的是()

答案:signal是一个函数,其返回值是一个函数指针,该指针指向一个带一个int参数、无返回值的函数

首先解释void(*func)(int),

返回值类型 ( * 指针变量名) ([形参列表]);
注1:“返回值类型”说明函数的返回类型,“(指针变量名 )”中的括号不能省,括号改变了运算符的优先级。若省略整体则成为一个函数说明,说明了一个返回的数据类型是指针的函数,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例如:
int func(int x); /* 声明一个函数 */
int (*f) (int x); /* 声明一个函数指针 */
f=func; /* 将func函数的首地址赋给指针f */
或者使用下面的方法将函数地址赋给函数指针:
f = &func;
赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。
具体的,函数指针的应用举个例子:
比如你有三个函数
void hello(void) { printf("你好!"); }
void bye(void) { printf("再见!"); }
void ok(void) { printf("好的!"); }
typdef void (*funcptr)(void);   这样就构造了一个通用的函数,你用的时候可以这样:
void speak(int id)
{
funcptr words[3] = {&hello, &bye, &ok};
funcptr fun = words[id];
(*fun)();
}

      这样的话,如果speak(0)就会显示“你好!”

      speak(1)就会显示“再见!”
      speak(2)就会显示“好的!”

      用于处理参数和返回值的形式都一样,但是功能不确定的一组函数,可以使用函数指针。比如算术运算符,加、减、乘、除,都可以用typedef int (*calc)(int,int)代表,等等。


10,下面代码求n值,空白处填写代码正确的是()

void fact(int n)
{
	if (n == 1)
		return 1;
	______________
}
答案:return fact(n-1)*n


11,TCP通信中,其建立连接及终止连接分别需要经过几次握手()

答案:3 4

       TCP是一个面向连接的服务,面向连接的服务是电话系统服务模式的抽象,每一次完整的数据传输都必须经过建
立连接,数据传输和终止连接3个过程,TCP建立连接的过程称为三次握手,下面看一下三次握手的具本过程
TCP三次握手过程
       1 主机A通过向主机B 发送一个含有同步序列号的标志位的数据段给主机B ,向主机B 请求建立连接,通过这个数据段,
主机A告诉主机B 两件事:我想要和你通信;你可以用哪个序列号作为起始数据段来回应我.
       2 主机B 收到主机A的请求后,用一个带有确认应答(ACK)和同步序列号(SYN)标志位的数据段响应主机A,也告诉主机A两件事:
我已经收到你的请求了,你可以传输数据了;你要用哪个序列号作为起始数据段来回应我
       3 主机A收到这个数据段后,再发送一个确认应答,确认已收到主机B 的数据段:"我已收到回复,我现在要开始传输实际数据了

4次断开
       1 当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求
       2 主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1
       3 由B 端再提出反方向的关闭请求,将FIN置1
       4 主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束.
       由TCP的三次握手和四次断开可以看出,TCP使用面向连接的通信方式,大大提高了数据通信的可靠性,使发送数据端和接收端在数据正式传输前就有了交互,为数据正式传输打下了可靠的基础


12,函数foo的原型如下,则foo(0xAABB4455)返回结果()

unsigned int foo(unsigned int _in)
{
	unsigned char ret = 0,uc = -1;
	return _in >>24^uc;
}

答案:0x55

      因为在计算机系统中,数值一律用补码来表示和存储。所以uc其实是-1的补码,即11111111,而_in >>24^uc 先右移24位再和uc进行位异或,可得到0x55。


15,关于UDP通信,下面描述错误的是()

A, IP组播只能基于UDP协议进行通信    B, UDP通信是不可靠的,如需可靠传输,需上层应用支持

C, UDP是面向流字符的通信协议          D, UDP端口号与TCP端口号是相互独立的

答案:C

       众所周知UDP通信协议是不可靠的通信协议,其可靠性必须由上层应用实现。一般都会采用消息重传来实现其可靠性,采用消息重传的时候有两种方式,一种是发送者发起,另一种是接收者发起。

UDP是面向报文的,而TCP是面向字节流的


16,( )是DBMS的基本单位,它是用户定义的一组逻辑一致的程序序列。

A,程序      B, 命令      C, 事务      D, 文件
答案:C

17,函数foo原型如下,则foo(Ox32)打印结果是( )

void foo(char _case)
{
	switch (_case)
	{
	case '1':printf("1"); break;
	case '2':printf("2");
	case '3':printf("3"); break;
	case '4':printf("4");
	default:printf("error"); break;
	}
}
答案:23

因为Ox32是十六进制,转换成十进制是50,也就是字符'2' ,然后接着执行下一条语句。


三、填空题

1,在32位系统中,下面代码的打印结果为:_____,______

void foo(void)
{
#pragma pack(2)
	typedef struct
	{
		unsigned long index;
		char name[9];
		char *attr[4];
	}tSA,*ptSA;
#pragma pack()
	tSA sa[5];
	ptSA psa1 = sa, psa2 = &sa[4];
	unsigned long i = (unsigned long)psa1,j = (unsigned long)psa2;
	printf("%d,%d", psa2 - psa1, j - 1);
}


3,函数strtoull()实现字符串到数字的转换,其中ptr为字符串输入,base为转换进制(2~36之间),注意,下面实现中假设ptr以\0结尾,而且只包含'0'~'9','A'~'Z','a'~'z'字符。


正确代码如下:

#include<iostream>
#include<string>
using namespace std;
unsigned long long int stroull(const char* ptr,int base)
{
	unsigned long long ret=0;
	if (base < 2 || base>36 || ptr == NULL)return ret;
	while (*ptr)
	{
		int digit;
		if (*ptr >= '0'&&*ptr <= '9'&& *ptr < '0' + base)
		{
			digit = *ptr - '0';
		}
		else if (*ptr >= 'A'&& *ptr <= 'A'&& *ptr<'A' + base-10)
		{
			digit = *ptr - '0'+10;
		}
		else if (*ptr >= 'a'&&*ptr <= 'a'&& *ptr<'a' + base-10)
		{
			digit = *ptr - '0' + 10;
		}
		else
			break;
		ret *= base;
		ret += digit;
		ptr++;
	}
	return ret;
}
int main()
{
	string s;
	cin >> s;
	int base;
	cin >> base;
	cout<<stroull(s.c_str(), base)<<endl;
}


你可能感兴趣的:(海格面试题总结)