北京君正笔试题
北京君正笔试题
常规题
答案
#define MULT(A, B) (A) * (B)
答案
#define 8GNUM 8*1024*1024
答案
volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改。volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如 果没有 volatile 关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。所以遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
参考
答案
const int* a
:表示a是一个指针,它指向的是一个常量int类型的数据,不可更改。int* const a
:表示a是一个常量指针,它指向的int类型的数据是可以改变的,但是a本身是一个常量指针,不能改变其指向。
答案
1 | a = a ^ b; |
答案
A
答案
vector
:可变大小的数组,可以保存任意类型的数据;list
:双向链表,可以快速插入和删除元素;deque
:双端队列,可以快速在两端添加或移除元素;stack
:后进先出(LIFO)的数据结构;queue
:先进先出(FIFO)的数据结构;priority_queue
:优先队列,根据元素的优先级来排序;set
:集合,保存唯一无序的元素;map
:映射,以 key-value 的形式存储元素;unordered_set
:无序集合,保存唯一无序的元素;unordered_map
:无序映射,以 key-value 的形式存储元素。
答案
设计模式是指在特定情况下,为解决某一特定问题而提出的模式化的、可重复使用的解决方案。常见的设计模式有单例模式、工厂模式、模板模式等等。
例如:工厂模式:工厂模式是一种用于创建对象的设计模式,其目的是将具体的创建逻辑从客户端代码中分离出来,从而使得同一个工厂可以创建出不同类型
的对象。例如,一个汽车工厂可以创建出轿车、卡车和SUV等不同类型的汽车。
答案
C++中引用和指针的区别主要有以下几点:
- 引用是一种符号,而指针是一种变量。
- 引用必须在声明的时候初始化,而指针可以在任何时候进行初始化。
- 引用只能绑定到一个对象,而指针可以在任何时候指向任何对象。
- 引用不能为空,而指针可以为空。
- 引用的大小和原对象的大小是一样的,而指针的大小取决于指针变量的类型。
- 引用可以用来改变原始值,而指针只能用来改变指向的对象。
- 引用更安全,指针更灵活。
答案
1 | char *my_strcpy(char *dest, const char *src) |
答案
1 | void sort(int array[]) { |
附加题
答案
DMA的数据一致性是指在DMA传输过程中,源和目的地中的数据保持一致。为了保证数据的一致性,DMA控制器通常会进行一些特定的操作,比如实现缓冲器或缓存的技术,以确保数据的完整性和一致性。另外,DMA控制器还可以采用一些错误检测技术,比如校验和等,来检测数据传输过程中是否出现错误。
答案
inux内核提供了多种内存申请方法,比如kmalloc
、vmalloc
、__get_free_pages
、__get_dma_pages
等等,它们有以下几种不同的特点:
kmalloc
:该函数可以用于申请任意大小的内存块,但大小不能超过一定的限制(通常在128KB以下),并且可以用于非DMA内存申请;vmalloc
:该函数可以用于申请任意大小的内存块,且大小没有上限,但由于它使用的是虚拟的内存空间,所以速度会比较慢;__get_free_pages
:该函数可以用于申请大小为一页(4KB)的内存块,并且可以用于非DMA内存申请;__get_dma_pages
:该函数可以用于申请大小为一页(4KB)的内存块,并且只能用于DMA内存申请。
答案
答案
TLB(Translation Lookaside Buffer)是一种高速缓存,用于翻译虚拟地址到物理地址。TLB 将虚拟地址映射到物理地址的过程称为“地址翻译”。TLB 中的每一项都包含了虚拟地址和相应的物理地址。当 CPU 尝试访问一个虚拟地址时,它会首先检查 TLB,如果找到相应的物理地址,就可以直接访问;如果没有找到,就会调用内存管理单元(MMU),MMU 会从页表中查找相应的物理地址,并将其添加到 TLB 中,之后 CPU 会使用该物理地址来访问内存。
内核是通过将虚拟地址映射到物理地址来使用 TLB,即将虚拟地址映射到物理地址,以便在访问内存时,可以减少对内存管理单元(MMU)的调用,从而提高效率。内核会首先检查 TLB 中是否有虚拟地址对应的物理地址,如果有,就会直接使用该物理地址;如果没有,就会调用 MMU,从中查找相应的物理地址,并将其添加到 TLB 中,之后内核会使用该物理地址来访问内存。
答案
#define MULT(A, B) (A) * (B)
答案
中断是用来处理硬件或软件异常的一种机制,它可以帮助系统检测到并处理硬件或软件错误,以便系统能够恢复正常运行。
所谓这个中断在arm这个架构下分了三层。所谓中断,就是cpu感知外部事件变化的一种方式。除了中断,还有轮询,还有DMA,但是中断是我们用的最多的一种方式。
中断它和轮询相比,不需要cpu不断的去检测或者探测外设的状态。所谓中断就是指的是当外设或者系统定时器,产生了一个中断信号将来要上报给Cpu,但是cpu不会去直接接收中断信号,cpu让中断控制器去接收。
之前在玩STM32的过程中发现不是说所有的这些外设都是直接的连接到中断控制器上的,有一部分是通过外部中断连接到了中断控制器上,比如说我们的gpio的管脚是连接到了外部中断上,将来外部中断是不是再连接到中断控制器上。也就是说将来我的串口、i2C的那些设备可以直接给中断控制器发送中断信号,但是我gpio类的接口我得通过外部中断去上报这终端信号。再有我中断控制器可以进行中断屏蔽。我可以屏蔽你的这些外部中断,也可以不屏蔽,如果不屏蔽中断,中断信号就可以往上报了,往上报就报给中断控制器。
中断控制器完成两个事,第一:为所有连接到这上面的中断源分配一个中断号,而且这个中断号跟异常向量表里边的顺序是息息相关的,不能轻易更改,要想改的话,也得在最后边改。如果我一改,那个顺序乱了就接收不了中断。这是中断控制器要干的。为所有连接上来的中断源分配一个中断信号。
第二:还要处理中断优先级的问题。arm在提供解决方案的时候,给咱们规定了一个8位的寄存器,也就是256个优先级,256个可设置的优先级,还有三个固定的NMI,Reset还有一个硬件失效,stm32只支持16个中断优先级。
中断优先级又分一个组优先和子优先,所以我就需要到时候去配组优先和子优先的配比问题,要设置配比。到这儿,中断控制器就搞定了中断信号,比如说按键按下了以后,这个中断信号就进入了中断控制器,报给了Cpu核。至于说cpu核心怎么去处理,那是不是就cpu核的事了。
总结
君正面试题个人感觉比较全面,C/C++基础、Linux、硬件原理还有考察纠错能力。如果想要全部写出来难度还是有的,特别是附加题,想要精炼简洁地写出题目要点,还是要下很多的功夫。
2021年的面试题大相径庭,就是常规题多了一道对于static
的理解这里先不整理,后续面试题再进行整理。