2020秋招前端面經-常見手撕代碼題

下面整理一下最近這段時間面試過程當中遇到的一些手撕的代碼題,其中有些題目遇到過不止一次,也都是比較基礎的題目,你們能夠參考一下,ps:若是你沒時間刷完大部分的leetcode題,那麼我建議優先刷一下leetcode的 熱題 HOT 100,確實很容易被問到,並且筆試裏面也會遇到,劍指也能夠,可是我沒刷過,具體的不是很瞭解。
面試

  1. 多維數組降維問題

關於這個問題,在ES6中有一個新的方法arr.flat()方法,能夠直接返回降維後的數組,flat的參數爲降維的維度,默認爲一維,能夠爲數字,Infinity爲任意維,可是這個方法在低版本的瀏覽器中還不支持,因此通常會讓你寫一個原生的方法,這裏介紹幾種方法
數組

//方法一:常規方法,遞歸遍歷,判斷是否數組,須要用到額外的全局變量
var result=[]
var flat=function (arr) {
  for(let i=0;i<arr.length;i++){
    if(Array.isArray(arr[i])){
      flat(arr[i])
    }else{
      result.push(arr[i]);
    }
  }
}
//上述方法優化
var flat=function (arr) {
  var result=[]
  for(let i=0;i<arr.length;i++){
    if(Array.isArray(arr[i])){
      result=result.concat(flat(arr[i]))
    }else{
      result.push(arr[i]);
    }
  }
  return result;
}
//上述方法的簡潔寫法,利用箭頭函數
let flat = arr => arr.reduce((begin,current)=>{
  Array.isArray(current)?begin.push(...flat(current)):begin.push(current);
  return begin;
},[])
//方法二:使用字符串分割
var flat=function(arr){
  let strarr=arr+"";
  let str=strarr.split(",");
  return str;
}
複製代碼
  1. 全部子序列問題
//全部順序子序列(輸出全部有序的子序列)
var subSequence=function (arr){
  let res=[];
  for(let i=0;i<arr.length;i++){
    for(let j=i;j<arr.length;j++){
      res.push(arr.slice(i,j+1))
    }
  }
  return res;
}
console.log(subSequence([1,2,3]))
//結果爲 1 1,2 1,2,3, 2 2,3 3

//全部數組元素排列組合
// var allSubSequence=function(arr){
//   let len=arr.length;
//   let mark=new Array(len);
//   let result=[];
//   var recursion=function(arr,mark,n,i){
//     if(n==i){
//       let temparr=[];
//       for(let k=0;k<i;k++){
//         if(mark[k]==1){
//           temparr.push(arr[k]);
//         }
//       }
//       result.push(temparr);
//       return;
//     }
//     mark[n]=0;
//     recursion(arr,mark,n+1,i)
//     mark[n]=1;
//     recursion(arr,mark,n+1,i)
//   }
//   recursion(arr,mark,0,len);
//   return result;
// }
// console.log(allSubSequence([1,2,3,4]));
//輸出結果爲
// [],
// [ 4 ],
// [ 3 ],
// [ 3, 4 ],
// [ 2 ],
// [ 2, 4 ],
// [ 2, 3 ],
// [ 2, 3, 4 ],
// [ 1 ],
// [ 1, 4 ],
// [ 1, 3 ],
// [ 1, 3, 4 ],
// [ 1, 2 ],
// [ 1, 2, 4 ],
// [ 1, 2, 3 ],
// [ 1, 2, 3, 4 ] 
//原理: 
//原理,使用二進制的排列組合來實現
//將a,b,c,d 分別以二進制佔位符表示,0即表示不存在,1表示不存在,mark數組即用來存儲這個佔位符
//如0000則表示空集,1111表示集合{a,b,c,d},0001表示{d},0110表示{b,c}
//本質就是將0000按二進制加到1111,每加1就輸出一次其表示的數
//遞歸的原理圖以下,當只有abc三個數時
//                0
//            0
//                1
//        0
//                0
//            1
//                1
// start
//                0
//            0
//                1
//        1
//                0
//            1
//                1
複製代碼
  1. 多維數組每一維排列組合
var result=[];
var results=[];
var doExchange=function (arr, depth) {
  for (let i = 0; i < arr[depth].length; i++) {
    result[depth] = arr[depth][i];
    if (depth !== arr.length - 1) {
      doExchange(arr, depth + 1)
    } else {
      results.push(result.join(" ").split(" "))
    }
  }
}

doExchange([[1,2,3],[4,5],[6,7]],0)
for(let i=0;i<results.length;i++){
  for(let j in results[i]){
    results[i][j]=parseInt(results[i][j])
  }
}
console.log(results)
//結果:
// [ 1, 4, 6 ],
// [ 1, 4, 7 ],
// [ 1, 5, 6 ],
// [ 1, 5, 7 ],
// [ 2, 4, 6 ],
// [ 2, 4, 7 ],
// [ 2, 5, 6 ],
// [ 2, 5, 7 ],
// [ 3, 4, 6 ],
// [ 3, 4, 7 ],
// [ 3, 5, 6 ],
// [ 3, 5, 7 ]
複製代碼
  1. js實現對象屬性的get,set方法

