2022面试回忆录 — Moka

322 阅读2分钟

1、var、let 和 const 的区别

  • var 声明的范围是函数作用域,let 和 const 声明的范围是块作用域
  • var 声明的变量会被提升到函数作用域的顶部,let 和 const 声明的变量不存在提升,且具有暂时性死区特征
  • var 允许在同一个作用域中重复声明同一个变量,let 和 const 不允许
  • 在全局作用域中使用 var 声明的变量会成为 window 对象的属性,let 和 const 声明的变量则不会
  • const 的行为与 let 基本相同,唯一一个重要的区别是,使用 const 声明的变量必须进行初始化,且不能被修改

2、箭头函数和普通函数区别

  • 箭头函数没有自己的this对象
  • 不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误
  • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替
  • 不可以使用yield命令,因此箭头函数不能用作 Generator 函数

不适用场合:
由于箭头函数使得this从“动态”变成“静态”,下面两个场合不应该使用箭头函数

  • 定义对象的方法,且该方法内部包括this
  • 需要动态this的时候,也不应使用箭头函数

3、prefetch 和 preload

juejin.cn/post/691520…

4、vue2和vue3的响应式区别

使用 proxy 代替 defineProperty
Vue3 对比 Vue2.x juejin.cn/post/689229…

5、vite

6、Event Loop

juejin.cn/post/684490…

7、聊一下EventBus,发布-订阅和观察者模式区别?

juejin.cn/post/705544…

8、cdn容灾(本人没做过)

juejin.cn/post/705283…

9、pm2主要特点

  • 内建负载均衡(使用Node cluster 集群模块、子进程,可以参考朴灵的《深入浅出node.js》一书第九章)
  • 线程守护,keep alive
  • 0秒停机重载,维护升级的时候不需要停机.
  • 多平台支持 Linux (stable) & MacOSx (stable) & Windows (stable).
  • 停止不稳定的进程(避免无限循环)
  • 控制台检测
  • 提供 HTTP API
  • 远程控制和实时的接口API ( Nodejs 模块,允许和PM2进程管理器交互 ) 参考 blog.csdn.net/qq_17475155…

10、微前端、低代码?

算法题

第一题 判断两条线是否相交

/**
 * @param {{start: number, end: number}} first - 第一个区间
 * @param {{start: number, end: number}} second - 第二个区间
 * start end 是number 且需要考虑 小数情况
 * @return {boolean} 是否有交集
 */
function isOverlapped (first, second) {
  // 先判断不想交的情况
  if (first.end < second.start || second.end < first.start) {
    return false;
  }
  return true;
}

// test case
const a = { start: 3, end: 5 };
const b = { start: 9, end: 10 };
const c = { start: 4, end: 6 };
const d = { start: 5, end: 8 };

const r1 = isOverlapped(a, b);
const r2 = isOverlapped(c, d);
const r3 = isOverlapped({ start: 1, end: 5 }, { start: 2, end: 4 });
console.log(r1, r2, r3); // false true true

第二题 对相交区间进行合并

/**
 * @param {Range[]} intervals - 若干个区间
 * @return {Range[]} 合并后的区间
 */

解法一

function merge (interval) {
  const result = [interval.shift()];
  while (interval.length) {
    const current = interval.shift();
    for (let i = 0; i < result.length; i++) {
      const res = result[i];
      if (isOverlapped(current, res)) {
        result[i] = {
          start: Math.min(current.start, res.start),
          end: Math.max(current.end, res.end)
        };
        break;
      }
      if (i === result.length - 1) {
        result.push(current);
      }
    }
  }
  return result;
}

解法二
更优解,时间复杂度更低,O(n)
排序后,如果前一项跟当前项没有交集,那么也不会跟后一项有交集

function merge (interval) {
  interval.sort((a, b) => a.start - b.start);
  const result = [
    interval[0]
  ];
  for (let i = 1; i < interval.length; i++) {
    const prev = result[result.length - 1];
    const current = interval[i];
    if (isOverlapped(prev, current)) {
      result[result.length - 1] = {
        start: Math.min(prev.start, current.start),
        end: Math.max(prev.end, current.end)
      };
    } else {
      result.push(current);
    }
  }
  return result;
}

// test case
const e = [{ start: 3, end: 5 }, { start: 9, end: 10 }, { start: 4, end: 6 }, { start: 5, end: 8 }, { start: 10, end: 12 }, { start: 11, end: 14 }];

const f = [{ start: 4, end: 7 }, { start: 6, end: 9 }, { start: 1, end: 3 }, { start: 8, end: 10 }];

console.log(merge(e)); // [{start: 3, end: 8}, {start: 9, end: 14}]
console.log(merge(f)); // [{start: 1, end: 3}, {start: 4, end: 10}]

第三题

/*
Moka前端团队的技术分享2周一次,一次2人
为了确定下一次是谁来分享,团队中引入了分享积分制,具体规则为:

每个人都有一个积分,初始值是0。
每次分享后所有人摇一轮骰子,点数作为积分累加到各自的积分中,骰子范围是1-12。
积分最高的2个人将作为下一次的分享人。
为了避免连续分享,某个人分享后他的积分会被清零且跳过本次的摇骰子环节。
如果积分最高的人数超过2人,则相同分数的人继续摇骰子,直到决出2个积分最高的人。需要注意的是,这期间摇骰子的积分也同样累积。

请你编写代码模拟这个过程,数据结构和函数组织自由发挥
*/

const list = [
  { id: 1, score: 0 },
  { id: 2, score: 0 },
  { id: 3, score: 0 },
  { id: 4, score: 0 },
  { id: 5, score: 0 }
];

function getPerson (list) {
  const temp = [];
  list.forEach(person => {
    person.score = person.score + Math.floor(Math.random() * 12) + 1;
    temp.push(person);
  });
  // 排序
  temp.sort((person1, person2) => person2.score - person1.score);
  const result = [];
  let num = 1;
  for (let i = 0; i < temp.length; i++) {
    if (num === 2) {
      break;
    }
    if (result.length && result[result.length - 1].score !== temp[i].score) {
      num++;
    }
    result.push(temp[i]);
  }
  if (result.length > 2) {
    return getPerson(result);
  } else {
    const tempRes = JSON.parse(JSON.stringify(result));
    result.forEach(item => {
      item.score = 0;
    });
    return tempRes;
  }
}

// 查看原数据,分享者是否清零
console.log(list);
// 得到下次的分享者
console.log(getPerson(list));