Before you write

I want to tell you why I wrote it. Although I have three years of experience, all of them are small factories. Although I am longing for them, I have little chance before. I am trying to rush into a big factory at the critical point of just three years. Then I received the interview opportunity of a big factory. Well, I failed in the end, but I think I have gained a lot, which is the first step towards a big factory. Without going through the process, just talk about the interview questions and feel the difference from the previous interview.

Some questions for the interview

What are the semantics of HTML5’s new tags, Section and article

“Section” means a functional area, “article” means a specific content, and “article” means a specific content.

The section element represents a generic section of a document or application. A section, in this context, is a thematic grouping of content, typically with a heading.

The article element represents a complete, or self-contained, composition in a document, page, application, or site and that is, in principle, independently distributable or reusable, e.g. in syndication. This could be a forum post, a magazine or newspaper article, a blog entry, a user-submitted comment, an interactive widget or gadget, or any other independent item of content.

When article elements are nested, the inner article elements represent articles that are in principle related to the contents of the outer article. For instance, a blog entry on a site that accepts user-submitted comments could represent the comments as article elements nested within the article element for the blog entry.

Author information associated with an article element (q.v. the address element) does not apply to nested article elements.

The section element represents a general section of the document, which is an area divided by topic, usually with a heading. An article represents a complete or self-contained combination of documents, pages, applications, or sites that can be distributed independently or reused. For example, an article can represent a forum post, a magazine or newspaper article, a blog entry, user-submitted comments, an interactive widget or gadget, or any other stand-alone content. An internally nested article also needs to be associated with the external article content. Instead of using article for author-related information, use the Address element.

The precedence of CSS selectors and which of the elements with an ID attribute and 10 class attributes takes precedence when declaring CSS

We all know the precedence of CSS selectors: ID selectors > class selectors, attribute selectors, pseudo-class selectors > tag selectors, pseudo-element selectors > general selectors. So which selector, describing an ID and 10 classes above, has a higher priority?

I was a little confused because I answered that id represents priority 100 and class represents priority 10, so should the 10 classes theoretically be able to replace ID? I don’t think it makes a lot of sense. The precedence of 100 and 10 is specified from left to right. That is to say, an id selector has 100 values and is written as 0,1,0,0. Ten class selectors have 100 values and are written as 0,0,100,0. From left to right, 0,1,0,0 is always greater than 0,0,100,0, and no number of class selectors can be carried, so that one id selector has a higher priority than any number of class selectors.

Using the function returned by bind as a constructor, what does this refer to

Here is an understanding of the bind implementation, so let’s look at how the bind method is implemented:

Function.prototype.myBind = function(context, args) {
  const self = this;
  const params = Array.prototype.slice.call(arguments.1);
  function FNO() {}
  function Fn() {
    const bindParams = Array.prototype.slice.call(arguments);
    // If this is currently an instance of a function, the function is used as a constructor, so its context refers to the instance, otherwise the context is the specified context
    return self.call(this instanceof Fn ? this : context, params.concat(bindParams));
  }

  FNO.prototype = this.prototype;
  Fn.prototype = new FNO();

  return Fn;
}
Copy the code

The problem becomes obvious with this implementation. If bind returns a function called as a constructor, this does not refer to the set this, but to an instance of the constructor. We can use an example to prove it:

var obj = {
    name: 'qiugu'
};

function Person(age) {
    this.age = age;
}

// Note that new is followed by parentheses, otherwise an error will be reported because person. bind cannot be called as a constructor
const p = new (Person.bind(obj, 20));
console.log(p);

Copy the code

Okay, so that’s clear, because bind is implemented, you can also see that when called as a constructor, this instanceof Fn, this points to an instanceof that constructor.

What does the constructor of the new call return, if any, or if the return value is an object or underlying type

Here, again, the key is to know an implementation of new. Let’s review the implementation of new:

function objFactory(fn, ... args) {
  // Generate an empty object
  const obj = new Object(a);// Link the object's prototype to the constructor's prototype. Doing so gives the object access to the property methods on the constructor's prototype
  obj.__proto__ = fn.prototype;
  // Execute the constructor to point the context to the newly created object using call, thus accessing the property methods on this
  constres = fn.call(obj, ... args);If the constructor returns a value, we need to determine whether the type of the return value is an object. If it is an object, we need to return the object
  // If it is a base type, the created object is returned
  return typeof res === 'object' ? res : obj;
}
Copy the code

So the answer is also obvious, so sometimes, the interviewer may not directly ask you how to implement new, you may have memorized, you may have seen, changing the way is more to prove that you really understand the principle.

A method to remove the weight of an array

This one is easier, but if you want to make your interviewer more satisfied, you should understand all of the following (whisper bb: I remember three at the time).

  1. Double for loop
function unique(arr) {
  if (!Array.isArray(arr)) return;
  let res = arr[0];
  for(let i = 1; i < arr.length; i++) {
    let flag = true;
    for(let j = 0; j < res.length; j++) {
      flag = true;
      if (arr[i] === res[j]) break;
    }
    if (flag) res.push(arr[i]);
  }
  return res;
}
Copy the code
  1. indexOf
function unique(arr) {
  if (!Array.isArray(arr)) return;
  let res = [];
  for(let i = 0; i < arr.length; i++) {
    if (res.indexOf(arr[i]) === -1) { res.push(arr[i]); }}return res;
}
Copy the code
  1. filter
function unique(arr) {
  if (!Array.isArray(arr)) return;
  return arr.filter((item, index) = > arr.indexOf(item) === index);
}
Copy the code
  1. sort
function unique(arr) {
  if (!Array.isArray(arr)) return;
  arr.sort();
  let res = [];
  for(let i = 0; i < arr.length; i++) {
    if(arr[i] ! == arr[i-1]) res.push(arr[i]);
  }
  return res;
}
Copy the code
  1. reduce
function unique(arr) {
  if (!Array.isArray(arr)) return;
  return arr.reduce((prev, cur) = > {
    returnprev.includes(cur) : prev : [...prev, cur]; } []); }Copy the code
  1. Set
function unique(arr) {
  if (!Array.isArray(arr)) return;
  return [...new Set(arr)];
}

// We can also use array. from to convert a Set to an Array
function unique(arr) {
  if (!Array.isArray(arr)) return;
  return Array.from(new Set(arr));
}

Copy the code
  1. Use objects or maps to remove weights
function unique(arr) {
  if (!Array.isArray(arr)) return;
  let obj = {}, res = [];
  for(let i = 0; i < arr.length; i++) {
    if(! obj[arr[i]]) { res.push(arr[i]); obj[arr[i]] =1;
    } else{ obj[arr[i]]++; }}return res;
}
Copy the code

Reference source

The difference between any and unknown in TypeScript

I have used TS, but I have not used unknown, so I did not answer. I went back and looked over the materials.

Any is the parent or subclass of any type and is not type safe. What is type unsafe? If we’re too lazy to write a definition, we’ll just say any and let the compiler ignore checking for values of type any. This can lead to unexpected errors that are hard to troubleshoot. Unknown is type safe and can be assigned to any value. However, when we use it to perform some operations, such as calling a value of unknown type as a method, the compiler will report an error, because you are not sure whether the variable is a method or not, so it cannot be called. You need to make sure it can be called before you call it.

let fn:unknown = () = > {};
if(typeof fn === 'function') {
    fn();
}
Copy the code

The compiler will not report an error if you call it at this time, so it is type-safe.

Hooks implementation, and why it is implemented this way. How is the state of useState stored

React source code implementation, I only read some analysis of the article, the actual lack of in-depth understanding.

Hooks are implemented in linked lists, so putting Hooks in the criteria would break the structure of the linked list. The linked list structure is also based on the linked list itself. Linked lists have low space requirements and do not need continuous space, so the operation efficiency of adding and deleting linked lists is high. As for how useState stores state, We know that React uses Fiber as a structure to store component state, so the state in useState is also stored on the corresponding Fiber of the node.

A minimalist implementation of Hooks

Handwritten implementation of EventEmit

This problem has not been done, although there is understanding, but did not pay attention to its implementation, behind the serious look at its implementation, and then write again, to understand its implementation principle.

