前端常見面試題

要什麼自行車啊發表於2019-06-20

三欄佈局

  • float
    <div>
      <section class="a1">a1</section>
      <section class="a2">a2</section>
      <section class="a3">a3</section>
      <section class="a4">a4</section>
      <section class="a5">a5</section>
    </div>
    div {
      width: 180px;
      height: 50px;
    }
    section {
      float: left;
    }
    .a1 {
      width: 50px;
      height: 50px;
      background-color: tan;
    }
    .a2 {
      float: right;
      width: 50px;
      height: 50px;
      background-color: tan;
    }
    
    .a3 {
      width: 80px;
      height: 25px;
      background-color: red;
    }
    .a4 {
      width: 40px;
      height: 25px;
      background-color: #ddd;
    }
    .a5 {
      width: 40px;
      height: 25px;
      background-color: #666;
    }
    複製程式碼
  • position
    div {
      width: 180px;
      height: 50px;
      position: relative;
    }
    .a1 {
      position: absolute;
      width: 50px;
      height: 50px;
      background-color: red;
    }
    .a2 {
      position: absolute;
      left: 50px;
      width: 80px;
      height: 25px;
      background-color: blue;
    }
    .a3 {
      position: absolute;
      left: 50px;
      top: 25px;
      width: 40px;
      height: 25px;
      background-color: green;
    }
    .a4 {
      position: absolute;
      left: 90px;
      top: 25px;
      width: 40px;
      height: 25px;
      background-color: tan;
    }
    .a5 {
      position: absolute;
      width: 50px;
      height: 50px;
      left: 130px;
      background-color: red;
    }
    複製程式碼
  1. flex
div {
  width: 180px;
  height: 50px;
  display: flex;
  flex-flow: column wrap;
  align-content: flex-start;
}
.a1 {
  width: 50px;
  height: 50px;
  background-color: red;
}
.a2 {
  width: 80px;
  height: 25px;
  background-color: tan;
}
.a3 {
  flex-grow: 1;
  background-color: aqua;
}
.a4 {
  width: 25px;
  height: 50px;
  background-color: #fff;
}
.a5 {
  flex-grow: 1;
  background-color: red;
}
複製程式碼
  1. 三欄等寬佈局
div {
  width: 180px;
  height: 50px;
  display: flex;
  background-color: tan;
}

section {
  flex: auto;
}

.a1 {
  background-color: #fff;
}
.a2 {
  background-color: #444;
}
.a3 {
  background-color: red;
}
複製程式碼

垂直居中

  1. position
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
複製程式碼
  1. table
div {
  width: 100px;
  height: 100px;
  position: relative;
  background-color: tan;
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}
span {
  background-color: red;
}
複製程式碼
  1. 行內塊
div {
  width: 100px;
  height: 100px;
  position: relative;
  background-color: tan;
}
section {
  width: 50px;
  height: 50px;
  display: inline-block;
  margin: 25px;
  background-color: red;
}
複製程式碼
  1. float
div {
  width: 100px;
  height: 100px;
  position: relative;
  background-color: tan;
}
section {
  width: 50px;
  height: 50px;
  margin: 25px;
  float: left;
  background-color: red;
}
複製程式碼
  1. line-height
div {
  width: 100px;
  height: 100px;
  background-color: tan;
  text-align: center;
  line-height: 100px;
}
span{
  background-color: #fff;
  vertical-align: middle;
}
複製程式碼

盒模型

margin-box, border-box, padding-box, content-box
首先是最內層content-box,用來顯示元素資訊
向外是padding-box,主要用於設定元素四個方向的內邊距,
再向外是border-box,用於設定元素四個方向的邊框樣式,
最外層是margin-box,為了讓元素與其他元素隔開,對於垂直方向上的BFC元素的margin會發生合併,去較大的值
padding-box和margin-box是透明的,padding-box會受元素的背景的影響,可以通過box-sizing設定
padding-box和border-box不能去負值,margin-box可以取負值
還有元素的溢位屬性,處理空白空間及文字溢位

  * css中每個元素都看作多個盒子的組合,我們可以通過設定這些盒子的屬性來改變元素的樣式
  * 如果設定 box-sizing 為 content-box,那麼寬度就是內容區的寬度
  * 如果設定為 border-box,那麼寬度就死活內容區寬度+padding+border
