• 前端基础


    —webpack—

     

    webpack是一个打包模块化javascript的工具,在webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子,最后输出由多个模块组合成的文件,webpack专注构建模块化项目。

    WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。

     

     

    webpack打包体积优化---插件 webpack-bundle-analyzer

     

    webpackgruntgulp的不同?

    三者都是前端构建工具,grunt和gulp在早期比较流行,现在webpack相对来说比较主流,不过一些轻量化的任务还是会用gulp来处理,比如单独打包CSS文件等。

    grunt和gulp是基于任务和流(Task、Stream)的。类似jQuery,找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作构成了一个任务,多个任务就构成了整个web的构建流程。

    webpack是基于入口的。webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的Loader来处理不同的文件,用Plugin来扩展webpack功能。

    webpack类似的工具还有哪些?谈谈你为什么最终选择(或放弃)使用webpack

    同样是基于入口的打包工具还有以下几个主流的:

    • webpack
    • rollup
    • parcel

    从应用场景上来看:

    • webpack适用于大型复杂的前端站点构建
    • rollup适用于基础库的打包,如vue、react
    • parcel适用于简单的实验性项目,他可以满足低门槛的快速看到效果

    由于parcel在打包过程中给出的调试信息十分有限,所以一旦打包出错难以调试,所以不建议复杂的项目使用parcel

     

    有哪些常见的Loader?他们是解决什么问题的?

    • file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
    • url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
    • source-map-loader:加载额外的 Source Map 文件,以方便断点调试
    • image-loader:加载并且压缩图片文件
    • babel-loader:把 ES6 转换成 ES5
    • css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
    • style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS
    • eslint-loader:通过 ESLint 检查 JavaScript 代码

     

    有哪些常见的Plugin?他们是解决什么问题的?

    • define-plugin:定义环境变量
    • commons-chunk-plugin:提取公共代码
    • uglifyjs-webpack-plugin:通过UglifyES压缩ES6代码

     

    LoaderPlugin的不同?

    不同的作用

    • Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。
    • Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

    不同的用法

    • Loadermodule.rules中配置,也就是说他作为模块的解析规则而存在。 类型为数组,每一项都是一个Object,里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options)
    • Pluginplugins中单独配置。 类型为数组,每一项是一个plugin的实例,参数都通过构造函数传入。

     

    webpack的构建流程是什么?从读取配置到输出文件这个过程尽量说全

    Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

    1. 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
    2. 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
    3. 确定入口:根据配置中的 entry 找出所有的入口文件;
    4. 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
    5. 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
    6. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
    7. 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

    在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。

     

    是否写过LoaderPlugin?描述一下编写loaderplugin的思路?

     

    webpack的热更新是如何做到的?说明其原理?

    如何利用webpack来优化前端性能?(提高性能和体验)

    webpack优化前端性能是指优化webpack的输出结果,让打包的最终结果在浏览器运行快速高效。

    • 压缩代码。删除多余的代码、注释、简化代码的写法等等方式。可以利用webpack的UglifyJsPlugin和ParallelUglifyPlugin来压缩JS文件, 利用cssnano(css-loader?minimize)来压缩css
    • 利用CDN加速。在构建过程中,将引用的静态资源路径修改为CDN上对应的路径。可以利用webpack对于output参数和各loader的publicPath参数来修改资源路径
    • 删除死代码(Tree Shaking)。将代码中永远不会走到的片段删除掉。可以通过在启动webpack时追加参数--optimize-minimize来实现
    • 提取公共代码。

     

    如何提高webpack的构建速度?

    1. 多入口情况下,使用CommonsChunkPlugin来提取公共代码
    2. 通过externals配置来提取常用库
    3. 利用DllPlugin和DllReferencePlugin预编译资源模块 通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来。
    4. 使用Happypack 实现多线程加速编译
    5. 使用webpack-uglify-parallel来提升uglifyPlugin的压缩速度。 原理上webpack-uglify-parallel采用了多核并行压缩来提升压缩速度
    6. 使用Tree-shaking和Scope Hoisting来剔除多余代码

     

    怎么配置单页应用?怎么配置多页应用?

     

    npm打包时需要注意哪些?如何利用webpack来更好的构建?

    如何在vue项目中实现按需加载?

    Vue UI组件库的按需加载 为了快速开发前端项目,经常会引入现成的UI组件库如ElementUI、iView等,但是他们的体积和他们所提供的功能一样,是很庞大的。 而通常情况下,我们仅仅需要少量的几个组件就足够了,但是我们却将庞大的组件库打包到我们的源码中,造成了不必要的开销。

    不过很多组件库已经提供了现成的解决方案,如Element出品的babel-plugin-component和AntDesign出品的babel-plugin-import 安装以上插件后,在.babelrc配置中或babel-loader的参数中进行设置,即可实现组件按需加载了。

     

    单页应用的按需加载 现在很多前端项目都是通过单页应用的方式开发的,但是随着业务的不断扩展,会面临一个严峻的问题——首次加载的代码量会越来越多,影响用户的体验。

    通过import(*)语句来控制加载时机,webpack内置了对于import(*)的解析,会将import(*)中引入的模块作为一个新的入口在生成一个chunk。 当代码执行到import(*)语句时,会去加载Chunk对应生成的文件。import()会返回一个Promise对象,所以为了让浏览器支持,需要事先注入Promise polyfill

     

     

     

     

    —vue—

    vue-cli3安装教程

    https://www.jianshu.com/p/5d6080099fba

     

     

    Vue的生命周期

    beforeCreate(创建前) 在数据观测和初始化事件还未开始
    created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
    beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
    mounted(载入后)el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
    beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
    updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
    beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
    destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

    1.什么是vue生命周期?

    答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。

    2.vue生命周期的作用是什么?

    答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

    3.vue生命周期总共有几个阶段?

    答:它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。

    4.第一次页面加载会触发哪几个钩子?

    答:会触发 下面这几个beforeCreate, created, beforeMount, mounted

    5.DOM 渲染在 哪个周期中就已经完成?

    答:DOM 渲染在 mounted 中就已经完成了。

     

     Vue实现数据双向绑定的原理:Object.defineProperty()

    vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

    vue的数据双向绑定MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。

    js实现简单的双向绑定

    <body>

        <div id="app">

        <input type="text" id="txt">

        <p id="show"></p>

    </div>

    </body>

    <script type="text/javascript">

        var obj = {}

        Object.defineProperty(obj, 'txt', {

            get: function () {

                return obj

            },

            set: function (newValue) {

                document.getElementById('txt').value = newValue

                document.getElementById('show').innerHTML = newValue

            }

        })

        document.addEventListener('keyup', function (e) {

            obj.txt = e.target.value

        })

    </script>

    Vue组件间的参数传递

    1.父组件与子组件传值
    父组件传给子组件:子组件通过props方法接受数据;
    子组件传给父组件:$emit方法传递参数
    2.非父子组件间的数据传递,兄弟组件传值
    eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。)

    Vue的路由实现:hash模式 history模式

    hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
    特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
    hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。

    history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
    history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”

    vue路由的钩子函数

    首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。

    beforeEach主要有3个参数to,from,next

    toroute即将进入的目标路由对象,

    fromroute当前导航正要离开的路由

    nextfunction一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。

    一句话就能回答的面试题

    1.css只在当前组件起作用
    答:在style标签中写入scoped即可 例如:<style scoped></style>

    2.v-if v-show 区别
    答:v-if按照条件是否渲染,v-show是display的block或none

    3.$route$router的区别
    答:$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等。

    4.vue.js的两个核心是什么?
    答:数据驱动、组件系统

    5.vue几种常用的指令
    答:v-for 、 v-if 、v-bind、v-on、v-show、v-else

    6.vue常用的修饰符?
    答:.prevent: 提交事件不再重载页面;.stop: 阻止单击事件冒泡;.self: 当事件发生在该元素本身而不是子元素的时候会触发;.capture: 事件侦听,事件发生的时候会调用

    7.v-on 可以绑定多个方法吗?
    答:可以

    8.vue key 值的作用?
    答:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。

    9.什么是vue的计算属性?
    答:在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:①使得数据处理结构清晰;②依赖于数据,数据更新,处理结果自动更新;③计算属性内部this指向vm实例;④在template调用时,直接写计算属性名即可;⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。

    10.vue等单页面应用及其优缺点
    答:优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
    缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。

     

     

     

     

     

     

     

     

     

    react

     

    react 生命周期函数

    • 初始化阶段:
      • getDefaultProps:获取实例的默认属性
      • getInitialState:获取每个实例的初始化状态
      • componentWillMount:组件即将被装载、渲染到页面上
      • render:组件在这里生成虚拟的 DOM 节点
      • componentDidMount:组件真正在被装载之后
    • 运行中状态:
      • componentWillReceiveProps:组件将要接收到属性的时候调用
      • shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回 false,接收数据后不更新,阻止 render 调用,后面的函数不会被继续执行了)
      • componentWillUpdate:组件即将更新不能修改属性和状态
      • render:组件重新描绘
      • componentDidUpdate:组件已经更新
    • 销毁阶段:
      • componentWillUnmount:组件即将销毁

     

    angular

     

     

    js性能优化

    尽量减少HTTP请求次数

    减少DNS查询

    使用CDN

    使用GET来完成AJAX请求

    最小化DOM的操作次数

     

    节流防抖

     

    打包优化,项目优化等

    使用插件查看项目所有包及体积大小

    抽离项目中公共依赖的、不常变动的、体积较大的包

    将一个较大的业务代码文件,拆成多个较小的文件,异步加载(或者优化业务代码

    使用CDN引入资源

    dllPlugin为了提高打包效率,往往将第三库与业务逻辑代码分开打包,因为第三方库往往不需要经常打包更新

     

    webpack 按需打包加载 https://github.com/eyasliu/blog/issues/8

     

     

     

    webpack打包bundle.js体积大小优化:https://github.com/youngwind/blog/issues/65

     

     

     

     

    MVC MVVM MVP

    对于MVVM的理解?

    MVVM 是 Model-View-ViewModel 的缩写。
    Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
    View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
    ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。
    MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
    ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

     

    mvc

    Model-View-Controller(模型-视图-控制器):用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑.它强制性的使应用程序的输入、处理和输出分开。最典型的MVC就是JSP +servlet+javabean的模式。

     

    MVP 

    Model-View-Presenter:是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View责显示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller

     

    MVVM

    Model-View-ViewModel:和MVC模式一样,主要目的是分离视图(View)和模型(Model);在概念上是真正将页面与数据逻辑分离的模式,在开发方式上,它是真正将前台代码开发者(JS+HTML)与后台代码开发者分离的模式(asp,asp.net,php,jsp)。

     

    1. 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
    2. 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
    3. 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xaml代码。
    4. 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

     

     

    typescript

    TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持,它由 Microsoft 开发

    https://ts.xcatliu.com/introduction/what-is-typescript

    为什么选择 TypeScript

    TypeScript 增加了代码的可读性和可维护性

    • 类型系统实际上是最好的文档,大部分的函数看看类型的定义就可以知道如何使用了
    • 可以在编译阶段就发现大部分错误,这总比在运行时候出错好
    • 增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等

    TypeScript 非常包容

    • TypeScript 是 JavaScript 的超集,.js 文件可以直接重命名为 .ts 即可
    • 即使不显式的定义类型,也能够自动做出类型推论
    • 可以定义从简单到复杂的几乎一切类型
    • 即使 TypeScript 编译报错,也可以生成 JavaScript 文件
    • 兼容第三方库,即使第三方库不是用 TypeScript 写的,也可以编写单独的类型文件供 TypeScript 读取

    TypeScript 拥有活跃的社区

    • 大部分第三方库都有提供给 TypeScript 的类型定义文件
    • Google 开发的 Angular2 就是使用 TypeScript 编写的
    • TypeScript 拥抱了 ES6 规范,也支持部分 ESNext 草案的规范

    TypeScript 的缺点

    任何事物都是有两面性的,我认为 TypeScript 的弊端在于:

    • 有一定的学习成本,需要理解接口(Interfaces)、泛型(Generics)、类(Classes)、枚举类型(Enums)等前端工程师可能不是很熟悉的概念
    • 短期可能会增加一些开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript 能够减少其维护成本
    • 集成到构建流程需要一些工作量
    • 可能和一些库结合的不是很完美

     

    lesssasspostcss

    它们都是css预处理器。css预处理器的概念:CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件,以供项目使用。CSS预处理器为CSS增加一些编程的特性,无需考虑浏览器的兼容性问题。 比如说:Sass(SCSS)、LESS、Stylus、Turbine、Swithch CSS、CSS Cacheer、DT CSS等。都属于css预处理器。

    其中比较优秀的: Sass、LESS,Stylus

     

    nodejs

     

    linuxnginxsql

     

    web.glthree.js

     

     

    Koa2 node

     

     

     

    内存泄漏常见情况

    指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。

    1、意外的全局变量 

    js中如果不用var声明变量,该变量将被视为window对象(全局对象)的属性,也就是全局变量.

    function foo(arg) {

    bar = "this is a hidden global variable";

    }

    // 上面的函数等价于

    function foo(arg) {

    window.bar = "this is an explicit global variable";

    }

     

    所以,你调用完了函数以后,变量仍然存在,导致泄漏.

     

    如果不注意this的话,还可能会这么漏:

    function foo() {

    this.variable = "potential accidental global";

    }

        // 没有对象调用foo, 也没有给它绑定this, 所以this是window 

    foo(); 

    你可以通过加上’use strict’启用严格模式来避免这类问题, 严格模式会组织你创建意外的全局变量.

    2、被遗忘的定时器或者回调

    3、没有清理的DOM元素引用

    4、闭包引起的内存泄露

    怎样避免内存泄露

    1)减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收;

    2)注意程序逻辑,避免“死循环”之类的

    3)避免创建过多的对象  原则:不用了的东西要及时归还。

     

     

     

    ssr

    SSR:服务器渲染

    1、利用SEO(搜索引擎)

    2、页面渲染时间短

    3、服务器压力过大

     

    unit单元测试和e2e端到端测试的区别

    .unit测试

    站在程序员的角度测试
    unit测试是把代码看成是一个个的组件。从而实现每一个组件的单独测试,测试内容主要是组件内每一个函数的返回结果是不是和期望值一样。
    例如:

    const compare = (a,b) => a>b?a:b

    对这个函数进行测试

    expect(compare(1,2)).to.equal(2) //ok

    expect(compare(2,1)).to.equal(1) //ok

    测试完成

    而代码覆盖率是指代码中每一个函数的每一中情况的测试情况,上述测试的代码覆盖率是100%

    const compare = (a,b) => a>b?a:b

    对这个函数进行测试

    expect(compare(2,1)).to.equal(1) //ok

    测试完成

    这样代码覆盖率是50%,因为else情况没有测试到

    .e2e测试

    站在用户角度的测试
    e2e测试是把我们的程序堪称是一个黑盒子,我不懂你内部是怎么实现的,我只负责打开浏览器,把测试内容在页面上输入一遍,看是不是我想要得到的结果。

    两者的存在都是很有意义的。
    unit测试是程序员写好自己的逻辑后可以很容易的测试自己的逻辑返回的是不是都正确。
    e2e代码是测试所有的需求是不是都可以正确的完成,而且最终要的是在代码重构,js改动很多之后,需要对需求进行测试的时候测试代码是不需要改变的,你也不用担心在重构后不能达到客户的需求。

     

    小程序

    • WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。内部主要是微信自己定义的一套组件
    • WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式
    • js 逻辑处理,网络请求
    • json 小程序设置,如页面注册,页面标题及tabBar

     

    Promise 对象

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

     

     

    applycall

     apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.

     Function.apply(obj,args)方法能接收两个参数

    obj:这个对象将代替Function类里this对象

    args:这个是数组,它将作为参数传给Function(args-->arguments

     

    call:和apply的意思一样,只不过是参数列表不一样.

     Function.call(obj,[param1[,param2[,…[,paramN]]]])

    obj:这个对象将代替Function类里this对象

    params:这个是一个参数列表

     

    arguments

    它是JS的一个内置对象,常被人们所忽略,但实际上确很重要,JS不像JAVA是显示传递参数,JS传的是形参,可以传也可以不传,若方法里没有写参数却传入了参数,该如何拿到参数呢,答案就是arguments了,在一些插件里通常这样使用。

     

     

    prototype__proto__constructor

    prototype:是函数的一个属性,可共享,同时在创建实例中减少内存占用

     

    importrequire

    mportrequire都是被模块化所使用。

    遵循规范

    require 是 AMD规范引入方式

    import是es6的一个语法标准,如果要兼容浏览器的话必须转化成es5的语法

    调用时间

    require是运行时调用,所以require理论上可以运用在代码的任何地方,require可以理解为一个全局方法

    import是编译时调用,所以必须放在文件开头

    本质

    require是赋值过程,其实require的结果就是对象、数字、字符串、函数等,再把require的结果赋值给某个变量

    import是解构过程,但是目前所有的引擎都还没有实现import,我们在node中使用babel支持ES6,也仅仅是将ES6转码为ES5再执行,import语法会被转码为require

    语法

    require / exports :遵循 CommonJS/AMD,只能在运行时确定模块的依赖关系及输入/输出的变量,无法进行静态优化。 

    用法只有以下三种简单的写法:

        const fs = require('fs')

        exports.fs = fs

        module.exports = fs

     

    import / export:遵循 ES6 规范,支持编译时静态分析,便于JS引入宏和类型检验。动态绑定。 

    写法就比较多种多样:

        import fs from 'fs'

        import {default as fs} from 'fs'

        import * as fs from 'fs'

        import {readFile} from 'fs'

        import {readFile as read} from 'fs'

        import fs, {readFile} from 'fs'

     

        export default fs

        export const fs

        export function readFile

        export {readFile, read}

        export * from 'fs'

     

     

     

     

     

    eggThinkJs

     

     

     

    为什么虚拟 dom 会提高性能

    虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。

    JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了

     

     

     

     

     

    Http协议面试题

     

    1、说一下什么是Http协议?

    对器客户端和 服务器端之间数据传输的格式规范,格式简称为“超文本传输协议”。

    2、什么是Http协议无状态协议?怎么解决Http协议无状态协议?(曾经去某创业公司问到)

    • 无状态协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息
    • 无状态协议解决办法: 通过1、Cookie 2、通过Session会话保存。

    3、说一下Http协议中302状态(阿里经常问)

    • http协议中,返回状态码302表示重定向。
    • 这种情况下,服务器返回的头部信息中会包含一个 Location 字段,内容是重定向到的url。

    4Http协议有什么组成?

      请求报文包含三部分:

    • 请求行:包含请求方法、URI、HTTP版本信息
    • 请求首部字段
    • 请求内容实体

      响应报文包含三部分:

    • 状态行:包含HTTP版本、状态码、状态码的原因短语
    • 响应首部字段
    • 响应内容实体

    说一下网络传输的过程

     

    5Http协议中有那些请求方式?

    • GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器
    • POST:用于传输信息给服务器,主要功能与GET方法类似,但一般推荐使用POST方式。
    • PUT: 传输文件,报文主体中包含文件内容,保存到对应URI位置。
    • HEAD: 获得报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URI是否有效。
    • DELETE:删除文件,与PUT方法相反,删除对应URI位置的文件。
    • OPTIONS:查询相应URI支持的HTTP方法。

    6Http协议中Http1.01.1区别?

    • http1.0中,当建立连接后,客户端发送一个请求,服务器端返回一个信息后就关闭连接,当浏览器下次请求的时候又要建立连接,显然这种不断建立连接的方式,会造成很多问题。
    • http1.1中,引入了持续连接的概念,通过这种连接,浏览器可以建立一个连接之后,发送请求并得到返回信息,然后继续发送请求再次等到返回信息,也就是说客户端可以连续发送多个请求,而不用等待每一个响应的到来。

    7getpost请求区别?(初级程序员必备问题)

    区别一:

    • get重点在从服务器上获取资源。
    • post重点在向服务器发送数据。

    区别二:

    • get传输数据是通过URL请求,以field(字段)= value的形式,置于URL后,并用"?"连接,多个请求数据间用"&"连接,如http://127.0.0.1/Test/login.action?name=admin&password=admin,这个过程用户是可见的。
    • post传输数据通过Http的post机制,将字段与对应值封存在请求实体中发送给服务器,这个过程对用户是不可见的。

    区别三:

    • Get传输的数据量小,因为受URL长度限制,但效率较高。
    • Post可以传输大量数据,所以上传文件时只能用Post方式。

    区别四:

    • get是不安全的,因为URL是可见的,可能会泄露私密信息,如密码等。
    • post较get安全性较高。

    区别五:

    • get方式只能支持ASCII字符,向服务器传的中文字符可能会乱码。
    • post支持标准字符集,可以正确传递中文字符。

    9、常见Http协议状态?

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    200:请求被正常处理

     

    204:请求被受理但没有资源可以返回

     

    206:客户端只是请求资源的一部分,服务器只对请求的部分资源执行GET方法,相应报文中通过Content-Range指定范围的资源。

     

    301:永久性重定向

     

    302:临时重定向

     

    303:与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上

     

    304:发送附带条件的请求时,条件不满足时返回,与重定向无关

     

    307:临时重定向,与302类似,只是强制要求使用POST方法

     

    400:请求报文语法有误,服务器无法识别

     

    401:请求需要认证

     

    403:请求的对应资源禁止被访问

     

    404:服务器无法找到对应资源

     

    500:服务器内部错误

     

    503:服务器正忙

    10Http协议首部字段?

    a、通用首部字段(请求报文与响应报文都会使用的首部字段)

    • Date:创建报文时间
    • Connection:连接的管理
    • Cache-Control:缓存的控制
    • Transfer-Encoding:报文主体的传输编码方式

    b、请求首部字段(请求报文会使用的首部字段)

    • Host:请求资源所在服务器
    • Accept:可处理的媒体类型
    • Accept-Charset:可接收的字符集
    • Accept-Encoding:可接受的内容编码
    • Accept-Language:可接受的自然语言

    c、响应首部字段(响应报文会使用的首部字段)

    • Accept-Ranges:可接受的字节范围
    • Location:令客户端重新定向到的URI
    • Server:HTTP服务器的安装信息

    d、实体首部字段(请求报文与响应报文的的实体部分使用的首部字段)

    • Allow:资源可支持的HTTP方法
    • Content-Type:实体主类的类型
    • Content-Encoding:实体主体适用的编码方式
    • Content-Language:实体主体的自然语言
    • Content-Length:实体主体的的字节数
    • Content-Range:实体主体的位置范围,一般用于发出部分请求时使用

    11HttpHttps优缺点?

    • 通信使用明文不加密,内容可能被窃听,也就是被抓包分析。
    • 不验证通信方身份,可能遭到伪装
    • 无法验证报文完整性,可能被篡改
    • HTTPS就是HTTP加上加密处理(一般是SSL安全通信线路)+认证+完整性保护

    12Http优化

    • 利用负载均衡优化和加速HTTP应用
    • 利用HTTP Cache来优化网站

    13Http协议有那些特征?

    1、支持客户/服务器模式;2、简单快速;3、灵活;4、无连接;5、无状态。

     


     

    https://juejin.im/post/5d23e750f265da1b855c7bbe

     

  • 相关阅读:
    圣杯布局(定宽与自适应)
    【转载】jQuery插件开发精品教程,让你的jQuery提升一个台阶
    DOM 事件深入浅出(一)
    匿名类型
    类和结构
    C#预处理器指令
    Main()方法
    枚举
    预定义数据类型
    C#语言
  • 原文地址:https://www.cnblogs.com/herozhi/p/11286738.html
Copyright © 2020-2023  润新知