关于嵌入式软件工程师的面试题(一)

ARM是什么RM的分类br> 1.1》是一家公司的名字—->专门生产IP核(内核–CPU)—->依靠专利授权盈利
1.2》是一系列ARM内核的芯片的代称
ARM7,ARM9,ARM11
Cortex-A :针对计算量比较大,有交互性界面的领域—–手机,平板,投影仪
Cortex-R :针对实时性比较高的领域—-航空航天,汽车刹车
Cortex-M :针对微控制器领域—-洗衣机,电饭煲 —–STM32

芯片里面有什么br> 内核—-CPU
片上外设:外设位于芯片内部,位于内核外部
片外外设:外设位于芯片外部

MCU开发本质br> 与内核沟通,控制片上外设,驱动片外外设。

内核结构:哈佛结构:数据存储和指令存储是分开的
    冯诺依曼架构:输出存储和指令存储是不分开的

STM32的开发方式有哪些br> 寄存器开发方式
标准外设库开发方式
Cube库开发方式
LL库

GPIO的作用
控制引脚的输入输出模式

什么是时钟br> 一段有序的脉冲,相对于人的脉搏,MCU是来一个脉冲处理一次数据,脉冲的频率会影响处理数据的速率
脉冲由晶振产生提供给芯片内部

什么是滴答计时器
systick是一个24bit的系统定时器,它是向下计数的计数方式,从计数值到0。计数到0时会重复计数,所以当计数完成需要关闭定时器

联合体和结构体的区别br> 各成员各自拥有自己的内存,各自使用互不干涉,同时存在的,遵循内存对齐原则。一个struct变量的总长度等于所有成员的长度之和。
各成员共用一块内存空间,并且同时只有一个成员可以得到这块内存的使用权(对该内存的读写),各变量共用一个内存首地址。因而,联合体比结构体更节约内存。一个union变量的总长度至少能容纳最大的成员变量,而且要满足是所有成员变量类型大小的整数倍。不允许对联合体变量名U2直接赋值或其他操作。

描述内存分配方式以及它们的区别br> 1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
2) 在栈上创
建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。

请说出const的作用onst与#define 相比,有何优点br> const修饰的类型是常类型,常类型的变量或对象的值是不能被更新的。
const可节省空间,避免不必要的内存分配,提高效率
const常量有数据类型,而宏常量没有数据类型

如何打印出当前执行代码的文件名、函数名、行号br> printf(“[%s %s] %s: %s: %dn”,
            __DATE__, __TIME__, __FILE__, __func__, __LINE__);
__FILE__    当前程序文件名的字符串
__FUNCTION__或__func__    当前函数名的字符串
__LINE__    当前行号的整数
__DATE__    当前日期的字符串
__TIME__    当前时间的字符串

头文件中的ifndef/define/endif 的作用br> 防止头文件被重复包含和编译

#include 与 #include “file.h”的区别br> #include表示编译器将从标准库目录中开始查找此文件
#include”file.h”表示编译器将从当前工作目录上开始查找此文件

全局变量和局部变量有什么区别怎么实现的作系统和编译器是怎么知道的 br> 在操作系统中,全局变量存储在内存的静态存储区域,而局部变量存放在内存的栈区
操作系统和编译器通过内存分配的位置来知道的全局变量分配在全局数据段,并且在程序被运行的时候就被加载

局部变量、全局变量和静态变量的含义和区别
局部变量 
在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能使用它们,在此函数以外时不能使用这些变量的,它们称为局部变量.
全局变量
在函数外定义的变量是外部变量,外部变量是全局变量,全局变量可以为本文件中其它函数所共用,它的有效范围从定义变量的位置开始到本源文件结束.
静态变量 
静态变量的作用范围要看静态变量的位置,如果在函数里,则作用范围就是这个函数.
静态全局变量,只在本文件可以用,虽然整个程序包含多个文件,但静态全局变量只能用在定义它的那个文件里,却不能用在程序中的其他文件里.它是定义存储因型为静态型的外部变量,其作用域是从定义点到程序结束

解释堆和栈的区别br> 栈简介
栈由操作系统自动分配释放 ,用于存放函数的参数值、局部变量等,其操作方式类似于数据结构中的栈
堆简介
堆由程序员分配释放, 若程序员不释放,程序结束时由OS回收,分配方式倒是类似于链表

堆栈溢出一般是由什么原因导致的br> 函数调用层次太深。
动态申请空间使用之后没有释放。
数组访问越界。
指针非法访问。

局部变量能否和全局变量重名br> 能,局部会屏蔽全局。要用全局变量,需要使用”::”

全局变量可不可以定义在可被多个.c文件包含的头文件中br> 可以,在头文件或不同的c文件中用static来修饰同名全局变量。

