面試題(11)之 大廠外包面試題

寫在前面:html

一年沒有面試了,約了一個外包面試,去大廠,就當我去檢測我這1年的成果了。前端

1 變量提高

var a = 1
function a() {
  return 2
}
console.info(a) // 1
console.info(typeof a) // number

 

2 異步

for(var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.info(i)
  });
}
// 3 3 3

 

3 隨機排序

實現一個方法,將有序的數組變爲亂序es6

// 解法一
function getRandomArr(arr) {
  let len = arr.length
  let randomIndex = Math.floor(Math.random() * len)
  let temp
  while(len >= 0) {
    temp = arr[randomIndex]
    arr.splice(randomIndex, 1)
    arr.push(temp)
    len--
    randomIndex = Math.floor(Math.random() * len)
  }
  return arr
}

 

// 解法二
function getRandomArr(arr) {
  /* 每次循環時都要與第i項互換位置 */
  for (var i = 0; i < arr.length; i++) {
    var j = parseInt(Math.random() * arr.length)
    /* 將所獲取的數和第i個數互換位置 */
    var temp = arr[i]
    arr[i] = arr[j]
    arr[j] = temp
  }
  return arr
}

 

// 解法三
function getRandomArr(arr) {
  arr.sort(() => {
    return (0.5-Math.random())
  })
  return arr
}

 

4 綁定DOM事件

實現一個綁定DOM事件的js函數,可兼容多種瀏覽器web

4.1 方法一

<button id="mydiv">點擊觸發事件</button>
<script>
    /* 由於 JavaScript 中全部對象都集成與 Object,那麼只有給Object原型添加一個事件綁定函數,
     就不須要在處理綁定事件的時候,每次寫一長串代碼,直接調用便可。 */
    // ev 事件屬性
    // fn 觸發事件
    Object.prototype.addListener = function (ev, fn) {
        if (this.attachEvent) { // 兼容IE9 IE10 
            alert('a')
            this.attachEvent('on' + ev, fn)
        } else { // 兼容:firefox、chrome、IE、safari、opera
            alert('v')
            this.addEventListener(ev, fn, false)
        }
    }
    var mydiv = document.getElementById("mydiv")
    mydiv.addListener('click', click1, false)
    function click1() {
        alert("click1")
    }
</script>

 

4.2 方法二

function addEvent(ele, type, func) {
    if(ele.addEventListener()) {
        // Chrome
        ele.addEventListener(type, func)
    } else {
        // IE瀏覽器
        ele.attachEvent('on' + type, func)
    }
}

 

5 問題:減小頁面首次請求加載的方式有哪些

前端優化清單(一):之首屏優化面試

  1. 首屏最小化chrome

    首屏HTML儘可能小,控制DOM節點數、請求數、外鏈數數據庫

  2. 元素優化segmentfault

    優化落在首屏內的元素性能和結構,包括基礎頁、元素請求、圖片、JS、是否調用第三方內容、層次機構等。數組

  3. 頁面靜態化瀏覽器

    首屏頁包含了頁面基礎頁時間(第一次請求),以屏內的元素總的DNS解析時間,創建鏈接時間,SSL握手時間,發出請求時間,重定向時間,內容下載時間等。

  4. 基礎頁優化 以靜態頁面的形式存放,用戶相關數據依賴Ajax,好比登陸信息。用戶默認顯示未登陸狀態,異步獲取到用戶數據後更新。

  5. 首屏廣告優化 重點減小廣告JS的下載次數,減小狀態上報次數,避免iframe。同時處理腳本放在頁面底部,修改廣告的載入順序,避免影響頁面顯示。

  6. 首屏按需加載 隱藏tab頁,用了異步加載的方式,只有當用戶正在要看這塊內容的時候纔去拉取。

  7. 單獨合併素材 將代發佈的源文件進行壓縮合並,減小文件數量,受權請求最少原則。

  8. 統計代碼優化 針對用戶行爲統計代碼如(CNZZ,百度統計等),進行去除冗餘,統一放到首屏後加載。

 

6 如何避免出現XSS漏洞

  1. 輸入過濾。永遠不要相信用戶的輸入,對用戶輸入的數據作必定的過濾。如輸入的數據是否符合預期的格式,好比日期格式,Email格式,電話號碼格式等等。這樣能夠初步對XSS漏洞進行防護。上面的措施只在web端作了限制,攻擊者通抓包工具如Fiddler仍是能夠繞過前端輸入的限制,修改請求注入攻擊腳本。所以,後臺服務器須要在接收到用戶輸入的數據後,對特殊危險字符進行過濾或者轉義處理,而後再存儲到數據庫中。

  2. 輸出編碼。服務器端輸出到瀏覽器的數據,可使用系統的安全函數來進行編碼或轉義來防範XSS攻擊。在PHP中,有htmlentities()和htmlspecialchars()兩個函數能夠知足安全要求。相應的JavaScript的編碼方式可使用JavascriptEncode。

  3. 安全編碼。開發需儘可能避免Web客戶端文檔重寫、重定向或其餘敏感操做,同時要避免使用客戶端數據,這些操做需儘可能在服務器端使用動態頁面來實現。

  4. HttpOnly Cookie。預防XSS攻擊竊取用戶cookie最有效的防護手段。Web應用程序在設置cookie時,將其屬性設爲HttpOnly,就能夠避免該網頁的cookie被客戶端惡意JavaScript竊取,保護用戶cookie信息。

  5. WAF(Web Application Firewall),Web應用防火牆,主要的功能是防範諸如網頁木馬、XSS以及CSRF等常見的Web漏洞攻擊。由第三方公司開發,在企業環境中深受歡迎。

 

