面试真题 | 极氪
开篇强调个事情:
- 一定要把超链接里面的文章看了,那都是为了你们写的。老板!!!现在多学点,涨个2k工资,真的很值得。
要不吃学习的苦,要不吃生活的苦。
1. 自我介绍
专开新篇,等我!
2. 项目介绍,提问
专开新篇,等我!
3. SPI通信和I2C的速率
SPI通信
SPI 主设备组件提供了行业标准的 4 线主设备 SPI 接口。此外,它还提供 3 线(双向)SPI 接口。
这两种接口都支持四种 SPI 工作模式,可与任何 SPI 从设备进行通信。除了标准 8 位字长之外,SPI 主设备还支持可配置的 3 ~ 16 位字长,用于与非标准 SPI 字长进行通信。
SPI 信号包括标准串行时钟(SCLK)、主入从出(MISO)、主出从入(MOSI)、双向串行数据(SDAT)和从设备选择(SS)。
更多一定要看下面的链接,专门为老板你写的,不真实的掌握,随便一追问你就露馅了。
I2C通信
I2C就是IIC或者I2C,全称Inter-Integrated Circuit,内部集成电路总线,是飞利浦公司在上世纪八十年代初开发的一种同步的串行通信总线。
与SPI相比,它的接线形式更简单,只需要两根信号线就可以实现数据的双向传送。
它被广泛地应用在EEPROM这样的存储设备上,近年来在四轴无人机上也有广泛的应用,比如说MPU6050这样的IMU传感器。
I2C是一种同步的通信机制,两根信号线一根用于时钟信号,另一根则用于数据传送。根据时钟信号的来源,I2C的通信设备分为主从两种模式。
每次通信都是由主设备发起,并产生时钟信号用于主从设备之间的数据同步,在通信结束后,主设备需要停止产生时钟。
I2C总线上允许连接多个设备, 与SPI的片选信号不同的是,它采用寻址的方式选定从设备通信。
更多一定要看下面的链接,专门为老板你写的,不真实的掌握,随便一追问你就露馅了。
4. LCD驱动
5. 设备和驱动如何匹配的?
匹配的顺序:
- 1、先用设备树中的 compatible 属性和 platform_driver中的driver中的 of_match_table 来匹配
- 2、再用 platform_driver 中的 id_table 中的 name 和 platform_device 中的 name来匹配
- 3、最后用platform_device中的name和 platform_driver 中的 driver中的 name来匹配
但是这些东西,咱们还是要深层次的搞熟悉。毕竟这些东西在咱们工作的时候也会用到。所以大家一定要详细的看看下面这几篇文章:
6. 设备树是怎么做的?
7. bootloader的流程
-
BootLoader的第一阶段通常包含以下步骤(以执行的先后顺序):
- 硬件设备初始化
- 为加载 Boot Loader的stage2准备RAM空间。
- 拷贝Boot Loader的stage2到RAM空间中。
- 设置好堆栈。
- 跳转到stage2 的 C 入口点。
-
BootLoader的第二阶段通常包括以下步骤(以执行的先后顺序):
- 初始化本地阶段要使用到的硬件设备
- 检测系统内存映射(memory map)
- 将kernel映像和根文件系统映像从flash上读到RAM空间中。
- 为内核设置启动参数
- 调用内核
8. uboot和BootLoader的关系,uboot的流程
uboot这玩意真的能考很多,同时也是真的很实用!!!
9. 智能指针的底层实现
三种智能指针:
- std::shared_ptr:
使用引用计数,每一个shared_ptr的拷贝都指向相同的内存,每次拷贝都会触发引用计数+1,每次生命周期结束析构的时候引用计数-1,在最后一个shared_ptr析构的时候,内存才会释放。
- std::weak_ptr:
用来监视shared_ptr的生命周期,它不管理shared_ptr内部的指针,它的拷贝析构都不会影响引用计数,纯粹是作为一个旁观者监视shared_ptr中管理的资源是否存在,可以用来返回this指针和解决循环引用问题。
- std::unique_ptr:
独占型的智能指针,它不允许其它智能指针共享其内部指针,也不允许unique_ptr的拷贝和赋值。
10. 构造函数能否声明为虚函数?
inline, static, constructor三种函数都不能带有virtual关键字。 inline是编译时展开,必须有实体;
static属于class自己的,也必须有实体;
virtual函数基于vtable(内存空间),constructor函数如果是virtual的,调用时也需要根据vtable寻找,但是constructor是virtual的情况下是找不到的,因为constructor自己本身都不存在了,创建不到class的实例,没有实例,class的成员(除了public static/protected static for friend class/functions,其余无论是否virtual)都不能被访问了。
虚函数实际上不能被内联:虚函数运行时所需的代价主要是虚函数不能是内联函。
这也是非常好理解的,是因为内联函数是指在编译期间用被调用的函数体本身来代替函数调用的指令,但是虚函数的“虚”是指“直到运行时才能知道要调用的是哪一个函数。”
但虚函数的运行时多态特性就是要在运行时才知道具体调用哪个虚函数,所以没法在编译时进行内联函数展开。
当然如果通过对象直接调用虚函数它是可以被内联,但是大多数虚函数是通过对象的指针或引用被调用的,这种调用不能被内联。 因为这种调用是标准的调用方式,所以虚函数实际上不能被内联。
**构造函数不能是虚函数。**而且,在构造函数中调用虚函数,实际执行的是父类的对应函数,因为自己还没有构造好, 多态是被disable的。
虚函数对应一个vtable(虚函数表),类中存储一个vptr指向这个vtable。如果构造函数是虚函数,就需要通过vtable调用,可是对象没有初始化就没有vptr,无法找到vtable,所以构造函数不能是虚函数。
你可以这样回答!
- 1.构造函数不可以是虚函数,因为虚函数时通过vtable来调用的,而vtable是通过构造函数来构建的,所以这就矛盾了,因此不可以是虚函数。
- 2.如果有继承存在,则多态基类的析构函数必须是虚函数,要不然对象析构的时候会导致内存没法完全释放,即没法析构子类对象的内存空间
静态的对象是属于整个类的,不对某一个对象而言,同时其函数的指针存放也不同于一般的成员函数,其无法成为一个对象的虚函数的指针以实现由此带来的动态机制。
11. 如何理解哈希?
- 作为名词,指哈希函数。(和哈希算法,散列函数,散列算法,消息摘要函数,消息摘要算法,指的是同一种东西)
- 作为动词,指执行哈希函数这一行为的过程。
- Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。简单的说就是一种将不固定长度的值压缩到某一固定长度的值的函数。
从网上搜了下“哈希”,发现没有直接关于“哈希”这个词的解释,都是周边相关的,例如,哈希函数,哈希算法,散列函数,哈希表什么的。 初步给人感觉这个词语极有可能是一类东西的统称,就像水果,汽车这样词语。
后来又google了英文hash [hæʃ] 发现维基百科中关于hash在计算机方面的解释,也是罗列了一些哈希函数,哈希表这样相关词语。
- 所以吧,这他不能挑你的问题了!
- 参考连接:https://gist.github.com/arrayadd/8a4ab3f05
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
让实战与真题助你offer满天飞!!! 每周更新!!! 励志做最全ARM/Linux嵌入式面试必考必会的题库。 励志讲清每一个知识点,找到每个问题最好的答案。 让你学懂,掌握,融会贯通。 因为技术知识工作中也会用到,所以踏实学习哦!!!