掌阅前端笔试复盘:从JS基础到工程化方案设计全解析
2026/8/29 0:44:06 网站建设 项目流程

2025年春招我投了掌阅集团的前端岗,笔试安排在晚上七点,两个半小时,全程一个在线编码平台加一道限时方案设计题。说实话,投完简历之后我做了不少准备,刷了两个月八股文和算法题,自认为前端基础还算扎实,但看到卷子的那一刻还是有点蒙:它不是单纯考某一个点,而是把 JS 基础、框架原理、工程化、浏览器机制和实际业务场景全揉在一起,有些题连题干都好几百字,读题就花了大量时间。这篇文章把我这次笔试的完整经历和复盘写出来,包括题型分布、核心考点拆解、失分点和我后来总结的备考思路,希望能给接下来准备前端岗位笔试的同学一点参考。

掌阅做数字阅读平台,前端岗位不只是写后台管理系统,还涉及阅读器、H5 页面、移动端适配、内容分发这些业务,所以我对笔试的预期是会更偏重真实场景。实际做下来也确实如此,基础题占一半,剩下的是框架原理、工程化和综合设计题。下面我按题型和考察点一条一条说。

1. 笔试整体观感:题型分布与考察重点

1.1 掌阅前端笔试考了什么:从题型说开去

先说卷面结构。我这次的笔试分四块:单选题、多选题、编程题、方案设计题。单选和多选加起来大概 20 道,覆盖 JS 基础、CSS 布局、浏览器机制、HTTP 缓存、Vue/React 原理。编程题有三道,一道是手写防抖和节流,一道是数组扁平化加去重排序,还有一道是 LeetCode 中等偏下难度的动态规划,题目大意是求最长递增子序列。方案设计题是两道选一道,我选了“大文件上传”那道,另一道是“阅读器章节预加载与缓存策略”,说实话那道更贴掌阅业务,但我当时对大文件上传更熟,就选了这个。

整体下来我的感受是:题目不算偏怪,但非常考验熟练度和知识的体系化。比如单选题里有一道问0.1 + 0.2 !== 0.3的原因,很多人会背成“浮点数精度问题”就选了,但它后面还追问了“在二进制中 0.1 的表示是什么”,这就是把八股文往底层多挖了一层。还有一道多选题关于事件循环,里面混了 Promise、async/await、setTimeout 甚至requestAnimationFrame,如果只是背“微任务先于宏任务”很容易做错,因为requestAnimationFrame的时机和普通的宏任务不太一样。

这些题目其实反映了一个趋势:前端笔试不再满足于“你知道这个 API 吗”,而是考“你知不知道它为什么这样设计,底层发生了什么”。掌阅的笔试尤其明显,毕竟阅读器对性能要求高,首屏渲染、滚动列表、图片懒加载这些场景都需要理解浏览器底层才能做好。

1.2 为什么这些题目会成为“拦路虎”

很多同学复习前端笔试的时候习惯于刷面经、背答案,结果一到真实笔试就翻车,是因为题目稍微“换壳”就认不出来了。掌阅这次有好几道题就是这么设计的:它不直接问“防抖是什么”,而是给你一段实际代码,问“快速点击按钮时为什么只执行一次,如果要求第一次立即执行怎么写”。如果你只是背了防抖的模板,不知道immediate参数的含义和实现逻辑,就会卡住。

另一个失分点是时间分配。两个半小时听起来很多,但单选多选涉及大量阅读,每道题都可能要花两三分钟,手写代码题还要考虑格式和边界,最后留给方案设计题的时间往往不足三十分钟。我考场里明显感觉到后半程心态有点崩,因为阅读器缓存那道方案题虽然没选,但光看完题干就花了不少时间,以至于后面检查编程题的时间被压缩了。

所以我把这次笔试的“拦路虎”总结为三点:一是题目很长,需要快速抓重点;二是考察底层原理,不能只背结论;三是方案设计题没有标准答案,必须在有限时间内展示出清晰的思路。后面我会针对每一类问题展开讲。

2. 基础题与手写题:送分题还是陷阱题?

2.1 那些“看似简单”的JS题

先挑几道印象深刻的单选题说说。

