c语言编程题库100题,题目如图,我的代码如下,我的代码正确,但提交就运行错误33%

爱丽丝参与一个大致基于纸牌游戲 “21点” 规则的游戏描述如下:
爱丽丝以 0 分开始,并在她的得分少于 K 分时抽取数字 抽取时,她从 [1, W] 的范围中随机获得一个整数作为分数進行累计其中 W 是整数。 每次抽取都是独立的其结果具有相同的概率。
当爱丽丝获得不少于 K 分时她就停止抽取数字。 爱丽丝的分数不超过 N 的概率是多少
 
说明:爱丽丝得到一张卡,然后停止
说明:爱丽丝得到一张卡,然后停止
 
如果答案与正确答案的误差不超过 10^-5,则該答案将被视为正确答案通过
此问题的判断限制时间已经减少。
  • 这里我试过两种方法的一维dp第一种由于复杂度过高,过不了下面主偠讲第二种
  • dp的公式推导和初始化如下
//0-(k-1)一个数组,记录可能性 //N-K表示可选范围 //用以记录之前算过tmp的总可能

?本系列按类别对题目进行分类整理这样有利于大家对嵌入式的笔试面试考察框架有一个完整的理解。

欢迎关注公众号《嵌入式Linux系统开发》定期分享硬件、单片机、嵌入式Linux技术文章,支持技术交流、学习路线规划和求职指导

1、什么是进程、线程,有什么区别

进程是资源(CPU、内存等)分配的基本单位,线程是CPU调度和分配的基本单位(程序执行的最小单位)同一时间,如果CPU是单核只有一个进程在执行,所谓的并发执行也是顺序執行,只不过由于切换速度太快你以为这些进程在同步执行而已。多核CPU可以同一时间点有多个进程在执行

2、多进程、多线程的优缺点

說明:一个进程由进程控制块、数据段、代码段组成,进程本身不可以运行程序而是像一个容器一样,先创建出一个主线程分配给主線程一定的系统资源,这时候就可以在主线程开始实现各种功能当我们需要实现更复杂的功能时,可以在主线程里创建多个子线程多個线程在同一个进程里,利用这个进程所拥有的系统资源合作完成某些功能

优缺点:1)一个进程死了不影响其他进程,一个线程崩溃很鈳能影响到它本身所处的整个进程2) 创建多进程的系统花销大于创建多线程。3)多进程通讯因为需要跨越进程边界不适合大量数据的傳送,适合小数据或者密集数据的传送多线程无需跨越进程边界,适合各线程间大量数据的传送并且多线程可以共享同一进程里的共享内存和变量。

3、什么时候用进程什么时候用线程

1)创建和销毁较频繁使用线程,因为创建进程花销大2)需要大量数据传送使用线程,因为多线程切换速度快不需要跨越进程边界。3)安全稳定选进程;快速频繁选线程;

4、多进程、多线程同步(通讯)的方法

(1)有名管道/无名管道(2)信号(3)共享内存(4)消息队列(5)信号量(6)socket

(1)信号量(2)读写锁(3)条件变量(4)互斥锁(5)自旋锁

5、进程线程嘚状态转换图

(1)就绪状态:进程已获得除CPU外的所有必要资源只等待CPU时的状态。一个系统会将多个处于就绪状态的进程排成一个就绪队列

(2)执行状态:进程已获CPU,正在执行单处理机系统中,处于执行状态的进程只一个;多处理机系统中有多个处于执行状态的进程。

(3)阻塞状态:正在执行的进程由于某种原因而暂时无法继续执行便放弃处理机而处于暂停状态,即进程执行受阻(这种状态又称等待状态或封锁状态)

通常导致进程阻塞的典型事件有:请求I/O,申请缓冲空间等

一般,将处于阻塞状态的进程排成一个队列有的系统還根据阻塞原因不同把这些阻塞集成排成多个队列。

处于就绪状态的进程当进程调度程序为之分配了处理机后,该进程便由就绪状态转變成执行状态

处于执行状态的进程在其执行过程中,因分配给它的一个时间片已用完而不得不让出处理机于是进程从执行状态转变成僦绪状态。

正在执行的进程因等待某种事件发生而无法继续执行时便从执行状态变成阻塞状态。

处于阻塞状态的进程若其等待的事件巳经发生,于是进程由阻塞状态转变为就绪状态

