前端面試問題總結(jié)

HTML

html5的新特性

  • 文件類型聲明(<!DOCTYPE>)僅有一型:<!DOCTYPE HTML>。

  • 新的解析順序:不再基于SGML。

  • 繪畫 canvas;

  • 用于媒介回放的 video 和 audio 元素;

  • 語意化更好的內(nèi)容元素:article、footer、header、nav、section;

  • 表單控件:calendar、date、time、email、url、search;

  • input元素的新類型:date, email, url等。

  • 新的技術(shù):webworker, websocket, Geolocation;

  • 新的屬性:ping(用于a與area), charset(用于meta), async(用于script)。

  • 全域?qū)傩裕篿d, tabindex, repeat。

  • 新的全域?qū)傩裕篶ontenteditable, contextmenu, draggable, dropzone, hidden, spellcheck。

  • 新應(yīng)用程序接口:

    • HTML Geolocation
    • HTML Drag and Drop
    • HTML Local Storage
    • HTML Application Cache
    • HTML Web Workers
    • HTML SSE
    • HTML Canvas/WebGL
    • HTML Audio/Video
  • 移除的元素:

    • 純表現(xiàn)的元素:basefont,big,center,font, s,strike,tt,u;
    • 對可用性產(chǎn)生負面影響的元素:frame,frameset,noframes;

Web Worker

Web Worker的基本原理就是在當前javascript的主線程中,使用Worker類加載一個javascript文件來開辟一個新的線程,起到互不阻塞執(zhí)行的效果,并且提供主線程和新線程之間數(shù)據(jù)交換的接口: postMessageonmessage。

JS : worker.js


var math =function(n) {
   //肥腸復雜的數(shù)學計算
};
onmessage =function(evt) {
    var d = evt.data;
    postMessage(d);
};

HTML:

<!DOCTYPE HTML>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <script type="text/javascript">
//WEB頁主線程
var worker =new Worker("worker.js");
//創(chuàng)建一個Worker對象并向它傳遞將在新線程中執(zhí)行的腳本的URL
var data = ... //要計算的數(shù)據(jù)
 worker.postMessage(data);
//向worker發(fā)送數(shù)據(jù)
 worker.onmessage =function(evt){
//接收worker傳過來的數(shù)據(jù)函數(shù)
   console.log(evt.data);
//輸出worker發(fā)送來的數(shù)據(jù)
 }
 </script>
 </head>
 <body></body>
</html>

input元素常見類型

  • button
  • checkbox
  • file
  • hidden
  • image
  • password
  • radio
  • reset
  • submit
  • text

CSS

盒模型

IE 盒子模型、W3C 盒子模型;

區(qū) 別: IE的content部分把 border 和 padding計算了進去;

content-box:讓元素維持W3C的標準盒模型。

布局所占寬度Width:

Width = width + padding-left + padding-right + border-left + border-right

布局所占高度Height:

Height = height + padding-top + padding-bottom + border-top + border-bottom

border-box:讓元素維持IE傳統(tǒng)盒模型(IE6以下版本和IE6~7的怪異模式)。

布局所占寬度Width:

Width = width(包含padding-left + padding-right + border-left + border-right)

布局所占高度Height:

Height = height(包含padding-top + padding-bottom + border-top + border-bottom)

position屬性

  • static:默認的屬性值,按照標準流(包括浮動方式)進行布局。
  • relative:稱為相對定位,使用相對的盒子的位置常以標準量的排版方式為基礎(chǔ),然后使盒子相對于它在原本的標準位置偏移指定的距離.相對定位仍在標準流中,它對父塊和兄弟塊盒子沒有任何影響。
  • absolute:絕對定位,盒子的位置以它的包含框為基準進行偏移。絕對定位從標準流中脫離,并且以它最近的一個已經(jīng)定位祖先元素為基準進行定位。沒有已經(jīng)定位的祖先元素,則以瀏覽器窗口為基準進行定位。
  • inherit:規(guī)定從父元素繼承 position 屬性的值。
  • fixed:固定定位,與絕對定位類似,以瀏覽器窗口為基準進行定位,拖動瀏覽器窗口的滾動條時,位置保持不變。

fixed實例

HTML:

<body>
  <div id="a">
    <div id="c">
        <br>
        <br>
        <br>
    </div>
  </div>
</body>

CSS:

#a{
    height: 300px;
    width: 500px;
    background-color: #7c82ab;
  }
#c{
    width:500px;
    height:auto;
    background-color:#ccc;
    postion:fixed;
    bottom:0px;
}

diplay常用屬性

  • block 像塊類型元素一樣顯示。
  • none 缺省值。像行內(nèi)元素類型一樣顯示。不保留位置,會引起reflow回流和repaint重繪。
  • inline-block 像行內(nèi)元素一樣顯示,但其內(nèi)容象塊類型元素一樣顯示。
  • list-item 像塊類型元素一樣顯示,并添加樣式列表標記。
  • table 此元素會作為塊級表格來顯示
  • inherit 規(guī)定應(yīng)該從父元素繼承 display 屬性的值

清除浮動

1.父級div定義 overflow: auto;

HTML:


<div class="outer over-flow">
    <div class="div1">1</div>
    <div class="div2">2</div>
    <div class="div3">3</div>
</div>

CSS:


.over-flow{
    overflow: auto;
    zoom: 1; /*zoom: 1;for IE6/7 Maxthon2*/
}

2.clear:both;

div{
    float:left;
    clear:both;
}

3.after 方法

.outer {
    zoom:1; /*zoom: 1;for IE6/7 Maxthon2*/
}
.outer:after {
    clear:both;
    content:".";
    display:block; /*for FF/chrome/opera/IE8*/
    width: 0;
    height: 0;
    visibility:hidden;
    }

