前端面試總結

curiousby發表於2017-08-08

不錯文章推薦

一、html部分

二、 css部分

1、BFC 連結

  • 在一個塊級排版上下文中,盒子是從包含塊頂部開始,垂直的一個接一個的排列的。 相鄰兩個盒子之間的垂直的間距是被margin屬性所決定的,在一個塊級排版上下文中相鄰的兩個塊級盒之間的垂直margin是摺疊的

2、水平豎直居中方案連結

3、重繪和重排 詳情

  • 重繪:當盒子的位置、大小以及其他屬性,例如顏色、字型大小等都確定下來之後,瀏覽器便把這些原色都按照各自的特性繪製一遍,將內容呈現在頁面上。 重繪是指一個元素外觀的改變所觸發的瀏覽器行為,瀏覽器會根據元素的新屬性重新繪製,使元素呈現新的外觀。 觸發重繪的條件:改變元素外觀屬性。如:color,background-color等。
  • 重排: 當渲染樹中的一部分(或全部)因為元素的規模尺寸,佈局,隱藏等改變而需要重新構建, 這就稱為迴流(reflow)。每個頁面至少需要一次迴流,就是在頁面第一次載入的時候。
  • 聯絡:重繪和重排的關係:在迴流的時候,瀏覽器會使渲染樹中受到影響的部分失效,並重新構造這部分渲染樹,完成迴流後,瀏覽器會重新繪製受影響的部分到螢幕中,該過程稱為重繪。 所以,重排必定會引發重繪,但重繪不一定會引發重排。

4、三列布局(左右兩邊固定,中間自適應) 連結

4.1利用浮動,注意左中右位置

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .left{
            width: 200px;
            height: 200px;
            background: red;
            float: left;
        }
        .middle{

        }
        .right{
            width: 200px;
            height: 200px;
            background: blue;
            float: right;
        }
    </style>
</head>
<body>
    <div>
        <div class="left">left</div>
        <div class="right">right</div>
        <div class="middle">前些日子從@張鑫旭微博處得一份推薦(Front-end-tutorial),號稱 最全的資源教程 -前端涉及的所有知識體系;有粗略檢視,果然“歎為觀止”,至少比想象中涉獵豐富許多;果斷有Fork了來:Front-end-tutorial;本就有收藏&分享欲,這種事兒早期也想做了,勘嘆見識未廣而深;幸遇這良心收集,得以借他人之酒杯,一澆我心之夙願塊壘。畢竟人為收集,並未臻於不可附加之境,還是有許多可以補充的點;因此,有特引於部落格,將酌情適當增刪些內容,一來做自己查糾探索之源,二來分享給更多朋友;好文章好工具,很多時候都被隱藏於犄角旮旯了,有居乾貨,歡請分享。</div>
    </div>
</body>
</html>

複製程式碼

4.2利用position 絕對定位,脫離文件流

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .left{
            width: 200px;
            height: 200px;
            background: red;
            position: absolute;
            left: 0;
            top:0;
        }
        .middle{
           margin:0 200px;
        }
        .right{
            width: 200px;
            height: 200px;
            background: blue;
            position: absolute;
            top: 0;
            right: 0;
        }
    </style>
</head>
<body>
    <div>
        <div class="left">left</div>
        <div class="middle">前些日子從@張鑫旭微博處得一份推薦(Front-end-tutorial),號稱 最全的資源教程 -前端涉及的所有知識體系;有粗略檢視,果然“歎為觀止”,至少比想象中涉獵豐富許多;果斷有Fork了來:Front-end-tutorial;本就有收藏&分享欲,這種事兒早期也想做了,勘嘆見識未廣而深;幸遇這良心收集,得以借他人之酒杯,一澆我心之夙願塊壘。畢竟人為收集,並未臻於不可附加之境,還是有許多可以補充的點;因此,有特引於部落格,將酌情適當增刪些內容,一來做自己查糾探索之源,二來分享給更多朋友;好文章好工具,很多時候都被隱藏於犄角旮旯了,有居乾貨,歡請分享。</div>
        <div class="right">right</div>
    </div>
</body>
</html>
複製程式碼

