作为前端面试官的面试套路手册

由于最近大量面试人,总结了一套面试套路。个人认为 或许/maybe/probably/perhaps 能够选出 Lead 以下的人。

不过这一套下来,需要 2 个小时,需要根据面试者不同情况,删减或者忽略问题。

Lead 以上 level 我没有把握。Lead 以下,如果他过了,我有 70%的概率会满意他进来后工作的表现。

HTML

你看看,作为面试官,明知道自己的问题不明确,需要别人再次确认,还是故意这样问。

但是,作为程序员,通过交流明确需求是一个技能。但是当别人答不上来,我会给引导,然后会明确需求的。

CSS

refer

CSS_Selectors

JavaScript

<body>
    <button>click me</button>
    <script>
        for (var index = 0; index < 10; index++) {
            document.querySelector('button').addEventListener('click', () => {
                console.log(index);
            })

        }
    </script>
</body>
asyncThing1()
  .then(function () {
    return asyncThing2();
  })
  .then(function () {
    return asyncThing3();
  })
  .catch(function (err) {
    return asyncRecovery1();
  })
  .then(
    function () {
      return asyncThing4();
    },
    function (err) {
      return asyncRecovery2();
    }
  )
  .catch(function (err) {
    console.log("Don't worry about it");
  })
  .then(function () {
    console.log("All done!");
  });

HTTP

Node.js

这方便的考察全都是代码分析,

ps: 虽然我没有想好,怎么面试 node.js 知识?但是我认为,下面几段代码,还是可以达到目的的。:)

1. 代码 1, 考察 的运行顺序, Q: 问下列代码的运行顺序。

Note: setImmediate and setTimeout(null,0), 运行顺序没有绝对先后。

import { readFile } from "fs";

console.log("-----------------------start--------------------");

// next tick
process.nextTick(() => {
  console.log("NT1: --nextTick1----");
});
// IO polling
readFile("./dom.html", (error, res) => {
  console.log("-----readFile---IO polling----"); // thread pool polling
});

// set immediate
setImmediate(() => {
  console.log("----------setImmediate---------");
});

// set timeout
setTimeout(() => {
  console.log("----------setTimeout---------");
}, 0);

//
console.time("add");
function add() {
  let count = 0;
  for (let index = 0; index < 100000000; index++) {
    count += index;
  }
  return count;
}
console.log(`----------user sync--${add()}------- `);
console.timeEnd("add");
// next tick
process.nextTick(() => {
  console.log("NT2: --nextTick2----");
});

2. 代码 2

如果面试者,回答 node.js 是单线程的,让他先看第一段代码。 如果面试者,回答不是单线程的,让他阐述下为什么? 最后还是要用代码,验证他的理解程度。

import { pbkdf2Sync } from "crypto";
const startTime = Date.now();
let index = 0;
for (index = 0; index < 3; index++) {
  pbkdf2Sync("secret", "salt", 100000, 64, "sha512");
  const endTime = Date.now();
  console.log(`${index} time, ${endTime - startTime}`);
}
const endTime = Date.now();
console.log(`${index} time, ${endTime - startTime}`);
// 0 time, 185
// 1 time, 84
// 2 time, 279
// 3 time, 280

//1. node.js 是单线程的吗?
// 让面试者再次确认,是单线程的.

演示下面这段代码,让面试者,产生质疑是单线程。

import { pbkdf2 } from "crypto";
import { cpus } from "os";
console.log(cpus().length);
let startTime = console.time("time-main");

// 告诉,pbkdf2是异步的,让面试者猜测时间
// 最后

for (let index = 0; index < 5; index++) {
  startTime = console.time(`time-${index}`);
  pbkdf2("secret", `salt${index}`, 100000, 64, "sha512", (err, derivedKey) => {
    if (err) throw err;
    console.timeEnd(`time-${index}`);
  });
}
console.timeEnd("time-main");

然后最后追问,node.js 是单线程的吗? 引导面试者得出大概 node.js,进行加密算法会使用线程池。因为加密算法很耗费 CPU 能力,node.js 需要单独使用线程池,保证主线程的 no-block。

UV_THREADPOOL_SIZE, 默认是 4. 然后,显示下段代码,

如果面试者不懂这方面知识,很容易进入套路,但是如果面试者懂,那么他在套路中,直接告诉你答案。

2. 代码 3, 网络请求

import { request } from "https";
const options = {
  hostname: "www.baidu.com",
  port: 443,
  path: "/img/PC_7ac6a6d319ba4ae29b38e5e4280e9122.png",
  method: "GET",
};

let startTime = console.time(`main`);

for (let index = 0; index < 40; index++) {
  startTime = console.time(`time-${index}`);
  const req = request(options, (res) => {
    console.log(`statusCode: ${res.statusCode}`);
    console.timeEnd(`time-${index}`);
    res.on("data", (d) => {
      // process.stdout.write(d);
    });
  });

  req.on("error", (error) => {
    console.error(error);
  });

  req.end();
}

console.timeEnd("main");

Q: 为什么 network 请求,即使循环 40 多次,他们的处理时间都是一样的?好像没有线程池?

CI CD

Angular

RXJS

问面试者还有什么问题吗?

一些不好回答与技术无关问题,甩锅给 HR。:)