前端面試總結

不錯文章推薦

1、html部分

2、 css部分

一、BFC 連接

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

二、水平豎直居中方案連接

三、重繪和重排 詳情

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

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

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.三、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>

複製代碼

3、js部分

一、new 構造函數發生了哪幾個步驟

  • 建立一個新對象;
  • 將構造函數的做用域賦給新對象(所以this就指向了這個新對象);
  • 執行構造函數中的代碼(爲這個新對象添加屬性);
  • 返回新對象

二、原型鏈問題 連接

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
複製代碼

三、http2優點 地址

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

四、強制緩存與協商緩存 地址

  • 強制緩存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  
複製代碼

五、手寫防抖函數 地址

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
}
複製代碼

六、二叉樹 地址

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

七、瀏覽器的事件循環 地址

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

八、閉包

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

九、數組的去重連接

let arr = [2,4,2,6,4,8,10];  
//一、利用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
}
//二、利用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
}
//三、利用對象的屬性不能相同的特色進行去重  
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
}
  
複製代碼

十、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);
});
}
}
複製代碼

4、react部分

一、生命週期

二、setState同步異步的問題

三、Route 渲染組件的三種方式

  • component 最經常使用,只有匹配 location 纔會加載 component 對應的 React組件
  • render 路由匹配函數就會調用
  • children 無論路由是否匹配都會渲染對應組件

5、node部分

一、中間件實現(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();  
複製代碼

二、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'));  
複製代碼

三、xss和csrf

  • xss跨站腳本攻擊 一、HttpOnly 防止劫取 Cookie 二、轉義
  • csrf跨站請求僞造 一、增長驗證碼 二、驗證token

6、前端常見算法 連接

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

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) );
複製代碼

二、冒泡排序

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]));
複製代碼

三、快速排序 連接

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]));
複製代碼

四、二分查找

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

複製代碼

五、數組的diff

const arrA = [1, 2, 3, 4];
const arrB = [1, 2, 5, 8];
const difference = arrA.concat(arrB).filter(v =>
  // console.log(v);
  arrA.includes(v) && !arrB.includes(v) // [1,3]

);
console.log(difference);

複製代碼
相關文章
相關標籤/搜索