前端面試題(移動適配,閉包,this,HTTP狀態碼,排序思路,頁面加載,數組去重)

前端面試題(移動適配,閉包,this,HTTP狀態嗎,排序思路,頁面加載,數組去重)

1 請寫出一個符合 W3C 規範的 HTML 文件

請寫出一個符合 W3C 規範的 HTML 文件,要求javascript

  1. 頁面標題爲「個人頁面」
  2. 頁面中引入了一個外部 CSS 文件,文件路徑爲 /style.css
  3. 頁面中引入了另外一個外部 CSS 文件,路徑爲 /print.css,該文件僅在打印時生效
  4. 頁面中引入了另外一個外部 CSS 文件,路徑爲 /mobile.css,該文件僅在設備寬度小於 500 像素時生效
  5. 頁面中引入了一個外部 JS 文件,路徑爲 /main.js
  6. 頁面中引入了一個外部 JS 文件,路徑爲 /gbk.js,文件編碼爲 GBK
  7. 頁面中有一個 SVG 標籤,SVG 裏面有一個直徑爲 100 像素的圓圈,顏色隨意
  8. 注意題目中的路徑
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>個人頁面</title>
    <link rel="stylesheet" href="./style.css">
    <link rel="stylesheet" href="./print.css" media="print">
    <link rel="stylesheet" href="./mobile.css" media="(max-width: 500px)">
    <style>
        body{
            padding:0;
            margin:0;
        }
    </style>
</head>
<body>
    <svg version="1.1" width="100px" height="100px" xmlns="http://www.w3.org/2000/svg">
        <circle cx="50" cy="50" r="50" fill="red"/>
    </svg>
    <script src="./main.js"></script>
    <script src="./gbk.js" charset="GBK"></script>
</body>
</html>

2 移動端是怎麼作適配的?

2016年騰訊前端面試題
移動端是怎麼作適配的?
回答要點:css

  1. meta viewport
  2. 媒體查詢
  3. 動態 rem 方案

