前端面試總結——持續更新

前端面試題總結

寫在前面的話:

  • 寫文目的:總結前端面試過程當中沒回答上來的點,深化印象,也方便往後溫習。
  • 寫文方法:寫以前先本身看相關知識,理解好後過段時間根據記憶來寫,最後對比糾正。

準備面試流程:

1.更新簡歷,多參考其餘的優秀簡歷javascript

2.複習面試題css

筆者就是由於只更新了簡歷沒有複習致使基礎不過關,錯過兩家心儀的公司。html

順便說下,平時工做中的確不少時候用不到也不會去背某些面試中的問題,不過面試題中基礎部分很重要,理解好基礎才更輕鬆掌握新框架新知識。時不時去看看面試題也不失爲一種鞏固基礎的方法。通常一面面基礎,二面面項目,項目經驗再多,一面過不了,什麼戲也不會有。前端

被面過的面試題:

css

css優先級,屬性選擇器的優先級在哪java

0.類型選擇器(如, h1)和僞元素(如, ::before)
1.類選擇器,屬性選擇器,僞類(如,:hover)
3.ID選擇器jquery

通用選擇器(universal selector)(*), 組合子(combinators) (+, >, ~, ' ') 和 否認僞類(negation pseudo-class)(:not()) 對特異性沒有影響。(可是,在 :not() 內部聲明的選擇器是會影響優先級,在計算選擇器數量時仍是會把其中的選擇器當作普通選擇器進行計數)。git

4.給元素添加的內聯樣式總會覆蓋外部樣式表的任何樣式 ,所以可看做是具備最高的優先級。github

權重記憶口訣。一個元素名,或者僞元素+1,一個屬性選擇器/class或者僞類+10,一個id+100,一個行內樣式+1000。面試

**!important 規則例外
當在一個樣式聲明中使用一個!important 規則時,此聲明將覆蓋任何其餘聲明。**算法

直接定位的樣式權重大於繼承的樣式,不管繼承的規則的特異性(優先級)如何。

Styles for a directly targeted element will always take precedence over inherited styles, regardless of the specificity of the inherited rule.

h1 {
  color: purple;
}
#parent {
  color: green;
}

當它應用在下面的HTML時:

<html>
<body id="parent">
  <h1>Here is a title!</h1>
</body>
</html>

瀏覽器會將h1渲染成紫色。
由於h1選擇器清晰地定位了元素。

~ 組合器

A + B 匹配任意元素,知足條件:B是A的下一個兄弟節點(AB有相同的父結點,而且B緊跟在A的後面)

A ~ B 知足條件:B是A以後的兄弟節點中的任意一個(AB有相同的父節點,B在A以後,但不必定是緊挨着A)(會盡量多匹配)

js基礎

什麼是閉包

閉包是由函數與建立該函數的環境所組成的

優勢:減小全局變量污染

缺點:影響腳本性能

3==true 打印出什麼

會打印出false,這裏會將true轉變成1

Number 和 String 或者 Bool 類型比較,會對String 或者 Bool 類型進行ToNumber()轉換

Number(true) // 1
Number(false) // 0
1==true //true
1===true //false
3==true //false

變量聲明提高

變量聲明不管出如今代碼的任何位置,都會在代碼執行前處理。因此在代碼的任何位置聲明變量就好像在代碼開頭聲明同樣。

var a = 100;
function fn() {
    alert(a);
    var a = 200;
    alert(a);
}
fn();
alert(a);
var a;
alert(a); //這裏alert出100
var a = 300;
alert(a);

not defined 與 undefined

console.log(a) //報錯 Uncaught ReferenceError: a is not defined

var b;
console.log(b) //undefined

判斷變量是否是數組的幾個方法

var a=[];
a.constructor===Array //true
a instanceof Array === true //true

⚠️ 注意:以上方法在跨frame時會有問題,跨frame實例化的對象不共享原型

var iframe = document.createElement('iframe');   //建立iframe  
document.body.appendChild(iframe);   //添加到body中  
xArray = window.frames[window.frames.length-1].Array;     
var arr = new xArray(1,2,3); // 聲明數組[1,2,3]     
  
alert(arr instanceof Array); // false     
  
alert(arr.constructor === Array); // false

解決:

Object.prototype.toString.call(a) // "[object Array]"
Array.isArray(a) //true

bind,call,apply用法與區別

用法:都是改變函數內this指向

bind:返回一個新的函數,調用新的函數才執行,新函數裏this永久地被綁定到了bind的第一個參數上

而call與apply能直接執行

fuc.call(thisObj,a,b,c)

fuc.apply(thisObj,[a,b,c]) // apply 傳數組