语句for( ;1 ;)有什么问题是什么意思br> for(;1;)中,循环条件结果需要是boolean类型,但1为int类型,不能自动转为boolean类型,故编译报错

关键字static的作用是什么br> 静态局部变量
  1.static修饰的局部变量,不像其他局部变量一样函数退出时就消失,它的存储于全局区,生命周期是整个文件;
  2.但是静态局部变量的作用域还是和其他局部变量一样在函数中,只能在该函数中调用,退出函数后还存在但不能使用;
  3.在声明时如果没有初始化,编译器会将它自动初始化为0。
静态全局变量:
  1.静态全局变量只能在本文件中访问,其他文件不可访问;
  2.其他文件中可以定义与它同名的变量,互不影响。
静态函数
  1.静态函数只能在声明它的文件中可见,其他文件中不能使用该函数;
  2.其他文件中可以定义与它同名的函数,互不影响。

关键字const是什么含意br> 被const修饰的变量,会被操作系统保护,防止修改

关键字volatile有什么含意br> volatile 的意思是“易失的,易改变的”。这个限定词的含义是向编译器指明变量的内容可能会由于其他程序的修改而变化

什么是预编译,何时需要预编译br> 什么是预编译:
预编译又称为预处理 , 是做些代码文本的替换工作。
处理以# 开头的指令 , 比如拷贝 #include 包含的文件代码,#define 宏定义的替换 , 条件编译等,就是为编译做的预备工作的阶段。
何时需要预编译:
总是使用不经常改动的大型代码体。
程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个“预编译头”

