Hello, I am river, because working reason, long time no update public articles, many students WeChat I private chat, don’t update to refund powder, it suddenly jumped up, hurriedly brought you a good letter, I also have been her collection of interview questions with answers to some classic algorithms, share with you.

Write a Promise

This is an old question to be honest, but a lot of companies ask it, and a lot of the front end doesn’t come out

function Promise(callback){
    const pending = 'pending';
    const fulfilled = 'fulfilled';
    const rejected = 'rejected';
    // The current state
    this.state = pending;
    / / the current value
    this.value = null;
    // Failure cause
    this.reason = null;
    // The success and failure array objects
    this.fulfilledCallback = [];
    this.rejectedCallback = [];

    // Processing succeeded
    this.resolve = (data) = >{
        setTimeout(() = >{
            if(this.state == pending){
                this.state = fulfilled;
                this.value = data;
                this.fulfilledCallback.map(fn= >fn(this.value)); }})}// Failure handling
    this.reject = (reason) = >{
        setTimeout(() = >{
            if(this.state == pending){
                this.state = rejected;
                this.reason = reason;
                this.rejectedCallback.map(fn= >fn(this.reason)); }})}// Capture success and failure and throw them into the success and failure array
    this.then = function(succesFn,errorFn){
        this.fulfilledCallback.push(succesFn);
        this.rejectedCallback.push(errorFn);
    }
    // Catch the exception and throw it directly into the exception array
    this.catch = (errorFn) = >{
        this.rejectedCallback.push(errorFn);
    }
    // The default is to execute resolve and reject once
    callback(this.resolve,this.reject);
}

// Verify the result
new Promise((resolve,reject) = >{
    setTimeout(() = >{resolve(10); },1000)
}).then((data) = >{
    console.log(data);
},(error) = >{
    console.log(error);
})
Copy the code

Notes:

  • Promise exposes the THEN /catch method
  • The Promise constructor receives a callback function that executes immediately
  • Then /catch is only responsible for putting the callback into the array
  • Resolve /reject is responsible for execution
  • Add a macro task to resolve/reject (setTimeout)

Compose composition function implementation

  1. The latter function takes an argument to the previous function
  2. The last function can take multiple arguments; the previous function can only take a single argument; The return value of the latter is passed to the former
// Demo:
const add = num= > num  + 10
const multiply = num= > num * 2
const foo = compose(multiply, add)
foo(5) = >30
Copy the code
// Aggregate function
export default function compose(. funcs) {
  // If null, return the null function and take an argument
  if (funcs.length === 0) {
    return arg= > arg
  }
  // If there is one, execute it and return the result
  if (funcs.length === 1) {
    return funcs[0]}// If you are not familiar with Reduce, read the technical article first
  return funcs.reduce((a, b) = > (. args) = >a(b(... args))) }Copy the code

Notes:

  • Compose is an aggregate function
  • Compose returns a function when it executes (so that’s why func.length==0, return an arrow function)
  • Reduce always returns an arrow function, and the latter function executes first and takes the result as an argument to the previous function, and so on

Curry (sum)

Ali Interview questions

Achieve the following effect: sum(1.3).sumOf()  4
sum(1.3) (2.4).sumOf() 10
Copy the code
function sum(){
    var arr = [].slice.apply(arguments);
    var fn = function(){
        arr = arr.concat([].slice.apply(arguments))
        return fn;
    }
    fn.sumOf = function(){
        return  arr.reduce((total,num) = >total+num,0);
    }
    return fn;
}
Copy the code

Implement a LazyPig

Ali Interview questions

Implement a LazyPig, which can be called as follows:

LazyPig("Peggy") 
/ / output:> Hello, I'm Peggy! LazyPig("Peggy").sleep(10).eat("dinner") // output > Hello, I'M Peggy!// Wait 10 seconds...
Wake up after 10
Eat dinner~
Copy the code
function LazyPig(name){
    console.log(`Hello,I'm ${name}`)
    var fn = {}
    fn.sleep = function(time){
        console.log(`Wake up ${time}`)
        let start = Date.now()
        while(Date.now()-start<=time){}
        console.log(`Wake up down`)
        return fn;
    }
    fn.eat = function(food){
        console.log(`Eat ${food}`)
        return fn;
    }
    return fn;
}
Copy the code

Array flattening

let list = [1.5[9.8], [2[1.9]], 7];
// The first method:
console.log(list.toString().split(', '));