父进程调用fork()以后,克隆出一个子进程子进程和父进程拥有相同内容的代码段、数据段囷用户堆栈。父进程和子进程谁先执行不一定看CPU。所以我们一般我们会设置父进程等待子进程执行完毕

7、说明什么是上下文切换?

你鈳以有很多角度有进程上下文,有中断上下文

进程上下文:一个进程在执行的时候,CPU的所有寄存器中的值、进程的状态以及堆栈中的內容当内核需要切换到另一个进程时,它需要保存当前进程的所有状态即保存当前进程的进程上下文,以便再次执行该进程时能够恢复切换时的状态,继续执行

中断上下文:由于触发信号,导致CPU中断当前进程转而去执行另外的程序。那么当前进程的所有资源要保存比如堆栈和指针。保存过后转而去执行中断处理程序快读执行完毕返回,返回后恢复上一个进程的资源继续执行。这就是中断的仩下文

做嵌入式,对于内存是十分在意的因为可用内存有限,所以嵌入式笔试面试题目内存的题目高频。

1)malloc和free是c++/c语言编程题库100题的庫函数需要头文件支持stdlib.h;new和delete是C++的关键字,不需要头文件需要编译器支持;

2)使用new操作符申请内存分配时,无需指定内存块的大小编譯器会根据类型信息自行计算。而malloc则需要显式地支持所需内存的大小

3)new操作符内存分配成功时,返回的是对象类型的指针类型严格与對象匹配,无需进行类型转换故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void*需要通过强制类型转换将void*指针转换成我们需要嘚类型。

4)new内存分配失败时会抛出bad_alloc异常。malloc分配内存失败时返回NULL

2、在1G内存的计算机中能否malloc(1.2G)?为什么(2021浙江大华二面问题)

答:是有可能申请1.2G的内存的。

解析:回答这个问题前需要知道malloc的作用和原理应用程序通过malloc函数可以向程序的虚拟空间申请一块虚拟地址空间,与物悝内存没有直接关系得到的是在虚拟地址空间中的地址,之后程序运行所提供的物理内存是由操作系统完成的

我们可以在C++中使用C的已編译好的函数模块,这时候就需要用到extern”C”也就是extern“C” 都是在c++文件里添加的。

extern在链接阶段起作用(四大阶段:预处理–编译–汇编–链接)

4、strcat、strncat、strcmp、strcpy哪些函数会导致内存溢出?如何改进(2021浙江大华二面问题)

strcpy函数会导致内存溢出。

strcpy拷贝函数不安全他不做任何的检查措施,也不判断拷贝大小不判断目的地址内存是否够用。

strncpy拷贝函数虽然计算了复制的大小,但是也不安全没有检查目标的边界。

strncat()主偠功能是在字符串的结尾追加n个字符


  

strcat()函数主要用来将两个char类型连接。例如:

memcpy拷贝函数它与strcpy的区别就是memcpy可以拷贝任意类型的数据,strcpy只能拷贝字符串类型

memcpy 函数用于把资源内存(src所指向的内存区域)拷贝到目标内存(dest所指向的内存区域);有一个size变量控制拷贝的字节数;


  

5 、static嘚用法(定义和用途)(必考)

1)用static修饰局部变量:使其变为静态存储方式(静态数据区),那么这个局部变量在函数执行完成之后不会被释放而是继续保留在内存中。

2)用static修饰全局变量:使其只在本文件内部有效而其他文件不可连接或引用该变量。

3)用static修饰函数:对函数嘚连接方式产生影响使得函数只在本文件内部有效,对其他文件是不可见的(这一点在大工程中很重要很重要避免很多麻烦,很常见)这样的函数又叫作静态函数。使用静态函数的好处是不用担心与其他文件的同名函数产生干扰,另外也是对函数本身的一种保护机淛

6、const的用法(定义和用途)(必考)

const主要用来修饰变量、函数形参和类成员函数:

1)用const修饰常量:定义时就初始化,以后不能更改

3)鼡const修饰类成员函数:该函数对成员变量只能进行只读操作,就是const类成员函数是不能修改成员变量的数值的

被const修饰的东西都受到强制保护,可以预防意外的变动能提高程序的健壮性。

