# 2019年09月刊

# 2019/09/23 - 2019/09/29 ⌚️


  • vue 中 keep-alive 标签是如何实现缓存组件的

  • map 与 forEach 的区别?

    点击

    都是遍历,只不过 map 方法是将数组进行一次遍历操作后返回一个新数组,原数组并没有变化

  • 移动端抓包工具的使用?fiddler

    bpu bpafter

    这里有个关于 fiddler 的讲解视频 (opens new window),很详细,推荐观看

  • vue 父组件监听子组件的 mounted

    // Parent.vue <Child @hook:mounted="doSth" />
    
    1
  • vue 父子组件的生命周期执行顺序?

    点击

    加载渲染过程:

    父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted。

    组件更新过程:

    父beforeUpdate->子beforeUpdate->子updated->父updated

    销毁过程:

    父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

  • base64 的图片和原本的图片谁大? base64 化会大一些

  • css 如何实现下雨的效果?

# 2019/09/16 - 2019/09/22 ⌚️


  • mogondb 的连表查询

  • mysql 与 mongodb 的区别 ?

  • web worker 是如何进行通信的?

  • chrome 给每个页面分配的内存是多少?貌似是 1 G

  • 如何排查页面卡顿的原因?

    可能的原因:死循环,不断触发重绘重排,变量指向大数据没有及时清除造成内存泄漏

    排查参考文章:狙杀页面卡顿 —— Performance 指北 (opens new window)

  • 如何使用 indexDB?

  • 实现输入 123456 返回 '654321',要求使用递归

    点击
    function reversal(num) {
      if (num < 10) return num + '';
      let value = (num / 10) | 0;
      let cha = num % 10;
      return `${cha}${reversal(value)}`;
    }
    
    1
    2
    3
    4
    5
    6

# 2019/09/09 - 2019/09/15 ⌚️


  • HTML 中行内元素与块级元素的区别

    点击

    行内元素水平排列,块级元素垂直排列。

    行内元素不可以设置宽高,宽度高度随文本内容的变化而变化,但是可以设置行高(line-height),同时在设置外边距 margin 上下无效,左右有效,内填充 padding 上下无效,左右有效;块级元素可以设置宽高,并且宽度高度以及外边距,内填充都可随意控制。

  • 前端如何应对高并发

    点击
    1. 减少 http 请求,如按钮防抖

    2. 启用浏览器缓存

    3. 压缩静态资源,开启 gzip

    4. cdn 加速

    5. 独立图片服务器

  • jsonp 的优缺点?

    点击

    JSONP 的优点是:它不像 XMLHttpRequest 对象实现的 Ajax 请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都 可以运行,不需要 XMLHttpRequest 或 ActiveX 的支持;并且在请求完毕后可以通过调用 callback 的方式回传结果。

    JSONP 的缺点则是:它只支持 GET 请求而不支持 POST 等其它类型的 HTTP 请求;它只支持跨域 HTTP 请求这种情况,不能解决不同域的两个页面之间如何进行 JavaScript 调用的问题。

  • 如何计算首屏时间和白屏时间?

  • webpack 中 loader 和 plugin 的区别是什么

    点击

    loader 一般是将某个语法统一处理为统一的语法

    plugin 一般是在打包前或打包后对结果进行再次操作

  • 什么是事件冒泡和事件捕获,区别是什么

    点击

    事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到 document 对象。与事件冒泡相反,事件捕获会从最外层开始发生,直到最具体的元素。

  • es6 的继承是如何实现的?

    点击

    简单的说:

    subClass.prototype.__proto__ = superClass.prototype;
    
    subClass.__proto__ = superClass;
    
    1
    2
    3

    那为什么这样一倒腾,它就实现了继承了呢?

    首先 subClass.prototype.__proto__ = superClass.prototype 保证了 c instanceof Parenttrue , Child 的实例可以访问到父类的属性,包括内部属性,以及原型属性。其次,subClass.__proto__ = superClass,保证了 Child.height 也能访问到,也就是静态方法。

