经过几个月的努力, 春招应该就这么结束了。总的来说这次春招结果还是比较理想(去哪儿网 offer + 百度 offer)。有点遗憾是腾讯一面由于我的项目经验不足, 而把我挂了。面试之前, 在网上看了许多面经, 对我的帮助也很大, 因此, 我也就决定写点东西, 算是对前人的工作的回报, 也算是为后来者提供经验。
去哪儿网的面试安排在成都春熙路的亚朵轻居, 酒店的氛围还是很温馨的。到了之后, 先让我们签到排队, 等待面试官叫号。
去哪儿网的一面面试官是我遇到的最好的面试官, 没有之一。因为这是我第一次面试, 过程中出现了许多尴尬的事情, 面试官很亲切的让我别紧张。有的问题我不太了解, 他也循序诱导, 让我最后得出较为满意的结果。面完之后, 就让我去等候室等二面。
下面是一面问题的罗列:
(1) STL 相关: STL 中的内存管理(allocator)的原理, 以及如何让它线程安全。
因为我对 STL 源码比较了解, 所以就很轻松地回答了 allocator 的实现原理, 相关实现可以参考《STL 源码剖析(侯捷)》。
由于对线程安全了解的比较少, 所以直接我给面试官说我不知道。面试官也没多说。等到后面回答了线程安全的单例模式时, 面试官让我把那里线程安全的知识用在这里来。然后我就大概写了一下分配器工作的关键代码的伪代码, 然后试着去加锁。最后面试官还是觉得很满意的。
(2) 操作系统相关: 什么是进程, 什么是线程。它们之间的区别和联系。
(3) 设计模式相关: 单例模式及其应用
(4)数据结构相关: 判断一个链表是否有环
bool hasCircle(ListNode* pHead){
ListNode* pFaster = pHead;
ListNode* pSlower = pHead;
do{
// 快指针走两步
if(pFaster->next != NULL) pFaster = pFaster->next->next;
// 慢指针走一步
pSlower = pSlower->next;
}while(pFaster != NULL && pSlower != NULL && pFaster != pSlower);
if(pFaster == NULL || pSlower == NULL) return false;
return true;
}
去哪儿网二面的面试官明显比一面面试官年纪大, 估计应该是管理层的。一开场就问了特别难的问题, 表示一脸懵逼。好在后面的问题回答得还算可以, 因此, 面试完之后, 面试官就让我去等 HR 面。
(1) 在公网的两台服务器, 每个服务器都有一个标准的时钟, 已知其中一个服务器时钟是准确的, 另外一个服务器的时钟快或慢了一些。请设计同步时钟的算法。
(2) STL 源码中的 hash 表的实现
HR 面就没什么好说的了。就是谈谈人生, 聊聊理想, 说说薪资。然后说我已经过了, 但是 offer 要等 5 月份, 全部人面完了之后一起发。然后 5 月初就收到了确认邮件。总的来说, 去哪儿网的面试还是很轻松的, 面试官人也都比较好。
腾讯是我这次春招的痛点啊。实在是为了腾讯面试准备了太久, 但是想不到一面就没有过。面试官结束之后说了句 “基础很扎实, 就是项目经验不足”。 顿时心都寒了。为了去参加腾讯面试, 还从四川千里迢迢跑到陕西, 没想到…
(1) 实现一个循环队列。
(2) 一个程序从开始运行到结束的完整过程。
(3) STL 的 unordered_map 和 map 的区别
(4) … (记不住了…, 对于不收我的公司, 连面试题目我也记不住。 呵呵…)
参加百度校招的经历算是一波三四五…折了。先是由于自己在百度校招官网申请了实习生, 学长的内推就没成功。然后由于腾讯一面就挂了, 没什么心情参加百度笔试, 差点儿就没参加了。 笔试通过后又通知我去北京现场面试,然而我根本没时间。发邮件给 HR 改为视频面试, HR 说改了之后可能会失去机会。没办法, 只好改了。还好, 当天晚上就给我发了视频面试的邀请。
总的来说, 百度更重视基础, 不太重视项目经验。 几乎全程都在问 C++ 和 数据结构之类的问题。
由于网络原因, HR 一面面试官几乎就没有用牛客网的平台, 直接打电话给我手机 —— 视频面试变成了电话面试。 = =!
(1) 写一个 memcpy() 函数
void *memcpy(void *dst, const void *src, size_t len)
{
if(NULL == dst || NULL == src){
return NULL;
}
void *ret = dst;
if(dst <= src || (char *)dst >= (char *)src + len){
while(len--){
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}else{
src = (char *)src + len - 1;
dst = (char *)dst + len - 1;
while(len--){
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return ret;
}
(2) 写一个快排
* 这也是老生常谈的问题了。
//[beg, end)
void QuickSort(vector<int>& datas, int beg, int end){
if(beg+1 >= end) return;
int i = beg, j = end - 1;
while(i < j){
while(i < j && datas[i] <= datas[beg]) ++i;
while(i < j && datas[j] > datas[beg]) --j;
if(i < j) swap(datas[i], datas[j]);
++i, --j;
}
swap(datas[beg], datas[j]);
QuickSort(datas, beg, j);
QuickSort(datas, j+1, end);
}
(3) 进程和线程的区别
(4) 介绍一下 STL 源码的内容。
(5) vector 的实现
(6) C++ 与 C 的区别。
(1) 单例模式
(2) 在C++中的 const 和 static 用法。
这个比较多, 详细的可以自己在网上找找。
(3) 计算下面几个类的大小
class A {};
: sizeof(A) = 1;class A { virtual Fun(){} };
: sizeof(A) = 4(32位机器)/8(64位机器);class A { static int a; };
: sizeof(A) = 1;class A { int a; };
: sizeof(A) = 4;class A { static int a; int b; };
: sizeof(A) = 4;(4) 已知某类:
class A
{
public:
A(int x){}
}
问: A a = 1;
是否正确, 如果正确, 那么它调用了哪些函数?
explicit
因此可以 int 类型强制转换来。因此, 该表达式正确。(5) 代码找错:
char* str = "hello"; 1)
char* p = new char[5]; 2)
strcpy(p, str); 3)
cout << p << endl; 4)
(6) class {}
内部实现的函数。
(7) C++ 语言的特性
(8) C++ 语言的虚函数相关
(9) 重载和重写的区别
百度三面比较随意。面试官也就随便问问代码, 聊聊人生。
(1)翻转一个链表
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
stack stk;
stk.push(nullptr);
while(pHead != nullptr){
stk.push(pHead);
pHead = pHead->next;
}
ListNode* tmp = nullptr;
while(stk.empty() == false){
if(tmp == nullptr){
pHead = tmp = stk.top();
}else{
tmp->next = stk.top();
tmp = tmp->next;
}
stk.pop();
}
return pHead;
}
};
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode* newHead = nullptr;
while(pHead != nullptr){
ListNode* tmp = pHead->next;
pHead->next = newHead;
newHead = pHead;
pHead = tmp;
}
return newHead;
}
};
(2) 冒泡排序
void bubble_sort(int datas[], int n)
{
if (NULL == datas || 0 == n)
{
return;
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n - i; ++j)
{
if (datas[j] > datas[j + 1])
{
swap(datas[j], datas[j + 1]);
}
}
}
}
(3) 为什么选择百度
5月6日面试, 5月17日收到 HR 的通知。确认信息, 问我是否有其他 offer, 选择入职时间, 实习时间。blabla…
总的来说, 这次春招的结果还算满意。中间可能也对自己的实力感到怀疑, 但是幸好自己没有放弃!