嵌入式工程师对于工作来说最重要的就是面试+笔试了,作为一个面试过很多家的老鸟来说,总结了一些嵌入式工程师经典笔试题,而且也是很厂家的,快看看你都掌握了没
1.给两个变量,如何找出一个带环单链表中是什么地方出现环的?
一个递增一,一个递增二,他们指向同一个接点时就是环出现的地方
1)。.堆栈溢出一般是由什么原因导致的?
没有回收垃圾资源
3).不能做switch()的参数类型是:
switch的参数不能为实型。
4)、队列和栈有什么区别?
队列先进先出,栈后进先出
2.什么是引用,引用与指针有什么区别?
1) 引用必须被初始化,指针不必。
2) 引用初始化以后不能被改变,指针可以改变所指的对象。
3) 不存在指向空值的引用,但是存在指向空值的指针。
3.A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?
static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。
他们都放在数据区,但是编译器对他们的命名是不同的。
如果要使变量在其他模块也有意义的话,需要使用extern关键字。
4.什么是二叉树,平衡二叉树?
左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1
5.internet采用哪种网络协议,该协议的主要层次是什么?
Tcp/IP 主要层次有应用层 传输层 网络层 数据链路层 物理层
ISO的七层模型是什么?
应用层 表示层 会话层 传输层 网络层 物理链路层 物理层
Tcp udp属于运输层
Tcp服务提供了数据流传输,可靠性,有效流控制,全双工操作和多路复用技术
Udp不提供可靠性,流控制以及错误恢复功能 udp头包含少,负载消耗小。
优缺点:
Tcp提供可靠的传输服务,有流量控制。缺点是包头大,冗余性不好。
Udp不提供稳定的服务 但包头小 开销小。
Internet物理地址和ip地址转换采用什么协议?
ARP(地址解析协议)
IP地址的编码分为那两部分?
网络号 和主机号 不过要与子网掩码与之后才能区分哪是网络号那是主机号。
6.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。
循环链表,用取余操作做
7..不能做switch()的参数类型是:
switch的参数不能为实型。
进程和线程的区别是什么?
进程是程序的一次执行
线程是进程内的一个执行单元,也是进程内的可调度实体。
与进程的区别:
调度:线程是可调度和分配的基本单元,进程是拥有资源的基本单位。
并发性:不同进程和同一个进程中的多个线程都可以并发。
拥有资源:进程是拥有资源的独立单位,而线程不拥有资源,但它可以访问属于进程的资源。
系统开销:由于创建进程和撤销进程 系统都要为之分配和回收资源,所以系统的开销明显大于线程创建和撤销时的开销
8.谈谈COM的线程模型。然后讨论进程内/外组件的差别。
1网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别?
1) 进程:子进程是父进程的复制,它获得父进程数据空间,堆 栈的复制品。
2) 线程:相对于进程而言,线程更接近于一个执行体的概念,它可以与同进程的其他线程同享进程资源,但同时拥有自己的栈空间,寄存器,指针(独立的执行序列)。
3) 两者都可以提高程序的并发度,提高程序的运行效率和响应。
4) 线程和进程各有优缺点,线程开销少,但不利于资源管理和保护。而进程恰恰相反,开销大,但对资源有独立掌控权,可更好地管理。
2.列举几种进程的同步机制
1)原子操作
2)信号量机制
3)自旋锁
4)管程,会合,分布式系统
3 进程间的通讯的途径
共享存储系统
消息传递系统
管道:以文件系统为基础
9.进程死锁的原因
资源竞争及进程推进顺序非法
10.死锁的4个必要条件
互斥、请求保持、不可剥夺、环路
11.死锁的处理
鸵鸟策略、预防策略、避免策略、检测与解除死锁
12. 操作系统中进程调度策略有哪几种?
FCFS(先来先服务),优先级,时间片轮转,多级反馈
13.数组和链表的区别
数组:数据顺序存储,固定大小
连表:数据可以随机存储,大小可动态改变
面试题: 线程与进程的区别和联系? 线程是否具有相同的堆栈? dll是否有独立的堆栈?
进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮你创建了一个主线程。
14.每个线程有自己的堆栈。
DLL中有没有独立的堆栈,这个问题不好回答,或者说这个问题本身是否有问题。因为DLL中的代码是被某些线程所执行,只有线程拥有堆栈,如果DLL中的代码是EXE中的线程所调用,那么这个时候是不是说这个DLL没有自己独立的堆栈?如果DLL中的代码是由DLL自己创建的线程所执行,那么是不是说DLL有独立的堆栈?
以上讲的是堆栈,如果对于堆来说,每个DLL有自己的堆,所以如果是从DLL中动态分配的内存,最好是从DLL中删除,如果你从DLL中分配内存,然后在EXE中,或者另外一个DLL中删除,很有可能导致程序崩溃
用宏定义写出swap(x,y)
#define swap(x,y) (x=x+y;y=x-y;x=x-y)
char * const p;
char const * p
const char *p
上述三个有什么区别?
char * const p; //常量指针,p的值不可以修改
char const * p;//指向常量的指针,指向的常量值不可以改
const char *p; //和char const *p
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char *str5 = "abc";
const char *str6 = "abc";
char *str7 = "abc";
char *str8 = "abc";
cout << ( str1 == str2 ) << endl;
cout << ( str3 == str4 ) << endl;
cout << ( str5 == str6 ) << endl;
cout << ( str7 == str8 ) << endl;
结果是:0 0 1 1
解答:str1,str2,str3,str4是数组变量,它们有各自的内存空间;
而str5,str6,str7,str8是指针,它们指向相同的常量区域。
15. 以下代码中的两个sizeof用法有问题吗?[C易]
void UpperCase( char str[] ) // 将 str 中的小写字母转换成大写字母
{
for( size_t i=0; i
if( 'a'<=str[i] && str[i]<='z' )
str[i] -= ('a'-'A' );
}
char str[] = "aBcDe";
cout << "str字符长度为: " << sizeof(str)/sizeof(str[0]) << endl;
UpperCase( str );
cout << str << endl;
答:函数内的sizeof有问题。根据语法,sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。函数外的str是一个静态定义的数组,因此其大小为6,函数内的str实际只是一个指向字符串的指针,没有任何额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为4个字节,因此返回4。
16.main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
输出:2,5
*(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是2,5
&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)
int *ptr=(int *)(&a+1);
则ptr实际是&(a[5]),也就是a+5
原因如下:
&a是数组指针,其类型为 int (*)[5];
而指针加1要根据指针类型加上一定的值,
不同类型的指针+1之后增加的大小不同
a是长度为5的int数组指针,所以要加 5*sizeof(int)
所以ptr实际是a[5]
但是prt与(&a+1)类型是不一样的(这点很重要)
所以prt-1只会减去sizeof(int*)
a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].