第一道是typeof nullnull == undefined的结果,这题很多人秒选。但后面跟了一道“如何判断一个变量是真正的对象”或者“如何区分数组和对象”,这就不是纯记忆了,需要理解Object.prototype.toStringinstanceof更可靠。我当时写了Object.prototype.toString.call(value) === '[object Object]',也把数组、正则、日期这些特殊情况列了出来。因为面试官想知道你是记了结论,还是理解了类型判断的原理。

第二道是关于==的隐式转换,比如[] == ![]的结果。这题几乎每一轮笔试都会出现,但有个容易忽略的坑:![]会先转成布尔值false,再和[]比较,于是变成了[] == false,接着[]转原始值成为空字符串,false转数字变成 0,空字符串转数字也是 0,所以结果是true。如果只看表面,很容易选成false。这种题考的就是“转换优先级”和“ToPrimitive”规则,不是靠背答案能应付的。

第三道是原型链和this结合起来的题。给出一个构造函数,里面有实例方法、原型方法、静态方法,然后问你不同调用方式下的输出。这里要注意箭头函数没有自己的this,普通函数的this取决于调用位置。我当时做的时候特意在草稿纸上画了原型链,把instanceConstructor.prototypeConstructor三者的关系标清楚,才没有掉坑。建议大家平时做题也养成画图的习惯,笔试不比面试,不能问面试官,只能自己稳一点。

2.2 手写Promise、防抖节流和深拷贝的评分点

编程题第一道是“手写防抖和节流,并说明区别”,这题我写了三个版本:基础版、带immediate参数的防抖、带throttle的首次执行。注意笔试评分时会看边界处理,比如this指向和参数透传。如果只写一个setTimeout壳子,可能只能拿一半分数。我当时的实现大致是:

function debounce(fn, wait = 300, immediate = false) { let timer = null; return function (...args) { const callNow = immediate && !timer; if (timer) clearTimeout(timer); if (immediate) { if (!timer) fn.apply(this, args); timer = setTimeout(() => { timer = null; }, wait); } else { timer = setTimeout(() => { fn.apply(this, args); timer = null; }, wait); } }; }

但注意我这个实现里有个小问题:当immediate为 true 时,timer本身是 timeout 的 id,在callNow判断里会把它当成布尔值用,虽然timer是数字,但为了严谨应该用timer !== null判断。笔试里的代码不需要一定跑通,但逻辑要自洽。

第二道是数组扁平化加去重排序。很多人会直接Array.from(new Set(arr.flat(Infinity))).sort((a, b) => a - b),但面试官可能更想看到你徒手递归实现flat,因为这样才能考察对递归和reduce的掌握。我写了两种解法,一种用reduce递归,一种用while循环加展开运算符,还考虑了稀疏数组的情况。数组的边界情况很多,[1, , 2]在遍历时undefined会被忽略,但flat会保留空位,这些细节都是加分项。

第三道是手写 Promise,但不是让你实现完整的Promise/A+,而是实现Promise.allPromise.race,并且要考虑输入不是数组的情况。我写了Promise.all的一个简化版,用计数器判断是否全部完成,同时用try/catch捕获每个 Promise 的异常。关键点是“返回一个新 Promise”,并且“结果数组保持原顺序”。如果直接把then结果 push 到数组里,遇到异步任务先完成就会顺序错乱,这其实是最常见的失分点。

2.3 CSS与浏览器渲染的那点事

CSS 题这次出现的比例不低,有一道考“水波纹进度条如何实现”的,正好问到怎么用 CSS 动画做点击反馈。题目给了两种方案,一种是transform: scale()opacity动画,另一种是改变width做进度条,问哪个性能更好。显然transformopacity的变化不会触发重排重绘,而是走合成器,所以性能更好。这背后就是“浏览器渲染流程”的问题:从 HTML/CSS 到解析、样式计算、布局、绘制、合成,每一层都可能成为性能瓶颈。

还有一道 CSS 布局题是“实现一个高度自适应、左右两栏固定宽度、中间自适应的三栏布局”。除了经典的 flex 和 grid 之外,还可以用圣杯布局、双飞翼布局。但笔试里最稳的是写 flex,因为简单直接。不过题目追问了“如果中间栏要先渲染,DOM 结构该怎么排”,这就涉及到双飞翼布局或者 grid 的order属性了。我当时先写了 flex 版本,又补充说明如果要求中间优先渲染,需要用双飞翼布局,并在注释里标了一下。虽然没写完整,但让批卷人看到思路是能拿分的。