這裏其實考察的是函數中this的指向問題,這裏用到了前文提到過的一個知識點 在js部分-ES6新增-函數相關擴展方法-普通函數中的this的四種調用模式
瀏覽器

//方法一:使用函數的方式實現
function Person(val){
  this.name="admin";
  this.getName=function(){
    return this.name;
  }
  this.setName=function(val){
    this.name=val;
  }
}
var per=new Person();
console.log(per.name)//admin
console.log(per.getName())//admin
per.setName(111)
console.log(per.getName())//111
//方法二:使用對象的方式實現(這種方式不能new一個實例)
var Person={
  name:"admin",
  getName(){
    return this.name;
  },
  setName(val){
    this.name=val
  }
}
console.log(Person.name)//admin
console.log(Person.getName())//admin
Person.setName("111")
console.log(Person.getName())//111
//方法三:使用原型鏈的按時實現
function Person(){ } 
Person.prototype.name="admin";
Person.prototype.getName=function(){
  return this.name;
};
Person.prototype.setName=function(val){
  this.name=val;
};
var per=new Person();
console.log(per.name)//admin
console.log(per.getName())//admin
per.setName(111)
console.log(per.getName())//111
複製代碼
  1. a==1&&a==2返回true,這個問題的原理就是js中的隱式類型轉換,涉及到兩個函數,js在遇到==的時候會先對數據使用valueOf函數將數據轉換爲原始類型,而後判斷值是否相等,若是不等,會對數據使用toString()方法,而後判斷兩個字符串是否相等。

toString()會把數據類型轉換成string類型,也就是說無論原來是什麼類型,轉換後一概是string類型
valueOf()會把數據類型轉換成原始類型,也就是說原來是什麼類型,轉換後仍是什麼類型,日期類型除外
markdown

let a={
  i:1,
  valueOf(){
    return a.i++;
  }
}
console.log(a==1&&a==2) //true

let b={
  i:1,
  toString(){
    return b.i++;
  }
}
console.log(b==1&&b==2) //true
複製代碼
  1. 每隔1秒輸出1,2,3,4...
//方法一:ES6 let 塊級做用域
//注意:這裏若是使用var的話,會每一個一秒輸出一個5,輸出5個5
for(let i = 1; i <5; i++){
  setTimeout(function () {
  console.log(i);
  },1000*i);
}
//方法二:ES5 閉包 匿名函數and函數自動執行
//       (function(i){})(i) 其中第一個()返回一個匿名函數,第二()起到當即執行的做用
for (var i = 1; i <= 10; i++) {
  (function (i) {
    setTimeout(function () {
      console.log(i);
    }, 1000 * i);
  })(i);
}
複製代碼
  1. js實現防抖和節流
/* 
  *fn --> 須要防抖的函數;
  *delaytime --> 毫秒數,防抖所需期限值;
*/
//防抖
//原理:當持續觸發事件時,必定時間段內沒有再觸發事件,事件處理函數纔會執行一次,若是設定的時間到來以前,又一次觸發了事件,
//就從新開始延時。
function debounce(fn,delaytime){
  let timer = null 
  return function(){
      if(timer){
        //進入這裏說明當前存在一個執行過程,而且同時又執行了一個相同事件,故取消當前的執行過程
        clearTimeout(timer) 
      }
      timer = setTimeout(fn,delaytime)    
  }
}
function show_scrollPosition(){
  var scrollPosition = document.body.scrollTop || document.documentElement.scrollTop;
  console.log("當前滾動條位置爲:",scrollPosition);
} 

window.onscroll = debounce(show_scrollPosition,1000)
//節流
//原理:規定一個期限時間,在該時間內,觸發事件的回調函數只能執行一次,若是期限時間內回調函數被屢次觸發,則只有一次能生效。
function throttle(fn, delay) {
  let last_time
  let timer = null
  return function () {
    let cur_time = new Date().getTime()
    if (last_time && cur_time < last_time + delay) { 
      //若爲真,則表示上次執行過,且在期限值範圍內
      clearTimeout(timer)
      timer = setTimeout(() => {
        fn();
        last_time = cur_time
      }, delay)
    } else {
      last_time = cur_time;
      fn();
    }
  }
}
function show_scrollPosition() {
  var scrollPosition = document.body.scrollTop || document.documentElement.scrollTop;
  console.log("當前滾動條位置爲:", scrollPosition);
}
window.onscroll = throttle(show_scrollPosition, 1000)
複製代碼
  1. js實現add(1)(2)(3)=6
function add(val){
  var rs = function(oval){
      return add(val + oval);
  }
  rs.toString = function(){
      return val;
  }
  return rs;
}
console.log(add(1)(2)(3) == 6);
複製代碼
相關文章
相關標籤/搜索