当前位置: 首页 > news >正文

重庆网站推广营销php+mysql网站开发教程

重庆网站推广营销,php+mysql网站开发教程,外贸网站源码多语言,成都网站排名收集的一些嵌入式软件工程师面试题目 1、将一个字符串逆序 2、将一个链表逆序 3、计算一个字节里#xff08;byte#xff09;里面有多少bit被置1 4、搜索给定的字节(byte) 5、在一个字符串中找到可能的最长的子字符串 6、字符串转换为整数 7、整数转换为字符串 … 收集的一些嵌入式软件工程师面试题目     1、将一个字符串逆序 2、将一个链表逆序 3、计算一个字节里byte里面有多少bit被置1 4、搜索给定的字节(byte) 5、在一个字符串中找到可能的最长的子字符串 6、字符串转换为整数 7、整数转换为字符串 linux 嵌入式面试 杂集一 2008年10月08日 星期三 11:24 A.M. C语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法。这些年我既参加也组织了许多这种测试在这过程中我意识到这些测试能为面试者和被面试者提供许多有用信息此外撇开面试的压力不谈这种测试也是相当有趣的。         从被面试者的角度来讲你能了解许多关于出题者或监考者的情况。这个测试只是出题者为显示其对ANSI标准细节的知识而不是技术技巧而设计吗这是个愚蠢的问题吗如要你答出某个字符的ASCII值。这些问题着重考察你的系统调用和内存分配策略方面的能力吗这标志着出题者也许花时间在微机上而不是在嵌入式系统上。如果上述任何问题的答案是是的话那么我知道我得认真考虑我是否应该去做这份工作。         从面试者的角度来讲一个测试也许能从多方面揭示应试者的素质最基本的你能了解应试者C语言的水平。不管怎么样看一下这人如何回答他不会的问题也是满有趣。应试者是以好的直觉做出明智的选择还是只是瞎蒙呢当应试者在某个问题上卡住时是找借口呢还是表现出对问题的真正的好奇心把这看成学习的机会呢我发现这些信息与他们的测试成绩一样有用。         有了这些想法我决定出一些真正针对嵌入式系统的考题希望这些令人头痛的考题能给正在找工作的人一点帮助。这些问题都是我这些年实际碰到的。其中有些题很难但它们应该都能给你一点启迪。         这个测试适于不同水平的应试者大多数初级水平的应试者的成绩会很差经验丰富的程序员应该有很好的成绩。为了让你能自己决定某些问题的偏好每个问题没有分配分数如果选择这些考题为你所用请自行按你的意思分配分数。 预处理器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) : (B)) 这个测试是为下面的目的而设的 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 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 h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer 人们经常声称这里有几个问题是那种要翻一下书才能回答的问题我同意这种说法。当我写这篇文章时为了确定语法的正确性我的确查了一下书。但是当我被面试的时候我期望被问到这个问题或者相近的问题。因为在被面试的这段时间里我确定我知道这个问题的答案。应试者如果不知道所有的答案或至少大部分答案那么也就没有为这次面试做准备如果该面试者没有为这次面试做准备那么他又能为什么出准备呢 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) 多线程应用中被几个任务共享的变量每一次被线程改变在内存的值都相应地改变 #define mem1 *(volatile unsigned int*)(0x40020000) 把mem1定义为*(volatile unsigned int*)(0x40020000) 的同义语。 也就是以后访问mem1就相当于从32的无符号地址处0x40020000取数据。 而*(volatile unsigned int*)(0x40020000) 这个声明的意思是把0x40020000这个十六进制转换成32位的无符号的指针 之后解除这个指针的引用也就是从0x40020000这个地址处读数据。 volatile unsigned int* 前面的关键字volatile表示这个地址处的值可能处在不断地变换之中比如可能是os修改了该地址处的值也可能是别的线程修改了该地址处的值。也就是说要求编译器不要对从该地址处读数据的代码进行优化。 在C/C中使用这些代码的时候一般是写底层的程序 回答不出这个问题的人是不会被雇佣的。我认为这是区分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 10. 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。 这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换typecast为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下     int *ptr;     ptr (int *)0x67a9;     *ptr 0xaa55; A more obscure approach is: 一个较晦涩的方法是     *(int * const)(0x67a9) 0xaa55; 即使你的品味更接近第二种方案但我建议你在面试时使用第一种方案。 中断Interrupts 11. 中断是嵌入式系统中重要的组成部分这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是产生了一个新的关键字 __interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR)请评论一下这段代码的。 __interrupt double compute_area (double radius) {     double area PI * radius * radius;     printf(\nArea %f, area);     return area; } 这个函数有太多的错误了以至让人不知从何说起了 1)ISR 不能返回一个值。如果你不懂这个那么你不会被雇用的。 2) ISR 不能传递参数。如果你没有看到这一点你被雇用的机会等同第一项。 3) 在许多的处理器/编译器中浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈有些处理器/编译器就是不允许在ISR中做浮点运算。此外ISR应该是短而有效率的在ISR中做浮点运算是不明智的。 4) 与第三点一脉相承printf()用到R0当ISR的计算结果也会用到R0。经常有重入和性能上的问题。如果你丢掉了第三和第四点我不会太为难你的。不用说如果你能得到后两点那么你的被雇用__asm            {        MOV R0,x        ADD y,R0,x/y //计算x/y 时R0 会被修改            }        在计算x/y 时R0 会被修改,从而影响R0x/y 的结果.用一个C 程序的变量代替 R0就可以解决这个问题:        __asm           {        MOV var,x        ADD y,var,x/y           }     内嵌汇编器探测到隐含的寄存器冲突就会报错 前景越来越光明了。. 代码例子Code examples 12 . 下面的代码输出是什么为什么 void foo(void) {     unsigned int a 6;     int b -20;     (ab 6) ? puts( 6) : puts( 6); } 这个问题测试你是否懂得C语言中的整数自动转换原则我发现有些开发者懂得极少这些东西。不管如何这无符号整型问题的答案是输出是 6。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型(小范围转为大范围)。因此-20变成了一个非常大的正整数所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题你也就到了得不到这份工作的边缘。 13. 评价下面的代码片断 unsigned int zero 0; unsigned int compzero 0xFFFF; /*1s 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 ab; 这个问题将做为这个测验的一个愉快的结尾。不管你相不相信上面的例子是完全合乎语法的。问题是编译器如何处理它水平不高的编译作者实际上会争论这个问题根据最处理原则编译器应当能处理尽可能所有合法的用法。因此上面的代码被处理成 c a b;//和ab13一样 因此, 这段代码持行后a 6, b 7, c 12。 如果你知道答案或猜出正确答案做得好。如果你不知道答案我也不把这个当作问题。我发现这个问题的最大好处是这是一个关于代码编写风格代码的可读性代码的可修改性的好的话题。 好了伙计们你现在已经做完所有的测试了。这就是我出的C语言测试题我怀着愉快的心情写完它希望你以同样的心情读完它。如果是认为这是一个好的测试那么尽量都用到你的找工作的过程中去吧。天知道也许过个一两年我就不做现在的工作也需要找一个。 雇佣合适的人对于Fog Creek软件公司来说是非常关键的。在我们这个领域有三类人可以挑选。在一个极端, 是哪些混进来的, 甚至缺乏最基本的工作技巧. 只要问这类人两三个简单的问题再读一下他们的简历就可以轻易地剔除他们。另一个极端的类型是 才华横溢的超级明星 这些人仅仅为了好玩就用汇编语言为Palm Pilot一种手掌电脑写了一个Lisp一种人工智能编程语言编译器。在这两种极端类型中间的是一大群不能确定水平的候选者也许他们中的某些人能干些什么这里的关键是明白超级明星和那一大堆属于中间类型的人的区别因为Fog Creek软件公司只雇佣超级明星。下面我要介绍一些找出超级明星的技巧。 Fog Creek公司最重要的雇佣标准是: 有头脑, 并且 完成工作 就是这些了。符合这样标准的人就是我们公司需要的员工了。 记住这条标准。 每天上床前背诵这条标准。我们公司的目标之一就是雇佣拥有这样的潜质的人而不是雇佣懂某些技术的人。任何人所拥有的某些具体技术都会在几年内过时所以雇佣有能力学习新技术的人要比雇佣那些只在这一分钟知道SQL编程是怎么回事的人对公司更划算一点。 有头脑确实是一个很难定义的品质。但是让我们看一些在面试时能提问的一些问题通过这些提问我们可以找出拥有这种品质的人。完成工作非常关键。看起来有头脑但是不能完成工作的人经常拥有博士学位在大公司工作过但是在公司中没有人听他们的建议因为他们是完全脱离实际的。比起准时交活儿他们宁愿对于一些学院派的东西沉思。这些人由以下特性而可以识别出来。他们总是爱指出两个根本不同的概念间的相似性。例如他们会说“Spreadsheets是一种特殊的编程语言”,然后花一个礼拜写一篇动人的智慧的白皮书。这篇白皮书论述了作为一个编程语言spreadsheet关于计算语言特性的方方面面。聪明但是没用。 现在我们来谈谈完成工作但是没有头脑的人。他们爱做蠢事。从来也没有考虑过将来得靠他们自己或者别的什么人来亡羊补牢。通过制造新的工作他们成为了公司的负债而不是资产。因为他们不仅没有为公司贡献价值还浪费了好员工的时间。这些人通常到处粘贴大堆的代码而不愿意写子程序。他们是完成了工作但是不是以最聪明的方式完成工作。 面试时最重要的法则是: 做决定 在面试结束时对于被面试者你不得不做一个直截了当的决定。这个决定只有两个结果雇佣或者不雇佣. 回到你的电脑前立刻用电子邮件通知招聘负责人你的决定。电子邮件的主题应该是雇佣或者不雇佣。接着你需要在正文中写两段来支持你的决定. 没有其他的答案。永远不要说“雇佣你但是不能在我的团队中”。这是非常粗鲁的因为你在暗示应试者没有聪明到能有和你一起工作的资格但是以他的头脑适合进入那些天生输家队伍。如果你发觉自己被诱惑想说出那句“雇佣你但是不能在我的队伍中”那么就简单的把这句话变成“不雇佣”再说出口。这样就没事了。甚至如果某个人在特定领域很能干但是在别的队伍中将会表现不好也是不雇佣。事物变化的如此之快我们需要的是在任何地方都能成功的人。如果某些情况下你发现了一个白痴专家拥有某些特殊能力的白痴这个专家对于SQL非常非常非常的精通但是除此之外什么也学不会不雇佣。在Fog Creek公司他们没有将来。 永远不要说“也许我吃不准”。如果你吃不准意味着不雇佣。看比你想象的容易的多。吃不准就说不同样如果你不能作出决定那意味着不雇佣。不要说”嗯雇佣我想是这样的。但是关于...我想知道 ...”。这种情况就是不雇佣。 最重要的是记住这点放弃一个可能的好人要比招进一个坏人强译者按中国有位哲人说过宁可错杀一千不可放过一个呵呵。一个不合格的求职者如果进入了公司将要消耗公司大量的金钱和精力。其他优秀员工的还要浪费时间来修复这个人的错误。如果现在你还在犹豫不雇佣。 如果你是Fog Creek公司的面试官当你拒绝了大量的应聘者时不要为Fog Creek公司将因此雇不到任何人了而忧虑。这不是你的问题。这是招聘负责人的问题。这是人力资源部的问题。这是Joel译者注: Fog Creek公司的老板本文作者的问题。但不是你的问题。不停地问自己哪种情况更糟糕一种情况是我们变成了一个庞大的糟糕的软件公司充斥着许多脑袋空空如可可果壳的家伙另一种情况是我们是一个小而高品质的公司。当然找到优秀的应聘者并聘用他们是很重要的。找到有头脑而且完成工作的人是公司中的每个员工的日常工作之一。但是当你作为Joel Creek公司的一员真的开始面试一个应聘者时要装作现在正有很多优秀的人想打破头挤进Fog Creek公司。总之无论找到一个不错的应聘者是多么的难永远不要降低你的标准。 但是你如何作出雇佣或者不雇佣这样艰难的决定你只要在面试过程中不停地问自己这个人有头脑吗这个人能完成工作吗要作出正确的回答在面试时你必须问对问题。 开个玩笑下面我要问个有史以来最差的面试问题: “Oracle 8i中的数据类型varchar和varchar2有什么区别”这是一个可怕的问题。掌握这种琐碎的技术细节和Fog Creek公司想雇佣你之间没有任何联系。谁会去记这种东西如果有在线帮助你可以在15秒内找到答案。 实际上还有更差的问题等会儿我会谈到的。 现在我们要谈到有趣的部分了面试时提哪些问题。我的面试问题清单来自于我去微软公司找第一份工作的经历。这里实际上有几百个微软面试问题。每个人都有偏爱的问题。你也可以发展一套自己的面试问题以及面试的个人风格这样你就可以比较容易地作出雇佣/不雇佣的决定。以下是我成功使用过的一些面试技巧 在面试前我读一遍应试者的简历然后在一张纸片上随便写以下我的面试计划。这个计划实际上就是我要问的问题清单。以下是一个例子用来面试程序员的 介绍 应试者参加过的项目 无法回答的问题 C语言函数 你满意吗 设计问题 挑战 你还有什么问题 在面试前我非常非常当心避免自己先入为主。如果在面试前你就已经想当然地认为一个麻省理工的博士一定是一个有头脑的人。那么在接下来的一小时的面试时间内无论那个麻省理工的博士说什么都不能改变你的最初印象。如果在面试前你就认为这个应试者是个傻瓜那么他面试时说什么也无济于事。面试就象一个非常精巧的天平。一小时的面试结束后就要对一个人下结论是不容易的但是你又必须在面试结束后得出结论。一些不起眼的细节可能会影响最后的结论。如果你在面试开始前对于应试者有了一点了解的话就好比天平的某一端加上了重重的砝码。这样面试本身就会变得没有用处了。以前有一次在面试前一个招聘负责人跑进我的房间说“你肯定会爱上这个家伙的! 对一个男孩? 天哪这简直让我发疯。我本来应该说“嗯如果你这么确定我会喜欢他为什么你不干脆雇佣他,何必让我浪费时间来面试”但是那时我还太年轻幼稚, 所以还是面试了那个人。当这个家伙开始说一些蠢话时我对自己说“哇塞这应该是个例外情况也许是大智若愚。”我开始带着玫瑰色眼镜看他了。于是我以说“雇佣”结束了面试虽然他是一个糟糕的面试者。接下来发生了什么事除了我其他的面试官都说不要雇佣这个人。教训是不要听别的人的话在面试应试者前不要四处打探这个面试者的情况。最重要的是不要和别的面考官谈论应试者除非你们都已经作出了独立的判断。这才是科学的做法。 作为面试步骤的第一步介绍的目的是让应试者放轻松。我通常花30秒钟讲一下我是谁接下来面试会如何进行。我总是使得应试者确信我们关心的是他她如何解决问题的而不是他她的最终答案是对还是错。顺便说一下面试时你不要和应试者隔着一个桌子坐着否则在你和面试者之间就有了一个障碍并且暗示着一种比较正式严肃的气氛这样应试者就很难放松了。更好的办法是把桌子靠墙放着或者和应试者坐在桌子的同一边这样有助于应试者放松。只有应试者不会因为紧张而表现失常你才能更有效的进行面试. 第二步的内容就是问应试者最近做了些什么项目。对刚毕业的学生, 如果有论文就问问论文, 没有的话, 就问问他们做过什么很喜欢的大作业.例如有时候我会问一下“你最喜欢上学期哪门课程不一定要和计算机相关的。”事实上如果应试者回答的课程和计算机没有关系我会比较高兴。有时候你会发现这个计算机系应届生选择了尽可能少的计算机相关课程但是却选修了很多和音乐相关的课程。但是他她却说最喜欢的课程是《面向对象数据库》。哼哼不错啊. 不过如果你直接承认你喜欢音乐胜于计算机, 而不是在这儿胡说八道的话, 我会更高兴一点。 当面试有工作经验的人时你可以让他们谈一下前一份工作。 我问这个问题的目的是在寻找一样品质热情。在应试者谈到他她最近做过的项目时你观察到以下迹象都是不错的 谈到他们做过的项目时变得热情洋溢他们的语速更快语言更生动活泼。这说明他们对某些东西有兴趣有热情因为现实中有许多人对所做的项目根本漠不关心呢。即使他们激动地表达对做过的项目的负面感情这也是一个好的信号。“我曾经为上一个老板安装Foo Bar Mark II但他是个傻瓜”表现出热情的人就是我们要雇佣的人。差的应试者对工作根本就不关心所以根本不会激动。一个非常好的信号是当应试者很激动地谈论上一份工作以至于暂时忘记了他们正在被面试。有时候应试者刚开始面试时表现的很紧张 -- 这是很正常的现象所以我通常忽略不计。但是当他们谈到单色计算艺术Computational Monochromatic Art时这个家伙变得极端兴奋, 一点都不紧张了。不错我喜欢这样的应试者因为他们关心他们做的事。什么是单色计算艺术拔掉你的电脑显示器的电源就可以看到了 能认真地去解释事情。某些人被我拒掉的原因就是他们不会用普通人能明白的语言去解释他们做过的项目。很多工科专业的人总是以为所有人都知道Bates理论译者注: Bates Theorem一种经济学的理论或者Peano公理组译者注: Peanos Axioms数论中的一些定理是什么。如果应试者开始满口行话了让他们停一停然后你说“能帮我个忙吗就是为了练习一下你能把刚才说的用我老祖母也能理解的话说一遍吗”但即便如此, 有些人还是继续用那些术语, 而且根本没法让人明白他们在说什么。天哪 如果这个项目是一个团队项目看看他们是否在有承担领导责任的迹象一个应试者可能会说“我们用的是X方法但是老板说应该是Y而客户说应该是Z。”我会问“那么你怎么做的”一个好的回答可能是“我设法和团队中别的人开了个会然后一起搞出个办法...”坏的回答看起来象“嗯我什么也不能做。这样的问题我解决不了。”记住聪明并且能完成工作。要搞清楚某人是否能完成工作的一个办法就是看看他她过去是否倾向于完成任务。事实上你可以主动要求他们给你个例子证明他们能担任领导作用完成任务。例如克服公司的陈规陋习。 现在我们谈谈清单上的第三款无法回答的问题。这很有趣。这个主意的关键在于问一些不可能有答案的问题就是想看一下应试者怎么办。“西雅图有多少眼科医生”“华盛顿纪念碑有多重”“洛杉机有多少加油站”“纽约有多少钢琴调音师” 聪明的应试者猜到你不是要测验他们的专业知识他们会积极地给出一个估计。“嗯洛杉机的人口是七百万每个人平均拥有2.5辆轿车...”当然如果他们的估计完全错误了也没有关系。重要的是他们能积极地试着回答问题。他们可能会试着搞清楚每个加油站的储量。“嗯需要四分钟给一个储油罐加满油一个加油站有十个油泵每天运行十八个小时...”他们也可能试着从占地面积来估计。有时, 他们的想法的创造力让你吃惊. 而有时, 他们直接要一个LA的黄页去查。这都是好迹象。 不聪明的应试者则被难住了。他们目瞪口呆地望着你好像你来自火星。你不得不提示“嗯如果你想建立一个象洛杉机那么大的城市你需要建立多少个加油站”你还可以提示他们“加满一个储油罐要多长时间”不过这些榆木疙瘩脑袋还是只会坐在那里发呆你得拖着他们往前走才行。这类人不会解决问题我们可不要这样的人。 关于编程问题我通常要求应试者用C语言写一些小函数。以下是我通常会出的题目 将一个字符串逆序 将一个链表linked list逆序 计算一个字节byte里有多少bit被置1 搜索给定的字节byte 在一个字符串中找到可能的最长的子字符串该字符串是由同一字符组成的 字符串转换成整数 整数转换成字符串这个问题很不错因为应试者要用到堆栈或者strev函数 注意通常你不会希望他们写的代码多于5行因为你没有时间理解太长的代码。 现在我们来详细看一看其中几个问题: 第一个问题: 逆序一个字符串。我这辈子还没有见过那个面试者能把这题目一次做对。所有的应试者都试图动态生成缓冲区然后将逆序的字符串输出到该缓冲区中。问题的关键在于谁负责分配这个缓冲区谁又负责释放那个缓冲区通过这个问题我发现了一个有趣的事实就是大多数认为自己懂C的人实际上不理解指针和内存的概念。他们就是不明白。这真叫人吃惊无法想象这种人也能做程序员。但他们真的就是这个问题可以从多个角度判断应试者 他们的函数运行快吗看一下他们多少此调用了strlen函数。我曾经看到应试者写的strrev的算法竟然只有O(n^2) 的效率而标准的算法效率应该是O(n)效率如此底下的原因是因为他们在循环中一次又一次调用strlen函数。 他们使用指针运算吗译者按原文为pointer arithmetic指的是加减指针变量的值使用指针运算是个好现象。许多所谓的“C程序员”竟然不知道如何使用指针运算pointer arithmetic。当然我在前文说过我不会因为应试者不掌握一种特定的技巧而拒绝他。但是理解C语言中的指针不是一种技巧而是一种与生俱来的才能。每年一所大学要招进200多个计算机系的新生所有这些小孩子4岁就开始用BASIC语言在Atari 800s写冒险游戏了。在大学里他们还学Pascal语言学得也很棒。直到有一天他们的教授讲了指针的概念突然他们开始搞不懂了。他们就是不能再理解C语言中的任何东西了。于是90%的计算机系学生转系去学政治学。为了挽回面子他们告诉朋友他们之所以转系是因为他们计算机系英俊貌美的异性太少。许多人注定脑子里就没有理解指针的那根弦。所以说理解指针是一种与生俱来的品质而不是一种单纯的技巧。理解指针需要脑子转好几个弯某些人天生不擅长转这几个弯。 第三个问题可以考考面试者对C的位运算的掌握但这是一种技巧不是一种品质所以你可以帮助他们。有趣的等他们建立了一个子函数用来计算byte中为1的位的数目然后你要求他们优化这个子函数尽量加快这个函数的运行速度。聪明的应试者会使用查表算法毕竟这个表只有 256个元素用不了多少内存整个表只需要建立一次。跟聪明的应试者讨论一下提高时间空间效率的不同策略是十分有意思的事情. 进一步告诉他们你不想在程序启动时初始化查询表。聪明的面试者可能会建议使用缓冲机制对于一个特定的byte只有在第一次被查询时进行计算然后计算结果会被放入查询表。这样以后再被查询时直接查表就行了。而特别特别聪明的面试这会尝试有没有建立查询表的捷径如一个byte和它的置1的bit数之间有没有规律可循 当你观察应试者写C代码时以下一些技巧会对你有帮助 事先向应试者说明你完全理解没有一个好的编辑器光在纸上写代码是困难的所以你不在乎他们手写的代码是否看上去不整洁。你也完全明白没有好的编译器和调试器很难第一次就写出完全没有bug的程序所以请他们不必为此担心。 好程序员的标志好程序员写完“{”符号后通常立刻跟上“}”符号然后再在当中填上代码。他们也倾向于使用命名规则虽然这个规则可能很原始。如果一个变量用作循环语句的索引好程序员通常使用尽可能少的字符为它命名。如果他们的循环语句的索引变量的名字是CurrentPagePositionLoopCounter显而易见他们写代码的经验还不够多。偶尔你会看到一个C程序员写下象if (0strlen(x))一样的代码常量被放在的左边。这是非常好的现象。这说明他因为总是把和搞混已经强迫自己养成这种习惯以避免犯错。 好的程序员在写代码前会订一个计划特别是当他们的代码用到了指针时。例如如果你要求逆序一个链表好程序员通常会在纸的一边画上链表的草图并表明算法中的索引指针当前移动到的位置。他们不得不这样做。正常人是不可能不借助草图就开始写一个逆序链表的程序的。差的程序员立刻开始写代码。 不可避免的你会在他们的程序中发现bug于是我们现在来到了第五个问题你对代码满意吗 你可能想问“好吧bug在哪里”这是来自地狱的一针见血的问题要回答这个问题可要大费口舌。所有的程序员都会犯错误这不是问题。但他们必须能找到错误。对于字符串操作的函数他们通常会忘记在输出缓冲区加上字符串结束符。所有的函数他们都会犯off-by-one错误译者按指的是某个变量的最大值和最小值可能会和正常值差1)。他们会忘掉正常的C语句结尾的分号。如果输入是零长度字符串他们的函数会运行错误。如果malloc调用失败而他们没有为此写好错误处理代码程序会崩溃。一次就能把所有事情做对的程序员非常,非常,非常地少.不过要是真的碰上一个的话, 提问就更有意思了. 你说,还有Bug。他们会再仔细地检查一遍代码。这个时候, 观察一下他们内心是否开始动摇了, 只是表面上勉强坚持说代码没有问题。总之在程序员写完代码后问一下他们是否对代码满意是个好主意。就像Regis那样问他们译者按Regis Philbin是美国ABC电视网的游戏电视节目主持人他的口头禅是“这是你的最后的答案吗” 第六部分关于设计的问题。让应试者设计某样东西。Jabe BlumenthalExcel的原始设计者喜欢让应试者设计房子。Jabe说曾经有一个应试者跑到白板前画了一个方块这就是他的全部设计。天哪一个方块立刻拒绝这样的家伙。你喜欢问什么样的设计问题 好的程序员会问更多的信息。房子为谁造的我们公司的政策是我们不会雇佣那些在设计前不问为谁设计的人。通常我会很烦恼我得打断他们的设计说“事实上你忘记问这个房子是给谁设计的了。这个房子是给一群长颈鹿造的。” 笨笨的应试者认为设计就像画画你想画什么就画什么。聪明的应试者明白设计的过程是一系列艰难的权衡。一个很棒的设计问题是设计一个放在街角的垃圾箱。想一想你得做多少权衡垃圾箱必须易于清空但是很难被偷走易于放进垃圾但是碰到狂风大作里面的垃圾不会被吹出来垃圾箱必须坚固而便宜。在某些城市垃圾箱必须特别设计以防恐怖分子在里面藏一个定时炸弹。 有创造力的应试者会给出有趣而独特的设计。我最喜欢的问题之一是为盲人设计一个放调味品的架子译者按原文为spice rack老外的厨房里有个专门放调味品的架子,上面放了很多小罐罐里面装了各种各样的调料通常许多应试者的建议是把布莱叶文一种盲人使用的文字刻在放调料的罐子上这样文字会卷起来而变形。我碰到一个应试者他的设计是把调料放在抽屉里因为他觉得水平地感知布莱叶文比垂直地做更方便。试试看这个答案这样有创意使我震惊我面试了有一打得程序员从来没有人想到过类似的答案。这样有创意的答案确实跃过了普通人考虑问题的条条框框。仅仅因为这个答案太有创意了而且应试者别的方面还过得去我雇佣了这个应试者他现在已经成为Excel团队中一个优秀的项目经理了译者按本文作者曾在微软工作过。 总是争取一个确定的了结。这也是完成工作的特质的一部分。有时候应试者会犹犹豫豫不能作出一个决定,试图回避困难的问题留着困难的问题不作决定就直接向下进行,这很不好。好的应试者有一种推动事情自然地前进的倾向即使你有意把他们拖回来。如果关于某个话题的讨论开始原地打转变得没有意义了好的应试者会说“嗯我们可以整天谈论这个但是我们得做点什么。为什么我们不开始...” 于是我们来到了第七部分挑战。这部分很好玩。在面试中留心一下, 当面试者的回答绝对的百分之百毫无争议时, 你可以说: 嗯, 等一下等一下. 然后花上两分钟玩一下魔鬼的游戏译者按原文为devils advocate魔鬼代言人指的是违背自己的良知为错误邪恶的观点辩护. 记住一定要在你可以肯定他正确时和他争论。 这个很有意思. 软弱的应试者会屈服。那我就和他说拜拜了。 坚定的应试者会找到一个办法说服你。他们会以肯尼迪总统的口才来说服你“也许我误会了你的意思”他们这样开头但是正文仍是坚定地站稳立场。这样的人我就雇佣。 不得不承认面试双方的地位并不是平等的。有可能应试者由于害怕你的权力而不敢于你争辩。但是好的应试者有足够的热情和勇气坚持正确的观点他们由于热切希望说服你而会暂时忘记正在被面试。这样的人就是我们要雇佣的人。 最后可以问一下应试者有什么想问的。一些人喜欢看看应试者这时是否会问一些聪明的问题。这是市面上流行的面试书籍的标准技巧。我个人不在乎应试者问什么因为这时我已经做了决定。麻烦在于应试者也许已经见了5、6个人进行了好几轮面试他们可能很累了以至于不能为每轮面试都准备一个聪明而独特的问题。所以如果他们没有可问的没关系。 我总是留下面试的最后5分钟来推销我的公司。这很重要。即使我不打算雇佣眼前这个应试者。如果你幸运的找到一个很棒的应试者你当然愿意做任何事情说服他她来你的公司。即使他们不是好的应试者你也要尽力让他们为Fog Creek公司激动这样面试结束时他们会对Fog Creek公司留下一个很好的印象。记住应试者并不仅仅是可能的雇员他们也是顾客也是我们公司的推销员。如果他们觉得我们的公司很棒他们也许会推荐朋友来面试。 啊哈我记得我说过我会给出一些应该避免的非常不好的反面的试题例子。 首先避免不合法的问题。有关种族宗教性别出生国年龄服役记录是否老兵性取向生理障碍的问题都是不合法的。即使他们的简历说他们1990年在军中服役也不要问有关问题。也许这会让他们愉快地谈论在海湾战争中的经历。但是你的问题还是不合法的。如果简历上写着他们上过Technion in Haifa, 不要问他们是否是以色列人, 即使只是为了闲谈, 因为这是违法的. 下面有一个很好的不合法的例子。点击这里有很多关于什么是违法的讨论。但是这个网站的其余问题够愚蠢的。 其次不要在问题中给予应试者暗示我们公司喜欢或者不喜欢什么样的员工。我能想到的一个例子是问应试者是否有小孩或者是否结婚了。应试者也许会想我们不喜欢有家庭拖累的员工。 最后不要问那些脑筋急转弯的题目例如6根火柴怎么拼出4个三角形。象这样的灵机一动的问题是不能看出应试者是否有“有头脑/完成工作”的品质。 面试与其说是科学不如说是艺术。但是只要你记住有头脑/完成工作这个原则你就可以应对自如。有机会就问问你的同事他们喜欢的面试问题和答案。这是我们公司员工午饭时热衷的话题之一。 linux 嵌入式面试 杂集二 2008年10月08日 星期三 11:28 A.M. 1、将一个字符串逆序 2、将一个链表逆序 3、计算一个字节里byte里面有多少bit被置1 4、搜索给定的字节(byte) 5、在一个字符串中找到可能的最长的子字符串 6、字符串转换为整数 7、整数转换为字符串 一ANSI C/C方面的知识 1、简答题。 1、 如何在C中初始化一个字符数组。 逐个字符赋值char s[] {‘A’,’B’,’C’,’D’}; 字符串赋值char s[] {“ABCD”}; 对于二维字符数组char s[2][10] {“cheng”,”jinzhou”}; 2、 如何在C中为一个数组分配空间。 如果是栈的形式Type s[N]定义后系统自动分配空间分配的空间大小受操作系统限制 若是堆的形式Type *s; s (Type *)malloc(sizeof(Type) * N); 分配的空间大小不受操作系统限制。 3、 如何初始化一个指针数组。 这里有必要重新对比一下指针数组与数组指针的差异。 a. 指针数组数组里存储的是指针。 如int * s[ 5 ] 表示数组s里存储了5个指向整型的指针。           Char * s[ 3 ] {“aaaaa”,”bbb”,”ccccc”} 表示数组s里存储3个指向字符型的指针分别指向字符串aaaaa、bbb、ccccc。 b. 数组指针其实就是数组里面存放的是数据。 如int ( * s )[ 5 ] 表示数组s里存储了5个整型数据。 4、 如何定义一个有10个元素的整数型指针数组。 Int * s [ 10 ]; 5、 s[10]的另外一种表达方式是什么。 * ( s 10 ) 二维数组S [ 5 ][ 8 ]的表示方法*( *(s 5) 8 ) 7、 要使用CHAR_BIT需要包含哪个头文件。 Include limits.h 在该头文件里 #define CHAR_BIT 8 8、 对(-1.2345)取整是多少   1 9、 如何让局部变量具有全局生命期。 使用Static局部变量就存储在全局区静态区便具有全局的生命期和局部的访问控制。 10、C中的常量字符串应在何时定义 没有理解到题目的意思我只是想说明一点定义常量字符串后它属于const型不能去修改它否则程序出错。 11 、如何在两个.c文件中引用对方的变量。 使用extern 12、使用malloc之前需要做什么准备工作。 定义一个指针后就可以malloc了。 13、realloc函数在使用上要注意什么问题。 Realloc后返回的指针与之前malloc返回的指针指向的地址不同。 14、strtok函数在使用上要注意什么问题。 首次调用时s必须指向要分解的字符串随后调用要把s设成NULL 15、gets函数在使用上要注意什么问题。 这里要将Scanf( )、gets( )放在一起比较。Scanf( )是遇到空格就判断为输入结束而gets( )则遇到回车才判断为输入结束。 16、C语言的词法分析在长度规则方面采用的是什么策略 尚不清楚望博友能告知万分感谢 17、ab所表示的是什么意思有什么问题 根据自增运算符的右结合性它是(a)(b)的意思但有的编译器里省略括号就不能通过同时也降低了程序可读性。 18、如何定义Bool变量的TRUE和FALSE的值。 #define TRUE 1 #define FALSE 0 19、C语言的const的含义是什么。在定义常量时为什么推荐使用const而不是#define。 Const是只读的意思它限定一个变量不允许被改变。 #define缺乏类型检测机制在预处理时候有可能引发错误。 Const方面的其它知识扩展          问题1const变量 const 限定的内容 下面的代码编译器会报一个错误请问哪一个语句是错误的呢   typedef char * pStr;   char string[4] abc;   const char *p1 string; // *p1 作为整体不能被修改但p1可以修改p1合法   const pStr p2 string; //相当于const (char*)p2string.p2作为一个整体不能被修改但是下面的p2非法修改pstr不是简单的代替。   p1;   p2;       问题2const变量 字符串常量 请问下面的代码有什么问题 char *p im hungry!; //定义的是字符串常量   p[0] I //不能修改字符串常量    问题const变量 字符串常量2   char a[3] abc 合法吗使用它有什么隐患 没有考虑到字符串结束符‘\0’所以会产生意想不到的错误。   比如以下程序 int main() {        int i;     char p[6] {a,b,c,d,e,f};     printf(%s,p);     while(1);     return 0; } 运行后显示 abcdef 问题3const 指针 类型声明中const用来修饰一个常量有如下两种写法那么请问下面分别用const限定不可变的内容是什么?     1)、const在前面 a. const int nValue //nValue是const 把类型int撇开变量nValue作为一个整体因此 nValue是const型 b. const char *pContent; //*pContent是const, pContent可变 把类型char撇开变量 *pContent作为一个整体因此 *pContent是const型 c. const (char *) pContent;//pContent是const,*pContent可变 把类型char * 撇开注意这里char * 是一个整体而变量 pContent作为一个整体因此 pContent是const型 d. char* const pContent; //pContent是const,*pContent可变 const与变量间没有类型变量 pContent作为一个整体因此 pContent是const型 e. const char* const pContent; //pContent和*pContent都是const 这里分为两层外层把类型char 撇开变量 * const pContent作为一个整体因此 * pContent是const型内层没有类型因此 pContent 是 const 型。 2)、const在后面与上面的声明对等 (这类型更容易判断) a. int const nValue // nValue是const     const与变量之间没有类型const后面那部分整体是const型因此nValue是const型 b. char const * pContent;// *pContent是const, pContent可变     const与变量之间没有类型const后面那部分整体是const型因此 * pContent是const型 c. const(char *) pContent;//pContent是const,*pContent可变     const与变量之间没有类型const后面那部分整体是const型因此 pContent是const型 d. char* const pContent;// pContent是const,*pContent可变     const与变量之间没有类型const后面那部分整体是const型因此 pContent是const型 e. char const* const pContent;// pContent和*pContent都是const 分为两层外层撇开类型charconst后面那部分整体* const pContent是const型因此 * pContent是const型内层const与pContent之间无类型因此pContent是const型。    C中CONST    C中常用:#define 变量名 变量值定义一个值替代,然而却有个致命缺点:缺乏类型检测机制,这样预处理理在C中成为可能引发错误的隐患,于是引入const. const使用: 1. 用于指针的两种情况:const是一个左结合的类型修饰符.    int const *A; //A可变,*A不可变    int *const A; //A不可变,*A可变 2.限定函数的传递值参数: void function(const int Var); //传递过来的参数在函数内不可以改变. 3.限定函数返回值型. const int function(); //此时const无意义 const myclassname function(); //函数返回自定义类型myclassname. 20、C语言的volatile的含义是什么。使用时会对编译器有什么暗示。          volatile的本意是“易变的” 由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化但有可能会读脏数据。当要求使用volatile 声明的变量的值的时候系统总是重新从它所在的内存读取数据即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。 精确地说就是优化器在用到这个变量时必须每次都小心地重新读取这个变量的值而不是使用保存在寄存器里的备份。 下面是volatile变量的几个例子 1). 并行设备的硬件寄存器如状态寄存器 2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3). 多线程应用中被几个任务共享的变量       嵌入式系统程序员经常同硬件、中断、RTOS等等打交道所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。 Volatile的完全扩展 1). 一个参数既可以是const还可以是volatile吗解释为什么。 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。 2). 一个指针可以是volatile 吗解释为什么。 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。 3). 下面的函数有什么错误 int square(volatile int *ptr) { return *ptr * *ptr; }     这段代码的有个恶作剧。这段代码的目的是用来返指针*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; } 1 请用最简洁的语言描述您从前的工作经历和工作成果。 测 试应聘者是否能够用几句话概要地介绍其主要的工作信息和重点业绩而不是以流水帐的形式重复履历表有已经注明的内容。在介绍工作成果时注意应聘者能否正 确表述其在原单位所发挥的作用。尽管有关基本能力的提问大多可以通过简历或应聘表格反映出来但通过回答可以考察应聘者的语言表达能力、仪表神态、目光注 视程度、肢体语言等方面。 2 您为什么重新求职 测试应聘者的求职动机是否合理。重新求职的原因可能因为应聘者原单位的问题但通过回答可以考察应聘者是否既能客观、委婉地说明原由。 3 什么样的单位是您求职的第一选择 测试在应聘者心目中是否对自己和单位的定位清晰明确而不是盲目应聘。 专业背景 4 您认为此工作岗位应当具备哪些素质 测试应聘者认为的岗位素质与招聘需要的岗位素质的吻合程度。 5 请谈谈你对您所从事专业的理解在专业方面有哪些重要的成果 考察应聘者的专业功底。 6 您认为自己应聘的职位在公司里所应当承担的主要职责是什么您个人有哪些方面的优势能够胜任这一职位还存在哪些缺陷和不足准备如何来弥补 考察应聘者个人对工作的理解以及是如何考虑个人与工作之间的匹配性的。 7 您认为自己在这个岗位上的竞争优势是什么 通过回答找到此应聘者与其他应聘人员的优势差异。 工作模式 8 您平时习惯于单独工作还是团队工作 工作习惯与应聘者应征的工作岗位有关。通常需要经常与他人合作或接触的岗位 ( 如秘书、公关等 ) 建议团队工作习惯而技术、设计类型的岗位则相对独立性较强。 9 在工作中您喜欢用哪种形式沟通您认为什么是最有效的沟通形式 通常面对面直接沟通的方式最为有效与书面沟通相比面对面沟通发生误解的可能性较小除非两一见面就剑拔弩张。 10 在过去的工作中您学习到了什么 考察应聘者是否能够从专业成就、人际关系、组织、产品、服务等多个角度来回答问题。当谈及其从前的经历时可测试应聘者是是否是个忠诚的、懂得尊重别人的员工。 11 您如何使自己了解业务上的最新动态 无论什么领域都会有大量专业资料刊登在各类刊物上。对自己的专业研究得越深入就越需要获得新的信息来源。 12 请介绍您原来单位的几个主要竞争对手的情况。 通过回答测试应聘者的市场竞争意识。对本单位津津乐道但对市场状况及竞争行情不甚了解的人员不是一名全面的工作人员。 13 您在工作中通常怎样分配时间 测试应聘者对时间的分配和使用习惯。 14 您未来三年内的目标是什么如何实现 考察应聘者是否对自己能够提出明确的目标并有切实的行动计划而不是“继续做好现在的工作”、“加强学习”等模糊的概念。 15 您对我们公司以及您所应聘的岗位有什么了解 一 名态度认真的求职者往往会在面试之前通过多种渠道去了解应聘单位。如果在应聘的开始已经向应聘者进行介绍可测试应聘者倾听的关注程度。如果事先没有向应 聘者进行有关本单位的情况介绍应聘者可以会借此机会提出了解单位的情况。主试人员在介绍完毕之后仍可通过类似问题考察应聘者。 价值取向 16 您对原来的单位和上司的看法如何 大骂原来单位及同事的应聘者绝非一名有修养的员工。考察应聘者是否能够客观委婉地表达其看法并结合自己放弃原来职位的意图。 17 业余时间您通常用来做什么 考察应聘者是否能够平衡工作与生活之间的关系。 18 描述您上一次在工作中挨批评的情景。 测试应聘者在既属于个人隐私、又有很强的专业性的领域里的沟通能力如何以及应聘者是否经得起批评并了解他以前的工作环境和沟通状况。 19 您是否愿意接受心理测试 考察应聘者是否能够坦诚相告。 20 您觉得怎样才算是成功 考察应聘者是否能够把受到赏识与做出有意义的贡献联系在一起而且可以正确地平衡事业与家庭之间的关系。 21 您认为做人的基本原则是什么 考察应聘者个人的行为准则和道德规范意识。 资质特性 22 您如何描述自己的个性 测试应聘者的个性与招聘单位的文化、风气、行为准则、岗位特点等之间的匹配程度。例如外向性格在公关、市场等工作岗位更具优势内向性格在科研、档案等工作岗位更具优势。 23 请列举您的三大优点和三大缺点。 应聘者是否能够坦诚相告自身的特性并考虑其特质是否影响到此岗位的工作及团队工作。 24 您原来的同事通常是如何评价您的 考察应聘者是否了解自己在他人心中的看法并正视面临的问题。 薪资待遇 25 是否方便告诉我您目前的待遇是多少 26 您所期望的待遇是多少 如果应聘者要求与更高层的主管商谈待遇问题招聘者可巧妙地变换提问方式“我们只是希望清楚您能够接受的待遇范围例如税后月薪 2000-2500 元左右。” 27 您要求公司必须的福利有哪些另外希望公司提供什么样的福利 涉及到人力成本及相关法规的问题同时通过应聘者谈到原单位的福利时可以看出单位实力以及自身的承受能力。 背景调查 28 您是否介意我们通过您原来的单位进行一些调查 重要的职位是必须进行调查的。通过应聘者回答问题时的态度及调查的材料可以测试其诚实程度。 linux 嵌入式面试 四 2008年10月08日 星期三 12:19 P.M. . What does the following program print? 中国台湾某著名计算机硬件公司2005年12月面试题 #include iostream using namespace std; int main (void) { int x 2, y, z; x * (y z 5); cout x endl; z 3; x (y z); cout x endl; x (y z); cout x endl; x (y z); cout x endl; x (y z); cout x endl; y 4; x (y | z); cout x endl; x (y || z); cout x endl; return 0; } 输出 10 10 1 3 1 7 1 2. What does the following program print? (中国某著名计算机金融软件公司2005年12月面试题) #include iostream using namespace std; int Vac 3; int main (void) { int Vac 10; ::Vac; cout ::Vac endl; cout Vac endl; return 0; } 输出 4 10 3. What will be the output of the following code (assume the necessary include files are present)? 中国台湾某著名杀毒软件公司2005年10月面试题 int i 3, j 4; i?i:j; printf(%d %d\n, i, j); 输出 4 4 4.以下代码的输出结果是什么中国某著名计算机金融软件公司2005年面试题 int i 1, j 2; int k ij; cout k endl; 输出 3 5. xx1, x1, x, 哪个效率最高为什么? (1) x x1 #include stdio.h int main(int argc, char* argv[]) { int x 0; x x 1; return 0; } .file a.c .text .globl main .type main, function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $16, %esp movl $0, -8(%ebp) addl $1, -8(%ebp) movl $0, %eax addl $16, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret .size main, .-main .ident GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4) .section .note.GNU-stack,,progbits (2) x 1 #include stdio.h int main(int argc, char* argv[]) { int x 0; x1; return 0; } .file b.c .text .globl main .type main, function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $16, %esp movl $0, -8(%ebp) addl $1, -8(%ebp) movl $0, %eax addl $16, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret .size main, .-main .ident GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4) .section .note.GNU-stack,,progbits (3) x #include stdio.h int main(int argc, char* argv[]) { int x 0; x; return 0; } .file c.c .text .globl main .type main, function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $16, %esp movl $0, -8(%ebp) addl $1, -8(%ebp) movl $0, %eax addl $16, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret .size main, .-main .ident GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4) .section .note.GNU-stack,,progbits 解析给出的答案是x的效率最高答案的解释如下 xx1最低因为它的执行过程如下 (1)读取右x下的地址 (2)x1 (3)读取左x的地址 (4) 将右值传给左边的x编译器并不认为左右x的地址相同 x1其次其执行过程如下 (1)读取右x下的地址 (2)x1 (3)将得到的值传给x因为x的地址已经读出 x效率最高其执行过程如下 (1) 读取右x的地址 (2) x自增1 以上解释表面上看似正确但看过相应的汇编代码后我们不难得到不同结论三个语句的效率是相同的因为他们的汇编代码是完全一样的也就是说执行时的机器指令是完全一样的最起码在gcc的编译器上是如此。 6. What will be the output of the following C code? 中国台湾某著名CPU生产公司2005年面试题 #include stdio.h #define product(x) (x*x) int main(void) { int i 3, j, k; j product(i); k product(i); printf(j%d,k%d\n,j,k); return 0; } 输出 j9,k49 解析 经过预处理后的部分代码gcc -E 6.c其实是做了宏替换 ... //前面部分省略 int main(void) { int i 3, j, k; j (i*i); k (i*i); printf(j%d,k%d\n,j,k); return 0; } .file 6.c .section .rodata .LC0: .string j%d,k%d\n .text .globl main .type main, function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $36, %esp movl $3, -16(%ebp) movl -16(%ebp), %eax imull -16(%ebp), %eax #第一个乘法 movl %eax, -12(%ebp) addl $1, -16(%ebp) #i加上了一个1i4 addl $1, -16(%ebp) #i加上了一个1i5 addl $1, -16(%ebp) #i加上了一个1i6 addl $1, -16(%ebp) #i加上了一个1i7 movl -16(%ebp), %eax imull -16(%ebp), %eax #第二个乘法 movl %eax, -8(%ebp) movl -8(%ebp), %eax movl %eax, 8(%esp) movl -12(%ebp), %eax movl %eax, 4(%esp) movl $.LC0, (%esp) call printf movl $0, %eax addl $36, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret .size main, .-main .ident GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4) .section .note.GNU-stack,,progbits 7. If there are int a 5, b 3; , the value of a and b are _ and _ after execute !ab; 中国某著名综合 软件公司2005年面试题 结果 5和3 8. We have two pieces of code, which one do yo prefer, and tell why. 美国某著名计算机嵌入式公司2005年10月面试题 A. // a is a variable 写法1 if (A a) { a; } 写法2 if(a A) { } B. 写法1 for(i0;i8;i) { X iYJ*7; printf(%d,x); } 写法2 SYJ*7; for(i0;i8;i) { printf(%d,iS); } 8.下面程序的结果是什么中国台湾某著名CPU生产公司2005年面试题 char foo (void) { unsigned int a 6; int b -20; char c; (a b 6) ? (c 1) : (c 0); return c; } 结果为1 分析unsigned int类型的数据与int类型的数据相运算后自动转化为unsigned int类型。因此ab的值不是-14而是一个unsignged int类型的书4294967282。需要弄明白“C语言中的自动类型转换的规则”。 1. 在 C程序中调用被C编译后的函数为什么要加extern C? C语言支持函数重载C语言不支持函数重载。函数被C编译后在库中的名字与C语言的不同。假设某个函数的原型为: void foo(int x, int y). 该函数被C编译器编译后在库中的名字为_foo而C编译器则会产生像_foo_int_int之类的名字。 C提供了C连接交换指定符号extern C解决名字匹配问题。 例如C标准头文件都有类似以下的结构 #ifndef __INCvxWorksh #define __INCvxWorksh #ifdef __cplusplus extern C { #endif /*...*/ #ifdef __cplusplus } #endif #endif /* __INCvxWorksh */ 2. 头文件中的ifndef/define/endi是干什么用的 防止该头文件被重复引用 3. #include filename.h和#incldue filename.h有什么区别 对于#include filename.h编译器从标准头文件的路径开始搜索filename.h在UNIX类的系统中通常是/usr/include。 对于#include filename.h编译器从包含该头文件的C源程序文件所在的路径开始搜索filename.h 4. 如何判断一段程序是由C编译器编译的还是由C 编译器编译的美国某著名网络开发公司2005年面试题 C编译时定义了_cplusplus而C编译时定义了_STDC_。 5. main主函数执行完毕后是否可能会再执行一段代码给出说明。美国某著名网络开发公司2005年面试题 #include stdio.h #include stdlib.h void func1(void), func2(void), func3(void); int main(void) { atexit(func1); atexit(func2); atexit(func3); printf(%s\n,__func__); return 0; } void func1(void) { printf(%s\n,__func__); } void func2(void) { printf(%s\n,__func__); } void func3(void) { printf(%s\n,__func__); } 执行结果如下 main func3 func2 func1 详细解释见abort、atexit、exit和_Exit 1. There are two int variables: a and b, dont use if, ?:, switch or other judgment statements, find out the biggest one of the two numbers.某国某著名网络开发公司2005年面试题 方案一 int max ((ab) abs(a-b))/2; 方案二 int c a -b; c unsigned (c) (sizeof(int)*8 - 1); 2. 如何将a、b不得值进行交换并且不使用任何中间变量 用异或语句比较简单不用担心溢出问题.如采用 aab; ba-b; aa-b; 这样做的缺点是如果a、b都是比较大的两个数aab 时就会溢出。 而采用 aa^b; ba^b; aa^b; 无须担心溢出的问题这样就比较好。 这样做的于那里是按位异或运算。按位异或运算符 ^ 是二元运算符其功能是参与运算的两数个地用的二进制位相异或当对应的二进制位相异时结果为1。 3.螺旋队列 21 22 ...... 20 7 8 9 10 19 6 1 2 11 18 5 4 3 12 17 16 15 14 13 看清以上数字排列的规律设1点的坐标是00x方向向右为正y方向向下为正。例如7的坐标为112的坐标为 013的坐标为11。编程实现输入任意一点的坐标x,y输出所对应的数字。芬兰某著名通信设别公司2005年面试题 1. What is the output of the following code? 中国台湾某著名杀毒软件公司2005年10月面试题 #define SR(x) (x*x) main() { int a, b 3; a SQR(b2); printf(\n%d,a); } 结果为11 #include stdio.h #define SQR(x) (x*x) int main (void) { int a, b 3; a SQR (b 2); printf (\n%d, a); return 0; } 经过预处理的宏替换后的部分代码如下 ... //以上部分省略 int main (void) { int a, b 3; a (b 2*b 2); printf (\n%d, a); return 0; } 宏定义具有副作用宏展开后容易造成二义性。较好的习惯是在宏定义的参数上加入括号来保证运算的优先级如 #define SQR (x) ((x)*(x)) 2. 用预处理指令#define声明一个常数用以表明1年中有多少秒忽略闰年问题美国某著名计算机嵌入式公司2005年面试题 #define SECONDS_PER_YEAR (60*60*24*365)UL 意识到这个表达式将使一个16位机的整型数溢出因此要用到长整型符号L告诉编译器这个常数是长整型数。 3.写一个“标准”宏MIN这个宏输入两个参数并返回较小的一个。美国某著名计算机嵌入式公司2005年面试题 #define MIN(x ,y) ((x)(y)?(x):(y)) 1. What does the keyword const means in C program? Please at least make two examples about the usage of const.中国台湾某著名CPU生产公司2005年面试题 在C程序中const的用法主要有定义常量、修饰函数参数、修饰函数返回值等3个用处。在C程序中它还可以修饰函数的定义体定义类中某个成员函数为恒态函数即不改变类中的数据成员。 (1)可以定义const 常量(2)const可以修饰函数的参数和返回值甚至函数的定义体。被const 修饰的东西都受到强制保护可以预防意外的变动能提高程序的健壮性。 2. const与 define相比有什么不同 C语言可以用const定义常量也可以用#define定义常量但是前者比后者有更多的优点 1const常量有数据类型而宏常量没有数据类型。编译器可以对前者进行类型安全检查而对后者只进行字符替换没有类型安全检查并且在字符替换中可能会产生意料不到的错误边际效应 2有些集成化的调试工具可以对const常量进行调试但是不能对宏常量进行调试。在C程序中只使用const常量而不使用宏常量即const常量完全取代宏常量。 常量的引进是在早期的C版本中当时标准C规范正在制定。那时常量被看作一个好的思想而被包含在C中。但是C中的const的意识是“一 个不能被改变的普通变量”。在C中它总是占用内存而且它的名字是全局符。C编译器不能把const看成是一个编译期间的常量。在C中如果写 const bufsize 100; char buf[bufsize]; 尽管看起来好像做了一件合理的事情但这将得到一个错误的结果。因为bufsize占用内存的某个地方所以C编译器不知道它在编译时的值。在C语言中可以选择这样书写 const bufsize; 这样写在C中是部队的而C编译器则把它作为一个声明这个声明指明在别的地方有内存分配。因此C默认const是外部连接的C默认const是内部连接的。这样如果在C中想完成与C中同样的事情必须用extern把内部连接改写外部连接 extern const bufsize; // declaration only 这种方法也可用在C语言中。在C语言中使用限定符const不是很有用即使是在常数表达式里必须在编译期间被求出想使用一个已命名的值使用const也不是很有用的。C迫使程序员在预处理里使用#define。 linux 嵌入式面试 五 2008年10月08日 星期三 12:20 P.M. 1、 如何在C中初始化一个字符数组。 这个问题看似很简单但是我们要将最简单的问题用最严谨的态度来对待。关键的地方初始化、字符型、数组。最简单的方法是char array[];。这个问题看似解决了但是在初始化上好像还欠缺点什么个人认为char array[5]{1,2,3,4,5};或者char array[5]{12345};或者char array[2][10]{China,Beijing};也许更符合“初始化”的意思。 2、 如何在C中为一个数组分配空间。 最简单的方法是char array[5]意思是分配给数组array一个5个字节的空间。但是我们要知道在C中数组其实就是一个名字其实质含义就是指针比如char array[]是到底分配的多少空间所以我们要将其分成为两种不同的形式给出答案 一种是栈的形式char array[5] 一种是堆的形式char *array; array(char *)malloc(5);//C: arraynew char[5]; 堆和栈的含义其实我也没弄太透彻改天明白了再发一篇。 我们要明白的是第一种形式空间分配的大小可能会受操作系统的限制,比如windows会限制在2M第二种形式成空间分配很灵活想分配多少分配多少只要RAM够大。 3、 如何初始化一个指针数组。 首先明确一个概念就是指向数组的指针和存放指针的数组。 指向数组的指针char (*array)[5];含义是一个指向存放5个字符的数组的指针。 存放指针的数组char *array[5];含义是一个数组中存放了5个指向字符型数据的指针。 按照题意我理解为初始化一个存放指针的数组char *array[2]{China,Beijing}其含义是初始化了一个有两个指向字符型数据的指针的数组这两个指针分别指向字符串China和Beijing。 4、如何定义一个有10个元素的整数型指针数组。 既然只是定义而不是初始化那就很简单且没有争议了int *array[10];。 5、 s[10]的另外一种表达方式是什么。 前面说过了数组和指针其实是数据存在形态的两种表现形式如果说对于数组s[]我们知道*ss[0]那么s[10]的另一种表达方式就是*(s10)。 6、 GCC3.2.2版本中支持哪几种编程语言。 这个问题实在变态就像问你#error的作用是什么一样。不可否认gcc是linux下一个亮点是一个备受无数程序员 推崇的编译器其优点省略1000字有兴趣可以自己查我翻了翻书书上曰支持C,C,Java,Obj- C,Ada,Fortran,Pascal,Modula-3等语言这个“等”比较要命不过我认为已经很全了如果认为还是不全干脆把ASM也加上 算了不过那已经不算是编译了。 7、 要使用CHAR_BIT需要包含哪个头文件。 如果结合上面的问题答题的人估计会认为自己撞鬼了这个问题实在是……搜索了一下应该是limits.h。 8、 对(-1.2345)取整是多少 其实不同的取整函数可能有不同的结果不过这个数没有太大的争议答案是-1。 9、 如何让局部变量具有全局生命期。 具体的生命期的概念我觉得我还要好好深入的学习一下但是这个题目还算比较简单即用static修饰就可以了但是只是生命期延长范围并没有扩大除非把这个变量定义在函数体外的静态区不过那样就变成全局变量了仿佛不符合题目要求。 10、C中的常量字符串应在何时定义 这个问题说实话不是很理解题干的意思据我理解有两种情况一种是预处理阶段用#define定义还有就是使用const修饰词不过const修 饰的是一个变量其含义是“只读”称之为常量并不准确但是确实可以用操作变量的方法当常量用。所以还是第一种比较靠谱。 11、如何在两个.c文件中引用对方的变量。 这个问题也问的挺含糊的怎么说呢最简单最直接的方法是为变量添加extern修饰词当然这个变量必须是全局变量。还有一种就是利用函数调用来进行 变量的间接引用比如这个C文件中的一个函数引用另外一个C中的函数将变量通过实参的形式传递过去。不过题目既然说是引用那么还是用第一个答案好了。 12、使用malloc之前需要做什么准备工作。 其实准备工作很多啊比如你需要一台计算机之类的。玩笑话我们首先要知道malloc的用途简单的说就是动态的分配一段空间返回这段空间的头指针。 实际的准备工作可以这么分需要这段空间的指针是否存在若不存在则定义一个指针用来被赋值还要清楚要返回一个什么类型的指针分配的空间是否合理 如果指针已经存在那么在重新将新的空间头地址赋值给这个指针之前要先判断指针是否为NULL如果不是要free一下否则原来的空间就会被浪费或 者出错free之后就按照前一种情形考虑就可以了。 13、realloc函数在使用上要注意什么问题。 这个函数我也才知道的汗一个。据我的初步理解这个函数的作用是重新分配空间大小返回的头指针不变只是改变空间大小。既然是改变就有变大、变小和为什么改变的问题。变大要注意不能大到内存溢出变小那变小的那部分空间会被征用原有数据不再存在为什么改变如果是想重新挪作他用还是先free了吧。 14、strtok函数在使用上要注意什么问题。 这个问题我不知道能不能回答全面因为实在是用的很少。这个函数的作用是分割字符串但是要分割的字符串不能是常量这是要注意的。比如先定义一个字符 串char array[]part1,part2;strtok的原形是char *strtok(char *string, char *delim);我们将,作为分隔符先用ptstrtok(array,,);得到的结果print出来就是part1那后面的 呢要写成ptstrtok(NULL,,);注意要用NULL如果被分割的字符串会被分成N段那从第二次开始就一直要用NULL。总结起 来需要注意的是被分割的字符串和分隔符都要使用变量除第一次使用指向字符串的指针外之后的都要使用NULL注意使用这个函数的时候千万别把指针 跟丢了不然就全乱了。 15、gets函数在使用上要注意什么问题。 这是一个键盘输入函数将输入字符串的头地址返回。说到要注意的问题我还是先查了一下网上的一些情况需要注意的就是gets以输入回车结束这个地球 人都知道但是很多人不知道的是当你输入完一个字符串后这个字符串可能依然存在于这个标准输入流之中当再次使用gets的时候也许会把上次输入的 东西读出来所以应该在使用之后用fflush(stdin);处理一下将输入流清空。最后也还是要注意溢出的问题。关于这个答案我比较含糊不知道有 没有高人高见 16、C语言的词法分析在长度规则方面采用的是什么策略 我无语……闻所未闻啊……还是搜索了一下有一篇文章地址是http://202.117.80.9/jp2005/20/kcwz/wlkc/wlkc/03/3_5_2.htm是关于词法分析器的。其中提到了两点策略 (1) 按最长匹配原则确定被选的词型(2) 如果一个字符串能为若干个词型匹配则排列在最前面的词型被选中。不知道是不是题干的要求还是其他什么。我乃一介草民望达人指点迷津 17、ab所表示的是什么意思有什么问题 这个东西称之为东西一点都不过分其实并没有语法错误按照C对运算符等级的划分的优先级大于那么这句话会被编译器看做(a) (b)这回明白了吧。有什么问题语法上没有问题有的是道德上的问题作为一个优秀的程序员我们要力求语句的合法性和可读性如果写这句的人是 在一个team里那么他基本会被打的半死……最后讨论一下结果假设a之前的值是3b是4那么运行完这个变态语句后a的值是4b是5语句的结 果是8。 18、如何定义Bool变量的TRUE和FALSE的值。 不知道这个题有什么陷阱写到现在神经已经大了一般来说先要把TURE和FALSE给定义了使用#define就可以 #define TURE 1 #define FALSE 0 如果有一个变量需要定义成bool型的举个例子bool aTURE;就可以了。 19、C语言的const的含义是什么。在定义常量时为什么推荐使用const而不是#define。 首先这个题干抽了10题回答的一个大嘴巴。关于常量的概念看来我要好好看看书了……我说过了const修饰词可以将一个变量修饰为“只读”这个就能 称为常量么姑且认为可以。回到题目中const是只读的意思它限定一个变量不允许被改变谁都不能改既然是修饰变量那么变量的类型就可以丰富多 彩int啊char啊只要C认识的都可以但是#define就不可以了在预处理阶段缺乏类型检测机制有可能会出错。还有就是变量可以 extern但是#define就不可以。貌似const还可以节省RAM这个我倒是没有考证过。至于const的用法和作用有很多我会总结后发 上来。 20、C语言的volatile的含义是什么。使用时会对编译器有什么暗示。 终于最后一题了容易么……如果这个测试是一个关于嵌入式的那么这道题非常重要从词面上讲volatile的意思是易变的也就是说在程序运行 过程中有一些变量可能会被莫名其妙的改变而优化器为了节约时间有时候不会重读这个变量的真实值而是去读在寄存器的备份这样的话这个变量的真实 值反而被优化器给“优化”掉了用时髦的词说就是被“和谐”了。如果使用了这个修饰词就是通知编译器别犯懒老老实实去重新读一遍可能我说的太“通俗 ”了那么我引用一下“大师”的标准解释 volatile的本意是“易变的” 。 由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化但有可能会读脏数据。当要求使用volatile 声明的变量的值的时候系统总是重新从它所在的内存读取数据即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。 精确地说就是优化器在用到这个变量时必须每次都小心地重新读取这个变量的值而不是使用保存在寄存器里的备份。 下面是volatile变量的几个例子 1). 并行设备的硬件寄存器如状态寄存器 2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3). 多线程应用中被几个任务共享的变量 嵌入式系统程序员经常同硬件、中断、RTOS等等打交道所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。 linux 嵌入式面试 杂集六 2008年10月08日 星期三 12:24 P.M. C语言面试题      1、局部变量能否和全局变量重名 答能局部会屏蔽全局。要用全局变量需要使用:: 局部变量可以与全局变量同名在函数内引用这个变量时会用到同名的局部变量而不会用到全局变量。对于有些编译器而言在同一个函数内可以定义多个同名的局部变量比如在两个循环体内都定义一个同名的局部变量而那个局部变量的作用域就在那个循环体内。 2、如何引用一个已经定义过的全局变量 答extern 可以用引用头文件的方式也可以用extern关键字如果用引用头文件方式来引用某个在头文件中声明的全局变理假定你将那个变写错了那么在编译期间会报错如果你用extern方式引用时假定你犯了同样的错误那么在编译期间不会报错而在连接期间报错。 3、全局变量可不可以定义在可被多个.C文件包含的头文件中为什么 答可以在不同的C文件中以static形式来声明同名全局变量。 可以在不同的C文件中声明同名的全局变量前提是其中只能有一个C文件中对此变量赋初值此时连接不会出错 4、语句for( 1 )有什么问题它是什么意思 答和while(1)相同。 5、do……while和while……do有什么区别 答前一个循环一遍再判断后一个判断以后再循环 6、请写出下列代码的输出内容 #include main() { int a,b,c,d; a10; ba; ca; d10*a; printf(bcd%d%d%dbcd; return 0; } 答1012120 7、static全局变量与普通的全局变量有什么区别static局部变量和普通局部变量有什么区别static函数与普通函数有什么区别 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序 当一个源程序由多个源文件组成时非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域 即只在定义该变量的源文件内有效 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内只能为该源文件内的函数公用 因此可以避免在其它源文件中引起错误。 从以上分析可以看出 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域 限制了它的使用范围。 static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static)内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数应该在一个头文件中说明要使用这些函数的源文件要包含这个头文件 static全局变量与普通的全局变量有什么区别static全局变量只初使化一次防止在其他文件单元中被引用; static局部变量和普通局部变量有什么区别static局部变量只被初始化一次下一次依据上一次结果值 static函数与普通函数有什么区别static函数在内存中只有一份普通函数在每个被调用中维持一份拷贝. 8、程序的局部变量存在于堆栈中全局变量存在于静态区 中动态申请数据存在于 堆中。 9、设有以下说明和定义 typedef union {long i; int k[5]; char c;} DATE; struct data { int cat; DATE 不属于标准类型不须对齐cow; double dog;} too; DATE max; 则语句 printf(%d,sizeof(struct date)sizeof(max));的执行结果是___52____ 答DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20 data是一个struct, 每个变量分开占用空间. 依次为int4 DATE20 double8 32. 所以结果是 20 32 52. 当然...在某些16位编辑器下, int可能是2字节,那么结果是 int2 DATE10 double8 20 10、队列和栈有什么区别 队列先进先出栈后进先出 11、写出下列代码的输出内容 #include int inc(int a) { return(a); } int multi(int*a,int*b,int*c) { return(*c*a**b); } typedef int(FUNC1)(int in); typedef int(FUNC2) (int*,int*,int*); void show(FUNC2 fun,int arg1, int*arg2) { INCpinc; int temp p(arg1); fun(temp,arg1, arg2); printf(%d\n,*arg2); } main() { int a; show(multi,10,a); return 0; } 答110 12、请找出下面代码中的所以错误 说明以下代码是把一个字符串倒序如“abcd”倒序后变为“dcba” 1、#includestring.h 2、main() 3、{ 4、 char*srchello,world; 5、 char* destNULL; 6、 int lenstrlen(src); 7、 dest(char*)malloc(len); 8、 char* ddest; 9、 char* ssrc[len]; 10、 while(len--!0) 11、 ds--; 12、 printf(%s,dest); 13、 return 0; 14、} 答 方法1 int main() { char* src hello,world; int len strlen(src); char* dest (char*)malloc(len1);//要为\0分配一个空间 char* d dest; char* s src[len-1];//指向最后一个字符 while( len-- ! 0 ) *d*s--; *d 0;//尾部要加\0 printf(%s\n,dest); free(dest);// 使用完应当释放空间以免造成内存汇泄露 return 0; } 方法2 #include #include main() { char str[]hello,world; int lenstrlen(str); char t; for(int i0; i   { tstr[i]; str[i]str[len-i-1]; str[len-i-1]t; } printf(%s,str); return 0; } 1.-1,2,7,28,63,126请问28和126中间那个数是什么为什么 第一题的答案应该是4^3-163 规律是n^3-1(当n为偶数024)n^31(当n为奇数135) 答案63 2.用两个栈实现一个队列的功能要求给出算法和思路 设2个栈为A,B, 一开始均为空. 入队: 将新元素push入栈A; 出队: (1)判断栈B是否为空 (2)如果不为空则将栈A中所有元素依次pop出并push到栈B (3)将栈B的栈顶元素pop出 这样实现的队列入队和出队的平摊复杂度都还是O(1), 比上面的几种方法要好。 3.在c语言库函数中将一个字符转换成整型的函数是atool()吗这个函数的原型是什么 函数名: atol 功 能: 把字符串转换成长整型数 用 法: long atol(const char *nptr); 程序例: #include #include int main(void) { long l; char *str 98765432; l atol(lstr); printf(string %s integer %ld\n, str, l); return(0); } 13.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C中应用什么实现? c用宏定义c用inline 14.直接链接两个信令点的一组链路称作什么? PPP点到点连接 15.接入网用的是什么接口? 16.voip都用了那些协议? 17.软件测试都有那些种类? 黑盒针对系统功能的测试 白合测试函数功能各函数接口 18.确定模块的功能和模块的接口是在软件设计的那个队段完成的? 概要设计阶段 19. enum string { x1, x2, x310, x4, x5, }x; 问x 0x8010050x8010f4 ; 20. unsigned char *p1; unsigned long *p2; p1(unsigned char *)0x801000; p2(unsigned long *)0x810000; 请问p15 ; p25 ; 选择题: 21.Ethternet链接到Internet用到以下那个协议? A.HDLC;B.ARP;C.UDP;D.TCP;E.ID 22.属于网络层协议的是: A.TCP;B.IP;C.ICMP;D.X.25 23.Windows消息调度机制是: A.指令队列;B.指令堆栈;C.消息队列;D.消息堆栈; 24. unsigned short hash(unsigned short key) { return (key)%256 } 请问hash(16),hash(256)的值分别是: A.1.16;B.8.32;C.4.16;D.1.32 找错题: 25.请问下面程序有什么错误? int a[60][250][1000],i,j,k; for(k0;k1000;k) for(j0;j250;j) for(i0;i60;i) a[i][j][k]0; 把循环语句内外换一下 26. #define Max_CB 500 void LmiQueryCSmd(Struct MSgCB * pmsg) { unsigned char ucCmdNum; ...... for(ucCmdNum0;ucCmdNum { ......; } 死循环 27.以下是求一个数的平方的程序,请找出错误: #define SQUARE(a)((a)*(a)) int a5; int b; bSQUARE(a); 28. typedef unsigned char BYTE int examply_fun(BYTE gt_len; BYTE *gt_code) { BYTE *gt_buf; gt_buf(BYTE *)MALLOC(Max_GT_Length); ...... if(gt_lenMax_GT_Length) { return GT_Length_ERROR; } ....... } 问答题: 29.IP Phone的原理是什么? IPV6 30.TCP/IP通信建立的过程怎样端口有什么作用 三次握手确定是哪个应用程序使用该协议 31.1号信令和7号信令有什么区别我国某前广泛使用的是那一种 32.列举5种以上的电话新业务 1.static变量和static 函数各有什么特点 3.描述一下嵌入式基于ROM的运行方式基于ram的运行方式有什么区别。 4.task 有几种状态 5.task 有几种通讯方式 6.C函数允许重入吗 7.嵌入式操作系统和通用操作系统有什么差别 linux 嵌入式面试 杂集七 2008年10月08日 星期三 12:27 P.M. 1、局部变量能否和全局变量重名 答能局部会屏蔽全局。要用全局变量需要使用:: 局部变量可以与全局变量同名在函数内引用这个变量时会用到同名的局部变量而不会用到全局变量。对于有些编译器而言在同一个函数内可以定义多个同名的局部变量比如在两个循环体内都定义一个同名的局部变量而那个局部变量的作用域就在那个循环体内。 2、如何引用一个已经定义过的全局变量 答extern 可以用引用头文件的方式也可以用extern关键字如果用引用头文件方式来引用某个在头文件中声明的全局变理假定你将那个变写错了那么在编译期间会报错如果你用extern方式引用时假定你犯了同样的错误那么在编译期间不会报错而在连接期间报错。 3、全局变量可不可以定义在可被多个.C文件包含的头文件中为什么 答可以在不同的C文件中以static形式来声明同名全局变量。 可以在不同的C文件中声明同名的全局变量前提是其中只能有一个C文件中对此变量赋初值此时连接不会出错 4、语句for( 1 )有什么问题它是什么意思 答和while(1)相同。 5、do……while和while……do有什么区别 答前一个循环一遍再判断后一个判断以后再循环 6、请写出下列代码的输出内容 #includestdio.h main() { int a,b,c,d; a10; ba; ca; d10*a; printf(bcd%d%d%dbcd; return 0; } 答1012120 7、static全局变量与普通的全局变量有什么区别static局部变量和普通局部变量有什么区别static函数与普通函数有什么区别 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序 当一个源程序由多个源文件组成时非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域 即只在定义该变量的源文件内有效 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内只能为该源文件内的函数公用 因此可以避免在其它源文件中引起错误。 从以上分析可以看出 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域 限制了它的使用范围。 static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static)内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数应该在一个头文件中说明要使用这些函数的源文件要包含这个头文件 static全局变量与普通的全局变量有什么区别static全局变量只初使化一次防止在其他文件单元中被引用; static局部变量和普通局部变量有什么区别static局部变量只被初始化一次下一次依据上一次结果值 static函数与普通函数有什么区别static函数在内存中只有一份普通函数在每个被调用中维持一份拷贝 8、程序的局部变量存在于堆栈中全局变量存在于静态区 中动态申请数据存在于 堆中。 9、设有以下说明和定义 typedef union {long i; int k[5]; char c;} DATE; struct data { int cat; DATE cow; double dog;} too; DATE max; 则语句 printf(%d,sizeof(struct date)sizeof(max));的执行结果是___52____ 答DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20 data是一个struct, 每个变量分开占用空间. 依次为int4 DATE20 double8 32. 所以结果是 20 32 52. 当然...在某些16位编辑器下, int可能是2字节,那么结果是 int2 DATE10 double8 20 10、队列和栈有什么区别 队列先进先出栈后进先出 11、写出下列代码的输出内容 #includestdio.h int inc(int a) { return(a); } int multi(int*a,int*b,int*c) { return(*c*a**b); } typedef int(FUNC1)(int in); typedef int(FUNC2) (int*,int*,int*); void show(FUNC2 fun,int arg1, int*arg2) { INCpinc; int temp p(arg1); fun(temp,arg1, arg2); printf(%d\n,*arg2); } main() { int a; show(multi,10,a); return 0; } 答110 12、请找出下面代码中的所以错误 说明以下代码是把一个字符串倒序如“abcd”倒序后变为“dcba” 1、#includestring.h 2、main() 3、{ 4、 char*srchello,world; 5、 char* destNULL; 6、 int lenstrlen(src); 7、 dest(char*)malloc(len); 8、 char* ddest; 9、 char* ssrc[len]; 10、 while(len--!0) 11、 ds--; 12、 printf(%s,dest); 13、 return 0; 14、} 答 方法1 int main() { char* src hello,world; int len strlen(src); char* dest (char*)malloc(len1);//要为\0分配一个空间 char* d dest; char* s src[len-1];//指向最后一个字符 while( len-- ! 0 ) *d*s--; *d 0;//尾部要加\0 printf(%s\n,dest); free(dest);// 使用完应当释放空间以免造成内存汇泄露 return 0; } linux 嵌入式面试 杂集八 2008年10月08日 星期三 12:28 P.M. 程序由多个模块组成所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下可以将所有包含文件预编译为一个预编译头。 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是指针它们指向相同的常量区域。 以下代码中的两个sizeof用法有问题吗 void UpperCase( char str[] ) // 将 str 中的小写字母转换成大写字母 { for( size_t i0; i
http://www.pierceye.com/news/251187/