CSS 和浏览器机制往往是联系在一起的,比如重绘重排、requestAnimationFrame、合成层。掌阅这类内容平台非常看重列表滚动性能,所以笔试中反复出现“如何减少重排”的选择题,比如批量修改样式用classList、先把元素display: none再修改最后显示、读写分离避免强制同步布局。这些点我复习的时候都看过,但真正做选择时还是会犹豫,因为有两个选项看起来都对。建议平时把“触发重排的属性和方法”整理成一张表背下来,例如offsetTopscrollTopgetComputedStyle这些读操作会强制刷新渲染队列,容易引发 Layout thrashing。

3. 框架与工程化:Vue/React背后的原理考察

3.1 响应式原理与虚拟DOM,八股文也有深水区

掌阅前端技术栈从招聘描述看主要是 Vue,React 也有一部分。笔试里 Vue 题明显多于 React,而且深入到了响应式原理。单选题考了 Vue3 的响应式是基于 Proxy,Vue2 是基于 Object.defineProperty,然后多选追问了“Proxy 相比 defineProperty 的优势”,四个选项包括“可以监听新增属性、可以监听数组索引变化、性能更好、可以监听删除操作”。如果没有真的用过 Vue3,很容易把“性能更好”当成必然选项,但 Proxy 并不天然更快,它只是在语义上更完整,性能还要看具体实现。这种细节就需要源码阅读经验了。

还有一道是关于nextTick的。题目说为什么修改数据后不能马上获取更新后的 DOM,应该怎么办?答案是 Vue 的异步更新队列机制,nextTick内部会用 Promise 或 MutationObserver 模拟微任务。这里有个容易忽略的点:在 Vue3 中nextTick返回的是一个 Promise,所以可以直接await nextTick()。我在备选答案里看到了这个选项,心一稳,说明我之前看过源码里的实现。

虚拟 DOM 和 diff 算法也考了,但不是直接问“diff 算法的时间复杂度”,而是给了一段列表渲染的代码,问为什么加key能优化渲染,以及用数组 index 作key有什么问题。这题我在实际开发中踩过坑,所以答得比较顺:index 会导致组件复用错误,比如列表头尾插入节点时,所有 key 都会变化,从而引发不必要的重建和状态错位。关键是要答出“key 是 diff 算法的复用标识,不是简单的唯一值”。

3.2 Webpack/Vite配置文件里的学问

工程化题占的比例比我预期高,大概有 4 道选择和一道简答题。简答题是“线上 CSS 和 JS 文件为什么要加 hash 后缀,hash、chunkhash、contenthash 有什么区别”。这题其实先要知道 hash 是为了浏览器长缓存,文件内容变了 URL 才会变,从而避免旧缓存问题。我有一次项目上线后用户反馈样式没更新,就是因为没做 contenthash,导致文件名没变,浏览器一直用旧缓存。所以答这题时我结合了实际经验:用contenthash按内容生成 hash,这样只有该文件变更时 URL 才变化;chunkhash是同一 chunk 共享 hash,如果异步 chunk 里一个文件变了,同 chunk 其他文件也可能跟着变,缓存失效范围变大;hash是整个构建一次一个 hash,一般不适合长期缓存。这题如果只会背概念,很难拿满分,必须能说出“为什么”。

另一道选择题是关于 Vite 为什么比 Webpack 快。选项里有“基于 ESM 原生模块、按需编译、使用 esbuild 预构建依赖、采用多进程打包”。实际上 Vite 开发环境冷启动快主要是因为“利用浏览器原生 ESM,只在请求时编译模块”,预构建依赖用 esbuild 把多包转成 ESM,减少了浏览器请求数。而“采用多进程打包”是 Rollup 插件可以做的,不是 Vite 启动快的核心原因。我之前用过 Vite 搭过小项目,这些点能对得上。

工程化还考了 Tree Shaking 的条件,问“什么情况下import { a } from './utils'中的 b 函数会被自动删除”。答案是“模块是 ESM 静态结构、没有副作用、没有使用 b”,如果 b 函数里调用了console.log或者有 top-level 副作用,一般不能删除;如果引入了整个对象import utils from './utils',也很难 tree shaking。实际项目里配置"sideEffects": false是有副作用的,需要小心,不能无脑配置。

3.3 微前端与模块联邦:笔试里的“加分项”