複製程式碼

單行文字溢位省略:

text-overflow:ellipsis; white-space:nowrap; overflow:hidden;

BFC

浮動,絕對定位,overflow不為visible,非塊級盒子塊級容器
觸發:
  1. float 除了none以外的值 
&emsp;2. overflow 除了visible 以外的值(hidden,auto,scroll ) 
&emsp;3. display (table-cell,table-caption,inline-block, flex, inline-flex) 
&emsp;4. position值為(absolute,fixed)

特性:
  在BFC中,盒子從頂端開始垂直地一個接一個地排列。
  盒子垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰盒子垂直方向的margin會發生重疊。
  在BFC中,每一個盒子的左外邊距(margin-left)會觸碰到容器的左外邊緣(border-left)。
  BFC不會與浮動盒子產生交集,而是緊貼浮動元素邊緣。
  計算BFC高度BFC時,自然也會檢測浮動的子盒子高度。

應用:
  自適應兩欄佈局
  解決margin疊加問題:下面元素新增父元素:overflow: hidden;
  清除浮動,計算BFC高度 
複製程式碼

閉合浮動的辦法:

  • 包含塊overflow:hidden/BFC
  • 包含塊display:flow-root/BFC
  • 包含塊變表格/BFC
  • 包含塊變行內塊元素/BFC
  • br標籤的清除浮動

談談你對MVVM開發模式的理解

  • MVVM主要分為model/view/viewmodel三部分
  • model:代表資料模型,資料和業務邏輯都在model層中定義
  • view:代表UI檢視,負責資料的展示
  • viewmodel:負責監聽model中資料的改變並且控制檢視的更新,處理使用者互動操作
  • Model和View並無直接關聯,是通過viewmodel來進行聯絡的,model和viewmodel之間有著雙向資料繫結的聯絡。因此當model中的資料改變時會觸發view層的重新整理,同樣view中由使用者互動操作而改變的資料也會在model中同步。
  • 這種模式實現了model和view的資料自動同步,因此開發者只需要專注於對資料的維護操作即可,而不需要自己操作DOM

如何優化SPA應用的首屏載入速度慢的問題

  1. 將公用的JS庫通過script標籤外部引入,讓瀏覽器並行下載資原始檔,提高下載速度;
  2. 在配置路由時,頁面和元件使用懶載入的方式引入,在呼叫某個元件時再載入對應的js檔案;
  3. 加一個首屏 loading 圖,提升使用者體驗;

跨域(Cross-Origin)

只要協議、主機、埠不一致,就會有跨域的問題

  • javascript跨域通訊
    • jsonp
    • CORS設定跨域頭
    • 在框架中配置跨域代理
  • jsonp的實現原理
    • script標籤引入外部網站的程式碼,一般都是使用查詢字串告訴對方我們頁面中的callback函式,然後對方把需要返回的資料包在這個函式裡面
    • 其實JSONP並不算真正意義上的AJAX請求,只是請求了一個js檔案並且執行了,而且這種跨域方法只能進行GET請求
  function jsonp(url, value, cb) {
    let cbName = 'JSONP_CALLBACK_' + Date.now() + '_' + Math.random().toString().slice(2)
    window[cbName] = cb
    url = url + '?q=' + value + '&callback=' + cbName
    let script = document.createElement('script')
    script.src = url
    script.onload = () => {
      document.body.removeChild(script)
      delete window[cbName]
    }
    document.body.appendChild(script)
  }

  function ajax(url = '', data = {}, type = 'GET') {
    if (type === "GET") {
      let urlStr = ""
      Object.keys(data).forEach(key => {
        urlStr += key + '=' + data[key] + '&'
      })
      if (urlStr) {
        urlStr = urlStr.substring(0, urlStr.length - 1)
        url += '?' + urlStr
      }
      return axios.get(url)
    } else if (type === "POST") {
      return axios.post(url, data)
    }
  }