CSS選擇器

  • id選擇器( # myid)
  • 類選擇器(.myclassname)
  • 標簽選擇器(div, h1, p)
  • 相鄰選擇器(h1 + p)
  • 子選擇器(ul > li)
  • 后代選擇器(li a)
  • 通配符選擇器( * )
  • 屬性選擇器(a[rel = "external"])
  • 偽類選擇器(a:hover, li:nth-child)

CSS3新增偽類:

  • p:first-of-type 選擇屬于其父元素的首個p元素的每個p元素。
  • p:last-of-type 選擇屬于其父元素的最后p元素的每個p元素。
  • p:only-of-type 選擇屬于其父元素唯一的p元素的每個p元素。
  • p:only-child 選擇屬于其父元素的唯一子元素的每個p元素。
  • p:nth-child(2) 選擇屬于其父元素的第二個子元素的每個p元素。
  • :enabled :disabled 控制表單控件的禁用狀態(tài)。
  • :checked 單選框或復選框被選中。

響應(yīng)式布局的原理

  • Meta標簽定義

    • 使用 viewport meta 標簽在手機瀏覽器上控制布局

      <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" />

    • 通過快捷方式打開時全屏顯示

      <meta name="apple-mobile-web-app-capable" content="yes" />

  • 隱藏狀態(tài)欄

    <meta name="apple-mobile-web-app-status-bar-style" content="blank" />

  • iPhone會將看起來像電話號碼的數(shù)字添加電話連接,應(yīng)當關(guān)閉

    <meta name="format-detection" content="telephone=no" />

  • 使用Media Queries適配對應(yīng)樣式

    常用于布局的CSS Media Queries有以下幾種:

    • 設(shè)備類型(media type):

      • all所有設(shè)備;
      • screen 電腦顯示器;
      • print打印用紙或打印預覽視圖;
      • handheld便攜設(shè)備;
      • tv電視機類型的設(shè)備;
      • speech語意和音頻盒成器;
      • braille盲人用點字法觸覺回饋設(shè)備;
      • embossed盲文打印機;
      • projection各種投影設(shè)備;
      • tty使用固定密度字母柵格的媒介,比如電傳打字機和終端。
    • 設(shè)備特性(media feature):

      • width瀏覽器寬度;
      • height瀏覽器高度;
      • device-width設(shè)備屏幕分辨率的寬度值;
      • device-height設(shè)備屏幕分辨率的高度值;
      • orientation瀏覽器窗口的方向縱向還是橫向,當窗口的高度值大于等于寬度時該特性值為portrait,否則為landscape;
      • aspect-ratio比例值,瀏覽器的縱橫比;
      • device-aspect-ratio比例值,屏幕的縱橫比。
  • 設(shè)置多種視圖寬度

@media only screen and (min-width:768px)and(max-width:1024px){}

@media only screen and (width:320px)and (width:768px){}
  • 百分比布局
    • 寬度不固定,可以使用百分比
    #head{width:100%;}
    #content{width:50%;}
    
    • 響應(yīng)式圖片
    #wrap img{
      max-width:100%;
      height:auto;
    

}

