前端面試題雜燴(答案)

藍莓_酸牛乳發表於2018-06-29

一、Html相關

1、html5新增的表單元素

  • datalist
  • keygen
  • output

二、css相關

  • 1、如何畫一個三角形(阿里一面同款)
      <div class="triangle"></div>
      .triangle{
          width:0;
          height:0;
          border-left:20px solid transparent;
          <!--border-left:20px solid transparent;-->
          border-top:20px solid pink;
      }
    複製程式碼

前端面試題雜燴(答案)

  • 2、CSS3中對溢位的處理: overflow:visiblle/hidden/auto/scroll

    • visible:如果內容區域的大小能夠容納子矩形物件,瀏覽器會正常地顯示子矩形物件;當內容區域無法容納子矩形區域時,瀏覽器會在內容區域之外,顯示完整的子矩形物件。
    • hidden:如果內容區域的大小能夠容納子矩形物件,瀏覽器會正常地顯示子矩形物件;當內容區域無法容納子矩形區域時,瀏覽器會顯示內容區域之內的子矩形物件,超出內容區域的則不顯示。
    • scroll:如果內容區域的大小能夠容納子矩形物件,瀏覽器會正常地顯示子矩形物件,並且顯示預設滾動條;當內容區域無法容納子矩形區域時,瀏覽器會在內容區域之內顯示完整的子矩形物件,並且顯示滾動條、啟用滾動條功能,讓使用者能夠瀏覽完整的子矩形物件。
    • auto:如果內容區域的大小能夠容納子矩形物件,瀏覽器會正常地顯示子矩形物件;當內容區域無法容納子矩形區域時,瀏覽器會在內容區域之內顯示完整的子矩形物件,並且顯示滾動條、啟用滾動條功能,讓使用者能夠瀏覽完整的子矩形物件。
  • 3、CSS的選擇器及優先順序:

前端面試題雜燴(答案)

不同級別:
    在屬性後面使用 !important 會覆蓋頁面內任何位置定義的元素樣式。
    作為style屬性寫在元素內的樣式
    id選擇器
    類選擇器
    標籤選擇器
    萬用字元選擇器
    瀏覽器自定義或繼承
總結排序:!important > 行內樣式>ID選擇器 > 類選擇器 > 標籤 > 萬用字元 > 繼承 > 瀏覽器預設屬性
權重值:
    內聯樣式表的權值為 1000
    ID 選擇器的權值為 100
    Class 類選擇器的權值為 10
    HTML 標籤選擇器的權值為 1
