2016 腾讯软件开发面试题(部分)

nuws6854 2年前
   <h2>一、前言</h2>    <p>这篇文章是 2016 腾讯软件开发面试题中不定项选择题集合中的 1 -12 题,其中后面的 13-25题在下周的博客中写,说明一下,这篇文章跟以往的每周一题有点不同,因为如果选择一两题,文章的边幅有点少,而且选择题相对来说,难度没那么大,更主要的是为了让大家全面的感受一下腾讯的面试题。</p>    <h2>二、2016 腾讯软件开发面试题(不定项选择题【1-12】)</h2>    <p>1、已知一棵二叉树,如果先序遍历的节点顺序是: ADCEFGHB ,中序遍历是: CDFEGHAB ,则后序遍历结果为:( )</p>    <p>A. CFHGEBDA</p>    <p>B. CDFEGHBA</p>    <p>C. FGHCDEBA</p>    <p>D. CFHGEDBA</p>    <p>知识点</p>    <p>对于二叉树的遍历方式一般分为三种先序、中序、后序三种方式:</p>    <ul>     <li>先序遍历(根左右)<br> 若二叉树为空,则不进行任何操作:否则<br> 1、访问根结点。<br> 2、先序方式遍历左子树。<br> 3、先序遍历右子树。</li>     <li>中序遍历 (左根右)<br> 若二叉树为空,则不进行任何操作:否则<br> 1、中序遍历左子树。<br> 2、访问根结点。<br> 3、中序遍历右子树。</li>     <li>后序遍历 (左右根)<br> 若二叉树为空,则不进行任何操作:否则<br> 1、后序遍历左子树。<br> 2、后序遍历右子树。<br> 3、放问根结点。</li>    </ul>    <p>因此,根据题目给出的先序遍历和中序遍历,可以画出二叉树:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/adf9802f41a6b85efb1f90100aa51699.png"></p>    <p>二叉树遍历.png</p>    <p>最后结果选择: D</p>    <p>2、下列哪两个数据结构,同时具有较高的查找和删除性能?( )</p>    <p>A. 有序数组</p>    <p>B. 有序链表</p>    <p>C. AVL 树</p>    <p>D. Hash 表</p>    <p>知识点</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/bf2b3bb9db28ddbf7fb8cd1f6e14cbf2.png"></p>    <p>几种常见的数据结构操作性能.png</p>    <p>平衡二叉树的查找,插入和删除性能都是 O(logN) ,其中查找和删除性能较好;哈希表的查找、插入和删除性能都是 O(1) ,都是最好的。所以最后的结果选择: CD</p>    <p>3、下列排序算法中,哪些时间复杂度不会超过 nlogn?( )</p>    <p>A. 快速排序</p>    <p>B. 堆排序</p>    <p>C. 归并排序</p>    <p>D. 冒泡排序</p>    <p>知识点</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/1ac7c0fbf8ec5093d1214e78140860fe.png"></p>    <p>几种常见的排序算法对比.png</p>    <p>根据上图,观察平均情况,最好最差情况的时间复杂度基本可以知道答案了,最后结果选择: BC</p>    <p>4、初始序列为 1 8 6 2 5 4 7 3 一组数采用堆排序,当建堆(小根堆)完毕时,堆所对应的二叉树中序遍历序列为:( )</p>    <p>A. 8 3 2 5 1 6 4 7</p>    <p>B. 3 2 8 5 1 4 6 7</p>    <p>C. 3 8 2 5 1 6 7 4</p>    <p>D. 8 2 3 5 1 4 7 6</p>    <p>初始化序列:1 8 6 2 5 4 7 3,,小根堆就是要求结点的值小于其左右孩子结点的值,左右孩子的大小没有关系,那么小根堆排序之后为:1 2 4 3 5 6 7 8;</p>    <p>中序遍历:左根右,故遍历结果为:8 3 2 5 1 6 4 7</p>    <p>故最后选择的结果: A</p>    <p>5、当 n = 5 时,下列函数的返回值是:( )</p>    <pre>  [cpp] viewplaincopy  int foo(int n)    {        if(n<2)return n;        return foo(n-1)+foo(n-2);    }  </pre>    <p>A.5</p>    <p>B.7</p>    <p>C.8</p>    <p>D.1</p>    <p>这题只需把数代进去,就可以知道结果了,所以最后结果选: A</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/fc0dabac3517676debf88cd789e4d1f0.png"></p>    <p>递归.png</p>    <p>6、 S 市 A ,B 共有两个区,人口比例为 3:5 ,据历史统计 A 区的犯罪率为 0.01% ,B 区为 0.015% ,现有一起新案件发生在 S 市,那么案件发生在 A 区的可能性有多大?( )</p>    <p>A.37.5%</p>    <p>B.32.5%</p>    <p>C.28.6%</p>    <p>D.26.1%</p>    <p>这道题首先得了解犯罪率是什么?犯罪率就是犯罪人数与总人口数的比。因此可以直接得出公式:( 3 <em>0.01% ) / ( 3</em> 0.01% + 5 * 0.015% ) = 28.6%</p>    <p>当然如果不好理解的话,我们可以实例化,比如 B 区假设 5000 人,A 区 3000 人,A 区的犯罪率为 0.01%,那么 A 区犯罪人数为 30 人,B 区的犯罪率为 0.015% ,那么 B 区的犯罪人数为 75 人 ,求发生在 A 区的可能性,就是说 A 区的犯罪人数在总犯罪人数的多少,也就是 30/(30+75)=0.2857</p>    <p>当然,也可以回归到我们高中遗忘的知识:</p>    <p>假设C表示犯案属性</p>    <p>在A区犯案概率:P(C|A)=0.01%</p>    <p>在B区犯案概率:P(C|B)=0.015%</p>    <p>在A区概率:P(A)=3/8</p>    <p>在B区概率:P(B)=5/8</p>    <p>犯案概率:P(C)=(3/8 <em>0.01%+5/8</em> 0.015%)</p>    <p>根据贝叶斯公式:P(A|C) = P(A,C) / P(C) = [P(C|A) P(A)] / [ P(C|A) P(A)+ P(C|B) P(B) ] 也可以算出答案来</p>    <p>故,最后结果选择为: C</p>    <p>7、Unix系统中,哪些可以用于进程间的通信?( )</p>    <p>A.Socket</p>    <p>B.共享内存</p>    <p>C.消息队列</p>    <p>D.信号量</p>    <p>知识点</p>    <ol>     <li>管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;</li>     <li>信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数);</li>     <li>报文(Message)队列(消息队列):消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。</li>     <li>共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。<br> 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。</li>     <li>套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。</li>    </ol>    <p>故最后选择的结果为: ABCD</p>    <p>8、静态变量通常存储在进程哪个区?( )</p>    <p>A.栈区</p>    <p>B.堆区</p>    <p>C.全局区</p>    <p>D.代码区</p>    <p>静态变量的修饰关键字:static,又称静态全局变量。故最后选择的结果为: C</p>    <p>9、查询性能( )</p>    <p>A. 在Name字段上添加主键</p>    <p>B. 在Name字段上添加索引</p>    <p>C. 在Age字段上添加主键</p>    <p>D. 在Age字段上添加索引</p>    <p>结果选: B</p>    <p>10、IP地址131.153.12.71是一个(B)类IP地址。</p>    <p>A.A</p>    <p>B.B</p>    <p>C.C</p>    <p>D.D</p>    <p>知识点</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/89342b546855e4c42b8682092317951c.png"></p>    <p>IP地址分类.png</p>    <p>故将 131 转为二进制 :10000011,因此为 B 类 IP 地址,结果选 B</p>    <p>11、下推自动识别机的语言是:(C)</p>    <p>A.0型语言</p>    <p>B.1型语言</p>    <p>C.2型语言</p>    <p>D.3型语言</p>    <p>知识点</p>    <p>这是有关编译原理的。</p>    <p>乔姆斯基体系是计算机科学中刻画形式文法表达能力的一个分类谱系,是由诺姆·乔姆斯基于1956年提出的。它包括四个层次:</p>    <ul>     <li>0-型文法(无限制文法或短语结构文法)包括所有的文法。该类型的文法能够产生所有可被图灵机识别的语言。可被图灵机识别的语言是指能够使图灵机停机的字串,这类语言又被称为递归可枚举语言。注意递归可枚举语言与递归语言的区别,后者是前者的一个真子集,是能够被一个总停机的图灵机判定的语言。</li>     <li>1-型文法(上下文相关文法)生成上下文相关语言。这种文法的产生式规则取如 αAβ -> αγβ 一样的形式。这里的A 是非终结符号,而 α, β 和 γ 是包含非终结符号与终结符号的字串;α, β 可以是空串,但 γ 必须不能是空串;这种文法也可以包含规则 S->ε ,但此时文法的任何产生式规则都不能在右侧包含 S 。这种文法规定的语言可以被线性有界非确定图灵机接受。</li>     <li>2-型文法(上下文无关文法)生成上下文无关语言。这种文法的产生式规则取如 A -> γ 一样的形式。这里的A 是非终结符号,γ 是包含非终结符号与终结符号的字串。这种文法规定的语言可以被非确定下推自动机接受。上下文无关语言为大多数程序设计语言的语法提供了理论基础。</li>     <li>3-型文法(正规文法)生成正规语言。这种文法要求产生式的左侧只能包含一个非终结符号,产生式的右侧只能是空串、一个终结符号或者一个非终结符号后随一个终结符号;如果所有产生式的右侧都不含初始符号 S ,规则 S -> ε 也允许出现。这种文法规定的语言可以被有限状态自动机接受,也可以通过正则表达式来获得。正规语言通常用来定义检索模式或者程序设计语言中的词法结构。</li>    </ul>    <p>正规语言类包含于上下文无关语言类,上下文无关语言类包含于上下文相关语言类,上下文相关语言类包含于递归可枚举语言类。这里的包含都是集合的真包含关系,也就是说:存在递归可枚举语言不属于上下文相关语言类,存在上下文相关语言不属于上下文无关语言类,存在上下文无关语言不属于正规语言类。</p>    <p>四种类型的文法的主要特点:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/28b91f0a3aa92cfa313116c2053e4f44.png"></p>    <p>四种类型的文法的主要特点.png</p>    <p>因此答案选择:B</p>    <p>12、下列程序的输出是:( )</p>    <pre>  [cpp] viewplaincopy  #define add(a+b) a+b    int main()    {        printf(“%dn”,5*add(3+4));        return ;    }  </pre>    <p>A.23</p>    <p>B.35</p>    <p>C.16</p>    <p>D.19</p>    <p>因为我主要是 java 开发的,可是毕竟 c 和 c++ 都是大学的必修课,因此还是有点了解的。这里主要看清楚 define ,#define 的本质就是一个代换,题目 #define add(a+b) a+b 表明了 add(a+b) 替换成 a+b ,因此代码输出的那一行其实是 printf(“%dn”,5*3+4); ,所以最后的结果选择 D</p>    <h2> </h2>    <p> </p>    <p>来自:http://blog.jobbole.com/110287/</p>    <p> </p>