前端开发面试经验

面试其实考的就是一个归纳总结的能力,对于平时coding时理解的东西的一个归纳,比如下面,很多东西都是明白,但当面试时被问到,却是和已掌握的知识对不上。

  • web标准

    • HTML、CSS、JS三者分离
    • 结构、表现、行为三者分离
  • 可访问性、可用性

    • 各平台兼容性
    • 所用用户一视同仁,包括残障
    • 语义化 标签如下
      • title、hn、header、nav、main、article、section、aside、footer、small、strong、em、mark、figure、figcaption、cite、blockquote、time、abbr、dfn、address、del、ins、code、pre、progress
  • web 安全

    • XSS

      • 攻击: 用户注入 script 标签并执行脚本发送ajax获取cookie或其他

      • 应对: 对于用户输入 转译后再输出

      • 攻击升级 先利用unicode隐藏<>然后jquery.append 会在将append元素变为fragment的时候,找到其中的script标签,再使用eval执行一遍。jquery的append使用的方式也是innerHTML。而innerHTML是会将unicode码转换为字符实体的,触发用户脚本。

      • 图片 src 触发脚本

          src = '\" onerror=\"javascript:脚本;\"'
          // 实际上复制给img标签 触发onerror事件
          
      
      • 应对:转译url...

      • 攻击再升级: innerHTML时 插入unicode隐藏后的 img标签、插入后执行脚本

      • 应对:对于输入\进行json转译 \ 不会当作unicode处理

      • 攻击在升级 get请求中url参数加脚本 让客户端执行

      • 应对:使用url中的参数前先转译、更不要去eval

      • 保护cookie中的敏感信息在cookie中使用HttpOnly让js无法读写。

      • xss的升级攻击方式,同学们有兴趣的话,可以自己去研究一下

      https://blog.csdn.net/fengyinchao/article/details/52303118

    • CSFR Cross-site request forgery跨站请求伪造)

      • 解释:被黑客利用,你在访问黑客的网站的时候,进行的操作,会被操作到其他网站上(如:你所使用的网络银行的网站)

      • 攻击:黑客在其网站图片src上 加上你的业务的API 简单get提交请求,用户在浏览黑客的网站一次就相当与请求一次你的API

      • 应对:日常业务严格按照post去做 更不要使用jsonp

      • 攻击:黑客在其网站上以按钮伪装form提交发送post请求仿造你的关键业务逻辑

      • 应对:

        1. session里加验证码 (经常加眼正常影响用户体验)

        2. 验证token 整个页面的一次session 使用一个token, 所有用户提交都要带上本次页面中生成的token

    • 网络劫持攻击

      • 解释:我们的网站不是直接访问到我们的服务器上,经过一些中间层、比如wifi

      • 攻击:在这些中间层中获取用户数据

      • 应对:使用https加密 或者进行非对称加密 客户端加密 服务端解密

    • 控制台注入代码

      • 攻击:用户无知 手动执行黑客脚本

      • 应对:在控制台给予用户警示

    • 钓鱼

      • 攻击:替换网站域名 要求用户输入信息

      • 应对:古老的攻击,网民提高素质吧

  • 同源策略限制

    • CookieLocalStorageIndexDB 无法获取

    • DOM 和 JS对象无法获得

    • ajax 请求不能发送

  • 跨域

    • JSONP 原理:利用script标签跨域加载js文件 指定执行函数名把json以参数传回并执行指定方法 只能实现get请求 安全性存在问题

    • document.domain + iframe 跨域 仅限于主域相同子域不同的情况下 同时设定 document.domain = 'domain.com' 自窗口通过 window.parent 获取父窗口的window

    • location.hash + iframe A域iframe指向B域 A域通过改变iframe hash,B域监听 window.hashchange 接收传参

    • window.name + iframe 跨域 iframe 触发两次 onload 第一次onload时改变iframe.contentWindow.location 同时留存数据于window.name中 为同域页面 第二次 onload时读取iframe.contentWindow.name中数据

    • HTML5 (window.oepnwindows.frames的属性成员调用)postMessage A域JS发送消息到B域 B域监听message方法接收

    • CORS Cross-Origin Resource Sharing 服务端设置 Access-Control-Allow-Origin
      跨域 传cookie 前端在xhr设置是否读写cookie xhr.withCredentials = true 服务端 Access-Conrol-Allow-Credentials = true

    • Nginx 跨域 解决iconfont字体文件跨域 location / { add_header Access-Control-Allow-Origin *; } 接口跨域 Cookie读写

    #proxy服务器
    server {
        listen       81;
        server_name  www.domain1.com; # 有请求发起同域
    
        location / {
            proxy_pass   http://www.domain2.com:8080;  #反向代理
            proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
            index  index.html index.htm;
     
            # 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
            add_header Access-Control-Allow-Origin http://www.domain1.com;  #当前端只跨域不带cookie时,可为*
            add_header Access-Control-Allow-Credentials true;
        }
        
    }
    
    • Nodejs 中间件跨域

      • 同nginx
      • webpack-dev-server
      // webpack.config.js 部分配置 开发环境跨域问题
      module.exports = {
          entry: {},
          module: {},
          ...
          devServer: {
              historyApiFallback: true,
              proxy: [{
                  context: '/login',
                  target: 'http://www.domain2.com:8080',  // 代理跨域目标接口
                  changeOrigin: true,
                  cookieDomainRewrite: 'www.domain1.com'  // 可以为false,表示不修改
              }],
              noInfo: true
          }
      }
      
    • webSocket协议跨域

