在外网看到davidshariff这篇关于前端应该学习的内容,给了我很大的启发,也明确了哪些知识是我们应该着重去学习和关注的。所以花了些时间翻译出来,希望给曾经在前端浩瀚学海里面迷茫找不到方向的人一些参考。文中有翻译不够准确的地方欢迎指正。
在亚马逊和雅虎任职的这几年,我面试了许许多多前端方面的应聘者。在这篇文章中我想分享一些能够帮助大家更好准备面试的关键点。
事先声明,这篇文章的内容不是在前端面试时你可能会被问到的具体的问题清单,而是面试中会涉及到的知识点的原理的一个概括。
面试并不容易,作为应聘者,你必须在45分钟之内好好的展示自己。而作为面试官,如果在这短短时间内去判断一个候选人是否适合这个岗位也很有难度。面试很难帮我们确认候选人跟岗位是完全匹配的,但是通过对面试问题的回答可以对于候选人有个区分度。
即作为应聘者也曾担任过面试官的我,希望能通过这篇文章来展示前端开发当中最为重要的几个方面。
常见误区
最常见的一个问题就是许多候选人准备面试非常纠结于一些很细节化的问题,诸如“什么是盒子模型”或者“js当中==和===的区别”等。当然这些细节问题如果了解当然是很好的,但是这些问题并不能真正反映出应聘者的水平。
相反的,可以预见我们所遇到的面试大多可能更注重手撕代码。面试中经常会要求应聘者实现UI布局,封装组件或者实现一个Lodash或者Underscore.js中封装好的方法。比如:
- 实现网站的基本布局
- 实现一个日期选择器(date picker),carousel或者购物车
- 实现个debounce方法或者深拷贝
而说到各种框架,另一个我常见的问题就是应聘者拿最新框架中的方法来解决面试所问的问题。你可能不理解当我在实际工作当中使用的都是jQuery, React, Angular这样的成熟框架,为什么还要自己重复造轮子,而不是在面试中直接用这些框架去回答。
我们要知道,技术、框架和组件库会不断的更新,而更为看重的能力是对于前端开发的底层原理的理解而不是对封装工具的依赖性。如果脱离了轮子你就无法解答问题,那么至少希望候选人能大概了解并能解释所用的工具在运行的时候的原理是什么。
总体来说,我们对大部分的面试的设想还是要更多倾向于实用性编程。
JavaScript
作为候选人了解js和其底层原理是很有必要的。当我们在应聘一些更资深级别的面试的时候往往会考察对于语言了解的深度。至少,以下这几个js的原理必须要理解。
- Execution context, especially lexical scope and closures.
- 执行上下文,尤其是词法作用域和闭包
- Hoisting, function & block scoping and function expressions & declarations.
- 变量提升,函数、块级作用域和函数表达式以及声明
- Binding – specifically call, bind, apply and lexical this.
- 绑定,尤其是call bind apply和this指向
- Object prototypes, constructors and mixins.
- 对象原型、构造函数和继承
- Composition and high order functions.
- 高阶函数
- Event delegation and bubbling.
- 事件捕获和事件冒泡
- Type Coercion using typeof, instanceof and Object.prototype.toString.
- 类型判断,typeof, instanceof and Object.prototype.toString.
- Handling asynchronous calls with callbacks, promises, await and async.
- 异步处理,promises, await and async.
- When to use function declarations and expressions.
- 什么时候使用函数声明和表达式
DOM
如何遍历和操作DOM非常重要。但是这对于非常依赖jQuery、angular和react这些框架的开发者来说非常困难。由于框架的使用,在日常工作中,我们很少会直接去进行DOM操作。但是在没有框架的时候,我们需要了解这些方面:
- Selecting or finding nodes using document.querySelector and in older browsers document.getElementsByTagName.
- 能用
document.querySelector
定位到具体的节点(还有老式浏览器中document.getElementsByTagName) - Traversal up and down – Node.parentNode, Node.firstChild, Node.lastChild and Node.childNodes.
- 上下遍历-Node.parentNode, Node.firstChild, Node.lastChild and Node.childNodes.这些节点代表的含义
- Traversal left and right – Node.previousSibling and Node.nextSibling.
- 左右遍历- Node.previousSibling and Node.nextSibling.
- Manipulation – add, remove, copy, and create nodes in the DOM tree. You should know operations such as how to change the text content of a node and toggle, remove or add a CSS classname.
- DOM操纵-DOM树的增删改查。必须要了解如何修改dom节点的文本内容以及怎么修改其CSS class
- Performance – touching the DOM can be expensive when you have many nodes, you should at least know about document fragments and node caching.
- 性能-在DOM节点很多的情况下操作DOM树可能带来性能问题。至少要了解document fragments和node caching
CSS
最基本的我们要知道页面如何布局,如何使用子选择器或者后代选择器来命中元素。以及什么时候应该使用class和id。
- Layout – sitting elements next to each other and how to place elements in two columns vs three columns.
- 布局-相邻元素布局和两列三列布局
- Responsive design – changing an element’s dimensions based on the browser width size.
- 响应式布局-如何根据浏览器的宽度修改元素的大小
- Adaptive design – changing an element’s dimensions based on specific break points.
- 自适应布局-根据不同屏幕像素改变元素的大小
- Specificity – how to calculate a selector’s specificity and how the cascade affects attributes.
- 权重-如何计算选择器的具体权重和继承所影响的属性。
- Appropriate namespacing and naming of classnames.
- 恰当的命名空间和class命名
HTML
对于实现的布局和相关的属性应该使用哪个HTML标签应该手到擒来。
- Semantic markup.
HTML标签的语义 - Tag attributes, such as disabled, async, defer and when to use data-.
标签属性,如:disabled, async, defer和何时使用 data- - Knowing how to declare your doctype (most people are not writing new pages every day and forget this) and what meta tags are available to use.
懂得不同doctype声明的使用场景(大部分人不会每天都写新的页面,因而容易遗忘这一点),以及该使用什么样的meta标签。 - Accessibility concerns, for example, making sure an input checkbox has a larger responding area (use label “for”). Also, role=”button”, role=”presentation”, etc.
良好的交互性,比如:保证input checkbox输入框有较大的输入区域(使用"for"属性),还有设置role=”button”或者role=”presentation”等。
系统设计
系统设计的面试通常是针对后端开发人员,尤其是涉及到MapReduce、设计分布式键对值存储或者CAP定理以及相关的知识点。尽管对于日常主要做前端开发的工程师来说可以不需要对系统设计等知识有非常深入的了解,但是工作中遇到设计前端应用框架也是很正常的。这些问题通常是比较宽泛的,类似于:“设计一个仿Pinterest的网站”或者“介绍一下如何实现一个购物结算的服务”。我列出了以下几个方面值得大家思考的:
- Rendering – client-side (CSR), server-side (SSR) and universal rendering.
- 渲染-客户端、服务端和全局渲染机制
- Layout – if you’re designing a system used by multiple development teams, you need to think about building components and if you require teams to follow a consist markup to use said components.
- 布局。如果你所设计的系统会被多个开发团队使用,你需要考虑可构建组件,如果你希望团队遵循包含的标记来使用组件,那可以考虑声明式组件。
- State management such as choosing between unidirectional data flow or two-way data binding. You should also think about if your design will follow a passive or reactive programming model, and how components related to each other for example Foo–> Bar or Foo –>Bar.
- 状态管理,如在单向数据绑定和双向数据绑定的状态管理。同时也要考虑设计是遵循被动模型还是响应式变成模型,以及组件之间是如何彼此关联的,例如Foo–> Bar or Foo –>Bar.
- Async flow – your components may need to communicate in real-time with the server. The design you propose should consider XHR vs bidirectional calls. If your interviewer asks you to support older browsers, your design will need to choose between hidden iFrames, script tags or XHR for messaging. If not, you could propose using websockets or you might decide server-sent events (SSE) are better.
- 异步数据流。你的组件可能会需要与服务端请求实时数据。在设计的过程中,需要考虑XHR和双工通信的对比。如果在面试中问到需要向下兼容浏览器,那么你所考虑的具体方案还需要靠考虑到隐藏式iFrames、script标签或者XHR等通信方式。如果不需要考虑兼容性,那么可以考虑使用websockets或者server-sent events (SSE)会更好。
- Separation of concerns – Model-View-Controller (MVC), Model-View-ViewModel (MVVM) and Model-View-Presenter (MVP) patterns.
- 分离模式设计。Model-View-Controller (MVC)、Model-View-ViewModel (MVVM) 和Model-View-Presenter (MVP) 模式的异同。
- Multi-device support – Will your design use the same implementation for the web, mobile web, and hybrid apps or will they be separate implementations? If you were building a site like Pinterest, you might consider three columns on the web but only one column on mobile devices. How would your design handle this?
- 多设备支持。你是否会遇到一套代码需要适配web、移动端web以及混合APP,或者说不同平台分别实现?。如果是创建一个适配PC和移动端的网站,需要考虑到web端的三列布局,但是移动端只有一列布局之间应该如何设计和实现。
- Asset delivery – In large applications, it’s not uncommon to have independent teams owning their own codebases. These different codebases probably have dependencies on each other and each usually has their own pipeline to release changes to production. Your design should consider how assets are built with dependencies (code splitting), tested (unit and integration tests) and deployed. You should also think about how you will vend assets through a CDN or inline them to reduce network latency.
- Asset资源调度。在大型应用当中,每个独立团队有自己的代码仓非常常见。这些不同的代码仓可能互相依赖,而且每个代码仓通常都有独立的流程来发布生产环境更新。在设计的时候需要考虑到assets资源文件与依赖如何打包、测试和发布。同时还要考虑到如何通过CDN来加载资源或者内置资源来减少网络请求。
前端方面的系统设计是一个非常大的课题,值得我们更多的关注。后续我会再写一篇博客来详细展开这方面的内容。
Web性能
除了常见的编程实践方案之外,面试官有可能会要求查看你的代码设计及其性能优化点。常见有比如吧css加载放在document上方,js文件放下document代码下方加载。现在web快速发展,因此需要我们对这方面都要有所了解。
- Critical rendering path.
- 关键渲染顺序
- Service workers.
- Service workers
- Image optimizations.
- 图片优化
- Lazy loading and bundle splitting.
- 懒加载和分包
- General implications of HTTP/2 and server-push.
- HTTP2和服务端推送的基本原理
- When to prefetch and preload resources.
- 资源预加载的发生时间
- Reduce browser reflows and when to promote an element to the GPU.
- 减少浏览器回流和以及GPU什么时候重构元素
- Differences between the browser layout, compositing and painting.
- 不同浏览器布局、组成和绘制
数据结构和算法
前端是否要掌握算法和数据结构具有一定的争议,但是对于时间复杂度的概念和常见的时间复杂度如O(n),O(nlogn)有一个基本认识对你来说百利而无一害。单页应用如今非常常见,了解如内存管理等只是对于应用开发非常有帮助。比如,如果你需要创建一个客户端输入检查的应用,了解基本的数据结构和算法会给你很大的帮助。
当然我并不是说你要具备CS学位,但是如今的前端发展迅速,再也不是像以前一样简单的写写页面了,因而需要我们有良好的计算机基础。在网上有许许多多的在线资源可以可以快速学习这些基础只是。
基本的网络知识
对于web网络的技术和规范要有一个基本了解。
- HTTP requests – GET and POST along with associated headers such as Cache-Control, ETag, Status Codes, and Transfer-Encoding.
- HTTP请求符。Get和POST以及其相关的请求头如 Cache-Control, ETag, Status Codes和Transfer-Encoding.
- REST vs RPC.
- REST与RPC
- Security – when to use JSONP, CORs, and iFrame policies.
网络安全,什么时候使用JSONP,CORs和iFrame
总结
成为一个前端工程师需要非常多的知识储备。不要被所需要的知识深度所限制,而是要积极去学习用户们使用的产品背后所有涉及到的各个部分的原理。
除了这篇文章所提到的技术要点,你还有可能需要展示自己的项目经历,介绍遇到的有挑战的场景以及对对不同方案所做的权衡。
当然这篇文章不可能涵盖前端面试的方方面面,我写的肯定有所遗漏。如果遗漏了重要的知识点,欢迎分享你的面试经验,跟我一起优化这篇文章的内容。
原文需墙:Preparing for a Front-End Web Development Interview at Top Tech Companies
作者:davidshariff