第一篇:2012最新的嵌入式软件工程师面试题笔试并且含答案
2012最新的嵌入式软件工程师面试题笔试并且含答案
随着科技信息的进步,在某个领域的突破发展也是大势所趋,就像各个企业对嵌入式软件工程师 的要求也是随着需求的变化不段变化,所以2012最新的嵌入式软件工程师的面试题还是有必要了 解熟悉下的。
1.算术运算符,赋值运算符和关系运算符的运算优先级按从高到低依次为
A.算术运算、赋值运算、关系运算
B.算术运算、关系运算、赋值运算
C.关系运算、赋值运算、算术运算
D.关系运算、算术运算、赋值运算
参考答案:B
2.设#define N 3
#define Y(n)((N+1)*n)
则表达式2*(N+Y(5+1))的值是
A.42
B.48
C.54
D.出错
深圳达内福田培训中心提供的参考答案:B
3.打印一个N*N的方阵,N为每边字符的个数(3〈N〈20),要求最外层为“X”,第二层为“Y ”,从第三层起每层依次打印数字0,1,2,3,...例子:当N =5,打印出下面的图形:
X X X X X
X Y Y Y X
X Y 0 Y X
X Y Y Y X
X X X X X
4.多态类中的虚函数表是Compile-Time,还是Run-Time时建立的?
参考答案:
虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组.而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是 实现多态的关键.5.执行下述程序的输出结果是ABCDEFCDEFEF。
#include
char b[]=“ABCDEF”;
main()
{
char *bp;
for(bp=b;*bp;bp+=2)
printf(“%s”,bp);
printf(“n”);
}
6.函数 int compare(int a,int b),定义为该函数的函数指针P:为
int(*p)(int,int);p= compare;
#include
void sub(char*s,int num)
{
int i ,j=num;
char t;
while(j-->1)
{
for(i=0;i { if(s[i] { t=s[i]; s[i]=s[i+1]; s[i+1]=t; } } } } main() { char *s=“CEAeded”; sub(s,6); printf(“%sn”,s) } 7.用变量a给出下面的定义 a)一个整型数(An integer) b)一个指向整型数的指针(A pointer to an integer) c)一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer) d)一个有10个整型数的数组(An array of 10 integers) e)一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers) f)一个指向有10个整型数数组的指针(A pointer to an array of 10 integers) g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer) h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数(An array of ten pointers to functions that take an integer argument and return an integer) 深圳达内福田培训中心提供的答案是: a)int a;// An integer b)int *a;// A pointer to an integer c)int **a;// A pointer to a pointer to an integer d)int a[10];// An array of 10 integers e)int *a[10];// An array of 10 pointers to integers f)int(*a)[10];// A pointer to an array of 10 integers g)int(*a)(int);// A pointer to a function a that takes an integer argument and returns an integer 以上是2012年嵌入式软件工程师面试题,答案也都是深圳福田达内培训中心提供的参考答案,如果想了解更多关于这类的信息或是对这有什么疑问可以打电话咨询0755-82353533。 嵌入式软件工程师面试题 预处理器(Preprocessor) 1.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR(60 * 60 * 24 * 365)UL 我在这想看到几件事情: 1).#define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 2).懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。 3).意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。 4).如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。 2.写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。 #define MIN(A,B)((A)<=(B)(A):)) CC++试题集 CC++ Development这个测试是为下面的目的而设的: 1).标识#define在宏中应用的基本知识。这是很重要的,因为直到嵌入(inline)操作符变为标准C的一部分,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。 2).三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。 3).懂得在宏中小心地把参数用括号括起来 4).我也用这个问题开始讨论宏的副作用,例如:当你写下面的代码时会发生什么事? Least = MIN(*p++, b); 3.预处理器标识#error的目的是什么? 如果你不知道答案,请看参考文献1。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种 问题的答案。当然如果你不是在找一个书呆子,那么应试者最好希望自己不要知道答案。 死循环(Infinite loops) 4.嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢? 这个问题用几个解决方案。我首选的方案是: while(1){ } 一些程序员更喜欢如下方案: for(;;){ } 这个实现方式让我为难,因为这个语法没有确切表达到底怎么回事。如果一个应试者给出这个作为方案,我将用这个作为一个机会去探究他们这样做的基本原理。如果他们的基本答案是:“我被教着这样做,但从没有想到过为什么。”这会给我留下一个坏印象。 第三个方案是用 goto Loop: … goto Loop; 应试者如给出上面的方案,这说明或者他是一个汇编语言程序员(这也许是好事)或者他是一个想进入新领域的BASIC/FORTRAN程序员。 数据声明(Data declarations) 5.用变量a给出下面的定义 a)一个整型数(An integer)int a; b)一个指向整型数的指针(A pointer to an integer)b)int *a; c)一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer)c)int **a; d)一个有10个整型数的数组(An array of 10 integers)d)int a[10]; e)一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers) e)int *a[10];// An array of 10 pointers to integers f)一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)f)int(*a)[10]; g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)g)int(*a)(int); h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数(An array of ten pointers to functions that take an integer argument and return an integer) int(*a[10])(int); 人们经常声称这里有几个问题是那种要翻一下书才能回答的问题,我同意这种说法。当我写这篇文章时,为了确定语法的正确性,我的确查了一下书。 但是当我被面试的时候,我期望被问到这个问题(或者相近的问题)。因为在被面试的这段时间里,我确定我知道这个问题的答案。应试者如果不知道 所有的答案(或至少大部分答案),那么也就没有为这次面试做准备,如果该面试者没有为这次面试做准备,那么他又能为什么出准备呢? Static 6.关键字static的作用是什么? 这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用: 1).在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 2).在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。 3).在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。 大多数应试者能正确回答第一部分,一部分能正确回答第二部分,同是很少的人能懂得第三部分。这是一个应试者的严重的缺点,因为他显然不懂得本地化数据和代码范围的好处和重要性。 Const 7.关键字const是什么含意? 我只要一听到被面试者说:“const意味着常数”,我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法,因此ESP(译者:Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章,只要能说出const意味着“只读”就可以了。尽管这个答案不是完全的答案,但我接受它作为一个正确的答案。(如果你想知道更详细的答案,仔细读一下Saks的文章吧。)如果应试者能正确回答这个问题,我将问他一个附加的问题:下面的声明都是什么意思? Const int a; int const a; const int *a; int * const a; int const * a const; 前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意识a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。如果应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即使不用关键字const,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?我也如下的几下理由: 1).关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了 告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。) 2).通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。 3).合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。 Volatile 8.关键字volatile有什么含意 并给出三个不同的例子。 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子: 1).并行设备的硬件寄存器(如:状态寄存器) 2).一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3).多线程应用中被几个任务共享的变量 回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。 1).一个参数既可以是const还可以是volatile吗?解释为什么。 2).一个指针可以是volatile 吗?解释为什么。 3).下面的函数有什么错误: int square(volatile int *ptr) { return *ptr * *ptr; } 下面是答案: 1).是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。 2).是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。 3).这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码: int square(volatile int *ptr) { int a,b; a = *ptr; b = *ptr; return a * b; } 由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下: long square(volatile int *ptr) { int a; a = *ptr; return a * a; } 位操作(Bit manipulation) 9.嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a,写两段代码,第一个设臵a的bit 3,第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变。 对这个问题有三种基本的反应 1).不知道如何下手。该被面者从没做过任何嵌入式系统的工作。 2).用bit fields。Bit fields是被扔到C语言死角的东西,它保证你的代码在不同编译器之间是不可移植的,同时也保证了的你的代码是不可重用的。我最近不幸看到Infineon为其较复杂的通信芯片写的驱动程序,它用到了bit fields因此完全对我无用,因为我的编译器用其它的方式来实现bit fields的。从道德讲:永远不要让一个非嵌入式的家伙粘实际硬件的边。 3).用 #defines 和 bit masks 操作。这是一个有极高可移植性的方法,是应该被用到的方法。最佳的解决方案如下:#define BIT3(0x1<<3) static int a; void set_bit3(void) { a |= BIT3; } void clear_bit3(void) { a &= ~BIT3; } 一些人喜欢为设臵和清除值而定义一个掩码同时定义一些说明常数,这也是可以接受的。我希望看到几个要点:说明常数、|=和&=~操作。访问固定的内存位臵(Accessing fixed memory locations)CC++ Development 10.嵌入式系统经常具有要求程序员去访问某特定的内存位臵的特点。在某工程中,要求设臵一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast)为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下: int *ptr; ptr =(int *)0x67a9; *ptr = 0xaa55; 一个较晦涩的方法是: *(int * const)(0x67a9)= 0xaa55; 即使你的品味更接近第二种方案,但我建议你在面试时使用第一种方案。 中断(Interrupts) 11.中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是,产生了一个新的关键字__interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。 __interrupt double compute_area(double radius) { double area = PI * radius * radius; printf(“ Area = %f”, area); return area; } 这个函数有太多的错误了,以至让人不知从何说起了: 1).ISR 不能返回一个值。如果你不懂这个,那么你不会被雇用的。 2).ISR 不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。 3).在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。 4).与第三点一脉相承,printf()经常有重入和性能上的问题。如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点,那么你的被雇用前景越来越光明了。 代码例子(Code examples).下面的代码输出是什么,为什么? Void foo(void){ unsigned int a = 6;int b =-20; (a+b > 6)puts(“> 6”): puts(“<= 6”); } 这个问题测试你是否懂得C语言中的整数自动转换原则,我发现有些开发者懂得极少这些东西。不管如何,这无符号整型问题的答案是输出是“>6”。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题,你也就到了得不到这份工作的边缘。 13.评价下面的代码片断: unsigned int zero = 0; unsigned int compzero = 0xFFFF; /*1's complement of zero */ 对于一个int型不是16位的处理器为说,上面的代码是不正确的。应编写如下: unsigned int compzero = ~0; 这一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的经验里,好的嵌入式程序员非常准确地明白硬件的细节和它的局限,然而PC机程序往往把硬件作为一个无法避免的烦恼。 到了这个阶段,应试者或者完全垂头丧气了或者信心满满志在必得。如果显然应试者不是很好,那么这个测试就在这里结束了。但如果显然应试者做得不错,那么我就扔出下面的追加问题,这些问题是比较难的,我想仅仅非常优秀的应试者能做得不错。提出这些问题,我希望更多看到应试者应付问题的方法,而不是答案。不管如何,你就当是这个娱乐吧… 动态内存分配(Dynamic memory allocation) 14.尽管不像非嵌入式计算机那么常见,嵌入式系统还是有从堆(heap)中动态分配内存的过程的。那么嵌入式系统中,动态分配内存可能发生的问题是什么? 这里,我期望应试者能提到内存碎片,碎片收集的问题,变量的持行时间等等。这个主题已经在ESP杂志中被广泛地讨论过了(主要是 P.J.Plauger, 他的解释远远超过我这里能提到的任何解释),所有回过头看一下这些杂志吧!让应试者进入一种虚假的安全感觉后,我拿出这么一个小节目:下面的代码片段的输出是什么,为什么? Char *ptr; if((ptr =(char *)malloc(0))== NULL) puts(“Got a null pointer”); else puts(“Got a valid pointer”); 这是一个有趣的问题。最近在我的一个同事不经意把0值传给了函数malloc,得到了一个合法的指针之后,我才想到这个问题。这就是上面的代码,该代码的输出是“Got a valid pointer”。我用这个来开始讨论这样的一问题,看看被面试者是否想到库例程这样做是正确。得到正确的答案固然重要,但解决问题的方法和你做决定的基本原理更重要些。 Typedef 15.Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如,思考一下下面的例子: #define dPS struct s * typedef struct s * tPS; 以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么?这是一个非常微妙的问题,任何人答对这个问题(正当的原因)是应当被恭喜的。答案是:typedef更好。思考下面的例子: dPS p1,p2; tPS p3,p4; 第一个扩展为 struct s * p1, p2; 上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。 晦涩的语法 16.C语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么? Int a = 5, b = 7, c; c = a+++b; 这个问题将做为这个测验的一个愉快的结尾。不管你相不相信,上面的例子是完全合乎语法的。问题是编译器如何处理它?水平不高的编译作者实际上会争论这个问题,根据最处理原则,编译器应当能处理尽可能所有合法的用法。因此,上面的代码被处理成: c = a++ + b; 因此, 这段代码持行后a = 6, b = 7, c = 12。 如果你知道答案,或猜出正确答案,做得好。如果你不知道答案,我也不把这个当作问题。我发现这个问题的最大好处是:这是一个关于代码编写风格,代码的可读性,代码的可修改性的好的话题 嵌入式软件工程师 目录 简介 2 待遇 3 职业要求 4 发展前景 5 职业发展 简介 2 待遇 3 职业要求 4 发展前景 职业发展 简介 嵌入式系统是以应用为中心,以计算机技术为基础,并且软硬件可裁剪,适用于应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。它一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统以及用户的应用程序等四个部分组成,用于实现对其他设备的控制、监视或管理等功能。 嵌入式软件工程师就是编写嵌入式系统的工程师。2 待遇 IBM、微软、华为、Yahoo、联想、搜狐、亚信、花旗...2010'应届毕业生就业安置计划火热启动:先实训后上岗,转正年薪50000元。3 职业要求 应具备哪些能力 最直接的方法,就是去根据各公司,招聘网站的嵌入式软件工程师的应聘要求来分析 我帮你总结下: 1.最重要的是C语言编程,以及C++,这个与你读程,应用,开发项目,做系统移植息息相关; 2.操作系统: LINUX,WINCE等,至少学习过一种,(目前主流的还是Linux)并且还需要对些基础知识有蛮多的了解; 3.对ARM,FPGA,DSP等这些硬件比较了解。(目前主流的是ARM,像三星,华为,小米等大型的生产厂商最底层的硬件用的都是ARM) 这是最常规的条件 当然,最主流的一般就是LIUNX.同时具备一些基本素质,像英语能力,有相关的项目经验,也很重要 推荐: 你可以去按照招聘要求分析,也可以按照培训机构的培训目的,方向,内容来分析得知,像海同科技就是蛮不错的.算得上是业内的领军企业.4 发展前景 嵌入式领域较新,发展非常快,很多软硬件技术出现的时间都不太长(如ARM处理器、嵌入式操作系统、LINUX操作系统),大多数人没有条件接触或进入嵌入式行业,更谈不上能有机会接受专业人士的指导。因此,踏进这个行业的难度比较大,嵌入式人才稀缺,身价自然也水涨船高。 权威部门统计,我国嵌入式人才缺口每年50万人左右。根据前程无忧网发布的调查报告,嵌入式软件开发是未来几年最热门和最受欢迎的职业之一,具有10年工作经验的高级嵌入式工程师年薪在30万元左右。即使是初级的嵌入式软件开发人员,平均月薪也达到了3000—5000元,中高级的嵌入式工程师月薪平均超过10000元。做软件实际上有高下之分,开发语言从机器语言、汇编到C、C++,再到红透半边天的Java、C#等,该学哪种呢?为什么有些开发者工资低,而有些开发者千金难求?为什么3年的Java高级程序员薪水仅仅8k-10k,而一个Linux底层C语言程序员两年经验就敢要10k的薪水? 还是门槛,比如月薪15k的Linux嵌入式开发职位,门槛就有 Linux系统、Shell编程、Linux开发环境、C语言、ARM硬件平台、数据结构、Linux内核、驱动程序等,粗略数数就有8道关口,他需要非常熟悉整个的计算机体系,能做出实际的产品,而Java的开发者却仅仅是会使用名叫Java的语言工具,始终高高飘在众多层次之上,开发项目非常快,甚至可以不知道OSI模型,很可能自始至终都是软件蓝领。 嵌入式开发本身也有高下之分,至少包含嵌入式应用程序工程师和底层的驱动内核工程师两种。前者同样是使用现成工具进行简单劳动,比如使用J2ME开发小游戏或者进行一些界面开发,而后者是根据芯片具体情况把操作系统(如Linux)移植到上面,同时编写必要的驱动程序,改写相应的内核代码。很显然后者是一个公司真正的技术核心。而技术核心的工资很可能是其他开发者的数倍。 嵌入式开发突出强制和项目,学习不仅仅是学习几项技术,而是构建你的知识体系。比如学习嵌入式开发,就要从基础Linux,C语言,数据结构开始,到ARM,汇编,Linux内核、驱动等,更重要的是更多的项目练习,设计至少5个项目,多达10000行强制核心代码的编写可以让你真正获得知识。为进入外企或者出国做准备。 未来的几年内,随着信息化,智能化,网络化的发展,嵌入式系统技术也将获得广阔的发展空间。美国著名未来学家尼葛洛庞帝99年1月访华时预言,4~5年后嵌入式智能(电脑)工具将是PC和因特网之后最伟大的发明。我国著名嵌入式系统专家沈绪榜院士98年11月在武汉全国第11次微机学术交流会上发表的《计算机的发展与技术》一文中,对未来10年以嵌入式芯片为基础的计算机工业进行了科学的阐述和展望。1999年世界电子产品产值已超过12000亿美元,2000年达到13000亿美元,预计2005年,销售额将达18000亿美元。一些先进的PDA在显示屏幕上已实现汉字写入、短消息语音发布,日用范围也将日益广阔。对于企业专用解决方案,如物流管理、条码扫描、移动信息采集等,这种小型手持嵌入式系统将发挥巨大的作用。自动控制领域,不仅可以用于ATM机,自动售货机,工业控制等专用设备,和移动通讯设备结合、GPS、娱乐相结合,嵌入式系统同样可以发挥巨大的作用。5 职业发展 从个人整体发展来说,如果想创业,做自已的产品,嵌入式软件开发可以开发出专利产品。 另一个发展路径是:积累丰富开发经验的嵌入式软件开发工程师可以向嵌入式系统开发工程师发展,从而晋升为产品研发经理或IT项目经理。对测试理论和方法有一定了解的嵌入式软件开发工程师还可以转作嵌入式系统测试工程师,最终也可发展为IT项目经理 1.web中的forward和redirect的区别? 前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量使用forward()方法,并且,这样也有助于隐藏实际的链接。在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用sendRedirect()方法。 2.xml在解释的时候DOM和SAX协议的区别和含义? DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问 SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问 3说明JNDI、JMS、JTA、RMI的意思? JNDI(Java Naming and Directory Interface)是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似JDBC都是构建在抽象层上。 JMS(Java Messaging Service)是Java平台上有关面向消息中间件的技术规范,翻译为Java消息服务。JMS支持点对点和发布/订阅两种消息模型。 JTA(Java Transaction API)为 J2EE平台提供了分布式事务服务。要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法.RMI是Java的一组拥护开发分布式应用程序的API。RMI使用Java语言接口定义了远程对象,它集合了Java序列化和Java远程方法协议(Java Remote Method Protocol)。它大大增强了Java开发分布式应用的能力 4.单例模式 Public class Signle{ Private Signle(){ } Pirvate static Signle signle = new Signle();Public static Signle gets(){ Retrun signle;} } 5数据库中left join的意思,和在什么场合中应用? LEFT JOIN操作用于在任何的 FROM 子句中,组合来源表的记录。使用 LEFT JOIN 运算来创建一个左边外部联接。左边外部联接将包含了从第一个(左边)开始的两个表中的全部记录,即使在第二个(右边)表中并没有相符值的记录。ejb中的sessionbean和entitybean的区别和含义? SessionBean在J2EE应用程序中被用来完成一些服务器端的业务操作,例如访问数据库、调用其他EJB组件。EntityBean被用来代表应用系统中用到的数据。 对于客户机,SessionBean是一种非持久性对象,它实现某些在服务器上运行的业务逻辑。 对于客户机,EntityBean是一种持久性对象,它代表一个存储在持久性存储器中的实体的对象视图,或是一个由现有企业应用程序实现的实体。 7抽象类和接口的区别 1:一个类可以实现任意多的接口,但是最多只能对一个抽象类进行子类化。 2:一个抽象类可以包括非抽象方法,而一个接口的所有方法在效果上都是抽象的。3:一个抽象类可以申明并使用变量,而一个接口不行。 4:一个抽象类中的方法的访问修饰符可以使public,internal,protected,protected internal,private,而接口成员的访问修饰符在默认情况下都是public,而且,在申明接口成员时,不允许使用访问修饰符(甚至不能使用public)。5:一个抽象类可以定义构造函数,而一个接口不行。 8对象序列化的含义 Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从其它地方 把该Byte 流里的数据读出来。重新构造一个相同的对象。这种机制允许你将对象通过网络 进行传播,并可以随时把对象持久化到数据库、文件等系统里。Java的序列化机制是RMI、EJB、JNNI等技术的技术基础。 9数据库中的锁包括什么? 基本的封锁类型有两种:排它锁(X锁)和共享锁(S锁).所谓X锁,是事务T对数据A加上X锁时,只允许事务T读取和修改数据A,… 所谓S锁,是事务T对数据A加上S锁时,其他事务只能再对数据A加S锁,而不能加X锁,直到T释放A上的S锁若事务T对数据对象A加了S锁,则T就可以对A进行读取,但不能进行更新(S锁因此又称为读锁),在T释放A上的S锁以前,其他事务可以再对A加S锁,但不能加X锁,从而可以读取A,但不能更新A.jsp和serverlet的区别 (1).简单的来说Jsp就是含有Java代码的html,而servlet是含有html的Java代码;(2).Jsp最终也是被解释为servlet并编译再执行,Jsp不过是servlet的另一种编写方式;(3).Jsp擅长表示,servlet擅长数据处理,在MVC三层结构中,Jsp负责V(视图),servlet负责C(控制),各有优势,各司其职; 11.oracle中数据表的交集怎么表示 第一种方法:利用操作符intersect 第二种方法: in子句 jsp页面中如何传递参数(1)直接在URL请求后添加(2)jsp:param 3)设置session和request jsp中的doget()和dopost()方法的作用? 这个两个方法都是http协议的方法,doget用于传输数据量较小(密码会泄露),dopost数据量较大,14什么是用例?如何确定用例? 在不展现一个系统或子系统内部结构的情况下,对系统或子系统的某个连贯的功能单元的定义和描述。 一个用例可以看作是系统的一个功能,例如增加用户,增加角色,查询一个具体的一个事物,在Ejb的设计中,一个use case跟Session bean的一个方法是对应的(使用的session fasade模式),你说的基础数据管理,我会把它处理成为一个抽象用例,因为我认为基础数据这个概念非常的抽象,什么是真正的基础数据?例如说一个系统中邮政编码算是这个系统的基础数据,那么”邮政编码修改”这个就应该算是用例了.15活动图和时序图的区别? 时序图主要强调时间的顺序 活动图主要强调空间上类的交互 16什么是策略模式?什么情况下使用? 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换 Context(应用场景): 1、需要使用ConcreteStrategy提供的算法。 2、内部维护一个Strategy的实例。 3、负责动态设置运行时Strategy具体的实现算法。 4、负责跟Strategy之间的交互和数据传递。 17面向接口编程的好处 使用接口编程,易于程序扩展,降低程序耦合性。 包括结构清晰,类之间通信简单易懂,扩展性好,提高复用性等等。 18事物 事务就是一系列的操作,这些操作完成一项任务.只要这些操作里有一个操作没有成功,事务就操作失败,发生回滚事件.即撤消前面的操作,这样可以保证数据的一致性.而且可以把操作暂时放在缓存里,等所有操作都成功有提交数据库,这样保证费时的操作都是有效操作. 嵌入式软件工程师笔试题(含答案).txt26选择自信,就是选择豁达坦然,就是选择在名利面前岿然不动,就是选择在势力面前昂首挺胸,撑开自信的帆破流向前,展示搏击的风采。选择题 1:设float a=2, b=4, c=3;,以下C语言表达式与代数式(a+b)+c计算结果不一致的是 A.(a+b)*c/2 B.(1/2)*(a+b)*c C.(a+b)*c*1/2 D.c/2*(a+b) 参考答案:B,因为a,b,c三个变量都是浮点数,所以在B答案中其结果是0,因为在计算1/2是就是0,如果改成1/2.0就正确了。 2:为了向二进制文件尾部增加数据,打开文件的方式应采用 A.″ab″ B.″rb+″ C.″wb″ D.″wb+″ 参考答案:D 3:下述程序执行后的输出结果是 #include main() { int x='f'; printf(“%cn”,'a'+(x-'a'+1)); } A.g B.h C.i D.j 参考答案:A 4:C语言中,下列运算符优先级最高的是 A.! B.% C.>> D.= = 参考答案:A 5:数组定义为“ int a [ 4 ];”,表达式()是错误的。 A.*a B.a [ 0 ] C.a D.a++ 参考答案:D 6:执行语句“ k=7>>1;”后,变量 k 的当前值是 A.15 B.31 C.3 D.1 参考答案:C 7:定义函数时,缺省函数的类型声明,则函数类型取缺省类型 A.void B.char C.float D.int 参考答案:D 8:若main()函数带参数,参数个数最多是 A.0 B.1 C.2 D.3 参考答案:C 只知道有定义形式main(int argc,char* argv[])) 9:若有宏定义:#define MOD(x,y)x%y 则执行以下语句后的输出结果是 int a=13,b=94; printf(″%dn″,MOD(b,a+4)); A.5 B.7 C.9 D.11 参考答案:B 10:下列各个错误中,哪一个不属于编译错误 A.改变 x 原值 3 为 5,写作“ x==5;” B.花括号不配对 C.复合语句中的最后一条语句后未加分号 D.变量有引用、无定义 参考答案:A 11:下列程序段运行后,x 的值是() a=1;b=2;x=0; if(!(--a))x--; if(!b)x=7;else ++x; A.0 B.3 C.6 D.7 参考答案:A 12:设 #define N 3 #define Y(n)((N+1)*n) 则表达式2*(N+Y(5+1))的值是 A.42 B.48 C.54 D.出错 参考答案:B Y(5+1)传递过去的应该是6,而不是简单的把5+1给替换掉 13:若定义了char ch[]={″abc def″},*p=ch;则执行printf(″%c″,*p+4);语句的输出结果是 A.def B.d C.e D.0 参考答案:C 14:下列转义字符中错误的是 A.′ 00′ B.′14′ C.′x111′ D.′2′ 参考答案:C error C2022: '273' : too big for character 15:算术运算符,赋值运算符和关系运算符的运算优先级按从高到低依次为 A.算术运算、赋值运算、关系运算 B.算术运算、关系运算、赋值运算 C.关系运算、赋值运算、算术运算 D.关系运算、算术运算、赋值运算 参考答案:B 16:设#define N 3 #define Y(n)((N+1)*n) 则表达式2*(N+Y(5+1))的值是 A.42 B.48 C.54 D.出错 参考答案:B 17:表达式 strcmp(“ 3.14 ”,“ 3.278 ”)的值是一个 A.非零整数 B.浮点数 C.0 D.字符 参考答案: A 18:设struct { short a; char b; float c; }cs; 则sizeof(cs)的值是 A.4 B.5 C.6 D.7 参考答案: D 字节对齐的话应该是8 19:若变量已正确定义,表达式(j=3,j++)的值是 A.3 B.4 C.5 D.0 参考答案:A 20:C 语言中运算对象必须是整型的运算符是 A.% B./ C.! D.** 参考答案:A 简答题 21:打印一个N*N的方阵,N为每边字符的个数(3〈N〈20),要求最外层为“X”,第二层为“Y”,从第三层起每层依次打印数字0,1,2,3,...例子:当N =5,打印出下面的图形: X X X X X X Y Y Y X X Y 0 Y X X Y Y Y X X X X X X 22:谈谈COM的线程模型。然后讨论进程内/外组件的差别。 23:多态类中的虚函数表是Compile-Time,还是Run-Time时建立的? 参考答案: 虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组.而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键.24:#include void main() { int c; while((c=getchar())!= ′ n ′) switch(c-′ 2 ′) { case 0: case 1:putchar(c+4);break; case 2:putchar(c+4);break; case 3:putchar(c+3);break; default:putchar(c+2);break; } printf(″ n ″); } 运行时输入: 2473,输出结果: 参考答案:6897 VC++6.0测试过 25:用两个栈实现一个队列的功能? 参考答案: 设2个栈为A,B, 一开始均为空.入队: 将新元素push入栈A;出队: (1)判断栈B是否为空; (2)如果不为空,则将栈A中所有元素依次pop出并push到栈B; (3)将栈B的栈顶元素pop出;这样实现的队列入队和出队的平摊复杂度都还是O(1), 26:写一语句实现x是否为2的若干次幂的判断。 参考答案:!(X)&(X-1) 27:解二次方程:a*x*x+b*x+c int Quadratic(double a,double b,double c,double& x1,double& x2);返回值:解的个数 28:如何判别一个数是unsigned。 参考答案; #define issignal(x)((x>=0 && ~x>=0)? 1:0)//为1是无符号 为0有符号 29:执行下述程序的输出结果是ABCDEFCDEFEF。 #include char b[]=“ABCDEF”; main() { char *bp; for(bp=b;*bp;bp+=2) printf(“%s”,bp); printf(“n”); } 30:已知一个数组table,用一个宏定义,求出数据的元素个数。 参考答案:#define NTBL #define NTBL(sizeof(table)/sizeof(table[0]))第二篇:嵌入式软件工程师面试题
第三篇:嵌入式软件工程师
第四篇:用友软件Java工程师面试题(含答案)
第五篇:嵌入式软件工程师笔试题(含答案)