[译]准备 2017 前端面试

原文:Preparing for a Front-End Web Development Interview in 2017 by David Shariff

在最近这几年里,我在亚马逊和雅虎面试了许多专注于前端开发的 Web 开发者和软件工程师。在这篇文章中,我想分享一些能帮助大家更好地准备面试的点。

声明:本文并没有罗列出所有在前端面试中可能遇到的问题,但你可以将其视为知识基准。

面试是很难的,作为候选人,你通常需要45分钟的时间来展示你能做什么。而作为面试官,也很难在这么短的时间内评估出这个人是不是适合。因为天下间没有唯一的面试标准,因此通常要求面试官从给定的一个范围里评判,除了提出的问题是由他们自己决定的。

我将从双方的角度出发,作为面试自己的面试官,尽量去覆盖所有重要的在面试中你可能会被问到的前端开发领域。

常见的误解

过去我看到面试者所犯的最大的错误之一是没有准备好应付琐碎的问题,如“什么是盒子模型?”或者“告诉我在JavaScript 里 == 和 === 之间的区别?”。虽然知道这些问题的答案很好的,但实际上并没有真正告诉面试官多少面试者的水平。

因为,你可能面对的是一个更现实些的面试——使用JavaScript,CSS 和 HTML 编写代码。在面试中被要求实现一些 UI,或构建一个小部件,或者根据一个库(如Lodash 和 Underscore.js)来编写常用的工具类函数。 例如下面这些:

  • 构建通用 Web 应用程序的布局和交互,如 Netflix 网站。
  • 实现小部件,如日期选择器,轮播或购物车。
  • 写一个类似于 debounce 的功能或者深度复制一个对象。

说到库,我常常看到的另一个错误是面试者完全依靠最新的框架来解决面试问题。你可能会想,如果我在实际开发中可以使用jQuery,React,Angular 等等,哪我为什么要重新造轮子呢,为什么不能在面试中使用呢?但是实际上呢,技术,框架和库都会随着时间的推移而变化——因此我更有兴趣看到你知道前端开发的基本原理,而不是依赖于更高层次的抽象。如果你无法回答面试问题,我希望你至少能够彻底解释和理解这些库到底在做些什么。

总的来说,你要明白的是大部分面试问的都是非常实际的编程问题和实在的问题。

JavaScript

你需要知道 JavaScript 并且需要了解它的里里外外。你所面试的职位的级别越高,在该语言的知识就需要越深。 至少,下面列出的 JavaScript 主题应该知道:

  • 执行上下文,特别是词法作用域(lexical scope)和闭包。
  • 声明提升,函数与块作用域和函数表达式与声明。
  • 绑定——特别是 call,bind,apply 和词法 this(lexical this)。
  • 对象原型,构造函数和混合。
  • Composition and high order functions.
  • 事件委托和冒泡。
  • 类型判断(type coercion),使用typeof,instanceof和Object.prototype.toString。
  • 使用回调函数,Promise,await 和 async 处理异步调用。
  • 何时使用函数声明和表达式。

DOM

知道如何遍历和操纵 DOM 是很重要的,然而大多数面试者强调他们一直依赖于 jQuery 或者最近一直在撰写很多 React & Angular 类型的应用程序。在日常工作中你不太可能会这样做,因为我们大多数人正在使用抽象的类型,但是在不使用库的情况下,你应该知道如何执行以下操作:

  • 使用 document.querySelector 或旧浏览器 document.getElementsByTagName 选择或查找节点。
  • 上下遍历——Node.parentNode, Node.firstChild, Node.lastChild 和 Node.childNodes。
  • 左右遍历——Node.previousSibling 和 Node.nextSibling。
  • 操作——在 DOM 树里添加,删除,复制,创建节点。你还应该知道如何改变一个节点的文本内容和切换,删除或添加一个 CSS 类名.
  • 性能——拥有大量节点的时候操作 DOM 的代价是昂贵的,你至少要知道 document fragments 和节点缓存。

CSS

你应该至少知道如何在页面上对元素进行布局,知道如何使用子代或直接后代选择器定位元素以及何时使用 class 与 ID。

  • 布局——知道如何将元素紧靠排列在一起以及知道两列和三列布局。
  • 响应式设计——根据浏览器宽度改变一个元素的尺寸。
  • 自适应设计——根据具体的断点改变元素的尺寸。
  • 权重(specificity)——知道如何计算一个选择器的权重和级联对(样式)属性的影响。
  • 适当的 namespacing 和对 classname 的命名。

HTML

