面经汇总

    记录双非渣本,非科班软件工程专业学生的面试记录。在校期间主要是进行了竞赛相关的事情,没有做过项目,害怕内卷,大三上学期就开始准备外出实习增加一点实习/项目经验。欢迎能看到这片文章的公司能有幸给我一个面试的机会(联系我要简历哇)。

2020

开通金融

岗位: C++ 实习生
时间: 11.12
base: 北京
状态: 拒 OFFER

一面

  电话面,C++ 语法方面问了我 C++ 多态的含义,为什么使用多态,虚函数、纯虚函数的意义,new/deletefree/malloc 的区别,(C++ 八股文)。计算机操作系统方面问了一些进程/线程同步的问题,以及几个锁的知识,提到了一个锁队列我没听说过 (面试官说,来之前我也没听说过)。说了一下堆和栈的区别。还有 (操作系统的八股文)。之后就是和面试官聊竞赛,吧啦吧啦,反问了去了能学到什么,会做那些工作。时间大概在 20 分钟左右。第一次面试心里很紧张,很多自己知道的知识描述的很乱,没能很好的展示自己。

HR 面

  电话面,一面大概过了 20 分钟 HR 就打电话过来谈薪,也很庆幸第一次的面试能有了结果,但是教练这边更希望我能参加完后续的比赛后再出去实习,于是拒绝了这份工作。

电魂

岗位: C++ 服务器开发
时间: 11.27
base: 杭州
状态: 一面挂

一面

  电话面,电话大概持续了半个小时左右,第一个问题就是问我难道不需要上课么?我大概回答了一下,因为学校后期的课程都在转移到人工智能方向,而且双非渣本确实感觉到那些课程是纯理论的课程,老师不想讲学生不想听,于是就想早早出去实习。然后开始问了我一下 structunion 的区别,以及它们两个都有什么缺点。然后我说了一下两者的存储时所占用的内存空间,说了 struct 的缺点,但是一时间没想到 union 的缺点。然后问了我一个一些服务器开发的问题:

  1. 有两个 0~1000 范围的变量如何存储这两个变量使得它们在网络传输中所占用的带宽最小
一开始想到了把两个变量相加,但是传输过去后想不到什么好的方法能再拆开,然后说了用 `struct`,`enum`,但是感觉都是使用了两个 `int` 类型的变量。然后面试官提示了一下字节,想到把 `int` 的 32 位拆分成两个 16 位,分别存储两个 0 ~ 1000 的变量。
到现在我还是很不解,为什么要做这种极致的压缩,在传输的过程中一个 TCP 包完全可以包括这两个小数据,并且为了维护这个传输的规则需要在 TCP 数据包中额外添加一个用于描述此种拆分数据方式的规则,
好像增加了数据的传输带宽。而且怎么看这都是应用层的优化,不是传输层,不解。
  1. 在一个游戏中有匹配和取消匹配两个选项,TCP 建立连接后是如何让客户端是如何让服务端知道自己做了什么选择?
说实话没有仔细了解过这个事情,对于 TCP 的了解只停留在传输的过程,协议的格式,时序图,具体内部的实现没有了解过,盲猜了一手说 TCP 数据包头部应该能携带相关的数据用于判断,
又想了一下好像 TCP 报文没有能存储自定义数据的地方,就很不自信,但是面试官说是可以的,也不知是怎么实现的。

  上面两个问题都没回答好,然后开始让我介绍一个项目,做过的 demo,随便说一个,然后真的没有什么项目于是就...面试官推荐我到 Github 上多看看一些开源的项目,说什么你的算法数据结构已经很好了,可以去看一些项目了,时间还长多去学一些和计算机相关的知识就不了了之了。说一个星期后等二面。

二面

  也是刚面试结束一会, HR 发来信息开始问我的情况,问我怎么知道的电魂,对电魂了解多少,是不是想留在电魂还是只想在电魂学习,换一个学习环境,你觉得电魂能带给你什么等等等等,最后 HR 一句可能不太行,电魂 DONE!

百家云

岗位: C++ 开发实习生
时间: 12.2 - 12.3
base: 北京
状态: 拒 OFFER

