第一阶段自我介绍。
第二阶段是C++语法。
1.虚函数问题,析构函数为什么经常被声明为虚函数?析构函数里面能调用虚函数么?
答:为了防止通过父类指针析构子类对象时能正确的调用虚函数。析构函数调用虚函数语法上是没有问题的,但是标准应该是不建议的。
2.sizeof运算符的问题。char str[12]="hello"; sizeof(str)是多少?sizeof一个类的时候,都什么会被计算?静态成员会被计算进来么?如果这是一个子类,它的父类成员会被计算么?
答:sizeof(str)结果应该是12(感谢一楼的提醒,我是又搞错了)。sizeof一个类的时候,非静态成员变量、有虚函数的话虚表指针会都计算进去,静态成员变量,还有成员函数都是不会被计算的。如果是子类,那么父类中的成员也会被计算的。
鉴于一楼回复发现的问题,我给出对比:
void GetSize(char str[])
{
void* p = malloc(15);
printf("%d\n%d",sizeof(str),sizeof(p));
}
这个函数中,无论你传递多长的字符串作为参数,输出都是4 这一点和直接char str[12]还不一样!
3.C++中什么属于多态?你有什么看法。
答:这个还是虚函数,虚函数其实是为了让程序员根据子类的实际情况实现函数,而在调用时不必关心这些细节。
4.const限定符。char const* ptr; const char * ptr, char * const ptr的区别?
前两个都是常量指针,即他们指向的位置不能更改。第三个是指向的类型是常量字符,但是指针指向的位置可以更改。
编程题
迭代实现二叉树的前序遍历?
这个用堆栈就好了
#include
#include
using namespace std;
typedef struct _Tree
{
int a;
struct _Tree* left;
struct _Tree* right;
}Tree;
void PrePrintTree(Tree* root)
{
if(root == NULL)
return;
Tree* p =NULL;
stack st;
st.push(root);
while (st.size()>0)
{
p = st.top();
st.pop();
if(p->right!=NULL)
st.push(p->right);
if(p->left!=NULL)
st.push(p->left);
printf("%d\n",p->a);
}
}
算法题:
1.给一个长度为n的字符串,怎么实现循环右移k位,k可能大于n。
这个我首先想到的是将k%n之后,将后k个字符拷贝出来,然后将前n-k个字符依次向后移动,然后把之前拷贝的k个字符拷贝到前k位上。
但是面试官问我有没有空间复杂度是O(1)的算法。我说那就是计算每个字符右移之后的下表,然后交换了。他让我写出来坐标转换的公式,当时好紧张。想了半天没写出来。
他就说先算了。。悲剧。。。
2.大数据的top k问题。说在大量数据中,n个整数,求最大的k个整数。
这个是大数据的经典问题,用最小堆,首先用前k个数构建一个最小堆,这样堆顶元素是最小的,然后遍历剩下的数,如果大于堆顶,则用它替换堆顶,并调整堆,保持最小堆。如果小于或者等于则直接跳过。
概率题:
说一个硬盘,它坏掉的可能性为x,问一年内它坏掉的可能性是多少?
我说这就是1-它一年内不坏的可能性= 1-(1-x)^365
面试官又问,说N个硬盘,一年内坏掉k个的概率?
这个我貌似说的不对,我觉得应该用贝叶斯公式,但是公式被我给忘记了。。。悲剧。。活该数理统计63分。。。
项目:
问你在做这些项目中遇到过什么问题?怎么克服的?你实习的时候做的这个项目怎么做的?
前面两个问题因人而异。最后一个我是在腾讯做地址新词的发现和提取的。给他讲了一下CRF条件随机场,以及我怎么用的,正确率多少,剩余错误数据怎么办,怎么提高正确率。
——————————————分割————————————————————————————
总的来说很不满意,尤其是C++语法,一半都答错了。丢人了。算法题也是一知半解。。。估计要悲剧了。。。