4.3、flex實現


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .container{
            display: flex;
        }
        .left{
            width: 200px;
            height: 200px;
            background: red;
        }
        .middle{
            flex: 1;
        }
        .right{
            width: 200px;
            height: 200px;
            background: blue;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="left">left</div>
        <div class="middle">前些日子從@張鑫旭微博處得一份推薦(Front-end-tutorial),號稱 最全的資源教程 -前端涉及的所有知識體系;有粗略檢視,果然“歎為觀止”,至少比想象中涉獵豐富許多;果斷有Fork了來:Front-end-tutorial;本就有收藏&分享欲,這種事兒早期也想做了,勘嘆見識未廣而深;幸遇這良心收集,得以借他人之酒杯,一澆我心之夙願塊壘。畢竟人為收集,並未臻於不可附加之境,還是有許多可以補充的點;因此,有特引於部落格,將酌情適當增刪些內容,一來做自己查糾探索之源,二來分享給更多朋友;好文章好工具,很多時候都被隱藏於犄角旮旯了,有居乾貨,歡請分享。</div>
        <div class="right">right</div>
    </div>
</body>
</html>

複製程式碼

4.4雙飛翼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .middle-wrap {
            float: left;
            width: 100%;
            height: 200px;
            background-color: yellow;
        }
        .middle-wrap .middle {
            height: 200px;
            margin: 0 200px; /*留出距離*/
            background-color: yellow;
        }
        .left {
            float: left;
            width: 200px;
            margin-left: -100%;
            height: 200px;
            background-color: red;
        }
        .right{
            float: left;
            width: 200px;
            height:200px;
            margin-left: -200px;
            background-color: green;
        }
    </style>
</head>
<body>
<div>
    <!--主元素要放在文件流最前面-->
    <div class="middle-wrap">
        <div class="middle"><span>div-middle</span></div>
    </div>
    <div class="left"><span>div-left</span></div>
    <div class="right"><span>div-right</span></div>
</div>
</body>
</html>
複製程式碼

4.5聖盃佈局


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .container{
            padding:  0 100px;/* 留出左右的距離*/
            height: 100px;
        }
        .middle {
            float: left;
            width: 100%;
            height: 50px;
            background-color: yellow;

        }
        .left {
            float: left;
            width: 100px;
            margin-left: -100%;
            height: 50px;
            background-color: red;
            position: relative;
            left: -100px;/*往左拉*/
        }
        .right{
            float: left;
            width: 100px;
            height:50px;
            margin-left: -100px;
            background-color: green;
            position: relative;
            right: -100px;/*往右拉*/
    </style>
</head>
<body>
<div class="container">
    <!--主元素要放在文件流最前面-->
    <div class="middle"><span>div-middle</span></div>
    <div class="left"><span>div-left</span></div>
    <div class="right"><span>div-right</span></div>
</div>
</body>
</html>

複製程式碼

三、js部分

1、new 建構函式發生了哪幾個步驟

  • 建立一個新物件;
  • 將建構函式的作用域賦給新物件(因此this就指向了這個新物件);
  • 執行建構函式中的程式碼(為這個新物件新增屬性);
  • 返回新物件

2、原型鏈問題 連結

前端面試總結

foo = function () {
    this.number = 1;
};
foo.number = 2;
foo.prototype.number = 3;
bar = new foo();
console.log(foo.number); //2 
console.log(bar.number);    //1
console.log(foo.constructor);   //Fun
console.log(foo.prototype.constructor); //foo 
console.log(bar.constructor);   //foo 
console.log(bar.prototype);     //underfined
複製程式碼

3、http2優勢 地址

  • 多路複用
  • 二進位制分幀
  • 首部(頭部)壓縮
  • 服務端主動推送訊息

4、強制快取與協商快取 地址

  • 強制快取Catch-Control 、 Expires
cache-control:max-age=691200  
expires:Fri, 14 Apr 2017 10:47:02 GMT  
複製程式碼
  • 協商快取
Last-Modified和If-Modified-Since對應  
Etag和If-None-Match  
複製程式碼

5、手寫防抖函式 地址

function debounce(func, wait = 0) {
    let timer;

    function clearTimer() {
        clearTimeout(timer);
        timer = null;
    }

    function debounced(...args) {
        let self = this;
        if (timer == null) {
            addTimer();
            return
        } else {
            clearTimer();
            addTimer();
            return
        }

        function addTimer() {
            timer = setTimeout(() => {
                invokeFunc();
                clearTimer()
            }, wait)
        }

        function invokeFunc() {
            func.apply(self, args)
        }
    }
    return debounced
}
複製程式碼

6、二叉樹 地址

  • 前序遍歷:訪問根–>遍歷左子樹–>遍歷右子樹;
  • 中序遍歷:遍歷左子樹–>訪問根–>遍歷右子樹;
  • 後序遍歷:遍歷左子樹–>遍歷右子樹–>訪問根;
  • 廣度遍歷:按照層次一層層遍歷;

7、瀏覽器的事件迴圈 地址

  • 常見的巨集任務:
    setTimeout
    setImmediate(只有ie支援)
    setInterval
    messageChannel
  • 常見的微任務:
    Promise.then()
    mutationObserver
    process.nextTick(callback)

8、閉包

for (var j = 0; j < 3; j++) {
    (function (j) {
        setTimeout(function () {
            console.log(j)
        }, 1000)
    })(j)
}
複製程式碼

9、陣列的去重連結

let arr = [2,4,2,6,4,8,10];  
//1、利用for巢狀for,然後splice去重  
function unique(arr) {
    for (let i = 0; i < arr.length; i++) {
        for (let j = i + 1; j < arr.length; j++) {
            if (arr[i] == arr[j]) {
                arr.splice(j, 1);
                j--;
            }
        }
    }
    return arr
}
//2、利用indexOf去重  
function unique1(arr) {
    let array = [];
    for (let i = 0; i < arr.length; i++) {
        if (array.indexOf(arr[i]) === -1) {
            array.push(arr[i])
        }
    }
    return array
}
//3、利用物件的屬性不能相同的特點進行去重  
function unique2(arr) {
    let array = [];
    let obj = {};
    for (let i = 0; i < arr.length; i++) {
        if (!obj[arr[i]]) {
            array.push(arr[i]);
            obj[arr[i]] = 1;
        } else {
            obj[arr[i]]++
        }
    }
    return array
}
  
複製程式碼

10、promise實現多個請求併發,控制併發數

const promises = [p1, p2, p3, p4, p5];
const max = 2;
let ins = 0;
let result = [];

function send(promises) {
if(promises.length) {
const pros = promises.slice(ins * max, max);
ins++;
pros.length && Promise.all(pros).then(res => {
result = result.concat(res);
send(promises);
});
}
}
複製程式碼

四、react部分

1、生命週期

前端面試總結

2、setState同步非同步的問題

前端面試總結

前端面試總結

3、Route 渲染元件的三種方式

  • component 最常用,只有匹配 location 才會載入 component 對應的 React元件
  • render 路由匹配函式就會呼叫
  • children 不管路由是否匹配都會渲染對應元件

五、node部分

1、中介軟體實現(koa)

function app() {  
  
}  
app.routes = [];  
app.use = function (fn) {  
 app.routes.push(fn)};  
app.use((ctx,next)=>{  
 console.log(1); next(); console.log(2);});  
app.use((ctx,next)=>{  
 console.log(3); next(); console.log(4);});    
  
let index= 0;  
function next() {  
 if(app.routes.length ===index) return; let route =  app.routes[index++]; console.log(String(route)); route({},next);}  
next();  
複製程式碼

2、generator函式

//  generator 必須要有* 配合yeild ,碰到yield 就停止,再次呼叫next就繼續走  
// 當遇到return時就迭代完成了  
// 第一個next傳遞引數是沒有效果的  
// 第二次next傳遞的引數 是第一次yield的返回值  
function* thing() {
    let a = yield 1;
    console.log(a);
    let b = yield 2;
    console.log(b);
    return b;
}
let it = thing();  
console.log(it.next(111));  
console.log(it.next(2000));  
console.log(it.next('4000'));  
複製程式碼

3、xss和csrf

  • xss跨站指令碼攻擊 1、HttpOnly 防止劫取 Cookie 2、轉義
  • csrf跨站請求偽造 1、增加驗證碼 2、驗證token

六、前端常見演算法 連結

1、隨機生成指定長度的字串

function randomString(n){
    let str = 'abcdefghijklmnopqrstuvwxyz9876543210';
    let tmp = '',i=0,l=str.length;
    for(i=0;i<n;i++){
        tmp+=str.charAt(Math.floor(Math.random()*l))
    }
}

console.log(str.charAt(8) );
複製程式碼

2、氣泡排序

function bubbleSort(arr) {
    for(let i=0;i<arr.length-1;i++){
        for(let j=0;j<arr.length-i-1;j++){
            if(arr[j]>arr[j+1]){
                let temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
    return arr
}
console.log(bubbleSort([8,94,15,88,55,76,21,39]));
複製程式碼

3、快速排序 連結

function quickSort(arr) {
    if (arr.length == 0) {
        return [];
    }
    let left = [];
    let right = [];
    let pivot = arr[0];

    for(let i=1;i<arr.length;i++){
        if(arr[i]<pivot){
            left.push(arr[i])
        }else{
            right.push(arr[i]);
        }
    }
    return quickSort(left).concat(pivot,quickSort(right))
}

console.log(quickSort([15, 94, 8, 88]));
複製程式碼

4、二分查詢

function binary_search(arr, key) {
    var low = 0,
        high = arr.length - 1;

    while(low <= high) {
        var mid = parseInt((high + low) /2);
        // console.log(mid+'h'+high+'l'+low);
        if(key == arr[mid]) {
            return mid;
        } else if(key > arr[mid]) {
            low = mid + 1;
        } else {
            high = mid -1;
        }
    }
    return -1
}

var arr = [1,2,3,4,5,6,7,8,9,10,11,23,44,86];
var result = binary_search(arr, 10);
console.log(result);   // 9
var resultNone = binary_search(arr, 100);
console.log(resultNone);  // -1

複製程式碼

相關文章