一面

  两位面试官都很和蔼,说起话来很放松,(但是我全程紧张,可能是上次面试挂了有点怕)。好像什么都问了又好像什么都没问??问了我一个进程调度的问题,由于实在没学过,只听说过有一个时间优先调度还有一个啥紧急调度啥的感觉要补一补这方面的知识了。C++ 语法方面的知识答的还算好,基本上都答出来了。网络方面的话,有些东西有印象但是记不太清了,尤其是那个 TCP 的拥塞控制,只记得快启动慢恢复,还有那个回复的时间图像,但是具体的方法记不清了,确实要复习emmm。还有就是四次挥手差点被我描述成三次挥手,紧张的雅痞。然后问了我一些算法的思想,主席树啊,快排啊,等等都是我博客上写的东西。然后问了我一些树的知识,例如二叉排序树,平衡树 (只听过,真不会),手写代码的时候写出来了 BUG,很简单的代码,就很离谱,搞不懂自己脑子当时在想什么。然后就开始闲聊,emmm,面试体验很好1。结尾留给了我一个问题,至今也没有想到什么好的解法。
ps: 面试官是 14 级计科 ACM 的学长,呜呜瞬间感觉开始给他介绍 ACM 的时候好尴尬~~~

那个,我多问一个问题吧,你就把你的想法说一下就好。
现在有一个随机数生成器,能生成 1~5 五个数字。现在希望你能将其改造成能够等概率生成 1~2 这两个数的随机数生成器。

我的答案
1. 当随机出来的数字是 5 时,直接 continue,然后剩下的直接除2 输出就行,这样会慢,因为有 20% 的概率的数据是无用的
2. 感觉是因为序列的奇偶个数不同,每次取消一个数字就能保证这个序列的奇偶数字个数一样,从而保证1和2的概率相等。但是慢就慢在,去掉的这一个数字产生的概率,所以当一下产生很多个 1-5 的数字,这个区间的数字很大时这个去掉的数字出现的概率就很小甚至可以忽略的时候应该就很快了

二面

  第二天晚上临时通知我二面,总经理面直接咯噔了一下。好像都在聊人生,聊技术,聊发展。然后问了一个海盗分金的问题,也暴露了自己不认真读题的毛病,但是总体的思路得到了面试官的认可还算可行。聊了半小时,很愉快的结束了面试。等 HR 面了。

HR 面

  好像基本上就没有这个面试,直接跟我沟通 OFFER 了,说老板那边催让赶紧办理入职,好像下周一就能拿到 OFFER,还是很开心的。

跟谁学

岗位: 后端 golang 研发工程师 (实习)
时间: 12.04
base: 北京
状态: 拒 OFFER

一面

  自我介绍完了以后就直接开始写题,是在一个他发来的网页上,但是不能编译运行,题目描述如下,好像是哪里的原题,有印象写过,想了一下就用单调队列能解,于是说了一下思路,写了一下代码,也没让运行,面试官说思路差不多,写的看上去没什么BUG,就过了。第二个问题,当时脑子抽了,没想到边读边写,说了用字典树去省去一些空间,也说了把 100G 的 IP 文件分开去读写,但是忽略了一个问题,局部小不是全局小,局部大不是全局大,面试官给了提示然后我想明白了然后就过了。

1. 编程题:求一个字符串中没有重复字符的最长子串。
2. 思维题:有一个 1G 内存,硬盘无限大的电脑,要处理一个 100G 大小的存有 IP 地址的文件,要求取出现次数最多的 10 个 IP 地址

  然后问了一些 C++ 的基础知识为什么是面向对象啊,怎么实现的啊等等,问了 TCP 可靠的原因、流量控制,以及 Socket 编程的一些知识,都是比较基础的。操作系统的话好像是没有问我。这部分面试的话很顺利,没有什么卡壳的地方,问的问题都还能回答出来,相比我在百家云的面试而言更简单一点。

  反问环节,问了面试官主营的业务,以及如果我去了会做哪些业务,问了一下会有几次面试,他说实习的话技术面只有一面进度也比较快,就结束了。面试时长大概是 30 分钟左右。

HR 面

   下午14:40 刚结束的面试说进度比较快,晚上 6 点 HR 就发信息要 HR 面了,说处理的快没想到是这么快。。。也没有聊什么,只问了我的基本情况,说了一下薪资待遇,问了一下我的入职日期。然后问我有没有接着面别的公司,然后说了一下百家云的 OFFER,HR 说那不是从我们这里分出去的公司么,还是来总部比较好,就结束了。

货拉拉

岗位: C++ 研发实习生(导航方向)
时间: 12.10
base: 北京
状态: 一面挂

