• 头条二面


      还是要diss一下周六的平安总部面试,面试体验渣到极点,以至于我已经在心里把所有平安职位拉黑。

      二面直接放点题目吧,作为记录,所有题目都需要现场手写,痛苦。

     

      自我介绍的时候,面试官问了下有什么东西特别有成就感,我就说原生实现了Datepicker的插件,然后就开始特别细节的问。

      源代码比较长,贴个地址吧:https://github.com/pflhm2005/JS-components/blob/master/vanilla-picker/index.js

      这一块问了比较久,因为完全是自己写的,所以全部都能答出来。

      接下里是现场出题。

      

    1、实现JSON.stringify的polyfill

      想了老久,手写很痛苦,就讲思路了。

      普通类型略,复杂类型根据对象、数组做遍历,然后用'{'、'}'、'['、']'字符进行拼接,中间涉及到null、undefined,直接跳过。

      还有一个循环引用的问题,需要直接报错,问题是如何判断存在循环引用,这里贴一个自己写的深拷贝代码,里面有处理循环引用的思路:

    const deepClone = (o) => {
      let path = new WeakMap();
      path.set(o, 'this');
      let path_ar = ['this'];
      return (function inner(o) {
        let result = {};
        Object.keys(o).forEach(v => {
          let value = o[v];
          path_ar.push(v);
          if(value && typeof value === 'object') {
            if (path.has(value)) {
              let dupi_path = path.get(value).split('.').slice(1);
              let origin = result;
              dupi_path.forEach(v => {
                origin = origin[v];
              });
              result[v] = origin;
            } else {
              path.set(value, path_ar.join('.'));
              result[v] = inner(value);
            }
          } else {
            result[v] = value;
          }
          path_ar.pop();
        });
        return result;
      })(o);
    };

      因为拿深拷贝的循环引用处理讲的,面试官就问我这个深拷贝后的对象,循环引用还指向之前的么,我就回答新对象中所有属性跟老的完全无关。

    2、嵌套数组的环形遍历

      这个题目有点意思,直接上图:

      比如说上面这个二维数组,可以理解成一个矩阵,然后遍历方式如下:

      一圈圈从外向内遍历,当然题目是m*n的矩阵。

      一开始看到题目感觉也挺新鲜,细写发现好恶心,变量用不过来,就简单讲了下思路,大概是设定一个遍历规则,然后遍历的初始和终止条件,嵌套for循环搞定。

      回家后写了下,代码如下:

    let iterator = (ar) => {
      let m = ar.length;
      let n = ar[0].length;
      for(let i = 0,j = n;i !== j;i++,j--,m--) {
        for(let i2=i;i2<j;i2++) {
          console.log(ar[i][i2]);
        }
        for(let i3=i+1;i3<m;i3++) {
          console.log(ar[i3][m-1]);
        }
        for(let i4=j-1;i4>i;i4--) {
          console.log(ar[m-1][i4-1]);
        }
        for(let i5=m-2;i5>i;i5--) {
          console.log(ar[i5][i])
        }
      }
    }

      这TM现场手写,怕是要疯了。

    3、sum(1,2).value()、sum(1)(2).value()均返回3

      这里一眼就看出来是函数柯里化,但是下手的时候很懵逼。

      想了好久好久,面试官都有点看不下去了,最后写出来了(完整手写出来,真的不容易啊):

    function sum(...args){
      let n = args.reduce((a,b) => a+b, 0);
      function inner(...args2){
        return sum.apply(null, [n, ...args2]);
      }
      inner.value = () => { console.log(n); };
      return inner;
    }

      面试官看了会,说写的倒不错,但是内部函数每次都会创建一个闭包,有没有优化的办法。

      我一脸痛苦的看了他一眼,他想了想说算了。

      这里贴一个优化版的,不知道符不符合面试官要求:

    let sum = (...args) => {
      let result = [...args];
      return (function(r) {
        let inner = (...args) => {
          r.push(...args);
          return inner;
        }
        inner.value = () => { console.log(r.reduce((a,b) => a+b, 0)); };
        return inner;
      })(result)
    };

      缓存一个数组,每次调用都返回同一个内部函数,不会重复走大函数流程,错了我就删掉。。。

    4、字符串驼峰化

      简单讲就是aa-bb => aaBb,aa--bb => aaBb。

      先是简单的版本:

    function camel(str) {
      let ar = str.split('-');
      let result = [];
      let l = ar.length;
      for(let i = 1;i < l;i++) {
        if(!ar[i]) continue;
        result.push(ar[i][0].toUpperCase() + ar[i].slice(1));
      }
      return ar[0] + result.join('');
    }

      然后面试官说,可能分隔符有多种,比如说_、@等等,然后函数不变,仍然只能传一个参数。

      我说这得重写,我的第一行就不管用了。

      面试官让讲思路,我就简单说直接遍历,设一个flag,标记是否遇到了分隔符,然后把分隔符后面的第一个非分隔符大写。

      回家后,代码如下:

    // 假设分隔符有_和-两种
    function camel(str) {
      let cut = ['_', '-'];
      let ar = str.split('');
      let l = ar.length;
      let flag = false;
      for(let i = 0;i < l;i++) {
        let cur = ar[i];
        if(cut.indexOf(cur) !== -1) {
          ar[i] = '';
          flag = true;
        }
        else if(flag){
          ar[i] = ar[i].toUpperCase();
          flag = false;
        }
      }
      return ar.join('');
    }

       后面就问了一些工程化的问题(cdn、渲染优化),我一个都不会,果然还是太年轻。

  • 相关阅读:
    Thread.Join
    WPF几个基础概念的浅显理解
    Vue v-bind指令
    Vue设置路由跳转的两种方法: <router-link :to="..."> 和router.push(...)
    前端上传视频、图片、文件等大文件 组件Plupload使用指南
    vue如何获取并操作DOM元素
    css中border-sizing属性详解和应用
    vue使用axios发送post请求时的坑及解决原理
    vue中的js引入图片,使用require相关问题
    vue 动态添加body背景图片
  • 原文地址:https://www.cnblogs.com/QH-Jimmy/p/9986821.html
Copyright © 2020-2023  润新知