阿里巴巴2014校招笔试题-2013年9月14日

参考:http://flyown34317.blog.163.com/blog/static/19707301620139112402917/

 

 

1 假设把整数关键码K散列到有N个槽的散列表,以下哪些散列函数是好的

A、h(k)= k/N

B、h(k)   =1;

C、h(k)=kmod N

D、h(k)= (K+Random(N)) modN,Random(N)返回0-N-1的整数,

2 下面的排序算法中.初始数据集的排列顺序对算法的性能无影响的是

A 堆排序

B 冒泡排序

C、插入排序

D、快速排序

 

 

3.下面说法错误的是_。

A、ClSC计算机比RISC计算机指令多

B、在指令格式中,采用扩展操作码设计方案的目的是为了保持指令字长度而增加寻址空间.

C、增加流水线段数理论上可以提高CPU频率

D、冯.诺依曼机体系结构的主要特征是存储程序的工作方式

4.不属于冯.诺依曼机体系结构必要组成部分的是_。

A、CPU B、Cache C、RAM D、ROM

输入数据和程序的输入设备
记忆程序和数据的存储器
完成数据加工处理的运算器
控制程序执行的控制器
输出处理结果的输出设备

 

 

5.一个栈的入栈序列为ABCDE则不可能的输出序列为_。

A、DECBA  B、DCEBA  C、ECDBA  D、ABCDE

6.你认为可以完成编写一个C语言编译器的程序设计语言是_.

A、汇编语言 B、C语言 C、VB语言 D、以上皆可

第一个C语言编译器应该是用汇编写的,但是第一个成熟的C语言编译器应该是由汇编和C语言共同写的。 编译原理讲到了“自举编译器”。大意就是先用底层语言(应该是汇编)写一个能运行,但效率极低的C语言编译器(底层语言不好优化),有了C语言的编译器以后,就可以用C语言好好写一个编译器了,用之前那个运行没问题,但效率低得编译器编译一下,就得到了可以使用的编译器了。

第一个C的编译器前10%是用汇编写的,后90%使用C写的,只要把必要的核心组件汇编了,以后部分就用滚雪球的方式编写,以后的C编译器基本都是用C写的了。

 

 

 

7.关于C++/JAVA类中static成员和对象成员的说法正确的是:

A、static成员变量在对象构造时生成

B、static成员函数在对象成员函数中无法调用

C、虚成员函数不可能是static成员函数

D、staric成员函数不能访问static成员变量

 C++类中谈到static,我们可以在类中定义static成员,static成员函数!C++primer里面讲过:static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在,每个static数据成员是与类关联的对象,并不与该类的对象相关联!这句话可能比较拗口,其实可以这么理解:每个static数据成员可以看成是类的一个对象,而不与该类定义的对象有任何关系!下面我们就来具体看看类中的static数据成员!

无论创建多少个对象,static成员只有一份拷贝

静态数据成员在编译时创建并初始化,也就是在该类的任何对象之前就初始化好了。

【引用】http://hi.baidu.com/yyzz990/item/46739ce019d536f52b09a472

静态函数
用static声明的函数是静态函数。静态函数可以分为全局静态函数和类的静态成员函数。

Static关键字
在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份。
用static声明的方法是静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。
静态方法不再是针对于某个对象调用,所以不能访问非静态成员。
可以通过对象引用或类名(不需要实例化)访问静态成员

为什么虚函数必须是非静态成员函数
如果定义为虚函数,那么它就是动态绑定的,也就是在派生类中可以被覆盖的,这与静态成员函数的定义本身就是相矛盾的。

 

 

8 假设下图中每个正文形的连长为1,则从A到Z的最短路径条数为()

A、11 B、12 C、13 D、14

 

就是把这个图转换为有向图,方向指向Z,然后进行深度优先遍历,结果到达Z的条数。

 