複製程式碼
  • 4、BFC(塊級格式化上下文)

    1、block-level box:display 屬性為 block, list-item, table 的元素,會生成 block-level box。並且參與 block fomatting context;
    2、定義:它是一個獨立的渲染區域,只有Block-level box參與, 它規定了內部的Block-level Box如何佈局,並且與這個區域外部毫不相干(不會影響盒子外的佈局外部佈局也不會影響盒子內的佈局)。
    3、佈局規則:
        內部的Box會在垂直方向,一個接一個地放置。
        Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
        每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。
        BFC的區域不會與float box重疊。
        BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素。反之也如此。
        計算BFC的高度時,浮動元素也參與計算
    4、觸發BFC:
        根元素
        float屬性不為none
        position為absolute或fixed
        display為inline-block, table-cell, table-caption, flex, inline-flex
        overflow不為visible
    
    複製程式碼
  • 5、清除浮動的方法:

    1、觸發父元素的BFC(塊級格式化上下文);

    2、在浮動元素後增加元素,並將clear:both;

         <div class="div1 clearfloat"> 
            <div class="left">Left</div> 
            <div class="right">Right</div> 
            <div style="clear:both"></div>
        </div>
        
        <div class="div2">
            div2
        </div>
        .div1{background:#000080;border:1px solid red;}
        .div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}
    複製程式碼

    3、在父元素上使用after偽類

        <div class="div1 clearfloat"> 
            <div class="left">Left</div> 
            <div class="right">Right</div> 
        </div>
        <div class="div2">
            div2
        </div>
       .div1{background:#000080;border:1px solid red;}
       .div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}
       .left{float:left;width:20%;height:200px;background:#DDD}
       .right{float:right;width:30%;height:80px;background:#DDD}
       .clearfloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}
       .clearfloat{zoom:1}
    複製程式碼
  • 6、實現一個兩列等高佈局

  • 7、怎麼樣讓一個元素消失

      是怎樣的的消失法呢?
      1、display:none;(元素不會被繪製)
      2、visibility:hidden(visible/collapse),元素不可見,但是仍處於dom結構中,會影響佈局。
      3、opacity:0
      4、position: absolute; top: -999em; /* 不佔據空間,無法點選 */ 
         position: relative; top: -999em; /* 佔據空間,無法點選 */ 
    複製程式碼

三、js相關

1、閉包的理解:

  • 閉包的定義:有權訪問另一個函式作用域中變數的函式

  • 閉包的用途:(1)、可以在函式外部訪問函式內部的變數;(2)、可以將一些變數一直留在記憶體當中。(這塊的用處是什麼歡迎補充)

  • 閉包的副作用:由於閉包會攜帶包含它的函式的作用域,因此會比其他函式佔用過多的記憶體。過度使用閉包會導致記憶體佔用過多。(雖然像V8等優化後JavaScript引擎會嘗試收回被閉包占用的記憶體,但還是建議大家謹慎使用閉包)

  • 我對閉包的理解

    前端面試題雜燴(答案)

    • 從作用域鏈的角度出發:js分為全域性作用域和區域性作用域
      function createComparisonFunction(propertyName) {
          return function(object1, object2){
              var value1 = object1[propertyName];
              var value2 = object2[propertyName];
              if (value1 < value2){
                  return -1;
              } else if (value1 > value2){
                  return 1;
              } else {
                  return 0;
          } };
      }
      
      //建立函式
      var compareNames = createComparisonFunction("name");
      //呼叫函式
      var result = compareNames({ name: "Nicholas" }, { name: "Greg" });
      //解除對匿名函式的引用(以便釋放記憶體) compareNames = null;
    複製程式碼
    • 閉包與變數:

      作用域鏈的這種配置機制引出了一個引人注意的副作用:即閉包只能取得包含函式中任何變數的最後一個值。之快又引出了一個新的問題,如何避免這個問題,若是使用es6的let,那麼又會引出let和var的區別是什麼?

    • 閉包this指向:匿名函式的執行環境具有全域性性,其this物件通常指向window
    • this物件:this物件是在執行時基於函式的執行環境繫結的,在全域性函式中,this等於window,而當函式被作為某個物件的方法呼叫時,this 等 於那個物件。
    紅寶書上關於上述問題的例子
    1、function creatClosure1(){
        var result = new Array()
        for(var i = 0;i < 6;i++){
            result[i] = function(){
                return i
            }
        }
    }
    解決辦法:
    2、function creatClosure2(){
        for(var i = 0;i < 6;i++){
            result[i] = (function(num){
            //多了一個外層函式
                return function(){
                    return num
                }
            })(i)
        }
    }
    3、functionn  creatClosure3(){
        for(let i = 0;i < 6;i++){
            result[i] = function(){
                return i
            }
        }
    }
複製程式碼
  • let和var的區別
var:在函式作用域內生效,存在變數提升,可以重複宣告。
let:在塊級作用域生效,不存在變數提升,不允許重複宣告,必須先宣告後使用。
複製程式碼
//第一段程式碼  
var a = 2;  
var a = 3;  
alert(a);//3  
//第二段程式碼  
<span style="font-size:18px;"></span><pre name="code" class="javascript">a = 2;  
alert(a);//2 
在js程式碼執行的過程中,引擎負責程式碼的編譯及執行,編譯器負責詞法分析、語法分析、程式碼生成等工作,作用域則負責變數的管理即維護所有的表識別符號。

而編譯器和引擎在執行程式碼的過程中還會執行額外的工作:檢查變數是否存在。

        1.首先編譯器對程式碼進行分析拆解,從左至右遇見var a,則編譯器會詢問作用域是否已經存在叫a的變數了,如果不存在,則招呼作用域宣告一個新的變數a,若已經存在,則忽略var 繼續向下編譯,這時a = 2被編譯成可執行的程式碼供引擎使用。

        2.引擎遇見a=2時同樣會詢問在當前的作用域下是否有變數a,若存在,則將a賦值為2(由於第一步編譯器忽略了重複宣告的var,且作用域中已經有a,所以重複宣告會發生值得覆蓋而並不會報錯)。若不存在,則順著作用域鏈向上查詢,若最終找到了變數a則將其賦值2,若沒有找到,則招呼作用域宣告一個變數a並賦值為2(這就是為什麼第二段程式碼可以正確執行且a變數為全域性變數的原因,當然,在嚴格模式下JS會直接丟擲異常:a is not defined)。
複製程式碼
  • 2、如何判斷一個陣列

        1、es5定義的Array.isArray(arr);//返回true/false
        2、若是不支援isArray方法,則使用:
            a、Object.prototype.tostring.call(arr) == [Objejct Array];
            b、arr.constructor === 'Array'
        //將上述方式彙總成一個判斷是不是陣列的方法
         ifArray(arr){
            if(!!Array.isArray){
                return Array.isArray(arr);
            }else{
                let result;
                result = !!Object.prototype.toString.call(arr) === '[Object Array]'?true:false;
                return result;
                
            }
            // if(typeof arr === 'object' && arr.constructor.name === 'Array'){
            //     return true;
            // }else{
            //     return false;
            // }
        }
    複製程式碼
  • 3、JS實現倒數計時

    倒數計時校準

    vue寫的部分程式碼,大概是這個意思
      let _self = this;
        // let timeId;
        if(!!_self.showTime){
            return;
        }
        _self.showTime = true;
        _self.text = "重新傳送驗證碼";
        let startTime = new Date();
        let count = 1;
        timeId = setInterval(function(){
            console.log('count',count)
            let endTime = new Date();
            let offset = endTime - startTime - count*1000;
            console.log('offset',offset);
            count++;
        },1000);
        timeId = setInterval(function(){
            // console.log(_self.time);
            if(_self.time>0){
                 console.log(_self.time);
                _self.time -= 1;
            }else{
                _self.time = 5;
                _self.text = '獲取驗證碼'
                _self.showTime = false
                clearInterval(timeId);
            }
        },1000);
    複製程式碼
  • 陣列去重的三種實現方式

         //1、ES6 新特性 Set
        removeDuplicate1(arr){
            let arrNew = new Set(arr);
            return Array.from(arrNew);
        }
        //2、基本去重 for迴圈 +indexof
        removeDuplicate2(arr){
            let copyArr = [];
            for(let i = 0;i<arr.length;i++){
                if(copyArr.indexOf(arr[i]) < 0){
                    copyArr.push(arr[i]);
                }
            }
            return copyArr;
        }
        //3、利用物件的屬性
        removeDuplicate3(arr){
            if(arr.length<=1){
                return arr;
            }
            let obj = {};
            let copyArr = [];
            for(let i=0;i<arr.length;i++){
                if(!obj[arr[i]]){
                    obj[arr[i]] = 1;
                    copyArr.push(arr[i]);
                }
            }
            return copyArr;
        }
    複製程式碼

四、ES6相關

1、實現promise.all()

    function promiseAll(promises){
         return new Promise(function(resolve,reject){
           //先判斷引數是不是陣列
          if(!!Array.isArray){
            if(!Array.isArray(promises)){
              return
            }
          }else{
            if(!Object.prototype.toString.call(promises)==='[Object Array]'){
              return
            }
            if(!promises.constructor.name === 'Array'){
              return
            }
          }
           //再判斷引數陣列長度是否為0
           if(promises.length < 1){
             return resolve('is an empty obj')
           }
           let count = promises.length
           let successCount = 0
           let successArr = []
           promises.map(function(val,index){
             val.then((value) => {
               successCount++
               successArr.push(value)
               if(successCount === count){
                 return resolve(successArr)
               }
             }).catch((e) => {
               return reject(e)
             })
           })
         })
      }
    let p1 = Promise.resolve(Promise.resolve("wode"))
    let p2 = Promise.resolve(Promise.resolve("haole"))
    let p3 = Promise.reject(Promise.resolve("good luck"))
    this.promiseAll([]).then((results) => {
      console.log('success',results)
    }).catch( (e) => {
      console.log('fail',e)
    })
複製程式碼

五、演算法相關

六、計網相關

(一)、HTTP相關

1、get和post請求

  • 根據HTTP規範,GET用於資訊獲取,而且應該是安全的和冪等的 。

    1.所謂安全的意味著該操作用於獲取資訊而非修改資訊。換句話說,GET請求一般不應產生副作用。就是說,它僅僅是獲取資源資訊,就像資料庫查詢一樣,不會修改,增加資料,不會影響資源的狀態。

    2.冪等的意味著對同一URL的多個請求應該返回同樣的結果。

前端面試題雜燴(答案)
2、http三次握手和四次揮手 這篇講的很詳細:juejin.im/post/5a0444…

七、資料結構相關

八、作業系統相關

1、程式和執行緒的區別 2、執行緒的哪些資源共享,那些資源不共享

前端面試題雜燴(答案)

九、其他

  • base64相關

    1、base64原理

    2、前端效能優化中用到base64:

    
     1. 優點
     (1)base64格式的圖片是文字格式,佔用記憶體小,轉換後的大小比例大概為1/3,降低了資源伺服器的消耗;
     (2)網頁中使用base64格式的圖片時,不用再請求伺服器呼叫圖片資源,減少了伺服器訪問次數。
     2. 缺點
     (1)base64格式的文字內容較多,儲存在資料庫中增大了資料庫伺服器的壓力;
     (2)網頁載入圖片雖然不用訪問伺服器了,但因為base64格式的內容太多,所以載入網頁的速度會降低,可能會影響使用者的體驗。
     (3)base64無法快取,要快取只能快取包含base64的檔案,比如js或者css,這比直接快取圖片要差很多,而且一般HTML改動比較頻繁,所以等同於得不到快取效益。
     
     因為base64的使用缺點,所以一般圖片小於10kb的時候,我們才會選擇使用base64圖片,比如一些表情圖片,太大的圖片轉換成base64得不償失。當然,極端情況極端考慮。
    複製程式碼
  • 移動端網頁效能優化自查表

  • 2018 前端效能優化清單

  • 重排和重繪: 這篇就夠了

  • HTTP狀態碼說說你知道的 這篇挺詳細

  • 講講304(我能介紹一下瀏覽器快取機制嗎): 條件請求

  • 瀏覽器快取機制: 詳解

  • 從效能優化的角度講解了瀏覽器快取機制

  • 必須強推的面試乾貨之瀏覽器的渲染機制解析

  • DOMContentLoaded: DOM解析完成即觸發此事件,不等待styles, images等資源的載入(僅當DOM載入完成,不包括樣式表,圖片,flash)
    load:依賴的資源也已載入完成(頁面上所有的DOM,樣式表,指令碼,圖片,flash都已經載入完成了)
    DOMContentLoaded繫結到document,load繫結到window

相關文章