2023 front-end interview and answer arrangement

Jin San is about to start. As the saying goes, knowing yourself and your enemy is invincible, and there is nothing wrong with being more prepared. Study with everyone in the form of interviews and review our careers together. Today I will briefly summarize my personal interviews, including my experience in interviewing others. Come on, come on! ! !

Table of contents

hot start problem

1. Tell me about the difficult problems you have solved in your work or the bright spots in your own projects

2. Do you understand the browser's event loop?

    2.1 Why does js have an event loop mechanism in the browser?

    2.2 Do you understand the two tasks in the event loop?

    2.3 Why introduce the concept of micro-tasks, can only macro-tasks be used?

    2.4 Do you know the event loop of Node.js? What is the difference between the event loop in Node and the browser's event loop?

        2.5 At this time, so many theoretical questions have been asked, and practice 1

        2.6 Practice 2

     2.7 Practice 3 

3. How much do you know about event capture and bubbling mechanisms?

    3.1 Basic concepts

    3.2 What stage does window.addEventListener listen to?         

    3.3 What are the usual scenarios where these mechanisms are used? 

4. Have you ever used anti-shake and throttling in your work?

    4.1 Basic concepts

    4.2 What scenarios are they suitable for?

    4.3 Handwritten throttling function

5. Do you know Promise? Do you use it often?

    5.1 Promise.all( ) Do you know what features it has?

    5.2 What if one of the Promises fails?

    5.3 If a Promise reports an error, will other Promises still be executed?

    5.4 Writing a Promise.all( ) by hand

    5.5 Promise has been executed during initialization, so what can we do with this feature (extensibility issue)?

 6. Byte Classical Algorithm Problem----Receiving Rainwater


hot start problem

1. Tell me about the difficult problems you have solved in your work or the bright spots in your own projects

   Inspection purpose : The interviewer mainly looks at our ability to solve problems

   Answer : This question mainly depends on the accumulation of everyone's work. You can develop a good habit in the usual work process. No matter what you need to do, take some time to record it. This way, whether it is one year or two years, Or I will accumulate a lot in five years and there is no need, and then sort it out by myself, and give feedback to the interviewer during the interview, so that the interviewer will be shocked, and the offer will be available immediately~~~

2. Do you understand the browser's event loop?

     The purpose of the investigation : use this question as a breakthrough to dig deeper into your understanding of the entire concept

    2.1 Why does js have an event loop mechanism in the browser?

     answer :

               ① JS is single-threaded

               ② event loop

    2.2 Do you understand the two tasks in the event loop?

     answer :

                ① Macro task: overall code block, setTimeOut, setInterval, I/O operation

                ② Microtasks: new Promise().then(), mutationObserver (front-end backtracking)

    2.3 Why introduce the concept of micro-tasks, can only macro-tasks be used?

    answer :

        Macro task : the principle of first in first out

        During the execution of JS or the rendering of the page, macro tasks are executed according to the principle of first-in-first-out . We cannot accurately control these tasks being pushed into the task queue, but if we come out at this time with a very high priority What should I do at this time? If we only have macro tasks, and then push one into the task queue, adhering to the principle of first in, first out, then it must be the last to be executed, so we need to introduce micro tasks;

After understanding the macrotasks and microtasks, let's learn the execution order of macrotasks and microtasks.        

  • The code starts to execute, creating a global call stack, which scriptis executed as a macro task
  • During the execution process, the synchronous task is executed immediately, and the asynchronous task is registered in the microtask queue and the macrotask queue respectively according to the asynchronous task type
  • After the synchronization task is executed, check the task queue
    • If there are microtasks, execute all the microtask queues (including new microtasks generated during the execution of microtasks)
    • If there is no micro task, check the macro task queue and execute the first macro task. After the macro task is executed, check the micro task queue and repeat the above operation until the macro task queue is empty

    2.4 Do you know the event loop of Node.js? What is the difference between the event loop in Node and the browser's event loop?

    answer :

            The execution order of Node macro tasks:

                ① timers timer: Execute the callback functions of setTimeout and setInterval that have been arranged;

                ②pending callback Pending callback: execute the I/O callback delayed to the next loop iteration;

                ③idle, prepare: only used internally by the system;

                ④poll: Retrieve new I/O events and execute callbacks related to I/O

                ⑤check: execute setImmediate() callback function

                ⑥close callback:socket.on('close', (  )=>{  })

          The execution order of microtasks and macrotasks in node:

        First of all, everyone must understand that the execution order of microtasks and macrotasks in Node is related to the version of node

        Prior to Node V10:

                 ① Execute all the tasks in the above stage

                 ② Execute the content in the nextTick queue

                 ③ Execute the contents of the microtask queue

        After Node V10:

                Unified behavior with browsers

        2.5 At this time, so many theoretical questions have been asked, and practice 1

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}
async function async2() {
  console.log("async2");
}
console.log("script start");
setTimeout(() => {
  console.log("setTimeout");
}, 0);
async1();
new Promise((resolve) => {
  console.log("promise1");
  resolve();
}).then(() => {
  console.log("promise2");
});
console.log("script end");

