嵌软八股大全12 - 内存管理、网络相关问题

1、内存管理?

1.1、MCU 的程序存储在哪里?运行时如何寻找要执行的程序?

MCU 的程序经过预处理、编译、汇编、链接之后生成的二进制可执行文件存储在了主 FLASH 中,这个主 FLASH 在 32 位 MCU 的 4GB 寻址范围内一般有一个固定的起始地址,对于 STM32F4 为 0x08000000,MCU 上电/复位后运行的程序会从这个主 FLASH 的首地址处开始执行程序,不会有从存储介质加载应用程序代码到 RAM 中然后再执行的过程,这一点与能跑 Liunx 操作系统的高级 CPU 不同

因此 MCU 的主 FLASH 内存模型为四大分区:代码、数据(.data 和 .bss)、堆、栈

1.2、内存分区?

C/C++ 程序经过预处理、编译、汇编和链接四个步骤后会生成二进制的可执行文件,这个可执行文件在运行时会在内存中有特定的布局,布局如下

  1. 文本段(代码段、.txt),存放程序的实际机器指令代码
  2. 数据段(.data),存放已初始化的全局变量和静态变量
  3. BSS 段(.bss),存放未初始化的全局变量和静态变量
  4. 堆(Heap),动态分配的内存
  5. 栈(Stack),存放函数调用的局部变量、函数参数、返回地址等

1.3、堆栈区别?

栈 堆
申请方式 系统自动申请释放内存 用户手动申请释放内存
申请大小 向低地址申请的一块连续的内存空间 向高地址申请的不连续的内存空间
申请效率 使用的是一级缓存 存放在二级缓存中,速度要慢些

1.4、程序段还有哪些区?

除了上述常见的几个内存分区外,可能还存在如下几个内存区域

  1. .rodata 段,只读数据段,常量字符串和只读常量
  2. .init 段,初始化代码,通常在程序启动时运行一次
  3. ...

1.5、哪些地方会用到栈?

  1. 函数调用和返回
    1. 调用一个函数时,栈用于保存调用者的现场(例如返回地址和寄存器状态)
    2. 局部变量通常被分配在栈上
    3. 函数返回
  2. 递归调用
  3. 中断处理
  4. 上下文切换

1.6、内存分配函数?

如果系统中只有 10K 内存,而我要分配 12K,能分配成功吗?如果能,那么将分配到的区域用 memset 进行初始化,会成功吗?

1.7、静态局部变量与局部变量的区别?

静态局部变量是使用 static 声明的局部变量,主要有如下几点不同:

  1. 生命周期不同
    1. 静态局部变量生命周期持续到整个程序结束
    2. 局部变量生命周期持续到这个局部段结束
  2. 初始化不同
    1. 静态局部变量未显示初始化默认值为 0
    2. 局部变量未显示初始化默认值为未定义值
  3. 所在的内存分区不同
    1. 静态局部变量处于数据段(显式初始化)或 .bss 段(未显示初始化)
    2. 局部变量处于栈上

1.8、为什么 static 修饰局部变量只会初始化一次?

被 static 关键字修饰的变量会存放在 .data 或者 .bss 区域(静态区),而局部变量存放在栈区,他们会在进入函数时重新分配,退出函数时销毁,而静态的局部变量生存周期延长到整个程序的结束,只会在程序加载时初始化一次,不管函数调用几次

1.9、为什么局部变量未定义时,每次初始化的结果是不确定的?

有如下几点原因:

  1. 栈内存的管理
    1. 局部变量分配在栈上,栈一般用于存储函数调用的局部变量、返回地址、函数参数等
    2. 当我们定义了一个局部变量且没有显示初始化时,我们不知道之前这个位置保存了什么值
    3. 因此局部变量的值未知/随机
  2. 编译器的行为
    1. 编译器尽量避免增加不必要的运行时开销
    2. 如果编译器为每个局部变量都自动初始化为零或其他默认值,会增加额外的操作,并降低程序的效率

1.10、局部变量的值是个真随机数还是个伪随机数?

不是真随机数,也不是伪随机数,准确的说应该是“未定义值”,这些值是由于栈内存中残留的数据所导致的,因此它们是不可预测的,但并不是真正意义上的随机数

1.11、连续调用同一个函数两次,他的局部变量初始化结果是否会一致?

大概率不一致,栈上的内容在每次函数调用时可能不同,所以不能保证结果一致

1.12、静态区的创建和消失是在什么时候?

编译时确定存储位置和地址信息 程序加载时分配内存并进行初始化 程序结束时释放

1.13、我在 windows 里面运行了多个进程,其中一个进程执行完了,他的静态区会如何处理?

当一个进程结束时,操作系统会负责处理清理工作,释放与该进程相关的所有资源

1.14、栈的工作机制是什么?

栈,是一种后进先出(LIFO)的数据结构,基本操作包括 PUSH 和 POP,栈一般有如下几个用途:

  1. 函数调用和返回
  2. 中断处理
  3. 上下文切换

2、Network

2.1、OSI 模型?

OSI 模型从下到,具体如下所示:

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

欢迎来到我的专栏,在这里,我将整理并分享2024年各大企业的真实笔试/面试真题,同时还整理了嵌入式软件相关的八股知识。专栏内容涵盖C/C++基础、嵌软常见通信协议、ARM、FreeRTOS、Linux OS相关问题汇总,希望能帮助求职者了解考试趋势和嵌入式常见考点。无论你是准备面试,还是希望提升自己的专业知识,这里都能为你提供宝贵的参考和学习资源。

全部评论

相关推荐

评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务