【译】每一个JavaScript 开发者应该了解的10个面试题

原文地址javascript

1. 你能说出两种对 JavaScript 应用开发者而言的编程范式吗?

JavaScript 是多范式语言,支持 命令式/程序式编程,以及 OOP(面向对象编程)和函数编程。JavaScript 经过原型继承支持 OOP。html

但愿听到:

  • 原型继承(还有:原型,OLOO)
  • 函数式编程(还有:闭包,第一等函数,lambadas(匿名函数))

红牌警告:java

  • 没有范式概念,没有提到原型对象或函数编程

了解更多:git

2. 什么是函数编程?

函数编程经过建立数学意义上的方法来避免共享状态和修改数据来生成程序。Lisp 是最先支持函数编程的,受到 lambda 的启发。Lisp 和 不少Lisp 家族语言至今仍然使用。程序员

函数式编程是 JavaScript 基本概念。一些常见的函数工具在 ES5 中被添加。github

但愿听到:

  • 纯函数
  • 无反作用
  • 单一功能构成
  • 函数式语言:Lisp,ML,Haskell,Erlang,Clojure,Elm,F Sharp,OCaml等等
  • 提到支持函数式编程的特性:一等函数,高阶函数,做为参数/值的函数

红牌警告:面试

  • 没有提到纯函数和避免反作用
  • 不能提供函数式编程语言的例子
  • 不能识别 JavaScript 中函数式编程的特色

了解更多:算法

3. 类继承和原型继承的不一样?

类继承:继承来自类(相似蓝图-类的一种描述),建立子类关系:等级分类法。经过构造函数的 new 关键字实例化。类继承可能在 ES6 中不容许使用 class 关键字。编程

原型继承:实例继承直接来自另外一个对象。实例是经过工厂方法或者 Object.create()实现。实例可能从多个不一样的对象中组成,容许容易地选择性继承。设计模式

在 JavaScript 中,原型继承比类继承更加简单和可扩展。

但愿听到

  • 类:建立紧密耦合或者层次结构分类
  • 原型:提到连接继承,原型委托,函数继承,对象组合

红牌警告:

4. 函数式编程和面向对象编程的优缺点?

OOP优势:容易理解对象的基本概念,容易理解方法调用的意义。OOP 倾向使用命令式风格而不是声明式风格,它读起来像是直接指示计算机去作什么。

OOP缺点:OOP 典型地依赖共享状态。对象和行为被一个实体跟踪,也就是说任何数量的无序命令用函数能够随机访问,会致使像竞争条件同样的不可描述的行为。

FP优势:函数式范式,程序员能够避免共享状态和反作用,也就消灭了同个资源的多个函数计算引发的bug。这种特性是 point-free风格的可用性。相较于 OOP,函数倾向于快速简单而容易的重组通用的可复用代码。

函数式编程更喜欢声明和声明风格,它不会一步步指示操做,而是结合要作的事,让潜在的方法关系如何去作。这为重构和性能优化留下巨大的空间,甚至容许你替换所有算法只须要一点点代码改变,这种更有效的方式(好比:内存管理,使用懒惰评估替换有限评估)

利用纯函数的计算也很容易在多个处理器或跨分布式计算集群中扩展,而没必要担忧线程资源冲突,竞争条件等...

FP缺点:过分使用FP功能(如无点样式和大型组合)可能会下降可读性,由于生成的代码一般更抽象地指定,更简洁,更具体。

与函数式编程相比,更多人熟悉OO和命令式编程,所以即便是函数式编程中常见的习惯也会让新团队成员感到困惑。

FP比OOP有更陡峭的学习曲线,由于OOP的普遍流行使得OOP的语言和学习材料变得更具会话性,而FP的语言每每更具学术性和正式性。 FP概念常常被写成使用来自lambda演算,代数和类别理论的习语和符号,全部这些都须要在这些领域中的先验知识基础被理解。