一面

  面试的我浑身别扭,可以说是最难受的一次面试,面试官给我的感觉就是,在我回答任何问题之前,都要先问问面试官还有那些情况,还有那些没说明但是要我自己去询问的条件。时间间隔时间有点长了,尽量回忆的写吧。按照简历从上到下问了一遍,都很基础。让我写一个二分,一会一句,这里用户不能这么输入,不能这么设计接口,让我说一下怎么判断两个日期的相差了多少天,问了我 C++ 的八股文。问了我数据库,我直接说了只是最基础的会用,也没多问了,反正就是浑身难受。反问阶段:后期会不会调岗,说是按照个人意愿选择,一共有几面,他说有三面,让我下周三等通知。

一面更新

  时隔一周,HR 发来信息说不合适,想到也是意料之中,给出的评价如下:
image.png
  我实在想不通怎么才是整体成熟度,那个东西应该是在实际组内项目应该考虑的吧,我面试的是实习岗位,也要去面面俱到的考虑所有用户开发的情况么?答题的思路,面试官想要的答题思路就是,不断向面试官索要线索,而我好像只能在当前的给出的情况下去考虑最优的解决方案,可能这也是打了 ACM 后的弊端吧。感谢没让我继续二面,谢谢贵司。

望鼎科技

岗位: C++ 开发实习生
时间: 12.14
base: 北京
状态: 拒 OFFER

一面

  常规的自我介绍,然后直接我 C++ 11 的相关知识,问了我 C++ 11 有那些新特性,具体说一下右值引用和普通引用的区别, std::movestd::forward 这两个关键字,说实话没用过,只知道作用是啥,就没回答出来,但是面试官提示了一下,想到了 std::move 相当于一个类型转换static_cast<T&&> (lvalue)。然后问了我在使用 socket 编程的时候用的是原始的接口还是封装的 api 有没有用过 epoll 和多线程等等。然后问了我设计模式中单例模式的实现原理 - 方法。最后 C++ 的八股文随便问了几个。反问阶段:面试官强调他们是金融公司不是互联网公司,是 965 不存在 996,让我放心,然后说公司用的技术是腾讯的开源技术,说什么就🧄以后走了,想去大厂还是很有竞争力的。面试就持续了 20 分钟就结束了。

-------- 分割线 --------

2020 年的面试到此结束了,好像投哪家哪家不要(挂简历),想这早点投好像还不如金三银四。

滴滴

岗位: 后端研发实习生
时间: 12.29 --> 2.1
base: 北京
状态: 拒 OFFER

一面

  开始因为视频软件的不可抗力原因耽误了20分钟在左右的时间。常规的自我介绍然后开始询问 Linux 的常用的命令,查看剩余内存啊,查看硬盘容量 (这个没记起来),详细说一下系统调用的过程,询问我在 Linux 下都做了什么,了解过哪些线程间通讯方式,我说到了消息队列,让我详细展开说一下,emm
也不会,没答出来。开始询问我一些 STL 使用情况,问了我 unorder_map 的底层实现原理 (没答出来),问了我 set 的属性等等。然后说问我了解哪些设计模式,说一下工厂模式和代理模式。问我有没有学过 Mysql,或者 Redis,我说都没学过,问了解过跳表么,也直接说了不会。说一下,链表判环的过程,整个面试过程特别快,大概 10~20 分钟就结束了。感觉答得好一般,求过求过,过了我真直接去了。

  面试官给的评价是计算机基础和数据结构不太好,emm确实感觉自己有些东西没有理解的很深刻,面试的时候太紧张,居然忘了散列表是HASH,直接说不会,我人傻了,(一直在准备被问到红黑树的可能)。不过还有一次机会,这就补这就补。

二面

  “挂过不要紧,部门捞起接着面。”上次那个面试官又给了我一个机会。自我介绍完后就开始问我关于 C++ 语言的一些东西,问了 const 的用法,用在哪些地方都有什么作用。然后问了为什么链表要设置一个头节点,有哪些好处。堆和栈的区别以及如何只在堆上定义一个对象如何只在栈上定义一个对象(在栈上定义对象没答出来)。然后问了我对于智能指针的理解,讲一下如何设计一个 share_ptr,里面大概要包含那几个功能。然后问我设计模式相关的问题,对于常见的设计模式法则,我说了三个面试官说这个都是经验记不住也没关系,问我有没有实际用到过什么设计模式,然后问了我单例模式,什么时候用懒汉什么时候用饿汉,我说了他们俩的区别但是没答上来。算法方面面试官就没问我了,说可能已经很好了就不问了,然后就是反问阶段,面试官说组内是地图导肮的,但是不是寻路的地图导航而是做数据分析数据挖掘,做例如路径已经规划好了但是要引导用户怎么走这些。说这两天有结果的话 HR 会联系。