複製程式碼
  • CORS
    • 它允許瀏覽器向跨源伺服器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制
    • 簡單請求
      • 請求方法為HEAD、GET或者POST中的一種
      • HTTP的頭資訊有以下幾種欄位Accept、Accept-Language、Content-Language、Last-Event-ID
      • Content-Type的值只限於application/x-www-form-urlencoded、multipart/form-data、text/plain三個
      • 瀏覽器發出請求時,瀏覽器會自動在請求頭中新增一個欄位Origin,值為發出請求網頁的源地址
      • 服務端根據這個值,決定是否同意這次請求,如果Origin的值不在指定的許可範圍,瀏覽器接收到的HTTP回應將不包含Access-Control-Allow-Origin,丟擲錯誤被XMLHttpRequest的onerror回撥函式捕獲。如果Access-Control-Allow-Origin欄位正好跟帶過去的Origin的值一樣,則返回對應的資料,完成一次請求。
    • 非簡單請求以及option請求
      • 非簡單請求是那種對伺服器有特殊要求的請求,比如請求方法是PUT或DELETE,或者Content-Type欄位的型別是application/json。
      • 在進行非簡單請求之前,瀏覽器會在正式請求之前傳送一次預檢請求,這就是有時候我們會在控制檯中看到的option請求,就是說,正式請求之前,瀏覽器會去問服務端我這個地址能不能訪問你,如果可以,瀏覽器才會傳送正式的請求,否則報錯。
    • 總結
      • CORS實現跨域的方法就是根據請求頭的Origin值和響應頭的Access-Control-Request-Headers和Access-Control-Request-Method的值進行比對,通過了就可以請求成功,沒通過就請求失敗。
  • 比較
    • JSONP只支援GET請求,CORS支援所有型別的HTTP請求。JSONP的優勢在於支援老式瀏覽器,以及可以向不支援CORS的網站請求資料。

前端如何優化網站效能

  • 減少 HTTP 請求數量:
    • 瀏覽器與伺服器主要是通過 HTTP 進行通訊。瀏覽器與伺服器需要經過三次握手,每次握手需要花費大量時間。而且不同瀏覽器對資原始檔併發請求數量有限,一旦 HTTP 請求數量達到一定數量,資源請求就存在等待狀態,因此減少 HTTP 的請求數量可以很大程度上對網站效能進行優化。
  • CSS Sprites:
    • 國內俗稱 CSS 精靈,這是將多張圖片合併成一張圖片達到減少 HTTP 請求的一種解決方案,可以通過 CSS background 屬性來訪問圖片內容。這種方案同時還可以減少圖片總位元組數。
  • 合併 CSS 和 JS 檔案:
    • 現在前端有很多工程化打包工具,如:grunt、gulp、webpack等。為了減少 HTTP 請求數量,可以通過這些工具再發布前將多個 CSS 或者 多個 JS 合併成一個檔案。
  • 採用 lazyLoad:
    • 俗稱懶載入,可以控制網頁上的內容在一開始無需載入,不需要發請求,等到使用者操作真正需要的時候立即載入出內容。這樣就控制了網頁資源一次性請求數量。
  • 利用瀏覽器快取
    • 瀏覽器快取是將網路資源儲存在本地,等待下次請求該資源時,如果資源已經存在就不需要到伺服器重新請求該資源,直接在本地讀取該資源。
  • 減少 DOM 操作,達到減少重排(Reflow)
    • 基本原理:重排是 DOM 的變化影響到了元素的幾何屬性(寬和高),瀏覽器會重新計算元素的幾何屬性,會使渲染樹中受到影響的部分失效,瀏覽器會驗證 DOM 樹上的所有其它結點的 visibility 屬性,這也是 Reflow 低效的原因。如果 Reflow 的過於頻繁,CPU 使用率就會急劇上升。

Less / Sass