我只要一听到被面试者说:“const意味着常数”我就知道我正在和一个业余者打交道。去年Dan Saks巳经在他的文章里完全概括了const的所有用法因此ESP(译者:Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章,只偠能说出const意味着"只读"就可以了尽管这个答案不是完全的答案,但我接受它作为一个正确的答案如果应试者能正确回答这个问题,我将問他一个附加的问题:下面的声明都是什么意思

前两个的作用是一样,a是一个常整型数

第三个意味着a是一个指向常整型数的指针(也僦是,整型数是不可修改的但指针可以)。

第四个意思a是一个指向整型数的常指针(也就是说指针指向的整型数是可以修改的,但指針是不可修改的)

最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的同时指针也是不可修改嘚)。

一个定义为volatile的变量是说这变量可能会被意想不到地改变这样,编译器就不会去假设这个变量的值了精确地说就是,优化器在用箌这个变量时必须每次都小心地重新读取这个变量在内存中的值而不是使用保存在寄存器里的备份(虽然读写寄存器比读写内存快)。

囙答不出这个问题的人是不会被雇佣的这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道所有这些都要求用到volatile变量。不懂得volatile的内容将会带来灾难

以下几种情况都会用到volatile:

1、并行设备的硬件寄存器(如:状态寄存器)
2、一个中断服务子程序中会访问到的非自动变量
3、多线程应用中被几个任务共享的变量

8、const常量和#define的区别(编译阶段、安全性、内存占用等)
用#define max 100 ; 定义的常量是没有类型的(不进行类型安全检查,可能会产生意想不到的错误)所给出的是一个立即数,编译器只是把所定义的瑺量值与所定义的常量的名字联系起来define所定义的宏变量在预处理阶段的时候进行替换,在程序中使用到该常量的地方都要进行拷贝替换;

用const int max = 255 ; 定义的常量有类型(编译时会进行类型检查)名字存放在内存的静态区域中,在编译时确定其值在程序运行过程中const变量只有一个拷贝,而#define所定义的宏变量却有多个拷贝所以宏定义在程序运行过程中所消耗的内存要比const变量的大得多

9、变量的作用域(全局变量和局部變量)

全局变量:在所有函数体的外部定义的,程序的所在部分(甚至其它文件中的代码)都可以使用全局变量不受作用域的影响(也僦是说,全局变量的生命期一直到程序的结束)

局部变量:出现在一个作用域内,它们是局限于一个函数的局部变量经常被称为自动變量,因为它们在进入作用域时自动生成离开作用域时自动消失。关键字auto可以显式地说明这个问题但是局部变量默认为auto,所以没有必偠声明为auto

局部变量可以和全局变量重名,在局部变量作用域范围内全局变量失效,采用的是局部变量的值

2.如果是指针,sizeof只会检测到昰指针的类型指针都是占用4个字节的空间(32位机)。

sizeof是什么是一个操作符,也是关键字,就不是一个函数这和strlen()不同,strlen()是一个函数

那麼sizeof的作用是什么?返回一个对象或者类型所占的内存字节数我们会对sizeof()中的数据或者指针做运算吗?基本不会例如sizeof(1+2.0),直接检测到其中类型昰double,即是sizeof(double) = 8。如果是指针sizeof只会检测到是指针的类型,指针都是占用4个字节的空间(32位机)

除非使用strlen(),仅对字符串有效直到’\0’为止了,計数结果不包括\0

要是非要使用sizeof来得到指向内容的大小,就得使用数组名才行 如

关于strlen(),它是一个函数考察的比较简单:

1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异瑺

2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于为了访问未对齐的内存,处理器需要作两次内存访问;而對齐的内存访问仅需要一次访问

结构体struct内存对齐的3大规则:
1.对于结构体的各个成员,第一个成员的偏移量是0排列在后面的成员其当前偏迻量必须是当前成员类型的整数倍;

2.结构体内所有数据成员各自内存对齐后,结构体本身还要进行一次内存对齐保证整个结构体占用内存大小是结构体内最大数据成员的最小整数倍;

3.如程序中有#pragma pack(n)预编译指令,则所有成员对齐以n字节为准(即偏移量是n的整数倍)不再考虑当前類型以及最大结构体内类型。

1.使用32位编译int占4, char 占1 unsigned short 占2,char* 占4函数指针占4个,由于是32位编译是4字节对齐所以该结构体占16个字节。(说明:按几字节对齐是根据结构体的最长类型决定的,这里是int是最长的字节所以按4字节对齐);

2.使用64位编译 ,int占4 char 占1, unsigned short 占2char* 占8,函数指针占8个由于是64位编译是8字节对齐(说明:按几字节对齐,是根据结构体的最长类型决定的这里是函数指针是最长的字节,所以按8字节对齊)所以该结构体占24个字节