9,某进程在运行过程中需要等待从磁盘读入数据,此时该进程的状态将()

   A,从运行变为阻塞  B,从运行变为就绪  C,从就绪变为运行  D,从阻塞变为就绪

10,下面算法的时间复杂度是()

   Int f (unsigned int n){

     If( n == 0 || n == 1){

         Return 1;

}else return n*f(n-1);

}

 A,O(1)  B,O(n)  C,O(n^2)  D,O(n!)

 

10、 可以得出递归深度为n,每次递归只有一次操作,所以是O(n)

 

 

 

11n1开始,每个操作可以选择对n1,或者对n加倍,如果想获得整数2013,只需要()个操作

  A,18  B,24  C,21  D不可能

A     从2013开始,遇到偶数除2,遇到奇数-1.2012、1006、503、502、251、250、125、124、62、31、30、15、14、7、6、3、2、1.    18次操作

 

将2013转换成二进制序列111 1101 1101 "1"的个数表示加1的次数,为8,一共有11位,需要向右移10次。所以18次。

 

 

12,对于一个具有n个顶点的无向图,若采用邻接表表示,则存放表头结点的数组的大小为()  

A,n  B,n+1  C,n-1  D,n+边数

 

 

13,考虑一个特殊的hash函数h,能将任一字符串hash成一个整数k,其概率P(k) = 2 ^(-k)k=1,2,3….对一个未知大小的字符串集合S中的每一个元素取hash值所组成的集合为h(S)。若h(S)中最大的元素maxh(S) = 10,那么S的大小的期望是()

A,5  B,10  C,512  D,1024

对于几何中的每个字符串取hash可以看作是同分布的独立重复事件,所以每一个事件出现10的概率都是p=1/1024,那么当出现的时候,期望的次数就是1/p,1024

 

 

 

14,如下函数,在32bit 系统foo(2^31-3) 的值是()

   Int foo(int x){

     Return x&-x;

}

A,0  B,1  C,2  D,4

 

参考答案:C,首先-号比^的优先级高,所以实参应该是2^28,而C++中并没有幂指数的运算符,这个^只表示异或运算,所以实参的二进制值,

x的值为  0000 0000, 0000 0000, 0000 0000,0000 0010

               -x 的值为 1111 1111, 1111 1111, 1111 1111, 1111 1110

 x&-x; 0000 0000, 0000 0000, 0000 0000,0000 0010

即为2。

所以答案为C

 

 

 

 

 

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)是()

   Struct A{

                   Int a;

                   Short b;

                   Int c;

                   Char d;

};

Struct B{

            Int a;

            Short b;

            Char d;

            Int c;

};

A,16,16  B13,12  C,16,12  D,11,16

为保证4字节对齐,A中的b d都需要补齐,所以要16,B中,bd占用3个字节之后再补一个就可以了,所以12个

 

17,袋中有红球,黄球,白球个1个,每次任取一个又放回,如此连续抽取3次,则下列时间中概率是8/9的是()

A, 颜色全相同  B,颜色不全相同  C,颜色全不同  D,颜色无红色

18,一个洗牌程序的功能是将n张牌的顺序打乱。一下关于洗牌程序的功能定义说法最恰当的是()

A, 每张牌出现在n个位置上的概率相等   

B, 每张牌出现在n个位置上的概率独立     //这样会出现几张牌在一个位子上

C, 任何连续位置上的两张牌的内容独立    //出现相同

D, N张牌的任何两个不同的排列出现的概率相等

19,用两种颜色去染排成一个圈的6个旗子,如果通过旋转得到则只算一种,问一共有多少种染色模式。 

A,10  B,14  C,15  D,16

 

答案共14种

 

分析:题目意思是说旋转后相同的颜色排布算一种。相当于棋子没有区别,只有位置的相对关系。

 

设两种颜色为黑白

 

全黑1种+全白1种=2

 

1黑5白(1种)+1白5黑(1种)=2种

 

