阿里巴巴集团2014年校园招聘北京笔试题

第一部分 单选题(前10题,每题2分;后10题,每题3分;共50分。选对得满分,选错倒扣一分,不选得0分。)

1、字符串”alibaba”有___个不同的排列。

A.5040 B. 840 C. 14 D.420

答案:D

解析:

 

2、下列一段C++代码的输出是 。

classBase

{

public:

intBar(char x) {return (int)(x);}

virtualint Bar(int x) {return(2*x);}

};

classDerived :public Base

{

public:

intBar(char x) {return(int)(-x);}

intBar(int x) {return (x/2);}

};

voidmain(void)

{

DerivedObj;

Base*pObj=&Obj;

printf(“%d,”,pObj->Bar((char)(100)));

printf(“%d,”,pObj->Bar(100));

}

A.100,50 B. -100,200 C. -100,50D. 100,200

参考答案:A。考察C++中虚函数的知识点。

复制代码
#include <stdio.h>

class A {
public:
    void fn() { printf("fn in A\n"); }
    virtual void v_fn() { printf("virtual fn in A\n"); }
};

class B : public A {
public:
    void fn() { printf("fn in B\n"); }
    virtual void v_fn() { printf("virtual fn in B\n"); }
};

int main() {
    A *a = new B();
    a->fn();
    a->v_fn();
    return 0;
}
复制代码

  基类A有两个成员函数fn和v_fn,派生类B继承自基类A,同样实现了两个函数,然后在main函数中用A的指针指向B的实例(向上转型,也是实现多态的必要手段),然后分别调用fn和v_fn函数。结果是“fn in A"和"virtual fn in B"。这是因为fn是普通成员函数,它是通过类A的指针调用的,所以在编译的时候就确定了调用A的fn函数。而v_fn是虚函数,编译时不能确定,而是在运行时再通过一些机制来调用指针所指向的实例(B的实例)中的v_fn函数。假如派生类B中没有实现(完全一样,不是重载)v_fn这个函数,那么依然会调用基类类A中的v_fn;如果它实现了,就可以说派生类B覆盖了基类A中的v_fn这个虚函数。这就是虚函数的表现和使用,只有通过虚函数,才能实现面向对象语言中的多态性。

3、有一个二维数组A[10][5],每个数据元素占1个字节,且A[0][0]的存储地址是1000,则A[i][j]的地址是 。

A.1000+10i+j B. 1000+i+j C. 1000+5i+j D. 1000+10i+5j

答案:C

4、下列__不是线性表?

A.队列 B. 栈 C. 关联数组 D. 链表

答案:C

5.下列有关在一个处理器(processor)上跑两个线程(thread)的说法中,正确的是 。

A.一个线程可以改变另一个线程的程序计数器(program counter)

B.一个线程既不能读也不能写另一个线程的栈(stack)

C.一个线程可以读写另一个线程的寄存器(register)

D.以上都不对

答案:B。一个进程中的所有线程共享该进程的地址空间,但它们有各自独立的栈。

6、关于双链表的搜索给定元素操作的说法正确的是 。

A.从两个方向搜索双链表,比从一个方向搜索双链表的速度慢

B.从两个方向搜索双链表,比从一个方向搜索双链表的方差要小

C.从两个方向搜索双链表,比从一个方向搜索双链表速度要快

D.以上说法都不正确

答案:B。

7、对n个数字进行排序,期中两两不同的数字的个数为k,n远远大于k,而n的取值区间长度超过了内存的大小,时间复杂度最小可以是 。

A.O(nlogk) B. O(nk) C. O(n) D. O(nlogn)

答案:C。

解析:n远大于k的意思是,大多数数字都是重复的。申请2k个元素的内存,2个一对,一个存数字,一个用于计数,遍历n个数,进行计数,该过程的时间复杂度为O(n)。对k个数进行排序的最小时间复杂度为O(klogk),有多种排序方法。所以总的排序时间为:O(n)+O(klogk),而n远大于k,所以时间复杂度为O(n)。

 

8、一台指针式钟表的时钟和分钟的指向重合的时间间隔是__。

