2022阿里暑期实习面经记录

  • 2022-03-15
  • 1,340
  • 0
  • 0

投递的是【阿里集团-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面~

 


后续还剩一个心理评测没有做

总结

整个面试过程中都没有考查八股文,这一点还是比较舒适的,正好我八股文背的也不是很熟(笑)

评论

还没有任何评论,你来说两句吧

发表评论

冀ICP备19026961号