linux系统编程面试题

说明:所有题目均摘录于网络以及我所见过的面试题目,欢迎补充!

 

无特殊说明情况下,下面所有题s目都是linux下的32位C程序。

1、堆和栈有什么区别?

 (1)栈由操作系统分配和释放;堆则是程序员手动去申请释放;

(2)栈是一块连续的内存区域,也就是栈顶地址和栈的最大容量是系统规定的;堆是不连续的内存区域,是因为系统使用链表来存储空闲内存地址。

(3)对于栈,在函数调用时,第一个入栈的是函数调用语句的下一条可执行语句的地址,然后是函数参数(一般是从右到左)入栈,最后是局部变量(静态变量不入栈)。函数调用结束后,局部变量先出栈,然后是参数。对于堆,一般在堆头部用一个字节存放堆大小,其他内容由程序员安排。

2、栈可能是向上生长,也可能是向下生长,试写一段代码,判断栈生长方向?

解析:我们可以根据局部变量入栈的特性来判断,由栈的连续性还有局部变量入栈的方式,我们可以来判断栈的生长方向。

bool  StackDownward()
{
   int a = 1;
   int b = 2;
  
  if(&a > &b)
  {
     return true;   
  } 
  else
  {
     return false;
  }  
}

 3、定义一个宏,来求结构体中某成员的偏移量

#define offsetof(TYPE, MEMBER)  ((size_t) &((TYPE *)0)->MEMBER )

解析:将0转换为(TYPE *)类型,也就是结构体首地址为0,因此数据成员的偏移量也就是相对于0的偏移量,直接取该成员地址就是所求的偏移量。

4、判断大小端

可用两种方法,如下:

BOOL IsBigEndian()  
{  
    int a = 0x1234;  
    char b =  *(char *)&a;  //通过将int强制类型转换成char单字节,通过判断起始存储位置。即等于取b等于a的低地址部分  
    if( b == 0x12)  
    {  
        return TRUE;  
    }  
    return FALSE;  
}

联合体union的存放顺序是所有成员都从低地址开始存放,利用该特性可以轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写:

BOOL IsBigEndian()  
{  
    union NUM  
    {  
        int a;  
        char b;  
    }num;  
    num.a = 0x1234;  
    if( num.b == 0x12 )  
    {  
        return TRUE;  
    }  
    return FALSE;  
}

关于大小端的概念:

1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
2) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。


举一个例子,比如数字0x12 34 56 78在内存中的表示形式为:

1)大端模式:

低地址 -----------------> 高地址
0x12  |  0x34  |  0x56  |  0x78

2)小端模式:

低地址 ------------------> 高地址
0x78  |  0x56  |  0x34  |  0x12

可见,大端模式和字符串的存储模式类似。

参考:

1、《详解大端模式和小端模式》https://blog.csdn.net/ce123_zhouwei/article/details/6971544

原文地址:https://www.cnblogs.com/ralap7/p/9153470.html