腾讯校招现场一面(4.11)
现场面体验不是很好,主要等了太久了。上班到中午,吃个饭刚好去索菲亚酒店。两点叫我过去面试,面了十分钟(问了进程通信、Linux、数据库引擎区别),又说我不会C++,让我等面Java的同事,然后就等了N久,直到五点,期间居然有内推的约我晚上七点半面试,懵逼。
大概面了一个钟,感觉是最久的一次面试了。现场和面试官可以交互感觉很棒,我不会的面试官也给我讲了原理之类的。
自我介绍
手撕代码
给出n个长度不定的有序数组,如何找到n个数组都出现的元素。(下面中a为最短的数组长度,b为最长的数组长度)
一开始直接说使用二分去遍历,复杂度O(n * a * logb)。
想了几分钟,在面试官的旁击侧敲下想到了复杂度为O(n * b)的算法。具体是对于每个数组使用一个 pointer[n] 数组,代表当前数组遍历到了哪个位置,之后一直往后找,而不必从头开始搜了。
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;
void solve(vector<vector<int> > nums) {
int n = (int)nums.size();
int pointer[n];
memset(pointer, 0, sizeof pointer);
// 找到最短的数组
int mi = 0x3f3f3f3f, id = -1;
for (int i = 0; i < n; i++)
if (nums[i].size() < mi) mi = (int)nums[i].size(), id = i;
for (int i = 0; i < mi; i++) {
bool flag = true;
int now = nums[id][i];
for (int j = 0; j < n; j++) {
if (j == id) continue;
int sz = (int)nums[j].size();
while (pointer[j] < sz && now > nums[j][pointer[j]]) pointer[j]++;
if (now < nums[j][pointer[j]]) flag = false;
}
if (flag) cout << now << endl;
}
}
int main() {
vector<vector<int> > nums(5);
for (int i = 0; i < 5; i++) {
nums[i].push_back(i);
nums[i].push_back(i + 1);
nums[i].push_back(i + 2);
nums[i].push_back(i + 3);
nums[i].push_back(i + 4);
nums[i].push_back(i + 5);
}
// for (int i = 0; i < 5; i++)
// for (int j = 0; j < nums[i].size(); j++)
// printf("%d%c", nums[i][j], j + 1 == nums[i].size() ? '\n' : ' ');
solve(nums);
return 0;
}
垃圾收集机制
到CMS的时候刚好有点忘了,面试官也刚好说后面细节就不要讲了。
B+树
讲了和二叉树和B树的区别,还有磁盘IO会快点。
三次握手(答得不满意)
画了图,问为什么是三次。
就讲了两次会建立多个连接,导致资源浪费。
面试官说这不是主要原因,就给我讲了如果只有两次连接,第一次握手的时候接收方需要在内存中维护一些例如窗口大小等资源,这个时候如果发送方频繁发出握手请求,那么就会导致内存资源浪费。用面试官的话说,就是用一台小霸王一直发请求就可以搞垮服务器。
数据库三范式(不会)
一开始很自信答了会,讲到第二范式结果卡住了,GG。
第一范式
1NF的定义为:符合1NF的关系中的每个属性都不可再分。
第二范式
2NF定义:在1NF的基础上,每一个非主属性完全函数依赖于任何一个候选码。
2NF在1NF的基础之上,消除了非主属性对于码的部分函数依赖。
1NF会存在数据冗余过大,插入异常,删除异常,修改异常的问题。
第三范式
3NF在2NF的基础上,解决了非主属性对于码的传递函数依赖的问题。
进程通信(不会)
有什么想问的
这里我问了后台的开发语言,面试官说了C++,提到了Go,不知道怎么就开始聊起了Go, 我聊了一下接口很怪异,又聊了GoRoutine,然后讲了协程,不断给自己挖坑导致GG。