但愿听到

  • 提到共享状态的问题,竞争相同资源的不一样事物等等......
  • 意识到FP可以从根本上简化许多应用程序。
  • 意识到学习曲线的差别。
  • 阐明反作用以及它们如何影响程序的可维护性。
  • 意识到功能强大的代码库可能具备陡峭的学习曲线。
  • 意识到与同等的FP代码库相比,高度OOP代码库能够很是耐受变化而且很是脆弱。
  • 意识到不可变性致使了一个极易访问和可延展的程序状态历史记录,容许轻松添加诸如无限撤消/重作,倒带/重放,时间旅行调试等功能。 能够在任一范例中实现不变性,但共享有状态对象的扩散使OOP中的实现变得复杂。

红牌警告:没法列出一种风格或另外一种风格的缺点-有经验的人对任何风格都能说出一些限制。

了解更多

5. 何时类继承是一个合适的选择?

答案永远不会,或者几乎从不。 固然永远不会超过一个级别。 多级类层次结构是反模式。 多年来我一直在发出这个挑战,我听过的惟一答案属于几种常见的错误观念之一。 更常见的是,挑战是沉默。

“若是某个功能有时颇有用 有时很危险 若是有更好的选择 而后老是使用更好的选择。“ -- Douglas Crockford

但愿听到

  • 不多,几乎历来没有,或从未。
  • 从一个框架基类,如React.Component,单个级别有时是能够的。
  • “同意对象组合而不是类继承。”

了解更多

6. 何时原型继承是一个合适的选择?

原型继承有多种类型:

  • 受权(即原型链)。
  • 链接(即mixins,Object.assign())。
  • 功能性(不要与函数式编程混淆。用于为私有状态/封装建立闭包的函数)。

每种类型的原型继承都有本身的一组用例,但它们在启用组合方面一样有用,它建立了有一个或用一个或能够作一个的关系而不是使用类继承建立是一个的关系。

但愿听到

  • 在模块或函数编程没有提供明显解决方案的状况下。
  • 当须要从多个来源组合对象时。
  • 任什么时候候你须要继承。

红牌警告:

  • 不知道什么时候使用原型。
  • 没有意识到mixins或Object.assign()

了解更多

7.“同意对象组合超过类继承”是什么意思?

这是“设计模式:可重用的面向对象软件的元素”的引用。 这意味着代码重用应该经过将较小的功能单元组装到新对象中而不是从类继承并建立对象分类来实现。

换句话说,使用can-do,has-a或 uses-a 关系而不是is-a关系。

但愿听到:

  • 避免使用类层次结构。
  • 避免脆弱的基类问题。
  • 避免紧耦合。
  • 避免严格的分类(强制是一种新用例最终错误的关系)。
  • 避免大猩猩香蕉问题(“你想要的是香蕉,你获得的是拿着香蕉的大猩猩,以及整个丛林”)。
  • 使代码更灵活。

红牌警告:

  • 没有提到上述任何问题。
  • 未能阐明构成和阶级继承之间的差别,或组成的优点。

8.什么是双向数据绑定和单向数据流,它们有何不一样?

双向数据绑定意味着 UI 表单被绑定,用来动态地建模数据,使得当 UI 表单改变时,模型数据随之改变,反之亦然。

单向数据流意味着模型是单一的事实来源。 UI中的更改触发消息,指示用户对模型的意图(或React中的“存储”)。 只有模型才有权更改应用程序的状态。 结果是数据老是在单一方向上流动,这使得它更容易理解。

单向数据流是肯定性的,而双向绑定可能致使更难以遵循和理解的反作用。

但愿听到:

  • React是单向数据流的新规范示例,所以说起React是一个很好的信号。 Cycle.js是单向数据流的另外一种流行实现。
  • Angular是一种使用双向绑定的流行框架。

红牌警告:

  • 不了解任何一个意味着什么。 没法阐明差别。

9.单一与微服务架构的优缺点是什么?

单一体系结构意味着您的应用程序是做为一个有凝聚力的代码单元编写的,其组件旨在协同工做,共享相同的内存空间和资源。

微服务架构意味着您的应用程序由许多较小的独立应用程序组成,这些应用程序可以在本身的内存空间中运行,而且可能在许多不一样的机器上相互独立地进行扩展。

单一优势:单一架构的主要优点在于大多数应用程序一般都有大量的交叉问题,例如日志记录,速率限制以及审计跟踪和DOS保护等安全功能。