A.720/13分钟 B. 720/11分钟 C. 60分钟D. 以上都不正确

答案:B

【分析】时针60分钟走1/12*2π的弧度,V(时针)= 1/12*2π/60 (rad/min);分针60分钟走2π的弧度,V(分针)= 2π/60 (rad/min);假设从重合开始经过了T时间又重合了,则满足:V(时针)*T+2π=V(分针)*T。

9、两个大小不同的杯子R和S,R中装着一定量的小米,S中装着一定量的沙子。一名儿童用勺子从S中取出一勺沙子放入R,与小米混合之后,再从R中取出等体积的一勺混合物放入S。假定两勺物品的体积相等,且R和S都没有发生溢出。则以下说法中正确的是。

A.R中的沙子和S中的小米一样多

B.R中的沙子比S中的小米少

C.R中的沙子比S中的小米多

D.无法判断

答案:A。

解析:假定一勺的量是x, 开始从S转入x份的沙子放入R,此时R中有x的沙子.然后从R中转出x份的混合物, 假定混合物由a份小米, b份沙子组成, a+b = x,这时R中剩下x-b的沙子, S里多了a的小米, 而a = x - b.所以A是对的.

10、假定抛出的硬币落地之后正反两面出现的概率分别是1/2。那么抛10次和100次硬币(分别称为T10和T100)相比,以下说法正确的是 。

A.T100出现一半的正面比T10出现一半正面的概率更大

B.T100前3次都是正面的概率比T10前3次都是正面的可能性大

C.T100正面次数的方差小于T10出现正面次数的方差

D.T100出现正面的比例比T10出现正面的比例在(0.45,0.55)区间中的可能性更大。

答案:D。测试的次数越多,出现正面的概率越趋近于50%。

 

11、某福彩机构推出了一款简单的猜谜游戏:游戏玩家只需交纳n元,赌红或者黑。如果开奖结果与游戏玩家所赌的颜色相同,则玩家除得到交纳的n元赌资外,还可以获得n元作为奖励;否则该玩家失去交纳的n元赌资。为了游戏公平,开奖是红或者黑的概率均为1/2。某游戏玩家想出了一个玩法:开始出100元参与赌博,然后按照如下规则进行游戏,如果输掉,并且赌资充足,就把已经输了的总钱数翻倍作为赌资进行赌博;否则,就停止该游戏。假定该机构赌资无限,而玩家的赌资比较有限,以下关于该玩家退出游戏时的情形的评论中合理的是: 。

A.该玩家的策略可以保证游戏结束时赢钱数的期望为正数

B.该福彩机构长期会赔钱

C.该玩家会有一定概率在游戏结束时输钱,但输得不多

D.该玩家赢的可能性比输的可能性大

答案:C

【分析】如果赌徒有无穷多的钱,他和庄家的赢钱期望是相同的。但是他有可能输光钱。

12、有16瓶水,其中只有一瓶水有毒,小白鼠喝一滴之后一小时会死。请问最少用__只小白鼠,在1小时内一定可以找出至少14瓶无毒的水?

A.1只

B.3只

C.4只

D.16只

答案:B。将16瓶水两两分成A1-A8共8组,有b1-b3三只白鼠。b1-b3分别喝如下组:

b1:A1、A4、A5、A7;b2:A2、A4、A6、A7;b1:A3、A5、A6、A7。

因为例如b1死,b2、b3活,则说明A1中有一瓶毒水,其余7组都无毒;b1、b2死,b3活,则说明A4中有一瓶毒水,其余7组都无毒。

因此3只足矣。

 

13、有一台4核CPU的服务器,上面运行着1种在线服务。如果该在线服务处理一个请求在非独占IO上的等待时间和CPU计算上消耗的时间比为2:1,假定IO带宽充足,那么至少开 个线程能最大化性能地使用该服务器?

A.4 B. 8 C. 12 D. 线程越多越好

答案;C。

【分析】单核情况下,依据题意,该任务的一个线程的CPU执行和I/O等待周期为1:2,所以同时并发3个线程,可以随时有一个线程在使用CPU,从而使CPU的使用率最大。那么,4核就应该是12个线程。关于CPU调度,详见:http://blog.sina.com.cn/s/blog_630c97f20100vhc9.html

 