2021

玖玖盾

岗位: C++工程师
时间: 1.4
base: 北京
状态: 笔试挂 (卡毕业时间)
  emm,第一家笔试挂的公司,感觉我写的没毛病啊,emmm。笔试题目笔试作答
image.png

安芯网盾

岗位: Linux 开发工程师
时间: 1.6 -> 1.13
base: 北京
状态: 拒 OFFER

一面

  时间比较紧,当天做的笔试,当天晚上面试,夜里写的最后的编程题。本来说的是下午,面试官有事挪到了晚上 (考试提前离场)。 面试官是公司的 CTO(姚纪卫),面试的时候就感觉跟面试官聊什么他都了解过(基本上我会的都被问了)。。首先让我讲一下做的笔试题的思路(一套试卷,从上到下讲了一遍)。说我最后一道题思路对了,最后答案算错了。。。。然后问了关于操作系统的知识,主要问了一下虚拟内存的东西,我解释了一下 C 和 C++ 在内存分配上的规则(malloc/new) 是如何分配内存的,讲了一下关于 STL 的知识,都了解哪些容器。问我哪方面比较好,我说数据结构相对还好一点,然后让我解释了一下 map 的底层实现原理,说了红黑树的几个特点,然后面试管问是有序序列插入红黑树快还是无序快,我认为是无序,在数据极端的情况下,可能插入两次就要进行一次调整,但是无须序列的话情况乱但是没那么极端。问了一下和 AVL 的区别,解释哈希表,数据结构就到这了。问了我 TCP 的三次握手,我结合 TCP 状态转换图说了一下。最后问我学了哪些算法,巴拉了一堆让我说一下 KMP,简单解释了一下 next 数组的最长公共前缀后缀,剩下的就是反问了。

  问的问题很多,持续了大概 40 分钟,从语言 --> 操作系统 --> 数据结构 --> 计网 --> 算法。面试完后就是一个编程题,HR 给 3小时让我完成 (夜里临时借了室友电脑重新装的编译器),emmm,我写了半小时左右测试了几个当时想到的数据(总共大概用了一小时)就给发过去了,HR 看完就觉得要挂 (尽管我也这么觉得) 。面试的题目和代码仍在下面。

1.写一个函数处理文件路径:(说明:类似目录切换 \.\  表示保持当前路径,\..\返回上级)
输入任何一个路径字符串,把它转换成不含.和..的绝对文件路径,对不合法的路径/错误的路径给出提示
	比如:c:\1\2\..\3\.\1.txt  输出c:\1\3\1.txt
	比如:c:\1\3\1.txt  输出c:\1\3\1.txt

2.把一个文本文件中的内容做如下转换后(假定文件大小不大于10M字节),生成另一个新的文件把文件中的
所有*号提前,放在文件的最前面,其它内容不变,保存为一个新文件
	比如:hello *wor*ld*  处理后新文件的内容为:***hello world
        
要求:
1. 上面两个功能由main函数调用
2. 注意程序执行效率、可维护性(易维护/易读懂/)
3. 代码风格好,注释合理到位,完成时间不得超过2小时
4. 思路清晰易懂,时间和空间开销尽量最优化
5. 使用C/C++语言 (不能直接使用三方库实现)
#include <bits/stdc++.h>
#include <fstream>
using namespace std;
string simplifyPath(string path) {

    string head = "", tpath = path;
    for(int i = 0;i < tpath.size();i++) {
        head.push_back(tpath[i]);
        if(tpath[i] == ':') {
            path = "";
            for(int j = i + 1;j < tpath.size();j++) {
                path.push_back(tpath[j]);
            }
            break;
        }
    }
    //cout << head << endl << path << endl;
    for(int i = 0;i < path.size();i++) {
        if(path[i] == '/') {
            cout << "输入的路径包含非法字符 '\'" << endl;
            return "\\";
        }
    }

    stack<string> stak;
    path = path + "\\";//path末尾添加\",以便能添加最后一个分割的路径
    //cout << path << endl;
    //分割路径,将简化路径压入栈中
    //路径,temp 为""的话,最后连接路径需要加上"\"
    string temp = "\\";
    for (auto s : path) {
        // 没匹配到'\'时,将字符串放入 路径temp中
        if (s != '\\') {
            temp.push_back(s);
        } else {
            //路径为 .. 的话,将栈顶弹出
            if (temp == "\\..") {
                if (!stak.empty()) {
                    stak.pop();
                }
            }

            //路径为 . 或者无的话,当前路径无操作
            //路径为正常路径的话,压入栈中
            else if (temp != "\\" && temp != "\\.") {
                stak.push(temp);
            }
            //重置临时路径
            temp = "\\";
        }
    }
    string result = "";
    //拼接简化后的路径
    while (!stak.empty()) {
        result = stak.top() + result;
        stak.pop();
    }

    //若结果为空,返回"/"
    if (result.empty()) {
        result = "\\";
    }
    return head + result;
}

