阿里的笔试题

1.  单选题

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

A: h(K)=K/N;

B: h(K)=1;

C: h(K)=K mod N;

D: h(K)=(K+rand(N)) mod N, rand(N)返回0到N-1的整数

答案: 

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

A: 堆排序 B:插入排序

C: 冒泡排序 D:快速排序

答案: 

3.  下面说法错误的是:

A: CISC计算机比RISC计算机指令多

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

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

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

答案: b ,原因 扩展操作码的设计方案目的是保持指令字长度不变而增加指令操作的数量 

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

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

答案: a  d 都该选, b  c 我觉得该选 b ,因为 cache 是高速缓冲存储器,存取速度高于 ram ,冯诺依曼当时的 cpu 频率还没有那么快, cache 还没出来,所以我觉得该选 

5.  一个栈的入栈序列式 ABCDE则不可能的出栈序列是:

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

答案: 

6. 你认为可以完成编写一个 C语言编译器的语言是:

A:汇编 B:C语言 C:VB D:以上全可以

答案:我觉得该选 a

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

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

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

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

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

答案: 

8:看不清

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*N)  D:O(n!)

答案: 

11: n从1开始,每个操作可以选择对n加1或者对n加倍。若想获得整数2013,最少需要多少个操作。

A:18    B:24   C:21  D;不可能

答案: 

 A,18个完美解决,方法也很简单,尽量对2013用除法,显示2013->2012->1006->503->502->251->250->125->124->62->31->30->15->14->7->6->3->2->1

正向只能是+1和×2,所以逆向只能-1和/2,由上过程可得18次

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

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

答案: 

参考答案:对于几何中的每个字符串取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(n),O(n)

答案: 

16:在32为系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是:

Struct A 
{

Int a;short b;int c;char d;

};

Struct B 
{int a;short b;char c;int c;};

A: 16,16    B:13,12   C:16,12 D:11,16

答案: c

17:袋中有红球,黄球,白球各一个,每次任意取一个放回,如此连续3次,则下列事件中概率是8/9的是:

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

参考答案:A

解释:由于颜色任一颜色相同的概率为1/27

颜色无红色的概率为2/3×2/3×2/3=8/27

颜色全部相同的概率为1/9

颜色都不同,概率为3×1/3×2×1/3×1/3=2/9

颜色不全相同为8/9 

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

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

B: 每张牌出现在n个位置上的概率独立

C: 任何连续位置上的两张牌的内容独立

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

答案:个人看法是 a

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

参考答案:C

解释:应该有14种方案,设只有黑白两色,默认白色,那么,用p(n)表示有n个黑棋的种类

p(0)=p(6)=1

p(1)=p(5)=1

p(2)=p(4)=3 //相邻的一种,隔一个的一种,两个的一种

p(3)=4 //都相邻的一种,BB0B的一种,BB00B的一种,B0B0B的一种,一共4种

综上是14种

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

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

答案: c ,有左孩子就压栈 

还有一种答案:

参考答案:B 

解释:因为二叉树并不一定是平衡的,也就是深度d!=logn,有可能d》》logn。。所以栈大小应该是O(d)

第二部分:多选

21:两个线程运行在双核机器上,每个线程主线程如下,线程1:x=1;r1=y;线程2:y=1;r2=x;

X和y是全局变量,初始为0。以下哪一个是r1和r2的可能值:

A: r1=1,r2=1

B: r1=1,r2=0

C:r1=0,r2=0

D:r1=0,r2=1

我的答案: bd

参考答案:ABD

22. 关于 Linux系统的负载,以下表述正确的是:

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

B: 通过TOP命令查看

C: 通过uptime查看

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

参考答案:BC

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_49

解释,对于rand_x(x<7)的直接截断,只要rand数大于x直接忽略,保证rand_x能够做到概率相等。而对于其他的则采用7×rand_7+rand_7,可以-7得到rand_49,然后截断成rand_42,统一除以2,则是rand_21,其他类似。

