8月面试相关

面试总结

Posted by czk on August 26, 2021

http与htps

  • s是安全证书 传输加密保障安全
  • HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。

什么是ssl

  • Secure Sockets Layer 安全套接层
  • 信封

http1.0vs1.1 vs 2.0 vs3.0

  • 1.1对1.0 升级了
  • 支持长链接,断点续传,缓存控制改变,优化,携带header头部信息

  • 缓存处理,带宽优化及网络连接的使用,Host头处理(传了主机名称),长链接

  • 2.0 多路复用,提高性能,二进制格式传输 header压缩

  • 3.0 http1,2都是机遇tcp的链接,稳定性的同时也限定了他的发展,3.0udp

防抖节流

  • 防抖 每次事件触发则删除原来的定时器,建立新的定时器,你反复触发功能,那么只认最后一次,从最后一次触发开始计时。

      function debounce(fn, delay) {
        let timer = null;
        return function (...args) {
          let context = this;
          if(timer) clearTimeout(timer);
          timer = setTimeout(function() {
            fn.apply(context, args);
          }, delay);
        }
      }
    
  • 节流 如果在定时器的时间范围内再次触发,则不予理睬,等当前定时器完成,才能启动下一个定时器任务

      function throttle(fn, interval) {
        let flag = true;
        return funtion(...args) {
          let context = this;
          if (!flag) return;
          flag = false;
          setTimeout(() => {
            fn.apply(context, args);
            flag = true;
          }, interval);
        };
      };
    

call bind apply 是干嘛的?怎么实现

  • 都是对原来函数this指向的改变
  • bind
    1. 对于普通函数,绑定this指向
    2. 对于构造函数,要保证原函数的原型对象上的属性不能丢失
  • call
      Function.prototype.call = function (context, ...args) {
        var context = context || window;
        context.fn = this;
        var result = eval('context.fn(...args)');
        delete context.fn
        return result;
      }
    

new做了什么

1.  让实例可以访问到私有属性
2.  让实例可以访问构造函数原型(constructor.prototype)所在原型链上的属性
3.  如果构造函数返回的结果不是引用数据类型
```js
function newFactory(ctor, ...args) {
    if(typeof ctor !== 'function'){
      throw 'newOperator function the first param must be a function';
    }
    let obj = new Object();
    obj.__proto__ = Object.create(ctor.prototype);
    let res = ctor.apply(obj, ...args);

    let isObject = typeof res === 'object' && typeof res !== null;
    let isFunction = typoof res === 'function';
    return isObect || isFunction ? res : obj;
};
```

原型链

```js
实例  ====  _proto_  ====  ||                                null             
/\                                                           /\
new                       ||                                 ||
||                        \/
构造函数 ===》prototype==原型 === _proto_==>父级对象====》object.prototype
          《====constructor
```

JS如何实现继承

  • 借助call
      function Parent1(){
          this.name = 'parent1';
        }
        function Child1(){
          Parent1.call(this);
          this.type = 'child1'
        }
        console.log(new Child1);
    
  • 借助原型
       function Parent2() {
          this.name = 'parent2';
          this.play = [1, 2, 3]
        }
        function Child2() {
          this.type = 'child2';
        }
        Child2.prototype = new Parent2();
    
        console.log(new Child2());
    

forEach 并不能保证按顺序执行

  • forEach 拿过来直接执行了,这就导致它无法保证异步任务的执行顺序。比如后面的任务用时短,那么就又可能抢在前面的任务之前执行。
  • for…of并不像forEach那么简单粗暴的方式去遍历执行,而是采用一种特别的手段——迭代器去遍历

闭包理解,运用

  • 有权访问另外一个函数作用域中的变量的函数,
  • 在定时器、事件监听、Ajax请求或者任何异步中,只要使用了回调函数,实际上就是在使用闭包。

父子组件事件通信

  • Prop(常用)
  • $emit (组件封装用的较多)
  • .sync语法糖 (较少)
  • event bus
  • Provide/inject

promise异常捕获

  • try catch 不能捕获 是指同步函数的异常
  • 解决方案是可以在内层的 catch 再手动 throw 出异常
  • 同步window 有全局的错误捕获函数 onerror

前端缓存