void Final(ofstream out, ifstream in) {
    char c;
    while(!in.eof()) {

    }
}

void FileChange(string path) { //传入一个要打开的文件的路径
    ifstream infile;//打开两个文件一个读一个写
    ofstream outfie;
    infile.open(path);
    string newpath = path;
    int pos = newpath.find_last_of('.');
    newpath.insert(pos,1,'1');
    cout << newpath <<endl;
    outfie.open(newpath);
    if(!infile.is_open()) {
        cout << "open error" << endl; //可以使用C++的异常处理,assert(infile.is_open());
        exit (1);
    }
    string s = ""; //临时存储区,空间换时间,也可以再开一个文件,时间换空间依据情况而定
    char c;
    while(!infile.eof()) { //循环读入
        infile >> c;
        if(infile.eof()) break;
        if(c == '*')
            outfie << c;
        else
            s.push_back(c);
    }
    outfie << s;
    infile.close();
    outfie.close();
}

int main(){
    string path;
    cin >> path;
    cout << simplifyPath(path) <<endl;
    FileChange(path);
    return 0;
}

  面试官给的评价是代码的思路逻辑清晰,但是执行的效率几乎为零,需要好好指导学习一下。然后就给我过了,emmm,写的时候就想到这样的方法肯定不行。

深信服

岗位: C/C++软件开发工程师
时间: 1.24 -> 1.27 -> 1.29
base: 深圳
状态: 挂 OFFER 审批 (因为学校不是一本)

一面

  应该是目前持续时间最长的一面了,持续了 85 min,面试官和我一样是个 ACMer,所以面试的时候全程都在聊题目和一个小项目开发需要哪些模块。简单的自我介绍过后面试官问我在对内一般负责哪些方面,说了一下数据结构还算好一点,问了我都了解哪些数据结构,有没有了解过 dp 或者数论(面试官好像是学数论和dp的),然后问了图论学过哪些,字符串呢?大概都解释了一下。然后面试官开始现场百度题目,第一道题目是一道数学题描述如下:

给定一个数字 d $(d \leq 1000)$,找出最小的数 x,保证 x 的因子个数不小于 4 个,并且任意两个因子差值大于 d。

  我的第一反应是构造,构造一个数字的因子为 $1$、$1 + d$、$1 + 2d$、 $1 + 3d$,这种,类似于贪心,但是面试官说不对,这里面有一个性质是更相减损术,用这个能解决,但是我emm,真的没学过。

  第二道题目面试官先询问了我会不会并查集,然后说了半天我发现我俩题意没对上,后来又重新想了一下。题目描述如下:

给定数字 n,m 代表有 n 个数字,m 个操作, 针对 m 个操作每次给一个 l,r 删除给出区间内最小的且存在的数字,然后输出这个数字,题目中所有的数据范围均 $\leq 10^6$。

  想了一段时间想到了离线然后用线段树去维护这个区间最后一次是被哪个操作修改过,然后倒叙去更新线段树。最后遍历一下这个线段树即可(只保留第一次遇到的相应操作),面试官说这样也行,有没有别的方法,于是往并查集上去靠,发现可以首先把 $ n $ 个数字都连在一起,当要删除一个数字的时候去遍历这个区间的数字并查集查询第一个父亲不是自己的节点,删除的话就是让 $F[x] = x$ 即可。面试官说大概思路没问题但是路径压缩的时机不对,不是在删除的时候压缩,而是在查询的时候压缩。

  第三道题目经典的树状数组,莫队题目,一开始听成了单调队列,然后反应过来后然后跟面试官说这个是 HH的项链啊,两句话说了一下树状数组的思路,这是一道卡莫队的莫队题,本题结束。

  最后一题题目描述如下:

