英伟达半导体校招软件工程师面试经验——求职精灵(finsight.work)

收藏 5 浏览 763
2025-11-06 14:36:01

一、企业概况

1.1公司简介

英伟达(NVIDIA)成立于1993年,总部位于美国加州圣克拉拉,是全球领先的加速计算公司。公司以图形处理器(GPU)起家,业务从游戏显卡扩展到数据中心加速计算、人工智能训练与推理、专业可视化、汽车电子等领域,并通过 CUDA 软件栈构建了从芯片到开发工具再到行业方案的完整生态。英伟达半导体科技(上海)有限公司是其在中国的经营实体之一,承担研发与技术支持相关职能。软件工程师岗位在这里既包括底层驱动、编译器与运行时,也包括上层工具链、平台软件与算法实现,因此面试对代码质量、复杂度分析和系统思维的要求都比较高。

成立时间1993年
总部美国加州圣克拉拉,中国区在上海等地设有研发与业务机构
主营业务GPU 与加速计算芯片、数据中心与人工智能解决方案、专业可视化、汽车电子
技术特征以 GPU 硬件加 CUDA 软件栈构成生态,软硬件协同是核心竞争力

1.2岗位定位

软件工程师在英伟达的分工很细,可能落在驱动与固件、编译器与运行时、深度学习框架适配、平台工具或应用算法几条线。校招进来一般先做模块级的开发与调试,逐步承担子系统设计。这个岗位的特点是软硬件交界多:写的是软件,但要理解内存层次、并行度和硬件行为。所以面试不会只考算法题的对错,还会看你对复杂度、边界和工程权衡的敏感度。

所属体系软件研发体系,按驱动、编译器与运行时、框架适配、平台工具等方向划分
核心职责模块开发与调试、性能优化、接口与工具链维护、与硬件团队协同定位问题
发展路径软件工程师 → 高级工程师 → 技术专家或技术管理
能力要求数据结构与算法、C 与 C++ 基础、操作系统与并发、性能与复杂度分析
  • 面试以白板或共享文档写代码为主,边写边讲比一次写对更重要,卡住时说出思路也能得分
  • 每道题几乎都会追问复杂度与边界,答完代码要主动补一句时间空间开销

1.3招聘概况

校招面向计算机、软件工程、电子、自动化、数学等专业的本科、硕士与博士毕业生,岗位分布在上海、北京、深圳等地。流程一般是网申、在线笔试、两到三轮技术面、综合面与录用,技术面以算法与基础为主,部分方向会加问操作系统、网络或体系结构。具体岗位与批次以公司当年校园招聘公告为准。

招聘对象应届本科、硕士、博士毕业生
面向专业计算机科学与技术、软件工程、电子信息、自动化、数学等
工作地点上海、北京、深圳等
投递窗口以公司当年校园招聘公告为准

企业概况整理自公司官网、公开年报与招聘公告,具体数据以官方最新发布为准。

二、面试总体概述

2.1案例背景

英伟达软件工程师的校招技术面,题目集中在数据结构与算法基本功:字符串排列、数组去零、二叉树遍历与统计、区间合并、链表反转、排序实现。一共十一题,没有偏门算法,但每一题都会被追问边界条件、时间空间复杂度和「还有没有别的解法」。写得出代码只是入场券,讲得清为什么这么写、什么输入会让它出错,才是评分的重点。

2.2基本信息

公司英伟达半导体科技(上海)有限公司
岗位软件工程师
招聘类型校招
用工形式 / 部门直招 · 软件研发
工作地点上海
面试形式线上
面试轮次1 轮
平均时长45 分钟
题目数量共 11 题,均附参考答案
整体难度★★★★☆ 偏难
候选人背景学历 硕士 | 专业 计算机科学与技术 | 经历 有编译器相关课题与两段后端开发实习

2.3高频考点

考点分类出现轮次次数
字符串与数组的回溯、双指针专业基础技术面2
二叉树的遍历、统计与结构变换专业基础技术面5
排序与区间合并的贪心思路专业基础技术面2
链表指针操作与边界处理专业基础技术面1
重复元素查找的多解法比较专业基础技术面1