Less的變數名使用@符號開始 Sass的變數是必須$開始

  • 作用域:
    • Sass無全域性變數概念
    • LESS中的作用域和其他程式語言中的作用域非常的相同
  • 混合(Mixins):
    • Sass
      宣告:@mixin a($borderWidth:2px){}
      呼叫:@include error();
    複製程式碼
    • Less
      宣告:.error(@borderWidth:2px){}
      呼叫:.error();
    複製程式碼
  • 繼承
    • Sass
      @extend .block; /*繼承.block選擇器下所有樣式*/
    複製程式碼
    • Less
      .block;/*繼承.block選擇器下所有樣式*/
    複製程式碼

AntDesign / bootstrap

http協議

  • HTTP是基於TCP/IP通訊協議來傳遞資料
  • HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端伺服器模型。HTTP是一個無狀態的協議。
  • 工作過程大概如下:
    • 使用者在瀏覽器中鍵入需要訪問網頁的URL或者點選某個網頁中連結;
    • 瀏覽器根據URL中的域名,通過DNS解析出目標網頁的IP地址;
    • 在HTTP開始工作前,客戶端首先會通過TCP/IP協議來和服務端建立連結(TCP三次握手)
    • 建立連線後,客戶機傳送一個請求給伺服器,請求方式的格式為:統一資源識別符號(URL)、協議版本號,後邊是MIME資訊包括請求修飾符、客戶機資訊和可內容。
    • 伺服器接到請求後,給予相應的響應資訊,其格式為一個狀態行,包括資訊的協議版本號、一個成功或錯誤的程式碼,後邊是MIME資訊包括伺服器資訊、實體資訊和可能的內容。
    • 一般情況下,一旦Web伺服器向瀏覽器傳送了請求資料,它就要關閉TCP連線,然後如果瀏覽器或者伺服器在其頭資訊加入了這行程式碼:Connection:keep-alive,TCP連線在傳送後將仍然保持開啟狀態,於是,瀏覽器可以繼續通過相同的連線傳送請求。保持連線節省了為每個請求建立新連線所需的時間,還節約了網路頻寬。
  • 短連線:建立連線——資料傳輸——關閉連線...建立連線——資料傳輸——關閉連線,如果客戶請求頻繁,將在TCP的建立和關閉操作上浪費較多時間和頻寬。
  • 長連線:建立連線——資料傳輸...(保持連線)...資料傳輸——關閉連線
    • with pipeling: 每次建立連結後無需等待請求回來就可以傳送下一個請求
    • without pipeling: 客戶端只在收到前一個請求的響應後,才發出新的請求。
  • Http請求報文
    客戶端傳送一個HTTP請求到伺服器的請求訊息包括以下格式:
      請求行(request line)、請求頭部(header)、請求體組成
      請求行:
        方法:
            GET 獲取資源
            POST 向伺服器端傳送資料,傳輸實體主體
            PUT 傳輸檔案
            HEAD 獲取報文首部
            DELETE 刪除檔案
            OPTIONS 詢問支援的方法
            TRACE 追蹤路徑
        URL
        協議/版本號
      請求頭:
          通用首部(General Header)
          請求首部(Request Header)
          響應首部(Response Header)
          實體首部(Entity Header Fields)
          
      請求體
    複製程式碼
  • Http響應報文
    HTTP響應組成:響應行、響應頭、響應體。
    響應行
        (HTTP/1.1)表明HTTP版本為1.1版本,狀態碼為200,狀態訊息為(ok)
    響應頭
        Date:生成響應的日期和時間;
        Content-Type:指定了MIME型別的HTML(text/html),編碼型別是ISO-8859-1
    響應體
    複製程式碼
  • GET和POST區別
    • GET提交的資料會放在URL之後,以?分割URL和傳輸資料,引數之間以&相連,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的資料放在HTTP包的Body中.
    • GET提交的資料大小有限制(因為瀏覽器對URL的長度有限制),而POST方法提交的資料沒有限制.
    • GET方式需要使用Request.QueryString來取得變數的值,而POST方式通過Request.Form來獲取變數的值。
    • GET方式提交資料,會帶來安全問題,比如一個登入頁面,通過GET方式提交資料時,使用者名稱和密碼將出現在URL上,如果頁面可以被快取或者其他人可以訪問這臺機器,就可以從歷史記錄獲得該使用者的賬號和密碼.

