【面试笔记】嵌入式软件工程师,汽车电子软件相关
文章目录
- 1. C语言基础
- 1.1 const
- 1.2 static
- 1.3 回调函数的用法
- 1.4 宏定义
- 1.5 编译、链接过程
- 1.6 堆与栈的区别?
- 1.7 简单的字符串算法题,C语言实现
- 1.7.1 给定一个字符串,按顺序筛选出不重复的字符组成字符串,输出该字符串
- 1.7.2 给定4*4矩阵,回文打印输出
- 1.8 字节对其
- 2. MCU相关
- 2.1 MCU的启动过程描述
- 2.2 MCU的内存布局
- 2.3 使用volatile关键字的作用?
- 3. 汽车电子软件
- 3.1 CAN/CANFD相关
- 3.1 概述一个CAN消息如何被发送和接收的
- 3.2 CAN和FIFO CAN
- 3.3 CANFD的知识点
- 3.2 概述bootloader实现要点
- 3.2.1 跳转前要做什么?
- 3.3 简述ASPICE在项目研发中的应用
- 3.4 举例说明某个功能安全需求的实现过程
- 3.5 概述14229协议
- 3.6 概述15765协议
1. C语言基础
1.1 const
修饰变量
只可访问,不可重新赋值。
const int MAX_VALUE = 100;void printValue(const int value);
修饰指针
- 限制指向位置
const int *ptr;
- 限制指向数据
const int *const ptr;
1.2 static
静态变量
使用 static 关键字声明静态变量时,变量的生命周期会延长到整个程序运行期间,而不仅仅局限在其定义的作用域内。静态变量在第一次被赋值时初始化,并且保留其值直到程序结束。
静态全局变量
使用 static 关键字在全局作用域中声明的变量具有静态存储持续时间,但是其作用域被限制在声明该变量的源文件内。这使得该变量对其他源文件不可见,可以防止命名冲突。
静态函数
使用 static 关键字声明静态函数时,该函数仅在声明所在的源文件中可见,即它具有内部链接性。静态函数的作用域仅限于声明所在的源文件。这种方式可以避免与其他源文件中的同名函数产生冲突。
1.3 回调函数的用法
用于在函数执行过程中调用另一个函数。回调函数允许我们向一个函数传递另一个函数的地址,从而在需要时执行特定的操作。回调函数通常用于事件处理、异步编程、库函数的扩展等场景。
- 定义回调函数
首先定义一个函数作为回调函数,其函数原型应与回调的要求相匹配。例如:
void callbackFunction(int result) {printf("Callback result: %d\n", result);
}
- 在函数中注册回调函数
在需要的地方将回调函数注册进目标函数中,通常通过函数指针实现。例如:
void performOperation(void (*callback)(int)) {int result = 100; // 模拟操作结果// 执行操作...// 调用回调函数callback(result);
}
- 调用包含回调函数的函数
最后调用包含回调函数的函数,将回调函数的地址传递给要调用的函数。例如:
int main() {performOperation(callbackFunction); // 注册回调函数return 0;
}
在这个示例中,performOperation 函数执行某个操作后调用了注册的回调函数 callbackFunction,并将结果传递给回调函数进行处理。
通过回调函数,我们可以实现灵活的程序设计,允许函数根据不同情况来调用不同的操作,增加了程序的可扩展性和可重用性。当需要在函数执行过程中动态切换功能时,回调函数是一个非常有用的工具。
使用回调函数有以下一些好处:
- 灵活性和可扩展性
回调函数提供了一种灵活的机制,使得代码可以在不同的场景中进行定制和扩展。通过将特定的功能封装在回调函数中,可以根据需要动态地更改或添加行为,而无需修改主函数的逻辑。 - 解耦和模块化
回调函数有助于将不同的功能模块分离,使代码更具有模块化和可维护性。主函数可以专注于其核心逻辑,而将特定的任务委托给回调函数来处理。这样可以提高代码的可读性和可重用性。 - 异步处理和事件驱动
回调函数常用于异步操作或事件驱动的场景中。例如,在异步 I/O 操作完成或特定事件发生时,可以通过回调函数来处理相应的逻辑。这有助于提高程序的并发性和响应性。 - 定制性和扩展性
回调函数允许用户提供自己的自定义逻辑,以满足特定的需求。这使得程序可以更好地适应各种不同的用例和业务逻辑。 - 代码复用
回调函数可以作为可复用的模块,在多个地方被调用,从而减少代码冗余。
需要注意的是,在使用回调函数时,要确保正确处理回调函数的参数和返回值,并注意线程安全等问题。合理使用回调函数可以提高代码的灵活性和扩展性,但也需要谨慎设计和管理,以避免引入复杂度过高或难以调试的问题。
1.4 宏定义
在 C 语言中,宏定义是一种预处理器指令,用于在编译阶段进行文本替换。它允许你定义一个标识符(通常是一个宏名),并将其与一个特定的文本表达式或代码块关联起来。当在代码中使用该宏名时,编译器会将其替换为相应的文本。
宏定义的常见用法和好处包括:
- 常量定义
使用宏定义可以创建常量,例如定义一些具有特定值的常量,以增强代码的可读性和可维护性。 - 代码简化和抽象
宏定义可以用于简化复杂的表达式或代码块,使其更易于阅读和理解。例如,将常用的计算或操作封装在宏中,以便在多个地方重复使用。 - 条件编译
通过宏定义可以实现条件编译,根据不同的条件编译不同的代码块。这对于处理不同平台、版本或配置的情况非常有用。 - 代码移植性
宏定义可以帮助提高代码的可移植性。例如,可以使用宏来定义平台特定的代码或处理不同编译器的差异。 - 提高性能
在一些情况下,宏定义可以提供一定的性能优势,特别是对于一些简单的计算或操作。
例如,以下是一个简单的宏定义示例:
#define MAX_SIZE 100
在上面的示例中,MAX_SIZE 是一个宏名,100 是它关联的文本。在代码中使用 MAX_SIZE 时,它将被替换为 100。
需要注意的是,宏定义也有一些潜在的问题和限制:
- 宏展开问题
宏在编译时会进行文本替换,可能会导致一些意外的副作用,例如嵌套宏展开、参数求值顺序等问题。 - 缺乏类型检查
宏不进行类型检查,可能会导致在使用时出现类型不匹配或其他错误。 - 可读性问题
过度使用宏可能会使代码变得难以理解,特别是当宏的定义和使用变得复杂时。
因此,在使用宏定义时,应该谨慎考虑,并确保其使用不会导致代码的可读性和可维护性下降。在一些情况下,使用函数或其他语言特性可能是更好的选择。
1.5 编译、链接过程
预处理
根据以字符#开头的命令修饰的main.c的C源文件,生成预处理后的C源文件 main.i。
该过程主要进行文本替换、宏展开、删除注释等工作。
对应的gcc命令:
gcc -E main.c main.i
编译
编译器将文本文件main.i翻译(编译)成汇编文件main.s
对应的gcc命令:
gcc -S main.i mian.s
汇编
编译器将main.s翻译成机器语言指令,并把这些指令打包成一种可重定位目标程序的格式,并将结果保存在目标文件main.o中
把一个源文件翻译成目标程序的工作过程分为五个阶段:词法分析、语法分析、语义检查和中间代码生成。主要是进行词法分析和语法分析,又称为源程序分析,分析过程中发现语法错误并给出提示信息。
对应的gcc命令:
gcc -c main.s mian.o
链接
该过程编译器将静态库和动态库的库函数链接到可执行程序中。
静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时就不在需要库文件了,其后缀一般为.a。
动态库则是在程序运行时被链接加载,这样可以节省系统的开销,其后缀一般为.so,gcc在编译时默认使用动态库。
1.6 堆与栈的区别?
- 栈空间是系统自动分配和回收,堆的空间是用户手动分配回收的;
- 栈空间较小,堆空间较大;
- 栈的地址空间向下生长,堆则向上生长;
- 栈的存储效率更高。
参考:栈和堆,以STM32为例说明
1.7 简单的字符串算法题,C语言实现
1.7.1 给定一个字符串,按顺序筛选出不重复的字符组成字符串,输出该字符串
参考示例:
#include <stdio.h>
#include <string.h>void removeDuplicates(char *str) {int len = strlen(str);if (len < 2) return;int tail = 1;for (int i = 1; i < len; ++i) {int j;for (j = 0; j < tail; ++j) {if (str[i] == str[j]) break;}if (j == tail) {str[tail] = str[i];++tail;}}str[tail] = '\0'; //此处是关键
}int main() {char str[100];printf("Enter a string: ");scanf("%s", str);removeDuplicates(str);printf("String with duplicates removed: %s\n", str);return 0;
}
测试结果:
Enter a string: asbdssjikSNjs78137!@#ssa00smk
String with duplicates removed: asbdjikSN7813!@#0m
1.7.2 给定4*4矩阵,回文打印输出
参考示例:
#include <stdio.h>#define ROWS 4
#define COLS 4void printClockwise(int matrix[ROWS][COLS]) {int top = 0, bottom = ROWS - 1, left = 0, right = COLS - 1;while (top <= bottom && left <= right) {// Print top rowfor (int i = left; i <= right; ++i)printf("%d ", matrix[top][i]);top++;// Print right columnfor (int i = top; i <= bottom; ++i)printf("%d ", matrix[i][right]);right--;// Print bottom rowif (top <= bottom) {for (int i = right; i >= left; --i)printf("%d ", matrix[bottom][i]);bottom--;}// Print left columnif (left <= right) {for (int i = bottom; i >= top; --i)printf("%d ", matrix[i][left]);left++;}}
}int main() {int matrix[ROWS][COLS] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 16}};printf("Clockwise printing of the matrix:\n");printClockwise(matrix);return 0;
}
测试结果:
Clockwise printing of the matrix:
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
参考:算法11:顺时针转圈打印矩阵
1.8 字节对其
【问题】32位系统,一个结构体中,成员依次是char、short、int、char类型,问这个结构体总共占多少字节?
回答这个问题需要深刻理解结构体所占空间的分布:
|char |-----|short|short|4字节
|int |int |int |int |4字节
|char |-----|-----|-----|4字节
所以,该结构体共占12字节
测试代码:
#include <stdio.h>struct TMP{char a;short b;int c;char d;
};int main(void) {printf("size = %d", sizeof(struct TMP));return 0;
}
总结:
- 结构体成员占位是其自身类型长度的整数倍
- 结构体整体需要对齐,目标对齐长度的整数倍
2. MCU相关
2.1 MCU的启动过程描述
参考STM32的启动过程 — startup_xxxx.s文件解析(MDK和GCC双环境)
2.2 MCU的内存布局
参考:
- 内存布局:深度剖析应用程序中的内存布局
- stm32的内存分布
2.3 使用volatile关键字的作用?
- 硬件寄存器操作
单片机通常与硬件设备交互,硬件寄存器的值可能会在硬件事件的触发下发生改变。通过将访问硬件寄存器的变量声明为 volatile,可以告诉编译器不要对该变量进行优化,以确保每次访问都能获取到最新的寄存器值。 - 共享变量
在多线程或中断处理程序中,多个执行路径可能同时访问和修改同一个变量。将这样的共享变量声明为 volatile,可以确保编译器生成的代码正确地处理变量的读和写,避免出现竞态条件等问题。 - 中断服务程序
中断服务程序可能会修改一些全局变量,而这些变量在主程序中也会被访问。将这些变量声明为 volatile,可以保证中断服务程序对变量的修改能及时反映到主程序中。 - 实时性要求高的代码
在一些对实时性要求较高的场景中,使用 volatile 可以确保关键变量的访问不会被编译器优化掉,从而保证代码的实时性。
通过使用 volatile,可以帮助编译器生成更准确的代码,避免一些由于变量的不确定性导致的问题。然而,具体的应用场景和使用方法可能会因单片机的类型、编译器的特性以及项目的需求而有所不同。在实际编程中,还需要根据具体情况进行适当的测试和调试。
3. 汽车电子软件
3.1 CAN/CANFD相关
3.1 概述一个CAN消息如何被发送和接收的
TBD.
3.2 CAN和FIFO CAN
TBD.
3.3 CANFD的知识点
TBD.
3.2 概述bootloader实现要点
3.2.1 跳转前要做什么?
- 禁止所有外设时钟;
- 禁止使用的 PLL;
- 禁止所有中断;
- 清除所有中断挂起标志。
3.3 简述ASPICE在项目研发中的应用
TBD.
3.4 举例说明某个功能安全需求的实现过程
TBD.
3.5 概述14229协议
TBD.
3.6 概述15765协议
TBD.
相关文章:
【面试笔记】嵌入式软件工程师,汽车电子软件相关
文章目录 1. C语言基础1.1 const1.2 static1.3 回调函数的用法1.4 宏定义1.5 编译、链接过程1.6 堆与栈的区别?1.7 简单的字符串算法题,C语言实现1.7.1 给定一个字符串,按顺序筛选出不重复的字符组成字符串,输出该字符串1.7.2 给定…...
uniapp小程序开发 | 从零实现一款影视类app (后台接口实现,go-zero微服务的使用)
uniapp小程序开发实战系列,完整介绍从零实现一款影视类小程序。包含小程序前端和后台接口的全部完整实现。系列连载中,喜欢的可以点击收藏。 该篇着重介绍获取轮播图后台接口和获取正在热映电影的两个后台接口的实现。 后台服务使用golang,…...
【C#】委托
文章目录 委托自定义委托模板方法(工厂模式回调(callback)函数(观察者模式多播(multicast)委托委托的高级使用使用接口 重构 模板方法代码注意参考 委托 委托(delegate)是一种类型,定义了一种方…...
【面试题】创建两个线程交替打印100以内数字(一个打印偶数一个打印奇数)
阅读导航 一、问题概述二、解决思路三、代码实现四、代码优化 一、问题概述 面试官:C多线程了解吗?你给我写一下,起两个线程交替打印0~100的奇偶数。就是有两个线程,一个线程打印奇数另一个打印偶数,它们交替输出&…...
PgMP考试结束后多久出成绩?附成绩查询方法
PgMP考试结束后多久出成绩?这是许多参加PgMP考试的考生都非常关心的问题。今天就给大家讲解一下PgMP考试多久可以知道成绩? 一、PgMP考试成绩查询时间 PgMP考试一般在考试结束后的6-8周左右才会出成绩,届时PMI官方会通过电子邮件的形式提醒…...
springboot项目Redis统计在线用户
springboot项目Redis统计在线用户 我的项目有个显示用户的遗忘曲线,需要统计在线用户以计算他们的曲线 思考了两种方案,但都是用Redis的bitmap数据结构Bitmap是一种特殊类型的数组,其中每个元素只能存储0或1。在Redis中,Bitmap实际…...
GNeRF论文理解
文章目录 主要解决什么问题?结构设计以及为什么有效果?个人想法。 主要解决什么问题? 本文主要想要解决的问题是 如何使用uncalibrated的照片来进行Nerf重建。虽然说现在已经有了一些方式可以对相机位姿进行估计和优化,但是他们限…...
0531作业 链表
结果 整体代码 主要实现 /**实现* */ #include "./linklist.h"linklist* create_linklist(datatype param){linklist* node(linklist*)malloc(sizeof(linklist));if(NULLnode){puts("节点创建失败");}node->paramparam;node->pnextNULL;puts("…...
C++ STL - 容器
C STL(标准模板库)中的容器是一组通用的、可复用的数据结构,用于存储和管理不同类型的数据。 目录 零. 简介: 一 . vector(动态数组) 二. list(双向链表) 三. deque(…...
AI生成沉浸式3D世界(空间照片/视频)
面向Vision Pro等空间计算设备的产品指南 & 技术实现路径 一、通俗理解 ldi3格式概览:这是一种创新的3D内容格式,专为Vision Pro、Quest等VR头戴设备设计,让你能沉浸在一个几可乱真的三维世界,体验仿佛亲临其境的感受。 内容创作:利用开源工具,结合多角度摄像捕捉,…...
【Vue】异步更新 $nextTick
文章目录 一、引出问题二、解决方案三、代码实现 一、引出问题 需求 编辑标题, 编辑框自动聚焦 点击编辑,显示编辑框让编辑框,立刻获取焦点 即下图上面结构隐藏,下面结构显示,并且显示的时候让它自动聚焦。 代码如下 问题 “…...
【uCOS-III-编程指南】
uCOS-III-编程指南 ■ [野火]uCOS-III内核实现与应用开发实战指南■■■■ ■ [野火]uCOS-III内核实现与应用开发实战指南 添加链接描述 ■ ■ ■ ■...
2004NOIP普及组真题 2. 花生采摘
线上OJ: 【04NOIP普及组】花生采摘 核心思想: 1、本题为贪心即可。 2、因为本题严格限制了顺序,所以先把每个节点的花生数量按降序排序。然后逐一判断下一个花生是否需要去采摘即可 3、每一次采摘完,记录耗时 t 以及采集的花…...
SAP-SD-21-定义用于定价补充的定价过程
图9 维护条件类型...
Android AAudio——C API创建AudioTrack(六)
虽然 AAudio 试图提供一种直接的硬件访问途径,但在某些场景下,如处理兼容性问题、使用系统服务(如 AudioFlinger)或者在某些设备上,使用 AudioTrack 可能是最有效或最合适的途径。这并不违背 AAudio 的初衷,因为它的目标是提供高性能的音频处理,而不是避免使用系统服务。…...
实验七、创建小型实验拓扑《计算机网络》
早检到底是谁发明出来的。 一、实验目的 完成本实验后,您将能够: • 设计逻辑网络。 • 配置物理实验拓扑。 • 配置 LAN 逻辑拓扑。 • 验证 LAN 连通性。 二、实验任务 在本实验中,将要求您连接网络设备并配置主机实现基本的网络…...
SqlServer2016企业版安装
前言 好久没有知识的累积,最近工作上遇到新的SqlServer2016安装,记录一下 参考文章 SQL Server 2016软件安装包和安装教程 - 哔哩哔哩 (bilibili.com) 安装包准备 需要提前准备软件安装包如下 cn_sql_server_2016_enterprise_x64_dvd_8699450&…...
HBase数据库面试知识点:第一部分 - 基础概念与特点(持续更新中)
目录 一、HBase基础概念 1. HBase定义 2. 核心组件 3. HBase的特点 二、HBase与传统RDBMS的区别 1. 数据类型 2. 数据操作 3. 存储方式 4. 伸缩性 5. 事务性 三、HBase数据模型 四、HBase的特点 五、HBase与Hadoop生态系统的关系 一、HBase基础概念 1. HBase定义 …...
一个高效的go语言字符串转驼峰命名算法实现函数
在go语言的开发中我们经常需要对各种命名进行规范, 今天给大家介绍的是一个高效的将字符串转 驼峰命名 (即 首字母大写的命名方式)的函数。 // 字符串转驼峰命名 // author tekintian <tekintiangmail.com> func CamelStr(str string) …...
Python中__init__方法的魔力:构建对象的基石
Python中__init__方法的魔力:构建对象的基石 在Python的世界中,__init__方法是一个特殊的存在。它不仅是类的构造函数,更是对象生命周期的起点。通过__init__方法,我们可以初始化对象的状态,设置属性,甚至…...
Appium安装及配置(Windows环境)
在做app相关自动化测试,需要使用appium来做中转操作,下面来介绍一下appium的环境安装配置 appium官方文档:欢迎 - Appium Documentation 一、下载appium 下载地址:https://github.com/appium/appium-desktop/releases?page3 通…...
CANOE制造dll文件,以及应用dll文件
1、使用canoe自带的capl dll 2、然后使用Visual Studio 2022 打开项目 3、项目打开后修改下项目属性 4、修改capldll.cpp文件 4.1 添加的内容 void CAPLEXPORT far CAPLPASCAL appSum(long i, long j, long* s){*s i j;} {"sum", (CAPL_FARCALL)appSum, "…...
C++结合OpenCV进行图像处理与分类
⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三…...
Master-Worker 架构的灰度发布难题
作者:石超 一、前言 Master-Worker 架构是成熟的分布式系统设计模式,具有集中控制、资源利用率高、容错简单等优点。我们数据中心内的几乎所有分布式系统都采用了这样的架构。  我们曾经发生过级联故障,造成了整个集群范围的服…...
钢基础知识介绍
钢铁是一种铁碳合金,含有一定量的碳和其他合金元素,如硅、锰等。而钢材则是经过加工处理后的钢铁材料,具有更高的强度、硬度、塑性和韧性。钢铁的硬度、强度和耐磨性相对较低,而钢材经过加工处理后,其硬度、强度和耐磨…...
linux 系统监控脚本
1.对CPU的监控函数 function GetCpu(){cpu_numgrep -c "model name" /proc/cpuinfocpu_usertop -b -n 1 | grep Cpu | awk {print $2} | cut -f 1 -d "%"cpu_systemtop -b -n 1 | grep Cpu | awk {print $4} | cut -f 1 -d "%"cpu_idletop -b -…...
K8s Pod的QoS类
文章目录 OverviewPod的QoS分类Guaranteed1.如何将 Pod 设置为保证Guaranteed2. Kubernetes 调度器如何管理Guaranteed类的Pod Burstable1. 如何将 Pod 设置为Burstable2.b. Kubernetes 调度程序如何管理 Burstable Pod BestEffort1. 如何将 Pod 设置为 BestEffort2. Kubernete…...
TCP/IP协议栈
一、TCP/IP协议栈和OSI参考模型对比 二、TCP/IP五层功能 三、TCP/IP模型的层间通信与数据封装 四、TCP/IP模型的层间通信与数据解封装...
Vector容器详解
Vector容器详解 本文将详细介绍C#中的Vector容器,包括其定义、特点、使用方法以及示例代码。 目录 Vector容器简介Vector容器的特点Vector容器的使用方法示例代码 1. Vector容器简介 Vector容器是一种动态数组,它可以自动调整大小以容纳更多的元素。…...
设计模式-抽象工厂(创建型)
创建型-抽象工厂 角色 抽象工厂: 声明创建一个族产品对象的方法,每个方法对应一中产品,抽象工厂可以是接口,也可以是抽象类;具体工厂: 实现抽象工厂接口,复杂创建具体的一族产品;抽…...
网站建设预算费用/51link友链
以10为底的log函数:形式为 double log10(double x)以e为底的log函数(即 ln)double log (double x)如何表达log 以a为底b的对数:用换底公式:可以表达为:log(a)/log(b)#include#includeusing namespace std;int main(){double a3.…...
外贸网站优化建设/微信推广平台收费标准
1. 什么是网络 说明 网络就是一种辅助双方或者多方能够连接在一起的工具 如果没有网络可想单机的世界是多么的孤单 单机游戏(不能和远在他乡的朋友一起玩) 2. 使用网络的目的 就是为了联通多方然后进行通信用的,即把数据从一方传递给另外一方…...
给中小企业提供网站建设服务/seo是什么的
前言:索引是MySQL数据库中的重要对象之一,索引的目的在于提高查询效率。可以类比字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可。索引是表的目录,在查找内容之前可以先在目录中查找索…...
做网站的公司怎么推销/移动端排名优化软件
求开4个线程4秒内执行完以下程序;部分代码已标注不能修改 1 public class LogTest {2 // 里面的方法不能动3 public static void parseLog(String log) {4 System.out.println(log ":" (System.currentTimeMillis() / 1000));5 …...
国内企业建站模板/制作网站需要什么技术
修改mysql的root密码后,出现Host localhost is not allowed to connect to this MySQL server 错误。 解决办法: C:\Program Files\MySQL\MySQL Server 5.5\my.ini 在[mysqld]下加下面两行, skip-name-resolveskip-grant-tables 重启mysql的w…...
wordpress 回复可见/郑州专业网站建设公司
js跨域我用的比较多的就是jsonp和程序代理。但是jsonp只能用get,而且是js异步调用,有时候不能满足项目要求。下面的代码块是js调用一般处理程序的代理来实现js跨域的。如果js需要多次跨域,推荐下面的方法。 public string GetInfo(HttpContex…...