鉴于大家对这道题的解释看得不太清,我就在此展开解释一下:

首先分析:7×rand_7+rand_7

1.      首先它是由两个随机变量组成,亦即7X+Y,只不过X与Y是独立同分布的而已,所以上式子表示为Z=7X+Y

那么对于随机变量X,你可以理解为它是一个“量级”的概念,X取值为1~7

当X=1时,随机变量Z取值范围是1*7+(1~7),也就是8~14

当X=2时,随机变量Z取值范围是2*7+(1~7),也就是15~21

当X=3时,随机变量Z取值范围是3*7+(1~7),也就是22~28

以此类推。。。

可以产生8~56的随机数。

那么产生的8~56的随机数,概率都相等吗?

答案是必然的,因为X是量级的概念,达到每个量级的概率是1/7,在量级内,Y达到1~7每个数的概率依然是1/7,所以8~56的每个数的概率都是1/49

好了我们可以得到1/49等概率的8~56,直接在生产的时候-7,得到等概率1/49的1~49.。。。。

好,现在只需要记住,得到rand_49,1~49的每个数都是等概率的就可以了,因为我们要截断,也就是说,为了得到rand_23直接截断,判断输出如果>23,直接忽略,否则输出,大家可能有点别扭,因为有的随机数生成的时候可能时间上要比其他的长点。但是要记住,1~23每个数输出的概率都是相等的,只不过不能保证每次输出时间都分秒不差而已。时间长短是跟概率无关的概念。


3.  6 分)两个较长的单向链表 a  b ,为了找出及诶单 noed 满足 node in a 
并且 node in b 。请设计空间使用尽量小的算法(用 c/c++  java  或者伪代码)

答案网上找的

我们定义节点的距离为节点到链表开始所经过的节点数。如果两个链表长度相同,则相交节点其在两个链表上的距离一定相等。对于长度不同的两个链表,我们可以采用对齐的方式,使其向长度短的链表对齐。这样就可以应用上面的思路。具体算法如下:

C/C++ code ?

 

struct node  

{  

    int v;  

    node *next;  

};  

/* 

返回链表的长度 

链表为空 返回 

*/  

size_t listLen(node * p)  

{  

    size_t num = 0;  

    while (p!=NULL)  

    {  

        num++;  

        p = p->next;  

    }  

    return num;  

}  

//  如果找到了 则返回指针 指向公共节点  

//  如果不存在 则返回空指针  

node * findFirstCommenNode(node * pheada, node * pheadb)  

{  

    size_t lenA = listLen(pheada);  

    size_t lenB = listLen(pheadb);  

   

    node * plistA = pheada;  

    node * plistB = pheadb;  

    // 调整长度  

    //plistA  指向较长的一个  

    if (lenA < lenB)  

    {  

        plistB = pheada;  

        plistA = pheadb;  

        size_t t = lenA;  

        lenA = lenB;  

        lenB = t;  

    }  

    while(lenA > lenB)  

    {  

        plistA = plistA->next;  

        --lenA;  

    }  

    // 一样长了  

    // 寻找公共节点  

    while (plistA!=NULL && plistA != plistB)  

    {  

        plistA = plistA->next;  

        plistB = plistB->next;  

    }  

    return plistA;  

}  

 

算法的空间复杂度 O(1) ,时间复杂度 O(m+n) ,效果不错吧。

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

C/C++ code ?

1

2

3

4

5

6

7

8

9

#define N 5

int hash(int element){

   return element*2654435761;

}

int shardingIndex(int a){

    int p = hash(a);

    _________________________; // 这里是空格

    return p;

}

 

求高手指点

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

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

2014 阿里巴巴精选几道笔试题—哈尔滨站

1.  题目:宿舍内有五个童鞋一起玩对战游戏,每场比赛有一些人作为红方,另外一些人作为蓝方,请问至少需要多少场比赛才能使得任意两个人之间有一场红方对蓝方和一场蓝方对红方的比赛,请写出思路。

