拼多多筆試總結

走過了拼多多的面試,又重新走向了筆試。順便記錄一下有意思的題目。

題目是這樣的:設計一個函數mul,要你實現以下功能console.log(mul(1)(2)(3))//6 ;
console.log(mul(2)(3)(4))//24;

需要實現的功能就是輸入三個參數,使三個參數相乘。
關鍵就在於每次都要return一個函數,代碼見下:

var mul = function(a){
    return function(b){
        return function(c){
            return a*b*c;
        };
    };
};

當然,如果每次都傳入不一樣個數的參數的話,就不可能一直用這樣一個調用,不然會造成回調地獄啦~方法當然是有的,詳細見代碼:

這種就是類似於執行一個函數返回函數自身值:

function mul(x) {
    var product= x;
    var tmp = function (y) {
        product = product * y;
        return tmp;
    };
    tmp.toString = function () {
        return product ;
    };
    return tmp;
}
console.log(mul(1)(2)(3));  //6
console.log(mul(1)(2)(3)(4));   //24

總結一下HTTP 2.0的一些新特性

HTTP2.0的標準總體目標是爲了改善用戶在使用web時候的速度體驗(這些改進都是HTTP1.1中的痛點或者說是所遇到的瓶頸)。實現上主要是有7項技術:多路複用,流量控制,客戶拖拽,服務器推送,WebSocket以及協商和TLS義務化。不過具體到平時的使用體驗上,體現在如下幾個方面:

與HTTP 1.1相比,主要區別包括

  1. HTTP/2採用二進制格式而非文本格式
  2. HTTP/2是完全多路複用的,而非有序並阻塞的——只需一個連接即可實現並行
  3. 使用報頭壓縮,HTTP/2降低了開銷
  4. HTTP/2讓服務器可以將響應主動“推送”到客戶端緩存中

HTTP/2爲什麼是二進制?

比起像HTTP/1.x這樣的文本協議,二進制協議解析起來更高效、“線上”更緊湊,更重要的是錯誤更少。

爲什麼 HTTP/2 需要多路傳輸?

HTTP/1.x 有個問題叫線端阻塞(head-of-line blocking), 它是指一個連接(connection)一次只提交一個請求的效率比較高, 多了就會變慢。 HTTP/1.1 試過用流水線(pipelining)來解決這個問題, 但是效果並不理想(數據量較大或者速度較慢的響應, 會阻礙排在他後面的請求). 此外, 由於網絡媒介(intermediary )和服務器不能很好的支持流水線, 導致部署起來困難重重。而多路傳輸(Multiplexing)能很好的解決這些問題, 因爲它能同時處理多個消息的請求和響應; 甚至可以在傳輸過程中將一個消息跟另外一個摻雜在一起。所以客戶端只需要一個連接就能加載一個頁面。

消息頭爲什麼需要壓縮?

假定一個頁面有80個資源需要加載(這個數量對於今天的Web而言還是挺保守的), 而每一次請求都有1400字節的消息頭(着同樣也並不少見,因爲Cookie和引用等東西的存在), 至少要7到8個來回去“在線”獲得這些消息頭。這還不包括響應時間——那只是從客戶端那裏獲取到它們所花的時間而已。這全都由於TCP的慢啓動機制,它會基於對已知有多少個包,來確定還要來回去獲取哪些包 – 這很明顯的限制了最初的幾個來回可以發送的數據包的數量。相比之下,即使是頭部輕微的壓縮也可以是讓那些請求只需一個來回就能搞定——有時候甚至一個包就可以了。這種開銷是可以被節省下來的,特別是當你考慮移動客戶端應用的時候,即使是良好條件下,一般也會看到幾百毫秒的來回延遲。

服務器推送的好處是什麼?

當瀏覽器請求一個網頁時,服務器將會發回HTML,在服務器開始發送JavaScript、圖片和CSS前,服務器需要等待瀏覽器解析HTML和發送所有內嵌資源的請求。服務器推送服務通過“推送”那些它認爲客戶端將會需要的內容到客戶端的緩存中,以此來避免往返的延遲。

HTTP2.0性能增強的核心:二進制分幀

HTTP 2.0最大的特點: 不會改動HTTP 的語義,HTTP 方法、狀態碼、URI 及首部字段,等等這些核心概念上一如往常,卻能致力於突破上一代標準的性能限制,改進傳輸性能,實現低延遲和高吞吐量。而之所以叫2.0,是在於新增的二進制分幀層。
既然又要保證HTTP的各種動詞,方法,首部都不受影響,那就需要在應用層(HTTP2.0)和傳輸層(TCP or UDP)之間增加一個二進制分幀層。
在二進制分幀層上, HTTP 2.0 會將所有傳輸的信息分割爲更小的消息和幀,並對它們採用二進制格式的編碼 ,其中HTTP1.x的首部信息會被封裝到Headers幀,而我們的request body則封裝到Data幀裏面。
HTTP 2.0 通信都在一個連接上完成,這個連接可以承載任意數量的雙向數據流。相應地,每個數據流以消息的形式發送,而消息由一或多個幀組成,這些幀可以亂序發送,然後再根據每個幀首部的流標識符重新組裝。

HTTP2.0 首部壓縮

HTTP 2.0 在客戶端和服務器端使用“首部表”來跟蹤和存儲之前發送的鍵-值對,對於相同的數據,不再通過每次請求和響應發送;通信期間幾乎不會改變的通用鍵-值對(用戶代理、可接受的媒體類型,等等)只 需發送一次。事實上,如果請求中不包含首部(例如對同一資源的輪詢請求),那麼 首部開銷就是零字節。此時所有首部都自動使用之前請求發送的首部。