HTTP 缓存及缓存代理

  • 强缓存 HTTP/1.0时期,使用的是Expires,而HTTP/1.1使用的是Cache-Control。 当ExpiresCache-Control同时存在的时候,Cache-Control会优先考虑。
        - private: 这种情况就是只有浏览器能缓存了
        - no-cache: 跳过当前的强缓存,发送HTTP请求,即直接进入`协商缓存阶段`。
        - no-store:非常粗暴,不进行任何形式的缓存
    
  • 协商缓存
    1. 存tag分为两种: Last-Modified 和 ETag
    2. Last-Modified 即最后修改时间。在浏览器第一次给服务器发送请求后,服务器会在响应头中加上这个字段。
    3. ETag 是服务器根据当前文件的内容,给文件生成的唯一标识,只要里面的内容有改动,这个值就会变
  • 缓存位置

nexttick

  • 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
    1. 如果支持 Promise 就用 Promise
    2. 如果不支持就用 MutationObserver MDN-MutationObserver 它会在指定的DOM发生变化时被调用
    3. 如果不支持 MutationObserver 的话就用 setImmediate MDN-setImmediate
    4. 最后一个条件 如果这些都不支持的话就用setTimeout PromiseMutationObserver会在执行栈空闲的时候立即执行,它的响应速度相比setTimeout会更快,因为无需等渲染 image.png

new Vue做了什么

Vue 初始化主要就干了几件事情,合并配置,初始化生命周期,初始化事件中心,初始化渲染,初始化 data、props、computed、watcher 等等。 检测到如果有 el 属性,则调用 vm.$mount 方法挂载 vm,挂载的目标就是把模板渲染成最终的 DOM,那么接下来我们来分析 Vue 的挂载过程

diff算法

1.较新旧节点的时候,比较只会在同层级进行, 不会跨层级比较。

2.如果两个节点都是一样的,那么就深入检查他们的子节点。如果两个节点不一样那就说明Vnode完全被改变了,就可以直接替换oldVnode

  • 如果oldVnode有子节点而Vnode没有,则删除el的子节点
  • 如果oldVnode没有子节点而Vnode有,则将Vnode的子节点真实化之后添加到el
  • 如果两者都有子节点,则执行updateChildren函数比较子节点,这一步很重要

vue watch,computed

  • 相同点:他们两者都是观察页面数据变化的。

  • 不同点:computed只有当依赖的数据变化时才会计算, 当数据没有变化时, 它会读取缓存数据。 watch每次都需要执行函数。watch更适用于数据变化时的异步操作。

hash路由,url路由

  1. hash路由 hashchange()
    • 将路由的hash以及对应的callback函数储存
    • 触发路由hash变化后,执行对应的callback函数
  2. url
    • 在当前已有的 back、forward、go 基础之上,它们提供了对历史记录修改的功能。
    • 只是当它们执行修改时,虽然改变了当前的 URL ,但浏览器不会立即向后端发送请求

小程序的性能优化

  • 使用分包
  • 大部分小程序在渲染首页时,需要依赖服务端的接口数据,接口请求放到页面的生命周期 onLoad 中,而不是 onReady里。
  •  缓存请求数据
  • 避免频繁的去 setData
  • 必要时再监听onPageScroll

如何实现ie怪异盒。

box-sizing

instanof 和 type of

type of比较类型 机器码 只能知道是对象但是不知道是哪种对象[],{} null也为object instanof 遍历左侧的原型链

ie优化

  1. 使用jQuery的load()方法加载代码块时,空白标签未闭合,标签书写错误,错误嵌套
  2. IE6、7右浮动换行问题 使用css hack,*margin: -28px;为元素添加负的margin,调整位置将右浮动元素放在所有兄弟行内非浮动元素的前面
  3. E7不兼容opacity属性 filter: alpha(opacity=0); /*IE*/
  4. IE10以下不支持placeholder属性判断当前input的value是否等于空('')
  5. json未定义导入json2.js
  6. ie8 ajax domain 跨域问题
    引入Cross-Domain AJAX for IE8 and IE9
    https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
    

    null == undefiend

symbol 用来数组去重

webpack性能优化

  • cacheDirectory 来开启缓存
  • happypack多核,开辟一个线程池,拿到系统CPU的最大核数,happypack 将编译工作灌满所有线程
  • Externals的方式,我们将这些不需要打包的静态资源从构建逻辑中剔除出去,而使用 CDN 的方式,去引用它们。
  • 缩小构建目标主要是exclude 与 include的使用
  • 减少文件搜索范围resolve相关的配置,用来设置模块如何被解析。通过resolve的配置