Summary of front-end pen test questions in winter 2020

Original address: Some great interview questions [4]

Recently, I interviewed some companies and got some offer s. I don't record concept questions, but only coding questions.
In their spare time, they can do these problems and practice their hands.

Graffiti intelligence will recruit a large number of people in 2021. There are vacancies in front-end, Java, Android, iOS, Go and test! There are many other positions that can be selected in this link https://job.tuya.com/#carrers

Note: just send your resume to my email: gaokai20100801@qq.com Wechat for details: gaokai20100801

  • A number that appears only once
  • Summary interval
  • Achieve traffic light effect
  • Array de duplication
  • Return excel table column name
  • Detect empty objects
  • Achieve a+a+a print 'abc'
  • Implement an Event module
  • Large integer addition
  • SuperPerson inherits from Person
  • Hide part of string
  • Implement a sum(1,2,3)(4)(5)(6,7)(8)()
  • Implement an upgraded version of sum(1,2,3)(4)(5)(6,7)(8)(): how to add, subtract, multiply and divide?

A number that appears only once

Given a non empty array of integers, each element appears twice except that one element appears only once. Find the element that appears only once.
Example 1:

Input: [2,2,1]
Output: 1
Example 2:

Input: [4,1,2,1,2]
Output: 4
This is a simple and difficult problem of leetcode.
Title: leetcode 136 is a number that appears only once
Solution: 136 numbers that appear only once

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function (nums) {
  /** Solution 1: violent traversal
   *  Performance: 704ms 40.5MB
   */
  let numsSet = Array.from(new Set(nums));
  let numsMap = numsSet.map((num) => ({
    num,
    count: 0,
  }));
  nums.forEach((num, i) => {
    numsMap.forEach((numM, j) => {
      if (numM.num === num) {
        numM.count++;
      }
    });
  });
  let filterArr = numsMap.filter((num) => num.count === 1);
  return filterArr[0].num;
  /** Solution 2: Set appears add for the first time and delete for the second time
   *  Performance: 72 ms 38MB
   */
  let numsSet = new Set();
  for (let i = 0; i < nums.length; i++) {
    if (!numsSet.has(nums[i])) {
      numsSet.add(nums[i]);
    } else {
      numsSet.delete(nums[i]);
    }
  }
  return [...numsSet][0];
};

Summary interval

Given an out of order shaping array [0,1,7,13,15,16,2,4,5], find out the continuous number interval as follows: ["0 - > 2", "4 - > 5", "7", "13", "15 - > 16"]
This is a leetcode medium difficulty problem.
Title: leetcode 228 summary interval
Solution: 228 summary ranges

function continuous(arr) {
  arr.sort((a, b) => a - b);
  let stack = [];
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    if (stack.length === 0 || arr[i] - stack[stack.length - 1] === 1) {
      stack.push(arr[i]);
    } else {
      if (stack.length > 1) {
        result.push(`${stack[0]}->${stack[stack.length - 1]}`);
      } else {
        result.push(`${stack[0]}`);
      }

      stack = [];
      stack.push(arr[i]);
    }
    if (i === arr.length - 1) {
      if (stack.length > 1) {
        result.push(`${stack[0]}->${stack[stack.length - 1]}`);
      } else {
        result.push(`${stack[0]}`);
      }
    }
  }
  return result;
}
console.log(continuous([0, 1, 7, 13, 15, 16, 2, 4, 5]));

To achieve the traffic light effect, use the console to output "red", "green" and "yellow" signals, and the waiting time is 3s, 2s and 1s respectively

function trafficCtrl() {
  // Yellow 0 ~ 4 timeline
  const borders = { red: 3, green: 5, yellow: 6 };
  let current = 0;
  setInterval(() => {
    if (current >= 0 && current <= 2) {
      console.log('red', borders.red - current);
    } else if (current >= 3 && current <= 4) {
      console.log('green', borders.green - current);
    } else {
      console.log('yellow', borders.yellow - current);
    }
    current++;
    if (current > 5) {
      current = 0;
    }
  }, 1000);
}

trafficCtrl();

Red 3
Red 2
Red 1
Green 2
Green 1
Yellow 1
Red 3
Red 2
...

Array de duplication

Input:
['1', '2', '3', 1, '2', undefined, undefined, null, null, 1, 'a','b','b'];
Output:
["1", "2", "3", 1, undefined, null, "a", "b"]

