嵌入式面试提纲
一、TCP/IP 协议
1.1 TCP/IP 五层模型概述
-
链路层(Link Layer)
-
包括网卡驱动、以太网、Wi‑Fi、PPP 等。负责把数据帧(Frame)在相邻节点间传输。
-
-
网络层(Internet Layer)
-
最典型的是 IP 协议 (IPv4/IPv6)。负责 路由选路、分片与重组。
-
其他:ICMP(Ping、目的不可达等)、ARP/ND (地址解析协议/邻居发现)。
-
-
传输层(Transport Layer)
-
TCP(Transmission Control Protocol):面向连接、可靠传输、有序到达、流量控制与拥塞控制。
-
UDP(User Datagram Protocol):无连接、不保证可靠性、低开销。
-
-
会话层、表示层(合并在“应用层”讨论)
-
应用层(Application Layer)
-
HTTP/HTTPS、FTP、SMTP/POP3、DNS、Telnet、SSH 等。
-
面试常问:
请简述 TCP/IP 模型与 OSI 七层模型的对应关系。
TCP 与 UDP 的区别?各有什么典型应用场景?
DNS 查询过程是怎样的?(迭代查询 vs 递归查询)
1.2 IP 协议要点
-
IP 地址与子网掩码
-
IPv4:32 位,常见写法
192.168.1.10/24
(子网掩码 255.255.255.0)。 -
IPv6:128 位,常见压缩写法
fe80::1ff:fe23:4567:890a/64
。
-
-
分片与重组
-
当数据包超过链路层最大传输单元(MTU)时,IP 层会分片。目的主机负责重组。
-
-
路由选择
-
路由表:根据目的 IP 匹配最长前缀,选择下一跳。
-
默认网关、直连网络、三层交换等。
-
面试常问:
如何计算某 IP 的网络地址、广播地址?
什么是 CIDR?为什么要划分子网?
简述 IP 分片过程及可能带来的问题(性能、重组失败)。
1.3 TCP 核心机制
-
三次握手(Three‑way Handshake)
-
客户端发送 SYN, seq = x
-
服务器收到 SYN, 回复 SYN‑ACK, seq = y, ack = x+1
-
客户端收到 SYN‑ACK, 回复 ACK, ack = y+1;连接建立
-
-
四次挥手(Four‑way Teardown)
-
主动关闭方发送 FIN, seq = a
-
对端回复 ACK, ack = a+1
-
对端发送 FIN, seq = b
-
主动关闭方回复 ACK, ack = b+1;连接关闭
-
-
流量控制(窗口机制):
-
发送端发送窗口(rwnd)由接收端根据缓冲区大小告知。
-
-
拥塞控制(慢启动、拥塞避免、快速重传、快速恢复):
-
拥塞窗口(cwnd)从 1 MSS 开始,遇到丢包或超时则触发相应算法。
-
面试常问:
TCP 三次握手的目的?如果少一次会发生什么?
TCP 四次挥手与三次挥手有什么区别?为什么需要四次?
怎么理解 TCP 的流量控制与拥塞控制?
如何粗略计算 RTT?什么是滑动窗口?
1.4 UDP 与其他协议
-
UDP(User Datagram Protocol)
-
“不可靠”传输:不保证到达、不保证顺序。
-
头部开销小,仅 8 字节:
源端口(2B) | 目标端口(2B) | 长度(2B) | 校验和(2B)
。 -
常见应用:DNS 查询、VoIP、视频流、DHCP。
-
-
ICMP(Internet Control Message Protocol)
-
用于网络诊断(ping)、不可达报告、TTL 超时等。
-
-
常见端口号
-
HTTP:80,HTTPS:443,DNS:53,SSH:22,FTP:21,SMTP:25,POP3:110,IMAP:143 等。
-
面试常问:
为什么 DNS 通常使用 UDP?遇到数据包丢失怎么办?
简述 ICMP 报文类型(Echo Request/Reply,Destination Unreachable 等)。
常见的服务器如何处理端口抢占和端口复用?
二、C 语言基础
以下内容面向零基础读者,从最基本的概念开始,一步步推进到链表、环形队列和指针的“进阶姿势”。
2.1 结构体(struct
)
2.1.1 概念
-
定义:把多个不同类型的变量组合成一个“整体”,类似现实世界中“一个学生有姓名、年龄、成绩”。
-
语法:
struct Student {char name[32];int age;float score; };
-
用法:
struct Student s1; strcpy(s1.name, "Alice"); s1.age = 20; s1.score = 92.5f; printf("Name=%s, Age=%d, Score=%.1f\n", s1.name, s1.age, s1.score);
-
内存对齐:
-
结构体成员通常按自然对齐方式存放,字段之间可能插入“填充字节(Padding)”以保证访问效率。
-
sizeof(struct)
可能 > 各成员大小之和。
-
面试常问:
struct A { char c; int x; }
与struct B { int x; char c; }
谁更省空间,为什么?如何传递结构体到函数?按值还是按引用?优缺点?
什么是匿名结构体,什么时候用?
2.2 联合体(union
)
2.2.1 概念
-
定义:联合体的所有成员 共用同一块内存,只要给其中一个成员赋值,就修改了这块内存。
-
语法:
union Data {int i;float f;char str[20]; };
-
用法:
union Data d; d.i = 100; printf("d.i=%d, d.f=%f\n", d.i, d.f); // f 与 i 共享内存,值不确定
-
大小:
-
联合体的
sizeof
等于其最大成员的大小,再加上对齐需要的填充。
-
面试常问:
结构体和联合体有什么区别?各自适用场景?
为什么联合体可节省内存?举例说明。
如何安全地在联合体里存放二进制数据(如网络协议报文)?
2.3 枚举(enum
)
2.3.1 概念
-
定义:枚举是一组具名整型常量的集合,让代码更易读。
-
语法:
enum Weekday { MON = 1, TUE, WED, THU, FRI, SAT, SUN };
-
如果不显式赋值,默认从 0 开始自动 +1。
-
-
用法:
enum Weekday today = WED; if (today == WED) { printf("It's Wednesday\n"); }
-
底层本质:枚举常量本质是整型 (C 默认
int
)。
面试常问:
枚举常量的底层类型是什么?可以指定底层类型吗?
枚举 vs
#define
的区别?哪种更好?如何把枚举转为字符串?有哪些常见技巧?
2.4 单向链表(Linked List)
2.4.1 概念
-
定义