* 字體設(shè)置

  一個響應(yīng)式的字體應(yīng)關(guān)聯(lián)它的父容器的寬度,這樣才能適應(yīng)客戶端屏幕。css3引入了新的單位叫做rem,和em類似但對于Html元素,rem更方便使用。em是相對于根元素的,需重置根元素字體大?。?
  ```css
  html{font-size:100%;}
完成后,可以定義響應(yīng)式字體:
@media (min-width:640px){body{font-size:1rem;}}
@media (min-width:960px){body{font-size:1.2rem;}}
@media (min-width:1200px){body{font-size:2rem;}}

absolute和relative的差別

  • relative

    • 生成相對定位的元素,通過top,bottom,left,right的設(shè)置相對于其正常位置進行定位??赏ㄟ^z-index進行層次分級。
    • 定位為relative的元素脫離正常的文本流中,但其在文本流中的位置依然存在。
    • relative定位的層總是相對于其最近的父元素,無論其父元素是何種定位方式。
  • absolute

    • 生成絕對定位的元素,相對于static定位以外的第一個父元素進行定位。元素的位置通過"left","top","right"以及"bottom"屬性進行規(guī)定??赏ㄟ^z-index進行層次分級。
    • 定位為absolute的層脫離正常文本流,但與relative的區(qū)別是其在正常流中的位置不在存在。
    • 對于absolute定位的層總是相對于其最近的定義為absolute或relative的父層,而這個父層并不一定是其直接父層。如果其父層中都未定義absolute或relative,則其將相對body進行定位。

隱藏元素

  1. overflow
  2. opacity
  3. visibility
  4. display
  5. postion
  6. clip/clip-path
  7. z-index

布局

水平垂直居中

鏈接:https://juejin.im/post/5d5a39b66fb9a06afc2540ea

Flex 布局

鏈接:https://zhuanlan.zhihu.com/p/25303493

Grid 布局

鏈接:https://juejin.im/entry/5894135c8fd9c5a19507f6a1

瀑布流布局

鏈接:
https://juejin.im/post/5d365a65e51d454d1d6285eb

BFC

Block formatting context直譯為"塊級格式化上下文"。(普通流)具有BFC特性的元素可以看做是隔離了的獨立容器,容器里面的元素不會再布局上影響到外面的元素,并且BFC具有普通容器所沒有的一些特性。

BFC 布局規(guī)則
  • 內(nèi)部的Box會在垂直方向,一個接一個地放置。
  • Box垂直方向的距離由margin決定。屬于同一個BFC的兩個相鄰Box的margin會發(fā)生重疊
  • 每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對于從左往右的格式化,否則相反)。即使存在浮動也是如此。
  • BFC的區(qū)域不會與float box重疊。
  • BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此。
  • 計算BFC的高度時,浮動元素也參與計算
觸發(fā)BFC

只要元素滿足下面任一條件即可觸發(fā)BFC特性:

  • float屬性不為none.
  • position屬性不為static和relative.
  • display屬性為下列之一:table-cell,table-caption,inline-block,flex,or inline-flex.
  • overflow屬性不為visible.

HTTP

狀態(tài)碼

1. 常見狀態(tài)碼

  • 200 - 請求成功
  • 301 - 資源(網(wǎng)頁等)被永久轉(zhuǎn)移到其它URL
  • 304 - Not Modified,客戶端則直接從本地緩存中將頁面調(diào)取
  • 404 - 請求的資源(網(wǎng)頁等)不存在
  • 500 - 內(nèi)部服務(wù)器錯誤

2. 狀態(tài)碼分類

  • 1** 信息,服務(wù)器收到請求,需要請求者繼續(xù)執(zhí)行操作
  • 2** 成功,操作被成功接收并處理
  • 3** 重定向,需要進一步的操作以完成請求
  • 4** 客戶端錯誤,請求包含語法錯誤或無法完成請求
  • 5** 服務(wù)器錯誤,服務(wù)器在處理請求的過程中發(fā)生了錯誤

請求方式

  • GET:GET是http的默認請求方式, 一般用來獲取數(shù)據(jù)。
  • HEAD:HEAD方法與GET方法一樣,都是向服務(wù)器發(fā)出指定資源的請求。但是,服務(wù)器在響應(yīng)HEAD請求時不會回傳資源的內(nèi)容部分,即:響應(yīng)主體。這樣,我們可以不傳輸全部內(nèi)容的情況下,就可以獲取服務(wù)器的響應(yīng)頭信息。HEAD方法常被用于客戶端查看服務(wù)器的性能。
  • POST:POST請求會向指定資源提交數(shù)據(jù),請求服務(wù)器進行處理。如:表單提交、文件上傳。
  • PUT:PUT請求會身向指定資源位置上傳其最新內(nèi)容,通過該方法客戶端可以將指定資源的最新數(shù)據(jù)傳送給服務(wù)器取代指定的資源的內(nèi)容。
  • DELETE:DELETE請求用于請求服務(wù)器刪除所請求URI所標識的資源。DELETE請求后指定資源會被刪除。
  • TRACE:返回接受到的請求,用來查看數(shù)據(jù)經(jīng)過中間服務(wù)器時發(fā)生了哪些變動。
  • OPTIONS:OPTIONS請求與HEAD類似,一般也是用于客戶端查看服務(wù)器的性能。 這個方法會請求服務(wù)器返回該資源所支持的所有HTTP請求方法,該方法會用'*'來代替資源名稱,向服務(wù)器發(fā)送OPTIONS請求,可以測試服務(wù)器功能是否正常。JavaScript的XMLHttpRequest對象進行CORS跨域資源共享時,就是使用OPTIONS方法發(fā)送嗅探請求,以判斷是否有對指定資源的訪問權(quán)限。
  • CONNECT:要求使用SSL和TLS進行TCP通信。
  • PATCH:請求修改局部數(shù)據(jù)

RESTful架構(gòu)

REST是一種架構(gòu)風格:無狀態(tài),以資源為中心,充分利用HTTP協(xié)議和URI協(xié)議,提供統(tǒng)一的接口定義,使得它作為一種設(shè)計Web服務(wù)的方法而變得流行。在某種意義上,通過強調(diào)URI和HTTP等早期Internet標準,REST是對大型應(yīng)用程序服務(wù)器時代之前的Web方式的回歸。

架構(gòu)約束:

  • 客戶-服務(wù)器:通信只能由客戶端單方面發(fā)起,表現(xiàn)為請求-響應(yīng)的形式。
  • 無狀態(tài):通信的會話狀態(tài)(Session State)應(yīng)該全部由客戶端負責維護。
  • 緩存:響應(yīng)內(nèi)容可以在通信鏈的某處被緩存,以改善網(wǎng)絡(luò)效率。
  • 統(tǒng)一接口:通信鏈的組件之間通過統(tǒng)一的接口相互通信,以提高交互的可見性。
  • 分層系統(tǒng):通過限制組件的行為(即,每個組件只能"看到"與其交互的緊鄰層),將架構(gòu)分解為若干等級的層。
  • 按需代碼:支持通過下載并執(zhí)行一些代碼(例如Java Applet、Flash或JavaScript),對客戶端的功能進行擴展。

主要特征:

  • 面向資源(Resource Oriented)
  • 可尋址(Addressability)
  • 連通性(Connectedness)
  • 無狀態(tài)(Statelessness)
  • 統(tǒng)一接口(Uniform Interface)
  • 超文本驅(qū)動(Hypertext Driven)

WebSocket原理

Websocket是應(yīng)用層第七層上的一個應(yīng)用層協(xié)議,它必須依賴 HTTP 協(xié)議進行一次握手 ,握手成功后,數(shù)據(jù)就直接從 TCP 通道傳輸,與 HTTP 無關(guān)了。

Websocket的數(shù)據(jù)傳輸是frame形式傳輸?shù)?,比如會將一條消息分為幾個frame,按照先后順序傳輸出去。這樣做會有幾個好處:

1 大數(shù)據(jù)的傳輸可以分片傳輸,不用考慮到數(shù)據(jù)大小導致的長度標志位不足夠的情況。

2 和http的chunk一樣,可以邊生成數(shù)據(jù)邊傳遞消息,即提高傳輸效率。

HTTP2新特性

鏈接:https://juejin.im/post/5b88a4f56fb9a01a0b31a67e
來源:掘金

HTTP/2的通過支持請求與響應(yīng)的多路復用來減少延遲,通過壓縮HTTP首部字段將協(xié)議開銷降至最低,同時增加對請求優(yōu)先級和服務(wù)器端推送的支持。

1. 二進制分幀

HTTP/2 采用二進制格式傳輸數(shù)據(jù),而非 HTTP 1.x 的文本格式,二進制協(xié)議解析起來更高效。 HTTP / 1 的請求和響應(yīng)報文,都是由起始行,首部和實體正文(可選)組成,各部分之間以文本換行符分隔。HTTP/2 將請求和響應(yīng)數(shù)據(jù)分割為更小的幀,并且它們采用二進制編碼。
HTTP/2 中,同域名下所有通信都在單個連接上完成,該連接可以承載任意數(shù)量的雙向數(shù)據(jù)流。每個數(shù)據(jù)流都以消息的形式發(fā)送,而消息又由一個或多個幀組成。多個幀之間可以亂序發(fā)送,根據(jù)幀首部的流標識可以重新組裝。

2. 多路復用

多路復用,代替原來的序列和阻塞機制。所有就是請求的都是通過一個 TCP連接并發(fā)完成。 HTTP 1.x 中,如果想并發(fā)多個請求,必須使用多個 TCP 鏈接,且瀏覽器為了控制資源,還會對單個域名有 6-8個的TCP鏈接請求限制。
在 HTTP/2 中,有了二進制分幀之后,HTTP /2 不再依賴 TCP 鏈接去實現(xiàn)多流并行了,在 HTTP/2中:

  • 同域名下所有通信都在單個連接上完成。
  • 單個連接可以承載任意數(shù)量的雙向數(shù)據(jù)流。
  • 數(shù)據(jù)流以消息的形式發(fā)送,而消息又由一個或多個幀組成,多個幀之間可以亂序發(fā)送,因為根據(jù)幀首部的流標識可以重新組裝。
    這一特性,使性能有了極大提升:
  • 同個域名只需要占用一個 TCP 連接,消除了因多個 TCP 連接而帶來的延時和內(nèi)存消耗。
  • 單個連接上可以并行交錯的請求和響應(yīng),之間互不干擾。
  • 在HTTP/2中,每個請求都可以帶一個31bit的優(yōu)先值,0表示最高優(yōu)先級, 數(shù)值越大優(yōu)先級越低。有了這個優(yōu)先值,客戶端和服務(wù)器就可以在處理不同的流時采取不同的策略,以最優(yōu)的方式發(fā)送流、消息和幀。
3. 服務(wù)器推送

服務(wù)端可以在發(fā)送頁面HTML時主動推送其它資源,而不用等到瀏覽器解析到相應(yīng)位置,發(fā)起請求再響應(yīng)。例如服務(wù)端可以主動把JS和CSS文件推送給客戶端,而不需要客戶端解析HTML時再發(fā)送這些請求。
服務(wù)端可以主動推送,客戶端也有權(quán)利選擇是否接收。如果服務(wù)端推送的資源已經(jīng)被瀏覽器緩存過,瀏覽器可以通過發(fā)送RST_STREAM幀來拒收。主動推送也遵守同源策略,服務(wù)器不會隨便推送第三方資源給客戶端。

4. 頭部壓縮

HTTP 1.1請求的大小變得越來越大,有時甚至會大于TCP窗口的初始大小,因為它們需要等待帶著ACK的響應(yīng)回來以后才能繼續(xù)被發(fā)送。HTTP/2對消息頭采用HPACK(專為http/2頭部設(shè)計的壓縮格式)進行壓縮傳輸,能夠節(jié)省消息頭占用的網(wǎng)絡(luò)的流量。而HTTP/1.x每次請求,都會攜帶大量冗余頭信息,浪費了很多帶寬資源。
為了減少這塊的資源消耗并提升性能, HTTP/2對這些首部采取了壓縮策略:

  • HTTP/2在客戶端和服務(wù)器端使用“首部表”來跟蹤和存儲之前發(fā)送的鍵-值對,對于相同的數(shù)據(jù),不再通過每次請求和響應(yīng)發(fā)送;
  • 首部表在HTTP/2的連接存續(xù)期內(nèi)始終存在,由客戶端和服務(wù)器共同漸進地更新;
  • 每個新的首部鍵-值對要么被追加到當前表的末尾,要么替換表中之前的值。

5. 應(yīng)用層的重置連接

對于 HTTP/1 來說,是通過設(shè)置 tcp segment 里的 reset flag 來通知對端關(guān)閉連接的。這種方式會直接斷開連接,下次再發(fā)請求就必須重新建立連接。HTTP/2 引入 RST_STREAM 類型的 frame,可以在不斷開連接的前提下取消某個 request 的 stream,表現(xiàn)更好。

6. 請求優(yōu)先級設(shè)置

HTTP/2 里的每個 stream 都可以設(shè)置依賴 (Dependency) 和權(quán)重,可以按依賴樹分配優(yōu)先級,解決了關(guān)鍵請求被阻塞的問題

7. 流量控制

每個 http2 流都擁有自己的公示的流量窗口,它可以限制另一端發(fā)送數(shù)據(jù)。對于每個流來說,兩端都必須告訴對方自己還有足夠的空間來處理新的數(shù)據(jù),而在該窗口被擴大前,另一端只被允許發(fā)送這么多數(shù)據(jù)。

關(guān)于流量控制詳見: How does it work ?- 流量控制

8. HTTP/1 的幾種優(yōu)化可以棄用

合并文件、內(nèi)聯(lián)資源、雪碧圖、域名分片對于 HTTP/2 來說是不必要的,使用 h2 盡可能將資源細粒化,文件分解地盡可能散,不用擔心請求數(shù)多

瀏覽器緩存機制

鏈接: http://www.lxweimin.com/p/54cc04190252
來源:簡書

localStorage, sessionStorage, Cookie, Session

特性 Cookie localStorage sessionStorage
數(shù)據(jù)的生命期 一般由服務(wù)器生成,可設(shè)置失效時間。如果在瀏覽器端生成Cookie,默認是關(guān)閉瀏覽器后失效 除非被清除,否則永久保存 僅在當前會話下有效,關(guān)閉頁面或瀏覽器后被清除
存放數(shù)據(jù)大小 4K左右,很多瀏覽器都限制一個站點最多保存20個Cookie 一般為5MB 一 般為5MB
與服務(wù)器端通信 每次都會攜帶在HTTP頭中,如果使用cookie保存過多數(shù)據(jù)會帶來性能問題 僅在客戶端(即瀏覽器)中保存,不參與和服務(wù)器的通信 僅在客戶端(即瀏覽器)中保存,不參與和服務(wù)器的通信
易用性 需要程序員自己封裝,源生的Cookie接口不友好 源生接口可以接受,亦可再次封裝來對Object和Array有更好的支持 源生接口可以接受,亦可再次封裝來對Object和Array有更好的支持

前端模塊化

鏈接:https://juejin.im/post/5aaa37c8f265da23945f365c
來源:掘金

前端安全

鏈接: https://zhuanlan.zhihu.com/p/83865185
來源:知乎

DNS解析

原理

https://juejin.im/post/5b0a32a36fb9a07ab979f0b4
原理鏈接:
來源: 掘金

基于的協(xié)議:

區(qū)域傳送時使用TCP,主要有一下兩點考慮:
1.輔域名服務(wù)器會定時(一般時3小時)向主域名服務(wù)器進行查詢以便了解數(shù)據(jù)是否有變動。如有變動,則會執(zhí)行一次區(qū)域傳送,進行數(shù)據(jù)同步。區(qū)域傳送將使用TCP而不是UDP,因為數(shù)據(jù)同步傳送的數(shù)據(jù)量比一個請求和應(yīng)答的數(shù)據(jù)量要多得多。
2.TCP是一種可靠的連接,保證了數(shù)據(jù)的準確性。

域名解析時使用UDP協(xié)議:
客戶端向DNS服務(wù)器查詢域名,一般返回的內(nèi)容都不超過512字節(jié),用UDP傳輸即可。不用經(jīng)過TCP三次握手,這樣DNS服務(wù)器負載更低,響應(yīng)更快。雖然從理論上說,客戶端也可以指定向DNS服務(wù)器查詢的時候使用TCP,但事實上,很多DNS服務(wù)器進行配置的時候,僅支持UDP查詢包。

Vue

vue面試題:

  1. https://github.com/fengshi123/blog
    來源:GitHub

  2. https://segmentfault.com/a/1190000016344599
    來源:segmentfault

Vue數(shù)據(jù)雙向綁定機制

鏈接:https://segmentfault.com/a/1190000006599500
來源:segmentfault

虛擬DOM

鏈接:https://juejin.im/post/5d36cc575188257aea108a74
來源:掘金

Vuex和Vue-bus的區(qū)別

https://juejin.im/post/5c09cb73518825159512778b
來源:掘金

Vue 的diff算法https://juejin.im/post/5ce4c113518825526b293de1

https://juejin.im/post/5ad6182df265da23906c8627
來源:掘金

組件化

鏈接:https://juejin.im/post/5ce4c113518825526b293de1

來源:掘金

JavaScript

基本數(shù)據(jù)類型

值類型(基本類型):字符串(String)、數(shù)字(Number)、布爾(Boolean)、對空(Null)、未定義(Undefined)、Symbol。
引用數(shù)據(jù)類型:對象(Object)、數(shù)組(Array)、函數(shù)(Function)。

引用變量和數(shù)值變量

  • 基本類型值 簡單的數(shù)據(jù)段,保存在棧內(nèi)存中;typeof檢測。
  • 引用類型值 可能有多個值構(gòu)成的對象,保存在堆內(nèi)存中;instanceof檢測。

與其他語言不用,JavaScript不允許直接訪問內(nèi)存中的位置,也就是說不能直接操作對象的內(nèi)存空間。在操作對象時,實際上是在操作對象的引用而不是實際的對象。也就是說包含引用類型值的變量實際上包含的并不是對象本身,而是一個指向該對象的指針。

  • 按值訪問相當于是將原數(shù)據(jù)的值進行一次拷貝,給新的變量,原變量發(fā)生改變后,按值訪問的不會變化。一般是string,number這樣的基本類型。

    var a = 1;
    var b = a;
    alert(a+";"+b);//1;1
    a = 2;
    alert(a+";"+b);//2;1  b不會發(fā)生改變,因為是按值訪問
    
  • 按引用是指在內(nèi)存區(qū)內(nèi)只有一份,新的變量只是擁有一個指向它的指針,一旦內(nèi)存區(qū)內(nèi)的內(nèi)容發(fā)生變化,所有指向它的引用都將發(fā)生變化,一般是對象,包括用戶自定義對象和內(nèi)置對象,Array和Function。

    var a = {name: "Zoe"};
    var b = a;
    console.log(a.name);//Zoe
    console.log(b.name);//Zoe
    
    a.name = "Alex"; 
    console.log(a.name);//Alex
    console.log(b.name);//Alex 按引用訪問,指針指向的區(qū)域已經(jīng)被更改
    

變量提升

JavaScript 中,函數(shù)及變量的聲明都將被提升到函數(shù)的最頂部。
JavaScript 中,變量可以在使用后聲明,也就是變量可以先使用再聲明。

var變量提升

console.log(a);
var a =1;

// 等價于

var a ;
console.log(a); // 1
a = 1; 

function提升

a(); // 1

function a() {
    console.log(1);
}

JavaScript 只有聲明的變量會提升,初始化的不會。

var x = 5; // 初始化 x

elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y;           // 顯示 x 和 undefined

var y = 7; // 初始化 y

JavaScript引擎的工作方式是,先解析代碼,獲取所有被聲明的變量,然后再一行一行地運行。這造成的結(jié)果,就是所有的變量的聲明語句,都會被提升到代碼的頭部,叫做變量提升(hoisting)??梢杂胠et來約束。let 聲明的變量的作用域是塊級的。

閉包

JavaScript 變量屬于本地或全局作用域。當一個內(nèi)部函數(shù)被其外部函數(shù)之外的變量引用時,就形成了一個閉包。
全局變量能夠通過閉包實現(xiàn)局部(私有)。

var cat = (function(){
  var name = 'secret'; //name變量私有化,外部無法訪問
  return {
    get_name: function() {
      return name;
    },
    set_name: function(new_name) {
      name = new_name;
    }
  }
}());
cat.get_name (); //得到'secret'
cat.name; //Type error
cat.set_name('m');
cat.get_name(); // 'm'

多人合作的項目中如何解決命名空間沖突

  • 防止全局聲明的修改
  • 防止其他來源代碼的修改
  • 模塊化開發(fā)
  • 命名空間
  var ValidateUtil = {
    type1 : function(){};
    type2: function(){};
  };

Promise

  • 對象的狀態(tài)不受外界影響。有三種狀態(tài):padding(進行中)、fulfilled(成功)、rejected(失敗)。只有異步操作的結(jié)果,可以決定當前是哪一種狀態(tài),任何其他操作都無法改變這個狀態(tài)。
  • 一旦狀態(tài)改變,就不會再變,任何時候都可以得到這個結(jié)果。三個狀態(tài)只有從padding到fulfilled或者從padding到rejected。狀態(tài)只有從padding改變到fulfilled或者refected,兩種改變。
//基本用法
 new Promise(function (resolve,reject) {
        console.log('promise準備階段');
        resolve("成功!");
        reject("失敗!");
    })

//實例
 function asyncPro(msg){
        return new Promise(function (resolve,reject) {
            console.log(msg+':promise準備階段');
            resolve(msg+'成功!');
            reject(msg+"失??!");
        });
    }
    asyncPro('第一步').then(function (msg) {
        console.log(msg);
        return asyncPro('第二步');
    }).then(function (msg) {
        console.log(msg);
        return asyncPro('第三步');
    }).then(function(msg){
        console.log(msg);
    });

原生ajax

  //1. 創(chuàng)建ajax對象
  var xhr = null;
  if(window.XMLHttpRequest){
      xhr = new XMLHttpRequest();
  } else {
      //為了兼容IE6
      xhr = new ActiveXObject('Microsoft.XMLHTTP');
  }

  //2. 連接服務(wù)器open(方法GET/POST,請求地址, 異步傳輸)
  xhr.open('GET',  'data.txt',  true);

  //3. 發(fā)送請求
  xhr.send();

  //4.處理返回數(shù)據(jù)
  /*
  ** 每當readyState改變時,就會觸發(fā)onreadystatechange事件
  ** readyState屬性存儲有XMLHttpRequest的狀態(tài)信息
  ** 0 :請求未初始化
  ** 1 :服務(wù)器連接已建立
  ** 2 :請求已接受
  ** 3 : 請求處理中
  ** 4 :請求已完成,且相應(yīng)就緒
  */
  xhr.onreadystatechange = function(){
      if(xhr.readyState == 4){
          /*
          ** Http狀態(tài)碼
          ** 1xx :信息展示
          ** 2xx :成功
          ** 3xx :重定向
          ** 4xx : 客戶端錯誤
          ** 5xx :服務(wù)器端錯誤
          */
          if(xhr.status == 200){
              success(xhr.responseText);
          } else {
              if(failed){
                  failed(xhr.status);
              }
          }
      }
  }

什么是內(nèi)存泄漏

JavaScript中最常用的垃圾收集方式是標記清除(mark-and-sweep)。當變量進入環(huán)境(例如,在函數(shù)中聲明一個變量)時,就將這個變量標記為“進入環(huán)境”。從邏輯上講,永遠不能釋放進入環(huán)境的變量所占的內(nèi)存,因為只要執(zhí)行流進入相應(yīng)的環(huán)境,就可能用到它們。而當變量離開環(huán)境時,這將其 標記為“離開環(huán)境”。
雖然JavaScript 會自動垃圾收集,但是如果我們的代碼寫法不當,會讓變量一直處于“進入環(huán)境”的狀態(tài),無法被回收。

常見內(nèi)存泄漏的原因

  • 循環(huán)引用
function cycle() {
    var o1 = {};
    var o2 = {};
    o1.a = o2;
    o2.a = o1; 

    return "Cycle reference!"
}
cycle();
  • 全局變量引起的內(nèi)存泄漏

    function yyy(){
      yyy = 'xxxxxx';//yyy 成為一個全局變量,不會被回收
    }
    
  • 閉包引起的內(nèi)存泄漏

      var yyy = (function(){
          var yyy = 'xxxxxx';// 被閉包所引用,不會被回收
          return function(){
              console.log(yyy);
          }
      })()
    
  • dom清空或刪除時,事件未清除導致的內(nèi)存泄漏

      <div id="container">
      </div>
      $('#container').bind('click', function(){
          console.log('click');
      }).remove();
      //把事件清除了,即可從內(nèi)存中移除
      <div id="container">
      </div>
      $('#container').bind('click', function(){
          console.log('click');
      }).off('click').remove();
    

清空數(shù)組的常用方法

  • 將數(shù)組 length 賦值為0
  • 將數(shù)組賦值為[ ]
  • splice()刪除數(shù)組元素arr.splice(0, arr.length);

bind,call,apply的用法

  • Function.prototype.call()和Function.prototype.apply()

call()和apply()可以看作為某個對象的方法,通過調(diào)用方法的形式來間接調(diào)用函數(shù)。 它們的第一個參數(shù)是要調(diào)用函數(shù)的母對象,它是調(diào)用上下文,在函數(shù)體內(nèi)通過this來獲得對它的引用。 apply()方法和call()方法的作用相同,只不過函數(shù)傳遞的方式不一樣,它的實參都放入在一個數(shù)組中。

    var n = {};
   
   function f(a, b) {
     return a + b;
   }
   
   f.call(n, 1, 2);        // 將函數(shù)f作為n的方法,實際上就是重新設(shè)置函數(shù)f的上下文
   f.apply(n, [1, 2]);
  • Function.prototype.bind()

bind()是在ES5中新增的方法,從名字可以看出,這個方法的主要作用就是將函數(shù)綁定到某個對象。 當在函數(shù)f()上調(diào)用bind()方法并后傳入一個對象n作為參數(shù),這個方法將返回一個新函數(shù): (以函數(shù)調(diào)用的方式)調(diào)用新的函數(shù)將會把原始的函數(shù)f()作為n的方法來調(diào)用。例如:

```js
function f(y) {
  return this.x + y;
}