$ n $ 个数字,有 $ m $ 次操作,每次三个数字 $ x $,$ y $,$ k $,代表把 $ x $ 位置的数字改为
$ y $,然后输出前 $ k $ 小的数字的和,题目中所有数据均 $\leq 10^5$。

  想了一下可以用 $ set $,然后里面放一个结构体代表他的下表和编号然后修改的时候二分编号找到对应的就能改,求和的话直接求和就行,面试官说可行,有没有别的方法,此时强调了一下数据范围较小。然后我想到了用权值线段树,首先权值线段树的一个功能能够查全局 $ k $ 小,然后依靠这个性质,当要把 $ x $ 位置的数字改为 $ y $,只需要在权值线段树上把相应位置的 $ 0 $ 改为 $ 1 $,反之亦然,查询的话直接通过权值线段树的性质去查即可。面试官表示也可行,说其实可以直接用数组去做,对每个操作加加,然后赋值就行了(没听懂)和你说的线段树思路差不多是一个意思。

  最后问了一工程开发的问题,如何实现代码的文本查重。首先如果有很多份代码怎么快速的处理他们的查重$n^2$么?想了一下用一个代码先去跑一遍,然后建树实现一个 BFS 的过程,乱说了一通面试官说我们下一个问题,此事已经完成了预处理,怎么能对代码进行文本查重,从那几个方面入手呢?我第一时间没思路,面试官引导了一下,如果是你你会从那几个方面更改代码防止自己被查重呢。我说了一下可以更改代码的执行顺序,执行结构,变量名,代码风格,更甚至去改变代码的语言等等。然后对着我说的情况面试官让我一点点的把他们判重。我说了一下首先应该用正则表达式把所有的变量名都统一替换,删除空格,换行,缩进等等,然后通过 Hash 去匹配判断。面试官说如何才能判断简单的变量名交换呢,我一时哑口无言,说可以尝试看看用两个字符串的子集比上两个字符串的并集拿到一个比值应该可以,两个字符串的子集面试管说可以用 $LIS$ 和最短编辑距离去做。后面就是说如何判断一个人把代码扔到另一个函数里面去执行了,我想了一会说这个东西应该没法用文本编辑去查询,面试管说这个确实,这个情况会通过编译器生成的语法树去查询,语法树记录了一个程序的执行顺序,然后问我怎么去判断两个语法树是否相同,我说了一下用 DFS 序,一开始面试官说可能 DFS 顺序一样,但是是两科语法树,我和他一起分析了一下发现不会出现这种情况,面试官说可行就结束了。最后说了一下二面面试官下周应该会联系你。

  哇真的累,是我面试过最长的一次但是面试的体验是非常不错的,能和面试官一起交流分析出来问题的解决方面,在解决最后一个项目问题上也被面试官一步一步引导尝试着去说了不错的思路一改我之前在校招中对深信服的看法。

二面

  简单的自我介绍后上来就是直接做两个算法题,第一题描述如下

有 $ n $ 个数字, $ k $ 次操作,每次删除第 $k_i$ 个位置的数字,问最后一个剩下的是哪个数字。

  权值线段树求全局第 $ k $ 小即可。

  第二题题目描述如下:

给定 $ n $ 个数字,求出一段长度为 $ k $ 下标连续的序列的和为 $ m $,以及升级版求出一段长度不定,下标连续的子序列和为 $ m $。
  基础版很容易想到用滑动窗口去做,维护一个长度为 $ k $的滑动窗口即可。然后升级版的话,我先考虑了只有正数的情况,一样维护一个和就行,小了往右,大了往左。针对负数的情况用 map + 前缀和即可,面试官说用哈希表,其实是一样的。上述两个题基本上是秒了。

  然后问我有没有想过做算法工程师方面的想法,然后问了我会 Linux 么,问了我会 AC自动机 么,我说好久没用忘了。然后问了我 static 的作用以及如何定义一个二维数组的指针使得指针加一能够跳跃到逻辑的下一维,我说我不会,面试官说可以 int *p[200] 即可,问了我会不会 memcpy/memmset,我说我知道 memset,面试官解释了一下 memcpy。最后给我出了一个抓兔子的问题:

地上有 n 个洞,有一只兔子一个农民,兔子初始的位置随机,兔子每天必须跳到相邻的洞里,农民每天可以去查看一个洞的情况,问农民执行怎么样的查看策略才能保证一定能抓到兔子。
  面试官说从程序实现的角度去分析,然后我给出了一个保证能抓到的策略。。。。面试官说策略可行,但是我他面试中是唯一一个给出确切解法的人。。。。。就离谱。

  反问阶段问了加班情况,会负责那些东西,说是近期会有人联系三面。

HR面

  最长的一次 HR 面试,问了一下我的学习情况以及为什么做竞赛,对目标工作地有什么想法和女朋友是否在一块工作,问对我影响最大的是一件什么事情,平时专业课的成绩怎么样,对预期的工作怎么样有什么想法,拿了那几家公司的 OFFER,为什么不去,对工作有哪些要求,和室友的关系怎么样,朋友呢?在集训队负责人负责什么东西,怎么安排,然后就结束了。

图森未来

岗位: 研发实习生-simulation
时间: 2.3
base: 北京
状态: 一面挂

一面

  很难受的一次面试,被问到绝望。。问各种区别,为什么是这样为什么不是那样,这样有什么好处,把我的操作系统问烂了。。。最后的算法题写了一小时也没写出来,面试官让我证明自己的算法正确性,说我的思路没问题就是要证明,最后勉强证明了,但是代码没实现成功就GG了。

CVTE

岗位: C/C++软件开发实习生
时间: 2.4 --> 2.19
base: 广州
状态: 二面过

  总体来说 CVTE 对于项目的要求较高,每次面试都会在开始的时候跟我聊我做的项目尽管我没有项目就聊平时在学校写的课程设计。。。然后就是简历上的东西过一遍,时间也有点长了就不去详细描述了,对于C++问的比较多,然后就没了。。

字节跳动

岗位: 后端开发实习生-国际支付职位
时间: 2.5 -> 2.7 -> 2.8 -> 2.10 -> 2.16
base: 北京
状态: 实习中...

一面

  前期的挂简历挂的我难受,换了一个老哥帮忙推了一下然后第二天联系我约了面试。简单的自我介绍后面试官问我 MySql 学的怎么样,然我说一下里面的事务,我说我基本不会 MySql,他还是给我出了几个 MySql 的题目,很显然,我一个都没答出来。然后问了我 HTTP 相关的问题,比如怎么连接的常见的状态码以及含义,HTTPS 的一些东西,我都没答好,因为真的没学过。然后问了我对设计模式的理解,让我手撕了一个单例模式我写了懒汉式、懒汉式线程安全、双检锁三种,面试官比较满意。然后给我出了一个题目,计算二叉树的深度以及二叉树的最大直径。然后按照面试官的要求都改了一下。最后让我说了一下 I/O 复用,说了一下 select/eopll 的区别优劣。面试官是滴滴跳出来的,听到我有滴滴的 offer 然后让我先等等,他尽力帮我年前把字节的流程走完,然后果真走完了。然后面试官说为什么我的设计模式这么好,但是数据库怎么会一点不会。。。emmmm (这就学)

二面

  二面面试官上来就把一面没回答好的 HTTPS 组合拳来了一套,我还是没答好。对于 MySql 确认了一遍我是真的不会。然后开始问我操作系统相关的知识,问了内存管理(分页,分段,段页),然后问了内存分配算法,我说了首次适应算法和最佳适应算法,然后面试官让我分析一下这两个哪个比较好,然后我说最佳适应可能好点,然后我后来去查好像是首次最好。。。。然后问了我进程线程的区别,上下文切换,操作系统这部分答的还算好。。然后面试官给我出了一道题,双指针,然后面试官给了几组测试数据都过了就结束了。然后我当天晚上开始猛看 HTTPS 的相关知识。。。。

/*
给你一个整数数组 arr ,请你删除一个子数组(可以为空),使得 arr 中剩下的元素是 非递减 的。
一个子数组指的是原数组中连续的一个子序列。
请你返回满足题目要求的最短子数组的长度。
arr = [1,2,3,10,4,2,3,5]
*/

