2022阿里暑期实习面经记录
投递的是【阿里集团-CTO线-智能引擎事业部】,存储方向,有一位学长工作offer签了这里,即将入职,于是他推荐我来他这组实习。
3.9 一面 电话面试
不到一个小时
前面25分钟,自我介绍+聊项目,面试官问项目真的问的超级细,字节暑期夏令营的那个项目,点怎么存的,边怎么存的,用的什么数据结构存的,点和边之间的关系怎么表示的,都问了一遍。-_-||
接下来一道智商题,大概10分钟:64 匹马,8 个赛道,最少几场比赛找出最快的 4 匹马
再接下来,笔试算法题,面试官往邮箱发一封邮件,点进去做,题目都挺简单,大概做了不到二十分钟吧
一共两道题,第一题
有无限数量的1,5,10,20,100面值的硬币,问最少多少个硬币能凑到N元钱。 ------ 贪心即可
第二题
给你一个数组,比如[5,7,7,8,8,8,10],再给你一个数字k,问k在数组中的首尾范围,若不存在输出[-1, -1]。比如k=8,则输出[3, 5] ------ 二分查找,先对k进行二分,再对k+1进行二分(即C++中的lower_bound和upper_bound),其中的差值即是答案。
3.14 笔试
6道单选,6道多选,3道算法题,一个半小时,时间还是有点紧张的。对于我来说,选择题还是有点难度的,考查的知识面非常广,操作系统,数据库,数据结构,Linux系统知识,计算机网络都有涉及到。而对于基础架构部门这个大方向来说,数据库知识很少会用到,所以这方面就比较薄弱。前面选择题大概用了30多分钟,后面算法题的时间就不太够了,第三道算法题没有写完,笔试结束后又花了十分钟给它写完了。
算法题第一题
给你一个0x12ab3格式的十六进制字符串,字符串长度<=200000,问转成二进制之后包含多少个1。保证由0x开头,a-f均为小写 ----- 一个十六进制位对应四个二进制位,打表或者针对每个十六进制位分别去计算都可以,我是打表做的
#include <iostream>
#include <map>
using namespace std;
map<char, int> mp;
void init() {
mp['1'] = 1;
mp['2'] = 1;
mp['3'] = 2;
mp['4'] = 1;
mp['5'] = 2;
mp['6'] = 2;
mp['7'] = 3;
mp['8'] = 1;
mp['9'] = 2;
mp['a'] = 2;
mp['b'] = 3;
mp['c'] = 2;
mp['d'] = 3;
mp['e'] = 3;
mp['f'] = 4;
}
int main() {
init();
string s;
int ans = 0;
cin >> s;
for (int i = 2; i < s.length(); i++) {
ans += mp[s[i]];
}
cout << ans << endl;
return 0;
}
第二题
(题目描述之后再补)
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, m;
int ans = 0;
cin >> n >> m;
vector<vector<int> > a(n, vector<int>(m));
// cin && left
for (int i = 0; i < n; i++) {
int flag = 0;
for (int j = 0; j < m; j++) {
cin >> a[i][j];
if (a[i][j]) flag = 1;
if (!a[i][j] && flag) ans++;
}
}
// right
for (int i = 0; i < n; i++) {
int flag = 0;
for (int j = m-1; j >= 0; j--) {
if (a[i][j]) flag = 1;
if (!a[i][j] && flag) ans++;
}
}
// up
for (int j = 0; j < m; j++) {
int flag = 0;
for (int i = 0; i < n; i++) {
if (a[i][j]) flag = 1;
if (!a[i][j] && flag) ans++;
}
}
// down
for (int j = 0; j < m; j++) {
int flag = 0;
for (int i = n-1; i >= 0; i--) {
if (a[i][j]) flag = 1;
if (!a[i][j] && flag) ans++;
}
}
cout << ans << endl;
return 0;
}
第三题
(题目描述之后再补),一道大模拟,我觉得我写的应该没问题吧
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int N = 8;
char mp[N + 2][N + 2];
queue<char> qu[N + 1];
int d[4][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
void make_zero(int x, int y, char color) {
mp[x][y] = ' ';
for (int i = 0; i < 4; i++) {
if (mp[x + d[i][0]][y + d[i][1]] == color) {
make_zero(x + d[i][0], y + d[i][1], color);
}
}
}
int check_zero(char opt) {
int ans = 0;
if (opt == 'a') {
for (int i = 1; i <= N; i++) {
int head = 1, tail = 1;
while (tail <= N) {
while (mp[i][tail] == ' ') {
tail++;
}
if (tail > N) break;
mp[i][head] = mp[i][tail];
head++; tail++;
}
for (int j = head; j <= N; j++) {
mp[i][j] = qu[i].front();
qu[i].pop();
ans++;
}
}
} else if (opt == 'd') {
for (int i = 1; i <= N; i++) {
int head = N, tail = N;
while (tail >= 1) {
while (mp[i][tail] == ' ') {
tail--;
}
if (tail < 1) break;
mp[i][head] = mp[i][tail];
head--; tail--;
}
for (int j = head; j >= 1; j--) {
mp[i][j] = qu[i].front();
qu[i].pop();
ans++;
}
}
} else if (opt == 'w') {
for (int i = 1; i <= N; i++) {
int head = 1, tail = 1;
while (tail <= N) {
while (mp[tail][i] == ' ') {
tail++;
}
if (tail > N) break;
mp[head][i] = mp[tail][i];
head++; tail++;
}
for (int j = head; j <= N; j++) {
mp[j][i] = qu[i].front();
qu[i].pop();
ans++;
}
}
} else if (opt == 's') {
for (int i = 1; i <= N; i++) {
int head = N, tail = N;
while (tail >= 1) {
while (mp[tail][i] == ' ') {
tail--;
}
if (tail < 1) break;
mp[head][i] = mp[tail][i];
head--; tail--;
}
for (int j = head; j >= 1; j--) {
mp[j][i] = qu[i].front();
qu[i].pop();
ans++;
}
}
}
return ans;
}
int main() {
int n, ans = 0;
int x, y;
char opt;
scanf("%d", &n);
for (int i = 1; i <= N; i++) {
scanf("%s", &mp[i][1]);
}
getchar();
for (int i = 1; i <= N; i++) {
for (int j = 0; j < n * N; j++) {
scanf("%c", &opt);
qu[i].emplace(opt);
}
getchar();
}
for (int i = 0; i < n; i++) {
ans = 0;
scanf("%d %d %c", &x, &y, &opt);
// x--; y--;
make_zero(x, y, mp[x][y]);
// for (int j = 1; j <= N; j++) {
// printf("## %s\n", &mp[j][1]);
// }
ans = check_zero(opt);
// printf("-------------------\n");
// for (int j = 1; j <= N; j++) {
// printf("## %s\n", &mp[j][1]);
// }
printf("%d\n", ans);
getchar();
}
return 0;
}
3.15 二面 视频面
二面的面试官应该是组里的leader吧,感觉很有经验,会引导你去思考问题,也会引导性地去提出问题,而不是上来就先做个自我介绍,然后再做道算法题这种模式。
面试过程中没有做那种很刻板的自我介绍,问了问实验室课题在做什么,然后对于字节夏令营的项目和商汤实习也都进行了比较细致的提问
接下来考查了几道智商题。
第一题
扔骰子,1 2点A赢,3 4 5点B赢,6点重新扔,问最后B赢的概率 ------ 稳妥一点,等比数列求解,得到答案是3/5。得到答案后猜想,直接第6点不看,按前5点算,不就是3/5嘛
第二题
1毛钱能买一个桃,3个桃核能换一个桃,给你1块钱,问最多能吃到几个桃 ------ 直接计算是14个桃,同时剩2个桃核,于是我回答了14。 面试官问:剩下的2个桃核有别的用嘛。我答:没有。面试官:这么斩钉截铁就回答没有? 继续思考,跟别人借1个桃核,3个桃核换一个桃,吃完之后的桃核再还给他,于是最多能吃15个桃。 ------ 后续面试结束之后,我去百度搜索这个问题,发现标准答案还真的就是上面我说的那个(笑)
第三题
二维平面内,给你n个点,n个点之间的横坐标各不相同,问怎么求得两点之间斜率最大的两点是哪两个点 ------ 刚开始想的是把所有点排序,在每个单调递增区间内找斜率最大值,然后再在这几个最大值这寻找最大值 面试官提示,如果所有点都是递减的,不存在单调递增区间呢,所有的斜率都是负值 继续思考,画图,发现只需在排序后求相邻两点间的斜率并且取最大值即可 ------ 面试结束后,找到是这道题,题解,https://www.cnblogs.com/nowandforever/p/4616937.html 原题,http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1100
第四题
(1)给你一个有序数组,已知有一个数出现的次数超过了数组的一半,问这个数是多少 (2)给你一个有序数组,不确定是否有一个数出现的次数超过了数组的一半,问怎么知道到底有没有一个数出现的次数超过了数组的一半 ------ (1)比较好想,很快就想出了答案,数组的中位数n/2这个点,就是答案 (2)思考了一段时间,也尝试了几个错误答案,最后得到的答案是: 因为如果有一个数出现的次数超过了数组的一半,那么它一定会经过n/2这个点, 对n/2这个点的值,进行二分查找,找到它的起始位置,对起始位置下标加上n/2之后,如果数值没有变,就说明存在,反之不存在
最后一道算法题,经典问题,k个一组翻转链表。
面试结束,面试官介绍了一下组里的工作内容,说有其他想找实习的同学也可以推荐过来,然后接下来等待HR面~
后续还剩一个心理评测没有做
总结
整个面试过程中都没有考查八股文,这一点还是比较舒适的,正好我八股文背的也不是很熟(笑)
发表评论