当一切都在同一个应用程序中运行时,很容易将组件与这些跨领域的问题联系起来。

还有性能优点,由于共享内存访问比进程间通讯(IPC)更快。

单一架构缺点:随着应用程序的发展,单一应用程序服务每每会紧密耦合并纠缠在一块儿,所以很难将服务隔离,例如独立扩展或代码可维护性。

单一体系结构也很难理解,由于当您查看特定服务或控制器时,可能存在依赖性,反作用和魔法,这些并不明显。

微服务优势:微服务架构一般组织得更好,由于每一个微服务都有很是特定的工做,而且不关心其余组件的工做。解耦服务也更容易重构和从新配置,以知足不一样应用程序的需求(例如,同时提供Web客户端和公共API)。

它们还能够具备性能优点,具体取决于它们的组织方式,由于它能够隔离热服务并将其扩展为独立于应用程序的其他部分。

微服务缺点:当您构建新的微服务架构时,您可能会发现许多在设计时没有预料到的跨领域问题。一个单一的应用程序能够创建共享的魔术助手或中间件来处理这些跨领域的问题,而不须要太多的努力。

在微服务架构中,您须要为每一个交叉问题产生单独模块的开销,或者将交叉问题封装在全部流量路由经过的另外一个服务层中。

最终,即便是单一的体系结构也倾向于经过外部服务层来传输流量以解决交叉问题,可是采用单一体系结构,能够延迟这项工做的成本,直到项目更加成熟为止。

微服务常常部署在他们本身的虚拟机或容器上,致使VM争用工做激增。这些任务常常经过容器队列管理工具自动完成。

但愿听到:

  • 尽管初始成本高于monolthic应用程序,但对微服务的积极态度。意识到微服务从长远来看每每会表现更好而且规模更大。
  • 关于微服务与单片应用程序的实用性。构建应用程序,以便服务在代码级别彼此独立,但在开始时很容易捆绑在一块儿做为单个应用程序。微服务开销成本可能会延迟,直到付出代价变得更加实际。

红牌警告:

  • 不了解单片和微服务架构之间的差别。
  • 对微服务的额外开销没有意识到或不切实际。
  • 不知道IPC和网络通讯对微服务形成的额外性能开销。
  • 对微服务的缺点太负面了。没法明确解决单一应用程序的分离方式,以便在时机成熟时将它们轻松拆分为微服务。
  • 低估了独立可扩展微服务的优点。

10.什么是异步编程,为何它在JavaScript中很重要?

同步编程意味着,除了条件和函数调用以外,代码从上到下依次执行,阻止长时间运行的任务,如网络请求和磁盘I / O.

异步编程意味着引擎在事件循环中运行。当须要阻塞操做时,将启动请求,代码将继续运行而不会阻塞结果。当响应准备就绪时,将触发中断,从而致使运行事件处理程序,控制流继续执行。经过这种方式,单个程序线程能够处理许多并发操做。

用户界面本质上是异步的,而且花费大部分时间等待用户输入来中断事件循环并触发事件处理程序。

默认状况下,节点是异步的,这意味着服务器的工做方式大体相同,在循环中等待网络请求,并在处理第一个请求时接受更多的传入请求。

这在JavaScript中很重要,由于它很是适合用户界面代码,而且很是有利于服务器上的性能。

但愿听到:

  • 了解阻塞意味着什么,以及性能影响。
  • 了解事件处理,以及为何它对UI代码很重要。

红牌警告:

  • 不熟悉异步或同步的术语。
  • 没法表达性能影响或异步代码与UI代码之间的关系。

结论

坚持高级主题。若是他们可以回答这些问题,那一般意味着他们有足够的编程经验能够在几周内得到语言怪癖和语法,即便他们没有不少JavaScript经验。

不要基于易于学习的东西(包括经典的CS-101算法或任何类型的拼图问题)取消候选人资格。

你真正须要知道的是,“这位候选人是否理解如何将应用程序放在一块儿?”

这就是口语采访。

在真实的采访中,我更增强调编码挑战和观察候选人代码。这些主题在个人“掌握JavaScript面试”系列中有详细介绍。

pic
相关文章
相关标签/搜索