#include <iostream>
#include <bits/stdc++.h>
#include <vector>
using namespace std;
int main() {
    vector<int> arr = {};
    int n = arr.size();
    vector<int> a;
    a.resize(n+1);
    for(int i = 1;i <= n;i++)
        a[i] = arr[i-1];
     int pre = 1;
    for(int i = 2;i <= n;i++) {
        if(a[i] >= a[i-1]) pre++;
        else break;
    }
    if(pre == n) {
        cout << "---0个数字" << endl;
        return 0;
    }
    int bak = 1;
    for(int i = n-1;i >= 1;i--) {
        if(a[i] <= a[i+1]) bak++;
        else break;
    }
    //cout << pre << " " << bak << endl;
    int ans = min(n - pre, n - bak);
    int r = n - bak + 1,l = 1;
    int al = pre, ar = r;
    for(;l <= pre;l++) {
        for(;r <= n;r++) {
            if(a[r] >= a[l]) break;
        }
        if(ans > r - l - 1) {
            al = l;
            ar = r;
            ans = r - l - 1;
        }
        ans = min(ans, r - l - 1);
    }
    for(int i = al+1;i <= ar-1;i++) {
        cout << a[i] << endl;
    }
}

三面

  三面是部门的 Leader,先问了我一些个人的基本情况以及自己的一些打算,基本全程在聊天,介绍了部门的基本情况,问我能不能接受转语言,我明确了我不写 Java,然后其他都可以。还有我的英语水平如何,部门的文档可能都是英文的,一周会给我加一节英语课能不能接受,然后就开始问问题。问了我之前没答好的 HTTPS 一些东西,我主动说了一下 HTTPS 的非对称 + 对称加密的过程以及为什么要这么做。面试官表示赞同。然后问了我 TCP 传输为什么可靠,详细说了一下拥塞控制,流量控制。然后面试官说既然是搞竞赛的就出一个难一点的题,一个比较麻烦的模拟题。

/*
给定一个数组,元素都是英文单词(由英文字母大小写、数字、标点组成,单词中间不会出现空格),以及一个正整数L,每个单词的长度都保证不超过L。要求将这些单词排版成一个段落,格式如下:

1 - 每一行的字符总数为L,每一行里相邻的单词中间至少有一个空格做间隔。单词不可以跨行,每一行应该尽可能放置多的单词。

2 - 如果一行里有多于一个单词的,要求左右对齐排版,即这行的首末字符不能是空格。如果一行只有一个单词,则左对齐,并在结尾用空格补足L个字符。

3 - 同一行内单词间隔的空格数应该尽量均匀,如果不能平均分配,则靠左的间隔可以比靠右的间隔有更多空格。比如10个空格分配给三个间隔,应该是4-3-3,而不能是5-3-2,或者3-4-3。


words = ["This", "is", "an", "example", "of", "text", "justification."]
L = 16

"This    is    an"
"example  of text"
"justification.  "
*/

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main() {
    vector<string> words = {"This", "is", "an", "example", "of", "text", "justification."};
    int L = 16;
    int i = 0;
    while(i < words.size()) {
        int j = i, len = 0;
        while(j < words.size() && len + words[j].size() + j - i  <= L) {
            len += words[j].size();
            j++;
        }
        int spe_len = L - len;
        string tmp = "";
        for(int s = i;s < j;s++) {
            tmp += words[s];
            if(spe_len > 0) {
                int tmp_spe = 0;
                if(j == words.size()) {
                    if(j - s == 1) tmp_spe = spe_len;
                    else tmp_spe = 1;
                } else {
                    if(j - s > 1) {
                        if(spe_len % (j - s - 1) == 0) tmp_spe = spe_len / (j - s - 1);
                        else tmp_spe = spe_len / (j - s - 1) + 1;
                    } else {
                        tmp_spe = spe_len;
                    }
                }
                for(int k = 0;k < tmp_spe;k++)
                    tmp.push_back(' ');
                spe_len -= tmp_spe;
            }
        }
        cout << tmp << endl;
        i = j;
    }
}
/*
This    is    an
example  of text
justification.  
*/

  面试官大概看了一下说我的思路没问题,代码的边界处理的也比较好不会有越界的情况,后面就对于部门的一些介绍以及我的一些疑问的解答,以及让我自己对自己做一个评价,询问了我想做什么。

HR面

  介绍了一下在比赛的过程中是充当怎么样的角色,然后有没有遇到很困难的东西最后是怎么解决的,对于队内的任务是怎么分配的,在比赛中最困难的时候是怎么调整的,对于从学生到职场环境状态的转变要怎么去适应,沟通能力如何,自我评价一下自己的优劣。

春招总结

  其实严格意义来说我,并没有参加过春招但是我也不会去参加春招了找工作、准备面试真的很累。很感谢上述公司给我的面试机会 货拉拉 除外。后续就真的从一个啥也不会的 Acmer 变成一个职场人了。