function EventEmit() {
  this.listeners = {};
}

EventEmit.prototype.on = function(eventName, cb) {
  // Since events can be registered repeatedly, we need an array to store the queue for event callbacks
  if (!this.listeners[eventName]) {
    this.listeners[eventName] = [cb];
  } else {
    this.listeners[eventName].push(cb);
  }
}

EventEmit.prototype.once = function(eventName, cb) {
  if (!this.listeners[eventName]) {
    this.listeners[eventName] = [cb];
  } else {
    this.listeners[eventName].push(cb);
  }
  // Use a flag to indicate that this is a one-time event callback
  this.listeners[eventName].once = true;
}

EventEmit.prototype.off = function(eventName) {
  if (this.listeners[eventName]) {
    this.listeners[eventName] = null;
  }
}

EventEmit.prototype.emit = function(eventName, args) {
  if (this.listeners[eventName]) {
    this.listeners[eventName].forEach(fn= > fn.apply(this, args));
    // If this is a one-time event, destroy the event after execution
    if (this.listeners[eventName].once) this.off(eventName); }}Copy the code

Algorithm problem

/** * Divide the day into 48 segments, each of which is half an hour, and use a 48-bit bitmap to represent multiple working hours in the day. Calculate the effective working time a day * enter '110011100000000000000000111100000000000000000000' * output [' 00:00-01:00 ', '2:00-03:30', '12:00-2:00] * /
function solution(bitmap) {
    let p = 0, res = [], ans = [];
    for(let i = 0; i < bitmap.length; i++) {
        if (bitmap[i] === '0') p++;
        else if (bitmap[i] === '1' && (bitmap[i+1= = ='0'| |! bitmap[i+1])) {
            res.push([p, i]);
            p = i+1; }}const format = (left, right) = > {
        const timeZone = new Date().getTimezoneOffset() * 60 * 1000;
        const leftTime = new Date(left / 2 * 60 * 60 * 1000 + timeZone);
        const leftHours = leftTime.getHours() < 10 ? '0' + leftTime.getHours() : leftTime.getHours() + ' ';
        const leftMinus = leftTime.getMinutes() < 10 ? '0' + leftTime.getMinutes(): leftTime.getMinutes() + ' ';
        const leftStr = `${leftHours}:${leftMinus}`;
        const rightTime = new Date((right / 2 + 0.5) * 60 * 60 * 1000 + timeZone);
        const rightHours = rightTime.getHours() < 10 ? '0' + rightTime.getHours() : rightTime.getHours() + ' ';
        const rightMinus = rightTime.getMinutes() < 10 ? '0' + rightTime.getMinutes(): rightTime.getMinutes() + ' ';
        const rightStr = `${rightHours}:${rightMinus}`;
        return [leftStr, rightStr];
    }
    for(let i = 0; i < res.length; i++) {
        const item = format(res[i][0], res[i][1]);
        ans.push(item);
    }
    return ans;
}
console.log(solution('110011100000000000000000111100000000000000000011'));

Copy the code

This problem is behind their own to do, the implementation of the idea is the above 48 bits of bitmap, into such a structure

// Each subarray stores the corresponding index range of 1
[[0.1], [4.6], [24.27]]
Copy the code

Therefore, how to change into such a structure is the key to this problem. Although I have written 200 questions, I still ignore the process of thinking, which is also the deepest feeling of this time.

Wrote last

I have sorted out some API implementation code and put it here

These are just part of the interview, and is their answer is not good enough or is not answered, the general feeling is: not you will be ok, but also need to really understand, the so-called true understanding is no matter how the topic changes, the principle or those, only really understand the principle, will not be asked.

As for the algorithm, I also refer to the learning methods of many community leaders, classification and brush questions, but I still ignore some things, such as the process of thinking, how to deduce, whether there are other methods and so on, rather than to see if the answer is correct. So in fact, brushing questions is not to enable us to have enough experience in the number of questions, but to cultivate the thinking process of solving problems. What we should care about is how to think and whether we can solve problems in a different way if the thinking is incorrect.

Finally, I hope this article can give you are preparing for the interview partners some experience and thinking.