# 2019/09/02 - 2019/09/08 ⌚️


  • GIT 中 pull 与 fetch 的区别?

    点击

    使用 git fetch 更新代码,本地的库中 master 的 commitID 不变,还是等于 1。但是与 git 上面关联的那个 orign/master 的 commit ID 变成了 2。这时候我们本地相当于存储了两个代码的版本号,我们还要通过 merge 去合并这两个不同的代码版本,如果这两个版本都修改了同一处的代码,这时候 merge 就会出现冲突,然后我们解决冲突之后就生成了一个新的代码版本。

    这时候本地的代码版本可能就变成了 commit ID=3,即生成了一个新的代码版本。

    git pull 更新代码的话就比较简单暴力了,使用 git pull 的会将本地的代码更新至远程仓库里面最新的代码版本,看起来像 git fetch + get merge,但是根据 commit ID 来看的话,他们实际的实现原理是不一样的(commit id 覆盖了远程的)。

    不要用git pull,用git fetch和git merge代替它。
    
    git pull的问题是它把过程的细节都隐藏了起来,以至于你不用去了解git中各种类型分支的区别和使用方法。当然,多数时候这是没问题的,但一旦代码有问题,你很难找到出错的地方。看起来git pull的用法会使你吃惊,简单看一下git的使用文档应该就能说服你。
    
    将下载(fetch)和合并(merge)放到一个命令里的另外一个弊端是,你的本地工作目录在未经确认的情况下就会被远程分支更新。当然,除非你关闭所有的安全选项,否则git pull在你本地工作目录还不至于造成不可挽回的损失,但很多时候我们宁愿做的慢一些,也不愿意返工重来。
    
    
    1
    2
    3
    4
    5
    6
  • 详解 js 位运算? (opens new window)

  • 电商项目中的价格由前端计算还是后端计算,为什么?

    点击

    如购物车的价格,由前端计算显示,能提高用户体验;

    订单实际价格应由后端进行计算,如果由前端进行计算,可能出现代码注入修改价格,或者是伪装用户身份提交极低的价格生成订单,或者是拦截请求修改请求的价格参数,这些都是很危险的。

    所以显示由前端进行计算,实际价格应由后端进行计算,这样会出现一个问题:如果前端计算不正确该怎么办?此时想到的办法就是在前端计算完价格后显示给用户,然后调用后台接口计算价格判断是否有误,再进行抉择。

  • html 如何设置不缓存?

  • vue 实例化做了哪些事?

    点击

    可以参考文章:《实例化 vue 发生了什么》 (opens new window), 《如何解释 vue 的生命周期才能令面试官满意?》 (opens new window)

  • var 与 let 的区别

    点击
    1. 可以用 let 定义块级作用域变量
    2. let 没有变量提升与暂时性死区
    3. let 变量不能重复声明
  • 搜索二叉树的中序遍历排序

    点击

    对于任意一个节点,先遍历他的左子树,再遍历本身,再遍历右子树,最后得到一个升序的数组

    function Node(val) {
      this.left = null;
      this.right = null;
      this.value = val;
    }
    
    function generateBST(root, array) {
      var length = array.length;
    
      for (var i = 1; i < length; i++) {
        insertNode(root, array[i]);
      }
    }
    
    function insertNode(node, value) {
      if (value < node.value) {
        if (node.left === null) {
          node.left = new Node(value);
        } else {
          node = node.left;
          insertNode(node, value);
        }
      } else {
        if (node.right === null) {
          node.right = new Node(value);
        } else {
          node = node.right;
          insertNode(node, value);
        }
      }
    }
    
    var array = [2, 3, 4, 12, 3, 54, 6, 7, 1];
    var root = new Node(array[0]);
    
    generateBST(root, array);
    
    // 中序遍历
    function inorderSearch(root) {
      var array = [];
    
      _inorderSearch(root, array);
      return array;
    }
    
    function _inorderSearch(node, array) {
      if (!node) {
        return;
      }
      _inorderSearch(node.left, array);
      array.push(node.value);
      _inorderSearch(node.right, array);
    }
    console.log(root);
    console.log(inorderSearch(root));
    
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55