0%

嵌入式面试题总结

C/C++题目

static关键字:

  1. static修饰局部变量:使其变为静态储存方式(静态数据区),在函数执行完之后不会被释放,继续背包留在内存中

  2. static修饰全局变量:使其只在本文件有效,其他文件不可连接或引用该变量

  3. static修饰函数:函数只在本文件有效,对其他文件是不可见的。静态函数好处:不用担心与其他文件的同名函数产生干扰,是对函数的一种保护机制

const关键字

  1. const修饰常量:定义时就初始化,以后不能更改

  2. const修饰形参:在该函数里不能改变

  3. const修饰类成员函数:该函数对成员变量只能进行只读操作。即:const类成员函数不能修改成员变量的值。

    1
    2
    3
    4
    5
    const int a = 10;    		//a是一个常整形数,10不能修改
    int const a = 10; //a是一个常整形数,10不能修改
    const int *a = 10; //a是一个指向常整型的指针,指针可以修改(a可以改),整型数(*a、10)不能修改
    int *const a = 10; //a是一个指向整形的常指针,指针不能修改(a不可以改),整型数(*a、10)可以修改
    int const *a const; //a是一个指向常整型数的常指针,指针、整型数都不能修改

代码编译到可执行文件的过程

  1. 预编译:hello.c —–> hello.i

  2. 编译:hello.i —–> hello.s

  3. 汇编:hello.s —–> hello.o

  4. 链接:hello.o —–> hello可执行文件

其中:.c .i .s 文件为文本文件

.o 与可执行文件为二进制文件

1
2
3
4
5
6
graph LR
A[hello.c] -- 预处理器cpp --> B[hello.i]
B[hello.i] -- 编译器ccl --> C[hello.s]
C[hello.s] -- 汇编器as --> D[hello.o]
E[printf.o] --包含--> D[hello.o]
D[hello.o] -- 链接器ld --> F[hello可执行文件]

内存四区、什么变量分别存储在什么区域,堆上还是栈上

  • 栈区:函数的参数值、返回值、局部变量等

  • 堆区:用于动态内存分配

  • 全局区(静态区):全局变量、静态变量、常量等。全局区=未初始化数据(bss) + 初始化数据(data) + 文字常量区(data)

  • 代码区:可执行文件的二进制代码(函数)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int a0=1;				//全局初始化变量。生命周期为整个程序运行期间;作用域为所有文件;存储位置为data段
    static int a1; //全局静态未初始化变量。生命周期为整个程序运行期间;作用域为当前文件;存储位置为bss段
    const static a2=0; //全局静态变量
    extern int a3; //全局初始化变量。

    void fun(void)
    {
    int a4; //局部变量。生命周期为fun函数执行期间。作用域为fun函数内部;存储位置为栈区
    volatile int a5; //局部易变变量
    return;
    }

堆区大还是栈区大

一般是堆区较大。

栈区:高地址->低地址,向下增长

堆区:低地址->高地址,向上增长

extern “C”的作用

可以在c++中使用c的以编译好的函数模块。

extern “C”在连接阶段起作用。

进程与线程

进程、线程是什么,有什么区别

  • 进程:资源分配的基本单位
  • 线程:CPU调度和分配的基本单位(程序执行的最小单位)

单核CPU,同一时间,只有一个进程在运行,并发执行,是因为切换速度过快

多核CPU,同一时间,可以执行多个进程

多线程、多进程优缺点

  1. 一个进程死了不影响其他进程;一个线程崩溃可能会影响它本身所处的进程。
  2. 创建多进程的花销大于创建多线程。
  3. 多进程通信因为需要跨越进程边界,不适合大量数据的传输,适合少量或密集数据传输。多线程无需跨越进程边界,适合线程间大量数据传输。并且多线程可以共享同一进程的共享内存和变量

多进程、多线程同步(通信)的方法

  • 进程间通信:
    1. 有名管道、无名管道
    2. 信号
    3. 共享内存
    4. 消息队列
    5. 信号量
    6. socket
  • 线程通信:
    1. 信号量
    2. 读写锁
    3. 条件变量
    4. 互斥锁
    5. 自旋锁

什么时候用进程、什么时候用线程

  1. 创建和销毁较频繁使用线程,因为创建进程开销大
  2. 需要传输大量数据使用线程,因为多线程切换快,不需要跨越进程边界
  3. 安全稳定选进程,快速频繁选线程

进程线程的状态切换

  1. 就绪状态:进程已获得除CPU外的所有资源,只等待CPU时的状态。一个系统会将多个处于就绪状态的进程排成一个就绪队列
  2. 执行状态:进程已获得CPU使用权,正在执行。单核处理器系统中,处于执行状态的进程只有一个;多核处理器,有多个处于执行状态的进程
  3. 阻塞状态:正在执行的进程由于某种原因而暂时无法继续执行。通常导致进程阻塞的典型事件有:请求I/O,申请缓冲空间等。一般,处于阻塞状态的进程会排成一个队列。

image-20210315203009813

父进程、子进程

父进程调用fork()函数后,克隆出一个子进程,子进程和父进程拥有相同内容的代码段、数据段和用户堆栈。父进程和子进程谁先执行不一定,看CPU。所以我们一般会设置父进程等待子进程执行完毕。

什么是上下文切换

  • 进程上下文:一个进程在执行的时候,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容,当内核需要切换到另一个进程是,他需要保存当前进程的所有状态、即保存当前进程的进程上下文,以便再次执行该进程时,能够恢复切换时的状态,继续执行。
  • 中断上下文:由于触发信号,导致CPU中断当前进程,转而去执行另外的程序。那么当前进程的所有资源要保存,比如堆栈和指针。保存后转而去执行中断处理程序,快读执行完毕返回,返回后恢复上一个进程的资源,继续执行。

网络编程

TCP、UDP区别

  • TCP—传输控制协议。面向连接的可靠的字节流服务。当客户端和服务端彼此交换数据前,必须在双方之间建立一个TCP连接,之后才能传输数据。

  • UDP–用户数据报协议。是一个简单的面向数据报的运输层协议。UDP不提供可靠性,只是把应用程序传给IP层的数据报发送出去,但是并不能保证他们能到达目的地。

    1. TCP面向连接、UDP面向无连接。

    2. UDP程序结构简单

    3. TCP面向字节流,UDP基于数据报

    4. TCP保证数据正确性,UDP可能丢包

    5. TCP保证数据顺序到达,UDP不保证

TCP、UDP优缺点

协议 优点 缺点
TCP 可靠稳定 慢、效率低,占用系统资源较高,易被攻击
UDP 快、比TCP稍安全 不可靠、不稳定

TCP、UDP适用场景

TCP:传输一些对信号完整性,信号质量有要求的信息。

UDP:对网络通信质量要求不高,要求通信速度快的场景。

TCP为什么可靠

因为TCP传输的数据满足3个条件:不丢失、不重复、按顺序到达

OSI典型模型网络模型

OSI模型 linux tcpip模型 常用协议 网络设备
应用层 应用层 telnet/DHCP/TFTP/FTP/MQTT/NFS/DNS/FTP/SNMP
表示层
会话层
传输层 传输层 TCP/UDP 四层交换机
网络层 网络层 IP/ICMP/IGMP/ARP 路由器,三层交换机
数据链路层 网络接口层 Ethernet/PPP/PPPoE 交换机(二层交换机),网桥,网卡(一半物理层,一半链路层)
物理层 中继器、集线器

单片机、RTOS

Linux

-------------THE END-------------

欢迎关注我的其它发布渠道