参考:http://blog.csdn.net/hackbuteer1/article/details/11931173
下面的标注【分析】是我给出的。
第一部分单选题(前10题,每题2分;后10题,每题3分,共50分,选对得满分,选错倒扣1分,不选得0分)
1、假设把整数关键码K散列到有N个槽的散列表,以下哪些散列函数是好的散列函数()
A、h(K)=K mod N;
B、h(K)=1;
C、h(K)=K/N;
D: h(K)=(K+rand(N)) mod N, rand(N)返回一个0到N-1的整数
【分析】:《算法导论》中P202关于“好的散列函数的定义”:每个key最大程度等可能的散列到任意一个slot中。加入随机化偏移量可以减少冲突的期望,极端情况是一堆相同的待散列key。
2. 下面排序算法中,初始数据集的排列顺序对算法的性能无影响的是()
A、堆排序 B、插入排序
C、冒泡排序 D、快速排序
3、下面说法错误的是:
A、CISC计算机比RISC计算机指令多
B、冯诺依曼机体系结构的主要特征是存储程序的工作方式
C、增加流水线段数理论上可以提高CPU频率
D、在指令格式中,采用扩展操作码设计方案的目的是为了保持指令字长不变而增加寻址空间
【分析】:
精简指令集计算机(RISC)只包含复杂指令集计算机(CISC)中使用频率很高的少量指令。
CPU流水线长度越长,运算工作就越简单,处理器的工作频率就越高,不过CPU的效能就越差,所以说流水线长度并不是越长越好的。
扩展操作码会使得指令变长,寻址空间变小。
4、不属于冯诺依曼机体系结构必要组成部分的是:
A、CPU B、Cache C、RAM D、ROM
【分析】:冯诺依曼5大组成:运算器、控制器、存储器、输入设备和输出设备。
5、一个栈的入栈序列式ABCDE,则不可能的出栈序列是:
A、DECBA B、DCEBA C、ECDBA D、ABCDE
6.你认为可以完成编写一个C语言编译器的设计语言是:
A、汇编语言 B、C语言 C、VB语言 D、以上皆可
7. 关于C++/JAVA类中的static成员和对象成员的说法正确的是:
A、虚成员函数不可能是static成员函数
B、static成员函数在对象成员函数中无法调用
C、static成员变量在对象构造时生成
D、static成员函数不能访问static成员变量
8、
C、13个
【分析】:将图中补全了的话,从A到Z要经过4次向右2次向下,即=15次,去掉2条路线即可。
9、某进程在运行过程中需要等待从磁盘上读入数据,此时该进程的状态将:
A、从就绪变为运行 B、从运行变为就绪
C、从运行变为阻塞 D、从阻塞变为就绪
10、下面算法的时间复杂度为:
1. int f(unsigned int n)
2. {
3. if(n == 0 || n == 1)
4. return 1;
5. else
6. return n*f(n-1);
7. }
A、O(1) B、O(n) C、O(N*N) D、O(n!)
11、n从1开始,每个操作可以选择对n加1或者对n加倍。若想获得整数2013,最少需要多少个操作。
A、24 B、21 C、18 D、不可能
12、对于一个具有n个顶点的无向图,若采用邻接表数据结构表示,则存放表头节点的数组大小为:
A、n B、n+1 C、n-1 D、n+边数
14:如下函数,在32bit系统foo(2^31-3)的值是:
1. int foo(int x)
2. {
3. return x&-x;
4. }
A、0 B、1 C、2 D、4
【分析】:写的小一点,2^7-3=[0111 1101]补码,-(2^7)=[1111 1101]原码=[0000 0010]反码=[0000 0011]补码
15、对于顺序存储的线性数组,访问节点和增加、删除节点的时间复杂度为:
A、O(n),O(n) B、O(n),O(1) C、O(1),O(n) D、O(1),O(1)
16、在32位系统环境中,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是:
1. struct A
2. {
3. int a;
4. short b;
5. int c;
6. char d;
7. };
8. struct B
9. {
10. int a;
11. short b;
12. char d;
13. int c;
14.};
A、16,16 B、16,12 C、13,12 D、11,16
17、袋中有红球,黄球,白球各一个,每次任意取一个又放回,如此连续抽取3次,则下列事件中概率是8/9的是:
A、颜色不全相同 B、颜色全相同 C、颜色全不同 D、颜色无红色
【分析】:三次都取出红球的概率:1/27,三次都相同的概率:3/27。
18、一个洗牌程序的功能是将n张牌的顺序打乱,以下关于洗牌程序的功能定义说法最恰当的是:
A、任何连续位置上的两张牌的内容独立
B、n张牌的任何两个不同排列出现的概率相等
C、每张牌出现在n个位置上的概率相等
D、每张牌出现在n个位置上的概率独立
19、用两种颜色去染排成一个圈的6个棋子,如果通过旋转得到则只算一种,一共有多少种染色模式。
A、10 B、14 C、15 D、16
【分析】:组合数学中经典问题,polya定理来解答。这里用一般方法。颜色为A和B。可以分为以下六种情况。
6A——1种
5A1B——1种
4A2B——4A围城一圈有4个空位,如果2B在一起放入任意一个,其他情况可以通旋转达到,有一种;如果2B分别放在一个空位,其他情况可以通旋转达到,有两种。共计3种。
3A3B——3A围城一圈有3个空位,3B一起放在任意一个位置,其他情况可以通旋转达到,有一种;3B分成2B、B放在两个空位,其他情况可以通旋转达到,有两种;3B分别放在三个位置,有一种。共计4种。
2A4B——3种。
1A5B——1种。
6B——1种。
共计:14种
20、递归式的先序遍历一个n节点,深度为d的二叉树,则需要栈空间的大小为:
A: O(logn) B:O(nlogn) C:O(n) D:(d)
第二部分不定向选项(4题,每题5分,完全正确计5分,漏选计2分,不选计0分,多选、错选计-2分)
21、两个线程运行在双核机器上,每个线程主线程如下,线程1:x=1;r1=y;线程2:y=1;r2=x;
x和y是全局变量,初始为0。以下哪一个是r1和r2的可能值:
A、r1=0,r2=0
B、r1=1,r2=0
C、r1=1,r2=1
D、r1=0,r2=1
22、关于Linux系统的负载(Load),以下表述正确的是:
A: Load:2.5,1.3,1.1表示系统的负载压力在逐渐减小
B: 通过就绪和运行的进程数来反映
C: 通过TOP命令查看
D: 通过uptime查看
23、关于排序算法的以下说法,错误的是:
A、归并排序的平均时间复杂度O(nlogn),最坏时间复杂度O(n^2)
B、堆排序平均时间复杂度O(nlogn),最坏时间复杂度O(nlogn)
C、冒泡排序平均时间复杂度O(n^2),最坏时间复杂度O(n^2)
D、快速排序的平均时间复杂度O(nlogn),最坏时间复杂度O(N^2)
24、假设函数rand_k会随机返回一个【1,k】之间的随机数(k>=2),并且每个证书出现的概率相等。目前有rand_7,通过调用rand_7()和四则运算符,并适当增加逻辑判断和循环控制逻辑,下列函数可以实现的有:
A、rand_3 B、rand_21 C、rand_23 D、rand_47
【分析】:可以实现任意的rand_k,参看本博客内容【腾讯2011.10.15校园招聘笔试题】分析1——random7生成random10。
第三部分填空与问答
25、某二叉树的前序遍历序列为-+a*b-cd/ef,后序遍历序列为abcd-*+ef/-,问其中序遍历序列是:
答案: a+b*c-d-e/f
26、某缓存系统采用LRU淘汰算法,假定缓存容量为4,并且初始为空,那么在顺序访问以下数据项的时候,1、5、1、3、5、2、4、1、2,出现缓存直接命中的次数是(),最后缓存中即将准备淘汰的数据项是()
参考:http://yjbys.com/bishi/timu/573905_2.html#
答案:3,3
解释:(LRU是Least Recently Used 近期最少使用算法。首先1调入内存,然后5调入内存,然后1调入内存(命中缓存),然后3调入内存,然后2调入内存,然后4调入内存(将最少使用的5置换出内存),然后1调入内存(命中缓存),然后2调入内存(命中缓存)。最后,最少使用的3将面临被置换出的危险。
27 、有两个较长的单向链表 a 和 b ,为了找出节点 node 满足 node in a 并且 node in b ,请设计空间使用尽量小的算法。(用 C/C++/JAVA 或伪码表示都可以)
【分析】:单链表求交点问题,参看本博客【算法导论学习-23】两个单链表(single linked)求交点。
28 、当存储数据量超出单节点数据管理能力的时候,可以采取的办法有数据库 sharding 的解决方案,也就是按照一定的规律把数据分散存储在多个数据管理节点 N 中(节点编号 0.1.2...N-1 )。假设存储的数据是 a ,请完成为数据 a 计算存储节点的程序。(没学过 C 语言的同学也可以用伪码完成)
参考答案看不明白,如下:
1. #define N 5
2. int hash(int element)
3. {
4. return element*2654435761;
5. }
6. int shardingIndex(int a)
7. {
8. int p = hash(a);
9. //1
10. return p;
11. }
空格1处: p %= N;
29、宿舍内5个同学一起玩对战游戏,每场比赛有一些人作为红方,另一些人作为蓝方,请问至少需要多少场比赛,才能使任意两个人之间有一场红方对蓝方和一场蓝方对红方的比赛?
答案:4场。
第四部分 JAVA选做题
1、以下每个线程输出的结果是什么?(不用关注输出的顺序,只需写出输出的结果集即可)
/** * 创建时间:2014年8月27日 上午11:16:57 * 项目名称:Test * @author Cao Yanfeng * @since JDK 1.6.0_21 * 类说明: 测试Thread的interrupt()方法 */ public class TestThread { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub final Thread t1 = new Thread() { @Override public void run() { // TODO Auto-generated method stub try { int i = 0; while (i++ < 100000000) { // nothing } System.out.println("A1"); } catch (Exception e) { // TODO: handle exception System.out.println("B1"); } } }; t1.start(); t1.interrupt(); Thread t2 = new Thread() { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep(5000); System.out.println("A2"); } catch (Exception e) { // TODO: handle exception System.out.println("B2"); } } }; t2.start(); Thread t3 = new Thread() { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep(50000); System.out.println("A3"); } catch (Exception e) { // TODO: handle exception System.out.println("B3"); } } }; t3.start(); t3.interrupt(); Thread t4 = new Thread() { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep(5); System.out.println("A4"); } catch (Exception e) { // TODO: handle exception System.out.println("B4"); } } }; t4.start(); t4.interrupt(); try { t4.start(); System.out.println("A5"); } catch (Exception e) { // TODO: handle exception System.out.println("B5"); } } }
*********************************************************************************************
输出:A1 A2 B3 B4 B5【分析】:线程调用interrupt()仅仅对线程设置了中断标记,线程的run()方法中的sleep()方法会检测到中断并抛出异常。t1、t2正常执行run(),而t3、t4输出异常信息,另外,如果一个线程执行完毕(不论是正常还是抛出异常),不管该线程是否isAlieve(),再次调用start()方法都会抛出异常,只能再次new一个新的thread。
2、一个有10亿条记录的文本文件,已按照关键字排好序存储,请设计算法,可以快速的从文件中查找关键字的记录。
参考:http://blog.sina.com.cn/s/blog_62ef85c20101mj3a.html
答案:10亿在 G量级, 分成100份, 为10M量级, 基本上放入内存无压力了.
在这10亿记录中, 均分为100份, 把每份的第一条记录关键字和此记录对应的文件偏移量先扫入内存(类似索引), 这里需要磁盘随机io 100次.
这样可以马上定位出指定关键字所在的记录块, 把相应的记录块拿到内存, 二分查找即可.
C++选做题略