前端常見面試題(一)

前端常見面試題

三欄佈局

  • 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()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章