嵌入式笔试面试刷题(day17)

2024-06-06 14:44

本文主要是介绍嵌入式笔试面试刷题(day17),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、单片机中断处理的流程是什么?
  • 二、进程间通信中使用锁和同步的目的是什么?
  • 三、define和const在内存占用上的差异是什么?
      • #define
      • const
      • 比较
      • 例子对比
  • 四、波特率是什么,为什么双方波特率要相同,高低波特率有什么区别
  • 五、cache的作用
  • 六、实时查看线程进程状态的linux命令
      • 1. `top`
      • 2. `htop`
      • 3. `ps`
      • 4. `pidstat`
      • 5. `perf top`
      • 6. `watch`
      • 7. `pstree`
      • 8. `strace`
  • 七、结构体和联合体的区别以及内存对齐方式,如何取消对齐方式
      • 结构体和联合体的区别
        • 1. 结构体(struct)
        • 2. 联合体(union)
      • 内存对齐方式
        • 对齐原则
        • 示例
      • 取消对齐方式
        • 使用`#pragma pack`
        • 使用`__attribute__((packed))`
        • 注意事项
      • 总结
  • 总结


前言

本篇文章接着为大家讲解嵌入式的笔试和面试专题。

一、单片机中断处理的流程是什么?

单片机的中断处理是一种用于提高系统响应速度和效率的重要机制。中断处理流程大致可以分为以下几个步骤:

  1. 中断发生
    当外部事件或内部事件触发中断源时,中断信号会被送到中断控制器。常见的中断源包括定时器溢出、中断引脚信号变化、串口接收完成等。

  2. 中断请求
    中断控制器检测到中断信号后,向CPU发出中断请求。如果CPU当前允许中断(即全局中断使能位已设置),CPU会在当前指令执行完毕后响应中断请求。

  3. 中断响应
    CPU完成当前指令后,执行以下操作:

保存现场:保存当前的程序计数器(PC)和其他重要寄存器的内容,以便在中断处理完成后恢复。
关闭全局中断:在处理中断过程中,为了防止嵌套中断,通常会临时关闭全局中断(具体实现可能因单片机而异)。
跳转到中断服务程序(ISR):CPU从中断向量表中读取对应中断的入口地址,并跳转到该地址开始执行中断服务程序。

  1. 中断服务程序(ISR)
    ISR是专门用于处理特定中断事件的代码,其主要步骤包括:

保存上下文:保存使用的寄存器状态(这一步有时在ISR开始时自动完成)。
处理中断:执行中断处理逻辑,例如读取传感器数据、处理通讯数据、控制外设等。
清除中断标志:在ISR结束前清除相应的中断标志位,防止同一中断反复触发。
恢复上下文:恢复寄存器状态,使程序可以无缝回到中断前的状态。

  1. 中断返回
    ISR完成后,执行中断返回指令(如RETI或IRET),CPU进行以下操作:

恢复现场:恢复中断前保存的程序计数器和其他寄存器内容。
重新使能中断:如果之前关闭了全局中断,在此步骤中重新使能。
继续执行主程序:CPU返回到中断发生时的程序继续执行。

二、进程间通信中使用锁和同步的目的是什么?

  1. 确保数据一致性
    在多进程或多线程环境中,不同进程或线程可能会同时访问和修改共享资源(如共享内存、文件等)。如果没有同步机制,这些操作可能会相互干扰,导致数据的不一致或损坏。

  2. 防止竞态条件
    竞态条件指的是多个进程或线程在没有适当同步的情况下竞争使用共享资源,从而导致不可预测的结果。例如,两个进程同时读取和修改一个共享变量,可能会导致最终的结果不正确。使用锁可以确保在同一时间只有一个进程或线程可以访问共享资源,从而避免竞态条件。

  3. 实现互斥(Mutex)
    互斥锁(Mutex)是一种常见的同步机制,它确保在同一时间只有一个进程或线程能够进入临界区(Critical Section)。通过使用互斥锁,可以保护共享资源不被多个进程或线程同时访问。

  4. 控制同步顺序
    有些时候,进程或线程之间需要按照一定的顺序执行操作。同步机制(如信号量、条件变量等)可以帮助协调这些操作顺序,确保按预期进行。

三、define和const在内存占用上的差异是什么?

#defineconst在内存占用上的差异可以从编译时处理和运行时行为两个方面进行分析。这两者在C/C++编程中都用于定义常量,但它们的机制和在内存中的表现有所不同。

