深信服笔试题1

时间:2022-05-30 14:39:22

1  char   *p   =   "hello   world";       p存储在()  //堆栈
    char   p[ ]   =   "hello   world";     p存储在()  //堆栈
  全局变量  //数据段
  static变量  //数据段
  分别在哪个地方?  
  1. 数据段   2. 代码段   3. 堆   4. 堆栈  

笔记:

  int   a   =   0;   //全局数据区
char *p1; //全局数据区,分配该区时内存全部清零

main() {
int b; 栈
char s[ ] = "abc"; // 栈
char *p2; // 栈
char *p3 = "123456"; //123456\0在常量区,p3在栈上。
static int c = 0; // 全局数据区

p1 = (char *)malloc(10);
p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在*数据区。

strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456" 优化成一个地方。
}

总结:

五大内存分区 :
在C++中,内存分成5个区,他们分别是堆、栈、*存储区、全局/静态存储区和常量存储区。

栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量存储区。里面的变量通常是局部变量、函数参数等。 
堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。 
*存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。 
全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。 
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。
 

2.  %   &   .  &&   <= = 那个优先级别最高

.  &    %   <=   &&    =

3. 以下哪些通信方式是可靠的通讯方式    (1)信号 (2)管道 (3)消息 (4)tcp (5)udp (6)串口I/O  


4.(M)?(a++):( a--),此处的M与下面哪一项是等价       

AM==OBM==1CM=ODM=1


5. Unix的启动顺序?

UNIX系统的启动过程如下:
1    用户打开计算机电源。
2    计算机自动执行ROM引导程序。
3    将第一块硬盘的boot区调入内存并执行。硬盘的boot区存有硬盘的分区信息和驱动程序。
4    将硬盘的活动分区上的bootstrap程序调入内存并执行。bootstrap程序位于该活动分区上的第0号块中。
5    将UNIX的启动程序/boot调入内存并执行。
6   将UNIX的内核程序/unix调入内存并执行。
7   检测并配置内存和硬件设备。
8    启动/etc/init进程。init将/etc/inittab调入内存,并根据启动层次的不同,选择/etc/inittab内不同的程序来执行。对于多用户来说,init会执行/sbin/bcheckrc和/sbin/brc进程,最后由/sbin/rc2进程将系统带入多用户使用环境,并为每个终端启动/etc/getty一个进程等待接收用户的登录。


6. 数制转换1512进制和九进制

10010111,177


7. 原码,反码和补码。
8. linux下,查看目录大小的命令是:du sh dirname
笔记:du命令详解
9.  修改文件属性的命令是:chomd
笔记:chmod命令详解
10. 切换为其他用户身份的命令是:su。
11. 插入排序算法。

· 有一个数组a[0]  a[i-1]为从小到大排序,a[i]a[count-1]没有排序,请您添加3条语句使它们按照从小到大排序。

int insert_sort(int a[],int count){	 for(int i=1;i<count;++i)	 {	 int j,t;	 t=a[i];	 (j=i-1;)	 while(j>=0&&t<a[j])         {		 (a[j+1]=a[j];)		 j--;         }        (a[j+1]=t;)}return 0;}

算法复杂度:

深信服笔试题1

12. VC中有哪些方法避免C编程中的头文件重复包含:

1).

#ifndef   !!!!

#def !!!!

#endif

2).
#pragma once 只要在头文件的最开始加入这条指令就能够保证头文件被编译一次
13.  在C++extern "C"的作用。
 

extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。

extern "C"是链接申明(linkage declaration),被extern "C"修饰的变量和函数是按照C语言方式编译和链接的。

14. 编程中异步IO和同步IO有什么区别?说说你可知道的几种IO?

简单的说“同步IO在编程里,一般是指某个IO操作执行完后,才可以执行后面的操作。异步IO则是,将某个操作给系统,主线程去忙别的事情,等内核完成操作后通知主线程异步操作已经完成。”
如果IO请求需要大量时间执行的话,异步文件IO方式可以显著提高效率,因为在线程等待的这段时间内,CPU将会调度其他线程进行执行,如果没有其他线程需要执行的话,这段时间将会浪费掉(可能会调度操作系统的零页线程)。如果IO请求操作很快,用异步IO方式反而还低效,还不如用同步IO方式。
几种IO:read/write;
 

15. 使用异步socket编程,通常因为网络拥塞send不出数据,会获得什么样的错误码(windows下举例),通常如何处理这种情况?

非阻塞SOCKET,SEND不出数据的原因有2个吧,TCP下连接断开了和该SOCKET处在阻塞状态(也就是说在发送数据中)。UPD发不出只有TCP后面的情况。