// 1. script start
// 2. async1 start
// 3. async2
// 4. promise1
// 5. script end
// 6. async1 end
// 7. promise2
// 8. setTimeout

        2.6 Practice 2

                This is more difficult. If you really can’t, don’t just open your mouth and say: “I can’t”. At this time, when I was an interviewer, I was thinking in my heart: “I’m so embarrassed, this is so embarrassing. "!" Let’s have fun and make a joke. At this time, try to express your own thinking. Even if it is wrong, you have to let the interviewer see your enterprising and research spirit!

console.log("start");
setTimeout(() => {
  console.log("children2");
  Promise.resolve().then(() => {
    console.log("children3");
  });
}, 0);

new Promise((resolve, reject) => {
  console.log("children4");
  setTimeout(() => {
    console.log("children5");
    resolve("children6"); // 此处大坑
  }, 0);
}).then((res) => {
  console.log("children7");
  setTimeout(() => {
    console.log(res);
  }, 0);
});

// 1. start
// 2. children4
/** 第一轮宏任务执行结束,尝试清空微任务队列,发现没有微任务,尝试执行下一轮宏任务   */
// 3. children2
/** 第二轮宏任务执行结束,尝试清空微任务队列,   */
// 4. children3
// 5. children5
/** 第三轮宏任务执行结束,尝试清空微任务队列,   */
// 6. children7
// 7. children6

     2.7 Practice 3 

        At this point, are you thinking in your heart: "Why does the interviewer hold on to the event loop?" The last question

const p = () => {
  return new Promise((resolve, reject) => {
    const p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(1); // 这里 不会再输出了,因为 resolve(2) 已经把结果输出
      }, 0);
      resolve(2);
    });
    p1.then((res) => {
      console.log(res);
    });
    console.log(3);
    resolve(4);
  });
};
p().then((res) => {
  console.log(res);
});
console.log("end");

// 1. 3
// 2. end
// 3. 2
// 4. 4

                 So far, the event loop is over!

3. How much do you know about event capture and bubbling mechanisms?

    3.1 Basic concepts

           Take HTML as an example: ↓

           Capture : After going from window → parent → child → son to the target element, it turns into bubbling

           Bubble : target element son → child → parent → window

    3.2 What stage does window.addEventListener listen to?         

// 冒泡阶段
window.addEventListener("click", () => {

}); // 第三个参数默认为 false,为false 时,监听的为冒泡阶段

// 捕获阶段
window.addEventListener("click", () => {
  
}, true);

    3.3 What are the usual scenarios where these mechanisms are used? 

        3.3.1. Event delegation 

    <ul id="ul">
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
    </ul>


    const ul = document.querySelector("ul");
    ul.addEventListener("click", (e) => {
      const target = e.target;
      if (target.tagName.toLowerCase() === "li") {
        const liList = document.querySelectorAll("li");
        //  这里之所以会这么写,是因为 liList 并非是一个真正的 Array
        // 此时返回的是一个 nodeList,如果想使用 数组的 方法,需要改变this
        const index = Array.prototype.indexOf.call(liList, target);
        console.log(`内容:${target.innerHTML},索引:${index}`);
      }
    });

        3.3.2 Scenario Design Questions

        A history page with click logic for several buttons, each button has its own click event

        Here comes a new requirement: add an attribute to each visiting user, if banned = true , the user cannot respond to the original function when clicking any button or element on the page. Instead, it directly alerts that you are banned.

        Implementation: use the event capture mechanism to complete ( of course, there are three ways to implement, or even more, here we only talk about event capture )      

/**
    * 场景设计题
    一个历史页面,上面有若干按钮的点击逻辑,每个按钮都有自己的 click 事件
     新需求来了:给每一个访问的用户添加了一个属性,如果 banned = true,此用户点击页面上的任何按钮或元素,
    都不可响应原来的函数。而是直接 alert 提示,你被封禁了。
*/


window.addEventListener(
  "click",
  (e) => {
    if (banned) {
      e.stopPropagation();
    }
  },
  true
);

4. Have you ever used anti-shake and throttling in your work?

    4.1 Basic concepts

        Anti-shake : When the event is continuously triggered, the time processing function will only be executed once if no more events are triggered within a certain period of time

        Throttling : When the event is continuously triggered, the event processing function is guaranteed to be called only once within a period of time (fixed time)

    4.2 What scenarios are they suitable for?

        Anti-shake : input input (huge engine)

        Throttling : resize (screen size change), scroll (when scrolling) ---> must be executed, give a fixed interval 

    4.3 Handwritten throttling function

        Time stamp writing method , execute immediately for the first time

// 时间戳写法,第一次立即执行
const throttle = (fn, interval) => {
  let last = 0;
  return () => {
    let now = Date.now();
    if (now - last >= interval) {
      fn.apply(this, arguments);
    }
  };
};
const handle = () => {
  console.log(Math.random());
};
const throttleHandle = throttle(handle, 3000);
throttleHandle();
throttleHandle();

        Timer writing method , the first time also needs to delay the specific time before executing

