1.C语言
C语言这一块的高频考点有预处理、关键字、数据类型、指针与内存管理。
(1)预处理有文件包含、宏定义、条件编译,其中最重要的是宏定义,通常考核宏定义的语法、宏替换与函数的区别等。
(2)C语言的关键字有很多,有普通的数据类型关键字(如char, struct等)、控制语句关键字(如continue, break等),还有常考的存储类关键字(auto, extern, static, const, register)、其他关键字(sizeof, typedef, volatile),对于这些关键字,我们都应该很清楚它们的含义。
(3)数据类型的重点有数组、结构体、共用体,常考的问题有“一维数组跟二维数组的指针式访问”、“结构体的内存对齐规则及原因”、“结构体跟共用体的区别”等。
(4)内存管理与指针,重点有如野指针问题、二重指针、内存管理的栈、内存管理的堆、大小端问题等。
待补充。。。
2.数据结构与算法
数据结构与算法的难度确实不小,但好在对于嵌入式软件工程师来说,招聘方一般不会要求掌握那些特别复杂的数据结构与算法。
(1)链表是最重要的,因为Linux内核中经常使用链表,驱动开发和应用编程很多时候也需要链表,所以必须掌握结构体的定义、链表的创建、链表的增加、删除、查找、逆序这些操作的具体编程方法。
(2)哈希表则不是很常用,一般不需要自己实现,直接使用别人实现的哈希表比较多,但我们仍然要了解哈希表的原理、特点、适用场景。
(3)二叉树、图等很少使用,不必过于纠结。
(4)对于算法,我们需要掌握冒泡排序、快速排序、二分查找等常用算法以及递归、分治、动态规划等算法思维。
待补充。。。
3.ARM裸机开发
ARM裸机开发的话,重点基本集中于ARM处理器、I/O接口、中断、寄存器与存储器这四部分。当然ARM裸机开发还包括uboot和汇编,但这部分一般很少涉及。
(1)ARM处理器部分需要我们了解ARM处理器的分类、工作状态和工作模式、指令集、总线等。
(2)I/O接口需要掌握GPIO的模式以及UART、IIC、USB、SPI这四个串行通讯接口。
(3)寄存器与存储器则需要掌握不同工作模式下的寄存器组织、各个寄存器的作用,还有存储器的种类和特点。
(4)中断则需要掌握不同中断类型的中断向量、工作模式,还有中断的过程。
学完了裸机开发,接下来就要进入Linux开发了,与裸机开发不同,有了Linux操作系统,Linux开发分为应用开发与驱动开发。应用程序运行在操作系统之上,而驱动程序则属于操作系统,应用程序通过操作系统提供的API来调用驱动程序,完成对硬件的操作。应用开发与驱动开发都需要遵循许多框架,比裸机开发复杂很多。
待补充。。。
4.应用编程与网络编程
应用编程的知识点包括文件IO、标准IO,进程及进程间通信、线程及线程间通信。
(1)进程间的通信方式包括无名管道、有名管道、信号量、消息队列、共享内存、信号、socket套接字等。
(2)线程间的通信方式包括信号量、互斥锁、条件变量等。
(3)网络编程是一个必须要掌握的重点,它本质上是一种进程间的通信方式(socket套接字),但它的原理比较复杂,会牵扯到很多计算机网络的相关知识。
总而言之,我们不仅需要理解进程、线程、以及它们各自之间各种通信方式的概念,同时还需要掌握多进程、多线程的编程。
待补充。。。
5.驱动开发与操作系统
驱动开发则是比应用编程与网络编程更底层的知识了,应用程序通过操作系统提供的API来调用驱动程序。驱动开发在笔试面试题中所占的比例较小,但如果你的项目经历涉及到驱动开发,那么你必须对该项目涉及的相关知识点了如指掌。
(1)驱动开发说到底也跟单片机开发一样是在配置各种外设的寄存器,但是它有了许许多多的框架,你必须严格遵守这些框架才能完成驱动程序的开发,这些框架也称为驱动模型,这是驱动开发必须要掌握的知识。
(2)一个完整的驱动程序通常包括模块的安装函数、模块的卸载函数、设备结构体、文件操作结构体、硬件的读写函数等等,一般在硬件的读写函数中进行具体的寄存器读写操作。
(3)驱动开发还需要掌握内核态下的内存管理、互斥机制、Makefile的编写等等。
操作系统方面的重点则是操作系统内核的原理以及常用的Linux shell指令。
(1)操作系统内核大致可以分为四个子系统:进程管理子系统、内存管理子系统、文件管理子系统、I/O管理子系统,学习操作系统内核的原理就是在学习这四个子系统的原理。
(2)进程管理子系统跟内存管理子系统较为重要,重点有如操作系统的调度策略、内存的分配方式、虚拟内存等等。
待补充。。。