分析:

需要四场比赛即可 .

第一场  红方为 ABE, 蓝方为 CD

第二场 : 红方为 CDE, 蓝方为 AB

第三场 : 红方为 AC, 蓝方为 BDE

第四场 : 红方为 BD, 蓝方为 ACE

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

解答 :

有 10 亿条记录的文本文件存储在磁盘中 , 不能一次存入内存 , 所以讲 10 亿条分为 N  , 然后顺序将第 N 份存入内存 , 对关键字进行哈希得到 ID  , 然后进行二分法比较 , 如果不在这一份之中 , 那么需要将磁盘中的第二份导入内存 , 就这样进行计算 ~~

2014

答案:

25 题:根据先序和中序写出后序

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

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

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

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

28 题: p %= N;

29 题: 4 

题目是某缓存系统采用 LRU 算法,假定缓存容量为 4 ,并且初始为空,那么在顺序访问以下数据项的时候,

1,5,1,3,5,2,4,1,2

出现缓存直接命中的次数是()次,最后缓存中即将准备淘汰的数据项是()。

先解释下概念吧

LRU  Least Recently Used )算法:就是把最近一次使用时间离现在时间最远的数据删除掉。具体实现请看这篇博文 《如何用 LinkedHashMap 实现 LRU 缓存算法》

下面就来解题吧,我们列出每一次访问数据项时,缓存的状态


1,5 
5,1  命中 
5,1,3 
1,3,5  命中 
1,3,5,2 
3,5,2,4  超过缓存容量上限,删除 1 
5,2,4,1  超过缓存容量上限,删除 3 
5,4,1,2  命中

所以答案就出来了,直接命中次数是 3 ,最后缓存中准备淘汰的数据项是 5

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

答案:

10亿在 G量级, 分成100份, 为10M量级, 基本上放入内存无压力了.

在这10亿记录中, 均分为100份, 把每份的第一条记录关键字和此记录对应的文件偏移量先扫入内存(类似索引), 这里需要磁盘随机io 100次.

这样可以马上定位出指定关键字所在的记录块, 把相应的记录块拿到内存, 二分查找即可.

题目二:各种排序算法的稳定性和时间复杂度(平均和最差):

排序法 平均时间复杂度 最差情形复杂度 稳定度 额外空间 备注
冒泡     O(n2)     O(n2) 稳定 O(1) n小时较好
交换     O(n2)     O(n2) 不稳定 O(1) n小时较好
选择     O(n2)     O(n2) 不稳定 O(1) n小时较好
插入     O(n2)     O(n2) 稳定 O(1) 大部分已排序时较好
基数    O(logRB)    O(logRB) 稳定 O(n)

B是真数(0-9),

R是基数(个十百)

Shell   O(nlogn)  O(ns) 1 不稳定 O(1) s是所选分组
快速   O(nlogn)    O(n2) 不稳定 O(nlogn) n大时较好
归并   O(nlogn)    O(nlogn) 稳定 O(1) n大时较好
  O(nlogn)    O(nlogn) 不稳定 O(1) n大时较好

题目三:查看系统负载

方法:w 或者 uptime 或者 procinfo 或者 top

[root@client1 ~]# top
 
top - 17:06:38 up 2 days,   3:06,   1 user,   load average: 0.00, 0.00, 0.00
Tasks: 162 total,    1 running, 161 sleeping,    0 stopped,    0 zombie
Cpu(s):   0.0%us,   0.0%sy,   0.0%ni,100.0%id,   0.0%wa,   0.0%hi,   0.0%si,   0.0%st
Mem:    2054588k total,    815752k used,   1238836k free,    102272k buffers
Swap:   4128760k total,            0k used,   4128760k free,    488684k cached
 