#define

#define是一个预处理指令,用于定义符号常量。在编译前,预处理器会将所有的#define符号替换为其定义的值。#define在预处理阶段处理,不会分配内存空间。

示例:

#define PI 3.14

在编译时,所有的PI都会被替换为3.14

  • 内存占用#define不会分配任何内存。它只是文本替换,因此不会占用运行时内存。但如果在多个地方使用这个常量,每个地方都会生成一份拷贝,这可能会增加代码大小。

const

const关键字用于定义一个常量变量。它是类型安全的,编译器会为它分配内存,并且该变量在运行时存在。

示例:

const double pi = 3.14;

在编译时,pi被分配一个内存位置,并在运行时使用这个内存位置的值。

  • 内存占用const变量会占用内存空间,因为它需要存储变量的值。编译器会在合适的内存区域(通常是数据段)为其分配空间。

比较

  1. 内存分配

    • #define:不分配内存,只进行文本替换,不会增加运行时的内存占用。
    • const:分配内存来存储常量值,运行时占用内存。
  2. 类型安全

    • #define:没有类型检查,只是简单的文本替换,可能导致类型错误。
    • const:有类型检查,类型安全,避免类型错误。
  3. 调试

    • #define:在调试时,预处理器替换后难以直接看到原始定义。
    • const:在调试时可以直接看到并检查常量变量的值。
  4. 作用域

    • #define:宏的作用域从定义点开始,到文件结束,或者通过#undef取消定义。
    • const:具有正常的变量作用域,可以是局部的、全局的或是类成员。

例子对比

考虑以下代码:

使用#define

#define SIZE 100
int arr[SIZE];

使用const

const int size = 100;
int arr[size];
  • 在第一个例子中,SIZE在预处理阶段会被替换为100,不会占用运行时内存。
  • 在第二个例子中,size会在数据段分配内存,并且在运行时占用内存。

总结来说,#define适用于简单的符号替换和宏定义,而const适用于需要类型安全和运行时可见的常量。#define不会占用运行时内存,而const会占用运行时内存,但带来了更多的类型安全和调试便利。

四、波特率是什么,为什么双方波特率要相同,高低波特率有什么区别

波特率(Baud Rate)是指每秒钟传输的符号(信号变化)的次数,用于衡量数据传输速率。它通常以每秒波特(Baud)为单位表示。波特率在串行通信中尤为重要,例如在串口通信(如UART)中。

波特率的定义
波特率(Baud Rate)是每秒传输的信号变化(或符号)数。例如,如果波特率是9600 Baud,则每秒钟有9600个信号变化。需要注意的是,波特率不一定等同于比特率(Bit Rate)。比特率是每秒传输的位数,而波特率是每秒传输的符号数。一个符号可以表示多于一位数据(如某些调制方式中)。

双方波特率必须相同的原因
在串行通信中,发送端和接收端必须以相同的波特率工作,这是因为:

同步性:波特率决定了发送和接收数据的速度。如果两端的波特率不同,接收端将无法正确解析发送端的数据,因为数据的起止点无法对齐。
数据完整性:不同波特率会导致数据位的错误解读,从而产生数据错误或丢失。
高低波特率的区别
传输速度:

高波特率:每秒传输更多的数据,因此可以提高通信速度。例如,115200 Baud 比 9600 Baud 传输数据更快。
低波特率:每秒传输的数据较少,通信速度较慢。
误码率:

高波特率:由于数据传输速度快,对传输介质的要求更高,更容易受到噪声和干扰的影响,从而可能增加误码率。
低波特率:传输速度慢,通常更稳定,误码率较低,对传输介质的要求较低。
信号质量:

高波特率:对于长距离传输,高波特率信号衰减和失真较严重,可能需要更好的传输介质或补偿措施(如中继器、调制解调器)。
低波特率:长距离传输时信号衰减和失真较小,适合质量较差的传输介质。
系统资源占用:

高波特率:需要更高的处理能力和更快速的硬件支持,可能会增加系统资源的占用。
低波特率:对硬件和处理能力的要求较低,系统资源占用较少。
选择波特率的考虑因素
应用需求:根据应用对数据传输速率的要求选择适当的波特率。
传输距离:长距离传输通常选择较低的波特率以确保信号质量。
传输介质:考虑传输介质的质量和抗干扰能力。
硬件性能:确保硬件能够支持所选择的波特率。

