每日嵌入式面经-操作系统(Linux)

一、常见 Linux 命令及其使用

(一)文件操作命令

ls

列出目录内容

查看文件系统目录结构、查找文件

可搭配 -l(长格式显示详情)、-a(显示隐藏文件)等选项

cd

切换目录

在不同项目文件夹间穿梭

无特殊输出,直接改变当前工作目录

cp

复制文件或目录

备份代码文件、配置文件

-r 选项用于递归复制目录

mv

移动或重命名文件 / 目录

整理项目文件架构

可在同一文件系统内移动或重命名,跨文件系统移动相当于复制加删除

rm

删除文件或目录

清理临时文件或错误安装的软件包

-r 选项递归删除目录,操作不可逆,需谨慎使用

  1. ls :用于列出目录内容。例如,ls -l 可以以长格式显示文件详情,包括文件类型、权限、所有者、大小、修改时间等;ls -a 能显示隐藏文件。在嵌入式项目中,常用于查看文件系统目录结构,快速定位所需文件。
  2. cd :切换目录。如 cd /home/user 切换到用户主目录,cd .. 返回上一级目录,方便在不同项目文件夹间穿梭。
  3. cp :复制文件或目录。cp file1 file2 复制文件,cp -r dir1 dir2 递归复制目录。在备份代码文件、配置文件时常用。
  4. mv :移动或重命名文件 / 目录。mv file1 file2 可重命名文件,mv file1 dir/ 将文件移动到指定目录,在整理项目文件架构时不可或缺。
  5. rm :删除文件或目录。rm file 删除文件,rm -r dir 递归删除目录。需谨慎使用,删除操作不可逆,常用于清理临时文件或错误安装的软件包。

(二)文本处理命令

cat

显示文件内容

查看配置文件、日志文件片段

可一次性查看小文件全部内容,搭配重定向符可输出内容

more/less

分页显示文件内容

查看大日志文件

less 支持上下翻页,比 more 更灵活

grep

文本搜索

快速定位日志中的错误信息、查看内核日志中与特定硬件相关部分

可结合管道符与其它命令搭配使用

awk/sed

强大的文本处理

awk 按列处理文本统计信息、sed 批量修改配置文件内容

  1. cat :显示文件内容。cat file 可一次性查看小文件全部内容;搭配重定向符,如 cat file1 > file2 可将文件 1 内容输出到文件 2。用于查看配置文件、日志文件片段。
  2. more/less :分页显示文件内容。more file 和 less file 都能实现分页,但 less 支持上下翻页,更灵活,适合查看大日志文件。
  3. grep :文本搜索工具。grep "pattern" file 在文件中查找包含特定模式的行,如 grep "error" logfile 快速定位日志中的错误信息;可结合管道符,如 dmesg | grep "usb" 查看内核日志中与 USB 相关部分。
  4. awk/sed :强大的文本处理工具。awk 善于按列处理文本,如统计日志中某列的错误次数;sed 用于替换文本内容,如批量修改配置文件中的 IP 地址格式。

二、Linux 嵌入式基础底层支持

(一)Linux 内核与文件系统

  1. 内核空间与用户空间内核空间包含内核代码、驱动程序等,负责系统核心功能,如进程调度、内存管理、设备驱动。
  2. 用户空间运行应用程序,二者通过系统调用接口(syscall )交互。
  3. 理解这一概念对分析系统崩溃、驱动开发问题至关重要。例如,当应用频繁访问硬件设备时,需通过系统调用进入内核空间调用驱动程序完成操作。内核版本选择对嵌入式系统影响深远。不同硬件平台适配不同内核版本,新版本虽引入新特性、修复漏洞,但也可能与旧硬件驱动兼容性不佳。如基于 ARM Cortex - A8 的开发板,可能需使用特定稳定内核版本确保外围设备正常工作。

(二)设备驱动开发

  1. 设备模型与驱动架构Linux 设备模型将设备抽象为总线、设备、驱动三级结构。总线代表设备连接方式(如 USB、I2C),设备是硬件实体,驱动实现设备操作功能。
  2. 了解设备模型有助于组织驱动代码,使其通用、可移植。例如,开发一个 I2C 接口的传感器驱动,需注册到 I2C 总线,遵循总线设备通信规范。
  3. 驱动程序分为字符设备、块设备和网络设备驱动。字符设备(如串口、按键)以字节流方式访问,块设备(如硬盘、U 盘)以数据块为单位操作,网络设备处理数据包收发。
  4. 不同设备驱动开发方法各异,需掌握对应的数据结构和操作函数。如编写字符设备驱动,要实现 open、read、write、ioctl 等文件操作函数。