PID USER         PR   NI   VIRT   RES   SHR S %CPU %MEM      TIME+   COMMAND
12085 root         20    0 15088 1284   952 R   0.3   0.1    0:00.02 top
1 root         20    0 19404 1572 1256 S   0.0   0.1    0:00.98 init
2 root         20    0       0      0      0 S   0.0   0.0    0:00.00 kthreadd
3 root         RT    0       0      0      0 S   0.0   0.0    0:00.14 migration/0
4 root         20    0       0      0      0 S   0.0   0.0    0:00.00 ksoftirqd/0
5 root         RT    0       0      0      0 S   0.0   0.0    0:00.00 migration/0
6 root         RT    0       0      0      0 S   0.0   0.0    0:00.00 watchdog/0
7 root         RT    0       0      0      0 S   0.0   0.0    0:00.13 migration/1
8 root         RT    0       0      0      0 S   0.0   0.0    0:00.00 migration/1
9 root         20    0       0      0      0 S   0.0   0.0    0:00.01 ksoftirqd/1
10 root         RT    0       0      0      0 S   0.0   0.0    0:00.01 watchdog/1
11 root         RT    0       0      0      0 S   0.0   0.0    0:00.14 migration/2
 
第一行解释: 
top - 17:06:38 up 2 days,   3:06,   1 user,   load average: 0.00, 0.00, 0.00 
17:06:38 :系统当前时间 
up 2 days :系统开机到现在经过了2天 
1 users:当前1用户在线
load average:0.00,0.00,0.00:系统1分钟、5分钟、15分钟的CPU负载信息
 
第二行解释: 
Tasks: 162 total,    1 running, 161 sleeping,    0 stopped,    0 zombie 
162 total:当前有162个任务
1 running:1个任务正在运行
161 sleeping:161个进程处于睡眠状态 
0 stopped:停止的进程数
0 zombie:僵死的进程数
 
第三行解释: 
Cpu(s):   0.0%us,   0.0%sy,   0.0%ni,100.0%id,   0.0%wa,   0.0%hi,   0.0%si,   0.0%st
 
0.0%us:用户态进程占用CPU时间百分比 
0.0%sy:内核占用CPU时间百分比
0.0%ni:renice值为负的任务的用户态进程的CPU时间百分比。nice是优先级的意思
100.0%id:空闲CPU时间百分比
0.0%wa:等待I/O的CPU时间百分比
0.0%hi:CPU硬中断时间百分比
0.0%si:CPU软中断时间百分比
 
第四行:
Mem:    2054588k total,    815752k used,   1238836k free,    102272k buffers 
2054588k total:物理内存总数
815752k used: 使用的物理内存
1238836k free:空闲的物理内存
102272k buffers:用作缓存的内存
 
第五行:
Swap:   4128760k total,            0k used,   4128760k free,    488684k cached
4128760k total:交换空间的总量
0k used: 使用的交换空间
4128760k free:空闲的交换空间
488684k cached:缓存的交换空间
 
最后一行:
PID USER         PR   NI   VIRT   RES   SHR S %CPU %MEM      TIME+   COMMAND
PID:进程ID
USER:进程的所有者
PR:进程的优先级
NI:nice值
VIRT:占用的虚拟内存
RES:占用的物理内存
SHR:使用的共享内存
S:进行状态 S:休眠 R运行 Z僵尸进程 N nice值为负
%CPU:占用的CPU
%MEM:占用内存
TIME+: 占用CPU的时间的累加值
COMMAND:启动命令
 
常用操作指令:
q:退出top命令
:立即刷 
s:设置刷新时间间隔
c:显示命令完全模式
t::显示或隐藏进程和CPU状态信息
m:显示或隐藏内存状态信息
l:显示或隐藏uptime信息
f:增加或减少进程显示标志
S:累计模式,会把已完成或退出的子进程占用的CPU时间累计到父进程的MITE+
P:按%CPU使用率排行
T:按MITE+排行
M:按%MEM排行
u:指定显示用户进程
r:修改进程renice值
kkill:进程
i:只显示正在运行的进程
W:保存对top的设置到文件~/.toprc,下次启动将自动调用toprc文件的设置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值