深信服笔试题1

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;
}

算法复杂度:


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的区别
点击打开链接





































  • 3
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值