1. CVTE 嵌入式软件开发 一面面经 8.13(1h20m)
1.1 Socket中UDP/TCP相关的封装函数
int socket(int af, int type, int protocol);
int bind(int sock, struct sockaddr *addr, socklen_t addrlen);
int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen);
int listen(int sock, int backlog);
int accept(int sock, struct sockaddr *addr, socklen_t *addrlen);
int close(int fd);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
1.2 三次握手和四次挥手
1.3 malloc和new的区别
1.4 宏定义在什么阶段处理
宏定义是在预编译阶段展开的
1.5 全局变量、局部变量、静态变量存储在什么地方?
局部变量只在其所处的函数体中有效,因此存放在栈区。
全局变量在整个程序生命周期内都有用,因此存放在静态数据区。
静态变量与全局变量一样存放在静态数据区。
1.6 UDP/TCP区别
2. 联发科武汉嵌入式软件开发一二三面面经
2.1 什么是系统调用
以下内容来自维基百科:
在电脑中,系统调用(英语:system call),指运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务。系统调用提供用户程序与操作系统之间的接口。大多数系统交互式操作需求在内核态运行。如设备IO操作或者进程间通信。
linux在x86上的系统调用过程如下:
- 把系统调用的编号存入 EAX;
- 把函数参数存入其它通用寄存器;
- 触发 0x80 号中断(int 0x80)。
2.2 虚拟内存,32位机虚拟内存分布,虚拟内存怎么到物理内存(MMU)
linux内存分布杂论–(32位虚拟内存分布,高端内存; 64位虚拟内存分布,寻址方式)
2.3 为什么C++可以函数重载,C不行
2.4 文件系统相关
没有具体那个问题,楼主不会,面试官跳过了
3. 华为优招 消费者BG终端芯片-嵌入式面经
3.1 堆和栈的区别,各自用在什么地方
3.2 进程和线程有什么区别
总结一下:
- 一个是操作系统的调度单位,一个是CPU的调度单位
- 地址空间
- 通信机制
- 切换开销
- 资源
3.3 相同进程的多个线程可以共享什么资源
共享的资源:
- 堆
- 全局变量
- 静态变量
- 文件等公共资源
独享的资源:
- 栈
- 寄存器
3.4 多进程或多线程同步可能会造成什么问题
以下是我的答案(可能不完善,有补充可以留言区指出):
- 死锁
- 活锁
- 饥饿
- 优先级反转
- 护航现象
3.5 死锁和优先级反转,分别说下是如何造成的?
Linux同步机制 - 基本概念(死锁,活锁,饿死,优先级反转,护航现象)
3.6 中断和信号量的区别和各自的底层实现原理
网上没搜到合适的答案,自己总结一下:
中断是由外部中断源或者内部中断信号引发的,中断触发后,CPU会自动的到中断向量表中查询中断服务函数的地址,然后保存现场,执行中断处理函数,完成后恢复现场继续原来的工作。
信号量用于保证资源的安全使用,在一个线程或进程使用一个互斥资源时,信号量就会减一,当信号量值小与0时,请求信号量的进程或线程要被阻塞直到其他进程(线程)释放了该互斥资源。
3.7 中断向量表一般放在哪里,它有什么用?
当计算机刚启动时,首先会启动引导程序(BIOS),在BIOS中会把中断向量表存放在内存开始位置(0x00000000)。BIOS会有自己的一些默认中断处理函数,而当BIOS处理完后,会将计算机控制器转交给linux,而linux会在使用BIOS的中断向量表的同时重新设置新的中断向量表(新的地址保存在配置中的CONFIG_VECTORS_BASE),之后会完全使用新的中断向量表。
3.8 segmentation fault的原因是什么?对应的中断向量表的哪一个异常向量?
造成segment fault,产生core dump的可能原因!
总的来说就是访问了不该访问了内存地址,例如写一块只有读权限的内存。
段错误对应的异常向量网上没找到。。。
3.9 什么情况下会栈溢出?如何避免?
传递的参数太大,或者无限制的递归也可能导致栈溢出。
要避免传递大实参,改用指针,递归要设置出口。
3.10 操作系统有哪几种锁
4. 诺瓦-嵌入式一、二面经
4.1 C语言数组、链表、数组指针与指针数组、声明与定义
主要说一下数组指针与指针数组:
数组指针表示的是指向数组的指针,对于一维数组int a[100]
,其对应的数组指针为int *p = a
,对于二维数组int a[100][100]
,对应的数组指针是int (*p)[100]
。
指针数组表示一个元素都是指针的数组,例如int* p[100]
。
4.2 结构体内存对齐
这个主要是为了CPU处理的效率提出的,意思是对于32位的处理器,如果结构体中有一个字符和整型变量,那么这个字符就需要4字节对齐,即该结构体大小为8字节。
4.3 野指针与内存泄漏
野指针通常指那些为初始化的指针或者经过free操作后的指针,这些指针通常都指向无效内存,如果使用可能会造成非法访问,内存泄漏。
4.4 判断链表是否有环,去除链表重复元素
可以试着做一下leetcode的相关题目:
4.5 递归的使用注意
这个我感觉主要有两点:
- 递归的出口
- 注意递归时候的重复运算,导致递归效率下降
4.6 Uboot如何向内核传参
4.7 Uboot启动流程和作用
4.8 socket编程细节
见 1.1
4.9 TCP稳定传输保证
主要是考三次握手和四次挥手,见1.2
4.10 IIC为什么上拉电阻
时间线 2021/8/20:16/30