面灵AI→

携程前端秋招一面面经(45 分钟)

轮次
一面
时间
2026-10
来源
牛客网

《面试题目》

  1. 自我介绍。
  2. 讲一下数组去重有哪些方法?
  3. map 和 reduce 具体是怎么实现数组去重的?
  4. 常见的排序算法有哪些?复杂度分别是多少?适用场景有哪些?
  5. 堆排序有什么适用场景吗?可以讲一下吗?
  6. 在浏览器当中输入一个 URL 到最终的页面展示,网络层面经历了哪些过程?
  7. 怎么用 Flex 布局实现两侧固定、中间自适应的三栏布局?
  8. 你对弹性布局的理解是什么?你觉得弹性布局当中最重要的概念是什么?
  9. 主轴和交叉轴的对齐方式有哪些?
  10. 如果一个列容器下面有四个行,这四行有四个 item,这四个 item 都要居中对齐,如果四项都要居中怎么实现?如果第一项左对齐、剩下的三项居中,这个又怎么实现?
  11. 讲一下什么是闭包,举一个你实际项目当中用过闭包的例子。
  12. 讲一下事件冒泡和事件委托有什么关系。
  13. 平时用 AI 写代码对吧?假如 AI 给你的反馈不符合预期,你是怎么去解决这个问题的?
  14. 如果是你写的提示词描述不清楚,那要怎么去优化这个提示词?
  15. 你的实习项目提到了 Puck,能讲一下这个 Puck 主要是做什么的吗?用户是谁?
  16. 你能讲一下从用户拖拽到最终生成 HTML 页面,这里边的原理是什么吗?
  17. 这个 Puck 通过拖拽之后生成的这份数据主要保存了哪些信息?
  18. 为什么选择 zustand?
  19. 旅行内容社区和审核管理平台这部分涉及到移动端,你觉得 React Native 和 React 有什么区别?
  20. 项目开发的过程中有遇到过什么性能问题吗?
  21. 做一个数据量很大的长列表优化,你觉得可以用什么方案?
  22. 虚拟列表的原理是什么?
  23. 虚拟列表实现的技术手段有哪些?
  24. scroll 触发的频率会很高,怎么优化?
  25. 除监听滚动事件之外,你还能想到其他的技术手段吗?

反问

  1. 部门业务是什么?
  2. 对我有什么建议?
  3. 面试流程是怎样的?

《参考解析》

数组去重:从能用到工程化。[...new Set(arr)] 最常用,靠 SameValueZero 判等:对基本类型有效,对象只按引用去重,1 与 '1' 视为不同,NaN 会正确保留一个。filter 加 indexOf 是 O(n²) 的基础写法且对 NaN 失效;用对象或 Set 做哈希表一次遍历是 O(n),业务里真正需要的是按字段去重对象数组(比如按 id)。reduce 的写法是把哈希表塞进累加器:acc.seen.has(cur) ? acc : (acc.seen.add(cur), acc.list.push(cur), acc);map 的用法是先用它把元素映射成键,再借 Map 的键唯一性去重,如 new Map(arr.map(i => [i.id, i])) 最后取 values()。答题时讲清「什么类型、按什么键、是否保持原顺序、复杂度多少」,比背三种写法更得分。

排序算法与堆排序的适用场景。冒泡、插入、选择是 O(n²),其中插入排序在近乎有序的数据上接近 O(n);归并、快排、堆排平均 O(n log n)。归并稳定、最坏也是 O(n log n),但要 O(n) 额外空间;快排平均最快、原地,但最坏退化为 O(n²) 且不稳定(随机化或三数取中可规避);堆排原地、最坏情况可预测,但常数大、跳跃访问对缓存不友好。JS 的 Array.sort 在 V8 里对长数组走 TimSort(稳定,归并与插入的混合)。堆排序真正的价值在三处:只要最大的前 K 个而不全排序(维护大小为 K 的小顶堆,O(n log K),海量数据 Top K 的标准解法)、数据流持续取极值(优先队列、定时器)、以及内存受限且要求最坏情况可预测。被追问「为什么不用快排」时,落到稳定性、额外空间、最坏情况与是否流式这几个指标上。

输入 URL 到页面展示的网络过程。按步讲:URL 解析与本地缓存查找(强缓存命中直接返回);DNS 解析(浏览器缓存、hosts、递归查询,命中 CDN 返回就近节点 IP);TCP 三次握手,HTTPS 再做 TLS 握手协商密钥;经过网关、负载均衡或 CDN;发送 HTTP 请求(带 Cookie 与 If-None-Match、If-Modified-Since 这类协商头);服务端返回响应(协商命中返回不带体的 304);之后进入解析渲染,构建 DOM 与 CSSOM、合成渲染树、布局、绘制、栅格化上屏,期间并发加载 JS、CSS、图片与字体。优化点顺着这条链给:预解析与预连接、HTTP/2 多路复用与连接复用、压缩、CDN 就近、内容哈希加长缓存、关键 CSS 内联、JS 用 defer/async 不阻塞解析。