websocket

首先Websocket是基於HTTP協議的,或者說借用了HTTP的協議來完成一部分握手。
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
複製程式碼
  • http long poll 和 ajax 輪詢都可以實現實時資訊傳遞

    • ajax輪詢: 讓瀏覽器隔個幾秒就傳送一次請求,詢問伺服器是否有新資訊。
    • long poll 都是採用輪詢的方式,不過採取的是阻塞模型,客戶端發起連線後,如果沒訊息,就一直不返回Response給客戶端。直到有訊息才返回,返回完之後,客戶端再次建立連線,周而復始
  • 特點:

    • 解決了http協議只能從客戶端向伺服器傳送請求的缺陷,有了websocket,伺服器也能主動向客戶端推送訊息
    • 和http一樣,是建立在tcp協議之上,預設埠也是80和443,
    • 沒有同源限制,客戶端可以與任意伺服器通訊
    • 協議識別符號是ws,伺服器網址就是URL
    • 可以傳送文字,也可以傳送二進位制資料

socket.io

socket.io 是一個能實現多人遠端實時通訊(聊天)的庫 它包裝的是 H5, WebSocket和輪詢, 如果是較新的瀏覽器內部使用 WebSocket,如果瀏覽器不支援, 那內部就會使用輪詢實現實時通訊

網頁從輸入網址到渲染完成經歷了哪些過程

1 輸入網址 2 傳送到DNS伺服器,並獲取域名對應的web伺服器對應的ip地址 3 與web伺服器建立TCP連線 4 瀏覽器向web伺服器傳送http請求 5 web伺服器響應請求,並返回指定url的資料(或錯誤資訊,或重定向的新的url地址) 6 瀏覽器下載web伺服器返回的資料及解析html原始檔 7 生成DOM樹,解析css和js,渲染頁面,直至顯示完成

資料結構和演算法

// reduce
  function reduce(ary, f, initVal) {
    var start = 0
    if (arguments.length == 2) {
      initVal = ary[0]
      start = 1
    }
    for (var i = start; i < ary.length; i++) {
      initVal = f(initVal, ary[i], i, ary)
    }
    return initVal
  }
// flattenDeep
  function flattenDeep(ary) {
    return [].concat(...ary.map(val => {
      if (Array.isArray(val)) {
        return flattenDeep(val)
      } else {
        return val
      }
    }))
  }
複製程式碼

ES6 新特性

  • 函式預設值
  • 模板字串:123${a}456,\
  • 解構賦值
  • let & const
    • let 無變數提升,有塊級作用域,禁止重複宣告
    • const 無變數提升,有塊級作用域,禁止重複宣告,禁止重複賦值
  • 新增庫函式
    • Number .EPSILON / .isInteger / .isInteger
    • String .includes / .repeat / .startsWith / .endsWith
    • Array .fill / .findIndex / .of() /
    • Object .assign
    • Math
  • 箭頭函式:共享父級 this 物件,共享父級 arguments,不能當做建構函式
  • 類 & 繼承
    • 本質為對原型鏈的二次包裝;類沒有提升;不能使用字面量定義屬性;動態繼承類的構造方法中 super 優先 this
  • 模組
    • 每個模組都有自己完全獨立的程式碼塊,跟作用域類似,但是更加封閉。
    • 無限制匯出匯出
    • 內聯匯出:嚴格模式下執行使用 export 關鍵字,後面緊跟宣告關鍵字(let、function 等)宣告一個匯出物件,宣告並同時匯出的匯出方式
    • 物件匯出
    • 一個模組只能有一個預設匯出