掌阅前端岗笔试里出现了一道微前端相关的多选题,问“微前端方案中主应用和子应用之间的通信方式有哪些”,选项包括 props 下发、自定义事件、路由参数、全局状态库。这题本身不难,难的是后面有一道“为什么需要微前端”的简答题,要求从业务角度分析。

我在回答时先说了微前端的核心价值:解决巨石应用带来的团队协作、独立部署、技术栈隔离问题。然后结合阅读器业务举例:如果掌阅要做“阅读+”生态,把书城、社区、VIP 会员这些模块拆成独立子应用,各团队可以独立发版,主应用只负责导航和登录态。但我同时也提到微前端不是银弹,如果团队规模不大、应用边界模糊,强行上微前端反而会带来样式隔离、依赖复用的复杂度。

模块联邦我也准备过,但笔试没考太深,只在多选里出现了一个选项:“Module Federation 相比 qiankun 的优势是什么”。我选了“运行时共享依赖而不需要统一技术栈”。其实 qiankun 也支持技术栈隔离,但模块联邦是 Webpack 原生能力,能在构建阶段就把公共依赖打成 shared 包,避免子应用重复打包 React/Vue 框架,从而减小体积。不过这题问的是“优势”,容易有歧义,我权衡后选了运行时依赖共享和动态远程加载。

这类题近几年出现频率明显变高,因为中大型公司的前端团队都在搞微前端改造。准备笔试时不能只看概念,要能说清“微前端适合什么场景、不适合什么场景”,并且知道 qiankun、wujie、Module Federation 的差异,不然很容易在多选里蒙错。

4. 方案设计题与算法题:拉开差距的地方

4.1 大文件上传、实时通信这些“场景题”怎么答

我选的方案设计题是“设计一个支持大文件上传的 H5 页面,要求支持进度显示、断点续传、暂停/恢复,并考虑多文件并发场景”。题目给了一个实际场景:阅读 App 中用户上传 PDF、epub 文件用于云端书架,单个文件可能达到 200MB。

我的解题思路分三层。第一层是文件切片,用Blob.prototype.sliceFile.prototype.slice把大文件切成固定大小的 chunk,比如每片 2MB,然后给每个 chunk 加序号和文件唯一标识,上传时可以用并发控制同时发 3 到 5 个分片。第二层是上传通道,我写了两种:用XMLHttpRequest可以监听upload.onprogress事件,得到每个请求的上传进度,然后聚合成总进度;用fetch需要自己封装进度模拟,不太适合精确上传进度。第三层是断点续传,核心是“后端先接收分片,记录已上传分片列表,前端上传前先调接口获取已上传分片,然后只上传缺失的分片”。

在实现上,我强调了几点:文件唯一标识可以用文件的sha1或者spark-md5计算,但超大文件计算哈希很耗时,可以用“抽样 + 增量计算”的方式,比如取文件头、中、尾三个片段算哈希,或者用 Web Worker 来做,避免主线程卡顿。正好这次热词里就有人提到“前端使用 worker 上传大文件”,我用 Worker 做文件分片和哈希计算,这样即使文件大也不会阻塞 UI。暂停和恢复则通过 AbortController 取消未完成的请求,上传队列里维护一个Set记录已完成和进行中的 chunk id。

关于多文件并发,我提了一个“线程池”思路:维护一个队列,最多同时上传 N 个文件,每个文件内部最多并发 M 个分片,总体控制浏览器连接数。这里我画了一张简单的队列逻辑图(在纸上),代码里用一个forEach实现并发池,大概这个样子:

async function uploadFiles(files, poolSize = 3) { let index = 0; const workers = new Array(poolSize).fill(0).map(async () => { while (index < files.length) { const file = files[index++]; await uploadOneFile(file); } }); await Promise.all(workers); }

虽然方案设计题不要写出完整代码,但把并发控制、错误重试、进度聚合这几个点讲清楚,比列一堆 API 更有说服力。笔试结束后我也在想,如果选“阅读器章节预加载与缓存策略”那题,可能更贴近掌阅业务,但大文件上传是我实际做过的功能,能写出更多细节,所以选自己熟悉的题目永远是稳妥策略。

4.2 前端算法题:别只背题目,要会推状态转移