var a = {
  x: 1
};

var m = f.bind(a);  // 通過調(diào)用 g(x) 來調(diào)用 a.f(x)
m(2); // 3
```

實現(xiàn)bind()方法:

```js
// 返回一個函數(shù),通過調(diào)用它來調(diào)用n中的方法f(),傳遞它所有的實參
function bind(f, n) {
  if (f.bind) return f.bind(n); // 如果bind()方法存在,使用bind()方法
  else return function () {
    return f.apply(n, arguments);
  }
}
```

$(document).ready() 與window.onload的區(qū)別

  • 執(zhí)行時間不同
    window.onload必須等到頁面內(nèi)包括圖片的所有元素加載完畢后才能執(zhí)行。
    $(document).ready()是DOM結(jié)構(gòu)繪制完畢后就執(zhí)行,不必等到加載完畢。

  • 編寫個數(shù)不同

    window.onload不能同時編寫多個,如果有多個window.onload方法,只會執(zhí)行一個
    $(document).ready()可以同時編寫多個,并且都可以得到執(zhí)行

  • 簡化寫法

    window.onload沒有簡化寫法
    (document).ready(function(){})可以簡寫成(function(){});

事件監(jiān)聽

  • element.addEventListener(type, listener[, useCapture]); // IE6~8不支持
  • element.attachEvent('on' + type, listener); // IE6~10,IE11不支持
  • element['on' + type] = function(){} // 所有瀏覽器

DEMO:

function test() {
    console.log(1);
    }
element.addEventListener('click', test, false);
element.attachEvent('onclick', test);
element.onclick = test;

原型鏈

在JavaScript中,每個對象都有一個指向它的原型對象的內(nèi)部鏈接。這個原型對象又有自己的原型,直到某個對象的原型為null為止,組成這條鏈的最后一環(huán)。這種一級一級的鏈結(jié)構(gòu)就成為原型鏈。

ES6寫法:

class a {
    constructor(name) {
    this.name = name;
    }
speak() {
    console.log(this.name + ' lalala');
    }
}
class aa extends a {
    speak() {
    console.log(this.name + ' hahaha');
     }
}

字符串反轉(zhuǎn)

JS方法:

  var reverseString = function(string) {
     string = string.split('').reverse().join('');
     return string;
  };

CSS方法:

  p{
      direction: rtl;
      unicode-bidi: bidi-override;
  }

滾動條監(jiān)聽

瀏覽器事件循環(huán)

鏈接:https://juejin.im/post/5afbc62151882542af04112d

function a () {
  console.log('---1---');
  setTimeout(() => {
    console.log('---2---');
    Promise.resolve().then(() => {
      console.log('-----3------');
    });
  }, 0);

  setTimeout(() => {
    console.log('---4---');
  }, 0);

  Promise.resolve().then(() => {
    console.log('---5---');

    return Promise.resolve().then(() => {
      console.log('---6---');
    });
  }).then(() => {
    console.log('---7---');
  });
}

/** 輸出
* ---1---
* ---5---
* ---6---
* ---7---
* undefined
* ---2---
* ---3---
*  ---4---
*/

跨域常用解決方案

  • JSONP
    利用<script>標簽沒有跨域限制的“漏洞”來達到與第三方通訊的目的。當需要通訊時,本站腳本創(chuàng)建一個<script>元素,地址指向第三方的API網(wǎng)址,形如:<script src="http://www.example.net/api?param1=1&param2=2"></script> 并提供一個回調(diào)函數(shù)來接收數(shù)據(jù)(函數(shù)名可約定,或通過地址參數(shù)傳遞)。
    第三方產(chǎn)生的響應(yīng)為json數(shù)據(jù)的包裝(故稱之為jsonp,即json padding),形如: callback({"name":"hax","gender":"Male"}) 這樣瀏覽器會調(diào)用callback函數(shù),并傳遞解析后json對象作為參數(shù)。本站腳本可在callback函數(shù)里處理所傳入的數(shù)據(jù)。

  • CORS 通過設(shè)置響應(yīng)頭的 Access-Control-Allow-Origin

  • window.name

  • window.postMessage() HTML5新特性

  • location.hash

  • document.domain

同源策略: 域名,協(xié)議,端口相同。

事件委托

對“事件處理程序過多” 問題的解決方案就是事件委托。事件委托利用了事件冒泡,只指定一個事件處理程序,就可以管理某一類的所有事件。例如,click事件會一直冒泡到document層次,所以我們可以為整個頁面制定一個onclick事件處理程序,而不必給每個可單機的元素分別添加事件處理程序。

HTML

<ul id="myLinks">
  <li id="a"></li>
  <li id="b"></li>
  <li id="c"></li>
</ul>

JavaScript

  var list = document.getElementById("myLinks");

  EventUtil.addHandler(list, "click", function(event){
    event = EventUtil.getEvent(event);

    switch(target.id){
      case "a":
        console.log("1");
        break;

      case "b":
        console.log("2");
        break;

      case "c":
        console.log("3"):
        break;
    }
  });

原生模態(tài)框

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <style type="text/css">
.lightbox {
  display: none;
}

/* Opened lightbox */
.lightbox:target {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Lightbox content */
.lightbox figcaption {
  width: 25rem;
  position: relative;
  padding: 1.5em;
  background-color: #fff;
}

/* Close button */
.lightbox .close {
  position: relative;
  display: block;
}

.lightbox .close::after {
  right: -1rem;
  top: -1rem;
  width: 2rem;
  height: 2rem;
  position: absolute;
  display: flex;
  z-index: 1;
  align-items: center;
  justify-content: center;
  background-color: black;
  border-radius: 50%;
  color: white;
  content: "×";
}

/* Lightbox overlay */
.lightbox .close::before {
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  position: fixed;
  background-color: rgba(0,0,0,.7);
  content: "";
  cursor: default;
}
    </style>
  </head>
  <body>
    <a href="#example">open</a>
    <div class="lightbox" id="example">
      <figure>
        <a href="#" class="close"></a>
        <figcaption>test</figcaption>
      </figure>
    </div>
  </body>
</html>

跑馬燈

鏈接: https://segmentfault.com/a/1190000016903385
來源:segment fault

Tab

鏈接:http://www.lxweimin.com/p/168fa8cc7e7b

輪播圖

鏈接: http://www.lxweimin.com/p/d3c650a5c994

函數(shù)節(jié)流和函數(shù)防抖

函數(shù)防抖(debounce):在事件被觸發(fā)n秒后再執(zhí)行回調(diào),如果在這n秒內(nèi)又被觸發(fā),則重新計時。即:只有任務(wù)觸發(fā)的間隔超過指定間隔的時候,任務(wù)才會執(zhí)行。
函數(shù)防抖原理:通過閉包保存一個標記來保存 setTimeout 返回的值,每當用戶輸入的時候把前一個 setTimeout clear 掉,然后又創(chuàng)建一個新的 setTimeout,這樣就能保證輸入字符后的 interval 間隔內(nèi)如果還有字符輸入的話,就不會執(zhí)行 fn 函數(shù)了。

function debounce(fn, interval) {
    let timeout = null;
    return function () {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            fn.apply(this, arguments);
        }, interval);
    };
}

函數(shù)節(jié)流(throttle) :規(guī)定在一個單位時間內(nèi),只能觸發(fā)一次函數(shù)。如果這個單位時間內(nèi)觸發(fā)多次函數(shù),只有一次生效。
函數(shù)節(jié)流原理:函數(shù)的節(jié)流就是通過閉包保存一個標記(canRun = true),在函數(shù)的開頭判斷這個標記是否為 true,如果為 true 的話就繼續(xù)執(zhí)行函數(shù),否則則 return 掉,判斷完標記后立即把這個標記設(shè)為 false,然后把外部傳入的函數(shù)的執(zhí)行包在一個 setTimeout 中,最后在 setTimeout 執(zhí)行完畢后再把標記設(shè)置為 true(這里很關(guān)鍵),表示可以執(zhí)行下一次的循環(huán)了。當 setTimeout 還未執(zhí)行的時候,canRun 這個標記始終為 false,在開頭的判斷中被 return 掉。

function throttle(fn, interval = 300) {
   let canRun = true;
   return function () {
       if (!canRun) return;
       canRun = false;
       setTimeout(() => {
           fn.apply(this, arguments);
           canRun = true;
       }, interval);
   };
}

應(yīng)用場景
  • debounce

    • search搜索聯(lián)想,用戶在不斷輸入值時,用防抖來節(jié)約請求資源。
    • window觸發(fā)resize的時候,不斷的調(diào)整瀏覽器窗口大小會不斷的觸發(fā)這個事件,用防抖來讓其只觸發(fā)一次
  • throttle

    • 鼠標不斷點擊觸發(fā),mousedown(單位時間內(nèi)只觸發(fā)一次)
    • 監(jiān)聽滾動事件,比如是否滑到底部自動加載更多,用throttle來判斷

大數(shù)相加

Number類型的精度是2的53次方。

function add(n, m) {
  // 操作數(shù)類型判斷, 要求為字符串。不滿足條件則拋出異常。
  if (typeof n !== 'string' || typeof m !== 'string') {
    throw new Error('數(shù)據(jù)類型錯誤, 大數(shù)相加操作數(shù)為字符串!');
  }

  // 數(shù)據(jù)反轉(zhuǎn), 方便后面的遍歷求和
  n = n.split('').reverse();
  m = m.split('').reverse();

  // 獲取較長的位數(shù), 并作為后面對應(yīng)位數(shù)遍歷的最大值
  const maxLength = Math.max(n.length, m.length);

  // 計算過程中, 臨時變量
  let tempN = 0; // 臨時存儲第1個操作數(shù)
  let tempM = 0; // 臨時存儲第2個操作數(shù)
  let tempAdd = 0; // 臨時存儲對應(yīng)位上的數(shù)相加的和
  let extNum = 0; // 滿10進1,保存進的值(1 或 0)

  // 計算結(jié)果
  const res = []; // 應(yīng)位上的書相加的和

  // 遍歷每一位上的數(shù)字,并求和。記錄滿十進一
  for (let index = 0; index < maxLength; index++) {
    // 缺位補0
    tempN = n[index] || 0;
    tempM = m[index] || 0;

    // 對應(yīng)位上的數(shù)字求和
    tempAdd = Number(tempN) + Number(tempM);

    // 進一(extNum 為進 1)
    if (extNum) {
      tempAdd += extNum;
    }

    // 滿十(存儲需要進的 1)
    extNum = tempAdd >= 10 ? 1 : 0;

    // 最后一位滿十進的一直接保存在當前求得的和中, 非最后一位則取 %10 后的值
    if (index === (maxLength - 1) && extNum) {
      res.push(tempAdd);
    } else {
      res.push(tempAdd % 10);
    }
  }

  // 返回計算后的數(shù)時注意翻轉(zhuǎn)
  return res.reverse().join('');
}

大數(shù)相減

大數(shù)相乘

大數(shù)相除

解決 0.1 + 0.2 != 0.3

在JavaScript中的二進制的浮點數(shù)0.1和0.2并不是十分精確,在他們相加的結(jié)果并非正好等于0.3,而是一個比較接近的數(shù)字 0.30000000000000004 ,所以條件判斷結(jié)果為 false。

    function numbersequal(a,b){
        return Math.abs(a-b)<Number.EPSILON;
    }
    
    var a=0.1 + 0.2;
    var b=0.3;
    console.log(numbersequal(a,b));  //true

算法

二叉樹遞歸遍歷

鏈接:http://www.lxweimin.com/p/72ea83e2feab
來源:簡書

二叉樹非遞歸遍歷

鏈接:https://juejin.im/post/5e1181445188253a5b3cd5cf

鏈表

鏈接:https://juejin.im/post/5b87c60c6fb9a019fa06495b
來源:掘金

查找URL中的參數(shù)

  1. 指定參數(shù)名稱,返回該參數(shù)的值或者空字符串
  2. 不指定參數(shù)名稱,返回全部的參數(shù)對象或者{}
  3. 如果存在多個同名參數(shù),則返回數(shù)組
function getUrlParam(sUrl,sKey){
    var result = {};
    sUrl.replace(/\??(\w+)=(\w+)&?/g,function(a,k,v){
        if(result[k] !== void 0){
            var t = result[k];
            result[k] = [].concat(t,v);
        }else{
            result[k] = v;
        }
    });
    if(sKey === void 0){
        return result;
    }else{
        return result[sKey] || '';
    }
}

斐波那契數(shù)列

用 JavaScript 實現(xiàn)斐波那契數(shù)列函數(shù),返回第n個斐波那契數(shù)。 f(1) = 1, f(2) = 1 等

//遞歸
function fibonacci(n) {
    if(n<0){
        return -1;
    }else if(n < 2){
        return n;
    }else{
       return arguments.callee(n-1) +  arguments.callee(n-2);
    }
}

//非遞歸
function getNthFibonacci(count) {
    if(count<0) return 0;
    if(count<=1) return 1;
    var first = 1;
    var second = 1;
    var third = 0;
    for(var i = 2; i <= count; i++) {
        third = first + second;
        first = second;
        second = third;
    }
    return third;
}

返回斐波那契數(shù)列函數(shù)

輸入大于0的整數(shù)n返回長度為n的斐波那契數(shù)列。

function fibonacci(n) {
  var result = [1,1];
    if(n <= 0){
        return -1;
    }else if(n == 1){
      result.pop(1);
    }else {
       for(var i = 2; i < n; i++){
         result.push(result[i-1] + result[i-2]);
       }
    }
    return result;
}

修改 this 指向

題目描述

封裝函數(shù) f,使 f 的 this 指向指定的對象
輸入例子:

bindThis(function(a, b){return this.test + a + b}, {test: 1})(2, 3)

輸出例子:

6

function bindThis(f, oTarget) {
    return f.bind(oTarget);
}

實現(xiàn)函數(shù)add

\* add(2,3);//5
   add(2)(3);//5
*\
function add(a) {
    if(arguments.length > 1){
      return arguments[0] + arguments[1];
        }else {
    return (function (b){return a + b});
    }
}

add(2,3);//5
add(2)(3);//5

十大經(jīng)典排序算法

鏈接:https://sort.hust.cc/

快速排序

var quickSort = function(arr) {
  if (arr.length <= 1) { return arr; }
  var pivotIndex = Math.floor(arr.length / 2);
  var pivot = arr.splice(pivotIndex, 1)[0];
  var left = [];
  var right = [];
  for (var i = 0; i < arr.length; i++){
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat([pivot], quickSort(right));
};

實現(xiàn)深度克隆

//JSON.parse
const newObj = JSON.parse(JSON.stringify(oldObj));


function deepClone(obj) {
    
    if(typeof obj !== 'object') {
        return -1;
    } else {
      var res = obj.constructor === Array ? [] : {};
       for (var k in obj) {
           if(typeof obj[k] === 'object') {
               res[k] = deepClone(obj[k]);
           } else {
                res[k] = obj[k];
           }
            
       }
    }
    return res;

}

 

String Shifting (賽碼網(wǎng))

我們規(guī)定對一個字符串的shift操作如下:

shift(“ABCD”, 0) = “ABCD”

shift(“ABCD”, 1) = “BCDA”

shift(“ABCD”, 2) = “CDAB”

換言之, 我們把最左側(cè)的N個字符剪切下來, 按序附加到了右側(cè)。

給定一個長度為n的字符串,我們規(guī)定最多可以進行n次向左的循環(huán)shift操作。如果shift(string, x) = string (0<= x <n), 我們稱其為一次匹配(match)。求在shift過程中出現(xiàn)匹配的次數(shù)。

var line = "";
while(str = read_line().trim()) {
    line += str;
}
var n = line.length;
var result = 0;
if(n > 500000) {
    print(1);
}
else {
  for(var i = 0; i < n; i ++) {
      if(line.substr(i) + line.substr(0, i) === line) {
          result ++;   
       }        
  }
   print(result);
}    

數(shù)組拍平

\\ 輸入 var arr = [1,2,[3,4,5,[6,[7,8],9],10,[11,12]];
\\ 輸出 arr = [1,2,3,4,5,6,7,8,9,10,11,12]

\\ 遞歸
function flat(arr) {
    if(!Array.isArray(arr)) return false;
    res = [];
    for(var i = 0; i < arr.length; i++) {
        if(Array.isArray(arr[i])) {
            res = res.concat(flat(arr[i]));
        } else {
            res.push(arr[i]);
        }
    }
    return res;
}

\\toString
function flat(arr) {
    if(!Array.isArray(arr)) return false;
    return arr.toString().split(',').map((v) => {
        return parseInt(v);
    });
}

統(tǒng)計字符串出現(xiàn)次數(shù)最多的字母

function findMost(str) {
    var container = {};
    var arr = str.split('');
    for(var i = 0; i < arr.length; i++) {
        if(!container[arr[i]]) {
            container[arr[i]] = 1;
        } else {
            container[arr[i]] += 1;
        }
    }
    var maxKey = 0;
    var maxValue = '';
    for(var k in container) {
        if(container[k] >= maxKey) {
            maxKey = container[k];
            maxValue = k;
        }
    }
    return maxValue;
}

兩個單向鏈表找相交結(jié)點

手寫代碼常用函數(shù)總結(jié)

鏈接:https://juejin.im/post/5e57048b6fb9a07cc845a9ef#heading-38
來源: 掘金

補充

常考算法

  1. 鏈接:https://juejin.im/post/5aa7c2306fb9a028c14a24b8
  2. 鏈接 https://segmentfault.com/a/1190000020230669
    3.(全) http://obkoro1.com/web_accumulate/algorithm/

全面總結(jié)

鏈接:https://juejin.im/post/5aae076d6fb9a028cc6100a9
來源:掘金

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內(nèi)容

  • 概要 64學時 3.5學分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,276評論 0 3
  • 前端開發(fā)面試題 面試題目: 根據(jù)你的等級和職位的變化,入門級到專家級,廣度和深度都會有所增加。 題目類型: 理論知...
    怡寶丶閱讀 2,605評論 0 7
  • 面試題一:https://github.com/jimuyouyou/node-interview-questio...
    R_X閱讀 1,638評論 0 5
  • 前端面試題的簡單整理,都只是大概回答,具體某些問題的具體理解后續(xù)會補上。 前端頁面有哪三層構(gòu)成,分別是什么?作用是...
    李歡li閱讀 492評論 0 2
  • 一、理論基礎(chǔ)知識部分 1.1、講講輸入完網(wǎng)址按下回車,到看到網(wǎng)頁這個過程中發(fā)生了什么 a. 域名解析 b. 發(fā)起T...
    我家媳婦蠢蠢噠閱讀 3,145評論 2 106