五、cache的作用

缓存(Cache)的主要作用是加速数据访问和提高系统性能。它是一种高效的临时存储机制,用于存储经常访问的数据,以便更快地响应数据请求。缓存广泛应用于计算机系统、网络、数据库和浏览器等各个领域。

缓存的作用

提高数据访问速度:

减少延迟:缓存存储经常访问的数据,减少从主存或远程服务器获取数据的时间,显著降低数据访问的延迟。
加快响应时间:对相同数据的多次请求可以直接从缓存中读取,从而提供更快的响应。
减少系统负载:

降低I/O操作:缓存减少了对磁盘、数据库或网络的频繁访问,降低了这些资源的负载。
分担服务器压力:在Web应用中,缓存可以缓解服务器的压力,减少对后端服务器的请求次数。

节省带宽:

减少网络传输:缓存存储静态资源(如网页、图像、视频等),减少了对这些资源的重复下载,节省了网络带宽。
优化流量:通过缓存中继节点(如CDN),将数据存储在离用户更近的地方,减少跨区域的数据传输,提高传输效率。

提高系统性能:

加速计算:缓存存储中间计算结果,避免重复计算,提高计算任务的效率。
平衡负载:通过分布式缓存系统,将数据分布存储在多个节点,平衡负载,提高系统的可扩展性和可靠性。

六、实时查看线程进程状态的linux命令

在Linux中,有多个命令可以用来实时查看线程和进程的状态。以下是一些常用的命令和它们的简要说明:

1. top

top命令是一个实时显示系统任务的命令,它默认显示进程信息。使用-H选项可以显示线程信息。

top -H

top命令的输出中,你可以看到每个线程的ID、CPU使用率、内存使用情况等信息。

2. htop

htoptop命令的增强版本,提供了更友好的用户界面和更多的功能。在htop中,你可以按 F2 进入设置,然后启用显示线程。

htop

按下F2 (或S),然后选择“Display options”,启用“Show custom thread names”。

3. ps

ps命令可以显示当前系统的进程和线程信息。使用-T选项可以查看某个特定进程的线程信息。

ps -eLf

或者查看某个特定进程的线程:

ps -T -p <PID>

4. pidstat

pidstat命令是sysstat包的一部分,用于收集每个进程的统计信息。使用-t选项可以显示线程信息。

pidstat -t

5. perf top

perf top命令是一个强大的性能监控工具,可以用来查看系统的实时性能数据,包括线程信息。

perf top

6. watch

watch命令可以用来定期执行指定命令,从而达到实时监控的效果。例如,使用watch结合ps命令来实时查看线程信息:

watch -n 1 "ps -eLf"

-n 1表示每秒更新一次。

7. pstree

pstree命令以树形结构显示进程和线程的关系,使用-p选项显示进程ID,使用-T选项显示线程。

pstree -p -T

8. strace

strace命令可以跟踪系统调用和信号,可以用于诊断和调试程序,查看进程和线程的运行状态。

strace -f -p <PID>

以上命令提供了多种方式来实时查看和监控Linux系统中的线程和进程状态,根据需要选择合适的工具即可。

七、结构体和联合体的区别以及内存对齐方式,如何取消对齐方式

结构体和联合体的区别

1. 结构体(struct)
  • 定义:结构体是一种用户定义的数据类型,它可以包含多个不同类型的数据成员。
  • 内存布局:结构体的每个成员都有自己的内存空间,成员的内存地址是连续的,并且成员按照定义的顺序存储。
  • 访问:结构体的所有成员可以同时存在,访问某个成员不会影响其他成员。
  • 示例
    struct ExampleStruct {int a;float b;char c;
    };
    
2. 联合体(union)
  • 定义:联合体是一种用户定义的数据类型,它可以包含多个不同类型的数据成员,但所有成员共享同一块内存空间。
  • 内存布局:联合体的所有成员占用同一块内存,大小等于其最大成员的大小。
  • 访问:在任何时刻,联合体中只能有一个成员是有效的,访问某个成员会覆盖其他成员。
  • 示例
    union ExampleUnion {int a;float b;char c;
    };
    

内存对齐方式

内存对齐是指数据在内存中按一定的规则对齐存储,以提高访问速度。内存对齐方式通常由编译器决定,但可以通过编译指令或属性进行控制。

