【面經】2019騰訊字節頭條提前批面試題整理

2019騰訊頭條提前批面試題整理

時間節點:2019年8月份的提前批

本人面試狀態:騰訊一面掛、字節一、二面、加面後掛

部分面試題有解答,部分我不太確定的答案就不放解答了。

字節頭條部分:

1. 編程題小試牛刀(閉包):實現一個函數 sum(),可以實現這樣的效果sum(1,2,3)(2)(1) = 9,即1+2+3+2+1 = 9,或者 sum(1)(2)(3).sumOf() = 6,即1+2+3 = 6。

簡要分析:這裏需要連續調用函數,並且要計算求和,並且這個求和的值還能緩存下來,實際上就是利用閉包實現累加求和。

function addSum(...numbers){

    var sum = 0
    for(let i of numbers){
        sum += i
    }

    var f = function (...num) {
    	for(let i of num){
    		sum += i
    	}
    	return f
    }
    f.sumOf = function () {
    	return sum
    }
    return f
}



console.log(addSum(1,2,3)(5).sumOf()) // 11

2. 事件循環機制終極考驗

補充閱讀:https://www.jianshu.com/p/65a23cb06452

補充閱讀:https://www.jianshu.com/p/0f97e6dadceb

請分析以下事件的輸出順序

async function a1() {
    console.log('async1 start');
    await a2();
    console.log('async1 end')
}
async function a2(){
    console.log('async2')
}

console.log('script start')     
setTimeout(function(){
    console.log('setTimeout')
}, 0);
a1();

new Promise((resolve)=>{
    console.log('Promise1');
    resolve();
}).then(()=>{
    console.log('Promise2')
})

執行結果:

script start
async1 start
async2
Promise1
Promise2
async1 end
setTimeout

關鍵點在於 async1 end 爲什麼比 Promise2 後輸出,此時需要把 async 函數轉化成 promise 對象帶入函數,發現輸出async1 end的語句確實是先加入到微任務隊列中去,但是他是一個嵌套的Promise.resolve(resolve),而 Promise2 雖然是後加入到微任務隊列,但是它不是嵌套的,而是resolve(),所以 Promise.resolve(resolve)會先執行,然後又把resolve加入到微任務隊列,然後Promise2輸出,然後才輸出 async1 end。

3. 函數節流和防抖動

概念:

節流 (throttle) 讓一個函數不要執行的太頻繁,減少執行過快的調用,叫節流。

函數節流就是讓連續執行的函數,變爲固定時間段間斷地執行。

特點:固定時間清除一次計時器,只要計時器存在就不做任何操作,計時器一旦消失就執行一次函數並添加一個在固定時間後消失的計時器,可以使用閉包實現。

var print = function (){
	console.log('hello world')
}

function throttlePro(delay, action) {
    var tId;
    return function () {
        if (tId) return;
        tId = setTimeout(function () {
            action()
            clearTimeout(tId);
            // setTimeout 返回一個整數,clearTimeout 之後,tId還是那個整數,setInterval同樣如此
            tId = null;
        }, delay);
    }
}

window.onscroll = throttlePro(1000,print)

去抖 (debounce) 去抖就是對於一定時間段的連續的函數調用,只讓其執行一次。

特點:連續函數不斷地清除計時器,計時器只執行最後一次觸發的函數,使用閉包實現記錄一個計時器的實例。

函數去抖背後的思路是指,減少函數在一定時間段內連續調用的次數,只讓其執行一次。創建一個定時器,在指定的時間間隔之後運行代碼。當第二次調用該函數時,它會清除前一次的定時器並設置另一個。如果前一個定時器已經執行過了,這個操作就沒有任何意義。然而,如果前一個定時器尚未執行,其實就是將其替換爲一個新的定時器。目的是隻有在執行函數的請求停止了一段時間之後才執行。

例如減少window.onscroll執行的頻率,滾動一次滾輪會觸發多次onscroll事件,使用函數去抖動的方式來它在指定時間內(500ms)只觸發一次onscroll事件,節約資源,提高性能。

function print(){
	console.log('hello world')
}
function debounce(delay, action) {
    var tId;
    return function () {
        if (tId) clearTimeout(tId);
        tId = setTimeout(function () {
            action()
        }, delay);
    }
}

window.onscroll = debounce(500, print)

4. 如何判斷一個對象爲空?

(1)遍歷屬性法

一旦該對象的屬性是可遍歷的即說明該對象存在屬性,則返回false,否則該對象爲空對象。

function judgeObj(obj){
    for(var attr in obj){
          return  false
    }
    return true
}

