搜索引擎工程师面试题.docx
《搜索引擎工程师面试题.docx》由会员分享,可在线阅读,更多相关《搜索引擎工程师面试题.docx(18页珍藏版)》请在冰豆网上搜索。
![搜索引擎工程师面试题.docx](https://file1.bdocx.com/fileroot1/2022-11/24/0a6cc9ee-7b06-41b6-bcf2-3e6ccf1610ce/0a6cc9ee-7b06-41b6-bcf2-3e6ccf1610ce1.gif)
搜索引擎工程师面试题
1.给两个数组和他们的大小,还有一动态开辟的内存,求交集,把交集放到动态内存dongtai,并且返回交集个数
longjiaoji(long*a[],longb[],long*alength,longblength,long*dongtai[])
2.单连表的建立,把'a'--'z'26个字母插入到连表中,并且倒叙,还要打印!
方法1:
typedefstructval
{intdate_1;
structval*next;
}*p;
voidmain(void)
{charc;
for(c=122;c>=97;c--)
{p.date=c;
p=p->next;
}
p.next=NULL;
}
}
方法2:
node*p=NULL;
node*q=NULL;
node*head=(node*)malloc(sizeof(node));
head->data='';head->next=NULL;
node*first=(node*)malloc(sizeof(node));
first->data='a';first->next=NULL;head->next=first;
p=first;
intlongth='z'-'b';
inti=0;
while(i<=longth)
{
node*temp=(node*)malloc(sizeof(node));
temp->data='b'+i;temp->next=NULL;q=temp;
head->next=temp;temp->next=p;p=q;
i++;
}
print(head);
3.可怕的题目终于来了
象搜索的输入信息是一个字符串,统计300万输入信息中的最热门的前十条,我们每次输入的一个字符串为不超过255byte,内存使用只有1G,
请描述思想,写出算发(c语言),空间和时间复杂度,
4.国内的一些帖吧,如baidu,有几十万个主题,假设每一个主题都有上亿的跟帖子,怎么样设计这个系统速度最好,请描述思想,写出算发(c语言),空间和时间复杂度,
#includestring.h
main(void)
{char*src="hello,world";
char*dest=NULL;
dest=(char*)malloc(strlen(src));
intlen=strlen(str);
char*d=dest;
char*s=src[len];
while(len--!
=0)
d++=s--;
printf("%s",dest);
}
找出错误!
!
#include"string.h"
#include"stdio.h"
#include"malloc.h"
main(void)
{
char*src="hello,world";
char*dest=NULL;
dest=(char*)malloc(sizeof(char)*(strlen(src)+1));
intlen=strlen(src);
char*d=dest;
char*s=src+len-1;
while(len--!
=0)
*d++=*s--;
*d='\0';
printf("%s",dest);
}
1.简述一个Linux驱动程序的主要流程与功能。
2.请列举一个软件中时间换空间或者空间换时间的例子。
voidswap(inta,intb)
{
intc;c=a;a=b;b=a;
}
--->空优
voidswap(inta,intb)
{
a=a+b;b=a-b;a=a-b;
}
6.请问一下程序将输出什么结果?
char*RetMenory(void)
{
charp[]=“hellowworld”;
returnp;
}
voidTest(void)
{
char*str=NULL;
str=RetMemory();
printf(str);
}
RetMenory执行完毕,p资源被回收,指向未知地址。
返回地址,str的内容应是不可预测的,打印的应该是str的地址
写一个函数,它的原形是intcontinumax(char*outputstr,char*intputstr)
功能:
在字符串中找出连续最长的数字串,并把这个串的长度返回,并把这个最长数字串付给其中一个函数参数outputstr所指内存。
例如:
"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回
9,outputstr所指的值为123456789
intcontinumax(char*outputstr,char*inputstr)
{
char*in=inputstr,*out=outputstr,*temp,*final;
intcount=0,maxlen=0;
while(*in!
='\0')
{
if(*in>47&&*in<58)
{
for(temp=in;*in>47&&*in<58;in++)
count++;
}
else
in++;
if(maxlen{
maxlen=count;
count=0;
final=temp;
}
}
for(inti=0;i{
*out=*final;
out++;
final++;
}
*out='\0';
returnmaxlen;
}
不用库函数,用C语言实现将一整型数字转化为字符串
方法1:
intgetlen(char*s){
intn;
for(n=0;*s!
='\0';s++)
n++;
returnn;
}
voidreverse(chars[])
{
intc,i,j;
for(i=0,j=getlen(s)-1;ic=s[i];
s[i]=s[j];
s[j]=c;
}
}
voiditoa(intn,chars[])
{
inti,sign;
if((sign=n)<0)
n=-n;
i=0;
do{/*以反序生成数字*/
s[i++]=n%10+'0';/*getnextnumber*/
}while((n/=10)>0);/*deletethenumber*/
if(sign<0)
s[i++]='-';
s[i]='\0';
reverse(s);
}
方法2:
#include
usingnamespacestd;
voiditochar(intnum);
voiditochar(intnum)
{
inti=0;
intj;
charstra[10];
charstrb[10];
while(num)
{
stra[i++]=num%10+48;
num=num/10;
}
stra[i]='\0';
for(j=0;j
{
strb[j]=stra[i-j-1];
}
strb[j]='\0';
cout<}
intmain()
{
intnum;
cin>>num;
itochar(num);
return0;
}
前几天面试,有一题想不明白,请教大家!
typedefstruct
{
inta:
2;
intb:
2;
intc:
1;
}test;
testt;
t.a=1;
t.b=3;
t.c=1;
printf("%d",t.a);
printf("%d",t.b);
printf("%d",t.c);
谢谢!
t.a为01,输出就是1
t.b为11,输出就是-1
t.c为1,输出也是-1
3个都是有符号数int嘛。
这是位扩展问题
01
11
1
编译器进行符号扩展
求组合数:
求n个数(1....n)中k个数的组合....
如:
combination(5,3)
要求输出:
543,542,541,532,531,521,432,431,421,321,
#include
intpop(int*);
intpush(int);
voidcombination(int,int);
intstack[3]={0};
top=-1;
intmain()
{
intn,m;
printf("Inputtwonumbers:
\n");
while((2!
=scanf("%d%*c%d",&n,&m)))
{
fflush(stdin);
printf("Inputerror!
Again:
\n");
}
combination(n,m);
printf("\n");
}
voidcombination(intm,intn)
{
inttemp=m;
push(temp);
while
(1)
{
if(1==temp)
{
if(pop(&temp)&&stack[0]==n)//当栈底元素弹出&&为可能取的最小值,循环退出
break;
}
elseif(push(--temp))
{
printf("%d%d%d",stack[0],stack[1],stack[2]);//§ä‥i¤@?
pop(&temp);
}
}
}
intpush(inti)
{
stack[++top]=i;
if(top<2)
return0;
else
return1;
}
intpop(int*i)
{
*i=stack[top--];
if(top>=0)
return0;
else
return1;
}
1、用指针的方法,将字符串“ABCD1234efgh”前后对调显示
#include
#include
#include
intmain()
{
charstr[]="ABCD1234efgh";
intlength=strlen(str);
char*p1=str;
char*p2=str+length-1;
while(p1{
charc=*p1;
*p1=*p2;
*p2=c;
++p1;
--p2;
}
printf("strnowis%s\n",str);
system("pause");
return0;
}
2、有一分数序列:
1/2,1/4,1/6,1/8……,用函数调用的方法,求此数列前20项的和
#include
doublegetValue()
{
doubleresult=0;
inti=2;
while(i<42)
{
result+=1.0/i;//一定要使用1.0做除数,不能用1,否则结果将自动转化成整数,即0.000000
i+=2;
}
returnresult;
}
intmain()
{
printf("resultis%f\n",getValue());
system("pause");
return0;
}
有一个数组a[1000]存放0--1000;要求每隔二个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。
以7个数为例:
{0,1,2,3,4,5,6,7}0-->1-->2(删除)-->3-->4-->5(删除)-->6-->7-->0(删除),如此循环直到最后一个数被删除。
方法1:
数组
#include
usingnamespacestd;
#definenull1000
intmain()
{
intarr[1000];
for(inti=0;i<1000;++i)
arr[i]=i;
intj=0;
intcount=0;
while(count<999)
{
while(arr[j%1000]==null)
j=(++j)%1000;
j=(++j)%1000;
while(arr[j%1000]==null)
j=(++j)%1000;
j=(++j)%1000;
while(arr[j%1000]==null)
j=(++j)%1000;
arr[j]=null;
++count;
}
while(arr[j]==null)
j=(++j)%1000;
cout<return0;
}方法2:
链表
#include
usingnamespacestd;
#definenull0
structnode
{
intdata;
node*next;
};
intmain()
{
node*head=newnode;
head->data=0;
head->next=null;
node*p=head;
for(inti=1;i<1000;i++)
{
node*tmp=newnode;
tmp->data=i;
tmp->next=null;
head->next=tmp;
head=head->next;
}
head->next=p;
while(p!
=p->next)
{
p->next->next=p->next->next->next;
p=p->next->next;
}
cout<data;
return0;
}
方法3:
通用算法
#include
#defineMAXLINE1000//元素个数
/*
MAXLINE元素个数
a[]元素数组
R[]指针场
suffix下标
index返回最后的下标序号
values返回最后的下标对应的值
start从第几个开始
K间隔
*/
intfind_n(inta[],intR[],intK,int&index,int&values,ints=0){
intsuffix;
intfront_node,current_node;
suffix=0;
if(s==0){
current_node=0;
front_node=MAXLINE-1;
}
else{
current_node=s;
front_node=s-1;
}
while(R[front_node]!
=front_node){
printf("%d\n",a[current_node]);
R[front_node]=R[current_node];
if(K==1){
current_node=R[front_node];
continue;
}
for(inti=0;ifront_node=R[front_node];
}
current_node=R[front_node];
}
index=front_node;
values=a[front_node];
return0;
}
intmain(void){
inta[MAXLINE],R[MAXLINE],suffix,index,values,start,i,K;
suffix=index=values=start=0;
K=2;
for(i=0;ia[i]=i;
R[i]=i+1;
}
R[i-1]=0;
find_n(a,R,K,index,values,2);
printf("thevalueis%d,%d\n",index,values);
return0;
}
试题:
voidtest2()
{
charstring[10],str1[10];
inti;
for(i=0;i<10;i++)
{
str1[i]='a';
}
strcpy(string,str1);
}
解答:
对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string,str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;
str1不能在数组内结束:
因为str1的存储为:
{a,a,a,a,a,a,a,a,a,a},没有'\0'(字符串结束符),所以不能结束
strcpy(char*s1,char*s2)他的工作原理是,扫描s2指向的内存,逐个字符付到s1所指向的内存,直到碰到'\0',因为str1结尾没有'\0',所以具有不确定性,不知道他后面还会付什么东东。
正确应如下
voidtest2()
{
charstring[10],str1[10];
inti;
for(i=0;i<9;i++)
{
str1[i]='a'+i;//把abcdefghi赋值给字符数组
}
str[i]='\0';//加上结束符
strcpy(string,str1);
}
第二个code题是实现strcmp
intStrCmp(constchar*str1,constchar*str2)
做是做对了,没有抄搞,比较乱
intStrCmp(constchar*str1,constchar*str2)
{
assert(str1&&srt2);
while(*str1&&*str2&&*str1==*str2){
str1++,str2++;
}
if(*str1&&*str2)
return(*str1-*str2);
elseif(*str1&&*str2==0)
return1;
elseif(*str1==0&&*str2)
return-1;
else
return0;
}
intStrCmp(constchar*str1,constchar*str2)
{
//省略判断空指针(自己保证)
while(*str1&&*str1++==*str2++);
return*str1-*str2;
}
第三个code题是实现子串定位
intFindSubStr(constchar*MainStr,constchar*SubStr)
做是做对了,没有抄搞,比较乱
intMyStrstr(constchar*MainStr,constchar*SubStr)
{
constchar*p;
constchar*q;
constchar*u=MainStr;
//assert((MainStr!
=NULL)&&(SubStr!
=NULL));//用断言对输入进行判断
while(*MainStr)//内部进行递增
{
p=MainStr;
q=SubStr;
while(*q&&*p&&*p++==*q++);
if(!
*q)
{
returnMainStr-u+1;//MainStr指向当前起始位,u指向
}
MainStr++;
}
return-1;
}
分析:
intarr[]={6,7,8,9,10};
int*ptr=arr;
*(ptr++)+=123;
printf(“%d%d”,*ptr,*(++ptr));
输出:
88
过程:
对于*(ptr++)+=123;先做加法6+123,然后++,指针指向7;对于printf(“%d%d”,*ptr,*(++ptr));从后往前执行,指针先++,指向8,然后输出8,紧接着再输出8