算法题是“给定一个数组,求最长连续递增子序列的长度”,题目描述有点绕,但其实就是 LeetCode 673 或 300 的变体,不过它要求的时间复杂度是 O(n log n),而且需要输出序列长度。我之前刷过这题,但笔试里不能直接写 O(n²) 的 DP,否则会被扣分。我最后用“dp + 二分”的方式写了,核心是维护一个tails数组,tails[i]表示长度为 i 的递增子序列的最小末尾值,然后遍历数组,用二分找到第一个大于等于当前元素的位置,更新tails。这样最终tails的长度就是最长递增子序列的长度。

笔试里写算法题有个坑:题面没有给详细的方法名和输入输出示例,需要自己定义函数签名。我考场里花了几分钟推理输入是什么、输出要什么,还好题目给了示例,[10,9,2,5,3,7,101,18]应该输出 4。这里要注意“连续递增”和“递增子序列”的区别,如果是连续递增,那就简单多了,但题目明确举例[1,3,5,4,7]的最长连续递增子序列是1,3,5,长度 3,而不是 DP 的 4。说实话我第一眼差点做错,因为平时刷题“最长递增子序列”默认是非连续的,需要仔细读题。后来我按连续递增做,O(n) 搞定。这提醒我笔试时候审题非常重要,不能凭肌肉记忆写代码。

还有一道算法题在编程题最后,是“判断二叉树是否对称”,要求用递归和迭代两种方式。递归的思路是isMirror(left, right),迭代用队列成对入队。这道题的难点是边界条件很多,比如空节点怎么处理、左右子树同时为空怎么返回。我写递归时花了很久,因为总想用层序遍历,但层序遍历需要记录空节点,代码量偏大。其实对称二叉树用递归最清晰,笔试时间有限,不要为了炫技选复杂解法,稳定通过才是第一目标。

4.3 反问环节:如何从笔试题目反推团队技术栈

做完整张卷子,我意识到笔试里的方案设计题其实能看出团队的技术倾向。大文件上传那题明显是“App 内嵌 H5 或收银台”常见的需求,掌阅后端服务可能已经有分片上传接口,前端更多是和它对接。阅读器预加载和缓存那题更贴业务,如果选择了它,需要结合“上一章/下一章预加载、章节列表缓存、长文本分片渲染”来答,可能还会涉及localStorageIndexedDB甚至RxDB这一类前端数据库方案。虽然现在我还没拿到后续通知,但我个人建议后续准备面试时,可以多了解一下掌阅 App 的阅读器实现,比如 epub 解析、字体适配、滚动翻页和滑动翻页的性能取舍。

另外,方案设计题并没有标准答案,但阅卷人会看你的技术视野。比如我在大文件上传里提到了使用 Web Worker 做文件分片和哈希,提到使用spark-md5计算指纹,提到XMLHttpRequest的上传进度比fetch更好,这些都说明我有实际项目经验。反过来,如果只回答“用 Element UI 的 Upload 组件”,可能只能拿基础分。所以准备笔试时,一定要把自己做过的项目细节提炼成“场景 + 技术选型 + 为什么这样选 + 遇到的坑”这种结构,这样在方案设计题里才能有的放矢。

方案设计和算法题是拉开差距的地方,因为基础题大家都会刷,但能不能在有限时间里把思路表达清楚,靠的是平时积累。我的建议是平时多写技术笔记,把项目里的难点和解决方案记录下来,笔试时才不会大脑空白。

5. 常见失分点与避坑指南

5.1 我踩过的坑:时间分配与题面阅读

这次笔试最让我吃亏的是时间分配。前面单选多选我做得太细,每道题都反复推敲,导致留到编程题的时间只有五十分钟。手写 Promise 那道我写了很久,因为一直纠结要不要完整实现 resolve、reject、then、catch、finally,最后只写了简化版。事后复盘,这类手写题不是让你写生产级代码,而是看核心逻辑,应该用尽量短的时间完成第一个版本,再回头优化。

还有一个坑是题面阅读。选择题里有一道问“以下哪个是 margin 塌陷的解决方案”,我一开始以为是问“margin 重叠”是什么,选了相邻两个块级元素 margin 取最大值,但题目其实是问“父元素和第一个子元素的 margin-top 什么时候会合并”,答案应该是给父元素加overflow: hidden或者加 padding/border。这两个概念经常混在一起,笔试里如果读题不仔细,就会选错概念。当时我花了不少时间对照选项,才意识到自己差点选偏。