console.log(judgeObj({}))

(2)JSON.stringify() 方法

function judgeObj2(obj){
    if(JSON.stringify(obj) == '{}')
    	return true
    else 
    	return false
}
console.log(judgeObj2({}))

(3)ES6 Object.keys()方法

Object.keys方法是JavaScript中用於遍歷對象屬性的一個方法 。

它傳入的參數是一個對象,返回的是一個數組,數組中包含的是該對象所有的屬性名。

function judgeObj3(obj) {
	if(Object.keys(obj).length == 0){
		return true
	} else {
		return false
	}
}

5. TCP 和 UDP的區別?

不僅需要知道有哪些區別,還有理解其中的緣由。

(1)TCP是面向連接的,UDP是無連接的。TCP需要有三次握手連接,UDP不需要

(2)TCP提供可靠的服務,保證通過TCP連接傳輸的數據不會丟失、不會重複、保證傳輸有序,但不保證按序到達。(TCP:確認與重傳機制、擁塞控制、流量控制)UDP不提供可靠性服務。

(3)TCP是面向字節流的,UDP是面向報文段的(一次發送一個報文)。

(4)UDP傳輸比TCP快,TCP首部開銷20字節、UDP首部開銷8字節

6. 如何使A類繼承於B類?

7.假設有一個大數組arr,長度很大,幾百萬個,循環執行pop方法,怎麼樣提高效率?

8.HTTP所有的請求方法類型?

HTTP1.0 中定義的方法:GET, POST 和 HEAD方法

HTTP1.1 中新增的5種方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法

1、OPTIONS

返回服務器針對特定資源所支持的HTTP請求方法,也可以利用向web服務器發送‘*’的請求來測試服務器的功能性

2、TRACE

回顯服務器收到的請求,主要用於測試或診斷

GET和POST的區別

最直觀的區別就是GET把參數包含在URL中,POST通過request body傳遞參數。

語義上對於GET方式用來獲取數據,POST用來提交的數據。

GET方式提交的數據最多隻能有1024字節(受URL地址長度影響),而POST則沒有此限制

9.項目部分:如何實現頭像的放大縮小、剪裁、圖片懶加載是怎實現的?

10.算法部分: 合併兩個有序數組、最長不重複子串、二叉樹中是否存和爲sum的路徑

(1)合併兩個有序數組(題目雖簡單,但需要快和不出錯,不寫冗餘的代碼)

var merge = function(nums1, m, nums2, n) {
    let nums = []
    let i = 0
    let j = 0
    while(i < m && j < n){
        if(nums1[i] <= nums2[j]){
            nums.push(nums1[i++])
        } else {
            nums.push(nums2[j++])
        }
    }
    
    while(i < m){
        nums.push(nums1[i++])
    }
    while(j < n){
        nums.push(nums2[j++])
    }
    return nums
};

(2)最長不重複子串

(3)二叉樹中是否存在路徑

 

騰訊部分

1. 高性能數組去重的方法?(隱式轉換,高頻考點)

2. Webpack如何提高打包效率?

3. Webpack如果減少壓縮體積?

4. Webpack打包的流程?

5.你的項目是如何構建的?

6.在你本期實習的項目中,你有哪些收穫,沉澱下了什麼技術?

7. 頁面長時間出現白屏如何排查問題?如果不能使用開發環境如何定位問題?

8.數據隱式轉換,數據類型判斷

9. 跨域有哪些方法,同源的機制,設置同源的機制是爲了什麼?

10.如何實現一個Promise對象,實現Promise對象的鏈式調用?

11.Promise.all方法的實現

12.瀏覽器的緩存機制,包括緩存位置分類類型 強緩存、協商緩存

解答參考:https://www.jianshu.com/p/54cc04190252

瀏覽器緩存機制從緩存位置上來說分爲四種

  • Service Worker(使用要求,協議必須爲 HTTPS)
  • Memory Cache(存儲在內存中的緩存,tab頁被關閉,緩存就釋放)
  • Disk Cache(硬盤中的緩存)
  • Push Cache(HTTP2推送緩存,只在session會話中存在)

強緩存和協商緩存(通過設置HTTP的header來實現)

如果沒有設置任何緩存會採用啓發式算法。(date-last-modify)*10%

用戶行爲對瀏覽器緩存的影響:刷新、強制刷新、輸入網址使用的緩存的位置

13.元素樣式居中的幾種方法?高度不固定。

14.== 和 === 的區別

15.作用域鏈

16.px、em、rem

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