2.4备考建议

优先级易失分点准备动作
P0代码能跑但说不清复杂度每道题写完强制自己说三句:时间复杂度、空间复杂度、最坏输入长什么样
P0边界条件靠运气固定检查四件事:空输入、单元素、全相同、极值溢出,做成写码后的口头清单
P1只会一种解法每道经典题准备两个解,比如排列的回溯与字典序、重复数字的求和与快慢指针
P1递归写法会,迭代写不出把二叉树三种遍历的迭代版各手写三遍,理解显式栈的作用
P2不知道面试官在等什么练「先说思路、再确认、后动手」的节奏,把澄清输入输出变成习惯
P2项目讲不出取舍给每个项目准备三个「为什么」:为什么用这个结构、为什么这么分层、瓶颈在哪

三、面试流程

3.1流程总览

#环节形式时长筛选重点
1网申投递公司招聘官网—学校专业、项目与方向匹配
2在线笔试在线编程60~90 分钟编码速度、边界处理与复杂度意识
3技术面线上一对一45~60 分钟算法实现、复杂度分析、代码质量
4交叉面或综合面线上一对一45 分钟项目深度、系统设计、协作与动机
5录用与沟通电话或邮件—岗位方向、薪资与到岗时间

3.2各环节说明

1网申投递

英伟达的岗位按方向和团队发布,投递时要看清是驱动、编译器、框架还是平台工具。简历里最好有一条能体现深度:比如自己写过一个解释器、做过 CUDA 优化、维护过开源项目。泛泛写「熟悉 C++」没有区分度。

  • 项目写清你负责的模块和技术难点
  • 有 GitHub 或论文的,放链接比写「精通」有效
2在线笔试

笔试通常是两到四道编程题,难度从简单到中等,语言不限。评分不只看通过用例,也看代码结构和是否处理了空输入、单元素、溢出这些边界。做题顺序建议先扫一遍,把最有把握的两道先拿满。

  • 先写暴力解再优化,别一上来追求最优
  • 提交前手动跑一遍空数组和单元素
3技术面

技术面在共享文档上写代码,面试官会给题、看你写、随时打断追问。常见节奏是先让你说思路,再写,再问复杂度,最后加一个约束条件让你改。写不出来时把思路讲清楚,比沉默硬写要好。

  • 写代码前先用两句话确认输入输出和约束
  • 每写完一个函数,主动说一句它的复杂度
4交叉面或综合面

这一轮可能由另一个团队面试官来面,问题会从算法转到项目:为什么这么设计、瓶颈在哪、如果数据量涨十倍怎么办。也可能问操作系统、并发、内存这些基础。回答要落到你做过的具体决定上。

  • 准备一个能讲十五分钟的项目,含取舍
  • 被问到不会的,说清你的推理路径
5录用与沟通

通过后进入录用沟通,确认团队方向、职级、薪资结构与到岗时间。外企的录用流程通常需要多轮审批,周期偏长,期间可以主动跟进进度。签约前问清试用期考核方式与是否有轮岗。

  • 问清具体团队和汇报线
  • 确认 offer 的组成,base 与奖金比例分开看

四、第 1 轮:技术面

4.1面试形式与时长

轮次名称技术面
面试类型技术面
时长45~60 分钟
形式线上
本轮题量11 题

4.2重点考查维度

  • 专业基础 —— 本组 11 道题

按题型归并为单轮:十一题以数据结构与算法为主,面试官逐题给出、现场编写并追问复杂度与边界,部分题目会临时增加约束条件。

考察回溯框架、去重处理与两种解法的取舍;考察双指针的原地操作与顺序保持;考察递归边界与遍历的空间代价

4.3面试真题与参考答案

