这一个笔试题在另一个博客中有拍的照片:http://blog.csdn.net/mungco/article/details/11267099详情请看这个链接
一简答
1 linux/unix远程登陆都用到了ssh服务,当网络出现错误时服务会中断,linux/unix端的程序会停止。为什么会这样?说下ssh的原理,解释中断的原理。
2一个最小堆,也是完全二叉树,用按层遍历数组表示。
1. 求节点a[n]的子节点的访问方式
a[2n],a[2n+1]
2. 插入一节点的程序void add_element(int *a,int size,int val);
void add_element(int *a , int size , int val){//小顶堆
a[++size]=val;
for(int i=size ; i>0 ; i/=2){
if(val<a[i/2])
a[i]=a[i/2];
else
break;
}
a[i]=val;
}
3. 删除最小节点的程序int ExtractMin(int *a , int size );
void SIFTDOWN(int *a , int i , int size){
int val=a[i];
int p=0;
while(i<=size){
if(a[2*i]<a[i])
p=2*i;
if(2*i+1<=size && a[2*i+1]<a[i])
p=2*i+1;
a[i]=a[p];
if(i==p)
return;
a[p]=val;
i=p;
}
}
int ExtractMin(int *a , int& size)
{
int val=a[1];
a[1]=a[size--];
SIFTDOWN(a,1,size);
}
3 通过某种hash算法,可以让用户稳定的均匀分布在一个区间内,这个区间的大小为100%,分布的最小粒度为0.1%,我们把这种区间叫做一层,现在有两个区间A、B,如何让层A中的任意子区间段都均匀分布到层B的100%中?例如:层A中取10%,这10%会均匀分布到层B中,即:层B的每一个10%区间都会有1%的区间A中的10%,也可以说层B的。如果现在有超过10层,每一层之间都需要有这种关系,又如何解决?
与其说是hash不如说这是一道概率题,等概率
二算法(具体题目内容请见上面链接中的图片)
1有一个数,比如N=123,一共有三位,所有位的值加起来是6。我们找出另外一个数141,也是三位,所有位加起来也是6,这样和123有同样关系的数还有很多,我们将求一个有这种关系并且是所有数中只比基123刚刚好大的数定义为F(N)。如果不存在,则F(N)=-1.现在有一个数n,它的位数小于1000.它的值小于10^500.求F(F(N))=-1。不记得问什么了?是问迭代过程怎么实现还是问什么时候停止的。反正是一个迭代
这道题的思路其实很简单,关键有两个问题需要解决:1)如何寻找F(N),2)如何判断F(N)不存在,由于这个编码可以很大,那么肯定需要存在数组里面,假设一个编码N为99999989,由于各个位之和需要相等,那么我们可以先将最低位减1将次低位加1,如果次低位为9的话就加到次次低位,如果高位全部为9的话就表示F(N)不存在,比如说9991,其F(N)就不存在,另种情况就是最低位为0,那么就不管这个低位0,转换为低位不为0的情况去做,这样就可以求出F(N)了
2 求一个全排列函数:
如p([1,2,3])输出:
[123],[132],[213],[231],[321],[323].
void permutation(int a[],int left , int right)
{
if(left>right){
for(int i=0 ; i<=right ; i++)
printf("%-4d",a[i]);
printf("\n");
}
for(int i=left ; i<=right ; i++){
swap(a[left],a[i]);
permutation(a,left+1,right);
swap(a[left],a[i]);
}
}
求一个组合函数
如p([1,2,3])输出:
[1],[2],[3],[1,2],[2,3],[1,3],[1,2,3]
这两问可以用伪代码。
void dfs(char c[] , int n , int depth , char a[] , int &k){
if(depth==n){
return;
}
for(int i=depth ; i<n ; i++){
a[k]=c[i];
a[k+1]='\0';
printf("%s\n",a);
k++;
dfs(c,n,depth+1,a,k);
k--;
}
}
void printall(char c[])
{
int k=0;
int n=strlen(c);
char *a=new char[n+1];
dfs(c,n,0,a,k);
}
三设计(具体题目请见链接,个人觉得百度的这道题目非常的有意思,他将他的技术问题抽象成了这么一道面试题,非常能考验应聘者的水平)
有两个十亿数据的表,表是xxID,xx,xx,xx之类的几个项,存的是url之类的,只说是存到硬盘的,中间没说内存限制什么的。
其中有一问是实现数据查找中的and ,or ,sub(与集, 交集,差集) 。其中要实现and(sub())之类的功能。
还有并行实现…不记得了。
问题如下:
1)设计一种数据存储格式与读取方法,主要从查询性能考虑,兼顾资源利用;
2)设计一种检索线程模型,需要支持多线程并发查询;
3)设计一种算法,支持AND,OR,SUB三种运算;
1>需要支持括弧操作,譬如如下查询:ID1 SUB(ID2 AND ID3) OR ID4;
2>考虑如何支持截断优化策略:当获取到前100个最终URLNo结果后停止后续检索过程;
另外一问是当查找(比如and运算)出前100位时,怎么让它停下来,不要再查找了。怎么实现这种高效查找前100位的运算。
这其实是倒排索引的结构,每一个TermID为一个索引,后面连接的Url为其索引的URL。题目第一问要求你为这种倒排索引结构设计一个不错的数据存储格式以支持较好的查询性能。
a[2n],a[2n+1]
void add_element(int *a , int size , int val){//小顶堆
a[++size]=val;
for(int i=size ; i>0 ; i/=2){
if(val<a[i/2])
a[i]=a[i/2];
else
break;
}
a[i]=val;
}
void SIFTDOWN(int *a , int i , int size){
int val=a[i];
int p=0;
while(i<=size){
if(a[2*i]<a[i])
p=2*i;
if(2*i+1<=size && a[2*i+1]<a[i])
p=2*i+1;
a[i]=a[p];
if(i==p)
return;
a[p]=val;
i=p;
}
}
int ExtractMin(int *a , int& size)
{
int val=a[1];
a[1]=a[size--];
SIFTDOWN(a,1,size);
}
3 通过某种hash算法,可以让用户稳定的均匀分布在一个区间内,这个区间的大小为100%,分布的最小粒度为0.1%,我们把这种区间叫做一层,现在有两个区间A、B,如何让层A中的任意子区间段都均匀分布到层B的100%中?例如:层A中取10%,这10%会均匀分布到层B中,即:层B的每一个10%区间都会有1%的区间A中的10%,也可以说层B的。如果现在有超过10层,每一层之间都需要有这种关系,又如何解决?
void permutation(int a[],int left , int right)
{
if(left>right){
for(int i=0 ; i<=right ; i++)
printf("%-4d",a[i]);
printf("\n");
}
for(int i=left ; i<=right ; i++){
swap(a[left],a[i]);
permutation(a,left+1,right);
swap(a[left],a[i]);
}
}
void dfs(char c[] , int n , int depth , char a[] , int &k){
if(depth==n){
return;
}
for(int i=depth ; i<n ; i++){
a[k]=c[i];
a[k+1]='\0';
printf("%s\n",a);
k++;
dfs(c,n,depth+1,a,k);
k--;
}
}
void printall(char c[])
{
int k=0;
int n=strlen(c);
char *a=new char[n+1];
dfs(c,n,0,a,k);
}