十道前端面试题第【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、谈一谈浏览器的缓存机制。

本周结束,下周继续!!!

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