// Solution 1: includes
function removeDuplicate(arr) {
    const result = [];
    for(const item of arr){
       if(!result.includes(item)) result.push(item);
    }
    return result;
}
// Solution 2: Map
function removeDuplicate(arr) {
     const map = new Map();
    for(const item of arr){
       if(!map.has(item)) map.set(item, true);
      }
     const result = [...map.keys()];
    return result;
}
// Solution 3: collision pointer
function removeDuplicate(arr) {
     const map = new Map();
     let i = 0;
     let j = arr.length - 1;
     while(i<=j){
  	      if(!map.has(arr[i])) map.set(arr[i], true);
  	      if(!map.has(arr[j])) map.set(arr[j], true);
  	      i++;
  	      j--;
     }
     const result = [...map.keys()];
          return result;
}
// Solution 4: filter
function removeDuplicate(arr) {
    return arr.filter((item, i)=> arr.indexOf(item) === i)
}

Write a function to return the column name of excel table

Input: 1 output: A
B: output 2
Input: 26 output: Z
Input: 27 output: AA
Input: 52 output: AZ

This is a simple and difficult problem of leetcode.
Title: leetcode 168 Excel table column name
Solution: 168 Excel table column name

function getExcelColumn(column) {
    const obj = {};
    let i = 0;
    const startCode = "A".charCodeAt();
    while (i < 26) {
        obj[i + 1] = String.fromCharCode(startCode + i);
        i++;
    }
    if (column <= 26) {
        return obj[column]
    }
    const stack = [];
    const left = column % 26;
    const floor = Math.floor(column / 26);

    if (left) {
        stack.unshift(obj[left])
        stack.unshift(obj[floor]);
    } else {
        stack.unshift('Z')
        stack.unshift(obj[floor - 1]);
    }
    const result = stack.join("");
    return result;
}

How to detect an empty object

// Solution 1: object prototype. toString. Call and JSON stringify
function isObjEmpty(obj){
    return Object.prototype.toString.call(obj)==="[Object object]" && JSON.stringify({}) === "{}";
}
// Solution 2: object keys() Object. values()
function isObjEmpty(obj){
    return Object.keys(obj).length === 0 || Object.values(obj).length === 0;
}
// Solution 3: for in
function isObjEmpty(obj){
    for(key in obj){
        if(key) return false
    }
    return true;
}

Achieve a+a+a print 'abc'

console.log(a + a + a); // Print 'abc'

// Topic 1
/*
  console.log(a + a + a); // Print 'abc'
*/

/**
 * Solution 1: object Defineproperty() external variable
 */
let value = "a";
Object.defineProperty(this, "a", {
  get() {
    let result = value;
    if (value === "a") {
      value = "b";
    } else if (value === "b") {
      value = "c";
    }
    return result;
  },
});
console.log(a + a + a);
/**
 * Solution 1 (optimized version): object Defineproperty() internal variable
 */
Object.defineProperty(this, "a", {
  get() {
    this._v = this._v || "a";
    if (this._v === "a") {
      this._v = "b";
      return "a";
    } else if (this._v === "b") {
      this._v = "c";
      return "b";
    } else {
      return this._v;
    }
  },
});
console.log(a + a + a);

/**
 * Solution 2: object prototpye. valueOf()
 */
let index = 0;
let a = {
  value: "a",
  valueOf() {
    return ["a", "b", "c"][index++];
  },
};
console.log(a + a + a);

/**
 * Solution 3: charCodeAt, charFromCode
 */
let code = "a".charCodeAt(0);
let count = 0;
Object.defineProperty(this, "a", {
  get() {
    let char = String.fromCharCode(code + count);
    count++;
    return char;
  },
});
console.log(a + a + a); // 'abc'

/**
 * Solution 3 (optimized version I): internal variable this_ Count and_ code
 */
Object.defineProperty(this, "a", {
  get() {
    let _code = "a".charCodeAt(0);
    this._count = this._count || 0;
    let char = String.fromCharCode(_code + this._count);
    this._count++;
    return char;
  },
});
console.log(a + a + a); // 'abc'

/**
 * Solution 3 (optimized version 2): internal variable this_ code
 */
Object.defineProperty(this, "a", {
  get() {
    this._code = this._code || "a".charCodeAt(0);
    let char = String.fromCharCode(this._code);
    this._code++;
    return char;
  },
});
console.log(a + a + a); // 'abc'

/*
 Title Extension: print ` a z`
 a+a+a; //'abc'
 a+a+a+a; //'abcd'
*/
/**
 * charCodeAt,charFromCode
 */
let code = "a".charCodeAt(0);
let count = 0;
Object.defineProperty(this, "a", {
  get() {
    let char = String.fromCharCode(code + count);
    if (count >= 26) {
      return "";
    }
    count++;
    return char;
  },
});
// Print 'abc'
console.log(a + a + a); // 'abc'