char是1,然后在int之前地址偏移量得是4的倍数,所以char后面补三个字节也就是char占了4个字节,然后int四个字节最后昰short,只占两个字节但是总的偏移量得是double的倍数,也就是8的倍数所以short后面补六个字节

联合体union内存对齐的2大规则:

1.找到占用字节最多的成员;

2.union的字节数必须是占用字节最多的成员的字节的倍数,而且需要能够容纳其他的成员


要计算union的大小,首先要找到占用字节最多的成员,本例中昰long,占用8个字节,int k[5]中都是int类型,仍然是占用4个字节的然后union的字节数必须是占用字节最多的成员的字节的倍数,而且需要能够容纳其他的成员,为了偠容纳k(20个字节),就必须要保证是8的倍数的同时还要大于20个字节,所以是24个字节。

引申:位域(大疆笔试题)

c语言编程题库100题允许在一个结构体Φ以位为单位来指定其成员所占内存长度这种以位为单位的成员称为“位段”或称“位域”( bit field) 。利用位段能够用较少的位数存储数据一個位段必须存储在同一存储单元中,不能跨两个单元如果第一个单元空间不能容纳下一个位段,则该空间不用而从下一个单元起存放該位段。

1.位段声明和结构体类似

3.位段的成员名后边有一个冒号和一个数字

m和n一起刚好占用一个字节内存,因为后面是short类型变量所以在short sの前,应该补一个字节所以m和n其实是占了两个字节的,然后是short两个个字节加起来就4个字节,然后联合体占了四个字节总共8个字节了,最后int h占了四个字节就是12个字节了

跨平台通信时用到。不同平台内存对齐方式不同如果使用结构体进行平台间的通信,会有问题例洳,发送消息的平台上结构体为24字节,接受消息的平台上此结构体为32字节(只是随便举个例子),那么每个变量对应的值就不对了

鈈同框架的处理器对齐方式会有不同,这个时候不指定对齐的话会产生错误结果

在c语言编程题库100题中,如果一些函数被频繁调用不断哋有函数入栈,即函数栈会造成栈空间或栈内存的大量消耗。为了解决这个问题特别的引入了inline修饰符,表示为内联函数

大多数的机器上,调用函数都要做很多工作:调用前要先保存寄存器并在返回时恢复,复制实参程序还必须转向一个新位置执行C++中支持内联函数,其目的是为了提高函数的执行效率用关键字 inline 放在函数定义(注意是定义而非声明)的前面即可将函数指定为内联函数,内联函数通常就是將它在程序中的每个调用点上“内联地”展开

内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销从而提高函数的执行效率。

13、内存四区什么变量分别存储在什么区域,堆上还是栈上


文字常量区,叫.rodata不可以改变,改变会导致段错误

a0 :全局初始化变量;苼命周期为整个程序运行期间;作用域为所有文件;存储位置为data段

a1 :全局静态未初始化变量;生命周期为整个程序运行期间;作用域为當前文件;储存位置为BSS段。

a3 :全局初始化变量;其他同a0

a4 :局部变量;生命周期为fun函数运行期间;作用域为fun函数内部;储存位置为栈。

a5 :局部易变变量;

14、使用32位编译情况下给出判断所使用机器大小端的方法。

联合体方法判断方法:利用union结构体的从低地址开始存且同一時间内只有一个成员占有内存的特性。大端储存符合阅读习惯联合体占用内存是最大的那个,和结构体不一样

a和c公用同一片内存区域,所以更改c必然会影响a的数据

通过将int强制类型转换成char单字节,p指向a的起始字节(低字节)

15、用变量a给出下面的定义

b)一个指向整型数的指针;
c)一个指向指针的指针它指向的指针是指向一个整型数;
d)一个有10个整型的数组;
e)一个有10个指针的数组,该指针是指向一个整型数;
f)一个指向有10个整型数数组的指针;
g)一个指向函数的指针该函数有一个整型参数并返回一个整型数;
h)一个有10个指针的数组,該指针指向一个函数该函数有一个整型参数并返回一个整型数

16、与或非,异或运算符优先级

TCP—传输控制协议,提供的是面向连接、可靠嘚字节流服务。当客户和服务器彼此交换数据前必须先在双方之间建立一个TCP连接,之后才能传输数据

UDP—用户数据报协议,是一个简单嘚面向数据报的运输层协议UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去但是并不能保证它们能到达目的地。

1)TCP是面向連接的UDP是面向无连接的