gcc编译代码的四个阶段,以及每个阶段所做的内容
预处理(Pre-Processing)预处理阶段主要工作是删除程序中所有的注释、处理以# 开头的命令
编译(compiling)gcc在编译阶段会对预处理后的代码进行各种检查(词法分析、语法分析、语义分析),来判断我们代码是否符合规范,如果通过就会生成汇编代码(
汇编(Assembling)把 .s 文件翻译成二进制.o文件
链接(Linking) 汇编阶段将代码编译成了二进制文件,还需要和系统其他组件(比如标准库、动态链接库等)结合起来才能正常运行

进程和线程的区别。
进程和程序的区别
程序是静态的,它是一些保存在磁盘上的指令的有序集合,没有任何执行的概念    
进程是一个动态的概念,它是程序执行的过程,包括创建、调度和消亡    
进程是系统分配资源的最小单位  
线程是cpu调度的最小单位

在C语言中,为什么static变量只初始化一次br> 存放在静态区的变量的生命周期一般比较长,一般与整个源程序“同生死、共存亡”,所以它只需初始化一次。

什么是内存泄露。
动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束

什么是野指针何避免br> 野指针:随机指向一块内存的指针
(1)当没有指针指向时,要置为NULL
(2)给指针指向的空间赋值时,一定要给指针分配空间
(3)检查是否分配成功
(4)分配成功之后,初始化
(5)使用时,注意不要越界
(6)使用完之后,free
(7)free之后再次置NULL

如何求解整型数的二进制表示中1的个数br> 按位与1

如何将char a中的第n位置1
|=(0x1

如何将char a中的第n位清0
&=~(0x1

交换两个变量的值,不使用第三个变量
int a,b;
a=10;b=12;
a=b-a; //a=2;b=12
b=b-a; //a=2;b=10
a=b+a; //a=12;b=10

Linux中各个目录的作用。
1. / 根目录
 整个 Linux 文件系统层次结构的根
2.  /bin 目录
需要在单用户模式可用的必要命令(可执行文件),面向所有用户
单用户模式:在最小环境中使用超级用户维护系统环境,例如:修改损坏的系统文件、修改配置文件等。
3. /boot 目录
该目录包含启动系统所需的文件
4. /dev 目录
该目录包含许多代表设备的特殊文件。
5./etc 目录
该目录包含系统范围内的配置文件。
6. /home 目录
该目录包含每个用户的家目录。
通常也将其设置为一个单独的分区。
7. /root 目录
root 用户的家目录
8. /run 目录 
/run 目录是一个相当新的目录,它为应用程序提供了一个标准位置来存储所需的临时文件,例如套接字和进程ID。
9. /sbin 目录
该目录包含基本二进制文件,这些二进制文件通常旨在由 root 用户运行以进行系统管理。
10. /tmp 目录
该目录存储临时文件,系统在重启时会自动清理该目录下的文件(不同Linux系统清理时间有差别,CentOS 是重启后清理十天前文件,Ubuntu 是每次重启后清理),所以不要将重要文件放到这个目录下。
11. /usr 目录
该目录包含用户使用的应用程序和文件,而不是系统使用的应用程序和文件。
12. /var 目录
该目录包含系统运行中内容不断变化的文件
13. /lib 目录
/bin 和 /sbin 目录中二进制文件需要的库文件。
14. /media 目录
可移除媒体(如CD-ROM)的挂载点。
115. /mnt 目录
该目录是临时挂载文件系统的位置。
16. /opt 目录
可选应用软件包目录。
17. /proc 目录
虚拟文件系统,将内核与进程状态归档为文本文件。
18. /srv 目录
该目录为系统提供的服务的数据,一些服务启动后,保存服务所需要的数据。
19. /cdrom 目录
该目录不是 FHS 标准的一部分,但是在 Ubuntu 和其他操作系统上可以看到它。 
20. /lost+found 目录
该目录用于存放系统异常时文件的碎片,以便于进行恢复。如果文件系统崩溃,则将在下次启动时执行文件系统检查。

如何建立软连接、硬链接
硬链接:ln file1 file2
软链接:ln -s file1 file2

文件权限修改用什么命令br> Linux命令:修改文件权限命令chmod、chgrp、chown
chmod 命令
chmod命令是非常重要的,用于改变文件或目录的访问权限。用户用它控制文件或目录的访问权限。
chgrp命令
功能:改变文件或目录所属的组。
chown 命令
功能:更改某个文件或目录的属主和属组

Grep 命令有什么用br> 作用
Linux系统中grep命令是一种强大的文本搜索工具

find 命令有什么用。
按名称或正则表达式查找文件
查找不同类型的文件
按指定的时间戳查找文件
按大小查找文件
按权限查找文件
按所有权查找文件
在找到文件后执行命令

管道符的作用。
管道符的符号:|
管道符的作用:是用于两个命令或者多个命令相链接,将前边的命令的执行结果传递到后边的命令

终止进程用什么命令带什么参数br> Linux kill 命令使用详解
功能说明:删除执行中的程序或工作。

使用什么命令查看用过的命令列表br> history 命令可以查看已经执行过的历史命令

使用什么命令查看磁盘使用空间br> df命令
df 命令是英文单词 disk-free 的缩写,用于查看 Linux 系统中的可用的和已经使用的磁盘空间
du 命令
du 命令是英语单词 disk useage 的缩写,它是以默认千字节大小显示文件、文件夹等磁盘使用情况

大小端序什么意思。
1. Big-Endian(大端):高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
2.Little-Endian(小端):低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

怎么通过程序得出大小段序。
void IsBigEndian()
{
    short int a = 0x1122;//十六进制,一个数值占4位
    char b =  *(char *)&a;  //通过将short(2字节)强制类型转换成char单字节,b指向a的起始字节(低字节)
    if( b == 0x11)//低字节存的是数据的高字节数据
    {
        //是大端模式
    }
    else
    {
        //是小端模式
    }
}

什么是标准IO
标准IO:
(1)标准IO是c语言标准提供的一系列进行输入输出的函数
(2)标准IO具有缓冲区
(3)标准IO是在系统调用之上构建的

标准IO的缓冲区类型
全缓冲
行缓冲
不带缓冲

当用户程序运行时会自动打开多少个标准流
标准输入流:stdin
标准输出流:stdout
标准错误输出流:stderr

请写出在缓冲IO中,可以对文件进行读数据的主要操作函数名。
fopen
fgetc
fgets
fread

strstr函数、strtok函数、strcat函数、strcmp函数
size_t strlen ( const char * str );
strlen函数用于求字符串长度,strlen所作的是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域开始扫描,直到碰到第一个字符串结束符’ ’为止,然后返回计数器值(长度不包含’ ’).
char* strcpy(char * destination, const char * source );
strcpy函数是将一个字符串拷贝到另一个字符串空间中,目的空间的内容会被覆盖。两个参数均为指针,把 source 中的内容 拷贝到 dest 目的空间中,返回值是目的空间的地址,即 dest
char * strcat ( char * destination, const char * source );
strcat函数将 source 指向的字符串内容追加到 dest 所指向字符串的后面, 返回追加后的字符串,即 返回 dest
int strcmp ( const char * str1, const char * str2 );
strcmp函数是用于比较两个字符串内容的函数。它的参数是两个指针,指向两个比较的字符串,它的返回值是一个数字 , 当str1大于str2的时候返回一个大于0的数;当str1等于str2的时候返回0;当str1小于str2的时候返回一个小于0的数。
char * strstr ( const char * str1, const char * str2 );
strstr 函数在 字符串str1 中查找 子串str2  , 查找成功返回  str1中子串的首元素地址,查找失败返回NULL。
char * strtok ( char * str, const char * sep );
strtok函数找到str中的下一个标记,并将其用 结尾,返回一个指向这个标记的指针

动态库和静态库的区别。
静态库
之所以称为静态库,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接
动态库
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库。

来源:梅子酒沐浴露

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年8月22日
下一篇 2022年8月22日

相关推荐