// Print 'abcd'
let code = "a".charCodeAt(0);
let count = 0;
// {... Define a...}
console.log(a + a + a); // 'abcd'

// Print 'abcdefghijklmnopqrstuvwxyz'
let code = "a".charCodeAt(0);
let count = 0;
// {... Define a...}
let str = "";
for (let i = 0; i < 27; i++) {
  str += a;
}
console.log(str); // "abcdefghijklmnopqrstuvwxyz"

/*
 Title Extension (optimized): print ` a z`
 a+a+a; //'abc'
 a+a+a+a; //'abcd'
*/

Object.defineProperty(this, "a", {
  get() {
    this._code = this._code || "a".charCodeAt(0);
    let char = String.fromCharCode(this._code);
    if (this._code >= "a".charCodeAt(0) + 26) {
      return "";
    }
    this._code++;
    return char;
  },
});
// Print 'abc'
console.log(a + a + a); // 'abc'

Implement an Event module

/**
 * Description: simply implement an event subscription mechanism, with methods of listening on and triggering emit
 * Example:
 * on(event, func){ ... }
 * emit(event, ...args){ ... }
 * once(event, func){ ... }
 * off(event, func){ ... }
 * const event = new EventEmitter();
 * event.on('someEvent', (...args) => {
 *     console.log('some_event triggered', ...args);
 * });
 * event.emit('someEvent', 'abc', '123');
 * event.once('someEvent', (...args) => {
 *     console.log('some_event triggered', ...args);
 * });
 * event.off('someEvent', callbackPointer); // callbackPointer It is a callback pointer and cannot be an anonymous function
 */

class EventEmitter {
  constructor() {
    this.listeners = [];
  }
  on(event, func) {
    const callback = () => (listener) => listener.name === event;
    const idx = this.listeners.findIndex(callback);
    if (idx === -1) {
      this.listeners.push({
        name: event,
        callbacks: [func],
      });
    } else {
      this.listeners[idx].callbacks.push(func);
    }
  }
  emit(event, ...args) {
    if (this.listeners.length === 0) return;
    const callback = () => (listener) => listener.name === event;
    const idx = this.listeners.findIndex(callback);
    this.listeners[idx].callbacks.forEach((cb) => {
      cb(...args);
    });
  }
  once(event, func) {
    const callback = () => (listener) => listener.name === event;
    let idx = this.listeners.findIndex(callback);
    if (idx === -1) {
      this.listeners.push({
        name: event,
        callbacks: [func],
      });
    }
  }
  off(event, func) {
    if (this.listeners.length === 0) return;
    const callback = () => (listener) => listener.name === event;
    let idx = this.listeners.findIndex(callback);
    if (idx !== -1) {
      let callbacks = this.listeners[idx].callbacks;
      for (let i = 0; i < callbacks.length; i++) {
        if (callbacks[i] === func) {
          callbacks.splice(i, 1);
          break;
        }
      }
    }
  }
}

// let event = new EventEmitter();
// let onceCallback = (...args) => {
//   console.log("once_event triggered", ...args);
// };
// let onceCallback1 = (...args) => {
//   console.log("once_event 1 triggered", ...args);
// };
// //Once listens only once
// event.once("onceEvent", onceCallback);
// event.once("onceEvent", onceCallback1);
// event.emit("onceEvent", "abc", "123");

// //off destroys the specified callback
// let onCallback = (...args) => {
//   console.log("on_event triggered", ...args);
// };
// let onCallback1 = (...args) => {
//   console.log("on_event 1 triggered", ...args);
// };
// event.on("onEvent", onCallback);
// event.on("onEvent", onCallback1);
// event.emit("onEvent", "abc", "123");

// event.off("onEvent", onCallback);
// event.emit("onEvent", "abc", "123");

Large integer addition

/**
* Please add large integers (which may be larger than Number.MAX_VALUE) through code
* var bigint1 = new BigInt('1231230');
* var bigint2 = new BigInt('12323123999999999999999999999999999999999999999999999991');
* console.log(bigint1.plus(bigint2))
*/
function BigInt(value) {
  this.value = value;
}

BigInt.prototype.plus = function (bigint) {
  let aArr = this.value.split("");
  let bArr = bigint.value.split("");
  let stack = [];
  let count = 0;
  while (aArr.length !== 0 || bArr.length !== 0) {
    let aPop = aArr.pop() || 0;
    let bPop = bArr.pop() || 0;
    let stackBottom = 0;
    if (stack.length > count) {
      stackBottom = stack.shift();
    }
    let sum = parseInt(aPop) + parseInt(bPop) + parseInt(stackBottom);
    if (sum < 10) {
      stack.unshift(sum);
    } else if (sum >= 10) {
      stack.unshift(sum - 10);
      stack.unshift(1);
    }
    count++;
  }
  return stack.join("");
};