三、常见高频面试考点

1.Linux系统中进程间通信的方式有哪些?各自的优缺点及应用选择?

inux系统中有多种进程间通信(Inter-Process Communication,IPC)的方式,每种方式都有其优缺点,适用于不同的场景。以下是一些常见的进程间通信方式:

管道(Pipe):一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用,进程的亲缘关系通常是指父子进程关系。

优点: 简单易用,适用于单向通信,可以通过shell命令实现。

缺点: 只能用于具有亲缘关系的进程之间,单向通信。

应用选择: 适用于父子进程之间或通过shell串联的进程。

命名管道(Named Pipe,也称为FIFO):命名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

优点: 允许无关的进程之间进行通信,通过文件系统的名字进行访问。

缺点: 只能用于单向通信。

应用选择: 适用于无关联的进程之间的单向通信。

消息队列(Message Queues):消息队列是由消息的链表,存放在内核中并由消息队列标识 符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

优点: 允许多个进程之间进行双向通信,支持异步通信。

缺点: 数据复制开销相对较大。

应用选择: 适用于需要异步通信、通过消息传递进行数据交换的场景。

共享内存(Shared Memory):映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。

优点: 最快的IPC方式,因为数据直接在进程间共享,无需复制。

缺点: 需要显式的同步机制,可能引起竞态条件。

应用选择: 适用于频繁的大量数据交换的场景,但需要谨慎处理同步。

信号量(Semaphores): 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。

优点: 提供了一种同步机制,防止竞态条件。

缺点: 使用复杂,容易引起死锁。

应用选择: 适用于需要同步进程并控制资源访问的场景。

套接字(Socket):是一种提供网络通信的编程接口,允许进程通过网络进行数据交换,使得不同主机上的进程能够进行通信。

优点: 跨网络通信,可用于不同主机上的进程通信。

缺点: 相对复杂,性能开销较大。

应用选择: 适用于网络通信或需要在不同主机上的进程之间进行通信的场景。

每种IPC方式都有其适用的场景和限制,选择取决于应用的需求和设计目标。通常,根据通信的性质、进程间关系以及数据交换的频率等因素来选择合适的IPC方式。

2.多进程与多线程的区别?

在Linux系统中,多进程和多线程都是用于并发执行的编程模型,但它们之间有一些关键的区别:

基本单位:

多进程: 每个进程都是独立的执行实体,有独立的地址空间、文件描述符和系统资源。

多线程: 所有线程都存在于同一进程中,共享相同的地址空间和系统资源。

资源开销:

多进程: 进程之间的切换涉及到上下文切换,通常需要更多的系统资源和时间。每个进程有独立的资源副本。

多线程: 线程之间切换更轻量,因为它们共享相同的地址空间和大部分资源。线程切换通常比进程切换更快。

通信和同步:

多进程: 进程之间通信复杂,通常需要采用IPC(进程间通信)机制,如管道、消息队列、共享内存等。同步通过信号量等机制实现。

多线程: 线程之间可以直接共享数据,通信相对容易。同步可以通过互斥锁、条件变量等机制来实现。

健壮性:

多进程: 进程之间的隔离性较强,一个进程的崩溃通常不会影响其他进程。

多线程: 一个线程的崩溃可能导致整个进程的崩溃,因为它们共享相同的地址空间和资源。

编程复杂度:

多进程: 编写和维护多进程程序可能更为复杂,因为进程之间的通信和同步涉及到更多的细节。

多线程: 编写多线程程序相对简单,因为线程之间共享数据,但需要小心处理共享资源的同步问题。

适用场景:

多进程: 适用于需要更强隔离性、独立性的任务,或者需要充分利用多核处理器的情况。

多线程: 适用于需要轻量、共享数据的任务,特别是IO密集型任务,可以通过多线程提高并发性能。

3.什么时候选多进程什么时候选多线程?

从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

选择多线程的情况:

共享数据:如果任务需要共享大量数据,而不涉及复杂的数据保护机制,多线程可能是一个合适的选择,因为线程之间共享相同的地址空间。