2黑4白(2个黑的可以紧挨着,2个黑的中间隔1个棋子,两个黑的中间隔2个棋子)共3种

 

4黑2白同2黑4白对称:3种

 

3黑3白:3个黑的连在一起(1种),3个黑的任意两个之间不相邻(1种),3个黑的有两个挨着,另外一个与这两个棋子都不相邻(2种)

 

共4种

 

特别是另外一个与这两个棋子都不相邻的情况,有两种,刚开始以为是对称的算一种了,而实际上是两种,因为这种通过旋转是转不到一样的。

 

所以总共有2+2+3+3+4=14种

 

 

20,递归式的先序遍历一个n节点,深度为d的二叉树,需要栈空间的大小为()

A,O(n)  B,O(d)  C,O(logn)  D,O(nlogn)

 

 

二,不定项选择

21,两个线程运行在双核机器上,每个线程主程序如下,线程1x=1;r1=y;线程2:y=1;r2=xxy是两个全局变量,初始化为0,一下哪一个是r1r2的可能值()

A,r1=1,r2=1  B,r1=1,r2=0  C,r1=0,r2=0  D,r1=0,r2=1

22,关于linux系统的负载(LOAD),以下表述正确的是()

A, 通过就绪和运行的进程数来反映

B, 可以通过TOP命令查看

C, 可以通过uptime查看

D, Load:2.5 1.3 1.1 表示系统的负载压力在逐渐减小

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)

答案: D

 

 

24,假定函数rand_k 会随机返回一个[1,k]之间的整数(K >= 2),并且每个整数值出现的几率相等。已知目前有rand_7的实现,请问通过调用rand_7和四则运算函数,并适当增加逻辑判断和循环等控制逻辑,下来函数可以实现的有()

   A,rand_3  B,rand_21  C,rand_23  D,rand_47

 

三,填空与问答

 

25、某二叉树的前序遍历序列为+a*b-cd/ef,后序遍历序列为abcd-*+ef/-,问其中序遍历序列是:a+b*c-d-e/f

阿里笔试 - flyown34317 - 折柳家园

 

26、某缓存系统采用LRU淘汰算法,假定缓存容量为4,并且初始为空,那么在顺序访问以下数据项的时候,151352412,出现缓存直接命中的次数是(),最后缓存中即将准备淘汰的数据项是()

答:直接命中的次数是3次,分别是访问151352412时。最后缓存中即将准备淘汰的数据项是5

 

 

27、有两个较长的单向链表ab,为了找出节点node满足node in a 并且 node in b,请设计空间使用尽量小的算法。(用C/C++/JAVA或伪码表示都可以)

答:node in a 并且node in b,就是求两个链表的公共节点吧

就是先分别遍历一遍链表A和链表B,在遍历时分别记下链表AB的长度,并且在最后看看链表A和链表B的最后一个节点是不是相同,如果相同则有公共节点,如果不同就没有公共节点。

找公共节点就是再利用两个指针,根据遍历时记录的长度,找到第一个公共节点,这个节点后面的就都是公共节点了。

 

struct ListNode{
	int data;
	struct ListNode* next;
};
typedef struct ListNode ListNode;
ListNode* findSameNode(ListNode *ahead, ListNode *bhead)
{
	ListNode *ap = ahead;
	ListNode *bp = bhead;
	
	int alen = 1,blen = 1;
	
	if(ahead == NULL) return NULL;	  	
 	if(bhead == NULL) return NULL;
 	
 	while(ap->next != NULL)
 	{
 		alen++;
 		ap = ap->next;
 	}
 	while(bp->next != NULL)
 	{
 		blen++;
 		bp = bp->next;
 	}
 	if(ap != bp)
 		return NULL;
	
 	if(alen > blen)
 	{
 		alen = alen - blen;
 		ap = ahead;
 		while(alen--)
	 	{
	 		ap = ap->next;
	 	}
	 }
	 if(blen > alen)
 	{
 		blen = blen - alen;
 		bp = bhead;
 		while(blen--)
	 	{
	 		bp = bp->next;
	 	}
	 }
	 //
	 while(ap != bp)
	 {
	 	ap = ap->next;
	 	bp = bp->next;
	 }
	 return ap;		
}

 

  

 

 