// 定时器写法,第一次也会延时 具体的时间执行
const throttle = (fn, interval) => {
  let timer = null;
  return function () {
    let context = this;
    let args = arguments;
    if (!timer) {
      timer = setTimeout(() => {
        fn.apply(context, args);
        timer = null;
      }, interval);
    }
  };
};
const handle = () => {
  console.log(Math.random());
};
const throttleHandle = throttle(handle, 1000);
throttleHandle();
throttleHandle();

        Accurately implement a throttling function, whether it is after the first time or the last time (to avoid the last execution and wait for a specific time before execution)

// 精确的实现一个节流函数,无论是第一次之后还是最后一次(避免最后一次执行还会再等具体时间之后再执行)
const throttle = (fn, delay) => {
  let timer = null;
  let startTime = Date.now();
  return function () {
    let curTime = null;
    let remainning = delay - (curTime - startTime);
    let context = this;
    let args = arguments;
    clearTimeout(timer);
    if (remainning <= 0) {
      fn.apply(context, args);
      startTime = Date.now();
    } else {
      timer = setTimeout(fn, remainning);
    }
  };
};

        

5. Do you know Promise? Do you use it often?

    5.1 Promise.all( ) Do you know what features it has?

         Answer : Promise.all( ) will accept a Promise array, which can be a Promise or a constant or other; the execution status is: the result will be returned after all the Promises in the Promise are executed;

    5.2  What if one of the Promises reports an error?

        Answer : If an error is reported, the entire Promise.all( ) will return a catch

    5.3  If a Promise reports an error, will other Promises still execute?

        Answer : Yes, because Promise has been executed at the beginning of creation (instantiation)

    5.4 Writing a Promise.all( ) by hand

        Interviewer : "Give you three Promises as follows, after calling your Promise.all() , see if the corresponding result will be returned within three seconds"        

// 测试
const pro1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("1");
  }, 1000);
});
const pro2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("3");
  }, 2000);
});
const pro3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("3");
  }, 3000);
});

// 测试题
const PromiseAll = (promiseArray) => {};

     How to achieve?

        Test point 1: The parameter in Promise.all() may not be a Promise , how to deal with it?

        Test point 2: The order of the return values ​​of Promise.all( ) is the order of the Promise you passed in . How to deal with it?

// 测试题
const PromiseAll = (promiseArray) => {
  return new Promise((resolve, reject) => {
    if (!Array.isArray(promiseArray)) {
      return reject(new Error("Type can only be array"));
    }
    const result = []; // promise 执行的结果集
    const promiseNums = promiseArray.length; // 当前循环次数
    let counter = 0; // 记录当前 promise 执行顺序,需要按照 传入的 promise 顺序返回
    for (let i = 0; i < promiseNums; i++) {
      Promise.resolve(promiseArray[i])
        .then((value) => {
          counter++;
          result.push(value);
          if (counter === promiseNums) {
            resolve(result);
          }
        })
        .catch((e) => reject(e));
    }
  });
};

console.log(
  PromiseAll([pro1, pro2, pro3])
    .then((res) => {
      console.log(res);
    })
    .catch((e) => {
      console.log(e);
    })
);

    5.5 Promise has been executed during initialization, so what can we do with this feature (extensibility issue)?

         Answer : You can use this feature of promise for caching;

        Use the decorator + Map structure to implement a Promise cache ;

const cacheMap = new Map();
const enableCache = (target, name, descriptor) => {
  const val = descriptor.value;
  descriptor.value = async (...args) => {
    const cacheKey = name + JSON.stringify(args);
    if (!cacheMap.get(cacheKey)) {
      const cacheValue = Promise.resolve(val.apply(this, args)).catch((_) => {
        cacheMap.set(cacheKey, null);
      });
      cacheMap.set(cacheKey, cacheValue);
    }
    return cacheMap.get(cacheKey);
  };
  return descriptor;
};
class PromiseClass {
  @enableCache
  static async getInfo() {}
}

PromiseClass.getInfo(); // 第一次发送请求
PromiseClass.getInfo(); // 第二次以后就是缓存
PromiseClass.getInfo();
PromiseClass.getInfo();

 6. Byte Classical Algorithm Problem---- Receiving Rainwater

Question stem:

        Given n non-negative integers representing the height map of each column with a width of 1, calculate how much rainwater can be received by the columns arranged in this way after it rains.

        Example 1:

        Enter height = [0,1,0,2,1,0,1,3,2,1,2,1]

        Output : 6

        Explanation : The above is a height map represented by the array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, it can receive 6 units of rainwater (as above Figure, the blue part represents rainwater)

        Example 2:

        Enter height = [4,2,0,3,2,5]

        Output : 9

Guess you like

Origin blog.csdn.net/weixin_56650035/article/details/123163419