今天下午去面试阿里了,一面结束之后就被叫“回去等通知”,面完之后心情久久不能平静,因为也算是为了这次面试认真地准备了半个月,结果还是不尽人意,毕竟自己技术(算法)方面还是欠缺。反正就一次面试失败,也没什么大不了的,想想还是写点面经吧,为自己总结一下,也为其他同样面试阿里的同学借鉴借鉴。
刚开始面试官就发问了,也没让我自我介绍,说那就先问点C++基础吧。
他拿给我一张纸,上面写着:
class a
{
virtual void f1(){};
void f2(){};
};
class b: public a
{
virtual void f1(){};
void f2(){}
};
a* aa = new a;
b* bb = new b;
a* ab = new b;
问: 分别用aa 、bb、ab调用f1, f2,调用的是哪个类中的函数。很简单,aa调用的是a类的两个函数,bb调用的是b类中的两个函数,abf 1调用的是b类中的函数,f2调用的是a类的函数。然后就问我 虚函数在内存中怎么存的,我说用虚表和虚指针,然后在纸上画了画,说类中一旦有虚函数,内存中就会有一个虚表(一维数组)存储各个虚函数的地址,然后首地址存在类中。他接着问,上面创建了那三个对象, 会有几个虚表和几个虚指针。这个问题想问的其实就是虚函数表数量是基于类的还是基于类创造出来的对象,我如实地说我不是很清楚,但我认为应该是基于类的,因为不可能每创建一个对象就复制一个虚函数表,事实确实是这样,然后有几个虚指针呢?我一开始说两个,但他提示错误,想了一下,其实是三个,每个对象里面都会存一个虚指针,指向自己的虚函数表。
然后他叫我来定义一些变量。我一开始也没搞清楚要我干嘛。叫我定义一个char,一个char的指针,一个char的引用,一个char的指针的指针,一个不能更改指向的char指针(好像还有其他,记不起来了),这里主要要注意的是初始化指针的时候记得用取值符;声明一个引用的时候必须初始化;还有一个char指针的指针,我傻逼地写了char* ppa = &pa,应该这样写char** ppa = &pa(pa是指向a的指针);一个不能更改指向的char指针,是char* const cp = &a 而不是const在前。写完之后他就让我计算一下所有变量所占的字节数。
接下来问C++中德struct和class有什么区别。缺关键字的时候struct默认是public,class 默认是private,继承也是这样,除此之外没有其他区别。然后又问,那C中的struct和C++ 中的class有什么区别,也很简单,就是C中的struct不能继承和多态,只是起到封装的作用。问C中的struct和C++中的struct,class三个哪个可以写构造函数,除了C中的struct之外都可以。
然后就问网络方面的东西,叫我画出网络7层模型。我没能全画出来,实际上7层是这样的:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。他问,知道http吧,我说超文本传输协议,在哪一层呢,应用层;TCP呢,传输层;ip协议,这个我说错了,其实是网络层。
再然后是编程,先叫我定义一个链表结构。然后写个函数返回链表中倒数第k节点。
我这样写
listNode* func(listNode* root, int k)
{
listNode* first = root;
listNode* second = root;
while(k--)
{
if(second != NULL)
second = second->next;
else break;
}
if(second == NULL)
return NULL;
else
{
while(second != NULL)
{
first = first->next;
second = second->next;
}
return first;
}
}
回来后我测试了一下,正确。
最后是算法题
有一个文件里面有10的8次方个int32位的整数,内存装不下这么多的数,问要怎么找出最大的k个数?
我是这样说的,先把文件中德数hash到多个小文件中,然后在各个文件中维护一个最小堆,最终每个文件找出本文件内最大的k个数,之后收集这些数排序。结果他说了一句,你这操作有很多计算量是不需要的,我马上就说最后不用排序,还是维护一个最小堆。然后他问第二个问题,怎么给这些数去重?我想了一会说最简单的就是还是先分成子文件,然后子文件内排序....我只是想先说出最烂的做法让他问怎么优化好让我继续想的,结果他说,那我这边就没什么问题了。。