建议大家在笔试前四十个小时里,不要盲目刷偏题怪题,而是把高频考点的基础概念重新过一遍,特别是容易混淆的:=====margin塌陷和合并、节流和防抖、强缓存和协商缓存、hashchunkhash等。用表格列出来,考前扫一眼,比临时刷题更有效。

5.2 面试官阅卷时的“隐形评分标准”

我自己也帮团队筛过前端简历和笔试,所以大概知道笔试阅卷时会关注什么。第一是思路,哪怕代码写不全,只要注释里写了“用两个指针从两边向中间移动”,也能拿到步骤分;第二是边界条件,比如空数组、空对象、空指针、输入为null的情况有没有处理;第三是代码风格,命名是否清晰、有没有过多 console、是不是用了一个大函数搞定一切。如果代码里能体现模块化思想,比如把文件切片、上传、进度计算拆成函数,印象分会好很多。

另外,方案设计题要特别注意“可维护性”。面试官喜欢的答案不是堆技能树,而是先讲清楚需求,再列出可选方案,最后给出推荐方案和理由。比如大文件上传,我会先说为什么不用单一PUT上传,因为网络中断后需要重传整个文件,浪费流量;然后说切片上传虽然增加后端复杂度,但能断点续传;再说切片大小怎么定,太大容易超时、太小请求数太多,2MB 是比较常见的选择。这种“为什么这么选”的思考过程,比单纯的方案列表更有说服力。

5.3 备考期的资料清单和学习路线

如果你也是为前端春招笔试准备,我比较推荐把时间花在四块:第一是 JS 语言核心,不只是背 API,要能手动实现Promise.allcall/apply/bind、深拷贝、防抖节流;第二是浏览器原理,特别是事件循环、渲染流程、缓存、跨域;第三是框架源码,Vue 和 React 至少要选一个深入,理解响应式、虚拟 DOM、更新调度;第四是工程化,Webpack/Vite 的核心机制、微前端、模块联邦。

具体资料方面,我刷的是牛客网的前端笔试题库,手写题会自己再在 IDE 里跑一遍,而不是只看答案。算法题我用 LeetCode 刷了大概两百道,重点刷了数组、字符串、二叉树、动态规划这四类。这里有个小技巧:不要按题号刷,而是按“解题模式”刷,比如“双指针”、“滑动窗口”、“前缀和”、“二分答案”、“状态压缩”这些模式,每类挑十道左右,快很多。

如果你想知道自己离掌阅这类公司还差多少,可以拿一套模拟题计时练一次。我是在笔试前三天做了两套模拟卷,严格按照时间走,这才发现原来自己做题慢是因为老在“不想写注释”和“想写完整”之间摇摆。提前暴露问题,考试时才不会慌。

6. 个人复盘与下一步计划

笔试结束后我马上把错的题回忆了一遍,自己在搜答案时发现有两道多选其实记错了:一道是关于MutationObserver是否属于微任务,虽然它一般作为微任务调度,但在浏览器规范里它不属于标准微任务队列,而是单独的任务队列;另一道是关于contenthash在提取公共依赖时可能产生的问题,虽然我选对了“公共模块提取会导致业务代码 contenthash 变化”这个选项,但没有深入解释为什么。

后来我查了一些资料,发现掌阅这种体量的公司很看重“性能优化”和“业务理解”。笔试里反复出现的阅读器场景不是偶然,它需要前端同学理解长列表渲染、字体加载、缓存策略、文本选择、翻页动画和内存管理。如果我能进到面试,我会重点准备这些方面:用createDocumentFragment和虚拟滚动优化阅读器目录、用IntersectionObserver做图片懒加载,以及用 IndexedDB 缓存章节内容,降低网络请求。如果后面还有类似笔试,我可能会主动选择那道“阅读器章节预加载与缓存策略”的方案题,因为它才能真正体现我对掌阅业务的理解。

最后再说一个小技巧:笔试的时候最好开一个本地编译器,我习惯用 VS Code 写代码,但笔试平台是网页编辑器,没有代码高亮和自动补全,手感很不一样。考前尽量用同样的在线平台做几道题,提前适应。我觉得这次笔试虽然没有发挥到完美,但它让我清晰看到了自己的短板在哪里,后面几个星期我知道该往哪个方向使劲了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询