相关文章:

  • 东莞网站建设价格价格网建企业
  • 做播放器电影网站需要多少钱6网络工程师证
  • dw怎么做网站标题图标网站建设进度表 免费下载
  • 西安哪些做网站的公司好做电子商务网站的意义
  • 圣融网站建设包装设计网站是什么样子的
  • 网站建设的利润设计宝
  • 厦门网站制作案例dede做手机网站
  • 网站建设 环保 图片重庆信息网
  • 做网站的主流软件珠海网站建设珠海
  • 江门市网站建设 熊掌号wordpress分类不显示图片
  • 上海做网站技术有趣的网站小游戏
  • 网站建设需要哪些内容中国建设银行对公网站
  • 网站菜单实现原理全网营销外包
  • 江阴招聘网站建设学徒开源网站开发文档下载
  • 金融网站开发公司六安城市网新闻
  • 什邡网站建设公司linux怎么使用wordpress
  • 安阳网站建设公司网络推广的目标
  • 人像摄影网站有哪些贵阳网站制作企业
  • 山西山西省建设厅网站首页哪个网站做分享赚佣金
  • 曲靖网站制作一条龙赣州章贡区邮政编码是多少
  • 海南省网站设计公司网址百度小说风云榜排名
  • 刷网站关键词排名原理寮步建设网站
  • 银川网站建设一条龙服务服装行业网站模板
  • 重庆建站程序建筑网站起名
  • 便宜网站制作wordpress函数手册
  • 适合在家做的网站工作做音乐网站要求
  • 在哪个网站做视频赚钱的建设彩票网站需要多少投资
  • 大连网站建设意动科技推荐做那个的电影网站
  • 博达 网站群建设wordpress打开乱码
  • 电商网站建设代理商定制网站开发介绍图