linux笔试题参考答案(4)

来源:互联网 发布:日语语法书推荐 知乎 编辑:程序博客网 时间:2024/05/29 03:15

linux笔试题参考答案(4)

(部分题目还没找到答案,改天在贴出)

1. 嵌入式linux和wince操作系统的特点和特性?

2. 嵌入式linux中tty设备驱动的体系结构?

3. 嵌入式设备,为加快启动速度,可以做哪些方面的优化?

4. USB设备的枚举过程?

5. PSRAM、SDRAM、DDR、DDR2的时序特性?

6. I2C触摸屏芯片与CPU的数据传输流程?画出相关图例?(这题目记得不是太清楚了,大概是考查I2C设备驱动的数据传输过程)


12.Linux有内核级线程么。
答:线程通常被定义为一个进程中代码的不同执行路线。从实现方式上划分,线程有两
种类型:“用户级线程”和“内核级线程”。用户线程指不需要内核支持而在用户程序
中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度
和管理线程的函数来控制用户线程。这种线程甚至在象DOS 这样的操作系统中也可实现
,但线程的调度需要用户程序完成,这有些类似Windows3.x 的协作式多任务。另外一
种则需要内核的参与,由内核完成线程的调度。其依赖于操作系统核心,由内核的内部
需求进行创建和撤销,这两种模型各有其好处和缺点。用户线程不需要额外的内核开支
,并且用户态线程的实现方式可以被定制或修改以适应特殊应用的要求,但是当一个线
程因I/O 而处于等待状态时,整个进程就会被调度程序切换为等待状态,其他线程得不
到运行的机会;而内核线程则没有各个限制,有利于发挥多处理器的并发优势,但却占
用了更多的系统开支。
Windows NT和OS/2支持内核线程。Linux 支持内核级的多线程
14.使用线程是如何防止出现大的波峰。
答:意思是如何防止同时产生大量的线程,方法是使用线程池,线程池具有可以同时提
高调度效率和限制资源使用的好处,线程池中的线程达到最大数时,其他线程就会排队
等候

22.TCP/IP建立连接的过程?(3-way shake)
答:在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
  第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状
态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个
SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)
,此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
23.ICMP是什么协议,处于哪一层?
答:Internet控制报文协议,处于网络层
27.IP组播有那些好处?
答:Internet上产生的许多新的应用,特别是高带宽的多媒体应用,带来了带宽的急剧
消耗和网络拥挤问题。组播是一种允许一个或多个发送者(组播源)发送单一的数据包
到多个接收者(一次的,同时的)的网络技术。组播可以大大的节省网络带宽,因为无
论有多少个目标地址,在整个网络的任何一条链路上只传送单一的数据包。所以说组播
技术的核心就是针对如何节约网络资源的前提下保证服务质量。

 