SuperPerson inherits from Person

//Write a class Person, which has the attributes age and name and the method say(something)
//Write another class Superman, inherit Person, have their own property power, and have their own method fly(height) ES5

function Person(age, name){
	this.age = age;
        this.name = name;
}
Person.prototype.say = function(something) {
    // ...
}

function Superman(age, name, power){
        Person.call(this, age, name, power);
	this.power = power;
}
Superman.prototype = Object.create(Person.prototype);
Superman.prototype.constructor = Superman;

Superman.prototype.fly = function(height) {
    // ...
}

let superman = new Superman(25, 'GaoKai', 'strong');

// class mode
class Person {
  constructor(age, name){
    this.age = age;
    this.name = name;
  }
  say(something){
  	// ...
  	console.log("say");
  }
}
class Superman extends Person{
  constructor(age, name, power){
	super(age, name)
	this.power = power;
  }
  fly(height){
    // ...
    console.log("fly");
  }
}

let superman = new Superman(25, 'GaoKai', 'strong');

Hide part of string

/**
 * Hide part of string
 * Description: implement a method to receive a string and a symbol, and hide the middle four bits of the string according to the specified symbol
 *   1. Use asterisk (*) when no symbol is specified
 *   2. When the received string is less than or equal to four bits, the symbol string of the same length is returned, which is equivalent to full hiding, such as 123, which is hidden***
 *   3. When the length of the string is an odd number greater than four bits, such as 123456789, it is 12 * * * * 789 after hiding, and the extra bit of the odd number is at the end
 * Example:
 *   mask('blibaba', '#');  // b####ba
 *   mask('05716666');   // 05****66
 *   mask('hello');  // ****o
 *   mask('abc', '?');  // ???
 *   mask('Beribaba Group ','? '// Beep???? group
 */
function mask(str, char = "*") {
  if(str.length<=4) return char.repeat(str.length);
  /* code implementation */
  let result = "";
  let i = Math.floor(str.length / 2) - 1;
  let j = Math.floor(str.length / 2);
  while(result.length!==str.length){
    if(j - i <= 4){
      	result = char + result;
    	result += char ;
    } else {
    	result = (str[i] || "") + result;
    	result += str[j] ;
    }
    i--;
    j++;
  }
  return result;
}

Implement an add(1,2,3)(4)(5)(6,7)(8)()

The return result is the sum of these numbers: 36.

This is a study of closure + recursion.

function sum(){
    const result = [...arguments].reduce((acc, cur)=>acc+cur)
    return function(){
            if(arguments.length === 0)return result
            return sum(...[...arguments, result]);
    }
}

Implement an upgraded version of sum(1,2,3)(4)(5)(6,7)(8)(): how to add, subtract, multiply and divide?

sum(1,2,3)(4)(5)(6,7)(8)()
minus(1,2,3)(4)(5)(6,7)(8)()
multiple(1,2,3)(4)(5)(6,7)(8)()
divide(1,2,3)(4)(5)(6,7)(8)()

In addition to summation, closure and recursion, we also investigate Coriolis functions.

sum and multiple don't pay attention to order.
minus and divide need to pay attention to the order, so in return curred (... [result,... Arguments]); Precede result.

function curry(callback){
    return function curried (){
        const result = callback(arguments)
        return function(){
                if(arguments.length === 0)return result
                return curried(...[result, ...arguments]);
        }
    }
}


let sum = (args) =>{
    return [...args].reduce((acc, cur)=>acc+cur)
}

let minus = (args) =>{
    return [...args].reduce((acc, cur)=>acc-cur)
}


let multiple = (args) =>{
    return [...args].reduce((acc, cur)=>acc*cur)
}

let divide = (args) =>{
    return [...args].reduce((acc, cur)=>acc / cur)
}


let currySum = curry(sum)
let curryMultiple = curry(multiple)
let curryDivide = curry(divide)
let curryMinus = curry(minus)

console.log(currySum(1,2,3)(4)(5)(6,7)(8)())
console.log(curryMultiple(1,2,3)(4)(5)(6,7)(8)())
console.log(curryDivide(1,2,3)(4)(5)(6,7)(8)())
console.log(curryMinus(1,2,3)(4)(5)(6,7)(8)())

I look forward to communicating with you and making progress together. Welcome to join the technical discussion group closely related to front-end development I created:

Strive to be an excellent front-end engineer!

Keywords: Javascript Front-end Interview

Added by mindfield on Thu, 10 Feb 2022 09:39:58 +0200