14、有一种语言称为lua,里面的数字只有一种类型(number),实际上是双精度浮点数。没有各种位数的整数,如32位、64位整数等。那么关于该语言的说法错误的是 。

A.该语言可以用number类型的变量作为数组下标

B.该语言可以表示任意32位数字整数的数字ID

C.该语言无法实现32位数字整数的按位与、或、异或运算

D.该语言可以正常进行双精度浮点数运算

答案:B

【分析】贴来的答案:A 可以用number类型的变量作为数组下标

毫无疑问是正确的。

错误的是B。

B 该语言可以表示任意32为整数的数组ID

原因是因为:

lua的基本类型number,其实就是用float表示的。 所谓的整数,其实也是用float去表示的, 如lua中的整数100,实际上是float类型100.0,所以lua不能表示32位整数的数组ID,本身没有那么大。

关于C选项:

C 该语言无法实现32为数字整数的按位与、或、异或运算

在最基本的库文件里确实没有内置的算法,但是在扩展库中还是存在的比如

require"bit"

bit.band(6,4)

bit.rshift(6,1)

bit.bor(6,4)

bit.bnot(6)

D 该语言可以正常进行双精度浮点数运算:

这个应该是对的,因为lua int的内部实现就是通过double实现的。

 

15、一个在线服务通常需要读取存储着海量数据的数据库。为了提高服务的处理速度,通常需要加cache(缓存)。以下场景中不合适使用cache的是 。

A.数据库中每条数据被访问到的概率近似相等,且独立

B.使用了多线程机制的服务

C.单条数据尺寸大小的数据

D.有着大量访问的服务

答案:A。如果每条数据被访问到的概率近似相等,那么缓存的意义不大。因为缓存的往往是访问频率比较高的数据。

 

16 如下一段神奇的代码实现的功能是    。

int miracle(unsigned int n)

{

int m=n==0 ? 0:1;

while(n=(n&(n-1)))

{

m++;

}

return m;

}

A.n的二进制表示中”0″的个数

B.n的二进制表示的倒序值

C.n的二进制表示中”1″的个数

D.一个均匀的哈希函数

参考答案:C。

【分析】C++中while(表达式),表达式类型转换为逻辑真假,只要表达式不等于0,表达式值为转换为逻辑真,循环条件便满足,执行循环体。这和JAVA不一样,JAVA中while(true)才执行循环体。谨记!

 

17、有1023个两两不同的整数,取值范围是1到1024,其按位异或的结果的取值范围是。

A.0到1024

B.0,1025到2047

C.1到1024

D.2到2048之前的全部偶数

答案:C。2^3=1,只有当两个数相等时其异或的值才为0,所以A、B、D都被排除,所以选择C。

 

18、七夕节n对恋人(n>=2)围成一圈举行篝火晚会。晚会的规则是:男女相间隔,且每对恋人处在相邻的位置上。请问有多少种不同的圈子?

A.(2n-1)!/2 B. 2(n-1)! C. 2^n*(n-1)! D. (2n)!

答案:B。

【分析】经典的圈排列问题:n对人有(n-1)!种圆圈排列。每一对男女的位置可以调换,所以乘以2^n,但由于男女相间隔,所以只能乘以2。

 

19、星期天有10个朋友约好一起郊游,在车站的集合时间是早晨9:50:00到10:00:00。已知每个人到达车站的时间是9:50:00到10:00:00内的均匀分布,且彼此独立。那么最后一人最可能到达的时间是 (精确到分钟,向下取整)。

A.各个分钟概率相等 B. 9:57 C. 9:58 D. 9:59

答案:D

 

20、已知某国家每年出生人口数每年递增3%,且男女比例为1:1。如果每个男性都希望找比自己小0.5到 3岁的女性结婚,且每个女性都希望找比自己大0.5到3岁的男性结婚,适婚年龄为20到30岁,那么对该国适婚男女婚配方面的说法正确的是 。

A.男女会比较均衡

B.会产生较多剩女