对齐原则
  1. 对齐边界:每个数据成员的地址必须是其类型大小的倍数。例如,4字节的int类型必须对齐到4的倍数的地址。
  2. 结构体对齐:结构体的大小必须是其最大成员对齐大小的倍数。
  3. 填充字节:为了满足对齐要求,编译器会在成员之间插入填充字节。
示例
struct ExampleStruct {char c;int i;
};

在32位系统上,char的对齐要求是1字节,int的对齐要求是4字节。为了对齐,编译器会在ci之间插入3个填充字节。

取消对齐方式

在某些情况下,可能需要取消对齐以节省内存。可以通过编译器指令来实现取消对齐。

使用#pragma pack

#pragma pack指令可以设置和恢复对齐方式。

#pragma pack(push, 1)
struct ExampleStruct {char c;int i;
};
#pragma pack(pop)

上述代码将结构体ExampleStruct的对齐方式设置为1字节对齐,然后恢复原有对齐方式。

使用__attribute__((packed))

在GNU编译器中,可以使用__attribute__((packed))来取消对齐。

struct ExampleStruct {char c;int i;
} __attribute__((packed));

上述代码将结构体ExampleStruct设为无对齐。

注意事项

取消对齐可能会导致性能下降,因为处理器对未对齐的数据访问速度较慢。此外,某些硬件可能不支持未对齐的数据访问,可能会引发异常。因此,在取消对齐时需谨慎。

总结

  • 结构体:每个成员都有独立的内存空间,可以同时存在,访问顺序按定义顺序。
  • 联合体:所有成员共享同一内存空间,只能有一个成员有效,覆盖其他成员。
  • 内存对齐:通过对齐边界和填充字节提高访问速度。
  • 取消对齐:通过#pragma pack__attribute__((packed))指令实现,但需考虑性能和兼容性。

总结

本篇文章就讲解到这里了,我们下篇文章再见。

这篇关于嵌入式笔试面试刷题(day17)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1036408

相关文章

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

荣耀嵌入式面试题及参考答案

在项目中是否有使用过实时操作系统? 在我参与的项目中,有使用过实时操作系统。实时操作系统(RTOS)在对时间要求严格的应用场景中具有重要作用。我曾参与的一个工业自动化控制项目就采用了实时操作系统。在这个项目中,需要对多个传感器的数据进行实时采集和处理,并根据采集到的数据及时控制执行机构的动作。实时操作系统能够提供确定性的响应时间,确保关键任务在规定的时间内完成。 使用实时操作系统的

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

嵌入式方向的毕业生,找工作很迷茫

一个应届硕士生的问题: 虽然我明白想成为技术大牛需要日积月累的磨练,但我总感觉自己学习方法或者哪些方面有问题,时间一天天过去,自己也每天不停学习,但总感觉自己没有想象中那样进步,总感觉找不到一个很清晰的学习规划……眼看 9 月份就要参加秋招了,我想毕业了去大城市磨练几年,涨涨见识,拓开眼界多学点东西。但是感觉自己的实力还是很不够,内心慌得不行,总怕浪费了这人生唯一的校招机会,当然我也明白,毕业

java面试常见问题之Hibernate总结

1  Hibernate的检索方式 Ø  导航对象图检索(根据已经加载的对象,导航到其他对象。) Ø  OID检索(按照对象的OID来检索对象。) Ø  HQL检索(使用面向对象的HQL查询语言。) Ø  QBC检索(使用QBC(Qurey By Criteria)API来检索对象。 QBC/QBE离线/在线) Ø  本地SQL检索(使用本地数据库的SQL查询语句。) 包括Hibern

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径 II - 力扣(LeetCode) 1. 91. 解码方法 - 力扣(LeetCode) //思路:动态规划。 cl

深入探索嵌入式 Linux

摘要:本文深入探究嵌入式 Linux。首先回顾其发展历程,从早期尝试到克服诸多困难逐渐成熟。接着阐述其体系结构,涵盖硬件、内核、文件系统和应用层。开发环境方面包括交叉编译工具链、调试工具和集成开发环境。在应用领域,广泛应用于消费电子、工业控制、汽车电子和智能家居等领域。关键技术有内核裁剪与优化、设备驱动程序开发、实时性增强和电源管理等。最后展望其未来发展趋势,如与物联网融合、人工智能应用、安全性与

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述