原型 與 prototype屬性

  1. 原型:

JavaScript的對象中都包含了一個" [[Prototype]]"內部屬性,這個屬性所對應的就是該對象的原型。對象從原型繼承方法與屬性。原型可能也有原型,這種關係被稱爲原型鏈。

"[[Prototype]]"做爲對象的內部屬性,是不能被直接訪問的。因此爲了方便查看一個對象的原型,大多數現代瀏覽器仍是提供了一個名爲"__proto__"這個非標準(不是全部瀏覽器都支持)的訪問器(ECMA引入了標準對象原型訪問"Object.getPrototype(object)")。

原型是由構造器函數建立的。從原型繼承的方法與屬性是在構造器函數中定義的。

  1. prototype屬性:

prototype屬性並不指向當前對象的原型對象(原型對象是一個內部對象,應當使用 __proto__ 訪問)。prototype屬性是繼承成員被定義的地方。

常見的對象定義模式是,在構造器(函數體)中定義屬性、在 prototype 屬性上定義方法。(在prototype屬性中定義屬性會不夠靈活)

發現的比較奇異的點:一個變量不是函數的話默認沒有 prototype屬性,是函數的話默認就有 prototype屬性,而且prototype對象中的constructor屬性就是它自己

var a = {};
  console.log(a.__proto__) //{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
  console.log(a.__proto__ === Object.prototype) //true 
  console.log(a.constructor) //ƒ Object() { [native code] }
  console.log(a.constructor === Object) //true

  //******不是函數的話默認沒有 prototype屬性
  console.log(a.prototype) //undefined 

  console.log('b:')
  var b = function c() { };
  console.log(b.__proto__) //ƒ () { [native code] }
  console.log(b.__proto__ === Function.prototype) //true

  console.log(b.constructor) //ƒ Function() { [native code] }
  console.log(b.constructor === Function) //true

  //******函數默認就有 prototype屬性,而且prototype對象中的constructor屬性就是它自己
  console.log(b.prototype) //{constructor: ƒ}
  console.log(b.prototype.constructor) //ƒ c() { }
  console.log(b.prototype.constructor===b) //true

constructor

每一個對象實例都具備 constructor 屬性,它指向建立該實例的構造器函數。

能夠將此屬性做爲構造器使用:

var person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);

得到某個對象實例的構造器的名字,能夠這麼用:

person1.constructor.name

該屬性的值是那個函數自己,而不是一個包含函數名稱的字符串。對於原始值(js中有5種:null undefined number boolean string),該屬性爲只讀。

var a = 1;
    console.log(a.prototype) //undefined
    console.log(a.constructor) //ƒ Number() { [native code] }

    var b = [];
    console.log(b.prototype) //undefined
    console.log(b.constructor) //ƒ Array() { [native code] }

    //改變 a b 的constructor爲 {}
    a.constructor = {}
    b.constructor = {}
    console.log(a.constructor) //沒有變,仍是 ƒ Number() { [native code] }
    console.log(b.constructor) //{}

new

class

函數堆棧

ECMAScript中變量的兩種類型

原始值:
引用值:

js三大組成部分

1.ECMAScript
2.dom
3.bom

http協議

除了 GET POST,還有哪些方法

keep-alive

http返回碼100 200 300 400分別表明什麼,即響應的5種類型

100:信息響應

200:成功

300:重定向

400:客戶端錯誤

500:服務端錯誤

理解重定向

http無狀態含義

解釋三次握手,四次揮手

三次握手

1.客戶端發syn包給服務端,等待服務器確認(syn:同步序列編號(Synchronize Sequence Numbers))

2.服務端發syn+ack包給客戶端

3.客戶端發確認包ack給服務端

四次揮手

中斷鏈接端能夠是Client端,也能夠是Server端。

1.關閉主動方發送fin包

2.被動方發送ack包

3.被動方關閉鏈接,發送fin包

4.主動方發送ack包確認

數據結構與算法

鏈表和數組的區別

瞭解過哪些排序算法

js代碼實現

本身實現個jQuery,能夠傳選擇器進去,而後實現css()與height()方法

demo

var myJquery4 = function (selector) {
        //console.log(this) //window
        return new jqNodes(selector) //new會創造一個對象實例,對象實例繼承自構造函數的prototype,這裏是jqNodes.prototype
    }

    var jqNodes = function (selector) {
        console.log(this)
        //1.以new調用時this指向即將建立的新對象 
        //2.直接調用則指向 window
        this._items = document.querySelectorAll(selector)
        return this
    }

    var myJqueryCore = {
        //放核心方法
        css: function () {
            console.log(this) //myJquery4('li').css('color') 這樣調用時是做爲new出來的對象原型裏的方法調用的,this指向new出來的對象
            var prop = arguments[0],
                val = arguments[1]
            if (!val) return getComputedStyle(this._items[0]).getPropertyValue(prop);

            Array.prototype.map.call(this._items, function (c) {
                return c.setAttribute('style', prop + ':' + val)
            })
            return this
        }
    }

    jqNodes.prototype = myJqueryCore //關鍵