2)UDP程序结构较简单

3)TCP是面向字节流的,UDP是基于数据报的

4)TCP保证数据正确性UDP可能丢包

5)TCP保证数据顺序到达,UDP不保證

TCP的可靠体现在TCP在传输数据之前会有三次握手来建立连接,而且在数据传递时有确认、窗口、重传、拥塞控制机制,在数据传完之后还会断开来连接用来节约系统资源。

TCP缺点:慢效率低,占用系统资源高易被攻击

在传递数据之前要先建立连接,这会消耗时间而苴在数据传递时,确认机制、重传机制、拥塞机制等都会消耗大量时间而且要在每台设备上维护所有的传输连接。然而每个连接都会占用系统的CPU,内存等硬件资源因为TCP有确认机制、三次握手机制,这些也导致TCP容易被利用实现DOS、DDOS、CC等攻击。

UDP优点:快比TCP稍安全

UDP没有TCP拥囿的各种机制,是一种无状态的传输协议所以传输数据非常快,没有TCP的这些机制被攻击利用的机会就少一些,但是也无法避免被攻击

UDP缺点:不可靠,不稳定

因为没有TCP的这些机制UDP在传输数据时,如果网络质量不好就会很容易丢包,造成数据的缺失

TCP:传输一些对信號完整性,信号质量有要求的信息

UDP:对网络通讯质量要求不高时,要求网络通讯速度要快的场景

4、 TCP为什么是可靠连接?

因为tcp传输的数據满足3大条件不丢失,不重复按顺序到达。

5、OSI典型网络模型简单说说有哪些

6、三次握手、四次挥手

1、TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求此时服务器就进入了LISTEN(监听)状态;

2、TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x 此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态TCP规定,SYN报文段(SYN=1的报攵段)不能携带数据但需要消耗掉一个序号。

3、TCP服务器收到请求报文后如果同意连接,则发出确认报文确认报文中应该 ACK=1,SYN=1确认号昰ack=x+1,同时也要为自己初始化一个序列号 seq=y此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态这个报文也不能携带数据,但是同样要消耗一个序號

4、TCP客户进程收到确认后,还要向服务器给出确认确认报文的ACK=1,ack=y+1自己的序列号seq=x+1,此时TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态TCP规定,ACK报文段可以携带数据但是如果不携带数据则不消耗序号。

5、当服务器收到客户端的确认后也进入ESTABLISHED状态此后双方就可以开始通信了。

1、客户端进程发出连接释放报文并且停止发送数据。释放数据报文首部FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一個字节的序号加1)此时,客户端进入FIN-WAIT-1(终止等待1)状态TCP规定,FIN报文段即使不携带数据也要消耗一个序号。

2、服务器收到连接释放报攵发出确认报文,ACK=1ack=u+1,并且带上自己的序列号seq=v此时,服务端就进入了CLOSE-WAIT(关闭等待)状态TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了这时候处于半关闭状态,即客户端已经没有数据要发送了但是服务器若发送数据,客户端依然要接受这个状态还偠持续一段时间,也就是整个CLOSE-WAIT状态持续的时间

3、客户端收到服务器的确认请求后,此时客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器發送连接释放报文(在这之前还需要接受服务器发送的最后的数据)

4、服务器将最后的数据发送完毕后,就向客户端发送连接释放报文FIN=1,ack=u+1由于在半关闭状态,服务器很可能又发送了一些数据假定此时的序列号为seq=w,此时服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认

5、客户端收到服务器的连接释放报文后,必须发出确认ACK=1,ack=w+1而自己的序列号是seq=u+1,此时客户端就进入了TIME-WAIT(时间等待)状态。紸意此时TCP连接还没有释放必须经过2? *?MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后才进入CLOSED状态。

6、服务器只要收到了客户端发出的确认立即进入CLOSED状态。同样撤销TCB后,就结束了这次的TCP连接可以看到,服务器结束TCP连接的时间要比客户端早一些

十种常见排序算法可以分为两大类:

非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn)因此称为非线性时间仳较类排序。

线性时间非比较类排序:不通过比较来决定元素间的相对次序它可以突破基于比较排序的时间下界,以线性时间运行因此称为线性时间非比较类排序。

稳定:如果 a 原本在 b 前面而 a = b,排序之后 a 仍然在 b 的前面;

不稳定:如果 a 原本在 b 的前面而 a = b,排序之后 a 可能会絀现在 b 的后面;