// The second method:
function flatten(list) {
    return list.reduce((prev, item) = > {
        return prev.concat(Array.isArray(item) ? flatten(item) : item); }}, [])console.log(flatten(list));
Copy the code

The object is flattened

/** * Flatten (input); /** * Flatten (input); /** * Flatten (input); Var input = {* example: * * a: 1, * b: [1, 2, {c: true}, [3]], * d: {e: 2 f, 3}, * g: null, * } * var output = flatten(input); * the output as follows * {* "a" : 1, * "b [0]" : 1, * [1] "b" : 2, * "b [2]. The c" : true, * "b [3] [0]" : 3, * "d.e" : 2, * "d.f" : 3, * / / "g" : Null, null or undefined, discard *} */Answer:` ``js let result = {}; var flatten = (data, key) => { if (data instanceof Array) { data.forEach((param, index) => { if (param instanceof Object) { flatten(param, `${key}[${index}]`); } else { result[`${key}[${index}]`] = param; }}); } else if (data instanceof Object) { for (var itemKey in data) { const itemValue = data[itemKey]; if (itemValue instanceof Object) { flatten(itemValue, itemKey); } else if (itemValue) { if (key) { result[`${key}.${itemKey}`] = flatten(itemValue, itemKey); } else { result[itemKey] = itemValue; } } } } else { return data; }}; flatten(input); console.log(result)Copy the code

Array to Tree

// Convert the array to a Tree
var list = [
    {
        id: 1.name: 'jack'.pid: 0
    },
    {
        id: 2.name: 'jack'.pid: 1
    },
    {
        id: 3.name: 'jack'.pid: 1
    },
    {
        id: 4.name: 'jack'.pid: 2},]const getTree = (root, result, pid) = > {
    for (let i = 0; i < root.length; i++) {
        if (root[i].pid == pid) {
            letitem = { ... root[i],children: [] }
            result.push(item)
            getTree(root, item.children, item.id)
        }
    }
}

let array = [];
getTree(list, array, 0)
console.log(JSON.stringify(array))
Copy the code

Object deep copy

// Object deep clone
let obj = {
    name: 'jack'.age: 10.fn: () = > {
        return this.name;
    },
    list: ['fe'.'node'.'small'].all: {
        child: true}}// method 1 :(the interviewer doesn't want it)
JSON.parse(JSON.stringify(obj))
// Method 2:
function deepClone(obj){
    let result;
    if(typeof obj === 'object'){
        result = Array.isArray(obj) ? [] : {}
        for(let i in obj){
            result[i] = typeof obj[i] === 'object'? deepClone(obj[i]):obj[i]; }}else{
        result = obj;
    }
    return result;
}
Copy the code

Greedy algorithm (change)

The shop owner had 1, 2, 5, and 10 notes. The guy bought something for 100 and spent 80. He figured out the best way to make change.

function MinCoinChange(coins) {
  return function(amount) {
    let total = 0, change = []
    for(let i= coins.length; i>=0; i--) {
      let coin = coins[i]
      while(total + coin <= amount) {
        change.push(coin)
        total += coin
      }
    }
    return change
  }
}

MinCoinChange([1.2.5.10]) (20) returns:10.10
Copy the code

Array deduplicate (deduplicate more than twice)

Routine to major home all know Set

// We know the array
var arr = [1.1.1.1.1.1.1.3.3.3.3.3.5.5];
/ / method
function delRepeat(){
    arr = arr.sort();/ / first order
    for(let i=0; i<arr.length; i++){if(arr[i] == arr[i+2]){
            arr.splice(i,1); i--; }}return arr;
}
/ / method 2
function delRepeat(){
    var newArr = [];
    var obj = {};
    arr.map(item= >{
        if(obj[item]){
            obj[item] +=1 ;
        }else{
            obj[item] = 1;
        }
        obj[item]<=2? newArr.push(item):' '
    })
    return newArr;
}
Copy the code

Large number addition algorithm

The sum of large numbers has many forms of examination questions, there are integer, decimal, square root, etc.

Let a =” 12345.12123″,b=”987654.92″;

function sum(a,b){
    let arr1 = a.split(' '),arr2 = b.split(' ');
    let count = 0;
    let arr = [];
    let a1 = a.split('. ') [1],b1 = b.split('. ') [1];
    let len = a1.length - b1.length;
    if(len>0) arr2. Push ('0'. Repeat (len))if(len<0) arr1. Push ('0'. Repeat (Math.abs(len)))
    while(arr1.length || arr2.length){
        let m = arr1.pop() || 0,n = arr2.pop() || 0;
        if(m ! ='. ') {let num = Number(m) + Number(n) + count;
            if(num > 9){
                count = 1;
                num%=10;
            }else{
                count = 0;
            } 
            arr.unshift(num);
        }else{
            arr.unshift('. '); }}if(count>0)arr.unshift(count);
    let res = arr.join(' ');
    console.log(res);
}
Copy the code

If it’s a positive integer, BigInt is easier to handle

Binary tree summation

var treenode = {
    value: 1.left: {
        value: 2.left: {
            value: 4,},right: {
            value: 5.left: {
                value: 7,},right: {
                value: 8,}}},right: {
        value: 3.right: {
            value: 6,,}}}function sum(root) {
    let list = []
    if (root) list.push(root.value);
    if (root.left) {
        list = list.concat(sum(root.left));
    }
    if (root.right) {
        list = list.concat(sum(root.right));
    }
    return list;
}
console.log(sum(treenode));
Copy the code

Climb the stairs

/* Suppose you are climbing the stairs. It takes you n steps to get to the top. You can climb one or two steps at a time. How many different ways can you climb to the top of the building? Thinking: f (1) : 1 f (2) : 11, 2 f (3) : 12, 111, 21 (4) : f 121, 1111, 211, 112, 22 f (n) = f (n - 1) + f (n - 2) * /
function fn(n) {
    if (n == 1) return 1;
    if (n == 2) return 2;
    return fn(n - 1) + fn(n - 2);
}
console.log(fn(4))
Copy the code

Simple template engine

const template = 'Hi, {{info.name.value}} Hello, it's the week {{day.value}}';

const data = {
    info: {
        name: {
            value: 'Joe'}},day: {
        value: '三'}};function render(template, data) {
    return template.replace(/{{\s+? ([\w.]+)\s+? }}/g.function ($0, $1) {
        return eval(`data.The ${$1}`)})}const result = render(template, data); 
// Hi, Zhang SAN. Today is Wednesday
console.log(result)
Copy the code

The front end simulates concurrent requests

Given that there are currently 100 requests and only five can be called at the same time, design a concurrent function.

function send(){
    // Initialize the array
    let list = Array.from({length:100}).map((k,i) = >i)
    // Maximum number of concurrent requests
    const limit = 5;
    
    // Define an asynchronous function
    const asyncGet =async (item)=>{
       return item;
    }
    // Initializes 100 asynchronous request functions. When the closure is executed, one request is executed, and when the request is completed, the next request is retrieved and executed
    const arr = []
    const handlers = () = >{
        list = list.map(item= >{
            return () = >{
                return asyncGet(item).then((res) = >{
                    console.log('res:'+res)
                    let next = list.shift();
                    if(next){
                        next()
                    }else{
                        console.log('All executed')
                    }
                })
            }
        })
    }
    
    handlers();
    // Fetch the maximum number of concurrent requests at one time and execute
    for(let i=0; i<limit; i++){let fn = list.shift();
        arr.push(fn())
    }
    
    Promise.all(arr).then((res) = >{
        
    })
}

send();
Copy the code

Shaking and throttling (the classic closure case)

/* Shake: definition: triggers only once within a specified period of time. If you call it again within a specified period of time, it will be cleared and continue to create a new task. Scene: Duc.onresize or onScroll, or search box */
function debounce(fn, wait) {
    var timeout = null;
    return function() {
        if(timeout ! = =null) {clearTimeout(timeout);
                timeout = setTimeout(fn, wait);
        }else{
             timeout = setTimeout(fn, wait); }}}window.addEventListener('scroll', debounce(() = >{
// TO-DO
}, 500));
/* Throttling: triggers only once for a fixed time. Scenario: Search box */
function throttle(fn,delay){
    let valid = true
    return function() {
       if(! valid){// No guests during the rest time
           return false 
       }
       // Work time, execute the function and set the status bit to invalid during the interval
        valid = false
        setTimeout(() = > {
            fn()
            valid = true;
        }, delay)
    }
}
Copy the code

Above is the front algorithm interview questions for you to sort out and share, not from the Internet to find at will, many of them are my experience and friends interview, I hope to help you.

Focus on the front end, focus on the future, I am your little front end helper: front end future