嵌入式面试题答案**

答案解析:

题1答案:

(1)复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。

(2)复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。

(3)用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

题2答案:

  • 互斥量用于线程的互斥,信号量用于线程的同步。

    互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

    同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。

  • 互斥量值只能为0/1,信号量值可以为非负整数。

也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。

  • 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。

题3答案:

  • 预处理:预处理相当于根据预处理命令组装成新的C程序,不过常以i为扩展名。
  • 编译: 将得到的i文件翻译成汇编代码.s文件。
  • 汇编:将汇编文件翻译成机器指令,并打包成可重定位目标程序的O文件。该文件是二进制文件。
  • 链接:将引用的其他O文件并入到我们程序所在的o文件中,处理得到最终的可执行文件。

题4答案:

  •  在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
  • 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
  • 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

题5答案:

 

  • 只读。
  • 使用关键字const也许能产生更紧凑的代码。
  • 使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。

 

题6答案:

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

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

题7答案:

  可以。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

题8答案:

  可以。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

题9答案:

a|=1<<3;      //bit3置1
a&=~(1<<3)  //bit3置0 

 题10答案:

  • ISR 不能返回一个值。
  • ISR 不能传递参数。
  • 在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。
  • printf()经常有重入和性能上的问题。

题11答案:

1、结构体

  • 各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。

2、联合体:

  • 各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度。应该说明的是, 这里所谓的共享不是指把多个成员同时装入一个联合变量内, 而是指该联合变量可被赋予任一成员值,但每次只能赋一种值, 赋入新值则冲去旧值。  

题12答案:

答:

1、总是使用不经常改动的大型代码体。

2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。

题13答案:

答:指针是多少位只要看地址总线的位数就行了。80386以后的机子都是32的数据总线。所以指针的位数就是4个字节了。

题14答案:

答:能,局部会屏蔽全局。

  局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。

  对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。

题15答案:

  • 引用必须被初始化,指针不必。
  • 引用初始化以后不能被改变,指针可以改变所指的对象。
  • 不存在指向空值的引用,但是存在指向空值的指针。

题16答案:

  答:真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮你创建了一个主线程。

  每个线程有自己的堆栈。

题17答案:

答:TCP和UDP是OSI模型中的运输层中的协议。TCP提供可靠的通信传输,而UDP则常被用于广播和细节控制交给应用的通信传输,两者主要的不同体现在一下几个方面:

  1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接

  2、TCP提供可靠的服务。它通过校验和,丢包时的重传控制,序号标识,滑动窗口、确认应答,次序乱掉的分包进行顺序控制实现可靠传输。即通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达; UDP尽最大努力交付,即不保证可靠交付。

  3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高要求的通信或广播通信场景。

  4、每一条TCP连接只能是点到点的; UDP支持一对一,一对多,多对一和多对多的交互通信方式。

  5、TCP对系统资源要求较多,UDP对系统资源要求较少。

UDP有时比TCP更有优势:

UDP以其简单、传输快的优势,在越来越多场景下取代了TCP, 如实时游戏。

  (1)网速的提升给UDP的稳定性提供可靠网络保障,丢包率很低,如果使用应用层重传,能够确保传输的可靠性。

  (2)TCP为了实现网络通信的可靠性,使用了复杂的拥塞控制算法,建立了繁琐的握手过程,由于TCP在内置的系统协议栈中,极难对其进行改进。

  采用TCP,一旦发生丢包,TCP会将后续的包缓存起来,等前面的包重传并接收到后再继续发送,延时会越来越大。

  基于UDP对实时性要求较为严格的情况下,采用自定义重传机制,能够把丢包产生的延迟降到最低,尽量减少网络问题造成的影响。

题18答案:

嵌入式面试题答案**嵌入式面试题答案**

 

 

题20答案:

 

  线程同步是指多线程通过特定的设置(如互斥量,事件对象,临界区)来控制线程之间的执行顺序(即所谓的同步)也可以说是在线程之间通过同步建立起执行顺序的关系。

 

(1)互斥量

  • 只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程同时访问。

(2)事件对象

  • 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作

(3)临界区

  • 通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
  • 在任意时刻只允许一个线程对共享资源进行访问
  • 如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。
  • 它并不是核心对象,不是属于操作系统维护的,而是属于进程维护的。

  线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作,而其他线程又处于等待状态,实现线程同步的方法有很多,临界区对象就是其中一种。

  在一般情况下,创建一个线程是不能提高程序的执行效率的,所以要创建多个线程。但是多个线程同时运行的时候可能调用线程函数,在多个线程同时对同一个内存地址进行写入,由于CPU时间调度上的问题,写入数据会被多次的覆盖,所以就要使线程同步。

题21答案:

(1)数组:

  • 优点——静态分配空间,而且局部申请,局部释放,你不用为他的内存空间管理而费心,
  • 缺点——灵活性不强,需要在编译时就确定数组的大小。

(2)指针

  • 优点——动态分配空间,极大的方便了动态数据结构的构造,因而灵活性强,
  • 缺点——内存空间的管理只能靠手工完成,而且容易造成内存错误。

题22答案:

  消息队列。

题23答案:

  一个程序至少一个进程,一个进程至少一个线程。

(1)进程线程的区别
  • 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
  • 资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。
  • 一个进程崩溃后,在保护模式下不会对其他进程产生影响,
  • 但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
  • 进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。。
  • 如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程
 (2)执行过程
  • 每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口。
  • 线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
  • 线程是处理器调度的基本单位,但是进程不是。
  • 两者均可并发执行。
(3)优缺点
  • 线程执行开销小,但是不利于资源的管理和保护。线程适合在SMP机器(双CPU系统)上运行。
  • 进程执行开销大,但是能够很好的进行资源管理和保护。进程可以跨机器前移。
 (4)多进程和多线程的优缺点 
  1)多进程优点
  • 每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系;
  • 通过增加CPU,就可以容易扩充性能;
  • 可以尽量减少线程加锁/解锁的影响,极大提高性能,就算是线程运行的模块算法效率低也没关系;
  • 每个子进程都有2GB地址空间和相关资源,总体能够达到的性能上限非常大
  2)多进程缺点
  • 逻辑控制复杂,需要和主程序交互;
  • 需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算
  • 多进程调度开销比较大;
  1)多线程的优点
  • 无需跨进程边界;
  • 程序逻辑和控制方式简单;
  • 所有线程可以直接共享内存和变量等;
  • 线程方式消耗的总资源比进程方式好;
  2)多线程缺点
  • 每个线程与主程序共用地址空间,受限于2GB地址空间;
  • 线程之间的同步和加锁控制比较麻烦;
  • 一个线程的崩溃可能影响到整个程序的稳定性;
  • 到达一定的线程数程度后,即使再增加CPU也无法提高性能,例如Windows Server 2003,大约是1500个左右的线程数就快到极限了(线程堆栈设定为1M),如果设定线程堆栈为2M,还达不到1500个线程总数;
  • 线程能够提高的总性能有限,而且线程多了之后,线程本身的调度也是一个麻烦事儿,需要消耗较多的CPU
(5)线程最多有多少个?

  看用户虚拟内存有多少,根据分配的栈空间决定。

  进程最多可以创建的线程数是根据分配给调用栈的大小,以及操作系统(32位和64位不同)共同决定的。

题24答案:

  • 对资源的管理和保护要求高,不限制开销和效率时,使用多进程。
  • 要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程。

 题25答案:

  • 管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
  • 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
  • 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  • 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
  • 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  • 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
  • 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

题26答案:

Linux下使用虚拟内存空间给每一个进程,32位操作系统下,每个进程都有独立的4G虚拟内存空间。
其中包括:

(1)内核区:用户代码不可见的区域,页表就存放在这个区域中。

(2)用户区

  • 代码段:只可读,不可写,程序代码段。
  • 数据段:保存全局变量,静态变量的区域
  • 堆区:就是动态内存,通过malloc,new申请内存,有一个堆指针,可以通过brk系统调用调整堆指针。
  • 文件映射区域:通过mmap系统调用,如动态库,共享内存等映射物理空间的内存区域。可以单独释放,不会产生内存碎片。
  • 栈区:用于维护函数调用的上下文空间,用ulimit -s 查看。一般默认为8M。

嵌入式面试题答案**

 

 

 题27答案:

嵌入式面试题答案**

 

 

(1)创建状态New  

  满足运行条件(分配到除CPU外的资源),进入就绪状态

(2)就绪状态Runnable/Start  

  获取CPU资源,得到时间片,进入运行状态

(3)运行状态Running
  • 主动睡眠sleep(),进入Time Waiting状态
  • 主动等待wait(),进入Waiting状态
  • I/O请求或者申请缓冲区失败,进入阻塞状态
  • 中断或者执行完毕,进入终止阶段
  • 时间片用完,进入就绪状态
(4)Time Waiting

  睡眠时间到,进入就绪状态

(5)Waiting

  被唤醒,进入就绪状态

(6)阻塞状态Blocked  

  I/O完成或者同步块释放,进入就绪状态

(7)消亡/终止状态Dead/Terminated

 题49答案 :

  • 冒泡排序
  • 选择排序
  • 插入排序
  • 希尔排序
  • 归并排序
  • 快速排序

 

上一篇:今日总结:网络编程


下一篇:计算机网络再次整理————tcp例子[五]