寫個輪播圖

以前感受比較困擾的是從最後一頁到第一頁如何無縫滑動。無縫滑動的關鍵在於在第一頁前放上最後一頁,在最後一頁後面再放上第一頁。在最後一頁點擊後一頁時,先滑動到放置在後邊的第一頁,滑動完成後馬上改變父元素的left值到排列在第二個的第一頁。

demo

html結構:

<div id="list" style="left: -600px;">
    <div>5</div>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>1</div>
</div>

關鍵js:

$('#list').animate({ left: newLeft }, function () {
    if (newLeft < -3000) {
        list.style.left = -600 + 'px';
    } else if (newLeft > -600) {
        list.style.left = -3000 + 'px';
    }
})

菜單高亮滾動監聽

主要參考了 http://blog.csdn.net/sinrryzh...
我修改爲了能夠有多個固定導航的

demo

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
        .fix-menu {
            position: fixed;
            right: 30px;
            top: 30px;
            width: 160px;
            list-style-type: none;
            font-size: 14px;
            padding: 0;
        }
        .fix-menu ul {
            list-style-type: none;
            padding: 0;
        }
        ._h2 a{
           
            padding-left: 20px;
        }
        ._h3 a{
            padding-left: 40px;
        }
        .fix-menu a {
            color: #333;
            text-decoration: none;
            line-height: 28px;
            display: block;
            width: 100%;
        }
        .fix-menu .active {
            background: #f4f6fb;
            color: green;
            border-left: 4px solid green;
        }
        .fix-menu .active a {
            color: green;
        }
    </style>

</head>

<body>
    <div class="main" id="main1">
        <div class="m-cloumn" id="c1">
            <h2>欄目1內容</h2>
        </div>
        <div class="m-cloumn" id="c2">
            <h2>欄目2內容</h2>
        </div>
        <div class="m-cloumn" id="c3">
            <h2>欄目3內容</h2>
        </div>
        <div class="m-cloumn" id="c4">
            <h2>欄目4內容</h2>
        </div>
        <div class="m-cloumn" id="c5">
            <h2>欄目5內容</h2>
        </div>
        <div class="m-cloumn" id="c6">
            <h2>欄目6內容</h2>
        </div>
        <div class="m-cloumn" id="c7">
            <h2>欄目7內容</h2>
        </div>

    </div>
    <div class="right-cloumn" id="menu1">
        <a href="#c1" class="curr">欄目1</a>
        <a href="#c2">欄目2</a>
        <a href="#c3">欄目3</a>
        <a href="#c4">欄目4</a>
        <a href="#c5">欄目5</a>
        <a href="#c6">欄目6</a>
        <a href="#c7">欄目7</a>
    </div>


    <div class="main" id="main2">
        <div class="m-cloumn" id="c2-1">
            <h2>欄目2-1內容</h2>
        </div>
        <div class="m-cloumn" id="c2-2">
            <h2>欄目2-2內容</h2>
        </div>
        <div class="m-cloumn" id="c2-3">
            <h2>欄目2-3內容</h2>
        </div>
        <div class="m-cloumn" id="c2-4">
            <h2>欄目2-4內容</h2>
        </div>
        <div class="m-cloumn" id="c2-5">
            <h2>欄目2-5內容</h2>
        </div>
        <div class="m-cloumn" id="c2-6">
            <h2>欄目2-6內容</h2>
        </div>
        <div class="m-cloumn" id="c2-7">
            <h2>欄目2-7內容</h2>
        </div>

    </div>
    <div class="right-cloumn" id="menu2">
        <a href="#c2-1">欄目2-1</a>
        <a href="#c2-2">欄目2-2</a>
        <a href="#c2-3">欄目2-3</a>
        <a href="#c2-4">欄目2-4</a>
        <a href="#c2-5">欄目2-5</a>
        <a href="#c2-6">欄目2-6</a>
        <a href="#c2-7">欄目2-7</a>
    </div>

    <script src="../jquery.min.js" type="text/javascript"></script>
    <script>
        (function ($, win, doc) {
            var scroll_highlight = function (obj) {
                return new scroll_rsilder(obj)
            }
            var scroll_rsilder = function (obj) {
                this.init(obj)
            }
            scroll_rsilder.prototype = {
                win_evet: function () {
                    var _this = this._this
                    $(win).on("scroll", function () {
                        var scrollTop = $(this).scrollTop();
                        _this.ele_evet(scrollTop);

                    })
                },
                ele_evet: function (scrollTop) {
                    var _this = this._this
                    $(this.cloumn).each(function (index) {
                        var offsetTop = $(this).offset().top;
                        var xd = parseInt(offsetTop - scrollTop);
                       
                        //console.log(index, offsetTop, scrollTop, xd, _this)

                        if (xd < _this.spacing) {
                            $(_this.silder).eq(index).addClass(_this.curr).siblings().removeClass();
                        }
                    })
                },
                init: function (obj) {
                    this._this = this,
                        this.cloumn = obj.cloumn,
                        this.silder = obj.silder,
                        this.spacing = obj.spacing || 100,
                        this.curr = obj.curr || "curr";
                    if (!this.cloumn) return;
                    this.win_evet();
                }

            }
            win.scroll_highlight = scroll_highlight;
        })(jQuery, window, document)
    </script>
    <script>
        $(function () {
            scroll_highlight({
                cloumn: "#main1 .m-cloumn",
                silder: "#menu1 a",
                spacing: 80,
                curr: "curr"
            })

            scroll_highlight({
                cloumn: "#main2 .m-cloumn",
                silder: "#menu2 a",
                spacing: 80,
                curr: "curr"
            })

        })
    </script>