知道哪些 HTML 标签最能表现你要展示的内容以及相关联的属性值应当是你的手头知识。

  • 语义标记。
  • 标签属性,如 disabled, async, defer 以及何时使用 data-*。
  • 知道如何声明你的doctype(大多数人并不是每天都写新页面,从而忘记了这个)以及什么 meta 标签可以使用。
  • 无障碍内容,比如使一个 input checkbox 有更大的响应区域(使用 lable "for")要有 role="button" ,role="presentation" 等等。

系统设计

后端的同仁们在系统设计面试时通常涉及到 MapReduce,设计分布式键值存储或需要 CAP 定理等知识。虽然前端工程师不需要深入了解如何设计这些系统,但是在被要求设计通用应用程序的前端架构时,你也不需感到惊讶。这些问题通常是不精准的,比如“设计一个像 Pinterest 这样的网站”或“告诉我如何建设一个购物结账服务”。以下是要考虑的领域:

  • 渲染——客户端(CSR),服务器端(SSR)和通用渲染。
  • 布局——如果您正在设计多个开发团队使用的系统,则需要考虑构建组件,并且要求团队遵循一定规范来使用这些组件。
  • 状态管理,如单向数据流或双向数据绑定之间的选择。还应该考虑如果你的设计是被动或响应式的编程模型的情况下,组件相互之间应该如何关联,例如 Foo->Bar 或 Foo->Bar。
  • 异步流程——你的组件可能需要与服务器实时通信。你提出的设计应同时考虑 XHR 与双向通讯。如果面试官要求你支持旧版浏览器,则需要在隐藏iframes,script 标签或 XHR 之中进行选择。如果没有,你可以建议使用websockets,或者你可能觉得服务器发送的事件(SSE)更好。
  • 分离关系——Model-View-Controller (MVC),Model-View-ViewModel (MVVM) 和 Model-View-Presenter (MVP) 模式。
  • 多设备支持 - 你是否会对 web,mobile web 和 hybrid app 使用相同的实现,还是考虑将其分开实现?如果你正在建立像 Pinterest 这样的网站,那你可能考虑在 web 上使用三列布局,但在移动设备上使用一列。这时你应该如何处理这个?
  • 资源分发——在大型应用中,独立团队拥有自己的代码库是很常见的。但这些不同的代码库有的依赖关系,并且每个通常都有自己的方式来发到更新到生产环境。你的设计应考虑到资源的构建方式(代码拆分),测试(单元和集成测试)以及部署。您还应该考虑如何通过 CDN 分发资源或将它们内联在一起以减少网络延迟。

前端系统设计是一个值得关注的大题目,我打算另写一篇专门介绍它的博客。

Web 性能

除了通用编程最佳实践之外,你还应该期望面试官能够浏览你的代码或设计及其性能。以前将 CSS 放在 document 的顶部以及 JS 脚本放在页面的底部是足够的,但 Web 正在快速发展,你应该明白这个领悟的复杂性。

  • 关键渲染路径。
  • Service workers。
  • 图像优化。
  • 懒加载和 bundle 拆分。
  • HTTP/2 和服务器推送的一般实现。
  • 何时预取和预加载资源。
  • 减少浏览器 reflow ,何时将元素提升到 GPU 处理。
  • 浏览器 layout,compositing 和 painting 之间的差异。

数据结构及算法

这可能是有争议的,但对 Big-O 时间复杂性和常见运行时间(如 O(N) 和 O(N Log N))的基本了解也不会对你有什么坏处。鉴于单页应用程序现在更加常见了,那么了解诸如内存管理之类的也不坏。例如,如果你被要求构建客户端拼写检查器,知道常见的数据结构和算法会使你的活容易的多。

我不是说要求你拥有 CS 学位,但是本行业已经以及不在是构建简单的网页。网上有很多资源可以帮助你很快地获得基础知识。

一般 Web 知识

你也要需要知道网络是怎么样的架构的技术和相关模型。

  • HTTP 请求——GET 与 POST 及相关联的 headers 比如 Cache-Control,ETag,状态码,和 Transfer-Encoding 等等。
  • REST vs RPC.
  • 安全性——何时使用 JSONP,CORs 和 iframe 策略。

总结

成为一个网站的开发或工程师,是需要大量的知识的。不要因为所需知识的深度停滞不前,而是要保持开放的心态来学习各种知识,以便用这些来构成客户使用的最终产品。

除了本文涵盖的技术主题之外,你还可以讨论过去的项目,描述一些有趣的情况以及你做过的权衡。

我相信我还有很多没有谈到的前端领域,我很乐意听到你的想法,或者让我知道我没有涵盖的你认为的某些重要的面试话题。

*最后感谢 Facebook 的 ShihChih Huang 以及 Coinbase 的 Preethi Kasireddy 对本文的复核。

posted @ 2017-07-20 22:50  雷夫·麦  阅读(288)  评论(0编辑  收藏  举报