如果首部發生變化了,那麼只需要發送變化了數據在Headers幀裏面,新增或修改的首部幀會被追加到“首部表”。首部表在 HTTP 2.0 的連接存續期內始終存在,由客戶端和服務器共同漸進地更新 。

所有的HTTP2.0的請求都在一個TCP鏈接上

HTTP 2.0 把 HTTP 協議通信的基本單位縮小爲一個一個的幀,這些幀對應 着邏輯流中的消息。並行地在同一個 TCP 連接上雙向交換消息。就好比,我請求一個頁面http://www.qq.com。頁面上所有的資源請求都是客戶端與服務器上的一條TCP上請求和響應的!

有關注TCP性能的同學就會知道,HTTP性能瓶頸關鍵在於低延遲而不是高帶寬!大多數HTTP 連接的時間都很短,而且是突發性的,但TCP 只在長時間連接傳輸大塊數據時效率才最高。HTTP 2.0 通過讓所有數據流共用同一個連接,可以更有效地使用TCP 連接,讓高帶寬也能真正的服務於HTTP的性能提升。

同時,單鏈接多資源的方式,使到至上而下的層面都得到了好處:
1. 可以減少服務鏈接壓力,內存佔用少了,連接吞吐量大了
2. 由於 TCP 連接減少而使網絡擁塞狀況得以改觀;
3. 慢啓動時間減少,擁塞和丟包恢復速度更快。

也就是說,“資源合併減少請求”的優化手段對於HTTP2.0來說是沒有效果的,只會增大無用的工作量而已

並行雙向字節流的請求和響應

在HTTP2.0上,客戶端和服務器可以把HTTP 消息分解爲互不依賴的幀,然後亂序發送,最後再在另一端把它們重新組合起來。注意,同一鏈接上有多個不同方向的數據流在傳輸。客戶端可以一邊亂序發送stream,也可以一邊接收服務器的響應,而服務器那端同理。
把 HTTP 消息分解爲獨立的幀,交錯發送,然後在另一端重新組裝是 HTTP 2.0 最 重要的一項增強。事實上,這個機制會在整個 Web 技術棧中引發一系列連鎖反應, 從而帶來巨大的性能提升,因爲:

可以並行交錯地發送請求,請求之間互不影響;
可以並行交錯地發送響應,響應之間互不干擾;
只使用一個連接即可並行發送多個請求和響應;
消除不必要的延遲,從而減少頁面加載的時間;
那麼也就是說“域名分區”這種優化手段對於HTTP2.0是無用的,因爲資源都是並行交錯發送,且沒有限制,不需要額外的多域名並行下載。

HTTP2.0的請求優先級

每個HTTP2.0流裏面有個優先值,這個優先值確定着客戶端和服務器處理不同的流採取不同的優先級策略,高優先級的流都應該優先發送,但又不會絕對的。絕對地準守,可能又會引入首隊阻塞的問題:高優先級的請求慢導致阻塞其他資源交付。分配處理資源和客戶端與服務器間的帶寬,不同優先級的混合也是必須的。

HTTP2.0的服務器推送

HTTP 2.0 新增的一個強大的新功能,就是服務器可以對一個客戶端請求發送多個響應。換句話說,服務器除了對最初請求的響應外,還可以額外向客戶端推送資源,而無需客戶端明確地請求。
當瀏覽器請求一個html,服務器其實大概知道你是接下來要請求資源了,而不需要等待瀏覽器得到html後解析頁面再發送資源請求。我們常用的內嵌圖片也可以理解爲一種強制的服務器推送:我請求html,卻內嵌了張圖。
有了HTTP2.0的服務器推送,HTTP1.x時代的內嵌資源的優化手段也變得沒有意義了。而且使用服務器推送的資源的方式更加高效,因爲客戶端還可以緩存起來,甚至可以由不同的頁面共享(依舊遵循同源策略)。當然,瀏覽器是可以決絕服務器推送的資源的。


假如頁面有一個input,給這個input綁定四個事件,綁定如下:
input.onmousedown=function(){
    console.log('mousedown');
}
input.onmouseup=function(){
    console.log('mouseup');
}
input.onclick=function(){
    console.log('click');
}
input.onfocus=function(){
    console.log('focus');
}

當點擊input按鈕,觸發的順序是mousedown–>focus–>up–>click


創建日期對象沒有兼容性問題的是

new Date(year,month,day,hour,minutes,seconds)


一些代碼題

var a={};
b={key:'b'};
c={key:'c'};
a[b]=123;
a[c]=456;
console.log(a[b]);//456
global.name='tester';
var test={
    name:'Chris Dai',
    getName:function(){
        return this.name;
    }
};
var tester=test.getName;
console.log(tester());//tester

console.log(test.getName());//Chris Dai
(function () {var a=b=3;})();
console.log(typeof a!=='undefined');//false
console.log(typeof b!=='undefined');//true
console.log(1+'2'+'2');//122
console.log(1+ +'2'+'2');//32
console.log(1+ -'1'+'2');//02
console.log(+'1'+'1'+'2');//112
console.log('A'-'B'+'2');//NaN2
console.log('A'-'B'+2);//NaN
console.log(NaN==NaN);//false
var a1=111;
console.log(a1);//111
console.log(a2);//undefined
console.log(a3);//報錯
var a2=222;
a3=333;
var i=1;
(function () {
    var start=new Date().getTime();
    var si=setInterval(function () {
        var now=new Date().getTime();
        if(now<(start+100)){
            i++;
        } else {
            console.log(i);
            clearInterval(si);
        }
    },10);
})();
//setInterval不能保證程序從什麼時候開始執行。因此本題答案中的8,9,10是都可以出現的。
發佈了95 篇原創文章 · 獲贊 22 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章