实习面试momenta经历-无人驾驶控制算法工程师

一面(考察代码能力):

首先让我做了一个简单的自我介绍;

然后发给我一到类似于力扣上面的算法题,C++版本解答,题目如下:

/* 如何会议室的使用时间区段,如 {1,4}, {2, 3}, {5, 5}, {6, 8}, {7, 8}, {9,11} 将重叠的或者连续的区段合并,那么结果是[1,4] [5,5] [6,8] [9,11]。
注意:时间区段的开始时间是有序并且是升序,所以不需要考虑排序问题。

由于题目较简单,主要考察短时间代码书写能力和边界条件考虑情况。
尽量在原地执行,即在原数组上合并。

如C++
void merge(vector arr) {
//合并
//打印最后的结果
}

示例1:in: 空; out: 空
示例2:in: [1, 2]; out: [1, 2]
示例3:in: {1,4}, {2, 3}, {4, 4}, {5, 5}, {6, 8}, {7, 8}, {9,11}; out:[1,4] [5,5] [6,8] [9,11]
*/

#include
#include

using namespace std;

void merge(vector>& intervals) {
    if(intervals.empty()) {
        return;
    }
    
    vector> mergedIntervals;
    mergedIntervals.push_back(intervals[0]);
    
    for(int i = 1; i < intervals.size(); i++) {
        vector& currentInterval = intervals[i];
        vector& lastMergedInterval = mergedIntervals.back();
        
        if(currentInterval[0] <= lastMergedInterval[1]) {
            lastMergedInterval[1] = max(currentInterval[1], lastMergedInterval[1]);
        }
        else {
            mergedIntervals.push_back(currentInterval);
        }
    }

这是我当时的回答,面试官也没有代码编辑器,直接飞书视频,让我共享桌面给我发了一个题目网址,让我作答;

回答完之后,面试官问我,从代码的角度哪里可继续进行优化,额额额;我当时就信口胡说,我说先把区间边界从小到大,使用冒泡排序法;最后面试官告诉我 for(int i = 1; i < intervals.size(); i++);代码中的intervals.size()重复计算,应该赋值给一个变量;

面试官问:emplace_back和push_back的区别与联系:我回答emplace_back这个函数可以直接在向量的尾部构造一个新的元素,而不需要创建一个临时对象。这样可以提高效率;

标准答案:

1、参数传递方式:

emplace_back接受的参数是构造元素所需的参数,而不是已经构造好的元素。它会在容器内部直接构造新元素,而不是通过拷贝或移动现有对象。

push_back接受的参数通常是已经构造好的元素,它会将这个元素拷贝或移动到容器中。

2、性能:

emplace_back通常比push_back更高效,因为他避免了额外的拷贝或者移动操作。由于emplace_back直接在容器内部构造元素,它可以在构造元素时,使用移动语义,从而减小了性能开销;

3、使用场景:

emplace_back通常更适合用于容器中存储的元素是自定义类对象的情况,因为它允许您直接传递构造函数所需的参数,而无需创建临时对象。

push_back适用于您已经有一个已经构造好的对象,或者当元素是内置类型(如intdouble等)时。

总之,emplace_back通常更灵活且性能更好,但要根据具体情况选择使用哪种方法。如果您有一个已经构造好的对象,或者不关心性能开销,那么使用push_back也是合理的。

#include

int main() {
    std::vector v;

    // 使用 push_back 添加元素
    int x = 42;
    v.push_back(x); // 拷贝 x 到容器中

    // 使用 emplace_back 添加元素
    v.emplace_back(56); // 直接在容器中构造元素

    return 0;
}
下一个问题是map和unordered_map之前的区别与联系:(没回答上来)

unordered_map是一个将key和value关联起来的容器,它可以高效的根据key值查找对应的value;

key值可以是唯一的,key和value的数据类型可以不同;

unordered_map存储元素时是没有顺序的,只是根据key的哈希值,将元素存在指定位置,所以根据key查找单个value时非常高效,平均可以在常数时间内完成;

unordered_map查询单个key的时候效率比map高,但是要查询某一范围内的key值时比map效率低;

运行效率方面:unordered_map最高,而map效率较低但 提供了稳定效率和有序的序列;

内存占用方面:map内存占用略低,unordered_map内存占用略高,而且是线性成比例的;

内部实现机理:

map: map内部实现了一个红黑树,该结构具有自动排序的功能,因此map内部的所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素,因此,对于map进行的查找,删除,添加等一系列的操作都相当于是对红黑树进行这样的操作,故红黑树的效率决定了map的效率。
unordered_map: unordered_map内部实现了一个哈希表,因此其元素的排列顺序是杂乱的,无序的

map
优点:有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作。红黑树,内部实现一个红黑书使得map的很多操作在lgn的时间复杂度下就可以实现,因此效率非常的高。
缺点:空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点,孩子节点以及红/黑性质,使得每一个节点都占用大量的空间
适用处:对于那些有顺序要求的问题,用map会更高效一些。

unordered_map
优点:内部实现了哈希表,因此其查找速度是常量级别的。
缺点:哈希表的建立比较耗费时间
适用处:对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map

map容器执行插入、删除、查找操作时的时间复杂度是O(log n)

unordered_map容器,执行插入、删除、查找操作时的时间复杂度是O(n)

至此;一面结束;

二面:上来让我做了一个复杂的自我介绍,根据我的简历对我进行了一系列的提问:

1、问我项目的事情:

使用PID控制器只用横向位置偏差控制;面试官说要用横向位置偏差控制和纵向速度双PID控制;然后问了我用五次多项式规划曲线过程;面试官给我讲解她的理解,我听得也是稀里糊涂;

最后问了我一下参加的比赛的情况;

面试官总结说我这些项目就像一个个小的demo;只适用于一些固定的较简单的场景;蒙骗领导过关的一些小伎俩(我觉得他们说的确实对);针对他们目前正在做的是自动泊车;适用于坡道、转弯、草地等,只要是有需求就应该能适应所有场景;(其实我应该再问问他针对我这种情况,在学校我要针对性的学习哪些东西);

个人感觉针对我这种一直在学校读书的同学来说真应该多出去实习;多跟面试官沟通;并且尽早明确自己的以后的就业方向不要迷茫;

你可能感兴趣的:(面试,职场和发展)