C.会产生较多剩男

D.信息不足,无法判断

答案:A。生男生女概率相同,且基数相等,所以有多少剩男就会有多少剩女。因此,男女会比较均衡。

 

第二部分 不定向选项(4题,每题5分。每题有1-5个正确选项,完全正确计5分,漏选计2分,不选计0分,多选、错选计-2分)

21、要提高多线程程序的效率,对锁的控制策略非常重要。一种策略是在锁的个数不太多、控制结构不太复杂的情况下,尽可能降低加锁的粒度;另一种策略是在合适的条件下取消用锁。以下情况中不可能取消锁的是 。

A.多线程写一个共同的数据结构,且写操作是原子操作

B.多线程写一个共同的数据结构,且写操作不是原子操作

C.多线程读一个共同的数据结构,且读操作不是原子操作

D.一个线程写,多个线程读一个共同的数据结构,写操作是原子操作,读操作不是原子操作

E.一个线程写、多个线程读一个共同的数据结构,写操作不是原子操作,读操作是原子操作

答案:BE。该题考察的是多线程锁机制以及原子操作的概念。

解析:"原子操作(atomic operation)是不需要synchronized",这是Java多线程编程的老生常谈了。所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。

22、一颗非空的二叉树的先序遍历序列与后序遍历序列正好相反,则该二叉树可能是 。

A.所有的结点均无右孩子

B.只有一个叶子结点

C.是一颗二叉树索树

D.所有的结点均无左孩子

答案:ABD。

23、以下数字在表示为double(8字节的双精度浮点数)时存在舍入误差的有 。

A. B. 10的30次方 C. 0.1 D. 0.5 E. 100

【答案】AB。因为是无限循环小数,存入必存在误差;10的30次方超出了double表示的范围,所以也存在误差。

24、给定如下C程序:

typedef struct node_s{

  int item;

  struc tnode_s* next;

}node_t;

void reverse_list(node_t* head)

{

  node_t *n=head;

  head=NULL;  

  while(n){

  }

  return head;

}

以下哪项能实现该函数的功能

A.node_t* m=head; head=n; head->next=m; n=n->next;

B.node_t* m=n; n=n->next; m->next=head; head=m;

C.node_t* m=n->next; n->next=head; n=m; head=n;

D.head=n->next; head->next=n; n=n->next;

参考答案:D。函数的功能是实现指针反转。

第三部分 填空与问答(5题,共30分)

25、(4分)某无聊的程序员在玩Windows上的记事本程序,不用鼠标,每次可以按以下键或组合之一:A、Ctrl+A(全选)、Ctrl+C(拷贝)、Ctrl+V(粘贴),那么在10次按键只能可以制造的最长文本长度为_20_ 。 

参考答案:"AAAAA"+"Ctrl+A"+"Ctrl+C"+"Ctrl+V"+"Ctrl+V"+"Ctrl+V"。所以最长文本长度为20。

 

26、(4分)若初始序列为gbfcdae,那么至少需要  次两两交换,才能使该序列变为abcdefg。任给一个自由a–g这7个字母组成的排列,最坏的情况下需要至少_6_次两两交换,才能使序列变为abcdefg。 

解析::每次交换可以把一个字符放在正确的位置,当前面的都放好后,最后一个自动放好。

 

27. (5分)在某恶劣天气,若地图上S点(左上角)到T点(右下角)的交通网如下图所示,其中每条边表示一条双向通道,其上的数字为该通路可通行的概率,且该概率两两独立。求S到T的可通行概率 _1/2_。   

解析:SCT+SBT+SABT = 1/2。

28.(8分)6度分离假说的含义是,世界上任何两个人要么是朋友,要么是朋友的朋友,或者更高阶的朋友的朋友(如朋友的朋友的朋友),改论断中”朋友”一词出现的次数为两人之间的距离,那么该距离小于等于6。如果某SNS(如QQ、旺旺等),有100万用户,其人际关系网咯符合以下两个假设: 

朋友关系是一种对称关系(如A和B是朋友,那么B和A也是朋友) 

符合2度分离假说 

第i个人拥有的朋友的个数为ni ,所有ni 中最大值为n 