7 CSS 如何實現div上下左右居中

未佈局前的樣式:

    .fa {
      width: 300px;
      height: 300px;
      background-color: #f5f5f5;
    }
    .son {
      width: 100px;
      height: 100px;
      background-color: #979191;
    }

  <div class="fa">
    <div class="son"></div>
  </div>

7.1 標準流居中

/* 前提:已知父子div的寬高 */
.fa {
    overflow: hidden; /* BFC */
}
.son {
    margin: 100px auto;
}

7.3 定位 + margin

.fa {
    position: relative;
}
.son {
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -50px;
    margin-top: -50px;
}

7.4 flex

.fa {
    display: flex;
    justify-content: center;
    align-items: center;
}

7.5 grid

.fa {
    display: grid;
    grid-template-columns: 33.3% 33.3% 33.3%;
    grid-template-rows: 33.3% 33.3% 33.3%;
}
.son {
    /* 開始於第2條行網格線,結束於第3條行網格線 */
    grid-column: 2/3;
    /* 開始於第2條列網格線,結束於第3條列網格線 */
    grid-row: 2/3;
}

 

8 判斷二維空間中的一個點是否在線段上

    // 實現一個函數,判斷二維空間中的一個點是否在線段上
    // 思路:該點分別到這兩點的距離 是否等於 這倆點距離之和
    const pointA = { x: 1, y: 4 }
    const pointB = { x: 4, y: 1 }
    let onePoint = { x: 2, y: 3 }
    let otherPoint = { x: 3, y: 1 }
    function isInLine(pointA, pointB, target) {
      let distanceA = distance(pointA, target)
      let distanceB = distance(pointB, target)
      let distanceAB = distance(pointA, pointB)
      return distanceA + distanceB === distanceAB ? 'true': 'false'
    }

    function distance(first, second) {
      let num = Math.pow((first.x - second.x), 2) + Math.pow((first.y - second.y), 2)
      return Math.round(Math.sqrt(num))
    }
    console.log(isInLine(pointA, pointB, onePoint)) // 'true'
    console.log(isInLine(pointA, pointB, otherPoint)) // 'false'

 

9 樹形結構

當時面試官問我保存的str1存在那裏,如今才知道,存在原型

有一個樹形結構:

var data = {
  key1: 'str1',
  key2: {
    key3: 'str3',
    key4: 'str4',
    key5: {
      ket6: 'str6'
    }
  }
}

實現一個方法getKeys(data, str),獲取字符串 str 在 data 中全部的上級節點名稱,例如:

getKeys(data, 'str1') 返回 'key1'

getKeys(data, 'str3') 返回 'key2 key3'

getKeys(data, 'str6') 返回 'key2 key5 key6'

如下解法有問題,可是思路很好

解法一

var data = {
  key1: 'str1',
  key2: {
    key3: 'str3',
    key4: 'str4',
    key5: {
      key6: 'str6',
      key7: {
        key8: 'str8'
      }
    }
    // ...
  }
}

function getKeys(data, str) {
  for(let key in data) {
    if(typeof data[key] == 'string' && data[key] == str) {
      this.keyName ? this.keyName += key: this.keyName = key
      return this.keyName
    } else if(typeof data[key] == 'object') {
      // keyName += key
      // keyName += ' '
      this.keyName ? this.keyName += key: this.keyName = key
      this.keyName += ' '
      return getKeys(data[key], str)
    }
  }
}

getKeys.prototype.keyName = ''

console.info(getKeys(data, 'str8'))

 

解法二

function  getKeys(data,str){
  var result=[];
  function recursion(data,str){
      for(var key in data){
          if(data[key] == str){
              result.push(key);
              return result;
          }
          if(typeof data[key] == 'object'){
              result.push(key);
              return recursion(data[key],str)
          }
      }
  }
  recursion(data,str);
}

 

10.原型 和 類

實現一個類,語法能夠是es5 / es6 / es7

調用代碼能夠輸出:item1-1 item2-2 item3-3

調用代碼以下:

var priorityQueue = new PriorityQueue();
priorityQueue.add('item1', 1);
priorityQueue.add('item3', 3);
priorityQueue.add('item2', 2);
priorityQueue.print();
priorityQueue.clear();

 

 答案

相關文章
相關標籤/搜索