最近有机会去X度--AIG面试,全程四轮,第一轮是电话面试,后面三轮是现场面试,全部要求现场编程,下面简单记录一下每轮面试的编程题目(包含我的答案):
第一轮 电话面试,
1 Implement a circular bufferun (循环缓冲区,自定义数据结构及接口函数)
#define BUFF_SIZE (100)
typedef struct __ST_CIRCULAR_BUFF
{
//起始位置
unsigned int start;
//
unsigned int end;
//可用空间
unsigned int len;
unsigned char buff[BUFF_SIZE];
}ST_CIRCULAR_BUFF;
ST_CIRCULAR_BUFF g_ST_CIRCULAR_BUFF;
int CIRCULAR_BUFF_init(ST_CIRCULAR_BUFF *p_st_buff)
{
p_st_buff->start = 0;
p_st_buff->end= 0;
p_st_buff->len= BUFF_SIZE;
memset(p_st_buff->buff,0,BUFF_SIZE);
}
int CIRCULAR_BUFF_write(ST_CIRCULAR_BUFF *p_st_buff,unsigned char c)
{
if(p_st_buff == NULL)
return -1;
if(p_st_buff->len == 0)
return -2;
p_st_buff->buff[p_st_buff->start] = c;
if((p_st_buff->start + 1) == BUFF_SIZE)
p_st_buff->start = 0;
else
p_st_buff->start += 1;
p_st_buff->len -= 1;
return 0;
}
int CIRCULAR_BUFF_read(ST_CIRCULAR_BUFF *p_st_buff,unsigned char *p_buff)
{
if(p_st_buff == NULL)
return -1;
if(p_st_buff->len == BUFF_SIZE)
return -2;
*p_buff = p_st_buff->buff[p_st_buff->end];
if((p_st_buff->end + 1) == BUFF_SIZE)
p_st_buff->end = 0;
else
p_st_buff->end += 1;
p_st_buff->len += 1;
return 0;
}
2 merge two ordered single link lists.(合并两个有序链表,按升序处理,数据结构和接口自定义)
typedef struct __NODE
{
typedef struct *next;
unsigned char value;
}NODE;
NODE *p_a_single_link_lists,*p_b_single_link_lists;
//有小到大
int merge_single_link_lists(NODE *p_a,NODE *p_b,NODE *p_new)
{
NODE *p_a_head = p_a;
NODE *p_b_head = p_b;
NODE *p_new_head;
if((p_a == NULL)|| (p_a == NULL))
return -1;
if(p_a_head->value < p_b_head->value)
{
p_new = p_a_head;
p_a_head = p_a_head->next;
}
else
{
p_new = p_b_head;
p_b_head = p_b_head->next;
}
p_new_head = p_new ;
while((p_a_head != NULL) && (p_b_head != NULL))
{
if(p_a_head->value < p_b_head->value)
{
p_new_head->next = p_a_head;
p_a_head = p_a_head->next;
}
else
{
p_new_head->next = p_b_head;
p_b_head = p_b_head->next;
}
p_new_head = p_new_head->next;
}
if(p_a_head != NULL)
p_new_head->next = p_a_head;
if(p_b_head != NULL)
p_new_head->next = p_b_head;
return 0;
}
3 找出下面函数的错误
int square(volatile int* pa) {
return *pa * *pa;
}
修改后如下
long square(volatile int* pa) {
int a = *pa;
return a * a;
}
4.检测一个整数是否是2的幂次方(我的方法是查表法,也可以用移位操作,但是取数据的应该没有查表法快速)
移位操作
应该没有直接取数快?
const unsigned int buff[32] = {
2,
4,
8,
16,
32,
64,
128,
256,
512,
1024,
1024 * 2,
1024 * 4,
1024 * 8,
1024 * 16,
1024 * 32,
1024 * 64,
1024 * 128,
1024 * 256,
1024 * 512,
1024 * 1024,
1024 * 1024 * 2,
1024 * 1024 * 4,
1024 * 1024 * 8,
1024 * 1024 * 16,
1024 * 1024 * 32,
1024 * 1024 * 64,
1024 * 1024 * 128,
1024 * 1024 * 256,
1024 * 1024 * 512,
1024 * 1024 * 1024,
1024 * 1024 * 1024 * 2,
1024 * 1024 * 1024 * 4,
};
bool check_int(unsigned int a)
{
bool ret = false;
int i = 0;
while(i < 32)
{
if(a == buff[i])
{
ret = true;
break;
}
if(a < buff[i])
{
break;
}
i++;
}
return ret;
}
5,检测大小端
int check_cpu()
{
unsigned int a = 0x11223344;
unsigned char *pa;
pa = &a;
if(*pa == 0x11)
printf("daduan");
else
printf("xiaoduan");
return 0;
}
第二轮 百度科技园2号楼
1,快速对一个整取开平方,平方根取整数
int fastSqrt(int x){
int left = 1,right = x;
int mid = 0;
while((left + 1) < right)
{
long temp = 0;
mid = (left + right)>>1;
if(mid * mid < x)
{
left = mid + 1;
}
else if(mid * mid > x)
{
right = mid - 1;
}
else if(mid * mid == x)
{
return mid;
}
}
return left;
}
2.一个有序链表的逆序(假设为升序)
typedef struct __NODE
{
unsigned int value;
struct __NODE *next;
}NODE;
int get_new_list(NODE *p_in,NODE *p_out)
{
NODE *p_in_head = p_in;
NODE *p_out_head = NULL;
while(p_in_head != NULL)
{
NODE *p_next = p_in_head->next;
p_in_head->next = p_out_head;
p_out_head = p_in_head;
p_in_head = p_next;
}
p_out = p_out_head;
return 0;
}
第二轮面试
1.有两个数组,数组a有m个元素,元素按升序排列,数组b有n+m个元素,其中前面n个元素是升序排列的,后面的m个为无意义的数据,合并a到b,保持b依然为升序数组
int a[m];int b[n + m];
int merge_two_array(int *pa,int *pb)
{
int a_start,b_start,new_start = 0;
if(pa == NULL) || (pb == NULL))
return -1;
memove(pb,pb+m,n);
a_start = 0;
b_start = m;
while((a_start < m) && (b_start < (n+m)))
{
if(a[a_start] < b[b_start])
b[new_start] = a[a_start++];
else
b[new_start] = b[b_start++];
new_start++;
}
if(a_start < m)
memcpy(a+a_start,b+new_start,(m - a_start));
return 0;
}
2。输出一个十进制整数的所有十进制位的的排列组合
打印一个整数的所有组合
例如 12345
组合为
12345,12354,
12435,12453,12534,12543,
13245,13254,13425,13452,13524,13542
14235, 14253, 14325, 14352, 14523, 14532
15234, ......
#define M (10)
void printf_data(unsigned char *p_index,unsigned char *p_data,int m)
{
int i = 0;
for(i = 0;i < m;i++)
{
printf("%d ",p_data[p_index[i]]);
}
printf("\n");
}
void do(unsigned char *p_index,unsigned char *p_data,unsigned char *p_used,unsigned char len,unsigned char step,unsigned char max)
{
if(step == max)
{
printf_data(p_index,p_data,max);
}
else
{
int i = 0;
for(;i < max;i++)
{
if(p_used[i] == 0)
{
p_used[i] = 1;
p_index[step] = i;
do(p_index,p_data,p_used,step + 1,max);
p_used[i] = 0;
}
}
}
}
void printf_int_list(int data)
{
unsigned char data[M];
unsigned char index[M];
unsigned char used[M];
int start = 0;
int temp = data;
while(temp > 10)
{
data[start] = temp % 10;
temp = temp / 10;
start++;
}
data[start] = temp;
do(index,data,used,0,start);
}
第三轮
保证逻辑完整性
void memcpy(void *p_src,void *p_dst,int size)
{
int i = size - 1;
if((p_src == NULL) || (p_dst == NULL) || (size == 0))
{
return;
}
while(i >= 0)
{
p_dst[i] = p_src[i];
i--;
}
}
还有几个问答
1。进程进通信
2。volatitle 作用
3。cache的工作原理
4。堆和栈内存那个速度快,有什么优缺点
5。地址对齐有什么好处
6。怎么写程序不影响功能的同时能降低功耗
7.。uboot