当前位置: 首页 > 科技观察

每个JavaScript工程师都要知道的10个面试题

时间:2023-03-20 10:52:18 科技观察

每个JavaScript工程师都应该知道的10个面试问题技术实力。如果你碰巧是候选人,你迟早也会接受面试。不管你是哪一方的,都让大哥教你几招。以人为本在《如何打造高速开发团队》一文中,我提出了一些观点。我觉得这些观点很重要,所以我在这里重申一下:优秀的团队是公司业绩的关键。一个企业要想在逆境中生存并有所成就,最重要的是首先要培养一支优秀的团队。正如MarcusLemonis所说,最重要的有三点(3P):人员、流程和产品。创业初期,你招的工程师一定是能自立的优秀队友。理想情况下,他可以帮助招聘工程师,指导其他工程师,帮助初级和中级工程师解决各种问题。这么优秀的队友,不管什么时候越多越好。要了解面试候选人时的常见注意事项,您可以阅读文章为什么在技术领域招聘如此困难。评估候选人真实水平的最好方法是结对编程。将编程与候选人结对,一切都取决于候选人。多观察,多倾听,看看应聘者是一个什么样的人。利用微博的API抓取消息并展示在时间线上,对于应聘者来说是一个很好的面试项目。然而,无论结对编程有多好,它都不能让你完全理解一个候选人。这时候面试也能帮上大忙——但不要浪费时间问一些语法(syntax)或者语言细节(languagequirks)——问一些进阶的问题,大哥。问项目架构(architecture)、编程范式(paradigms),这个层面的判断(thebigdesicions)能极大地影响一个项目的成败。有很多关于语法和语言特征(features)的小知识,大家谷歌大量搜索就可以搞定。工程师在工作中积累的软件工程经验,以及个人常用的编程范式和代码风格(惯用语),都是在Google上很难找到的宝贵财富。JavaScript的独特之处在于它在各种大型项目中都扮演着至关重要的角色。那么是什么让JavaScript如此特别呢?以下问题可能会帮助您找出答案。1.你能说出两种对JavaScript工程师很重要的编程范式吗?JavaScript是一种多范式编程语言,同时支持命令式/过程式编程、面向对象编程(OOP,Object-OrientedProgramming)和函数式编程(functionalprogramming)。JavaScript支持的面向对象编程包括原型继承。面试加分项Prototypalinheritance(即:原型,OLOO——对象链接到其他对象);函数式编程(即:闭包(closure)、头等函数(firstclassfunctions)、lambda函数:箭头函数)。面试减分连范式都不知道,更不知道什么是原型OO(prototypaloo)或函数式编程。进一步了解JavaScript的两大支柱第1部分:JS的两大支柱之一:原型设计OOJavaScript的两大支柱第2部分:JS的两大支柱中的第二个:函数式编程2.什么是函数式编程?函数式编程是一种结合数学函数并避免共享状态和可变数据的编程语言。Lisp发明于1958年,是最早支持函数式编程的语言之一,而lambda演算可以说催生了这门语言。即使在今天,Lisp编程语言家族也有着广泛的应用。函数式编程是JavaScript语言中一个非常重要的概念(它是JavaScript的两大支柱之一)。ES5规范中添加了许多常用的功能工具。Interviewbonuspurefunctions/functionpurity了解如何避免副作用简单函数的组合函数式编程语言:Lisp、ML、Haskell、Erlang、Clojure、Elm、F#、OCaml等提到了支持函数式编程(FP)的特性在JavaScript语言中:一类函数,高阶函数,函数作为参数(arguments)/值(values)。提到纯函数以及如何避免副作用没有提供函数式编程语言的例子没有说JavaScript中的哪些特性使函数式编程成为可能详细了解JavaScript的两大支柱第2部分:函数式编程不变性之道组合软件Haskell音乐学院3.类继承和原型继承有什么区别?ClassInheritance:实例继承于类(类与实例的关系可以类比建筑图纸与实际建筑物的关系🏠),同时创建父类-子类这种关系也称为层次关系类分类法。实例通常是通过使用new关键字调用类的构造函数来创建的。但是在ES6中,你可以在不使用class关键字的情况下继承一个类。原型继承(PrototypalInheritance):实例/对象直接继承自其他对象。要创建实例,通常使用工厂函数或Object.create()方法。实例可以由多个不同的对象组成,允许选择性继承。在JavaScript中,原型继承比类继承更简单、更灵活。面试奖励课程:创建紧密耦合或层次结构/分类法。原型:提到连接继承、原型委托、函数继承和对象组合。面试扣项原型继承和组合,和类继承相比,不知道哪个更好。LearnmoreaboutTheTwoPillarsofJavaScriptPart1:JS的两大支柱之一:PrototypeOOCommonMisconceptionsAboutInheritanceinJavaScript:CommonmisconceptionsAboutInheritanceinJavaScript:CommonmisconceptionsaboutInheritanceinJavaScript4.Functionalprogrammingandobject-orientedprogramming,eachare优点和缺点?面向对象编程的优点:更容易理解一些关于“对象”的基本概念,方法调用的含义也容易解释。面向对象编程通常使用命令式编码风格,较少使用声明式风格。这样的代码读起来就像一组简单的指令,计算机可以轻松遵循。面向对象编程的缺点:面向对象编程通常需要共享状态。对象和它们的行为往往依附于同一个实体,所以如果一堆函数访问这个实体,而这些函数的执行顺序是不确定的,就很可能会出错,比如竞争条件(raceconditions))这种现象(函数A依赖于实体的某个属性,但是在A访问该属性之前,该属性已经被函数B修改,那么函数A在使用该属性时可能得不到预期的结果)。函数式编程的优点:在函数式范式中编程时,您无需担心共享状态或副作用。这避免了多个函数调用同一批资源时可能出现的错误。有了“point-freestyle”(也叫隐式编程)等特性,函数式编程就大大简化了,我们也可以用函数式编程把代码组合成可复用性更强的代码,这是面向对象编程做不到的。函数式编程更喜欢声明式和符号式(指称风格)编码风格。这样的代码不是为了达到某个目的而需要一步步执行的一堆指令,而是着眼于宏观层面要做什么。至于怎么做,就藏在函数里面了。这样一来,要想重构代码,优化性能,就大有可为了。(译者注:以做一道菜为例,分为三个步骤:买菜->洗菜->做菜,每一步都是函数式编程的一个函数,无论是什么菜,这个过程都不??会改变。而要优化这个流程,自然是要深入到每一个步骤,这样无论内部怎么重构优化,整体流程都不会改变,这就是函数式编程的好处。)你甚至可以把一个算法可以被另一种更高效的算法替代,同时,基本不需要修改代码(比如用惰性求值策略(lazyevaluation)替代早期求值策略(eagerevaluation))。使用纯函数的计算可以轻松扩展到多处理器环境或应用于分布式计算集群,而无需担心线程资源冲突和竞争条件。函数式编程的不足:如果代码过多的使用了函数式编程的特性(比如无参风格,大量方法的组合),会影响其可读性,导致简洁有余,可读性不够。大多数工程师还是比较熟悉面向对象编程和命令式编程。对于刚接触函数式编程的人来说,即使是这个领域的一些简单术语也可能让他怀疑人生。函数式编程的学习曲线比较陡峭,因为面向对象编程太流行了,学习资料太多了。相比之下,函数式编程在学术领域的应用更为广泛,在工业界的应用则略显不足,自然没有那么“平易近人”。人们在讨论函数式编程时,经常会使用lambda演算、代数、范畴科学等学科的专业术语和符号来描述相关概念。把知识都懂了,能不让人头晕吗?共享状态、资源竞争等缺点(面向对象编程)函数式编程可以大大简化应用程序开发面向对象编程和函数式编程学习曲线两种编程方式各自的缺点,以及后期代码维护的影响。函数式代码库具有陡峭的学习曲线。面向对象编程风格的代码库难以修改且容易出现问题(与可比的函数式代码相比)不变性(immutability),可以大大提高程序状态历史(programstatehistory),这样你想添加无限undo/redo,rewind/playback等功能,加上向后调试等功能就简单多了。无论是面向对象编程还是函数式编程,两种范式都可以实现不变性,但是如果用面向对象来实现,共享状态对象的数量会急剧增加,代码也会变得复杂很多。面试减分并没有谈到这两种编程范式的缺点——如果你至少熟悉其中一种,你应该能说出很多这种范式的缺点。总是你们两个要深入了解你们,看来你们两个真的很重要。JavaScript的两大支柱第1部分:JS的两大支柱之一:PrototypeOOJavaScript的两大支柱第2部分:JS的两大支柱中的第二个:函数式编程5.什么时候应该使用类继承?永远不要使用类继承!或者尽量不要使用它。如果一定要用,就用它来继承一级(一层)。多级类继承只是一种反模式。这个主题(不太确定它是关于什么的......)我已经参与了多年的讨论,并且可用的少数答案最终成为常见的误解之一。更多的时候,这个话题讨论讨论,没有动静。如果一个特性有时有用但有时危险并且有另一个更好的特性可以使用,那么一定要使用另一个更好的特性~DouglasCrockford面试加分点尽量不要使用,甚至完全没有类继承。有时候只继承一层就可以了,比如继承框架的基类,比如React.Component。对象组合优于类继承。深入了解JavaScript的两大支柱第1部分:JS的两大支柱之一:PrototypeOOJSObjects—InheritedaMess:JSobject(inheritance):justinheritedmess(mess)6.什么时候应该使用原型继承?原型继承可以分为以下几类:delegation(也就是原型链)combination(concatenative,比如mixins,Object.assign())functional(函数式,这种函数式原型继承不是函数式编程。这里的函数是用于创建闭包实现私有状态(privatestate)或封装(encapsulation))以上三种原型继承各有适用场景,但都是有用的,因为它们可以实现组合继承(composition),即建立一个A拥有特征B(has-a)、A使用特征B(uses-a)或A可以实现特征B(can-do)的关系。相比之下,类继承建立了A是B的关系。面试加分知道什么时候模块或函数式编程不合适。当您需要组合来自许多不同来源的对象时,知道该怎么做。知道何时使用继承。面试减分不确定什么时候使用原型。不知道mixins和Object.assign()。DeepDiveintoProgrammingJavaScriptApplications:文章的“原型”部分7.为什么说“对象组合优于类继承”?这句话参考了《设计花纹》(DesignPatterns,设计模式)一书的内容。意思就是如果要实现代码重用,应该把一堆小的功能单元组合成各种满足自己需要的对象,而不是通过类继承一层层创建对象。换句话说,尝试通过编程来实现can-do、has-a或uses-a的关系,而不是is-a的关系。面试奖金避免使用类继承。避免使用有问题的基类。避免紧耦合。避免极其僵化的分类法(类继承创建的is-a关系会导致许多误用案例)香蕉和整个丛林”)。使代码更具可扩展性。面试扣分项目以上问题均未提及。对象组合和类继承的区别没有表述清楚,也没有提到对象组合的优点。深入理解组合优于继承引入Stamp规范8。Two-waydatabinding/one-waydataflow的含义和区别双向数据绑定(two-waydatabinding)是指UI层呈现的内容和Model层的数据动态绑定在一起,如果其中一个发生变化,它会立即反映在另一个上。例如,用户在前端页面的表单控件中输入一个值,该控件对应的Model层中的变量会立即更新为用户输入的值;反之亦然,如果Modal层的数据发生变化,变化的数据也会立即反映到UI层。单向数据流意味着只有模型层是唯一的真实来源。UI层的变化会触发相应的消息机制,将用户的目的告知Model层(对应React的store)。只有模型层才有权限改变应用程序的状态。这样一来,数据总是单向流动的,也更容易理解应用程序的状态是如何变化的。对于使用单向数据流的应用程序来说,跟踪状态变化很容易,但是对于使用双向数据绑定的应用程序来说,很难跟踪和理解状态变化。面试加分项React是典型的单向数据流,如果在面试中提到这个框架,就会加分。Cycle.js是另一个流行的单向数据流库。Angular是双向数据绑定的一个例子。面试扣项不懂单向数据流/双向数据绑定的含义,也分不清两者的区别。详细了解React.js9简介。单体架构和微服务架构的优缺点是什么?对于使用单体架构的应用程序,各个组件的代码作为一个整体存在,组件之间相互协作,共享内存和资源。微服务架构(microservicearchitecture)是由许多相互独立的小应用程序组成的。每个应用程序都有自己的内存空间,应用程序的扩展也独立于其他应用程序。单体架构的优点:大多数应用程序都有相当多的横切关注点,例如日志记录、流量限制以及审计跟踪和DOS保护等安全需求。单体架构在这方面有优势。当所有功能都运行在一个应用程序中时,将组件与横切关注点相关联是非常方便的。单体架构还具有性能优势。毕竟,访问共享内存比进程间通信(IPC)更快。单体架构的缺点:随着单体架构应用功能的不断发展,各个服务之间的耦合度会不断增加,以至于各个服务之间很难分离。独立扩展或者代码维护就更不方便了。微服务的优点:微服务架构一般都有更好的组织结构,因为每个服务都有自己特定的分工,不会干扰其他组件负责的部分。服务解耦后,更方便重新组合配置,为不同的应用提供服务(比如同时为Web客户端和公共API提供服务)。微服务如果以合理的架构部署,在性能上也是非常有优势的,因为这样可以很方便的将热点服务进行分离和扩展,而不会影响到应用中的其他应用。部分。微服务的缺点:在实际构建新的微服务架构时,会遇到很多在设计阶段没有预料到的横切关注点。如果是单体架构的应用,很简单,新建一个中间件(sharedmagichelpers不知道怎么翻译。。。)就可以解决这类问题,不麻烦。但是在微服务架构中就不一样了。要解决这个问题,要么为每个横切关注点引入一个独立的模块,要么将所有横切关注点的解决方案封装到一个服务层中,这样所有的流量都可以从这里经过。为了解决横切关注点的问题,虽然单体架构也倾向于将所有的路由流量都通过一个外部服务层来传递,但是在这种架构下,你可以等到项目非常成熟后再进行这种改造,这样你可以尽量推迟偿还这笔技术债。微服务一般部署在虚拟机或容器上。随着应用规模的不断增大,虚拟机争用工作(VMwranglingwork)的情况也会迅速增加。任务分配通常通过集装箱车队管理工具自动完成。面试加分项对微服务持积极态度,虽然初始成本会高于单一架构。知道微服务从长远来看性能和扩展性更好。有微服务架构和单体架构应用的实战经验。它可以在代码层面使应用中的各种服务相互独立,但在开发初期可以快速将各种服务打包成一个完整的单一架构应用。待应用相当成熟,且改造成本在可接受范围内后,即可进行微服务改造。面试减分不知道单体架构和微服务架构的区别。不知道微服务架构的额外开销,或者没有实践经验。不知道微服务架构中IPC和网络通信带来的额外性能开销。对微服务的低估太多了。目前尚不清楚何时应将单体架构应用程序解耦为微服务。低估了可独立扩展的微服务的好处。10.什么是异步编程?为什么它在JavaScript中如此重要?在同步编程中,代码会从上到下依次执行(条件语句和函数调用除外)。如果遇到网络请求或磁盘读写(I/O)等耗时任务,就会阻塞在这样的地方。在异步编程中,JS运行在一个事件循环中。当需要执行阻塞操作(blockingoperation)时,主线程发起(异步)请求,(工作线程会执行这个异步操作,)主线程继续执行下面的代码。(工作线程执行完后,)会发起响应,触发中断(interrupt),执行事件处理器(eventhandler)。执行完毕,主线程继续往回走。这样一个程序线程就可以处理大量的并发操作。用户界面(UI)本质上是异步的,大部分时间它等待用户输入,这会中断事件循环并触发事件处理程序。Node.js默认是异步的,用它构建的服务端和用户界面的执行机制是类似的,在事件循环中等待网络请求,然后对这些请求进行一一处理。异步在JavaScript中非常重要,因为它适合编写UI,并且在服务器端有很好的性能。面试加分项了解阻塞的含义和对性能的影响。了解事件处理程序以及为什么它对代码的UI部分很重要。面试扣项不熟悉同步和异步的概念。目前还不清楚异步代码和UI代码对性能的影响,也不清楚它们之间的关系。综上所述,多向应聘者询问高阶知识点。如果你能把这些概念解释清楚,就意味着即使申请者接触的JavaScript不多,也能在短短几周内理解语言细节和语法。弄清楚。不要因为考生在一些简单的知识上表现不好,比如经典的CS-101算法课,或者一些解谜题,就让考生通过。面试官真正应该关注的是候选人是否知道如何将一堆功能组织在一起以形成一个完整的应用程序。这就是电话面试的全部内容。线下面试我更看重应聘者实际写代码的能力。我将观察他如何编写代码。在我的《精通 JavaScript 面试》系列文章中,会有更深入的描述。