Flex 三栏布局与两轴对齐。两侧固定、中间自适应最简洁的写法是中间项 flex: 1(即 1 1 0%),两侧 flex: 0 0 200px;flex-basis: 0 的意义是按剩余空间分配而不是按内容起步,否则内容过长会挤压两侧。必须给中间项加 min-width: 0——Flex 项默认 min-width: auto,长文本或滚动容器会撑破布局,这是三栏最常见的坑。justify-content 管主轴(flex-start、center、space-between 等),align-items 管单行交叉轴(默认 stretch 会拉伸子项),align-self 覆盖单个子项,align-content 管换行后的行间分布;flex-direction: column 时两轴互换。四个行、每行四个 item 都居中:外层 display:flex; flex-direction:column; justify-content:center; align-items:center,每行再 justify-content:center;第一项左对齐、其余居中,用该项 margin-right: auto 把它推到左边,其余保持居中。弹性布局最重要的概念是「剩余空间的分配」,也就是 grow、shrink、basis 与最小尺寸的交互。

闭包与事件委托。闭包是函数与其定义时词法作用域的组合,内层函数引用外层变量,即使外层已返回这些变量仍存活在堆上。项目里的典型用途是防抖与节流(闭包保存定时器 id 与上次执行时间)、useDebounce 这类 Hook、事件处理保存上下文、以及模块模式隐藏实现细节;代价是变量不被回收,长期持有大对象或 DOM 引用会泄漏,所以要在卸载时清理定时器与监听。事件冒泡是事件从目标元素向上传到祖先,stopPropagation 可打断,preventDefault 只阻止默认行为不停冒泡;事件委托正是利用冒泡把监听统一挂在父容器,通过 event.target(配 closest 更健壮)判断来源,好处是监听器更少、动态新增的子元素自动生效。注意 focus、blur、mouseenter 不冒泡,不能直接委托。

长列表、虚拟列表与滚动优化。三条路:分页或懒加载累计、内容可见性渲染、虚拟列表。虚拟列表的核心是容器高度按总条数撑开、只渲染可视区加缓冲区的项,用 transform: translateY 或绝对定位偏移到正确位置,并维护「滚动位置 → 索引」映射(定高直接除,不定高要预测量或用 ResizeObserver 回填缓存)。技术手段包括缓冲区上下多渲染几条减少白屏、用 requestAnimationFrame 对齐渲染时机、只在索引区间变化时更新状态以避免高频重渲染、用 passive: true 让滚动不被监听器阻塞、把监听挂在容器而不是 window。除监听 scroll 外还有:IntersectionObserver 观察哨兵元素触发计算或加载、CSS content-visibility: auto 让浏览器跳过屏外渲染、contain: layout paint 限制重排范围;React 下也可直接用 react-window、react-virtuoso,把「自己实现要处理哪些边界」讲清比只说库名更有说服力。

Puck 拖拽、zustand 与 React Native。Puck 是开源的「可视化编辑器」框架,让非技术用户拖拽组件搭页面,用户是运营与内容编辑,价值是页面搭建不依赖前端发版。从拖拽到出 HTML 的原理是数据驱动:注册组件时给出「渲染组件加字段 schema」,拖入画布往数据模型插入节点(type、props、唯一 id),画布按数据递归渲染、编辑只改 JSON 不改 DOM;发布时把这份 JSON 落库并保留版本以便回滚,渲染端再用同一份数据渲染出真正的 HTML——保存的是组件树与 props,而不是 HTML 字符串。选 zustand 的理由是轻量、无 Provider 嵌套、按选择器订阅能精确控制重渲染、样板代码少,也容易在 React 之外读写状态;对比 Redux 的取舍是生态与心智负担。React Native 与 React 的区别:RN 渲染到原生视图、没有 DOM 与 CSS,样式是 JS 对象加 Flexbox 子集(默认 column),组件是 View、Text、Image 这类封装,导航、手势、权限、存储都走原生模块,所以跨端可复用的主要是业务逻辑与状态层。被问 AI 反馈不符合预期时,先分诊是理解偏差还是能力边界,再补上下文、给正反例、拆小任务,并要求它先给方案再动手、把报错原文回灌且一次只修一处。