处理的办法就是记录下该SOCKET的状态,当状态为阻塞的时间,放入缓冲,当该SOCKET再次可写时,发送。

16. 在vc中怎样解决内存泄漏的问题(release版本)
(1)放置宏assert( )。assert是宏,而不是函数。在C的assert.h头文件中。assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行。assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。
(2)CRT调试堆函数
17. 将程序移植到不同的32位cpu中,经常出现结构字节对齐和大小端的问题,有哪些方法避免?
结构体字节对齐:
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。
每个特定平台上的编译器都有自己的默认“对齐系数”(32位机一般为4,64位机一般为8)。我们可以通过预编译命令#pragma pack(k),k=1,2,4,8,16来改变这个系数,其中k就是需要指定的“对齐系数”;也可以使用#pragma pack()取消自定义字节对齐方式。
 

规则:

  1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。

  2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。

举例来说,
1).
#include <bits/stdc++.h>#pragma pack(2)struct X{	char a;	int b;	double c;};int main(){	X x;	std::cout << sizeof(x) << std::endl;	return 0;}

首先系统会将字符型变量a存入第0个字节(相对地址,指内存开辟的首地址);然后在存放整型变量b时,会以2个字节为单位进行存储,由于第一个二字节模块已有数据,因此它会存入第二个二字节模块,也就是存入到2~5字节;存放双精度实型变量c时,由于其宽度为8,其存放时会以2个字节为单位存储(2和8的最小值是2),也就是会找到第一个空的且是2的整数倍的位置开始存储,将c存入第四个2字节模块。总共14个字节,正好是二字节(#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个)的整数倍。
2).
 
#include <bits/stdc++.h>#pragma pack(4)struct X{	char a;	int b;	double c;};int main(){	X x;	std::cout << sizeof(x) << std::endl;	return 0;}
首先系统会将字符型变量a存入第0个字节(相对地址,指内存开辟的首地址);然后在存放整型变量b时,会以4个字节为单位进行存储,由于第一个4字节模块已有数据,因此它会存入第二个4字节模块,也就是存入到4~7字节;存放双精度实型变量c时,由于其宽度为8,其存放时会以4个字节为单位存储(4和8的最小值是4),也就是会找到第一个空的且是4的整数倍的位置开始存储,所以将c存入第3个4字节模块。总共16个字节,正好是4字节(#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个)的整数倍。
大小端问题可以通过全部转换为网络字节序进行处理:
uint32_t htonl(uint32_t hostlong);uint16_t htons(uint16_t hostshort);uint32_t ntohl(uint32_t netlong);uint16_t ntohs(uint16_t netshort);
大端模式是指高字节数据存放在低地址处,低字节数据放在高地址处。
小端模式是指低字节数据存放在低地址处,高字节数据放在高地址处。
18. 实现函数atoi( )和itoa( )
#include <bits/stdc++.h>using namespace std;void itoa(int i,char* string){  int flag = 0;  if(i<0)  {    string[flag++] = '-';    i = -i;  }    int j = i;  int pow;  for(pow=1;j>10;j/=10)  {    pow *= 10;  }  cout << pow << endl;  for(;pow>0;pow/=10)  {    string[flag++] = '0' + i/pow;    i%=pow;  }  string[flag++] = '\0';}int main(){  char s[10];  itoa(1234,s);  cout << "s=" << s << endl;}
#include <bits/stdc++.h>using namespace std;int atoi(char* s){  if(!s)    return -1;   int res = 0;  bool fushu = false;  int flag = 0;  if(*(s+flag)=='-')  {    fushu = true;    flag++;  }    vector<int> temp;  while(*(s+flag)!='\0')  {    if(*(s+flag)>='0' || *(s+flag)<='9' )    {      temp.push_back(*(s+flag)-'0');      flag++;    }    else      return -1;  }    int pow = temp.size()-1;  for(int i=0;i<temp.size();i++)  {    res += temp[i]*10^pow;    pow--;  }  return fushu?-res:res; }int main(){  cout << atoi("-1234") << endl;}

19. 异步socket编程中,send不出数据的错误码是什么,(举LinuxWindows为例),你是怎么处理的?

非阻塞SOCKETSEND不出数据的原因有2个吧,TCP下连接断开了和该SOCKET处在阻塞状态(也就是说在发送数据中)。UPD发不出只有TCP后面的情况。

处理的办法就是记录下该SOCKET的状态,当状态为阻塞的时间,放入缓冲,当该SOCKET再次可写时,发送。


20. new和malloc,free和delete的区别
点击打开链接