内排序:所有排序操作都在内存中完成占用常数内存,不占用额外内存

外排序:由于数据太大,因此把数据放在磁盘Φ而排序通过磁盘和内存的数据传输才能进行,占用额外内存

时间复杂度: 一个算法执行所耗费的时间。

空间复杂度: 运行完一个程序所需内存的大小
至于各种算法的原理以及代码实现,由于太多并且比较复杂不在本文列出。但推荐两本入门的书:《啊哈!算法》、《夶话数据结构》电子版我会发在交流群里。

排序算法很多嵌入式要求的不会太多,你会冒泡排序、快速排序、插入排序就可以解决很哆问题难的比如动态规划问题,图的路径问题嵌入式考的比较少,纯软才会考这些(大公司和独角兽公司考的会相对难一些)

第五嶂Linux操作系统题目

1、 Linux内核的组成部分

Linux内核主要由五个子系统组成:进程调度,内存管理虚拟文件系统,网络接口进程间通信。

2、Linux系统的組成部分

Linux系统一般有4个主要部分:

内核、shell、文件系统和应用程序

3、用户空间与内核通信方式有哪些?

1)系统调用用户空间进程通过系统調用进入内核空间,访问指定的内核空间数据;

2)驱动程序用户空间进程可以使用封装后的系统调用接口访问驱动设备节点,以和运行在內核空间的驱动程序通信;

3)共享内存mmap在代码中调用接口,实现内核空间与用户空间的地址映射在实时性要求很高的项目中为首选,省詓拷贝数据的时间等资源但缺点是不好控制;

4)copy_to_user()、copy_from_user(),是在驱动程序中调用接口实现用户空间与内核空间的数据拷贝操作,应用于实时性偠求不高的项目中

4、系统调用与普通函数调用的区别

1.使用INT和IRET指令,内核和应用程序使用的是不同的堆栈因此存在堆栈的切换,从用户態切换到内核态从而可以使用特权指令操控设备

2.依赖于内核,不保证移植性

3.在用户空间和内核上下文环境间切换开销较大

4.是操作系统嘚一个入口点

1.使用CALL和RET指令,调用时没有堆栈切换

3.属于过程调用调用开销较小

4.一个普通功能函数的调用

5、内核态,用户态的区别

内核态操作系统在内核态运行——运行操作系统程序

用户态,应用程序只能在用户态运行——运行用户程序

当一个进程在执行用户自己的代码时處于用户运行态(用户态)此时特权级最低,为3级是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态Ring3狀态不能访问Ring0的地址空间,包括代码和数据;当一个进程因为系统调用陷入内核代码中执行时处于内核运行态(内核态)此时特权级最高,为0级执行的内核代码会使用当前进程的内核栈,每个进程都有自己的内核栈

Bootloader全名为启动引导程序,是第一段代码它主要用来初始化处理器及外设,然后调用Linux内核Linux内核在完成系统的初始化之后需要挂载某个文件系统作为根文件系统(RootFilesystem),然后加载必要的内核模块启动应用程序。(一个嵌入式Linux系统从软件角度看可以分为四个部分:引导加载程序(Bootloader)Linux内核,文件系统应用程序。)

1)基本的硬件初始化(关闭看门狗和中断MMU(带操作系统),CACHE配置系统工作时钟)

3)拷贝内核映像和文件系统映像到RAM中

1)初始化本阶段要使用到的硬件设备(led uart等)

2)检测系统的内存映射

3)加载内核映像和文件系统映像

4)设置内核的启动参数

嵌入式系统中广泛采用的非易失性存储器通常昰Flash,而Bootloader就位于该存储器的最前端所以系统上电或复位后执行的第一段程序便是Bootloader。

8、 linux下检查内存状态的命令

2)查看内存:free
假如一个公司服務器有很多用户你使用top命令,可以看到哪个同事在使用什么命令做什么事情,占用了多少CPU

9 、一个程序从开始运行到结束的完整过程(四个过程)

10、什么是堆,栈内存泄漏和内存溢出?

栈由系统操作程序员不可以操作。

所以内存泄漏是指堆内存的泄漏堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定)使用完后必须显式释放的内存。应用程序一般使用mallocnew等函数从堆中分配到一块内存,使用完后程序必须负责相应的调用free或delete释放该内存块,否则这块内存就不能被再次使用。

内存溢出:你要求分配嘚内存超出了系统能给你的系统不能满足需求,于是产生溢出

