嵌入式软件面试【合集】
前言
“持续更新ing++”标题党实🔨,更新频率或许不高,但是一定会坚持(为了以后的高薪offer!)
相信努力都能获得回报,坚持终身学习的理念,征途漫漫,唯有奋斗!
大家的点赞、收藏是我源源不断的动力!
评论区欢迎大家一起来讨论啊~
一、嵌入式C语言
内存四区
堆区
:一般由程序员手动释放,若程序员不释放,程序结束时可能会由操作系统释放,malloc/free、new/delete都是对堆区进行操作栈区
:由编译器自动释放,主要存放程序局部变量、函数参数的值全局区
:全局区又分为全局变量区(static定义的变量)和常量区(const定义的常量)代码区
问: 如果给你的栈区很小,你该怎么处理
- 让其他存储区域去分担栈区的压力
- 减少函数的调用,特别是递归函数
关键字
static关键字的作用
- 在函数体里面,声明的静态变量不会因为函数的结束而被释放。
- 在函数体外,声明静态变量、静态函数,规定了该变量、函数的作用域只在当前模块(当前文件)
const关键字的作用
声明一个常量,该地址的值只读,不能修改
const int a;//常量a
int const a;//常量a
const int* a;//常量指针a,指向一个常量的指针,指针可以修改,指针指向的值不可修改
int* const a;//指针常量a,一个指针类型的常量,指针不可修改,指针指向的值可以修改
volatile关键字的作用
一个用volatile
声明的变量说该变量会被某些不可预知的因素修改,当使用该关键字声明后,每次使用该变量的时候都会重新去读取它的值。
应用场景
- 当某个变量的值会被中断处理函数修改时使用
- 多线程中的某个变量被多个任务共享时使用
- 某些寄存器的值会被硬件改变时使用
volatile和const可以同时使用么?这两个组合在什么情况下使用?
可以同时使用,例如只读的状态寄存器。
extern关键字的作用
extern
可以用于声明变量或者函数,表示变量或函数的定义在其他的文件中,提示编译器遇到该变量、函数时到其他模块去寻找其定义
不使用第三方变量如何交换两个数的值
方法一👇(有手就行)
//a = 1,b = 2
a = a + b;
b = a - b;
a = a - b;
方法二👇(Amazing!)
//位运算,异或
a = a ^ b;
b = a ^ b;
a = a ^ b;
//a ^ b ^ a 是等于b的
//a ^ b ^ a 是等于a的
大端小端
大端模式(Big-Endian)
:高字节存放在低地址
小端模式(Little-Endian)
:低字节存放在低地址
字节对齐
作用:提高CPU访问数据的效率
例如,假设一个处理器总是从存储器中取出8个字节,则地址必须为8的倍数。如果我们能保证将所有的double类型数据的地址对齐成8的倍数,那么就可以用一个存储器操作来读或者写值了。否则,我们可能需要执行两次存储器访问,因为对象可能被分放在两个8字节存储块中。
对齐规则、例子查看链接👉C语言字节对齐详解
指针
注意事项
野指针:只有定义没有初始化指针里面是一个垃圾值,这时候我们成为这个指针为野指针
- 不可以使用整形常量赋值一个指针变量,因为内存是操作系统分配我们的,不是我们随便取的
- 所有指针类型都是占用八个字节的存储空间
- 在被调函数中,通过形参来改变主调函数中某个变量值,函数需要返回多个参数时适用指针作为参数传值
指针与引用
指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名
。
- 不存在空引用,引用必须连接到一块合法内容
- 引用在创建时必须被初始化
- 一旦引用被初始化为一个对象,就不能指向另一个对象
- 使用引用时无须解引用
二、TCP/IP
OSI七层模式
物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
TCP三次握手四次挥手
TCP和UDP的区别
TCP
:提供面向连接的可靠传输服务
- 数据传输之前服务器和客户端要进行三次握手,会话结束后结束连接
- TCP保证数据按序到达,提供流量控制和
拥塞控制
,在网络拥堵的时候会减慢发送字节数
UDP
:提供无连接的传输服务
TCP拥塞控制
拥塞控制就是防止过多的数据注入到网络中,这样使得网络中的路由器或者链路不至于过载。
TCP拥塞控制方法主要包括:慢开始
,拥塞避免
,快重传
和快恢复
。
发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。
慢开始
是指发送方先设置cwnd=1,一次发送一个报文段,随后每经过一个传输轮次,拥塞串口cwnd就加倍,以指数形式增长。
设定一个门限值ssthresh(阈值),当cwnd > ssthresh,改用拥塞避免
算法。
拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,这样拥塞窗口按线性规律缓慢增长。
无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞,就把慢开始ssthresh设置为出现拥塞时的发送窗口大小的一半。然后把拥塞窗口设置为1,执行慢开始算法。
当接收方收到失序的报文段,按照快重传
,需要尽快发送对未收到的报文段的重复确认。
快恢复
是指当拥塞串口达到门限值,不直接开启慢启动算法,而是快恢复,快恢复就是收到三个重复的确认(可看作是网络已经拥塞了),此时并不执行慢开始算法,而是执行快恢复,就是新的门限值是原来的一半,直接进入拥塞避免阶段。
TCP滑动窗口
三、Linux
软链接与硬链接
命令:
ln
硬链接:ln source_node target_link
软链接:ln -s source_node target_link
区别
软链接
:实际上只是一段文字,里面包含着它所指向的文件的名字,系统看到软链接后自动跳到对应的文件位置处进行处理;可以对目录进行链接硬链接
:为文件新开设一个新的目录项,在Linux看来他们是等价的,所以硬链接不能链接两个不同文件系统上的文件,软链接可以;不可对目录进行链接
常考命令
chmod命令
作用:修改文件或者目录权限
使用样例
1、chmod abc filename
- chmod 777 file1.txt
- chmod 777 dir1
2、chmod u/g/o/a +/- r/w/x filename
u:所有者、g:文件组 、o:其他用户、a:全部
- chmod a+rwx file1.txt
- chmod u+rx,g-rx file2.txt
四、ARM
IIC
IIC时序
- 起始和终止信号:
SCL
线为高电平期间,SDA
线由高电平向低电平的变化表示起始信号;SCL
线为高电平期间,SDA
线由低电平向高电平的变化表示终止信号。 - 应答信号:I2C 总线协议规定,每传送一个字节数据后,都要有一个
应答信号
以确定数据传送是否被对方收到。应答信号由接收设备
产生,在SCL
为高电平期间,接收设备将SDA
拉低为低电平,表示数据传输正确,产生应答(ACK) - 数据传送:I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
I2C可以挂载多少个器件:IIC协议规定,在启动总线后第1字节的高7位是从节点的寻址地址,其中高四位为器件类型识别符,接着三位为片选,最后一位为读写位,当为1时为读操作,为0时为写操作,所以具体挂载多少个器件由I2C地址决定,7位寻址地址减去1个广播地址0x00不用,所以有2^7=128 - 1 = 127, 所以理论上可以挂127个从器件。
IIC仲裁
I2C总线上的仲裁分两部分:SCL线的同步和SDA线的仲裁。
- 同步
SCL同步是由于总线具有线“与”的逻辑功能,即只要有一个节点发送低电平时,总线上就表现为低电平。当所有的节点都发送高电平时,总线才能表现为高电平。正是由于线“与”逻辑功能的原理,当多个节点同时发送时钟信号时,在总线上表现的是统一的时钟信号。 - 仲裁
SDA线的仲裁也是建立在总线具有线“与”逻辑功能的原理上的。节点在发送1位数据后,比较总线上所呈现的数据与自己发送的是否一致。是,继续发送;否则,退出竞争。SDA线的仲裁可以保证I2C总线系统在多个主节点同时企图控制总线时通信正常进行并且数据不丢失。总线系统通过仲裁只允许一个主节点可以继续占据总线