Embedded Software Design Engineer
1 读程序段,回答问题
int main(int argc,char *argv[])
{
int c=9,d=0;
c=c++%5;
d=c;
printf("d=%d\n",d);
return 0;
}
a) 写出程序输出
b) 在一个可移植的系统中这种表达式是否存在风险?why?
#include "stdio.h"
int a=0;
int b;
static char c;
int main(int argc,char *argv[])
{
char d=4;
static short e;
a++;
b=100;
c=(char)++a;
e=(++d)++;
printf("a=%d, b=%d, c=%d, d= %d, e=%d",a,b,c,d,e);
return 0;
}
a) 写出程序输出
b) 编译器如果安排各个变量(a,b,c,d)在内存中的布局(eg. stack,heap,data section,bsssection),最好用图形方式描述。
2 中断是嵌入式系统中重要的组成部分,这导致了许多编译开发商提供一种扩展:让标准C支持中断,产生了一个新的关键字__interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论以下这段代码。
__interrupt double compute_area(double radius)
{
double area = PI * radius *radius;
printf("nArea = %f", area);
return area;
}
3 C/C++基础知识问题
a) 关键字volatile在编译时有什么含义?并给出三个不同使用场景的例子(可以伪代码或者文字描述)。
b) C语言中static关键字的具体作用有哪些?
c) 请问下面三种变量声明有何区别?请给出具体含义
int const *p;
int* const p;
int const* const p;
4 嵌入式系统相关问题
a) 对于整形变量A=0x12345678,请画出在little endian及big endian的方式下在内存中是如何存储的。
b) 在ARM系统中,函数调用的时候,参数是通过哪种方式传递的?
c) 中断(interrupt,如键盘中断)与异常(exception,如除零异常)有何区别?
5 设周期性任务P1,P2,P3的周期为T1,T2,T3分别为100,150,400;执行时间分别为20,40,100。请设计一种调度算法进行任务调度,满足任务执行周期及任务周期。
6 优先级反转问题在嵌入式系统中是一中严重的问题,必须给与足够重视。
a) 首先请解释优先级反转问题
b) 很多RTOS提供优先级继承策略(Priorityinheritance)和优先级天花板策略(Priorityceilings)用来解决优先级反转问题,请讨论这两种策略。
参考答案:
1 5 //我感觉答案应该是4,但标准答案给的是5...
存在风险,因为c=c++%5;这个表达式对c有两次修改,行为未定义,c的值不确定
int a=0; // data section
int b; 
  //data section
static char c; // BSS
int main(int argc,char *argv[])
{
 
  char d=4;        // stack
 
  static short e;   //BSS
 
  a++;
 
  b=100;
 
  c=(char)++a;
 
  e=(++d)++;
 
  printf("a=%d, b=%d, c=%d, d= %d, e=%d",a,b,c,d,e);
 
  return 0;
}
a=2,b=100,c=2,d=6,e=5
2 a)ISR不能返回一个值;
b)ISR不能传递参数;
c)浮点一般都是不可重入的;
d)printf函数有重入和性能上的问题。
3 a) 用volatile关键字定义变量,相当于告诉编译器,这个变量的值会随时发生变化,每次使用时都需要去内存里
重新读取它的值,并不要随意针对它作优化。
建议使用volatile变量的场所:
(1) 并行设备的硬件寄存器
(2) 一个中断服务子程序中会访问到的非自动变量(全局变量)
(3) 多线程应用中被几个任务共享的变量
b) 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
 
   在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数
访问。它是一个本地的全局变量。
 
   在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的
模块的本地范围内使用。
 
   static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
 
   static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
 
   static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
c) 一个指向常整型数的指针
 
   一个指向整型数的常指针
 
   一个指向常整型数的常指针
4
a) 0x12345678
little endian 
      big endian 刚好反过来
高地址--〉0x12 
    低地址--〉0x12
 
           0x34                0x34
 
           0x56                0x56
低地址--〉0x78 
    高地址--〉0x78
b)参数4的通过压栈方式传递
c) 
 异常:在产生时必须考虑与处理器的时钟同步,实践上,异常也称为同步中断。在处理器执行到由于编程失误而导致的错误指令时,或者在执行期间出现特殊情况(如缺页),必须靠内核处理的时候,处理器就会产生一个异常。
