LINUX应用开发工程师职位
本试卷从考试酷examcoo网站导出,文件格式为mht,请用WORD/WPS打开,并另存为doc/docx格式后再使用
说明:应用开发可考察的点非常多,关键的还是C语言和数据结构,此份试卷中包括了一部分的基本C语言,数据结构和SHELL编程没有涉及,请各位下来再精心准备C语言和数据结构,也了解一下shell编程(课件已经共享到考试酷班级空间里面),多看《程序员面试宝典》和一些经典的面试题。此份试卷中的分数表示的作用是“相应知识点的重要程度”,5分题是必须掌握的,其他的相应重要性依次降低。
1.写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。[5分]
参考答案:
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
解析:
这个测试是为下面的目的而设的:
1) 标识#define在宏中应用的基本知识。这是很重要的。因为在 嵌入(inline)操作符 变为标准C的一部分之前,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。
2)三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。
3) 懂得在宏中小心地把参数用括号括起来
2.用预处理指令#define 声明一个常数,用以表明1年中有多少秒[2分]
参考答案:
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
解析:
) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)
2)懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
3) 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
4) 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要
3.以下3个关键词,记得不要完全照搬网上的说法,加上自己的一点自己的理解和整理
static有什么用途?(请至少说明两种)[5分]
参考答案:
在C语言中,关键字static有三个明显的作用:
1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
4.关键字const有什么含意?[5分]
参考答案:
《程序员面试宝典》中是这样说的:
1.定义const常量
2.const可以修饰函数的参数和返回值,在C++中,还可以修饰函数的定义体
被const修饰的东西都受到保护,可以防止意外的改动,能提高程序的健壮性
扩展:
下面声明都是什么意思?
const int a;
int const a;
const int *a;
int * const a;
int const * a const;
/******/
前两个的作用是一样,a是一个常整型数
第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)
第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)
最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)
5.关键字volatile有什么含意?并给出三个不同的例子?[5分]
参考答案:
优化器在用到这个变量时必须每次重新从内存去读写这个变量的值,而不是使用保存在cache中数据。
下面是volatile变量的几个例子:
1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
6.解释下面a的含义:
a) int a; 一个整型数
b) int *a; 一个指向整型数的指针
c) int **a; 一个指向指针的的指针,它指向的指针是指向一个整型数
d) int a[10]; 一个有10个整型数的数组
e) int *a[10]; 一个有10个指针的数组,该指针是指向一个整型数的
f) int (*a)[10]; 一个指向有10个整型数数组的指针
g) int (*a)(int); 一个指向函数的指针,该函数有一个整型参数并返回一个整型数
h)int (*a[10])(int); 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数 [每空1分]
7.已知:
char str[] = "farsight";
char *p = malloc( 100 );
int n = 10;
void Foo ( char var[100]){}
请计算
sizeof (str ) = 9
sizeof ( p ) = 4
sizeof ( n ) = 4
sizeof ( var ) = 4 [每空1分]
8.嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变。[5分]
参考答案:
volatile unsigned int *a;
*a |=(1<<3);
*a &= ~(1<<3);
9.请说说进程和线程的差别?[5分]
参考答案:
进程是系统资源(比如打开的文件描述,信号等)管理的最小单位,线程是最小的执行单位.linux中用户空间的进程,线程对LINUX内核来说,都是任务
线程与进程的区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有独立饿系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。
10.进程间通讯有几种方式,各有特点?[5分]
参考答案:
A:进程间通信IPC包括6种,分别是:管道、消息队列、共享内存、信号量、信号、SOCKET域套接字
管道: 是存在于内存中的特殊文件,不支持lseek操作,是一种半双工通信,有固定的读端和写端,它分为无名管道和有名管道,无名管道可用于具有亲缘关系的进程间通信,有名管道则除无名管道特点外,还可用于无亲缘关系的进程间通信。
信号:一种异步通信方式,不仅可用于用户进程/线程之间,也可用于内核与用户进程/线程之间,信号的处理速度快于其它IPC,其编程方法是通过安装信号处理函数(句柄)进行。
消息队列、共享内存、信号量都是一种IPC对象,是一种资源,都是通过键值获取一个资源号。消息队列使用简单,效率最低;共享内存是将内存中的一段内存隐射到用户空间,使用效率最高,但其对数据的保护需要借助信号量进行;
信号量(semaphore),也叫信号量是用于不同进程或一个给定进程中不同线程同步的手段
SOCKET域套接字:通过网络socket编程接口实现进程间通信。
11.线程的资源保护机制,各有什么特点?[5分]
参考答案:
线程间资源保护机制包括3种:无名信号量、互斥锁、条件变量。
无名信号量常用与对线程间一个或多个资源访问的进行互斥或同步,和它类似的还有进程间的信号量(有名信号量),但用于线程时无名信号量的效率比较高
互斥锁常用于对线程间一个资源访问的进行互斥,防止多个线程同一时刻访问共同的资源
条件变量 以互斥锁为基础,它实现线程间同步的机制
12.LINUX应用开发中如果保证一个程序在系统中只有唯一的一个实例在运行?
提示: 参考进程课程中守护进程代码中的文件锁[3分]
参考答案:
最佳解决方法:采用对特定文件的一部分加上记录锁的方式。
void test_to_locked (){
int fd;
struct flock lock;
char *buf = "abdcefghijklmnopqrstuvwxyz";
//begin to test file lock
fd = open ("/tmp/mylock.lock", O_RDWR | O_CREAT, 0777);
if (fd < 0) {
perror ("Open file error");
exit (1);
}
write (fd, buf, strlen (buf));
fsync (fd);
//file be locked?
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 10;
lock.l_type = F_WRLCK;
lock.l_pid = -1;
if (fcntl (fd, F_GETLK, &lock) < 0) {
perror ("fcntl failed!");
exit (1);
}//
if(lock.l_type == F_WRLCK)
if (lock.l_type != F_UNLCK) {
printf ("have a daemon. so quit!
");
exit (1);
}
//locked file
lock.l_type = F_WRLCK;
if (fcntl (fd, F_SETLKW, &lock) < 0) {
printf ("Lock file failed: type = %d
", lock.l_type);
exit (1);
}
printf ("xxx program have runned
");}
13.(扩展)描述实时系统的基本特性?常见的实时系统有哪些?LINUX是否是实时系统?如何提高LINUX系统和应用的实时性?[4分]
参考答案:
实时系统(Real Time Operating System)的定义:
实时系统是指规定的时限内必须完成规定的操作做出相应响应的系统。系统行为的具有可预测性,意思是实时操作系统面对变化的负载(从最小到最坏的情况)时必须确定性地保证满足时间要求。请注意,它是指必须要满足时间响应的确定性,而不是指速度的快慢!
实时系统根据实时不满足时候带来的后果不同,分为:
硬实时:超过时限完成任务会导致灾难性后果
软实时:超过时限完成对任务会带来系统性能的严重下降
评价一个操作系统实时性好坏的三大性能指标是:抢占延迟、中断延迟、调度延迟
常见的硬实时系统有Vxworks, ucos-II/III, FreeRTOS,Wince(4.0以上版本),threadX等.标准的LINUX不是实时系统。
LINUX系统级的实时性提高主要有2种方式:
增加一层硬实时系统,把标准LINUX内核作为一个最低优先级任务去运行,这种方式有RT-Linux, Xenomai,RTAI,系统层次如下:
另外一种方式是: 通过修改标准的内核,增加实时性,这种方式主要有社区的Ingo Molnar的patch(http://www.kernel.org/pub/linux/kernel/projects/rt/)和 TimeSys的内核修改,层次如下:
不管采用哪种实时LINUX,都需要非常慎重和要经过严格的测试才能部署
应用方面: 如果标准的LINUX,可以通过nice命令或者nice()函数,加大相应任务的时间片提高任务所谓的“实时性”(注,这个并非真正的实时性,而是增加特定时间段里面重要任务运行的时间而非指实时任务就绪后立即去抢非实时任务的CPU的概念),如果使用系统级改进的实时系统,则采用相应的API调用去提高实时任务的实时性:
硬实时编程实例:(以下不用掌握)
软实时编程实例:
更多的参考:https://rt.wiki.kernel.org 和实时性讲座视频http://v.youku.com/v_show/id_XMTAyODU1OTc2.html
14.(扩展)解释一下嵌入式系统中的优先级翻转,什么情况下优先级会出现翻转,以及如何避免优先级翻转?[4分]
参考答案:
优先级翻转 (百度词条 http://baike.baidu.com/view/2422471.htm 解释的非常到位,摘录如下)更详细请查看:参考视频 http://v.youku.com/v_show/id_XMTAyODU1OTc2.html 第27分30秒左右的视频段
所谓优先级翻转问题(priority inversion)即当一个高优先级任务通过信号量机制访问共享资源时,该信号量已被一低优先级任务占有,而这个低优先级任务在访问共享资源时可能又被其它一些中等优先级任务抢先,因此造成高优先级任务被许多具有较低优先级任务阻塞,实时性难以得到保证。
例如:有优先级为A、B和C三个任务,优先级A>B>C,任务A,B处于挂起状态,等待某一事件发生,任务C正在运行,此时任务C开始使用某一共享资源S。在使用中,任务A等待事件到来,任务A转为就绪态,因为它比任务C优先级高,所以立即执行。当任务A要使用共享资源S时,由于其正在被任务C使用,因此任务A被挂起,任务C开始运行。如果此时任务B等待事件到来,则任务B转为就绪态。由于任务B优先级比任务C高,因此任务B开始运行,直到其运行完毕,任务C才开始运行。直到任务C释放共享资源S后,任务A才得以执行。在这种情况下,优先级发生了翻转,任务B先于任务A运行。
解决优先级翻转问题有优先级天花板(priority ceiling)和优先级继承(priority inheritance)两种办法。
优先级天花板是当任务申请某资源时, 把该任务的优先级提升到可访问这个资源的所有任务中的最高优先级, 这个优先级称为该资源的优先级天花板。这种方法简单易行, 不必进行复杂的判断, 不管任务是否阻塞了高优先级任务的运行, 只要任务访问共享资源都会提升任务的优先级。
优先级继承是当任务A 申请共享资源S 时, 如果S正在被任务C 使用,通过比较任务C 与自身的优先级,如发现任务C 的优先级小于自身的优先级, 则将任务C的优先级提升到自身的优先级, 任务C 释放资源S 后,再恢复任务C 的原优先级。这种方法只在占有资源的低优先级任务阻塞了高优先级任务时才动态的改变任务的优先级,如果过程较复杂, 则需要进行判断。
15.TCP/IP的分层和OSI模型的分层?[5分]
参考答案:
扩展:补充知识需要去看和理解一下,关于二层交换机,三层交换机,路由器的知识请参考:
http://network.51cto.com/art/201204/327555_1.htm 和 http://baike.baidu.com/view/116622.htm
16.TCP/IP 建立连接的3次握手过程和关闭链接的4次握手?[5分]
参考答案:
参看绘图的左边部分,关键点:
1. 要标注 客户端(client)和服务器(server)
2.三次握手一定是由客户端发起
3.SYN, ACK/ FIN,ACK一定要标示
17.建立socket的API函数(或者叫步骤)?[5分]
参考答案:
参看绘图部分,
关键点:
1. 要标注 客户端(client)和服务器(server)
2.连接一定是先由客户端发起
3.客户端、服务器之间的连接一定是在connect()和accept()之间进行
4.服务器端accpet()返回的是新的套接字描述符,客户端一定是和新套接字进行通信
5.面试如遇到,最好把函数的API里面参数补全
18.ARP/RARP协议是什么?ICMP是什么协议,他们各处于哪一层?
提示: 最好去查一下各是什么作用[5分]
参考答案:
参考如下手绘中的相关部分:1.ARP/RARP:地址解析/逆向地址解析, arp是IP地址解析为MAC地址 RARP MAC地址解析为IP地址,在TCP/IP协议族里面它处于网络层它们处于网络接口与物理层
2.ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息,在TCP/IP协议族里面它处于网络层
19.广播和多播的区别? [2分]
参考答案:
参考: http://net.chinaunix.net/5/2008/11/13/1311505.shtml 自己再总结一下
20.列举你所知道的尽可能多的TCP/IP中应用层协议
提示: HTTP,FTP,TELNET这些都是[3分]
参考答案:
嵌入式相关协议:
网页: http,
文件传输: ftp
远程登录:telnet ssh
邮件收发:pop3/imap, smtp
NTP: 网络时钟,用于低成本产品,节省
SNMP 简答网络管理协议,经常用于网络设备的集中管理,网上招聘和职位有专门的SNMP工程师
RTP/RTSP:常用于视频监控,网络播放音视频的设备
21.(扩展)RTP/RTSP协议的作用和基本原理?
注: 视频监控中经常需要要到这个协议,最近视频监控企业网上招聘比较多,请准备[5分]
参考答案:
RTP/RTSP协议是实时网络传输协议, 它可以根据网络状态调整画面质量,并可实现暂停、快进、快退等实时交互动作。
整个RTSP协议栈是在TCP/IP协议栈之上建立的,
RTP协议服务媒体数据的传输;
RTCP负责检查网络状况,如网络流量监测、网络阻塞监测;
RTSP提供控制功能,如播放、暂停、前进、后退等功能。
RTP/RTSP协议的分层和工作模式如下:
RTSP协议的没有统一的API,该协议的实现有 FFmpeg、Live555等开源项目
具体介绍参考: http://blog.c114.net/html/40/26740-55502.html
22.(扩展)如何解决网络通信中出现网络异常(或叫超时)的问题?可以采取哪些措施提高网络的性能?[5分]
参考答案:
可以采用2个方式:
内核中:网卡驱动中 2.6内核里面,使能1s的周期性检查定时器 网卡硬件或者我们通过GPIO,插拔网线时候产生中断,处理相应中断 这样就能立即检测到
应用层: 采用心跳检测 客服端服务器创建相应的链路,然后根据业务逻辑每隔一定的时间,相互通信,以验证双方的网络是否处于保活状态
23.(扩展)网络为什么会发生拥塞,发生拥塞的时候网络如何处理?[4分]
参考答案:
参考下图中偏右边的手绘图
真正过程参考:http://blog.csdn.net/machh/article/details/6731780
24.描述内存分配方式以及它们的区别?
提示:从局部变量,静态,全局变量,malloc()所处的内存位置去考虑[4分]
参考答案:
1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。
25.请画出linux程序运行时的内存映射并加以说明
提示: LINUX程序是通过ELF格式进行运行的[4分]
参考答案:
看下面图里面的exec()的过程
26.(扩展)下面是一个16×16的黑白图片:
static unsigned short stopwatch[] = {
0x07c6,
0x1ff7,
0x383b,
0x600c,
0x600c,
0xc006,
0xc006,
0xdf06,
0xc106,
0xc106,
0x610c,
0x610c,
0x3838,
0x1ff0,
0x07c0,
0x0000,
};
如何修改声明,可以使之在源代码中形象地表现出图形的模样?[2分]
参考答案:
上述图标实际上是高度是16点,宽是2个字节,实际上,字符库里面16×16的点阵字符和此类似。 把一个字节里面的所有值用二进制表示为0x0~0xff,再把字节中的每一位1用"x"表示,0用"_"表示,比如:#define ________ 0x0
#define _______X 0x1
#define ______X_ 0x2
#define ______XX 0x3
#define _____X__ 0x4
//...
#define XXXXXXX_ 0xfe
#define XXXXXXXX 0xff
比如ASCII字符"6"就可以表示为:
const unsigned char acFont16B_ASCII_0036[16] = { /* code 0036 */
________,
________,
________,
__XXX___,
_X__XX__,
XX______,
XX______,
XXXXX___,
XX__XX__,
XX__XX__,
XX__XX__,
XX__XX__,
_XXXX___,
________,
________,
________
};
又比如ASCII字符"E"就可以表示为:
const unsigned char acFont16B_ASCII_0045[ 16] = { /* code 0045 */
________,
________,
________,
_XXXXXX_,
_XX_____,
_XX_____,
_XX_____,
_XXXXXX_,
_XX_____,
_XX_____,
_XX_____,
_XX_____,
_XXXXXX_,
________,
________,
________
};
再比如汉字“财”:
const unsigned char acFontF16x16_HKS_8CA1[ 32] = { /* code 8CA1 */
________,___X____,
_XXXXX__,___X____,
_X___X__,___X____,
_XXXXX__,___X____,
_X___X_X,XXXXXXX_,
_X___X__,__XX____,
_XXXXX__,__XX____,
_X___X__,_X_X____,
_X___X__,_X_X____,
_XXXXX__,X__X____,
_______X,___X____,
__X_X_X_,___X____,
__X__X__,___X____,
_X___XX_,___X____,
X____X__,_X_X____,
________,__X_____
};
27.2个快速判断你的LINUX水平的问题:
1.你经常看什么技术类书籍?列举一下你经常去的技术类网站?
2.你写过多少行C语言代码? 你实现过的数据结构算法?
[4分]
参考答案:
列几本比较经典的:
LINUX的应用开发:
《unix高级环境编程》
《TCP/IP详解》
底层驱动参考书:
Jonathan Corbet等 《Linux device drivers》 3rd
Robert Love 《linux kernel development》 3rd
宋宝华 《linux驱动开发详解》 2nd
技术类网站:
www.kernel.org 内核源代码的网站
lwn.net 可免费看一周前所有技术类专题和周刊,强烈推荐
http://free-electrons.com/ 很多的linux,android免费的培训讲义
C语言代码方面,一般C完全掌握的代码量是写过1~2万行,请根据自己的实际情况和结合企业需求回答
数据结构:一般关键包括线性表,栈和队列,串,多维数组,二叉树等
冒泡,二分查找,拆半查找等
============ 本试卷共计27题,此处为结束标志。考试酷examcoo ============