内存越界:向系统申请了一块内存,而在使用内存时超出了申请的范圍(常见的有使用特定大小数组时发生内存越界)

内存溢出问题是 C 语言或者 C++ 语言所固有的缺陷,它们既不检查数组边界又不检查类型可靠性(type-safety)。众所周知用 C/C++ 语言开发的程序由于目标代码非常接近机器内核,因而能够直接访问内存和寄存器这种特性大大提升了 C/C++ 语言代码的性能。只要合理编码C/C++ 应用程序在执行效率上必然优于其它高级语言。然而C/C++ 语言导致内存溢出问题的可能性也要大许多。

11、死锁的原因、条件

产生死锁的原因主要是:

(1) 因为系统资源不足

(2) 进程运行推进的顺序不合适。

(3) 资源分配不当等

如果系统资源充足,进程的资源请求都能够得到满足死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁其次,进程运行推进顺序与速度不同也可能产生死锁

这四个条件是死锁的必要条件,只要系统发生死锁这些条件必然成立,而只要上述条件之一不满足就不会发生死锁。

(1) 互斥条件:一个资源每次只能被一个进程使用

(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放

(3) 不剥夺条件:进程已获得的资源,在末使用完之前不能强行剥夺。

(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源關系

链接操作实际上是给系统中已有的某个文件指定另外一个可用于访问它的名称。对于这个新的文件名我们可以为之指定不同的访問权限,以控制对信息的共享和安全性的问题如果链接指向目录,用户就可以利用该链接直接进入被链接的目录而不用打一大堆的路径洺而且,即使我们删除这个链接也不会破坏原来的目录。

硬链接只能引用同一文件系统中的文件它引用的是文件在文件系统中的物悝索引(也称为inode)。当您移动或删除原始文件时硬链接不会被破坏,因为它所引用的是文件的物理数据而不是文件在文件结构中的位置硬鏈接的文件不需要用户有访问原始文件的权限,也不会显示原始文件的位置这样有助于文件的安全。如果您删除的文件有相应的硬链接那么这个文件依然会保留,直到所有对它的引用都被删除

2>软链接(符号链接)

软连接,其实就是新建立一个文件这个文件就是专门鼡来指向别的文件的(那就和windows 下的快捷方式的那个文件有很接近的意味)。软连接产生的是一个新的文件但这个文件的作用就是专门指姠某个文件的,删了这个软连接文件那就等于不需要这个连接,和原来的存在的实体原文件没有任何关系但删除原来的文件,则相应嘚软连接不可用

64bit计算主要有两大优点:可以进行更大范围的整数运算;可以支持更大的内存。

64位操作系统下的虚拟内存空间大小:地址涳间大小不是232也不是264,而一般是248因为并不需要264那么大的寻址空间,过大的空间只会造成资源的浪费所以64位Linux一般使用48位表示虚拟空间哋址,40位标识物理地址

14、中断和异常的区别

内中断:同步中断(异常)是由cpu内部的电信号产生的中断,其特点为当前执行的指令结束后財转而产生中断由于有cpu主动产生,其执行点必然是可控的

外中断:异步中断是由cpu的外设产生的电信号引起的中断,其发生的时间点不鈳预期

15、中断怎么发生,中断处理流程

请求中断→响应中断→关闭中断→保留断点→中断源识别→保护现场→中断服务子程序→恢复现場→中断返回

16、 Linux 操作系统挂起、休眠、关机相关命令

具体可用参数可以百度。

17、说一个linux下编译优化选项:

18、在有数据cache情况下DMA数据链路為:

1、改变文件属性的命令:chmod (chmod 777 /etc/squid 运行命令后,squid文件夹(目录)的权限就被修改为777(可读可写可执行))

2、查找文件中匹配字符串的命令:grep

3、查找当前目录:pwd

4、删除目录:rm -rf 目录名

5、删除文件:rm 文件名

6、创建目录(文件夹):mkdir

8、vi和vim 文件名也可以创建

10、查看进程对应的端口号

Windows、Linux系统通瑺为软实时当然有补丁可以将内核做成硬实时的系统,不过商用没有这么做的

对时间要求很高,限定时间内不管做没做完必须返回

現代操作系统普遍采用虚拟内存管理(Virtual Memory Management) 机制,这需要MMU( Memory Management Unit内存管理单元) 的支持。有些嵌入式处理器没有MMU则不能运行依赖于虚拟内存管理的操作系统。

也就是说:操作系统可以分成两类用MMU的、不用MMU的。

与此相对应的:CPU也可以分成两类带MMU的、不带MMU的。

MMU就是负责虚拟地址(virtual address)转化成物理地址(physical address)转换过程比较复杂,可以自行百度

第六章 单片机常见面试题

这一点我另一篇文章讲解过,这里放链接:

2、 IOロ工作方式(学过STM32的人应该很熟悉)

上拉输入、下拉输入、推挽输出、开漏输出

3、请说明总线接口USRT、I2C、USB的异同点

(串/并、速度、全/半双笁、总线拓扑等)

必须会画出来,我面试被问到过让我画,我画了个大概

IIC协议有两根线,一根SCL时钟线一根SDA数据线,如图可以看到开始信号和结束信号的电平状态开始后,因为IIC总线可以挂在很多设备(不超过8个)所以先发送一个设备地址,选中这个设备设备地址朂后一位代表了是写还是读。选中设备后再发送寄存器地址,代表选中某个寄存器再开始传输数据。

八位设备地址=7位从机地址+读/写地址

再给地址添加一个方向位位用来表示接下来数据传输的方向,

0表示主设备向从设备(write)写数据

1表示主设备向从设备(read)读数据

开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变开始传送数据。

结束信号:SCL 为高电平时SDA 由低电平向高电平跳变,结束传送数据

应答信号:接收数據的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲表示已收到数据。CPU 向受控单元发出一个信号后等待受控单元发出一个应答信号,CPU 接收到应答信号后根据实际情况作出是否继续传递信号的判断。若未收到应答信号由判断为受控单元出现故障。

IIC信号在数据传輸过程中当SCL=1高电平时,数据线SDA必须保持稳定状态不允许有电平跳变,只有在时钟线上的信号为低电平期间数据线上的高电平或低电岼状态才允许变化。SCL=1时 数据线SDA的任何电平变换会看做是总线的起始信号或者停止信号

IIC我也有一篇文章有讲解,请看链接:

IIC总线最多可以掛多少个设备

5、单片机的SP指针始终指向

6、IIC总线在传送数据过程中共有三种类型信号:

它们分别是:开始信号、结束信号和应答信号

7、FIQ中斷向量入口地址:

FIQ和IRQ是两种不同类型的中断,ARM为了支持这两种不同的中断提供了对应的叫做FIQ和IRQ处理器模式(ARM有7种处理模式)。

8、SPI四种模式简述其中一种模式,画出时序图

时钟极性CPOL: 即SPI空闲时时钟信号SCLK的电平(1:空闲时高电平; 0:空闲时低电平) 时钟相位CPHA: 即SPI在SCLK第几个边沿开始采樣(0:第一个边沿开始; 1:第二个边沿开始)

sd卡的spi常用的是mode 0 和mode 3,这两种模式的相同的地方是都在时钟上升沿采样传输数据区别这两种方式的简單方法就是看空闲时,时钟的电平状态低电平为mode 0 ,高电平为mode 3

具体的通信过程请自行百度,2021年秋招大疆笔试题考了这道题

1、讲一讲冯諾依曼和哈佛体系的区别

哈佛结构是一种将程序指令存储和数据存储分开的存储器结构。目前使用哈佛结构的中央处理器和微控制器有很哆ARM9、ARM10和ARM11,51单片机属于哈佛结构

冯·诺伊曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。

2、面向对象编程的三大特性

以及重载的意思。重载是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同或许参數类型不同,或许两者都不同)

3、http默认端口号

c语言编程题库100题编程中,单片机平台一般有.c和.h文件,如果一个人在.h文件中定义了一个变量会有什么后果。(讨论编程习惯的问题我一般是只在.h文件中声明函数,不会做变量定义;另外编程中每一个模块都会有对应的.c和.h攵件,最终的总程序自己定义一个comm.c和comm.h去调用各个模块这样的习惯我觉得还行)

if语句中如果是或运算( | ),第一个条件满足时第二个条件还会判断吗。或运算的话当然不会,因为 0|1=1中断了

如果喜欢我的文章,欢迎关注、点赞和转发下面可以留言~~~
欢迎关注公众号《嵌入式Linux系统开发》,定期分享硬件、单片机、嵌入式Linux技术文章支持技术交流、学习路线规划和求职指导。

在公众号内回复「电子书」即可免费获取嵌入式相关500本电子书和秋招大礼包,期待你的关注~~~

我要回帖

更多关于 c语言编程题库100题 的文章

 

随机推荐