from http://web.jobbole.com/92405/

  • cookie

    • withCredentials:true Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为* 。Access-Control-Allow-Credentials true;

    • 浏览器可禁用cookie

    • session 服务端开辟一块空间储存数据 并生成 sessionID可指向这块空间,sessionIDcookie传到前端,储存在cookie里,前端发送ajax请求时携带此ID验证信息

  • webpack (loader plugin)

    • loader (对于模块的源代码进行转换,在 import 或加载时间预处理文件类似于其他构建工具中的“task”, 作用:1. 转换的作用,开发者所用到的都转换成网页加载必备的html+css+js+img等要求格式的文件。转换的对象是源代码,loader只对源代码转行,至于其他的功能,plugins就来接手它做不到的地方)

      • css-loader 解析css文件后,使用import加载,并且返回css代码

      • style-loader 把模块的导出作为样式添加到DOM中

      • sass-loader 加载和转译scss

      • less-loader 加载和转译less

      • postcss-loader css再处理

      • babel-loader 加载ES6+代码,使用babel转译为ES5

      • url-loader 处理图片类文件,但如果小与文件限制,跨域返回dataURL

      • file-loader 处理fonts/svg等,将文件发送到输出文件夹,并返回(相对)URL

      • vue-loader 加载和转译Vue组件

    • plugin (不同于 loader一次处理一个文件,plugin直接对整个构建过程起作用)常用plugins如下

      • HtmlWebpackPlugin 依据一个简单模版,帮助生成最终的html5文件,这个文件中自动引用打包后对js文件,每次编译都在文件名中插入一个不同的hash值, 可配置多个实例

      • CleanWebpackPlugin 清理打包路径文件

      • HotModuleReplacement 热替换

      • ProvidePlugin 全局加载额外的库文件

      • CommonsChunkPlugin 拆分第三方库 提取公共文件

      • ExtractTextWebpackPlugin 该插件跨域在打包时将css独立出来

      • UglifyJsPlugin 压缩混淆js

      • CopyWebpackPlugin 拷贝静态资源到编译目录

      • DefinePlugin 相当于定义全局变量 (webpack4 提供mode)

      • ChunkManifestPlugin 生成manifest文件

      • HashedModulesPlugin 生成的文件里的modules路径是hash值 缩小文件

      • LodashModuleReplacementPlugin Lodash库

  • babel (Babel是一个JavaScript编译器)

    简介babel 6+
    • 拆分成几个核心包,babel-core, babel-node, babel-cli

    • 没有默认的转换,需手动添加plugin即插件化

    • 增加了preset, 也就是预置条件

    • 增加.babelrc文件,方便自定义的配置

    编译过程
    1. parse: 通过babel/parser解析成AST。

    2. transforms[s]: All the plugins/presents, 进一步的做语法的自定义转译,仍然是AST

    3. generator: 最后通过 babel-generator生成output string。

    • babel-core:可以看作babel的编译器,babel的核心api都在这里面,比如transform,它会把我们的js代码,抽象成ast(abstract sytax tree)。我们可以理解为,它定义的一种分析js语法的树结构。也就是说es6的新语法,跟老语法是不一样的,那么必须先转成ast,去发现这个语法的kind,分别做相应的处理,才能转换成es5

    • babel-cli 提供命令行运行babel 也就是可以 babel filename去对文件转码

    • babel-external-helpersbabel-cli中的一个command,用来生成一段代码,包含babel所有的helper函数。babel有很多帮助函数,例如toArray函数,jsx转换函数,这些函数是babel transform的时候用,都放在babel-helpers这个包中。如果babel编译的时候检测到某件需要这些helpers,在编译成模块的时候,会放到模块顶部。

    • babel-node node filenam 换成 babel-node filename 可在命令行里编译后再执行

    • babel-register 它是一个编译器,require('babel-register')require(filename) 并通过node执行。其原理是通过改写node本身的require,添加工资,然后在require其他模块时,触发babel编译,其特点是实时编译,不需要输出文件,执行的时候再去编译。所以很适合用于开发。

    • babel-runtime 这个包很简单,就是引用了core-js和regenerator,然后生产环境把它们编译到dist目录下,做了映射,供使用。core-js是用于JavaScript的组合标准化库,它包含es5(object.freeze),es6的(Promise,Symbols, collections, iteraaztors, typed arrays), es7+提案等等的polyfills实现,即它几乎包含了所有的JavaScript最新标准的垫片。
      regenerator是来自于facebook的一个库,主要就是实现了 generator/yeild,async/await

    • babel-polyfill, babel-runtime已经是一堆polyfill了,为什么这里还有一个类似的包,它同样是引用了core-js 和 regenerator,垫片支持是一样的,babel-polyfill是为了模拟一个完整的es2015+环境,意在用于应用程序而不是库/工具。并且使用babel-node时,这个polifill会自动加载,也就是说,它会让我们的执行环境,模拟完美支持 es6+ 的环境,毕竟无论是浏览器环境还是 node 环境对 es6+ 的支持都不一样。它是以重载全局变量 (E.g: Promise), 还有原型和类上的静态方法 (e.g: Array.prototype.reduce/Array.from),从而达到对 es6+ 的支持。不同于 babel-runtime 的是, babel-polyfill是一次性引入到你的项目中,就像React包一样,同项目代码一起编译到生产环境。

    plugins
    • babel-plugin-transform-runtime, transform-runtime是为了方便使用babel-runtime的,它会分析我们的ast中,是否有引用babel-runtime中的垫片(通过映射关系),如果有,就会在当前模块顶部插入我们需要的垫片。有几个参数helpers,polyfill, regenerator, moduleName ,根据具体需要配置。
    transform-runtime 对比 babel-polyfill

    (babel-runtime和babel-plugin-transform-runtime统称为transform-runtime)另外,关于babel-runtime为什么是dependencies依赖。它只是一个几种了polyfill的library,对应需要的 polyfill 都是要引入项目中, 并跟项目代码一起打包的。不过他都不会引入,你用了哪个,plugin 就给你 require 哪个。所以即是你最终项目只是require('babel-runtime/core-js/object/values')其中的一个文件,但对于这包来说,也是生产依赖的。

    • babel-polyfill是当前环境注入这些 es6+ 标准的垫片,好处是引用一次,不再担心兼容,而且它就是全局下的包, 代码的任何地方都可以使用,缺点也很明显,它可能会污染原生的一些方法而把原生的方法重写。如果当前项目已经有一个polyfill的包了,那你只能保留其一。而且一次性引入这么一个包,会大大增加提及。如果你只用几个特性,就没必要了,如果你是开发较大的应用,而且会频繁的使用新特性并考虑兼容,那就直接引入把。

    • transform-runtime 是利用plugin自动识别并替换代码中的新特性,你不需要引入,只需要装好 babel-runtime和配置好plugin就可以了。好处是按需替换,检测到你需要那个,就引入哪个polyfll,如果只用了一部分,打包完成的文件提及对比babel-polyfill会小很多。而且transform-runtime不会污染原生的对象,方法,也不会对其他polyfill产生影响。所以transform-runtime的方式梗适合开发工具包,库,一方面是体积购销,另一方面是用户(开发者)不会因为引用了我们对工具包,而污染了全局原生方法,产生副作用,还是应该留给用户自己去选择。缺点是随着应用对增大,相同的polyfill每个模块都要做重复的工具(检测,替换),虽然polyfill只是也能用,编译效率不够高效。值得注意的是,instance 上增加的一些方法,babel-plugin-transform-runtime是没有做处理的,比如数组的includes,filter,fill, 这个算是一个关键问题,直接推荐用polyfill。

    presets (presets 就是plugins的组合,你也可以理解为是套餐)主要有
    • env
    • es2015
    • react
    • stage-x
    • babel-preset-env
    babel-preset-env

    它能根据当前的运行环境,自动确定你需要的 plugins 和 polyfills。 通过各个 es标准 feature 在不同浏览器以及 node 版本的支持情况,再去维护一个 feature 和 plugins 之间的映射关系,最终确定需要的 plugins。 useBuiltlns,env 会根据我们运行的环境,去判断需要什么样的 polyfill ,并且,打包后的代码体积也会大大减小

    from https://segmentfault.com/a/1190000011155061

  • 设计模式

    • 单体模式 思想在于保证一个特定的类仅有一个实例。 缺点:实例暴漏在外,可能被覆盖,额外的内存开销

    • 工厂模式 当创建相似的对象时执行重复的操作 在编译时不知道具体类型的情况下,为工厂客户提供一种创建对象的接口

    • 装饰者模式 装饰者模式的一个比较方面的特征在于其预期行为的可定制性和可配置特性。可以从具有一些基本功能的普遍对象开始,然后从科用装饰资源池中选择需要用于增强普通对象的那些功能,并且按照顺序进行装饰,尤其是当装饰顺序很重要的时候。通过从预定义装饰者对象中添加功能,从而运行时调整对象。

    • 迭代器模式 在迭代器模式中,通常有一个包含各种数据集合的对象。该数据可能储存在一个复杂数据结构内部,而要提供一种简单的方法能够访问数据结构中的每个元素。对象的消费者并不需要知道如何组织数据,所有需要做的就是提取出单个数据进行工作

    • 策略模式 策略模式支持您在运行时选择算法,代码的客户端可以使用同一个人接口来工作,但是它却根据客户正在试图执行任务的上下文,从多个算法中选择用于处理特定的任务的算法

    • 外观模式 内部静态属性、方法,外部暴漏接口

    • 观察者模式 观察者(observer)模式广泛应用于客户端javascript编程中。所有的浏览器事件(鼠标悬停,按键等事件),是该模式等例子。设计这种模式背后的主要动机是促进形成松散的耦合。

  • css3新特性

    • :last-child, :nth-child(n), nth-last-child(n) css3的新选择器

    • @font-face 加载服务端字体文件

    • border-radius 圆角

    • column-count, column-gap, column-rule 多列布局

    • shadow 阴影

    • gradient 渐变色

    • flex 弹性盒子模型

    • transition 过度动画

    • animation 帧动画

  • html5新特性

    • 标签 (article、aside、bdi、command、details、dialog、summary、figure、figcaption、footer、header、mark、meter、nav、progress、ruby、rt、rp、section、time、wbr

    • canvas 绘图

    • draggable HTML拖放 元素属性

    • navigator.geolocation 地理定位

    • audio、video 音频、视频

    • input type 输入框类型

    • Web储存

      • sessionStorage 会话级别储存

      • localStorage 永久存储

      • IndexDB 复杂数据 异步完成 indexDB.open 返回 request对象 request.result是我们需要的数据 requestonerroronsucccess事件监听 具有游标和索引、事务和锁但兼容性一般

    • 离线web应用(应用缓存)html attribute manifest

      • CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存

      • NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存

      • FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面

      CACHE MANIFEST
      # 2012-02-21 v1.0.0
      /theme.css
      /logo.gif
      /main.js
      NETWORK:
      login.php
      FALLBACK:
      /html/ /offline.html
      
    • Web Workers, 为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。不能跨域加载js。可以在worker中通过importScripts(url)加载另外的脚本文件,可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信,
      可以使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval(),可以使用XMLHttpRequest来发送请求,可以访问navigator的部分属性

    • Server-Sent Event EventSource 服务端推送

    • websocket

    from https://blog.csdn.net/chandoudeyuyi/article/details/69206236

  • 浏览器原理

    from https://blog.csdn.net/dangnian/article/details/50876241

  • http1.0 与 http1.1区别 http2有什么新特性

  • Promise中断 通过throw + catch

  • inmutable Hash算法实现

  • express、coa2 特点以及区别

  • 怎么算是一个好的模块

  • 正则、断言 以及贪婪模式

  • 从输入URL到页面渲染经历了什么

    1. 浏览器查询缓存,是否过期,如果没命中。

    2. 域名DNS解析,先查缓存,浏览器缓存、操作系统缓存、路由器缓存、ISP缓存(互联网提供商)、域名服务器递归查询 (经过的物理层和数据链路层先不谈)

    3. 连接目标IP并建立TCP连接。

    4. 如果目标有代理服务求,查询代理缓存,代理服务器请求目标服务器,经过web服务器处理,是否返回重定向再发起一个请求,或是查询缓存,返回资源到代理服务器再到客户端并断开TCP连接。

    5. 浏览器拿到数据,如果是text/HTML格式,则自上而下遇到css发起请求线程,遇到图片异步请求,遇到图片发起请求线程,请求有可能会写入缓存,遇到JS阻塞DOM树解析,DOM树解析结束后等待CSS加载完成解析成样式树后,与DOM树合成渲染树,layout计算,UI渲染。

  • Object.assign

    • 浅拷贝,对与对象内部复杂对象拷贝引用
    • 若用深拷贝可以使用 JSON.parse(JOSN.stringify(obj))
  • 原型链详解

    https://www.jianshu.com/p/dee9f8b14771

  • es6声明变量的6中方式

    • var
    • function
    • let
    • const
    • class
    • import
  • get 和 post 的具体区别
  • css盒模型 老IE模型
    • 正常模式 content-box
    • 怪异模式 border-box ie6、7、8
  • 文字图片环绕效果实现
    • img align 属性hspace于文字的间距

http://www.dailichun.com/2018/03/12/whenyouenteraurl.html 准备读

  • 箭头函数和普通函数的区别

    • 箭头函数是匿名函数,不能作为构造函数,不能使用new

    • 箭头函数不绑定arguments,取而代之用rest参数...解决

    • 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值

    • 箭头函数通过 call() 或 apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响。

    • 箭头函数没有原型属性

面试总结

在多次面试中,过度沉迷面试技巧,对面试中答不出的问题、技术方向做着全方位对查缺补漏,却影响了自己对主要学习计划,本末倒置。技术的内容、方向有太多太多了,面试时有所不会,是理所当然的,而你的学习、研究方向却是宇宙中心,万不可顾此失彼,今有所悟,感谢所有遇到的面试官。

你可能感兴趣的:(前端开发面试经验)