最近收集了许多嵌软的面试题,内容都是在很多文章中剪下来的!
目录
9.写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式中 a的值
1.死锁是什么?死锁的原因有哪些?
死锁: 指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。
死锁的原因有两个:
a. 竞争资源
1)可剥夺资源,是指某进程在获得这类资源后,该资源可以再被其他进程或系统剥夺,CPU和主存均属于可剥夺性资源;
2)不可剥夺资源,当系统把这类资源分配给某进程后,再不能强行收回,只能在进程用完后自行释放,如磁带机、打印机等。
产生死锁中的竞争资源之一指的是竞争不可剥夺资源(例如:系统中只有一台打印机,可供进程P1使用,假定P1已占用了打印机,若P2继续要求打印机打印将阻塞)。
产生死锁中的竞争资源另外一种资源指的是竞争临时资源(临时资源包括硬件中断、信号、消息、缓冲区内的消息等),通常消息通信顺序进行不当,则会产生死锁。
b. 进程间推进顺序非法
若P1保存了资源R1,P2保存了资源R2,系统处于不安全状态,因为这两个进程再向前推进,便可能发生死锁。例如上图进程都处于阻塞状态。
2.计算下面程序一共有多少条进程
如果有一个这样的表达式:cond1 && cond2 || cond3 这句代码会怎样执行呢?
1)cond1为假,那就不判断cond2了,接着判断cond3
2)cond1为真,这又要分为两种情况:
a、cond2为真,这就不需要判断cond3了
b、cond2为假,那还得判断cond3
fork调用的一个奇妙之处在于它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值(题干中说明了不用考虑这种情况)
下面我们来分析fork() && fork() || fork()会创建几个新进程。
很明显fork() && fork() || fork()创建了4个新进程。
3.异步IO和同步IO的区别
IO操作和应用程序可以同时运行,提高系统性能,提高IO流量。
在同步文件IO中,线程启动一个IO操作然后就立即进入等待状态,直到IO操作完成后才醒来继续执行。
而异步文件IO中,线程发送一个IO请求到内核,然后继续处理其他事情,内核完成IO请求后,将会通知线程IO操作完成了。
4.进程、线程、信号量
pthread_t tid;
pthread_create(&tid, NULL, pthread_func, NULL); //创建线程
pthread_join(tid, NULL); //等待子线程结束,并回收资源
pthread_detach(tid); //与当前进程分离
pthread_exit(NULL); //退出调用线程
pthread_cancel(tid); //取消线程
pthread_mutex mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_init(&mutex, NULL); //初始化一个互斥锁
pthread_mutex_lock(&mutex); //对互斥锁上锁
pthread_mutex_unlock(&mutex); //对互斥锁解锁
sem_t sem;
sem_init(&sem, 0, 1); //创建信号量并初始化它的值
sem_wait(&sem); //信号量的值减1
sem_post(&sem); //信号量的值加1
5.整数数组清零的函数
原型:extern void bzero(void *s, int n);
用法:#include <string.h>
功能:置字节字符串s的前n个字节为零且包括‘\0’。
说明:推荐使用memset替代bzero。menset函数在工程中常见。
原型:extern void *memset(void *buffer, int c, int count)
buffer:为指针或是数组。
c:是赋给buffer的值。
count:是buffer的长度。
说明:多用于清空数组。如:原型是memset(buffer, 0, sizeof(buffer));
6.阅读代码,判断值
void main(void)
{
char *str[]={"ab","cd","ef","gh","ij","kl"};
char *t;
t = (str + 4)[-1];
printf("%s", t);
}
显示为"gh"
7.阅读代码,判断值
int foo(void)
{
int i;
char c = 0x80;
i = c;
if(i>0)
return 1;
return 2;
}
返回值为2;因为i=c=-128;如果c=0x7f,则i=c=127。(char的范围是-128~127)
8.用效率最高的算法求各值
a=b*2 -> a=b<<1;
a=b/4 -> a=b>>2;
a=b%8 -> a=b&7;a=b/8*8+b%4 -> a=((b>>3)<<3)+(b&3);
a=b*15 -> a=(b<<4)-b;
9.写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式中 a的值
int a = 4;
(A)a += (a++); (B) a += (++a) ;(C) (a++) += a;(D) (++a) += (a++);
注:a++表示先运算后+1;++a表示先+1后运算
(A)分解成 a = a + (a++)==> a = (a+1) + a = 9
(B)分解成 a = a + (++a)==> a = (a+1) + (a+1) =10
(C)左值操作错误,a先运算,回来后发现a+1(换地方了)
(D)分解成 (a=4+1) = a + (a++)==> a = (a+1) + a =11
10.波特率
简单地说,波特率就是每秒钟传输的位数。
如波特率=115200bps,即1秒传输115200位。
无CRC校验位时,起始位+数据位+停止位=10bit,用时10/115200s。
有CRC校验位时,起始位+数据位+停止位+CRC校验位=11bit,用时11/115200s。
11.编译和链接有什么不同?(如外部符号的处理)
编译生成的是目标文件。
编译过程中对于外部符号不做任何解释和处理。外部符号对应的就是“符号”。
链接生成的是可执行程序。
链接将会解释和处理外部符号。外部符号对应的是地址。
12.ROM和RAM的区别
ROM是只读存储器,掉电不丢失
RAM是读写存储器,掉电会丢失
13.SRAM,DRAM和SDRAM的区别
SRAM:静态随机存储器,最为常见的CPU缓存cache,加电情况下,不需要刷新,数据不会丢失。SRAM速度快,价格昂贵。
DRAM:动态随机存储器,最为常见的系统内存,需要不断刷新,才能保存数据。DRAM容量大,价格低廉。
SDRAM:同步动态随机存储器,即数据的读取需要时钟来同步。
14.norflash和nandflash的区别
flash按照结构可以分为 norflash 和 nandflash 两大类。norflash的特点就是芯片内执行,这样应用程序可以直接在 flash 内存内运行,不必再把代码读到系统 RAM 中。
1)norflash 的容量大小为1MB~32MB ,而nandflash 的为16MB~512MB。norflash内存小,尺寸大;而nandflash内存大,尺寸小,较廉价。
2)norflash读速度快,但写入速度和擦除速度都很慢;nandflash读速度稍慢,但写入速度和擦除速度很快。并且nandflash擦除单元更小,相应的擦除电路也就更小,所以可以达到高存储密度。nandflash一般地址线和数据线共用,对读写速度有一定影响。norflash闪存数据线和地址线分开,所以相对而言读写速度快一些。
3)norflash的接口和RAM一样,而 nandflash 是使用I/O口来串行地存取数据。
4)使用norflash 的相对简单,可以非常直接地使用基于norflash 地内存,可以像其他存储器那样连接,还可以直接在上面运行代码;而使用 nandflash 的话就复杂了,需要I/O接口,必须先写入驱动程序,才可以继续执行其他的操作。
5)在nandflash内存中的每个块的最大擦除写次数是100万次,而norflash 的擦写次数是10万次。所以nandflash比norflash更耐用。
6)norflash常用于保存代码和关键数据。nandflash 用于保存数据