试估算n的最小值 。 

29.(9分)某电子商务网站进行A、B两种推荐算法的效果对比测试,对用户的访问请求按照1:9的比例随机分配给A和B两种算法处理。产生推荐结果后,按照两种指标对比两种算法产生的结果好坏:第一种指标是CTRPV=该算法下用户的点击展现次数/该算法下所有的展现次数,第二种指标是CTRUV=该算法下有点击的用户数/该算法下所有的用户数。假定每个用户会对该推荐服务2次访问,如果A和B的CTRPV持平(假设为0.01)。那么CTRUV哪个大,大的比小的大百分之多少。

 

第四部分:JAVA附加题(注,阿里有大量JAVA研发工程师需求;选作以下题目有机会增加该方向面试机会)

30.以下每个线程输出的结果是什么?(不用关注输出的顺序,只需写出输出的结果集即可)

public class TestThread {

    public static void main(String[] args) {

        Thread t1 = new Thread() {

            public void run() {

                try {

                    int i = 0;

                    while (i++ < 100000) {

                        // nothing

                    }

                    System.out.println("A1");

                } catch (Exception e) {

                    System.out.println("B1");

                }

            };

        };

        t1.start();

        t1.interrupt();

        // test2

        Thread t2 = new Thread() {

            public void run() {

                try {

                    Thread.sleep(5000);

                    System.out.println("A2");

                } catch (Exception e) {

                    System.out.println("B2");

                }

            };

        };

        t2.start();
        t2.interrupt(); 

        // test3

        Thread t3 = new Thread() {

            public void run() {

                try {

                    Thread.sleep(50000);

                    System.out.println("A3");

                } catch (Exception e) {

                    System.out.println("B3");

                }

            };

        };

        t3.start();

        t3.interrupt();

        // test4

        Thread t4 = new Thread() {

            public void run() {

                try {

                    Thread.sleep(50000);

                    System.out.println("A4");

                } catch (Exception e) {

                    System.out.println("B4");

                }

            };

        };

        t4.start();

        t4.interrupt();

        // test5

        try {

            t4.start();

            System.out.println("A5");

        } catch (Exception e) {

            System.out.println("B5");

        }

    }

}

参考答案:
B2
B5
B4
B3

A1

解析:

Thread.interrupt()方法不会中断一个正在运行的线程。它的作用是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。

interrupt方法并不是强制终止线程,它只能设置线程的interrupted状态,而在线程中一般使用一下方式: while (!Thread.currentThread().isInterrupted() && more work to do){},而被block的线程(sleep() or join())在被调用interrupt时会产生InterruptException,此时是否终止线程由本线程自己决定。详见:http://blog.sina.com.cn/s/blog_6ca570ed01016mti.html

 

31.一个有10亿条记录的文本文件,已按照关键字排好序存储,设计算法,可以快速的从文件中查找指定关键字的记录

答案:

可以建立B树索引。10亿在 G量级, 分成100份, 为10M量级, 基本上放入内存无压力了.

在这10亿记录中, 均分为100份, 把每份的第一条记录关键字和此记录对应的文件偏移量先扫入内存(类似索引), 这里需要磁盘随机io 100次。这样可以马上定位出指定关键字所在的记录块, 把相应的记录块拿到内存, 二分查找即可。

【系统工程师】 附加题

1、在互联网时代系统的稳定性要求越来越高,为了提升系统的稳定性,高可用技术被广泛运用,请列举至少4中相关的技术解决硬件、系统或网络等层面的单点问题。

 

 

2、请描述一下TCP建立连接三次握手的过程。

 

3.搜索引擎是很常用的web应用。大部分搜索引擎需要设计一个抓虫(Crawler),从很多网站抓去网页,分析数据,供搜索引擎使用。设想你来做一个搜索引擎的爬虫,需要抓去约一百万家网站的网页内容。

  1) 请画出一个抓虫系统的架构图。

  2) 重点说明你的爬虫需要如何优化来提升性能。

 

posted @ 2015-04-16 16:21  hzhtracy  阅读(598)  评论(0编辑  收藏  举报