所谓中断应该是指外部硬件产生的一个电信号,从cpu的中断引脚进入,打断cpu当前的运行;
所谓异常,是指软件运行中发生了一些必须作出处理的事件,cpu自动产生一个陷入来打断当前运行,转入异常处理流程。
异步与同步的区别`
5
6 高优先级任务需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务的现象叫做优先级反转
优先级继承策略(Priorityinheritance):继承现有被阻塞任务的最高优先级作为其优先级,任务退出临界区,恢
复初始优先级。
优先级天花板策略(Priorityceilings):控制访问临界资源的信号量的优先级天花板。
优先级继承策略对任务执行流程的影响相对教小,因为只有当高优先级任务申请已被低优先级任务占有的临界资源
这一事实发生时,才抬升低优先级任务的优先级。
 读程序段,回答问题
 
    int  main(int  argc,char  *argv[])
 
    {
 
        int  c=9,d=0;
 
        c=c++%5;
 
        d=c;
 
        printf("d=%d\n",d);
 
        return  0;
 
    }
 
    a)  写出程序输出
 
    5
 
    b)  在一个可移植的系统中这种表达式是否存在风险?why?
 
    #include  "stdio.h"
 
    int  a=0;   
 
    int  b;
 
    static  char  c;
 
    int  main(int  argc,char  *argv[])
 
    {
 
        char  d=4;
 
        static  short  e;
 
 
 
        a++;
 
        b=100;
 
        c=(char)++a;
 
        e=(++d)++;
 
        printf("a=%d,  b=%d,  c=%d,  d=  %d,  e=%d",a,b,c,d,e);
 
        return  0;
 
    }
 
    a)  写出程序输出
 
    以前学过c++,这个是可以的      e=(++d)++;
现在才发现在c中,这是不行的
 
    a=2,  b=100,  c=2,  d=  6,  e=5
 
    b)  编译器如果安排各个变量(a,b,c,d)在内存中的布局(eg.  stack,heap,data  section,bss  section),最好用图形方式描述。
 
    data section: a
 
    bss section: b,c,e
 
    stack d
 
 在采用段式内存管理的架构中,数据段(data  segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。   
 
 
在采用段式内存管理的架构中,BSS段(bss 
 segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block  Started  by  Symbol的简称。BSS段属于静态内存分配。
 
 
 嵌入式系统相关问题
 
    a)  对于整形变量A=0x12345678,请画出在little  endian及big  endian的方式下在内存中是如何存储的。
 
    
 
                     low - > high
 
    little endian   0x78 0x56 0x34 0x12
 
    big   endian   0x12 0x34 0x56 0x78
 
    
 
    b)  在ARM系统中,函数调用的时候,参数是通过哪种方式传递的?
 
    在arm汇编中,如果不超过4个参数时,是通过r0  -r3寄存器来传递参数,>4的通过压栈方式传递。  
 
    
 
    c)  中断(interrupt,如键盘中断)与异常(exception,如除零异常)有何区别?
 
    在《Linux内核设计与实现》一书中,说道:
 
      异常  :在产生时必须考虑与处理器的时钟同步,实践上,异常也称为同步中断。在处理器执行到由于编程失误而导致的错误指令时,或者在执行期间出现特殊情况(如缺页),必须靠内核处理的时候,处理器就会产生一个异常。  
 
      
 
      中断可分为同步(synchronous)中断和异步(asynchronous)中断:
1. 同步中断是当指令执行时由 CPU 控制单元产生,之所以称为同步,是因为只有在一条指令执行完毕后 CPU 才会发出中断,而不是发生在代码指令执行期间,比如系统调用。
2. 异步中断是指由其他硬件设备依照 CPU 时钟信号随机产生,即意味着中断能够在指令之间发生,例如键盘中断。
所谓中断应该是指外部硬件产生的一个电信号,从cpu的中断引脚进入,打断cpu当前的运行;
所谓异常,是指软件运行中发生了一些必须作出处理的事件,cpu自动产生一个陷入来打断当前运行,转入异常处理流程。
 
 
 优先级反转问题在嵌入式系统中是一中严重的问题,必须给与足够重视。
 
    a)  首先请解释优先级反转问题
 
    高优先级任务需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务的现象叫做优先级反转
 
   
 
    b)  很多RTOS提供优先级继承策略(Priority  inheritance)和优先级天花板策略(Priority  ceilings)用来解决优先级反转问题,请讨论这两种策略。
 
     优先级继承策略(Priority  inheritance):最低优先级任务继承现有被阻塞任务的最高优先级作为其优先级,任务退出临界区,恢
 
 
复初始优先级。
 
    优先级天花板策略(Priority  ceilings):控制访问临界资源的信号量的优先级天花板。
 
    优先级继承策略对任务执行流程的影响相对教小,因为只有当高优先级任务申请已被低优先级任务占有的临界资源
 
 
这一事实发生时,才抬升低优先级任务的优先级。
via的考题--继续
2007-06-29 11:09
1.via的考题一道
这个程序设计的思想是这样的:
为了测试32位机上的浮点数的运算精度,作如下考虑:
当1.5 == 1时(二进制1.1==1)精度为1个小数位
当1.25 == 1时(二进制1.01==1)精度为2个小数位
继续判断测试,直到两者相等,从而得到精度。
所以程序代码如下:
int main()
{ int nCount;
 
 float number1,number2;
 
 nCount = 0;
 
 number1 = 1.0;
 
 number2 = 1.0
 
 while( number1 + number2 != number1 ){
 
        nCount++;
 
        number2 /= 2.0;
 
  }
 
  printf( "%d bits accruacy.\n", nCount );
}
问题是,结果为多少?
经测试得64或者53或者24(稍加改动)。。。
得53和24已基本得出答案,主要是ieee 754标准中规定单双精度数字的底数指数 符号位所置。。。64的目前还没有得出结论。。。
2.改错题
void mymul(double *p)
{
 
       *p *= 2.0;
}
int main(int argc, char *argv[])
{
 
       float f   =6.0;
 
       mymul((double *) &f);
 
       printf("now f = %f\n", f);
 
       return0;
}
直接运行,结果为6.00000
这个题目很简单,可以有很多种改法,如:a.把float f=6.0;改为double f=6.0;睛面的mymul句不要强制类型转化b.把所有的数都当成float型来处理等等
但往细的方面想,float型默认4字节,double型默认8字节,虽然在vc6下能勉强运行(运行时报出调试窗口),但单步跟踪发现在mymul()中并没有得到正确执行,而是:Access Violation,这个错误常常在计算机用户运行的程序试图存取未被指定使用的存储区时遇到中,可见mymyl()这个函数并没有得到正确的执行。。。同样,用gcc来直接编译上述程序,虽然没有报错,但结果仍然为6.00000,可能gcc也是在执行mymul()时没有正确执行(不过我没拿gdb来跟踪看)
以下内容是补充,主要是一些基础的知识
1.解释命令ls -a | more具体含义. ls -a 是将当前目录下的文件名输出到终端,而加入后面的| more 是将输出结果分页显示 2.LINUX中的管道指什么重定向又指什么管道命令操作符是:”|”,它仅能处理经由前面一个指令传出的正确输出信息,也就是standard output 的信息,对于 stdandard error 信息没有直接处理能力。然后,传递给下一个命令,作为标准的输入 Linux重定向是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作。区别是: 1)、左边的命令应该有标准输出| 右边的命令应该接受标准输入 左边的命令应该有标准输出 > 右边只能是文件 左边的命令应该需要标准输入 < 右边只能是文件 2)、管道触发两个子进程执行"|"两边的程序;而重定向是在一个进程内执行3.GCC-g -o test.elf test.c的具体含义将test.c 文件编译输出为test.elf 带上调试信息,可以用GDB调试用4.浅述GCC编译器在编译时都有哪几个过程要经历四个相互关联的步骤:预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。预处理(Preprocessing):命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。编译(Compilation):接着调用cc进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。汇编(Assembly):汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.s为后缀的汇编语言源代码文件和汇编.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。连接(Linking):当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当位置,同时,该程序所调用到的库函数也从各自所在的档案库中连到合适的地方。 6.说明uclinux 和linux的区别uclinux不具有的功能:

1). 没有虚存管理

2). 不能运行时增加进程栈

3). 不支持分页

 4). 可执行程序不是elf, 而是flat

5). 不能用fork, 而是用vfork

6). RAMDISK

7解释下面一组GDB命令的含义.

 break 94设置断定,让程序在执行到第94行之前停止run 运行准备调试的程序 info line 121 查看第121行设置的断点的信息8.什么是链接脚本其作用是什么请编写一个简单的链接脚本链接脚本主要用于规定如何把输入文件内的section放入输出文件内, 并控制输出文件内各部分在程序地址空间内的布局. 实例:以下脚本将输出文件的text section定位在0×10000, datasection定位在0×8000000: SECTIONS { . = 0×10000;.text : { *(.text) } . = 0×8000000; .data : { *(.data) } .bss : {*(.bss) } } 解释一下上述的例子: . = 0×10000 : 把定位器符号置为0×10000 (若不指定, 则该符号的初始值为0). .text : { *(.text) } : 将所有(*符号代表任意输入文件)输入文件的.text section合并成一个.text section, 该section的地址由定位器符号的值指定, 即0×10000. . = 0×8000000 :把定位器符号置为0×8000000 .data : { *(.data) } :将所有输入文件的.data section合并成一个.data section, 该section的地址被置为0×8000000. .bss : { *(.bss) }: 将所有输入文件的.bss section合并成一个.bss section,该section的地址被置为0×8000000+.datasection的大小. 连接器每读完一个section描述后, 将定位器符号的值*增加*该section的大小. 注意: 此处没有考虑对齐约束. 9.编写一个SHELL脚本程序,将当前目录及其子目录中所有后缀为.O类型文件的文件名输出到用户指定的文件中. ls -a | *.o>result.txt 10.请写出5个LINUX基本系统调用的函数名称. 包括与设备文件的交互和与普通文件的交互的系统调用(open, close, ioctl, create, unlink, . .. );与进程相关的系统调用又包括进程控制系统调用(fork, exit, getpid, . . .), 11.描述LINUX中字符设备驱动的基本编写框架. 根据struct file_operations 的数据结构,填充里面的如:open,write,close,ioctl等函数并进行模块的初始化和退出

12.编写一个hello world程序,要求以创建进程的方式打印hello world.编写hello.c文件如下

 #include ""stdio.h "

 int main()

{  fork(); 

printf("hello world!/n"); 

exit(0); 

}

编译hello.c生成hello可执行文件在shell中执行#fork hello 便可以看到打印结果

13.浅谈bootloader,kelnel,filesystem三者之间的关系.嵌入式是linux启动过程如下。bootloader->kernel->filesystem->application先是bootloader,它是linux-kernel移植的基石,Bootloader是在系统启动之后、Kernel运行之前所执行的第一段代码,其任务是为调用Kernel准备必要的软硬件环境。完成bootlaoder的移植后,就是kernel的移植。主要包括添加特定模块的驱动,针对具体要求对内核进行配置。这里有两点要注意:一是有些参数要与所用的bootloader向对应,如nand的分区参数。二是bootlaoder对特定模块的驱动在进入kernel后便会有kernel接管,并有kernel重新驱动文件系统主要是建立根文件和一些系统功能的实现,如bash。用busybox很容易搞定。

3.Linux系统下.ko文件是什么文件?.so文件是什么文件?Linux下面文件名不代表什么。但是从常识上讲,.ko代码是驱动编译成的格式,.so文件一般是动态库文件4.二维数组AA [ 3 ][ 7 ]的另外一种表示方法:我想可以用指针来表示,如果数组元素为int型,则可以用int (*p)[7]来表示,p++后移动向下一行。5.请写出下列代码的输出内容 #include “stdio.h”   

main()   

{    

int a,b,c,d;    

a=10;    

b=a++;    

c=++a;    

d=10*a++;    

printf("b,c,d:%d,%d,%d",b,c,d);    

return 0;   

}

输出结果为:b, c, d: 10, 12, 120


原创粉丝点击