十道前端面試題第【04】篇

1、無重複字符的最長子串

需求:給定一個字符串(由英文字母、數字、符號和空格組成),請你找出其中不含有重複字符的最長子串的長度。

示例:輸入s = "abcabcbb",輸出爲 3。因爲無重複字符的最長子串是 "abc",所以其長度爲 3。

function maxSubString (s) {
    let map = new Map(), max = 0
    for(let i = 0, j = 0; j < s.length; j++) {
        if(map.has(s[j])) {
            i = Math.max(map.get(s[j]) + 1, i)
        }
        max = Math.max(max, j - i + 1)
        map.set(s[j], j)
    }
    return max
}
// 測試
maxSubString("abcabcbb")   // 3


2、求兩個矩形重疊面積的大小。

需求:在二維平面上,求四組座標構成的兩個矩形所重疊的面積大小。

示例:輸入[-3, 0, 3, 4, 0, -1, 9, 2],輸出 6(即重疊的面積大小爲 6),圖解如下。

function overlapArea([x1, y1, x2, y2, x3, y3, x4, y4]) {
  let min = Math.min
  let max = Math.max
  // 記錄矩形的右上角點、左下角點
  let [Ax,Bx] = [min(x1,x2), max(x1,x2)]
  let [Ay,By] = [min(y1,y2), max(y1,y2)]
  let [Cx,Dx] = [min(x3,x4), max(x3,x4)]
  let [Cy,Dy] = [min(y3,y4), max(y3,y4)]

  console.log(Ax, Ay, Bx, By, Cx, Cy, Dx, Dy)
  let w = 0
  let h = 0
  if(!(Cy>=By || Dy<=Ay || Dx<=Ax || Cx>=Bx)) {
    console.log('兩矩形重合')
    if(Cx>Ax) w = Bx-Cx
    if(Dx<Bx) w = Dx-Ax
    if(Ax>Cx && Bx<Dx) w = Bx-Ax
    if (Cx>Ax && Dx<Bx) w = Dx-Cx
    if(Cy<By) h = By-Cy
    if(Dy>Ay) h = Dy-Ay
    if(Dy>By && Cy<Ay) h = By-Ay
    if(By>Dy && Ay<Cy) h = Dy-Cy
  }
  return w*h
}
// 測試
overlapArea([-3, -3, 10, -1,   9, 2, 0, -1])   // 0,兩矩形不重合
overlapArea([-3, 0, 3, 4, 0, -1, 9, 2])   // 6,兩矩形重合


3、實現先進先出隊列

需求:最多使用兩個棧,實現先進先出隊列,並支持以下操作:

  • void push(int x) 將元素 x 推到隊列的末尾
  • int pop() 從隊列的開頭移除並返回這個元素
  • int peek() 不改變隊列,只返回隊列開頭的元素
  • boolean empty() 如果隊列爲空返回 true ;否則返回 false
var MyQueue = function() {
  this.inStack = []
  this.outStack = []
}

MyQueue.prototype.push = function(x) {
  this.inStack.push(x)
}

MyQueue.prototype.pop = function() {
  if (!this.outStack.length) {
    this.in2out()
  }
  return this.outStack.pop()
}

MyQueue.prototype.peek = function() {
  if (!this.outStack.length) {
    this.in2out()
  }
  return this.outStack[this.outStack.length - 1]
}

MyQueue.prototype.empty = function() {
  return this.outStack.length === 0 && this.inStack.length === 0
}

MyQueue.prototype.in2out = function() {
  while (this.inStack.length) {
    this.outStack.push(this.inStack.pop())
  }
}

// 測試
var queue = new MyQueue()
queue.push(1)  // [1]
queue.push(2)  // [1,2]
queue.push(3)  // [1,2,3]
queue.pop()    // [2,3]
queue.peek()   // 2
queue.empty()  // false


4、封裝洗牌算法。

function shuffle(arr) {
  let m = arr.length
  while (m){
    let index = Math.floor(Math.random() * m--)
    let cur = arr[m]
    arr[m] = arr[index]
    arr[index] = cur
  }
  return arr
}
// 測試一下
shuffle([1,2,3,4,5,6])


5、理解服務端渲染。

題目:什麼是服務端渲染?SSR、BSR各有什麼優勢和劣勢?有哪些SEO策略?

6、原生封裝 WebSocket。

const socket = new WebSocket('ws://localhost:8080')
socket.addEventListener('open', function (event) {
    socket.send('Hello Server!')
})
socket.addEventListener('message', function (event) {
    console.log('Message from server ', event.data)
})


7、原生封裝圖片上傳方法。

function upload(option) {
  if (typeof XMLHttpRequest === 'undefined') {
    return;
  }

  const xhr = new XMLHttpRequest();
  const action = option.action;

  if (xhr.upload) {
    xhr.upload.onprogress = function progress(e) {
      if (e.total > 0) {
        e.percent = e.loaded / e.total * 100;
      }
      option.onProgress(e);
    };
  }

  const formData = new FormData();

  if (option.data) {
    Object.keys(option.data).forEach(key => {
      formData.append(key, option.data[key]);
    });
  }

  formData.append(option.filename, option.file, option.file.name);

  xhr.onerror = function error(e) {
    option.onError(e);
  };

  xhr.onload = function onload() {
    if (xhr.status < 200 || xhr.status >= 300) {
      return option.onError(getError(action, option, xhr));
    }

    option.onSuccess(getBody(xhr));
  };

  xhr.open('post', action, true);

  if (option.withCredentials && 'withCredentials' in xhr) {
    xhr.withCredentials = true;
  }

  const headers = option.headers || {};

  for (let item in headers) {
    if (headers.hasOwnProperty(item) && headers[item] !== null) {
      xhr.setRequestHeader(item, headers[item]);
    }
  }
  xhr.send(formData);
  return xhr;
}


8、求兩個非負數的最大公約數。

function divisor(a,b) {
  for(i=a;i>0;i--){
    if(a%i==0){
      if(b%i==0){
        return i
      }
    }
  }
}
// 測試一下
divisor(512,768)   // 256


9、封裝方法,判斷兩個元素是否相等。

function isObject(obj) {
  return obj !== null && typeof obj === 'object'
}

function looseEqual(a, b) {
  if (a === b) { return true }
  var isObjectA = isObject(a);
  var isObjectB = isObject(b);
  if (isObjectA && isObjectB) {
    try {
      var isArrayA = Array.isArray(a);
      var isArrayB = Array.isArray(b);
      if (isArrayA && isArrayB) {
        return a.length === b.length && a.every(function (e, i) {
          return looseEqual(e, b[i])
        })
      } else if (a instanceof Date && b instanceof Date) {
        return a.getTime() === b.getTime()
      } else if (!isArrayA && !isArrayB) {
        var keysA = Object.keys(a);
        var keysB = Object.keys(b);
        return keysA.length === keysB.length && keysA.every(function (key) {
          return looseEqual(a[key], b[key])
        })
      } else {
        return false
      }
    } catch (e) {
      return false
    }
  } else if (!isObjectA && !isObjectB) {
    return String(a) === String(b)
  } else {
    return false
  }
}
// 測試一下
looseEqual(1,1) // true
looseEqual([1],[1]) // true
looseEqual({a:1},{a:1}) // true
looseEqual({a:1},{a:2}) // false


10、談一談瀏覽器的緩存機制。

本週結束,下週繼續!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章