程序员面试宝典.pdf
《程序员面试宝典.pdf》由会员分享,可在线阅读,更多相关《程序员面试宝典.pdf(212页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、 程序员面霸手册程序员面霸手册程序员面霸手册程序员面霸手册 VER 1.3 黄优黄优黄优黄优 2009.10 3前前前前 言言言言 本人计算机专业毕业,找工作厉尽艰辛,面尽无数公司,深感怀才不遇,整理前人心血,以成此书。为了让后人少走我的路,把自己遇到的一些问题,以及网上一些朋友的程序员面试笔试题以及一些在面试笔试中的重要知识点都写出来同大家分享。其中有些题目已经做了答案,而有些答案在后边的知识点里已经注明,要读者自行寻找。把这些题目和知识点整理成本册子,欢迎大家来信推荐一些在自己面试笔试中遇到的问题,以完善此书,不胜感激。此书闲来所做,只期望能对后来者起到一定帮助。此电子版,免费无限分发,请
2、勿用于商业目的,违者必究。如果你觉得好的话,将他分享给更多的朋友朋友。书中难免出现错误和不足,还望不吝赐教,如果你在笔试或者面试中遇到了此册中没有遇到的问题,可以发电子邮件或者在本书官网给我留言,希望能把大家遇到的问题收集在一起,不胜感激。希望大家一起交流,大家帮大家,大家都能找到一个自己喜欢和满意的工作。我的电子邮件:,QQ,QQ,QQ,QQ:1:1:1:1140603739140603739140603739140603739,本书永久性官网:httphttphttphttp:/ 处获取本书所有信息。2009.3 黄黄黄黄优优优优于西安于西安于西安于西安 4版权声明版权声明版权声明版权声明
3、 此书之电子版免费,可任意分发传播,但需保持本书完整性,书中内容禁止用于商业目的,如需要修改或因商业目的使用本书需联系作者本人,email:。未经授权非法利用本书用于商业目的将受严厉惩处。5版版版版本本本本更新更新更新更新说明说明说明说明 版本版本版本版本 更更更更新内容新内容新内容新内容 备注备注备注备注 v1.0(09.03)无 创建 v1.1(09.04)1.增加了操作系统部分。2.数据结构部分增加了 ADT 的实现代码。3.数据结构部分增加了 KMP 排序算法。4.增加附录一 ASCII 码表。5.增加了附录二 ADO.NET 连接字符串。6.增加了附录二 ADO.NET 连接字符串。
4、7.第四部分增加使用.NET 访问 MySql 数据库。8.java 有几道题目做了答案。9.数据库部分新增几道华为公司问答题目。10.修正一些小的疏忽和错误。更新及维护 v1.2 1.对知识点精华部分做了索引,方便信息查阅,并且对原来档案做了简化,以保持本书的简单易读性。2.整理内容,对内容进行了详细分类,并修改了分类,使框架简明易懂。更改 v1.2(09.10)1.修正了书中部分错误。2.补充部分答案。6目 录 第一部分 数据结构.7 A.笔试面试题集.7 B.知识点精华.17 第二部分 C/C+.26 A.笔试面试题集.26 B.知识点精华.84 第三部分 JAVA.103 A.笔试面试
5、题集.103 B.知识点精华.129 第四部分.NET.137 A.笔试面试题集.137 B.知识点精华.146 第五部分 数据库.179 A.笔试面试题集.179 B.知识点精华.192 第六部分 操作系统.203 A.笔试面试题集.203 附录一 ASCII码表.212 7 第一部分第一部分第一部分第一部分 数据结构数据结构数据结构数据结构 A.笔试面试题集笔试面试题集笔试面试题集笔试面试题集 1.在一个单链表中 p 所指结点之前插入一个 s(值为 e)所指结点时,可执行如下操作:q=head;while(q-next!=p)q=q-next;s=new Node;s-data=e;q-n
6、ext=_ s_;s-next=_ p_;备注:此题在以前版本中有错误,多谢朋友们指正。2.线性表的顺序存储结构是一种 A 的存储结构,而链式存储结构是一种 C 的存储结构。A随机存取 B索引存取 C顺序存取 D散列存取 3.线性表若采用链式存储结构时,要求内存中可用存储单元的地址_D _。A.必须是连续的 B.部分地址必须是连续的 C.一定是不连续的 D.连续或不连续都可以 4.在一个单链表中,已知 q 所指结点是 p 所指结点的前驱结点,若在 q 和 p 之间插入 s结点,则执行_。A.s-next=p-next;p-next=s;B.p-next=s-next;s-next=p;C.q-
7、next=s;s-next=p;D.p-next=s;s-next=q;5.在一个单链表中,若p所指结点不是最后结点,在p之后插入s所指结点,则执行 。A.s-next=p;p-next=s;B.s-next=p-next;p-next=s;C.s-next=p-next;p=s;C.p-next=s;s-next=p;6.在一个单链表中,若删除 p 所指结点的后续结点,则执行 。A.p-next=p-next-next;B.p=p-next;p-next=p-next-next;C.p-next=p-next;D.p=p-next-next;7.链表不具备的特点是_A_。A 可随机访问任何一
8、个元素 B 插入、删除操作不需要移动元素 C 无需事先估计存储空间大小 D 所需存储空间与线性表长度成正比 8注:链表是顺序结构,必须顺序访问。8.以下关于线性表的说法不正确的是 。A 线性表中的数据元素可以是数字、字符、记录等不同类型。B 线性表中包含的数据元素个数不是任意的。C 线性表中的每个结点都有且只有一个直接前趋和直接后继。D 存在这样的线性表:表中各结点都没有直接前趋和直接后继。9.在一个长度为 n 的顺序表中删除第 i 个元素,要移动 n-i 个元素。如果要在第 i 个元素前插入一个元素,要后移 n-i+1 个元素。10.栈操作数据的原则是 后进先出,队列操作数据的原则是 先进先
9、出。11.在栈中,可进行插入和删除操作的一端称 栈顶。12.栈和队列都是_非线性_结构;对于栈只能在 栈顶 插入和删除元素;对于队列只能在_队头_插入元素和 队尾 删除元素。13.通常采用的两种存储结构是 和 。14.计算机在运行递归程序时,要用到 编译器 提供的栈。15.一个栈的入栈序列 a,b,c,d,e,则栈的不可能的输出序列是_ C 。A.edcba B.decba C.dceab D.abcde 注:此题的难点在于不必考虑完全入完后再出栈,可以边入边出,也可以入几个再出。16.一个队列的数据入列序列是 1,2,3,4,则队列的出队时输出序列是_ B _。A.4,3,2,1 B.1,2
10、,3,4 C.1,4,3,2 D.3,2,4,1 17.判断一个表达式中左右括号是否匹配,采用 _D_ 实现较为方便。A 线性表的顺序存储 B 队列 C 线性表的链式存储 D 栈 18.栈与一般线性表区别主要在方面 C。A 元素个数 B 元素类型 C 逻辑结构 D 插入、删除元素的位置 19.“假上溢”现象会出现在 D 中。A 循环队列 B 队列 C 链队列 D 顺序队列 注:假上溢是由于头尾指针不断前移超出向量空间。20.在一个链队中,假设 F 和 R 分别是队首和队尾指针,则删除一个结点的运算是 C 。A R=F-next;B R=R-next;C F=F-next;D F=R-next;
11、21.表达式 a*(b+c)-d 的后缀表达式是 B。Aabcd*+-B.abc+*d-C.abc*+d-D.-+*abcd 9 注:-a(b+c)*d-abc*+d-22.判断链表是否存在环型链表问题:判断一个链表是否存在环,例如下面这个链表就存在一个环:例如 N1-N2-N3-N4-N5-N2 就是一个有环的链表,环的开始结点是 N5 这里有一个比 较简单的解法。设置两个指针 p1,p2。每次循环 p1 向前走一步,p2 向前走两步。直到 p2 碰到 NULL 指针或者两个指针相等结束循环。如果两个指针相等则说明存在环。struct link int data;link*next;bool
12、 IsLoop(link*head)link*p1=head,*p2=head;if(head=NULL|head-next=NULL)/该链表没有节点或者只有一个节点,则不用判断.return false;/先循环,再判断 do p1=p1-next;/p1 前进一步 p2=p2-next-next;/p2 前进一步 while(p2&p2-next&p1!=p2);/p2 不为空,p2 的下个节点不为空,p1 不等于 p2 继续循环,否则退出。/p2 为空则 p1p2 不相等则不存在环,p1=p2 则存在环 if(p1=p2)return true;else return false;23
13、.链表反转 单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题。比如一个链表是这样的:1-2-3-4-5 通过反转后成为 5-4-3-2-1。最容易想到的方法遍历一遍链表,利用一个辅助指针,存储遍历过程中当前指针指向的下一个元素,然后将当前节点元素的指针反转后,利用已经存储的指针往后面继续遍历。源代码如下:struct linka int data;linka*next;10 void reverse(linka*&head)if(head=NULL)/链表为空 return;linka*pre,*cur,*ne;pre=head;cur=head-next;while(cur
14、)ne=cur-next;cur-next=pre;pre=cur;cur=ne;head-next=NULL;head=pre;还有一种利用递归的方法。这种方法的基本思想是在反转当前节点之前先调用递归 函数反转后续节点。源代码如下。不过这个方法有一个缺点,就是在反转后的最后 一个结点会形成一个环,所以必须将函数的返回的节点的 next 域置为 NULL。因为 要 改变 head 指针,所以我用了引用。算法的源代码如下:linka*reverse(linka*p,linka*&head)if(p=NULL|p-next=NULL)head=p;return p;else linka*tmp=r
15、everse(p-next,head);tmp-next=p;return p;24.判断两个数组中是否存在相同的数字 给定两个排好序的数组,怎样高效得判断这两个数组中存在相同的数字?这个问题首先最直接能想到的是一个 O(nlogn)的算法。就是任意挑选一个数组,遍历 这个数组的所有元素,遍历过程中,在另一个数组中对第一个数组中的每个元素进行 binary search。用 C+实现代码如下:bool findcommon(int a,int size1,int b,int size2)int i;11 for(i=0;isize1;i+)int start=0,end=size2-1,mid
16、;while(start=end)mid=(start+end)/2;if(ai=bmid)return true;else if(aibmid)end=mid-1;else start=mid+1;return false;有一个 O(n)算法。首先设两个下标,分别初始化为两个数组的起始地址,依次向 前推进。推进的规则是比较两个数组中的数字,小的那个数组的下标向前推进一步,直到任何一个数组的下标到达数组末尾时,如果这时还没碰到相同的数字,说明数组 中没有相同的数字。bool findcommon2(int a,int size1,int b,int size2)int i=0,j=0;whi
17、le(isize1&jbj)j+;if(aibj)i+;return false;25.最大子序列问题:给定一整数序列 A1,A2,.An(可能有负数),求 A1An 的一个子序列 AiAj,使 得 Ai 到 Aj 的和最大 例如:整数序列-2,11,-4,13,-5,2,-5,-3,12,-9 的最大子序列的和为 21。对于这个问题,最简单也是最容易想到的那就是穷举所有子序列的方法。利用三重循环,依次求出所有子序列的和然后取最大的那个。当然算法复杂度会达到 O(n3)。显然这 种方法不是最优的,下面给出一个算法复杂度为 O(n)的线性算法实现,算法的来源于 Programming Pearl
18、s 一书。在给出线性算法之前,先来看一个对穷举算法进行优化的 12 算法,它的算法复杂度为 O(n2)。其实这个算法只是对对穷举算法稍微做了一些修改:其实子序列的和我们并不需要每次都重新计算一遍。假设 Sum(i,j)是 Ai.Aj 的和,那么 Sum(i,j+1)=Sum(i,j)+Aj+1。利用这一个递推,我们就可以得到 下面这个算法:int max_sub(int a,int size)int i,j,v,max=a0;for(i=0;isize;i+)v=0;for(j=i;jmax)max=v;return max;那怎样才能达到线性复杂度呢?这里运用动态规划的思想。先看一下源代码实
19、现:int max_sub2(int a,int size)int i,max=0,temp_sum=0;for(i=0;imax)max=temp_sum;else if(temp_sumnext=NULL)return head;do p1=p1-next;p2=p2-next-next;while(p2&p2-next);return p1;27.已知一个单向链表的头,请写出删除其某一个结点的算法,要求,先找到此结点,然后删除。slnodetype*Delete(slnodetype*Head,int key)中 if(Head-number=key)Head=Pointer-next;
20、free(Pointer);break;Back=Pointer;Pointer=Pointer-next;if(Pointer-number=key)Back-next=Pointer-next;free(Pointer);break;void delete(Node*p)if(Head=Node)while(p)28.判断一个字符串是不是回文 int IsReverseStr(char*aStr)int i,j;int found=1;if(aStr=NULL)return-1;j=strlen(aStr);for(i=0;ij/2;i+)if(*(aStr+i)!=*(aStr+j-i-
21、1)found=0;14 break;return found;注:回文是指某个串或者数字无论从左向右还是从右向左都一样。29.用两个栈实现一个队列的功能?要求给出算法和思路!设 2 个栈为 A,B,一开始均为空 入队:将新元素 push 入栈 A;出队:(1)判断栈 B 是否为空;(2)如果不为空,则将栈 A 中所有元素依次 pop 出并 push 到栈 B;(3)将栈 B 的栈顶元素 pop 出。30.Josephu 问题为:设编号为 1,2,n 的 n 个人围坐一圈,约定编号为 k(1=k=n)的人从 1 开始报数,数到 m 的那个人出列,它的下一位又从 1 开始报数,数到 m 的那个人
22、又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。数组实现:#include#include int Josephu(int n,int m)int flag,i,j=0;int*arr=(int*)malloc(n*sizeof(int);for(i=0;i n;+i)arri=1;for(i=1;i n;+i)flag=0;while(flag m)if(j=n)j=0;if(arrj)+flag;+j;arrj-1=0;printf(第%4d 个出局的人是:%4d 号n,i,j);free(arr);return j;15 int main()int n,m;scanf(
23、%d%d,&n,&m);printf(最后胜利的是%d 号!n,Josephu(n,m);system(pause);return 0;链表实现:#include#include typedef struct Node int index;struct Node*next;JosephuNode;int Josephu(int n,int m)int i,j;JosephuNode*head,*tail;head=tail=(JosephuNode*)malloc(sizeof(JosephuNode);for(i=1;i index=i;tail-next=(JosephuNode*)mal
24、loc(sizeof(JosephuNode);tail=tail-next;tail-index=i;tail-next=head;for(i=1;tail!=head;+i)for(j=1;j next;tail-next=head-next;printf(第%4d 个出局的人是:%4d 号n,i,head-index);free(head);head=tail-next;i=head-index;free(head);return i;16 int main()int n,m;scanf(%d%d,&n,&m);printf(最后胜利的是%d 号!n,Josephu(n,m);syste
25、m(pause);return 0;31.排序二叉树插入一个节点或双向链表的实现 32.问答题:1)什么是平衡二叉树?左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于 1 2)堆栈溢出一般是由什么原因导致的?没有回收垃圾资源 3)数组和链表的区别 数组:数据顺序存储,固定大小 链表:数据可以随机存储,大小可动态改变 4)冒泡排序算法的时间复杂度是什么?O(n2)17 B.知识点精华知识点精华知识点精华知识点精华 1.big endian,little endian big endian 是指低地址存放最高有效字节(MSB),而 little endian 则是低地址存放最低有效字节(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序员 面试 宝典
限制150内