ES8 新特性

  • String:新增padStart,padEnd
  • Object.values 方法返回一個給定物件自己的所有可列舉屬性值的陣列
  • Object.entries 方法返回一個給定物件自身可遍歷屬性 [key, value] 的陣列
  • Object.getOwnPropertyDescriptors 方法返回指定物件所有自身屬性的描述物件
  • 函式引數和函式呼叫中的尾逗號
  • Async 函式

BOM / DOM

  • DOM文件物件模型,BOM瀏覽器物件模型
  • DOM 是針對 HTML 和 XML 提供的一個API,為了能以程式設計的方法操作這個 HTML 的內容。將html中的每個元素都看作是一個物件,每個物件都叫做一個節點,這些節點組成一個DOM樹。document是DOM樹的根節點
  • BOM 是瀏覽器提供的附加物件,用於處理文件之外的所有內容,比如alert/confirm/prompt,BOM包含的物件有,document,screen,location,history,navigator
  • DOM是所有W3C標準都必須遵守的規則,BOM是各瀏覽器廠商遵守的規則
  • BOM的核心是window,它既是通過js訪問瀏覽器視窗的一個介面,又是一個Global(全域性)物件。這意味著在網頁中定義的任何物件,變數和函式,都以window作為其global物件。
  • DOM通過建立樹來表示文件,描述了處理網頁內容的方法和介面,從而使開發者對文件的內容和結構具有控制力,用DOM API可以輕鬆地刪除、新增和替換節點。
  • DOM 的根節點是BOM 的window 物件的子物件。

圖片懶載入

  • 三個API,我們獲得了三個值:
    • 可視區高度clientHeight、
    • 元素相對於其父元素容器頂部的距離offsetTop、
    • 瀏覽器視窗頂部與容器元素頂部的距離也就是滾動條滾動的高度scrollTop。
  • 當offsetTop - scroolTop < clientHeight,則圖片進入了可視區內,則被請求。
  var imgs = document.querySelectorAll('img');

  //offsetTop是元素與offsetParent的距離,迴圈獲取直到頁面頂部
  function getTop(e) {
      var T = e.offsetTop;
      while(e = e.offsetParent) {
          T += e.offsetTop;
      }
      return T;
  }

  function lazyLoad(imgs) {
      var H = document.documentElement.clientHeight;//獲取可視區域高度
      var S = document.documentElement.scrollTop || document.body.scrollTop;
      for (var i = 0; i < imgs.length; i++) {
          if (H + S > getTop(imgs[i])) {
              imgs[i].src = imgs[i].getAttribute('data-src');
          }
      }
  }

  window.onload = window.onscroll = function () { //onscroll()在滾動條滾動的時候觸發
      lazyLoad(imgs);
  }
複製程式碼

原型,閉包,高階函式,非同步

  • 閉包就是一個函式裡面生成並返回一個函式,返回的這個函式能讀取到外部函式裡面的變數
  • 原型就是 a 是例項,b 是建構函式,然後a.proto === b.prototype,使用instanceof來判斷的時候就是不停地向上尋找,還有讀取a的某個屬性如果沒有,就會預設去a的原型上找
  • 高階函式:高階函式是一個接收函式作為引數或將函式作為輸出返回的函式 map/reduce/filter
  • 非同步:js是單執行緒的,但瀏覽器是多執行緒的,當js執行遇到非同步程式碼時,會將程式碼交給webapi非同步執行,js則可以繼續執行下面的程式碼;非同步程式碼會被塞入task queue裡排隊,task queue會一直觀察棧裡程式碼有沒有執行完成,一旦發現棧空了,就會呼叫回撥函式,然後重新回到js執行緒中執行
  • www.zhihu.com/search?type…
  • async表示該函式要做非同步處理。await表示後面的程式碼是一個非同步操作,等待該非同步操作完成後再執行後面的動作。如果非同步操作有返回的資料,則在左邊用一個變數來接收它。