【备考助手】求职精灵(https://finsight.work/)收录了英伟达软件工程师历年面试真题与专项练习题库,涵盖数据结构与算法手写、复杂度分析与边界条件的专项训练,并支持 AI 模拟面试实时评分与优化建议,助你高效备战软件工程师面试。
Q1实现字符串的全排列,分别用递归和迭代两种方式。专业基础
提问形式 手写代码考察重点 考察回溯框架、去重处理与两种解法的取舍
参考答案

先问清:是否有重复字符、是否按字典序输出。

  • 回溯:固定第 i 位,与后面每个字符交换,递归 i+1 后换回,本层用集合去重。
  • 迭代:字典序法,先排序,反复找最右升序对、交换、反转后缀,天然有序。
  • 复杂度:结果 n! 个,时间 O(n·n!),栈深 O(n)。
def permute(s):
    res=[]
    def dfs(i):
        if i==len(s): res.append(''.join(s)); return
        for j in range(i,len(s)):
            s[i],s[j]=s[j],s[i]; dfs(i+1); s[i],s[j]=s[j],s[i]
    dfs(0); return res

去重版在循环前加 seen 判断即可。

追问链(2 条)
字符串有重复字符怎么去重?只求第 k 个排列怎么做?
回溯全排列字典序
Q2把数组中的零全部移到右侧,保持非零元素的相对顺序。专业基础
提问形式 手写代码考察重点 考察双指针的原地操作与顺序保持
参考答案

边界:空数组、全零、无零;是否要求原地修改,这决定空间复杂度。

  • 双指针:j 指向待填位置,i 遍历数组,遇到非零就交换并让 j 自增,零被挤到末尾且非零顺序不变。
  • 复杂度:时间 O(n),空间 O(1);开新数组的写法更简单,但空间 O(n),要先问是否允许。
def move_zeroes(a):
    j=0
    for i in range(len(a)):
        if a[i]!=0:
            a[j],a[i]=a[i],a[j]; j+=1
    return a

若题目不要求保序,可用首尾指针减少交换次数。

追问链(2 条)
如果要求最少交换次数呢?如果不要求保持顺序,能怎么优化?
双指针原地修改数组
Q3计算一棵二叉树的叶子节点数。专业基础
提问形式 手写代码考察重点 考察递归边界与遍历的空间代价
参考答案

先定义:叶子是左右子节点都为空的节点,空树返回 0。

  • 递归:空返回 0,左右都空返回 1,否则返回左右子树之和。
  • 迭代:用栈做深度优先,遇叶子计数,避免深树爆栈。
  • 复杂度:时间 O(n),空间 O(h),链状最坏 O(n)。
def leaves(root):
    if not root: return 0
    if not root.left and not root.right: return 1
    return leaves(root.left)+leaves(root.right)

若追问「第 k 层的叶子」,把深度一起传下去即可。

追问链(2 条)
不用递归怎么写?统计第 k 层的叶子节点数?
二叉树递归叶子节点
Q4合并所有重叠的区间。专业基础
提问形式 手写代码考察重点 考察排序加贪心的正确性与边界判断
参考答案

先确认:输入是否按起点有序、端点相接算不算重叠,这决定边界写法。

  • 按起点排序后,后一个区间只可能与结果末尾重叠;重叠就把终点取较大值,否则另起一段。
  • 复杂度:排序 O(n log n),合并 O(n),结果数组空间 O(n)。
def merge(iv):
    if not iv: return []
    iv.sort(key=lambda x:x[0]); res=[iv[0][:]]
    for s,e in iv[1:]:
        if s<=res[-1][1]: res[-1][1]=max(res[-1][1],e)
        else: res.append([s,e])
    return res

输入本身有序时可省掉排序,总时间降到 O(n)。

追问链(2 条)
如果区间是流式到达的呢?怎么合并两个已排序的区间列表?
区间合并排序贪心
Q5反转一个单链表。专业基础
提问形式 手写代码考察重点 考察指针操作的严谨性与边界处理
参考答案

先说清返回新头节点;空链表和单节点要能直接返回。

  • 三指针:每步先暂存 next,再把 cur.next 指向 prev,最后 prev 与 cur 同步后移,prev 即新头。
  • 递归:先反转后面的部分,再让 head.next.next 指回 head,并把 head.next 置空。
  • 复杂度:时间 O(n);迭代空间 O(1),递归 O(n)。
def reverse(h):
    prev,cur=None,h
    while cur:
        nxt=cur.next; cur.next=prev; prev,cur=cur,nxt
    return prev

易错点:忘记暂存 next 会断链,忘记置空会成环。

追问链(2 条)
递归版怎么防止成环?反转从 m 到 n 的节点?
链表三指针递归
Q6实现冒泡排序。专业基础
提问形式 手写代码考察重点 考察排序实现、优化意识与稳定性概念
参考答案

前提:原地、升序、稳定;长度小于 2 直接返回。

  • 外层跑 n-1 轮,内层相邻比较交换,每轮把最大值送到末尾。
  • 优化:加 swapped 标志,某轮无交换就提前结束,最好降到 O(n)。
  • 复杂度:平均与最坏 O(n²),最好 O(n),空间 O(1),稳定。
def bubble(a):
    for i in range(len(a)-1):
        ok=True
        for j in range(len(a)-1-i):
            if a[j]>a[j+1]:
                a[j],a[j+1]=a[j+1],a[j]; ok=False
        if ok: break
    return a

大数据量工程上用快排或归并,这题考基本功。

追问链(2 条)
怎么判断某一轮之后数组已经有序?冒泡和插入排序哪个更快?
冒泡排序复杂度稳定性
Q7实现二叉树的后序遍历。专业基础
提问形式 手写代码考察重点 考察遍历的递归迭代转换与栈的使用
参考答案

后序是左右根,递归和迭代都要会写。

  • 递归:先递归左子树,再右子树,最后访问根。
  • 迭代:按根右左的顺序入栈遍历,结果整体反转,就得到左右根。
  • 复杂度:时间 O(n),递归空间 O(h),迭代最坏 O(n)。
def postorder(root):
    res,st=[],[root] if root else []
    while st:
        n=st.pop(); res.append(n.val)
        if n.left: st.append(n.left)
        if n.right: st.append(n.right)
    return res[::-1]

若追问「不反转结果怎么写」,用 prev 指针模拟调用栈。

追问链(2 条)
不用反转结果的迭代写法?Morris 遍历怎么做?
后序遍历栈二叉树
Q8将二叉搜索树转换为有序的双向链表。专业基础
提问形式 手写代码考察重点 考察中序遍历的应用与指针细节
参考答案

先问:是否原地改指针、是否要循环链表。

  • 中序即升序,遍历时用 last 记前驱,last.right 指当前、当前.left 指 last。
  • 结束后若做循环链表再首尾相接,否则头.left 与尾.right 置空。
  • 复杂度:时间 O(n),空间 O(h)。
def to_list(root):
    first=last=None
    def dfs(n):
        nonlocal first,last
        if not n: return
        dfs(n.left)
        if last: last.right,n.left=n,last
        else: first=n
        last=n; dfs(n.right)
    dfs(root); return first

改指针前没暂存右子树,遍历会断。

追问链(2 条)
要求循环链表怎么改?不用递归能实现吗?
二叉搜索树双向链表中序遍历
Q9在 1 到 100 的数组中找出重复的数字。专业基础
提问形式 手写代码考察重点 考察对题目前提的敏感度与多解法比较
参考答案

先问条件:值域是 1 到 n 还是 1 到 100、只有一个重复还是多个、能否改数组,这三点决定解法。

  • 求和:总和减去 1 到 n 之和,时间 O(n)、空间 O(1),但只在「恰好一个重复、其余各出现一次」时成立。
  • 快慢指针:下标当指针、值当跳转,环的入口即重复数,时间 O(n)、空间 O(1),要求值域在 1 到 n。
  • 哈希或取负标记:通用性最好,代价是 O(n) 空间或修改原数组。
def dup(a):
    s=f=0
    while True:
        s=a[s]; f=a[a[f]]
        if s==f: break
    s=0
    while s!=f: s,f=a[s],a[f]
    return s

多个重复时只能用哈希或排序。

追问链(2 条)
如果有多个重复数字呢?数组只读且不能用额外空间,怎么解?
重复元素快慢指针求和法
Q10计算二叉树的高度。专业基础
提问形式 手写代码考察重点 考察定义澄清与递归的空间代价
参考答案

先对齐定义:高度按节点数还是边数算,空树是 0 还是 -1,不同定义答案差一。

  • 递归:空返回 0,否则左右子树较大值加一,代码最短。
  • 迭代:层序遍历,每处理完一层计数加一。
  • 复杂度:时间 O(n);递归空间 O(h),层序空间最坏 O(n)。
def height(r):
    if not r: return 0
    return 1+max(height(r.left),height(r.right))

若追问「判断是否平衡」,改成后序一次遍历同时返回高度与标记,避免 O(n²)。定义先对齐。

追问链(2 条)
怎么在 O(n) 内判断平衡?求最小深度有什么坑?
树高层序遍历递归
Q11将二叉搜索树转换为最大堆。专业基础
提问形式 手写代码考察重点 考察树结构变换与前提条件意识
参考答案

先确认结构能否改变:要求完全二叉树时,中序取升序、反转、按层序填充。

  • 中序得升序数组,反转即降序,再按 2i+1、2i+2 建树,父下标小于子下标,父值必不小于子值。
  • 时间与空间均 O(n)。
def to_heap(root):
    v=[]
    def ino(n):
        if n: ino(n.left); v.append(n.val); ino(n.right)
    ino(root); v.reverse()
    def build(i):
        if i>=len(v): return None
        n=TreeNode(v[i])
        n.left,n.right=build(2*i+1),build(2*i+2)
        return n
    return build(0)

形状必须保留时,只能自底向上交换值。

追问链(2 条)
如果必须保持原树形状呢?转成最小堆怎么改?
最大堆完全二叉树中序遍历

五、注意事项

英伟达的技术面节奏很紧,一题接一题,评分看的是过程而不是最终代码。以下八处是最常见的失分点。

01不确认边界就写

空输入、单元素、重复值、值域范围,这些不问清就动手,写完一跑就挂。开场两句话确认条件,能省掉一半返工。

02只给一种解法

面试官问「还有别的思路吗」时卡住,说明准备停在背题层面。每题至少准备暴力解与最优解两个版本。

03复杂度说错

把全排列说成 O(n!)、把排序说成 O(n),一个数字就能暴露基础不牢。写完主动报时间和空间,并说明最坏情况。

04忽略空间代价

递归写得漂亮但栈深 O(n),在深链上会爆。要说清递归深度,必要时给迭代版。

05代码没有收尾

链表反转忘记置空、树转链表忘记保存头节点,都是典型的收尾遗漏。写完回头扫一遍指针和返回值。

06题目条件默认成立

求和法找重复数只在「恰好一个重复」时成立,不声明前提就用,追问一句就崩。

07卡住就沉默

写不出来时一句话不说,面试官无法给分。把思路、卡点、你想尝试的方向说出来,过程本身就是评分项。

08不测试就给结果

写完不跑样例,等于把验证交给面试官。至少手动走一遍最简单的输入和一个边界输入。

总结收尾

这十一题没有一道是偏门算法,全部是数据结构课本上的经典题。真正的分水岭在于:你有没有在写之前确认条件,写完之后说清复杂度和边界,被追问时能不能给出第二种解法。把这些变成肌肉记忆,比多刷一百道难题更有效——面试官要判断的是你写代码时的思维习惯,而不是你背过多少题。

在此推荐你使用求职精灵(https://finsight.work/)进行系统备考。平台拥有英伟达等数百家知名企业的真实面经资源,独家支持中英双语 AI 模拟面试,可针对软件工程师进行定制化练习和智能评分优化;简历智能修改功能帮你打磨出一份亮眼的简历;超过 15 万道行测、专业题、英语题随时随地在线刷题。无论你是第一次校招还是已经面过几轮,求职精灵都能为你的求职之路提供有力支持。

以上内容整理自学员和应届同学反馈的真实面经,结合英伟达半导体科技(上海)有限公司的最新考情整理,仅供参考学习。祝各位求职者顺利拿到心仪offer! 本文由求职精灵内容团队整理发布 | 官网:https://finsight.work/