ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

优必选算法岗秋招笔试全解析:SLAM、路径规划与编程题备考攻略

优必选算法岗秋招笔试全解析:SLAM、路径规划与编程题备考攻略 每年到了八九月秋招就像一场准时开场的战役。“优必选”这个名字在机器人赛道里一直挺响人形机器人、四足机器人、伺服舵机这些业务线决定了它对算法岗的要求不会停留在“会调包”层面。我身边不少朋友今年投了优必选的算法岗笔试邮件来得倒挺快但打开题目那一刻有人直接愣住了有人则暗自庆幸自己平时啃过几本硬核的书。这篇东西就是写给准备投优必选算法岗、或者正在备战机器人方向算法笔试的同学。我会把2023年这轮秋招笔试的核心模块拆开讲清楚包括题目类型、考察重点、答题思路、以及我个人的一些复盘建议。不是官方参考答案更多是一个过来人对这套笔试题的观察和思考。1. 整体笔试结构与考察思路拆解1.1 岗位方向与笔试的对应关系优必选的算法岗并不是一个笼统的“算法工程师”头衔它内部其实分得很细。从秋招官网和实际笔试反馈来看主要方向包括计算机视觉算法岗人脸识别、物体检测、SLAM相关的视觉里程计等运动控制算法岗步态规划、全身动力学控制、ZMP稳定性判据等路径规划与导航算法岗ROS导航栈、A*、Dijkstra、动态窗口法等决策与强化学习算法岗机器人任务决策、模仿学习等笔试题目会根据你投递的具体方向做差异化出题。我当时整理过一些同学的反馈大家一致的观点是优必选的笔试不是纯LeetCode刷题模式而是“数据结构与算法基础 机器学习/深度学习理论 机器人领域专业知识 代码实操”四合一组合卷。这个结构其实很能说明问题它透露出公司对算法工程师的期待不是让你只当一个模型调参工而是要你既懂底层数据结构又能理解业务场景中的物理约束。比如四足机器人步态规划中涉及的支撑相与摆动相切换本质上就是个状态机 最优化问题你要能把它抽象成代码。1.2 试卷的整体结构根据我收集到的多份2023年秋招笔试回忆优必选算法岗的笔试时长一般是120分钟题型分布大致如下题型题量分值占比考察重点单选题20题20%数据结构、Python/C基础、机器学习概念多选题10题15%深度学习、强化学习、ROS机器人基础编程题3题45%算法实现、动态规划、图论、数学建模简答题2题20%SLAM/运动控制/视觉方向专业问题从这个分布可以看出编程题是绝对的大头拿不下编程题基本就告别面试了。单选题和多选题的覆盖面很广从KMP算法、堆排序到粒子群算法都有可能出现但总体难度不算太高重点在于概念是否清晰。1.3 出题逻辑背后的倾向我仔细分析过这些题目来源发现优必选的出题风格和互联网大厂有明显的区别。互联网大厂更喜欢考“奇技淫巧”型的算法题比如各种线段树的变种、状态压缩DP的极限优化。而优必选更偏向于“物理世界中的算法”换句话说它希望看到你能把算法和真实机器人系统结合起来。举个例子编程题里出现“二维平面上机器人从起点到终点的最短路径规划”这类题目时大多数同学会直接写一个A*算法但优必选可能会在题目描述里加上“存在动态障碍物”或者“机器人转弯有额外代价”。这个修饰词一加题目就从单纯的图搜索变成了动态规划 代价函数设计问题。这就是机器人公司出题的特点。2. 核心知识点解析与高频考点2.1 数据结构与基础算法经典题依然占坑先说所有人都躲不开的数据结构与算法。优必选的单选题基本上固定会出几类题频率极高我一一列一下。KMP算法。这个几乎是必考的。2023年秋招题目里就有“对于模式串p‘abacaba’其next数组是多少”这种原题。KMP的核心思想是利用已匹配的前缀信息避免模式串匹配失败后回退到开头重新比较。next数组的定义在优必选的题目里通常采用“前缀函数”的变体即next[i]表示模式串前i个字符组成的子串中最长相同前后缀的长度。遇到这种题千万别慌直接手算就行。以“abacaba”为例逐个位置手工推导next[0] -1或0视定义而定next[1]看“a”没有真前后缀记0next[2]看“ab”前缀a后缀b不匹配记0next[3]看“aba”最长相同前后缀是a长度1next[4]看“abac”前缀a、ab后缀c、ac、bac都不匹配记0next[5]看“abaca”最长相同前后缀是a长度1next[6]看“abacab”最长相同前后缀是ab长度2next[7]看整个“abacaba”最长相同前后缀是aba长度3这道题的关键坑在于不同教材里next数组的起点定义不一样有的从0开始有的从-1开始。笔试时一定要先看清楚题目给的是哪种定义不然白白丢分。排序算法。堆排序、冒泡排序、快速排序这些都是选择题的常客。优必选比较喜欢考的是“某种排序算法在不同数据分布下的时间复杂度表现”和“排序算法的稳定性”。比如它会问你快速排序在什么情况下退化到O(n²)堆排序建堆的时间复杂度是多少这些概念如果只是死记结论很容易在选项的细节上出错。我的建议是复习排序算法时不仅要记住复杂度表还要理解为什么。比如快速排序退化是因为每次partition都选到了极端值导致分割极度不均匀。理解了原理考试时无论选项怎么绕你都能识别出来。2.2 机器学习与深度学习理论从经典到前沿这一部分的选择题覆盖面很广从最基础的逻辑回归、SVM到近年热门的Transformer、CLIP都有可能出现。根据2023年秋招的反馈我整理了几个高频考点聚类算法K-Means的收敛性、K值的选取方法、DBSCAN的密度可达概念KNN算法K值选择对分类边界的影响、距离度量方式欧氏距离、曼哈顿距离卡尔曼滤波预测步和更新步的公式、状态协方差矩阵的更新方式这个在机器人定位中太常用了强化学习基础马尔可夫决策过程MDP、策略迭代与价值迭代的区别、探索与利用的权衡Transformer结构自注意力机制的计算流程、多头注意力的拼接方式、位置编码的作用这里我想特别提一下卡尔曼滤波因为这是机器人公司独有的考点互联网大厂基本不考。优必选笔试里出现过一道简答题让你写出卡尔曼滤波的五个核心公式并解释每个变量的物理意义。很多同学在简历里写了“熟悉机器人定位技术”结果到笔试连状态预测方程都写不出来这就很尴尬了。卡尔曼滤波五个公式其实有很清晰的逻辑只要理解了“预测”和“更新”两个阶段就不需要死记硬背预测阶段状态预测x̂ₖ⁻ A·x̂ₖ₋₁ B·uₖ协方差预测Pₖ⁻ A·Pₖ₋₁·Aᵀ Q更新阶段卡尔曼增益Kₖ Pₖ⁻·Hᵀ·(H·Pₖ⁻·Hᵀ R)⁻¹状态更新x̂ₖ x̂ₖ⁻ Kₖ·(zₖ - H·x̂ₖ⁻)协方差更新Pₖ (I - Kₖ·H)·Pₖ⁻可以这样理解预测阶段是根据运动模型推算出“我觉得我在哪”更新阶段是根据传感器数据告诉你“观测告诉我我在哪”卡尔曼增益就是权衡“我更相信运动模型还是更相信传感器”的权重。这个直觉建立起来后公式就不容易忘了。2.3 机器人领域专业知识优必选的“护城河”考点这部分的题目是优必选区别于其他公司笔试的核心标志。如果说前面的数据结构和机器学习是通用能力测试那么这部分就是筛选“真正了解机器人”的候选人的关卡。我梳理了2023年秋招笔试中出现的几个方向SLAM相关的题。这主要是针对视觉算法岗和导航算法岗的。常见的考点包括ORB-SLAM的特征点提取与匹配流程、图优化中的位姿图Pose Graph构建、回环检测的作用。有一道题问的是“在视觉SLAM中为什么需要进行局部地图优化而不是只依赖帧间匹配”其实考察的就是累积漂移问题。帧间匹配只考虑相邻帧的相对位姿误差会逐帧累积而局部地图优化通过同时优化多个关键帧的位姿和地图点把误差分摊开从而抑制漂移。运动控制方向的题。优必选做双足人形机器人起家ZMPZero Moment Point零力矩点理论几乎是必考。问题一般不会让你推导复杂的动力学公式而是考察概念什么是ZMPZMP落在支撑多边形内意味着什么如果ZMP超出支撑多边形会发生什么回答清楚这三点就够用了。我建议你用“行走的稳定性”来理解ZMP人走路时地面反作用力的合力作用点就是ZMP。只要这个点落在脚掌构成的支撑多边形内部机器人就稳一旦跑到支撑多边形外面机器人就会翻倒。这就是为什么双足机器人走路时会刻意控制躯干姿态和步态周期目的就是让ZMP始终待在支撑多边形内。路径规划与导航相关。这一块考的算法就多了。A*、Dijkstra、RRTRapidly-exploring Random Tree、动态窗口法DWA这些都可能出现在选择题或简答题里。有一道简答题问“A*算法中启发函数h(n)的设计对最终路径的影响”这个问题如果只看过LeetCode题解就很难答好因为它考的是图搜索中启发式函数的本质。A算法的核心公式是f(n) g(n) h(n)其中g(n)是从起点到当前节点n的实际代价h(n)是从节点n到终点的估计代价。当h(n)始终不大于真实代价时A保证找到最优路径此时h(n)是可采纳的如果h(n)估计过大搜索会加速但可能丢掉最优解。比如在栅格地图中使用欧氏距离作为启发函数通常比曼哈顿距离更接近真实代价但计算量也更大。所以设计启发函数实际上是在“搜索速度”和“路径最优性”之间做权衡。2.4 代码题不只考“写代码”这么简单2023年优必选秋招笔试的编程题基本上是3道题难度梯度非常明显。我拿其中一个同学反馈的题目组成来举例展示一下实际的考法。第一题通常是签到题考基础数据结构和简单模拟。比如“给定一个整数数组使用快速排序算法进行升序排序并输出每轮排序后的结果”。这道题考察的既是快速排序的实现也是在确认你是否理解分治思想因为题目要求输出“每轮排序后的结果”如果你只是调用了库函数那就拿不到过程分。第二题开始有难度了。有一道印象很深的题大意是有一个N x M的网格地图机器人从左上角出发目标是到达右下角。网格中每个格子的通过代价不同机器人每次只能向右或向下移动一步求最小代价路径。这题乍一看就是个典型的动态规划问题状态转移方程也很简单dp[i][j] grid[i][j] min(dp[i-1][j], dp[i][j-1])但优必选在题目里加了个限定条件机器人在转弯时需要额外消耗代价。这个条件就打破了常规动态规划的“无后效性”因为你不能只记录到达当前格子的最小代价还需要记录到达当前格子时的运动方向是向右到达的还是向下到达的。这时候状态定义要扩展成二维的dp[i][j][0] 表示从上方到达格子(i,j)的最小总代价 dp[i][j][1] 表示从左方到达格子(i,j)的最小总代价状态转移时就要考虑转弯的额外开销。这个考法其实很有机器人特色——现实世界中机器人转向确实有额外代价差速轮要减速、全向轮要重新分配轮速这比单纯的DP算法题多了工程味。第三题通常涉及图论或更复杂的算法设计。有同学反馈说遇到过“在无向带权图中求从节点s到节点t经过k条边的最短路径长度”的问题。这题可以转化为DP或使用动态规划的方式求解dp[k][v] min(dp[k-1][u] weight(u, v) for all edges (u, v) in graph)也就是在Bellman-Ford算法的思路上扩展用“经过的边数”作为阶段的维度最终在dp[k][t]中找最小值即可。这题对于熟悉图算法的人来说不算难但坑在于输入规模可能很大如果直接用朴素的三重循环复杂度是O(k·V·E)可能会超时需要考虑到用邻接表优化遍历。从这三道题可以看出优必选的编程题不只是要求你“能写代码”更要求你“能分析题目背后的约束条件并选择合适的数据结构和算法”。这和机器人大赛里那种“地图改了路径算法要不要换”的问题逻辑是一致的。3. 实操复盘如何高效准备这类笔试3.1 时间分配与复习优先级如果你现在准备投优必选的算法岗笔试准备时间又比较紧比如只剩两周我会建议你按照下面的优先级来分配精力第一优先级数据结构与算法基础每天2小时。把LeetCode高频题里与DP、图论、搜索相关的题刷一遍尤其是二维DP、状态机DP、Dijkstra、A*这类题目。不要贪多每天精做3-5题关键是吃透状态定义和转移方程。第二优先级机器学习/深度学习基础概念每天1小时。把KNN、K-Means、SVM、决策树、逻辑回归这几个经典算法的原理过一遍然后重点看Transformer的Self-Attention机制和卡尔曼滤波的五个公式。这些是高频考点且性价比最高。第三优先级机器人专业知识每天1小时。如果是投CV方向重点复习SLAM和特征点匹配如果是投控制方向重点复习ZMP和步态规划如果是投导航方向重点复习A*、DWA、RRT。注意结合自己做过的项目来理解不要死背概念。第四优先级编程手感每天1小时。不管你平时用C还是Python笔试时一定要用自己最熟练的语言。优必选笔试支持的主流语言是C和Python我建议算法部分用Python快速实现机器人类比推理题用C这样能兼顾开发速度和运行效率。3.2 用代码思路拆解一道高频面试题为了让上面的复习建议落地我拿一道和机器人路径规划相关的经典笔试题目来做一次拆解。这道题不是2023年的原题但它覆盖了DP、图论、路径规划三个优必选高频方向非常具有代表性。题目描述在一个10x10的栅格地图上机器人从坐标(0,0)出发目标到达(9,9)。地图中的每个格子若为1则代表障碍物机器人不能通行若为0则为自由空间。机器人只能上下左右移动每移动一步代价为1。求从起点到终点的最短路径长度。一看到“最短路径”和“只能上下左右移动”第一反应就是BFS。代码实现思路非常直接from collections import deque def shortest_path(grid): if not grid or grid[0][0] 1 or grid[-1][-1] 1: return -1 n, m len(grid), len(grid[0]) visited [[False] * m for _ in range(n)] queue deque() queue.append((0, 0, 0)) # (x, y, step) visited[0][0] True directions [(1, 0), (-1, 0), (0, 1), (0, -1)] while queue: x, y, step queue.popleft() if x 9 and y 9: return step for dx, dy in directions: nx, ny x dx, y dy if 0 nx n and 0 ny m and not visited[nx][ny] and grid[nx][ny] 0: visited[nx][ny] True queue.append((nx, ny, step 1)) return -1但笔试题目往往不会这么简单。优必选风格的做法是给它加上“机器人转弯有额外代价”的条件或者“某些格子通过需要消耗额外能量”的条件。加条件后BFS就不能直接用因为BFS假设每步代价相等一旦代价不等就要切换成Dijkstra或者带权重的DP。如果是“转弯消耗额外能量”最优解是通过增加状态维度来记录方向然后用Dijkstra。当前节点的状态从(x, y)扩展到(x, y, direction)其中direction记录上一步是从哪个方向移动来的。每一步移动时如果方向发生变化则需要加上转弯代价。这个思路和我在2.4节提到的扩展DP是完全一致的。这个案例说明了优必选笔试的一个特点它考的不是某一个孤立的算法而是看你能不能把一个看似简单的算法在增加现实约束之后进行合理的扩展。这恰恰是机器人算法工程师日常工作中最常做的事。3.3 关于代码风格的几个细节优必选笔试的代码题是线上OJ判题所以代码风格虽然不计分但有一些细节会影响你的调试效率。我根据自己的经验提几个建议变量命名不要用a、b、c这种用grid、n、m、visited这种有意义的命名。看起来是小事但在写DP或者BFS的状态转移时清晰的命名能大幅减少脑子混乱的概率。边界条件一定要先处理。比如数组为空、起点或终点是障碍物、地图尺寸为1x1等情况这些在OJ里是必测的corner case。Python写算法题时注意性能。如果你用Python遍历大数组时优先用range而不是list用collections.deque而不是list模拟队列这些微小的优化在N较大的时候能避免TLE。C选手要注意使用vector时频繁push_back会造成扩容开销可以先用reserve预留容量。但在笔试场景下题目给的输入规模一般不会大到需要这种优化的程度所以不必过度焦虑。4. 常见问题与避坑指南4.1 非机器人背景的同学如何快速补齐专业知识这个问题我几乎每年都会被问到。很多投优必选算法岗的同学学校背景和实习经历都是纯互联网方向的学过机器学习、做过推荐系统、刷过LeetCode但对机器人几乎是零基础。这部分同学在笔试中面临的最大风险是“选择题和专业题连蒙都没法蒙”。我的建议是不要试图在笔试前啃完一本《机器人学导论》那不现实。你应该做一个“最小知识集”的快速扫描花一晚上理解坐标变换与旋转矩阵的基本概念知道什么是欧拉角、什么是四元数花两小时理解卡尔曼滤波的五个公式并手推一遍一维的例子花一个晚上理解SLAM的基本框架知道前端、后端、回环检测、建图分别解决什么问题花三个小时理解ZMP和步态规划的核心思想花两小时理解ROS的基本概念节点、话题、服务、动作这些知识不需要你达到能推导公式的水平但至少要能看懂题目在说什么并且能把机器人专业用语和你已有的算法知识建立关联。比如看到“SLAM”要知道它本质上是状态估计问题和你在推荐系统里用到的贝叶斯估计有相通之处看到“路径规划”要知道它本质上是图搜索问题和你刷过的A*算法是同一套逻辑。4.2 选择题中容易混淆的概念优必选的多选题特别喜欢设置“看起来很对、其实错了”的选项专门收割那些概念掌握不牢固的同学。我整理了几个我见过的高频混淆点K-Means和KNN的混淆。K-Means是一种聚类算法是无监督学习KNN是一种分类或回归算法是有监督学习。但选择题选项里经常把两者的特点互相嫁接比如写成“K-Means在分类时考虑最近的K个邻居”这就是错的。还有一点K-Means的“K”是簇的个数KNN的“K”是邻居的个数含义完全不同。堆排序的稳定性。堆排序是不稳定排序这是确定的。但很多同学会误以为堆排序是稳定的因为堆的构建过程看起来很有序。实际上堆排序在取出堆顶元素与末尾元素交换时可能破坏相同元素的相对顺序所以它不稳定。快速排序和归并排序的底层实现。快排是原地排序空间复杂度O(log n)递归栈归并排序不是原地排序需要额外O(n)空间。这个在选择题里经常考很多人记反了。A*算法与Dijkstra算法的关系。A算法在启发函数h(n)0时退化为Dijkstra算法。这个结论是准确的但选项里可能会写成“A算法的最坏时间复杂度一定优于Dijkstra”这就不对了A*的时间复杂度依然取决于启发函数的选择和搜索空间的规模。4.3 编程题常见失分点编程题的失分点往往不在算法思路而在一些容易被忽略的细节上。首先输入输出的处理格式。优必选的OJ系统对输入输出的格式有严格要求比如多个测试用例之间的分隔符、浮点数的精度要求。有些同学在本地IDE跑通了自己造的测试数据但没注意到题目要求的是“输出最短路径长度保留两位小数”结果格式错了整个case不得分。建议笔试前先熟悉一下OJ系统的输入输出示例。其次没有考虑极端输入。很多题目会隐含“输入可能为空”“N和M可能极大”“图中存在负权边”等边界条件。如果你在代码开头没有做防御性判断很容易在隐藏测试用例上翻车。最后状态转移方程写对了但代码实现有bug。我见过很多人DP思路完全正确但在循环顺序上写错了导致数组越界或使用未初始化的值。比如二维DP里如果你要依赖左上方和上方的值那么循环遍历顺序必须是外层从左到右、内层从上到下不能反过来。这个细节在笔试压力下很容易出错建议平时刷题时就要养成检查遍历顺序的习惯。4.4 时间不够用怎么办120分钟做3道编程题加30道选择题加2道简答题时间其实非常紧张。我见过很多同学在选择题上纠结太久导致编程题只剩40分钟最后三道题全部AC不了。这里分享一个时间分配建议选择题30题建议25分钟内完成。遇到不确定的题目先标记跳过不要死磕。编程题3题建议80分钟内完成。先做最简单的第一题保底再做第三题或第二题中看起来更熟悉的那道。简答题2题建议15分钟内完成。每题不需要长篇大论把关键公式、关键流程和核心概念写清楚即可。这个时间分配方案的逻辑是编程题的分值占比最大值得用整块时间去解决简答题虽然有20%的分值但每题只要答出核心要点就能拿大部分分数不需要写论文。5. 笔试之后的复盘与面试衔接如果你顺利通过了笔试接下来就是面试环节了。优必选的面试通常会有一些项目深挖题和技术原理题这些问题和笔试内容是有一定承接关系的。比如面试官可能会问你“你笔试题第三题当时是怎么思考的如果地图变大100倍你的算法还可行吗”“你简历里提到了卡尔曼滤波能现场推导一下更新步吗”“你做过路径规划项目说说A*和DWA分别适合什么场景怎么配合使用”所以笔试结束后不要急着把题目忘掉。我建议你花半小时做一个笔试复盘把能回忆起来的题目和你的答案写下来尤其记录那些“你其实不太确定但蒙对”的题目。这些不确定的题目就是你知识体系中的薄弱环节面试前一定要补上。关于A和DWA的配合问题我再展开说一句因为这个在面试里问到的概率很高。A是全局路径规划算法它是在已知地图上先规划出一条从起点到终点的粗略路径它假设环境是静态的。DWA是局部路径规划算法它考虑的是机器人当前速度与周边障碍物的实时关系在每个控制周期内采样多组速度组合并选择一条不撞障碍物、且能朝全局目标前进的最优轨迹。实际系统中通常是先用A*规划全局路径然后把全局路径上的局部目标点作为DWA的指引由DWA完成实时的避障和运动控制。这种“全局局部”的配合思路也是优必选这类移动机器人公司算法岗面试中的常客。说到底优必选2023年秋招算法岗笔试最核心的考核目的是判断一个候选人能不能把算法基本功和物理世界的实际问题结合起来。你不需要在每一个领域都做到专家级别但你需要展示出足够的学习能力和知识迁移能力。我在复盘这份笔试题时最大的感受是公司不是在找最会刷题的人而是在找最能理解“机器人是怎么思考”的人。方向对了准备时就不容易跑偏。
返回列表