sessionstorage localstorage cookie區別

  1. 傳遞方式不同 cookie資料始終在同源的http請求中攜帶(即使不需要),即cookie在瀏覽器和伺服器間來回傳遞。 sessionStorage和loaclStorage不會自動把資料發給伺服器,僅在本地儲存。
  2. 資料大小不同 cookie資料還有路徑(path)的概念,可以限制cookie只屬於某個路徑下。 cookie資料最大4k,sessionStorage和localStorage比cookie大得多,可以達到5M或者更大。
  3. 資料有效期不同 sessionStorage:僅在當前瀏覽器視窗關閉前有效,自然也就不可能持久保持; localStorage:始終有效,視窗或瀏覽器關閉也一直儲存,因此用作持久資料; cookie只在設定cookie過期時間之前一直有效,即使視窗或瀏覽器關閉。
  4. 作用域不同 sessionStorage不同的瀏覽器視窗不能共享,即使是同一個頁面; localStorage所有同源視窗都是共享的; cookie所有同源視窗中都是共享的。

session / cookie

  • Cookie 可以保持登入資訊到使用者下次與伺服器的會話,換句話說,下次訪問同一網站時,使用者會發現不必輸入使用者名稱和密碼就已經登入了(當然,不排除使用者手工刪除Cookie),Cookie滿足同源策略 Cookie 在生成時就會被指定一個Expire值,這就是Cookie的生存週期,在這個週期內Cookie有效,超出週期Cookie就會被清除。有些頁面將Cookie的生存週期設定為“0”或負值,這樣在關閉瀏覽器時,就馬上清除Cookie,不會記錄使用者資訊,更加安全。

  • 由於HTTP協議是無狀態的協議,所以服務端需要記錄使用者的狀態時,就需要用某種機制來識具體的使用者,這個機制就是Session.典型的場景比如購物車,當你點選下單按鈕時,由於HTTP協議無狀態,所以並不知道是哪個使用者操作的,所以服務端要為特定的使用者建立了特定的Session,用用於標識這個使用者,並且跟蹤使用者,這樣才知道購物車裡面有幾本書。這個Session是儲存在服務端的,有一個唯一標識。

  • Session是在服務端儲存的一個資料結構,用來跟蹤使用者的狀態,這個資料可以儲存在叢集、資料庫、檔案中; Cookie是客戶端儲存使用者資訊的一種機制,用來記錄使用者的一些資訊,也是實現Session的一種方式。

event loop

第一步確認巨集任務,微任務
  巨集任務:script,setTimeout,setImmediate,promise中的executor
  微任務:promise.then,process.nextTick
process.nextTick優先順序高於Promise.then


timers: setTimeout / setInterval
I/O callbacks: 不在其他階段的所有回撥函式
poll: 獲取新的I/O事件
check:執行setImmediate
close callback: 執行關閉事件的回撥函式


在整個輪詢的開始執行process.nextTick
然後再執行setTimeOut、setInterval
再執行其他的回撥函式
最後執行setImmediate
複製程式碼

傳送ajax請求

axios / fetch
複製程式碼

Node.js

Node核心思想:1.非阻塞;&emsp;&emsp;2.單執行緒;&emsp;&emsp;3.事件驅動。
Node 是一個伺服器端 JavaScript 直譯器
當執行緒遇到IO操作的時候,不會以阻塞的方式等待IO操作完成或者資料的返回,而是將IO操作傳送給作業系統,
然後接著執行下一個操作,當作業系統執行完IO操作之後,以事件的方式通知執行IO的執行緒,
執行緒會在特定的時候執行這個事件。這一切的前提條件就是,系統需要一個事件迴圈,
以不斷的去查詢有沒有未處理的事件,然後給預處理。
複製程式碼

Redux

redux 是一個獨立的專門用於狀態管理的js庫
可以管理react應用中多個元件共享的狀態

用redux對元件的狀態進行集中式管理

元件:兩個方面
展現資料   狀態顯示
與使用者互動更新資料   更新狀態


redux核心是一個store(倉庫)
元件直接從store中讀取狀態

