2020年4月大廠騰訊前端面經分享

  • 2020 年 4 月 13 日
  • 筆記

前言

本人很榮幸參加了一次騰訊大廠的一面,雖然結果不理想,但是總歸是檢測了一下自己,發現了自己的不足地方,以此督促自己加強學習。
本次面試共分為筆試題一個小時和面試一個小時。

一、編程題(請用es6實現編碼):

1、 二分查找

給定一個 n 個元素有序的(升序)整型數組 nums 和一個目標值 target ,寫一個函數二分查找 nums 中的 target,如果目標值存在返回下標,否則返回 -1。

let arr = [1, 3, 5, 7, 9];
function search(nums, target) {
  let left = 0;
  let right = nums.length - 1;
  while(left <= right) {
    let mid = (right + left) / 2;
    if (nums[mid] == target) {
      return mid;
    } else if (nums[mid] < target) {
      left = mid + 1;
    } else {
      right = mid -1;
    }
  }
  return -1;
}
console.log(search(arr, 7));

2、 編寫一個非同步查詢等待結果的輪詢組件

組件具體輸入如下:

  1. 查詢執行方法
  2. 輪詢間隔
  3. 超時時長
  4. 最多輪詢次數
    組件輸出:
  5. 返回一個promise對象
  6. 查詢方法執行無異常,則輪詢結束,返回查詢結果
    解答:
  // vue程式碼
  data() {
    return {
      data: {}, // 請求結果
      remainTime: 0, // 剩餘限制時長
      start: 0, // 開始時間
      end: 0, // 請求得到數據的時間
    }
  }
  mounted () {
    // 請求之前計時 start
    this.start = Math.floor(new Date().getTime()/1000);
    this.query(50, 2, 10);
  },
  methods: {
    // 只要輪詢次數和最大限制時長任何一個達到閾值 就 停止輪詢
    query(num, interval, limitTime=60) { // 參數num:輪詢次數   interval:定時器時間(s)  l imitTime:最大限制時長(s)
      let timer;
      if (num > 1) {
        return new Promise((resolve, reject) => {
          let postParams = {
            id: this.$route.params.id
          }
          Api.getArticleOne(postParams).then(res => {
            this.data = res.data.data.content; // 這個只是介面返回的數據結構
            this.end = Math.floor(new Date().getTime()/1000);
          }, err => {
            reject(err);
          }).catch(err => {
            console.log(err)
          });
          if (this.end !== 0) {
            // 如果拿到數據了,就用當前的 剩餘限制時長 - (結束時間 - 開始時間)
            this.remainTime = limitTime - (this.end - this.start);
          } else {
            // 如果還沒拿到介面數據  這個時候  end就為0  需要繼續 輪詢  這個時候的剩餘時間還是 傳過來的 限制時長
            this.remainTime = limitTime;
          }

          if (this.remainTime <= 0) { // 如果剩餘時間小於等於 0 或者 循環次數 為 1 就結束定時器
            clearTimeout(timer);
            return;
          } else {
            // 輪詢一次  num就減少一次
            num--;
            this.remainTime = this.remainTime - interval; // 當前剩餘時長 = 當前剩餘時長 - 定時器
            timer = setTimeout(() => { this.query(num, interval, this.remainTime)}, interval * 1000);
          }
        }).catch(err => {
          console.log(err)
        })
      } else {
        clearTimeout(timer);
        return;
      }
    },
  }

3、 邏輯題

共有60塊磚,60人搬,男搬5,女搬3,兩個小孩搬1塊,一次搬完,需要小孩、男人、女人各多少人,有幾種組合方案?
解答:

function solution() {
  let x, y, z;
  for(x =1; x < 12; x++) {
    for(y = 1; y < 20; y++) {
      z = 60 - x - y;
      if (z%2 == 0) {
        if (5*x + y*3 + z/2 == 60) {
          console.log(x, y, z, '搬磚組合'); // 5 3 52
        }
      }
    }
  }
}
solution();

答案:只有一種方案:男人:5 ;女人: 3 ;小孩:52

二、問答題

1-5題

1. 請寫出下面程式碼輸出結果以及原因

var myname = "小明";
function showName(){ 
  console.log(myname); // undefined
  if(0){ var myname = "小紅" }
  console.log(myname); // undefined 
}
showName();

2. 請寫出下面程式碼輸出結果以及原因

function letTest() {
  let x = 1; 
  if (true) { 
    let x = 2; 
    console.log(x);  // 2
  }
  console.log(x); // 1
}
letTest();

3. 請寫出下面程式碼輸出結果以及原因?並且用箭頭函數實現

function bar() {
console.log(myName)
}
function foo() {
  var myName = "騰訊1"
  bar()
}
var myName = "騰訊2"
foo();// 騰訊2

箭頭函數:var foo = () => () => {
console.log(myName);
}

4. 請寫出下面程式碼輸出結果以及原因

var myObj = {
  name : "騰訊1",
  showThis: function(){
    console.log(this);
    var self = this;
    function bar(){
      self.name = "騰訊2";
    }
    bar()
  }
}
myObj.showThis(); // myObject對象
console.log(myObj.name); // 騰訊2
console.log(window.name); // undefined

5. 請寫出以下this指向情況

// 情況1
function foo() {
  console.log(this.a) //1
}
var a = 1
foo(); 
this指向window全局

// 情況2
function fn(){
  console.log(this);
}
var obj = {fn: fn};
obj.fn(); // this => obj this指向obj對象

// 情況3
function CreateJsPerson(name,age){
// this是當前類的一個實例p1
this.name=name; // => p1.name = name
this.age=age; // => p1.age = age
}
var p1=new CreateJsPerson("尹華芝",48);

// 情況4
function add(c, d){
  return this.a + this.b + c + d;
}
var o = {a: 1, b: 3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16   this指向o對象
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34 this指向o對象

// 情況5
<button id="btn1">箭頭函數this</button>
<script type="text/javascript">
  let btn1 = document.getElementById('btn1');
  let obj = {
    name: 'kobe',
    age: 39,
    getName: function () {
      btn1.onclick = () => {
          console.log(this);//obj
      };
    }
  };
  obj.getName();
this指向obj,因為箭頭函數的this是在外層函數定義的時候就指定了