轻量级任务:多线程适用于轻量级的任务,例如IO密集型操作,其中线程切换的开销相对较小。

共享资源的频繁访问:当任务需要频繁访问和更新共享资源时,多线程可能更为方便,因为线程之间可以直接访问相同的内存空间。

开发和维护的简易性:多线程通常更易于编写和维护,因为线程之间共享相同的上下文,共享数据更为直接,减少了通信和同步的复杂性。

选择多进程的情况:

隔离性和独立性:如果任务需要高度的隔离性和独立性,以防止一个任务的崩溃影响其他任务,多进程是一个更好的选择,因为进程之间有独立的地址空间。

并行计算:多进程适用于需要充分利用多核处理器并进行并行计算的情况,每个进程可以在一个独立的核上运行。

复杂的数据保护需求:如果任务涉及到复杂的数据保护机制,需要避免共享内存引起的竞态条件,多进程可能更为合适。

稳定性要求较高:如果任务对稳定性有很高的要求,即使一个进程崩溃也不会影响其他进程,多进程可能更为安全。

任务独立性较强:当任务之间相对独立,不需要频繁通信的时候,多进程可能更为合适。

4.进程间的竞态是指什么?

进程间竞态是指多个进程或线程在访问共享资源时,其最终结果取决于它们执行的相对顺序,而这个顺序是不确定的。竞态条件可能导致意外的行为和不确定性,因为多个进程试图并发地访问和修改共享资源,而没有适当的同步机制来协调它们的操作。

典型的竞态条件发生在以下情况下:

共享资源: 多个进程或线程共享同一资源,例如共享内存区域、文件、变量等。

并发访问: 进程或线程在同一时间间隔内并发地访问共享资源。

至少一个操作是写操作: 至少一个进程在访问共享资源时执行了写操作。

缺乏同步机制: 没有足够的同步机制来确保进程或线程之间的协调和互斥。

竞态条件可能导致不一致的结果、数据损坏和程序错误。

典型的竞态条件包括:

读-改-写竞态: 多个进程同时读取共享变量,然后一个或多个进程对其进行修改,并最终写回。由于并发执行,写回的结果可能不符合预期。

写-写竞态: 多个进程同时尝试写入共享变量,最后写入的值可能取决于执行的相对顺序。

读-写竞态: 一个进程在另一个进程执行写操作之前读取了共享变量,可能导致读取到过时或无效的数据。

避免竞态条件通常需要使用同步机制,例如互斥锁、信号量、条件变量等。这些机制可以确保在任何给定时间点只有一个进程或线程能够访问共享资源,从而避免了竞态条件的发生。

5.什么是进程死锁?造成死锁原因是什么?

进程死锁是指两个或多个进程被阻塞,彼此都在等待对方释放资源,导致它们无法继续执行下去的状态。在死锁中,每个进程都持有某些资源,并等待其他进程释放它们所需的资源。

死锁发生的主要原因包括以下四个必要条件,通常称为死锁的四个必要条件:

互斥条件(Mutual Exclusion):进程对资源的访问是互斥的,即同一时刻只能有一个进程使用该资源。

持有和等待条件(Hold and Wait):进程可以持有一些资源,并等待获取其他资源。如果一个进程在等待资源的同时保持了其他资源,就可能导致死锁。

非抢占条件(No Preemption):已经分配给进程的资源不能被抢占,只能由进程自愿释放。如果一个进程在等待某个资源的同时又不释放它已经持有的资源,就可能导致死锁。

循环等待条件(Circular Wait):存在一个进程链,每个进程都在等待下一个进程所持有的资源。这样的等待链形成一个循环,使得每个进程都被等待,并最终导致死锁。

当以上四个条件同时满足时,就可能发生死锁。避免死锁通常需要采取一些策略,如资源分配的谨慎策略、资源预先分配、死锁检测和恢复等。

嵌入式软件工程师面试完全指南

面经一共32篇文章,12w+字数,包含全部最新的面试必问考点,4.7w+同学学习,2800+订阅,非常适合在找工作面经薄弱的同学,3200+订阅还会涨价,提前订阅提前享受,持续更新中。

原帖链接:https://www.nowcoder.com/creation/manager/columnDetail/MJNwoM

全部评论

相关推荐

天门一键开:她的意思是问你有没有论文吧
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务