更新狀態:
1. Action Creators ==>> dispatch(action) :傳兩個值(type和data) type是傳的型別(刪除,增加,建立,更新)
2. store
3. Reducers ==>> 接受(previousState, action) 返回(newState)
4. React Component


createStore()
store: 管理state, reducer
方法: getState() , dispatch(action) , subscribe(listener)
action物件 
reducer返回的是新的狀態

applyMiddleware 中介軟體
thunk 非同步
複製程式碼

diff演算法

  • 只在同層進行比較
  • 如果節點發生變化,那麼就直接替換
  • 如果節點相同,遞迴比較子節點的變化
  • 如果有key,那麼就會key相同的進行比較

react-redux 的核心就是一個connect函式,接收兩個引數,mapStatetoprops,mapdispatchtoprops,返回一個高階元件,這個高階元件接受一個元件,返回一個元件,但是這個返回的元件的props上面多了資料以及運算元據的方法

function connect(mapStateToProps,mapDispatchToProps){
  return function(com){
    return class extends React.Component{
      render(){
        return (
          <Consumer>
            {store=>{
              state = mapStateToProps(store.getState())
              dispatch = mapDispatchToProps(store.dispatch)
              return <Comp {...state}{...dispatch}></Comp>
            }}
          </Consumer>
        )        }
    }
  }
}
複製程式碼

容器元件和展示元件

  • 容器元件負責管理資料和邏輯
  • 展示元件負責UI的呈現
  • 他們通過react-redux提供的connect方法取得聯絡

為什麼連線的時候是三次握手,關閉的時候卻是四次握手?

因為當Server端收到Client端的SYN連線請求報文後,可以直接傳送SYN+ACK報文。 其中ACK報文是用來應答的,SYN報文是用來同步的。 但是關閉連線時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET, 所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。 只有等到我Server端所有的報文都傳送完了,我才能傳送FIN報文,因此不能一起傳送。故需要四步握手。

  • 三次揮手:
    • 客戶端傳送 SYN 包到服務端,等待服務端確認
    • 服務端收到 SYN 包,同時自己也傳送一個 SYN+ACK 包給客戶端
    • 客戶端接收到 SYN+ACK 包,向服務端傳送確認包 ACK ,傳送完畢,客戶端與服務端 TCP 連線成功,完成三次握手
  • 四次揮手:
    • 客戶端連續傳送釋放報文 FIN ,等待服務端確認
    • 服務端收到釋放報文 FIN ,發出確認報文 ACK

redux

  action: 是store唯一的資訊來源,把action傳送給store必須通過store的dispatch方法。
          每個action必須有一個type屬性描述action的型別。
複製程式碼

XSS 與 CSRF 兩種跨站攻擊

  1. xss 跨站指令碼攻擊,主要是前端層面的,使用者在輸入層面插入攻擊指令碼,改變頁面的顯示,或則竊取網站 cookie,預防方法:不相信使用者的所有操作,對使用者輸入進行一個轉義,不允許 js 對 cookie 的讀寫
  2. csrf 跨站請求偽造,以你的名義,傳送惡意請求,通過 cookie 加引數等形式過濾
  3. 我們沒法徹底杜絕攻擊,只能提高攻擊門檻

負載均衡

當系統面臨大量使用者訪問,負載過高的時候,通常會使用增加伺服器數量來進行橫向擴充套件,使用叢集和負載均衡提高整個系統的處理能力

JS實現繼承的方法

1. 原型鏈繼承
  將父類的例項作為子類的原型
  function Cat() {}
  Cat.prototype = new Animal()
  Cat.prototype.name = 'cat'
  var cat = new Cat()
2. 構造繼承
  使用父類的建構函式來增強子類的例項,等於是複製父類的例項屬性給子類
  function Cat(name) {
    Animal.call(this)
    instance.name = name || 'Tom'
  }
  var cat = new Cat()
3. 例項繼承
  為父類例項新增新特性,作為子類的例項返回
  function Cat(name) {
    var instance = new Animal()
    instance.name = name || 'Tom'
    return instance
  }
  var cat = new Cat()
複製程式碼

相關文章