(能夠參考我寫的博客
CSS5:移動端頁面(響應式)
CSS9:動態 REM-手機專用的自適應方案
答:html

2.1作手機端頁面首先要加上一個meta標籤

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

content="width=device-width表示寬度等於設備寬度,意思就是不要將頁面寬度變成980px,用設備寬度.
user-scalable=no表示用戶不以縮放
initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0
初始縮放倍數,最大縮放倍數,最小縮放倍數,都是1.0,即不能縮放前端

2.2媒體查詢

經過媒體查詢,根據不一樣條件,使用不一樣的css樣式。
例如:java

<style>
        @media (max-width: 800px){/*若是媒體知足0到800 之間,那麼會應用這裏面的樣式*/
            body{
                background-color: red;
            }
        }
    </style>

2.3動態rem

由於手機須要兼容不少不一樣寬度的手機設備,因此將長度單位依賴於手機設備寬度,使用動態rem方案,那麼就能夠在不一樣手機上實現相同比例的頁面縮放而不影響佈局。
rem:root em,即<html>font-size.
實現動態rem,主要須要下面兩步:
1在<head>標籤里加上以下代碼,讓10rem等於頁面寬度linux

<head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
      <title>動態REM</title>
      <script>
        var pageWidth = window.innerWidth
         document.write('<style>html{font-size:'+pageWidth+'px;}</style>')
      </script>
    </head>

2使用sass自動將設計稿的px轉換爲rem
在scss文件裏寫這樣一個函數:git

@function px( $px ){
    @return $px/$designWidth*10 + rem;
    }

    $designWidth : 640; // 640 是設計稿的寬度,你要根據設計稿的寬度填寫。設計師的設計稿寬度須要統一

就可使用px()函數將像素轉化爲rem。github

3 實現圓角矩形和陰影怎麼作?

2017年騰訊前端實習面試題(二面)
用過CSS3嗎? 實現圓角矩形和陰影怎麼作?
(搜索MDN border-radius)
答:
用過。例如陰影,圓角,動畫,漸變和過渡
1.圓角:
簡寫屬性border-radius。例如
border-radius: 30px;
border-radius: 50%;
半徑參數能夠是長度單位,也能夠是百分比單位。面試

也能夠分別設置四個角segmentfault

border-top-left-radius:     4px 2px;
border-top-right-radius:    3px 4px;
border-bottom-right-radius: 6px 2px;
border-bottom-left-radius:  3px 4px;

半徑參數能夠是一個或兩個,一個參數表明圓形圓角,兩個參數是橢圓圓角

2.陰影:

語法:
box-shadow:inset x-offset y-offset blur-radius spread-radius color
五個參數分別是:投影方式 X軸偏移量 Y軸偏移量 陰影模糊半徑 陰影擴展半徑 陰影顏色

4 什麼是閉包,閉包的用途是什麼?

出處同上(一面二面都問了):
什麼是閉包,閉包的用途是什麼?
JavaScript高程P178
閉包的用途

答:

4.1什麼是閉包

閉包是指有權訪問另外一個函數做用域中的變量的函數。
例如

function foo(){
  var local = 1
  function bar(){
    local++
    return local
  }
  return bar
}

var func = foo()
func()

bar函數能夠訪問變量local,bar就是一個閉包。

4.2閉包的用途

  1. 模仿塊級做用域

    function A(num) {
        //核心代碼
       (funnction(){
        for(var i = 0; i<num; i++) {
          num++;
        }
        })()
        //核心代碼結束
        console.log(i)//underfined
      }

    匿名自執行函數在內部造成了一個閉包,使i變量只有塊級做用域。閉包的本質是函數,其實在這裏閉包就是那個匿名函數,這個閉包能夠獲得函數A內部的活動變量,又能保證本身內部的變量在自執行後直接銷燬。

  2. 存儲變量
    閉包的另外一個特色是能夠保存外部函數的變量,原理是基於javascript中函數做用域鏈的特色,內部函數保留了對外部函數的活動變量的引用,因此變量不會被釋放

    function B(){
       var x = 100;
       return {
           function(){
               return x
           }
       }
     }
    var m = B()//運行B函數,生成活動變量 x被m引用

    運行B函數,生成活動變量 x被m引用, 變量x不會被銷燬
    運行B函數,返回值就是B內部的匿名函數,此時m引用了變量x,因此B執行後x不會被釋放,利用這一點,咱們能夠把比較重要或者計算耗費很大的值存在x中,只須要第一次計算賦值後,就能夠經過m函數引用x的值,沒必要重複計算,同時也不容易被修改。

  3. 封裝私有變量

    function Person(){
       var name = 'default';
       this.getName:function(){
           return name;
       }
       this.setName:function(value){
           name = value;
       }
    }
    console.log(Person.getName())//default
    console.log(Person.setName('mike'))
    console.log(Person.getName())//mike

    設置了兩個閉包函數來操做Person函數內部的name變量,除了這兩個函數,在外部沒法再訪問到name變量,name也就至關因而私有成員。

5 call、apply、bind 的用法分別是什麼?

阮一峯的javascript教程--this
深刻淺出 妙用Javascript中apply、call、bind

答:

若是在函數中包含多層的this,this的指向是不肯定的。須要把this固定下來,避免出現意想不到的狀況。JavaScript提供了call、apply、bind這三個方法,來切換/固定this的指向。

5.1Function.prototype.call()

函數實例的call方法,能夠指定函數內部this的指向(即函數執行時所在的做用域),而後在所指定的做用域中,調用該函數。

var obj = {};

var f = function () {
  return this;
};

f() === window // true
f.call(obj) === obj // true

call的第一個參數就是this所要指向的那個對象,後面的參數則是函數調用時所需的參數。

5.2Function.prototype.apply()

apply方法的做用與call方法相似,也是改變this指向,而後再調用該函數。惟一的區別就是,它接收一個數組做爲函數執行時的參數。

apply方法的第一個參數也是this所要指向的那個對象,若是設爲null或undefined,則等同於指定全局對象。第二個參數則是一個數組,該數組的全部成員依次做爲參數,傳入原函數。原函數的參數,在call方法中必須一個個添加,可是在apply方法中,必須以數組形式添加

function f(x, y){
  console.log(x + y);
}

f.call(null, 1, 1) // 2
f.apply(null, [1, 1]) // 2

5.3Function.prototype.bind()

bind方法用於將函數體內的this綁定到某個對象,而後返回一個新函數

bind方法的參數就是所要綁定this的對象。

var counter = {
  count: 0,
  inc: function () {
    this.count++;
  }
};

var func = counter.inc.bind(counter);
func();
counter.count // 1

上面代碼中,counter.inc方法被賦值給變量func。這時必須用bind方法將inc內部的this,綁定到counter,不然就會出錯。

6 HTTP 狀態碼

出處同上:
請說出至少 8 個 HTTP 狀態碼,並描述各狀態碼的意義。

例如:

狀態碼 200 表示響應成功。

答:

狀態碼 202 表示:服務器已接受請求,但還沒有處理。
狀態碼 204 表示:請求處理成功,但沒有資源可返回。
狀態碼 206 表示:服務器已經成功處理了部分 GET 請求。

狀態碼 301 表示:請求的資源已被永久的分配了新的 URI。
狀態碼 302 表示:請求的資源臨時的分配了新的 URI。

狀態碼 400 表示:請求報文中存在語法錯誤。
狀態碼 401 表示:發送的請求須要有經過 HTTP 認證的認證信息。
狀態碼 403 表示:對請求資源的訪問被服務器拒絕了。
狀態碼 404 表示:服務器上沒法找到請求的資源。

狀態碼 500 表示:服務器端在執行請求時發生了錯誤。
狀態碼 503 表示:服務器暫時處於超負債或正在進行停機維護,如今沒法處理請求。

7 寫出一個 HTTP post 請求的內容

出處同上:
請寫出一個 HTTP post 請求的內容,包括四部分。
其中
第四部分的內容是 username=ff&password=123
第二部分必須含有 Content-Type 字段
請求的路徑爲 /path

看個人博客HTTP入門(一):在Bash中curl查看請求與響應

答:

1 POST /path HTTP/1.1
2 Host: www.baidu.com
2 User-Agent: curl/7.20.0 (x86_64-unknown-linux-gnu) libcurl/7.20.0 zlib/1.2.8
2 Accept: */*
2 Content-Length: 24
2 Content-Type: application/x-www-form-urlencoded
3 
4 username=ff&password=123

8 請說出至少三種排序的思路

這三種排序的時間複雜度分別爲

O(n*n)
O(n log2 n)
O(n + max)

答:

O(n*n) 冒泡排序:遍歷整個數組,依次比較相鄰兩個元素,將小的排在前面,大的排後面,這樣一遍循環下來就能夠將最大的元素排到最後,除去已經排過的最大的數,而後再次循環以上操做,直到最後一個爲止。

O(n log2 n) 快速排序:以第一個元素爲基準,比這個元素小的元素排在左邊,比這個元素大的排右邊,再以該元素左邊和右邊的第一個元素爲基準,在子區間重複以上的操做,直到只有一個數字排序爲止。

O(n + max) 基數排序:首先根據個位數的數值,將須要排序的一串數值分配到0-9的桶中。接着將這些桶中的數值從新串起來,造成新的數列。接着根據十位數、百位數直至最高位重複以上操做。

9 頁面從輸入URL到頁面加載顯示完成的過程

著名前端面試題:

一個頁面從輸入 URL 到頁面加載顯示完成,這個過程當中都發生了什麼?
這一題是在挖掘你的知識邊界,因此你知道多少就要答多少。

能夠先查閱一些資料再查,可是不要把本身不懂的東西放在答案裏,面試官會追問的。

知乎上:從輸入 URL 到頁面加載完成的過程當中都發生了什麼
答:

  1. DNS解析
    DNS解析的過程就是瀏覽器查找域名對應的 IP 地址;
  2. TCP鏈接
    瀏覽器根據 IP 地址向服務器發起 TCP 鏈接,與瀏覽器創建 TCP 三次握手:
    (1)主機向服務器發送一個創建鏈接的請求(您好,我想認識您);
    (2)服務器接到請求後發送贊成鏈接的信號(好的,很高興認識您);
    (3)主機接到贊成鏈接的信號後,再次向服務器發送了確認信號(我也很高興認識您),自此,主機與服務器二者創建了鏈接。
  3. 發送HTTP請求
    瀏覽器根據 URL 內容生成 HTTP 請求報文。HTTP請求報文是由三部分組成: 請求行, 請求報頭和請求正文,其中包含請求文件的位置、請求文件的方式等等。
  4. 服務器處理請求並返回HTTP報文

    服務器接到請求後,回想客戶端發送HTTP響應報文。HTTP響應報文也是由三部分組成: 狀態碼, 響應報頭和響應報文。服務器會根據 HTTP 請求中的內容來決定如何獲取相應的 HTML 文件,並將獲得的 HTML 文件發送給瀏覽器。

  5. 瀏覽器解析渲染頁面
    瀏覽器是一個邊解析邊渲染的過程。在瀏覽器尚未徹底接收 HTML 文件時便開始渲染、顯示網頁。在執行 HTML 中代碼時,根據須要,瀏覽器會繼續請求圖片、CSS、JavsScript等文件,過程同請求 HTML 。
  6. 關閉TCP鏈接或繼續保持鏈接

    (1)主機向服務器發送一個斷開鏈接的請求(不早了,我該走了);

    (2)服務器接到請求後發送確認收到請求的信號(知道了);

    (3)服務器向主機發送斷開通知(我也該走了);

    (4)主機接到斷開通知後斷開鏈接並反饋一個確認信號(嗯,好的),服務器收到確認信號後斷開鏈接;

10 如何實現數組去重

著名面試題:
如何實現數組去重?
假設有數組 array = [1,5,2,3,4,2,3,1,3,4]
你要寫一個函數 unique,使得
unique(array) 的值爲 [1,5,2,3,4]
也就是把重複的值都去掉,只保留不重複的值。

要求:

不要作多重循環,只能遍歷一次
請給出兩種方案,一種能在 ES 5 環境中運行,一種能在 ES 6 環境中運行(提示 ES 6 環境多了一個 Set 對象)
從 JavaScript 數組去重談性能優化
也談JavaScript數組去重
答:

ES5:
思路:核心是構建了一個 hash 對象來替代 indexOf. 注意在 JavaScript 裏,對象的鍵值只能是字符串,所以須要 var key = typeof(item) + item 來區分數值 1 和字符串 '1' 等狀況。
只循環一遍

function unique(arr) {
  var ret = []
  var hash = {}
  for (var i = 0; i < arr.length; i++) {
    var item = arr[i]
    var key = typeof(item) + item
    if (hash[key] !== 1) {
      ret.push(item)
      hash[key] = 1
    }
  }
  return ret
}

ES6:ES2015引入了一種叫做Set的數據類型。顧名思義,Set就是集合的意思,它不容許重複元素出現。
若是重複添加同一個元素的話,Set中只會存在一個。包括NaN也是這樣

function unique(array) {
   return Array.from(new Set(array));
}
相關文章
相關標籤/搜索