</body>

</html>

網上看的面試題&本身發現的面試知識點

注:本身發現的面試知識點通常是在工做學習中發現的基礎重要但以前被本身忽略的知識點。

js基礎

全等號優先級大於邏輯與

var a=1===2&&3?4:5

逗號操做符

逗號操做符 對它的每一個操做數求值(從左到右),並返回最後一個操做數的值。

var x=(0,1) //x=1

比較對象

兩個獨立聲明的對象永遠也不會相等,即便他們有相同的屬性,只有在比較一個對象和這個對象的引用時,纔會返回true.

encodeURI encodeURIComponent

  • encodeURI
    encodeURI 會替換全部的字符,但不包括如下字符,即便它們具備適當的UTF-8轉義序列:
類型         包含
保留字符    ; , / ? : @ & = + $
非轉義的字符    字母 數字 - _ . ! ~ * ' ( )
數字符號    #

encodeURI自身沒法產生能適用於HTTP GET 或 POST 請求的URI,例如對於 XMLHTTPRequests, 由於 "&", "+", 和 "=" 不會被編碼,然而在 GET 和 POST 請求中它們是特殊字符。然而encodeURIComponent這個方法會對這些字符編碼。

  • encodeURIComponent
    轉義除了字母、數字、(、)、.、!、~、*、'、-和_以外的全部字符。

dangerouslysethtml會過濾掉__html屬性裏的 ,是由於用了encodeURI函數來避免xss攻擊