28、当存储数据量超出单节点数据管理能力的时候,可以采取的办法有数据库sharding的解决方案,也就是按照一定的规律把数据分散存储在多个数据管理节点N中(节点编号0.1.2...N-1)。假设存储的数据是a,请完成为数据a计算存储节点的程序。(没学过C语言的同学也可以用伪码完成)

#define N 5

int hash(int element)

{

 return element*2654435761;

}

int shardingIndex(int a)

{

 int p = hash(a);

 //1

 return p;

}

 

空格1处: p %= N;

 

29、宿舍内5个同学一起玩对战游戏,每场比赛有一些人作为红方,另一些人作为蓝方,请问至少需要多少场比赛,才能使任意两个人之间有一场红方对蓝方和一场蓝方对红方的比赛?

答案为4场。

分析见下图:箭头表示一场红对蓝的比赛,(<- A B ->)表示AB红对蓝一场,BA红对蓝一场,带黑点的表示重复了一场比赛,具体的4场比赛见右边的4个图。

 

阿里笔试 - flyown34317 - 折柳家园

 

 

分析:一次划分中,某方可以有1人,另一方有4人或某方有2人,另一人有3人。

要使任意两个人之间有一场红方对蓝方和蓝方对红方的比赛,假设5个同学为A,B,C,D,E,相当有有向图的5个节点,任意两个节点间有两个方向的边连接。

即总的节点关系有(5个节点中选取两个节点)A(5,2)=5*4=20个关系。

而一次比赛(一次划分)能够生成的关系(一方两人一方三人的划分)c(2,1)*c(3,1)=2*3=6或者(一方四人一方一人的划分)c(4,1)*(c(1,1)=4*1=4,

所以一场比赛(一次划分)最多生成的关系次数为6

所以需要20/6=3.33..即至少需要4场比赛

 

 

 

C++选做题
Part I
假设你有一台计算机,配置如下:
48GB内存
16核CPU,3.0GHz
12块2TB SATA硬盘
有两个数据文件A和B,A的大小是40GB,B的大小是2TB,A和B的文件格式一样,都包含等长的100字节的记录,记录的前20个字节表示key,后 80个字节表示value,所有的key和value都由数字和大小写字母组成(0-9 A-Z a-z),同一个文件中的key没有排序,也没有重复。
文件A和B都切成了1GB(1*10^9字节)的数据块(名为A000001、A000002......A000010、B000001、B000002......B002000),均匀分布在6块硬盘上。
请问如何用最快的方法找到A和B之间共同的key,以及他们对应的value值(建议输出格式如下所示:<key><空格><A中对应value><空格><B中对应value>)


请描述你的方法里面用到的关键的数据结构和算法,估算这个方法需要的内存空间和运算时间,并说明你的推导过程。


Part II
如果你有100台服务器,每台配置如上描述,它们通过千兆网络组成一个集群,任意两台之间的带宽可以达到1000Mbps,同时假设文件A和B的大小也放大100倍(各位4TB和200TB),并且被切分成1GB的碎片,均匀分布在100台服务器上。
请问如何用最快的方法找到A和B之间共同的key,以及他们对应的value值(建议输出格式如下所示:<key><空格><A中对应value><空格><B中对应value>)


请描述你的方法里面用到的关键的数据结构和算法,估算这个方法需要的内存空间、网络流和运算时间,并说明你的推导过程。

 

posted @ 2014-03-28 22:45  Snowwolf_Yang  阅读(859)  评论(0编辑  收藏  举报