【机试题】2019大疆嵌入式笔试题A卷(附超详细解答)

您所在的位置:网站首页 嵌入式选择题 【机试题】2019大疆嵌入式笔试题A卷(附超详细解答)

【机试题】2019大疆嵌入式笔试题A卷(附超详细解答)

#【机试题】2019大疆嵌入式笔试题A卷(附超详细解答)| 来源: 网络整理| 查看: 265

前不久的大疆嵌入式线上笔试,可能是因为最近只是在做毕设项目,还没有来得及认真系统复习,直接崩了。就凭借着记忆,把一些记得住的笔试题分享一下,作下记录。

整个大疆嵌入式线上笔试,分为选择题(单选题、多选题)、填空题、简答题、编程题。也没有将所有的题目都记得,就分成填空选择题、简答题和编程题三块来介绍吧。

 

填空选择题 1、ARM指令和Thumb指令。(选择题)

解答:在ARM的体系结构中,可以工作在三种不同的状态,一是ARM状态,二是Thumb状态及Thumb-2状态,三是调试状态。而ARM状态和Thumb状态可以直接通过某些指令直接切换,都是在运行程序,只不过指令长度不一样而已。

ARM状态:arm处理器工作于32位指令的状态,所有指令均为32位;Thumb状态:arm执行16位指令的状态,即16位状态;thumb-2状态:这个状态是ARM7版本的ARM处理器所具有的新的状态,新的thumb-2内核技术兼有16位及32位指令,实现了更高的性能,更有效的功耗及更少地占用内存。总的来说,感觉这个状态除了兼有arm和thumb的优点外,还在这两种状态上有所提升,优化;调试状态:处理器停机时进入调试状态。

也就是说:ARM状态,此时处理器执行32位的字对齐的ARM指令;Thumb状态,此时处理器执行16位的,半字对齐的THUMB指令。 

ARM状态和Thumb状态切换程序:

从ARM到Thumb: LDR R0,=lable+1 BX R0(状态将寄存器的最低位设置为1,BX指令、R0指令将进入thumb状态);从ARM到Thumb: LDR R0,=lable BX R0(寄存器最低位设置为0,BX指令、R0指令将进入arm状态)。当处理器进行异常处理时,则从异常向量地址开始执行,将自动进入ARM状态。

关于这个知识点还有几个注意点:

ARM处理器复位后开始执行代码时总是只处于ARM状态;Cortex-M3只有Thumb-2状态和调试状态;由于Thumb-2具有16位/32位指令功能,因此有了thumb-2就无需Thumb了。

另外,具有Thumb-2技术的ARM处理器也无需再ARM状态和Thumb-2状态间进行切换了,因为thumb-2具有32位指令功能。

参考文章:ARM处理器的工作状态。

2、哪种总线方式是全双工类型、哪种总线方式传输的距离最短?(选择题)

解答:几种总线接口的通信方式的总结如下图所示:

UART、I2C、SPI、USB异同 总线接口串/并同步/异步速率工作方式用线总线拓扑结构信距离UART串异步

波特率设置

全双工

2线

Rx、Tx

RS485支持总线式、

星形、树形

最远1200m

I2C

同步

半双工

2线

SDA、SCL

总线型(特殊的树形)

SPI

同步

全双工

3线或4线

SCLK、SIMO、

SOMI、SS(片选)

环形

USB

同步

半双工

4线

Vbus(5V)、GND、 D+、D-(3.3V)

星形

3、TCP与UDP的区别。(选择题)

解答:TCP和UDP的区别总结如下图所示:

TCP和UDP的区别 角度TCPUDP是否连接面向连接(发送数据前需要建立连接)无连接(发送数据无需连接)是否丢包重试

实现了数据传输时各种控制功能,可以进行丢包的重发控制,

还可以对次序乱掉的分包进行顺序控制

不会进行丢包重试,也不会纠正到达的顺序模式流模式(面向字节流)数据报模式(面向报文)对应关系一对一支持一对一,一对多,多对一和多对多的交互通信头部开销最小20字节只有8字节可靠性全双工非常可靠、无差错、不丢失、不重复、且按序到达不保证可靠交付,不保证顺序到达拥塞控制有控制 更多详情

有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低

(对实时应用很有用,如IP电话,实时视频会议等)

资源要求TCP程序结构较复杂,较多UDP程序结构简单,少

参考文章:一看就懂系列之 超级详解TCP与UDP。

4、Linux的用户态与内核态的转换方法。(选择题)

解答:Linux下内核空间与用户空间进行通信的方式主要有syscall(system call)、procfs、ioctl和netlink等。

syscall:一般情况下,用户进程是不能访问内核的。它既不能访问内核所在的内存空间,也不能调用内核中的函数。Linux内核中设置了一组用于实现各种系统功能的子程序,用户可以通过调用他们访问linux内核的数据和函数,这些系统调用接口(SCI)称为系统调用;procfs:是一种特殊的伪文件系统 ,是Linux内核信息的抽象文件接口,大量内核中的信息以及可调参数都被作为常规文件映射到一个目录树中,这样我们就可以简单直接的通过echo或cat这样的文件操作命令对系统信息进行查取;netlink:用户态应用使用标准的 socket API 就可以使用 netlink 提供的强大功能;ioctl:函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。 5、linux目录结构,选项是/usr、/tmp、/etc目录的作用。(选择题)

解答:linux目录图:

/usr:不是user的缩写,其实usr是Unix Software Resource的缩写, 也就是Unix操作系统软件资源所放置的目录,而不是用户的数据啦。这点要注意。 FHS建议所有软件开发者,应该将他们的数据合理的分别放置到这个目录下的次目录,而不要自行建立该软件自己独立的目录;/tmp:这是让一般使用者或者是正在执行的程序暂时放置档案的地方。这个目录是任何人都能够存取的,所以你需要定期的清理一下。当然,重要资料不可放置在此目录啊。 因为FHS甚至建议在开机时,应该要将/tmp下的资料都删除;/etc:系统主要的设定档几乎都放置在这个目录内,例如人员的帐号密码档、各种服务的启始档等等。 一般来说,这个目录下的各档案属性是可以让一般使用者查阅的,但是只有root有权力修改。 FHS建议不要放置可执行档(binary)在这个目录中。 比较重要的档案有:/etc/inittab, /etc/init.d/, /etc/modprobe.conf, /etc/X11/, /etc/fstab, /etc/sysconfig/等等。

参考文章:Linux文件目录结构详解。

6、下面这段程序的运行结果?(选择题) int main(){         const int x=5;         const int *ptr;         ptr=&x;         *ptr=10;         printf("%d\n",x);         return 0; }

解答:编译出错。

这道题主要是讲解const与指针的问题:

const int a; int const a; const int *a; int * const a; const int * const a; int const * const a; 前两个的作用是一样,a是一个常整型数;第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以);第四个意思a是一个指向整型 数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的);最后两个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数 是不可修改的,同时指针也是不可修改的)。

也就是说:本题x是一个常量,不能改变;ptr是一个指向常整型数的指针。而当*ptr=10;的时候,直接违反了这一点。同时要记得一点,const是通过编译器在编译的时候执行检查来确保实现的。

7、在32位系统中,有如下结构体,那么sizeof(fun)的数值是() #pragma pack(1) struct fun{ int i; double d; char c; };

解答:13。

可能是一般的内存对齐做习惯了,如果本题采用内存对齐的话,结果就是24(int 4 double char 7)。但是#pragma pack(1)让编译器将结构体数据强制按1来对齐。

每个特定平台上的编译器都有自己的默认“对齐系数”(32位机一般为4,64位机一般为8)。我们可以通过预编译命令#pragma pack(k),k=1,2,4,8,16来改变这个系数,其中k就是需要指定的“对齐系数”。

只需牢记:

第一个数据成员放在offset为0的地方,对齐按照对齐系数和自身占用字节数中,二者比较小的那个进行对齐;在数据成员完成各自对齐以后,struct或者union本身也要进行对齐,对齐将按照对齐系数和struct或者union中最大数据成员长度中比较小的那个进行;

参考文章:#pragma pack()的解读。

8、Linux中的文件/目录权限设置命令是什么?(选择题)

解答:chmod

9、下面四个选项是四个整数在内存中的存储情况,请选择其中最大的一个。(选择题) 四个整数在内存的存储情况 ABCD

Big-endian

低地址    高地址

12 34 56 78

Big-endian

低地址    高地址

56 78 12 34

Little-endian

低地址    高地址

34 56 78 12

Little-endian

低地址    高地址

78 12 34 56

解答:大端小端问题:

所谓的大端模式(BE big-endian),是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中(低对高,高对高);所谓的小端模式(LE little-endian),是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中(低对低,高对高)。

那么A:12345678、B:56781234、C:12785634、D:56341278。

10、C语言的各种变量的存取区域,给你一段小程序,让你分析各个变量的存储区域(填空题)

解答:具体的题目内容忘了,但是大体上给出各个变量可能的存储区域:

堆:堆允许程序在运行时动态地申请某个大小的内存。一般由程序员分配释放;栈:由编译器自动分配释放,存放函数的参数值,局部变量等值;静态存储区:一定会存在且不会消失,这样的数据包括常量、常变量(const 变量)、静态变量、全局变量等;常量存储区:常量占用内存,只读状态,决不可修改,常量字符串就是放在这里的。 11、下面这段程序的运行结果?(填空题) int main() { int a[10] = { 0,1,2,3,4,5,6,7,8,9 }; memcpy(a + 3, a, 5); for (int i = 0; iBuf = buf; ringBuf->Size = size; ringBuf->RdId = 0; ringBuf->WrId = 0; }

解答:实际上我觉得提供的初始化代码部分,对WrId的初始化有点问题,Write()函数的完整代码如下:

typedef struct RingBuf { char *Buf; unsigned int Size; unsigned int RdId; unsigned int WrId; }RingBuf; void Init(RingBuf *ringBuf, char *buf, unsigned int size) { memset(ringBuf, 0, sizeof(RingBuf)); ringBuf->Buf = buf; ringBuf->Size = size; ringBuf->RdId = 0; ringBuf->WrId = strlen(buf); } void Write(RingBuf *ringBuf, char *buf, unsigned int len) { unsigned int pos = ringBuf->WrId; while (pos + len > ringBuf->Size) { memcpy(ringBuf->Buf + pos, buf, ringBuf->Size - pos); buf += ringBuf->Size - pos; len -= ringBuf->Size - pos; pos = 0; } memcpy(ringBuf->Buf + pos, buf, len); ringBuf->WrId = pos + len; } void Print(RingBuf *ringBuf) { for (int i = 0; i < ringBuf->Size; i++) { cout Buf[i]; } cout 0) { *array3 = *array1; merge(++array1, --len1, array2, len2, ++array3); } if ((*array1 >= *array2 || len1 == 0) && len2 > 0) { *array3 = *array2; merge(array1, len1, ++array2, --len2, ++array3); } return retn; }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3