encodeURI('/\/\//') -->」////「
encodeURI('\') --> Uncaught SyntaxError: Invalid or unexpected token
encodeURIComponent('/\/\//') -->"%2F%2F%2F%2F"
encodeURIComponent('/') --> "%2F"
encodeURIComponent('\') --> Uncaught SyntaxError: Invalid or unexpected token

http協議

xss

cross-site scripting,跨站腳本,屬於代碼注入的一種。它容許惡意用戶將代碼注入到網頁上,其餘用戶在觀看網頁時就會受到影響。這類攻擊一般包含了html以及用戶端腳本語言。
攻擊實例:用戶A提交表單事加入相似如下代碼,若是提交表單時沒有作檢測,而以後的結果頁面是其餘用戶也能看到的,那麼其餘頁面看到的結果頁就會受到影響。

<script>
    document.write('...')
</script>

解決辦法:不信賴用戶輸入,對特殊字符如」<」,」>」轉義。

uri url urn

uri:統一資源標識符
url:統一資源定位符
urn:統一資源名稱
url與urn是uri的子集。
讓uri能成爲url的是那個「訪問機制」,「網絡位置」。e.g. http:// or ftp://.。
urn是惟一標識的一部分,就是一個特殊的名字。

etag是什麼

ETag(entity tag)惟一地表示一份資源的實體標籤。
標籤是由 ASCII 字符組成的字符串,用雙引號括起來(如 "675af34563dc-tr34")。前面能夠加上 W/ 前綴表示應該採用弱比較算法。

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
ETag: W/"0815"

ETag由Web服務器根據URL上的資源的特定版本而指定。若是那個URL上的資源內容改變,一個新的不同的ETag就會被分配。ETag的比較只對同一個URL有意義——不一樣URL上的資源的ETag值可能相同也可能不一樣,從他們的ETag的比較中無從推斷。

用法:
1.檢測"空中碰撞"(資源同步更新而相互覆蓋):
在ETag和 If-Match 頭部的幫助下,能夠檢測到"空中碰撞"的編輯衝突。

2.緩存未更改的資源
若是用戶再次訪問給定的URL(設有ETag字段),顯示資源過時了且不可用,客戶端就發送值爲ETag的If-None-Match header字段:

If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
服務器將客戶端的ETag(做爲If-None-Match字段的值一塊兒發送)與其當前版本的資源的ETag進行比較,若是兩個值匹配(即資源未更改),服務器將返回不帶任何內容的304未修改狀態,告訴客戶端緩存版本可用(新鮮)。

If-Match 頭部

請求首部 If-Match 的使用表示這是一個條件請求。在請求方法爲 GET 和 HEAD 的狀況下,服務器僅在請求的資源知足此首部列出的 ETag 之一時纔會返回資源。而對於 PUT 或其餘非安全方法來講,只有在知足條件的狀況下才能夠將資源上傳。

應用:

  1. GET 和 HEAD 方法,搭配 Range首部使用,能夠用來保證新請求的範圍與以前請求的範圍是對同一份資源的請求。若是 ETag 沒法匹配,那麼須要返回 416 (Range Not Satisfiable,範圍請求沒法知足) 響應。

2.對於其餘方法來講,尤爲是 PUT, If-Match 首部能夠用來檢測用戶想要上傳的不會覆蓋獲取原始資源以後作出的更新。若是請求的條件不知足,那麼須要返回 412 (Precondition Failed,先決條件失敗) 響應。

語法:

If-Match: <etag_value>, <etag_value>, …

樂觀併發控制

ASCII字符串

ASCII (發音: /ˈæski/ ,American Standard Code for Information Interchange,美國信息交換標準碼) 是計算機中最經常使用的編碼方式,用於將字母,數字,標點符號和控制字符轉換爲計算機能夠理解的數字形式。

ASCII的侷限在於只能顯示26個基本拉丁字母、阿拉伯數目字和英式標點符號,所以只能用於顯示現代美國英語(並且在處理英語當中的外來詞如naïve、café、élite等等時,全部重音符號都不得不去掉,即便這樣作會違反拼寫規則)。而ASCII雖然解決了部分西歐語言的顯示問題,但對更多其餘語言依然無能爲力。所以如今的軟件系統大多采用Unicode。

ASCII主要用於顯示現代英語和其餘西歐語言。從2007年開始逐漸被UTF-8 代替。

Unicode

Unicode(中文:萬國碼、國際碼、統一碼、單一碼)是計算機科學領域裏的一項業界標準。它對世界上大部分的文字系統進行了整理、編碼,使得電腦能夠用更爲簡單的方式來呈現和處理文字。

UTF-8

UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字符編碼,也是一種前綴碼。它能夠用來表示Unicode標準中的任何字符,且其編碼中的第一個字節仍與ASCII兼容,這使得原來處理ASCII字符的軟件無須或只須作少部分修改,便可繼續使用。所以,它逐漸成爲電子郵件、網頁及其餘存儲或發送文字的應用中,優先採用的編碼。

Range首部

Range 是一個請求首部,告知服務器返回文件的哪一部分。在一個 Range 首部中,能夠一次性請求多個部分,服務器會以 multipart 文件的形式將其返回。若是服務器返回的是範圍響應,須要使用 206 Partial Content 狀態碼。假如所請求的範圍不合法,那麼服務器會返回 416 Range Not Satisfiable 狀態碼,表示客戶端錯誤。服務器容許忽略 Range 首部,從而返回整個文件,狀態碼用 200 。

語法:

Range: <unit>=<range-start>-
Range: <unit>=<range-start>-<range-end>
Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>
Range: bytes=200-1000, 2000-6576, 19000-

一級域名,二級域名

以www.baidu.com爲例子
最右邊一個點右邊的爲頂級域名(一級域名)com
一級域名左邊是二級域名 baidu

主域,子域

子域名域名系統等級中,屬於更高一層域的域。好比,mail.example.com
和calendar.example.com是example.com的兩個子域,而example.com
則是頂級域.com的子域

非技術問題

爲何換工做

不要說是由於錢少。上一家的薪資不要作假,由於公司可能會查。指望薪資能夠要高點,說明。

<script src="../jquery.min.js"></script><script src="../scroll-highlight.js"></script><script src="../fix-menu.js"></script>

相關文章
相關標籤/搜索