ARTICLE DETAIL

资讯详情

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

联想移动端笔试复盘:考点清单与实战思路

联想移动端笔试复盘:考点清单与实战思路 我是在秋招群里看到联想移动端类笔试通知的投的是客户端开发方向岗位描述里写的是负责移动端 App 的迭代和维护技术栈不锁死 Android / iOS / 跨端所以笔试也干脆把移动端相关的都揉在一起考。整套卷子做下来最大的感受是它不像某些大厂那样上来就甩五道 hard 算法题劝退而是更看重你对移动端这条链路的完整认知——从系统机制到网络、从性能优化到调试手段、从原生到跨端方案都有涉及。换句话说虽然名义上是笔试但它其实在筛真正处理过移动端问题的人。这篇复盘我拖了几天才写是想把当时印象深刻的题目、考完回去补的知识点、以及后来在面试里被追问到的内容都整理干净再发出来。如果你也在准备 2025 年秋招的移动端岗位或者刚开始投客户端方向这篇文章应该能帮你把备考范围收拢到一个比较务实的框里。1. 联想移动端笔试的考察框架与整体节奏1.1 题型构成与考试平台先说整体情况。联想这场笔试走的是牛客平台总时长 90 分钟题量不算夸张但节奏压迫感很强。我印象里卷面大概是这个构成单选 多选大约 30 道覆盖数据结构、操作系统、计算机网络、移动端基础知识。编程题两道一道算法题一道跟移动端场景结合的逻辑题。问答题一道给一个移动端业务场景让你描述技术方案。这里有个比较有意思的地方问答题其实比选择题占比还重。我当时看到问答题的时候愣了一下因为平时刷牛客网模拟题很少遇到这种形式。后来想想这其实跟联想移动端的业务形态有关——联想旗下有大量终端设备和配套 App他们需要的人不只是能写算法还得能针对真实设备场景做方案设计。所以那道问答题更像是面试的预演考察你面对一个模糊需求时能不能给出有结构的回答。选择题的难度分布比较均匀没有特别偏门的题但也没有白送分的题。比如有一道问 HTTPS 握手过程中客户端什么时候开始发送加密数据这类题在八股文里被反复背过但真正做起来会纠结于ChangeCipherSpec到底算握手还是算会话阶段。这种细节题就是拉差距的地方。1.2 时间分配与做题顺序建议90 分钟做这么多题时间其实偏紧。我自己的策略是先花 5 分钟快速扫一遍所有题目把编程题的要求先看懂但不着急做然后回头从选择题开始按顺序推进。之所以不先做编程题是因为编程题一旦沉浸进去很容易忘了时间等回过神来选择题就没时间做了。我实际的时间分配是这样的选择题40 分钟平均每题 1 分钟左右拿不准的先标记不恋战。编程题35 分钟两道题各留 15 分钟左右剩下 5 分钟检查边界。问答题15 分钟写出核心思路和关键步骤即可不追求长篇大论。编程题两道里面第一道是比较常规的算法题第二道是移动端场景题。场景题当时我看完第一眼觉得有点懵因为它包装了一个长列表滑动加载图片的业务外壳本质考的是可见区域计算和懒加载的思路。这类题在力扣上刷不到原题必须理解移动端渲染的基本逻辑才能答好。这里提醒一句牛客的在线编辑器不支持自定义测试用例的断点调试所以你平时如果习惯了本地 IDE 的调试能力考前一定要去牛客模拟环境练几道题提前适应那种编译报错只能靠眼睛找的状态。2. 高频考点清单计算机基础与移动端专项2.1 数据结构与算法笔试常客的考察深度不管投的是哪个客户端岗位数据结构与算法都是笔试的基础盘。联想这场笔试题里选择题涉及到的数据结构知识主要集中在数组、链表、二叉树和哈希表。其中有一道题让我印象很深给出一棵完全二叉树的数组存储结构要求判断某个索引位置的节点是左孩子还是右孩子以及它的父节点索引。这题表面考的是完全二叉树的性质实际上考的是你对数组下标关系和二进制位运算是否真的理解而不是记住公式就完事。链表相关的题也很经典。有一道选择题给了一个单链表的头节点要求删除倒数第 N 个节点选项中给出了几种实现思路有的是先遍历一遍拿到长度再删有的是用双指针。这题本身不算难但多选的陷阱在于空间复杂度为 O(1) 且只需遍历一遍到底满足不满足得把双指针的边界条件想清楚。算法题方面那道编程题我在后面第 3 章会详细拆解这里先给一个结论不要只刷力扣热题要重点关注图论里的拓扑排序、并查集、贪心这几类。因为移动端业务场景里任务调度、依赖解析、资源加载顺序这类问题经常会用图论思想去简化联想这种做多设备互联的公司尤其喜欢考这块。2.2 操作系统与网络移动端笔试的隐形得分点操作系统和计算机网络在移动端笔试里占比不低而且考得比后端岗更贴近实际。比如操作系统部分有一道题问的是线程和进程的区别选项里有进程是资源分配的基本单位线程是 CPU 调度的基本单位这个大家都会选。但另一道题问到了死锁的四个必要条件并且要求从移动端 App 常见场景里选出可能形成死锁的例子这就有点意思了——它把操作系统概念映射到了主线程等待 IO、锁竞争这类真实问题上。网络部分的重点非常集中TCP 三次握手、TCP 四次挥手、HTTP/HTTPS、DNS 解析、HTTP 缓存。其中 HTTP 缓存是移动端性能优化的核心知识点选择题里给了几个 Cache-Control 字段的值要求判断哪些可以私有缓存、哪些必须公有缓存还要判断 ETag 和 Last-Modified 的优先级。这类题没有太多技巧就是需要你把 RFC 文档里的细节记准确。我在备考时总结过一个口诀强缓存看 Cache-Control / Expires协商缓存看 ETag / Last-Modified强制刷新时走协商缓存正常刷新时先命中强缓存。笔试里判断缓存命中顺序的题用这个思路基本不会错。2.3 移动端专项系统机制与跨端原理移动端专项知识是这场笔试跟后端笔试拉开差异的地方。如果你是科班出身但平时只写后端这部分可能会比较吃亏。Android 方向的考点集中在 Activity 生命周期、进程优先级、Handler 消息机制、Binder 通信这几个模块。有一道多选题给了一段代码里面涉及 Activity A 启动 Activity B 时两个生命周期方法的调用顺序选项特别容易混淆的是 onPause 在 onStop 之前还是之后、onRestart 什么时候调用。这类题没有捷径把生命周期流程图背到肌肉记忆是基本要求。iOS 方向的考点我印象比较深的是一道关于 ARC 和引用计数的题它给了一段 Objective-C 代码让你判断某个对象在几个位置被强引用。这道题考的是你对 autoreleasepool 的理解以及对 strong / weak / copy 修饰符的掌握。现在很多做 Android 的同学对 iOS 完全不熟但大厂笔试经常混合出题建议还是把 iOS 内存管理的基本模型过一遍。Flutter 和 React Native 也有涉及。Flutter 考的是 Widget 分为 StatelessWidget 和 StatefulWidget以及 setState 之后 Widget 树的重建机制React Native 考的是 JS 线程和原生线程之间的通信方式。这些内容如果你没有实际用过至少要把它们的设计理念和适用场景背熟因为问答题很可能让你在原生和跨端之间做技术选型。2.4 性能优化必背清单高频中的高频移动端性能优化这几年是笔试和面试的绝对高频主题联想这场笔试也不例外。我感觉选择题和问答题加起来至少有 5 道题在直接或间接考察性能优化相关的内容。整理下来以下几个方向是必须掌握的启动优化冷启动和热启动的区别、启动耗时如何统计、如何通过懒加载和异步初始化减少启动时间。内存优化内存泄漏的常见场景Handler 匿名内部类持有 Activity、静态 View、单例持有 ContextLeakCanary 的工作原理。卡顿优化掉帧的原因、Choreographer 的帧回调机制、如何通过 Trace 工具定位耗时方法。包体积优化资源混淆、移除冗余库、so 库按需拆分、App Bundle 的作用。网络优化DNS 预解析、连接复用、请求合并、弱网环境的超时策略。笔试选择题里考的是这些概念是什么但问答题会让你把这些概念串联起来。比如那道问答题的核心就是一个图片加载很慢的页面如何定位和优化这本质上就是在让你背诵上面这张清单。光会背还不够最好能说出一次真实的排查经历比如用 Profiler 抓内存、用 Charles 看网络耗时、在弱网环境下复现问题。这些内容是你后面面试的弹药笔试阶段积累下来不会亏。3. 编程题实战复盘从读题到 AC 的完整思路3.1 题目一任务依赖调度与拓扑排序第一道编程题题目描述大概是这样的给定 N 个任务编号从 0 到 N-1有些任务之间有依赖关系例如任务 B 必须在任务 A 完成之后才能执行。要求输出一个合法的任务执行顺序如果有环则输出空数组。这题本质上就是拓扑排序力扣上有原题课程表 II。但笔试场景下有个背景干扰题目把任务包装成了App 启动时需要初始化的模块比如模块 A 是崩溃监控、模块 B 是网络库、模块 C 依赖 A 和 B 完成才能初始化。如果不仔细读题很容易被这个业务外壳带偏以为要写一个复杂的启动框架。我当时的思路是直接用 Kahn 算法维护一个入度数组和一个邻接表。先把所有入度为 0 的节点入队依次出队并更新邻居的入度每次更新后如果入度变为 0 就再次入队。最后检查出队节点个数是否等于 N如果不等于说明存在环。为了照顾牛客编辑器没有自动补全的情况我建议先把数据结构定义写在草稿纸上理清邻接表怎么建、入度数组怎么更新再动手敲代码。核心代码大概是这个形态vectorint findOrder(int numCourses, vectorvectorint prerequisites) { vectorvectorint adj(numCourses); vectorint indegree(numCourses, 0); for (auto p : prerequisites) { adj[p[1]].push_back(p[0]); indegree[p[0]]; } queueint q; for (int i 0; i numCourses; i) { if (indegree[i] 0) q.push(i); } vectorint order; while (!q.empty()) { int cur q.front(); q.pop(); order.push_back(cur); for (int next : adj[cur]) { if (--indegree[next] 0) q.push(next); } } return order.size() numCourses ? order : vectorint(); }这里有个容易踩的坑如果题目要求按字典序输出任务顺序那么队列要换成优先队列保证每次出队的是编号最小的节点。笔试时一定要仔细读输出要求不要想当然。3.2 题目二长列表图片懒加载的移动端场景题第二道编程题就明显偏移动端了。题目大意是有一个可滚动的长列表列表项包含图片 URL要求实现一个懒加载逻辑只有当图片进入可视区域时才真正开始加载同时要避免滚动过程中重复触发加载。给出的接口简化成了列表总高度 H、可视区域高度 viewportH、每个列表项高度固定 itemH、滚动偏移 scrollTop、以及一个 loadImage(url, index) 的函数。这道题看起来像是在考前端但在移动端原生开发里同样是核心场景——RecyclerView 的预加载、UICollectionView 的 cell 重用、Flutter 的 ListView.builder 懒加载本质都是只渲染可视区域附近的数据。题目里的固定 itemH 是个很强的简化条件它意味着你可以用数学计算直接得出当前应该加载哪些索引范围内的图片而不是依赖 onMeasure 回调。我的解法分两步。第一步是计算可视区域的起始索引和结束索引const startIndex Math.floor(scrollTop / itemH); const visibleCount Math.ceil(viewportH / itemH); const endIndex startIndex visibleCount;第二步是加上预加载缓冲把可视区域上下各多算几个 item 作为提前加载的余量。这里有一个判断依据如果滚动速度很快只加载可视区域内的图片会导致白屏闪烁所以一般会多加载 1 到 2 屏的缓冲。但缓冲也不宜过大否则就失去了懒加载节省流量的意义。为了避免重复加载我维护了一个 Set 记录已经请求过的索引。这题的核心得分点不是算法复杂度而是你能不能从移动端用户滑动列表这个真实场景出发回答清楚以下三个问题什么时候加载、加载哪些、如何避免重复加载。如果只是把 startIndex 和 endIndex 算出来然后循环 loadImage虽然也能跑通但拿不到高分。3.3 问答题ECharts 折线图在移动端的 Tooltip 展示方案问答题给了一个更具体的场景在移动端页面里用 ECharts 画折线图要求折线图渲染完成后自动展示最后一个数据点的 tooltip。这个需求看起来简单但里面藏了好几个移动端特有的坑。第一个坑是渲染时机。ECharts 的 setOption 方法是异步渲染的如果你在 setOption 之后立刻调用 dispatchAction 去 showTip大概率会失败因为图表还没有渲染完成。解决方案是监听 finished 事件或者用 setTimeout 延迟 100 到 300 毫秒再触发。我笔试时写的是后者但后来在实际项目里发现 finished 事件更可靠const chart echarts.init(document.getElementById(chart)); chart.setOption(option); chart.on(finished, () { chart.dispatchAction({ type: showTip, seriesIndex: 0, dataIndex: option.xAxis.data.length - 1 }); });第二个坑是 tooltip 的触发方式。移动端没有鼠标悬停的概念默认情况下 tooltip 是通过触摸点击触发的。如果要让 tooltip 自动显示需要把 triggerOn 设为 none 或 mousemove然后通过 dispatchAction 手动控制。我建议在移动端把 tooltip 的 confine 属性设为 true让提示框始终在图表容器内显示避免弹出窗口超出屏幕边界。这一点跟热词里提到的figma 移动端拨号弹出窗是同一个思路——移动端所有弹出层都必须考虑屏幕边缘和键盘弹起的影响。第三个坑是真机调试时手指滑动和 tooltip 的冲突。当你用手指滑动图表区域时ECharts 默认会触发 tooltip 联动导致弹窗频繁出现。这里需要判断手势是点击还是滑动在 touchend 里根据移动距离决定要不要隐藏 tooltip。这个细节笔试可能不会要求写代码但在问答题里能提到会显得你是真在移动端做过图表。4. 调试工具链vConsole 在任意页面插入的实战方案4.1 为什么移动端调试比 PC 端麻烦移动端调试和 PC 端调试最大的区别在于PC 端你可以随便打开 DevTools想看网络请求看网络请求想看控制台错误看控制台错误移动端真机上没有这些工具尤其是线上环境或者嵌入到第三方 WebView 里的页面你甚至没法用 USB 连接电脑调试。我自己的习惯是开发阶段用 Chrome DevTools 的远程调试或 Safari 的 Web Inspector但到了联调阶段、测试阶段就必须靠 vConsole 这种页面内的调试面板。vConsole 的原理很简单它往页面里注入一个悬浮按钮点击后弹出一个类似浏览器控制台的抽屉可以查看 Console 日志、网络请求、Cookie 和 localStorage。但它的实用价值远超表面看起来的简单因为你在任何能打开网页的移动端环境里都能用它不依赖电脑和 USB。这个能力在笔试场景里很加分——如果你在简历或面试里提到我在线上环境用 vConsole 定位过问题面试官会认为你具备独立排查线上问题的能力。4.2 在任意页面插入 vConsole 的两种方式笔试里虽然没有直接考 vConsole 的代码但移动端调试手段作为基础素养很容易出现在项目描述类的问题里。这里分享我在实际项目中用的两种插入方式。第一种方式适合你能修改页面源码的情况直接用 npm 安装npm install vconsole然后在入口文件里引入并初始化import VConsole from vconsole; const vConsole new VConsole();需要注意这个初始化代码应该放在业务代码执行之前否则可能收集不到早期的日志。如果你希望只在测试环境启用可以通过环境变量控制让生产环境不加载 vConsole。第二种方式适合任意页面这个限制条件比如你只能在一个第三方页面上临时调试或者线上环境无法改代码。这时候用浏览器书签或地址栏执行一段动态插入脚本的方式最方便把以下代码存成一个书签需要用到的时候在页面上打开书签javascript:(function(){var sdocument.createElement(script);s.srchttps://cdn.bootcdn.net/ajax/libs/vConsole/3.15.1/vconsole.min.js;s.onloadfunction(){new VConsole();};document.head.appendChild(s);})();4.3 真机调试的常见坑vConsole 好用是好用但用多了以后我也攒下几个坑。第一个坑是它默认会捕获 console 输出如果你的页面逻辑里定时器特别多Console 面板会被刷屏这时建议在 new VConsole 的时候通过配置关闭不需要的插件。第二个坑是 vConsole 的悬浮按钮在某些 WebView 里会被页面底部的安全区域遮挡特别是在 iPhone 的刘海屏机型上需要在 CSS 里调整一下按钮位置或者给页面加上 viewport-fitcover 的适配。还有一个印象很深的坑在一些定制浏览器内核里比如某些国产安卓手机自带的浏览器vConsole 的网络面板可能抓不到请求。这不是 vConsole 的问题而是这些浏览器对 XHR 对象的包装不同导致 vConsole 的代理没有生效。碰到这种情况我的兜底方案是在服务端加临时日志或者用抓包工具从网关层看请求。夸克这类基于 Chromium 的移动端浏览器兼容性相对好一些但也不能指望 100% 覆盖所有环境。把这些经验写进博客和面试描述里能让你在移动端调试这个话题下显得经验丰富。5. 框架选型大厂移动端技术栈与 Vue 移动端方案盘点5.1 大厂移动端技术栈背后的选型逻辑笔试问答题之外面试几乎是必问框架选型的。有一个热词是b站移动端技术框架有哪些我也顺着这个话题整理了一下自己的认知。B 站主站 Android 端是原生 Kotlin 为主部分页面用 Flutter 做跨端iOS 端是 Swift 为主还有一些运营活动页是 H5 加原生壳的 Hybrid 方案。这个结构本质上代表了大厂移动端团队的常见思路核心链路用原生保证性能和体验非核心页面用跨端或 H5 提高迭代效率。这个选型逻辑在笔试问答题里可以直接迁移。回答你会怎么选择移动端技术栈时不要只说Flutter 性能好或RN 生态大而是要从团队规模、业务频率、性能要求三个维度拆解。比如首页这种性能敏感型页面一定用原生而运营活动页这种迭代频繁、生命周期短的页面用 H5 更合适。这套逻辑放之四海而皆准联想这种产品线很多的公司尤其吃这一套。5.2 好用的 Vue 移动端开发框架对比虽然联想笔试没有明确考 Vue 框架但移动端开发这一块 Vue 系框架的生态绕不开尤其是做 Hybrid 开发的时候。前端同学如果走移动端方向大概率会在 uni-app、Taro、Vant 之间做选择。我整理了一个对比表框架定位适用场景特点注意事项Vant移动端组件库Vue 3 项目中的 UI 组件需求组件丰富、按需引入机制完善只提供 UI 层需要自己配构建工具uni-app跨端应用框架一套代码发布到 App / H5 / 小程序插件市场活跃、内置条件编译性能上限不如原生复杂交互有成本Taro跨端应用框架React 语法写小程序和 H5对 React 生态友好联想这类公司内部技术栈如果不统一引入要谨慎NutUI移动端组件库京东体系的 Vue 项目组件风格偏电商社区热度比 Vant 小一些这里提一个热词python 移动端gui。Python 阵营确实有一些移动端 GUI 方案比如 Kivy 和 BeeWare但在互联网公司移动端岗位的技术栈里几乎不会出现。你只需要知道它们的存在面试时如果被问到可以回答Python 移动端 GUI 在原型验证和教学工具有价值但生产环境的性能、生态和包体积都不占优势。这种回答能体现你的视野又不至于让面试官觉得你跑偏了。Vue 移动端笔试面试中还有一个高频题是移动端适配方案。rem、vw、viewport 三种方案要能讲清楚区别尤其是 postcss-px-to-viewport 这类工具在打包时的换算逻辑。笔试不会让你手写适配代码但选择题很容易给一个设计稿宽度让你算某个元素在 375px 屏上的实际尺寸。5.3 笔试中的框架题怎么答才出彩框架相关的问题在笔试里通常以场景题形式出现。我的答题套路是四步先明确业务需求包括用户量、使用频率、性能预期再给出选型候选方案并做两两对比然后说明最终推荐及理由最后补充该方案的落地风险。举个例子如果题目是一个需要快速迭代的移动端电商应用你会选择什么技术栈我会先判断这不是一个纯性能导向的 App因为电商活动的更新频率远高于对首屏帧率的要求。然后我会对比纯原生、React Native、Flutter、H5 四种方案在团队招聘难度、动态化能力、性能表现三个维度的差异。最后给出结论核心交易链路用原生活动页和运营页用 H5如果团队有跨端诉求再逐步引入 Flutter 做非核心模块的验证。这种结构化答题的好处是有层次、有取舍能让阅卷人一眼看出你不是在背概念而是真的在思考工程问题。6. 笔试结束后的复盘方法笔试交卷后我做的第一件事不是对答案而是把每一道不确定的题记录到备忘录里。选择题里有几道关于 Android Handler 和 iOS 内存管理的题我虽然选了但心里没底所以我回去后专门翻了官方文档确认。这些模棱两可的知识点往往就是面试时会追问到的地方趁热打铁把它们弄懂比盲目刷新题更有价值。我还做了一件事把编程题的两道题在本地 IDE 里重新写了一遍并且补充了边界情况的测试用例。任务依赖调度那题我额外测了只有一个任务、所有任务互相独立、存在环这三种情况。长列表懒加载那题我模拟了快速滑动到列表底部再滑回顶部的情况验证了去重逻辑是否真的能避免重复请求。如果时间充足我建议你也把常考的知识点整理成一份自己的移动端笔试清单不只是背题而是每个知识点下面都写一段实际项目里是怎么用的。比如启动优化对应的是冷启动时 onCreate 做了太多同步初始化卡顿优化对应的是主线程做了大量字符串拼接。笔试的题目总是会变但底层的工程思维是永恒的。把知识落到真实场景里你拿到任何一家公司的移动端笔试题都知道从哪个角度切入。
返回列表