今日頭條面試題匯總


CSS

  • 解釋 css 各種定位,absolute 相對於誰定位;
    -> position: relative/absolute/fixed/static/inherit/initial/unset/sticky
    -> 相對於最近一層position非static的父元素
    -> relative不會脫離文檔流

  • iframe 中的 fixed 定位和什么有關,怎么固定瀏覽器窗口
    -> iframe窗口非瀏覽器窗口,通過postmessage通信將top頁面的scrolltop傳遞給iframe,iframe內部通過監聽通訊事件動態設置元素的定

  • transfrom 的主要用法
    -> transform用來向元素應用各種2D和3D轉換,該屬性允許我們對元素進行旋轉、縮放、移動或傾斜等操作,有translate, scale, rotate, skew,

  • flex 盒子布局
    flex 布局詳解

  • 不同高的子盒子實現頭部對齊

// 1. padding 補償
.parent {
    width: 100%;
    overflow: hidden;
}
.left, right {
    float: left;
    padding-bottom:9999px;
    margin-bottom:-9999px;
}
// 2. flex 布局
.parent{
    display: flex;
}
  • css 盒模型;
    -> 標准盒子模型:寬度=內容的寬度(content)+ border + padding + margin -> box-sizing:content-box;
    -> 低版本IE盒子模型:寬度=內容寬度(content+border+padding)+ margin -> box-sizing:border-box;;

  • 重繪和回流的區別
    -> 重繪(repaint):當render tree中的一些元素需要更新屬性,單這些屬性只會影響元素的外觀,風格,而不會影響到元素的布局,此類的頁面渲染叫作頁面重繪。
    -> 回流(reflow):當render tree中的一部分(或全部)因為元素的規模尺寸,布局,隱藏等改變而引起的頁面重新渲染。
    -> 回流必將引起重繪,而重繪不一定會引起回流

  • 如何解決外邊距重合問題;
    -> 外邊距重疊是指兩個或多個盒子(可能相鄰也可能嵌套)的相鄰邊界(其間沒有任何非空內容、補白、邊框)重合在一起而形成一個單一邊界
    外層元素添加padding;
    外層元素 overflow:hidden;
    外層元素透明邊框 border:1px solid transparent;
    內層元素絕對定位 postion:absolute;
    內層元素 加float:left;或display:inline-block;

  • 清除浮動
    1、父級div定義 overflow: auto;;
    2、.clearfix

  • 兩列布局(右側定寬200px,左邊隨屏幕自動填充寬度)

// 1. float+margin(一側定寬,一側自動)  
// 2. position+margin(一側定寬,一側自動)
// 3. float+負margin(一側定寬,一側自動)
.right { 
    float:left; 
    width: 100%;
}
.right .cont {
    margin-left:200px;
}
.left {
    float: left; 
    width: 200px; 
    margin-left: -100%; 
}
  • 三列布局
// 1. float+margin(兩側定寬,中間自適應)
// 2. position+margin(兩側定寬,中間自適應)
// 3. float+負margin(兩側定寬,中間自適應)
.m-box { 
    float:left; 
    width: 100%;
}
.m-box .center {
    margin:0 200px;
}
.left,.right {
    float: left; 
    width: 200px; 
    margin-left: -100%;
}
.right {
    margin-left: -200px;
}
  • 垂直水平居中
// 1、絕對定位+margin:auto  
.box {
    margin: auto;
    position: absolute;
    left: 0; right: 0; top: 0; bottom: 0;
}

// 2、絕對定位+transform反向偏移

.box {
    margin: auto;
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
}

// 3、display: flex-box

.box {
    display: flex;
    align-items: center;
    justify-content: center;
}
  • css 實現4:3的塊元素
.box {
    width: 100%;
    height: 0;
    padding-top: 75%;
}
  • css寫個無限旋轉動畫
.ig{
    -webkit-animation:circle 1.5s infinite linear;
}
@-webkit-keyframes circle{
    0%{ transform:rotate(0deg); }
    100%{ transform:rotate(360deg); }
}
  • 用css畫一個三角形
.triangle{
    width: 0; height:0;
    border: 10px solid transparent;
    border-top-color: red;
}

簡答題

  • 自我介紹,項目介紹,項目中的難點以及解決方案;
  • 項目中遇到的技術問題
  • 最近在學什么東西
  • MVC/MVVM 的理解
  • 問了h5語義化的問題
  • 為什么用來React又用jquery
  • Reat寫組件有挑戰性的東西
  • 關鍵詞標記顏色
  • amd 和 cmd 規范理解;
  • es6相比es5有沒有什么比較好的特性
  • 箭頭函數和一般函數的區別
  • promise了解不
  • JS的數據類型
    -> number,boolean,string,undefined,null,object,symbol。
  • 發http請求會怎么做
  • 常見的狀態碼
  • http緩存怎么做到的
  • 瀏覽器緩存常見的http的頭 requestHeader
  • 性能優化的事情
  • 打包工具 Webpack 的配置,原理,webpack優化;
    -> 解析webpack配置參數,合並從shell傳入和webpack.config.js文件里配置的參數,生產最后的配置結果。
    -> 注冊所有配置的插件,好讓插件監聽webpack構建生命周期的事件節點,以做出對應的反應。
    -> 從配置的entry入口文件開始解析文件構建AST語法樹,找出每個文件所依賴的文件,遞歸下去。
    -> 在解析文件遞歸的過程中根據文件類型和loader配置找出合適的loader用來對文件進行轉換。
    -> 遞歸完后得到每個文件的最終結果,根據entry配置生成代碼塊chunk。
    -> 輸出所有chunk到文件系統。
  • nodeJS
  • 講講同源策略
  • url構成,解析一個url,包括hash值;
  • post和get的區別
  • 事件代理是什么事件代理中target和event細節
  • 原型鏈繼承對象、構造函數、prototype、_proto
  • http1.0 ,1.1,2.0的區別;
  • Object.defineProperty()的缺點;
  • post content-type類型
  • 然后問了冒泡,捕獲;
  • 手寫一個閉包;
  • 考察數組判定、
  • 一道異步代碼題,說出打印順序;
  • 三個url同時請求,要求按順序打印結果
  • http緩存優缺點
  • 單頁應用優缺點
  • 瀏覽器緩存優缺點
  • addEventListener()有幾個參數,是什么?
  • typeof的類型(舉例說屬於什么類型)
  • 問針對移動瀏覽器端開發頁面,不期望用戶放大屏幕,且要求“視口(viewport)”寬度等於屏幕寬度,視口高度等於設備高度,如何設置?
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, 
        maximum-scale=1, user-scalable=no">
  • == 與 === 的區別;
  • cookie是什么,怎么存儲。
  • cookie和session的區別;
  • 問請描述一下cookies,sessionStorage和localStorage的區別?
    答:cookie:一般由服務器生成,可設置失效時間。如果在瀏覽器端生成Cookie,默認是關閉瀏覽器后失效,也可設置過期時間,每次都會攜帶在HTTP頭中,如果使用cookie保存過多數據會帶來性能問題 sessionStorage: 僅在當前會話下有效,關閉頁面或瀏覽器后被清除 localStorage: 除非被清除,否則永久保存,僅在客戶端(即瀏覽器)中保存,不參與和服務器的通信
  • 介紹H5的兩個瀏覽器緩存,localStorage和sessionStorage的區別。
    保存數據的生命周期不同。 sessionStorage只是可以將一部分數據在當前會話中保存下來,刷新頁面數據依舊存在。但當頁面關閉后,sessionStorage 中的數據就會被清空
  • fetch和ajax的區別。
    1、fetch()返回的promise將不會拒絕http的錯誤狀態,即使響應是一個HTTP 404或者500。 服務器端返回 狀態碼 400 500的時候 不會reject Response.ok 屬性為 true。
    2、在默認情況下 fetch不會接受或者發送cookies ,要發送 cookies,必須設置 credentials 選項。 credentials: 'include'
  • Bom是什么,列舉你知道的Bom對象;
  • function.prototype.bind/call/apply的用法及區別
  • 問什么是瀏覽器的標准模式和怪異模式
    答:目前瀏覽器的排版引擎有三種模式:怪異模式(Quirks mode)、接近標准模式(Almost standards mode)、以及標准模式(Standards mode)。在怪異模式下,排版會模擬 Navigator 4 與 Internet Explorer 5 的非標准行為。為了支持在網絡標准被廣泛采用前,就已經建好的網站,這么做是必要的。在標准模式下,行為即(但願如此)由 HTML 與 CSS 的規范描述的行為。在接近標准模式下,只有少數的怪異行為被實現。 那么所謂標准模式,就一定都“標准”嗎?答案當然是否定的,因為各個瀏覽器廠商實現標准的階段不同,所以各個瀏覽器的“標准模式”之間也會有很大的不同。 Firefox、Safari、Chrome、Opera (自 7.5 以后)、 IE8 和 IE9 都有一個准標准模式。那么既然標准模式都不那么標准,准標准的模式肯定就更不標准了。
  • 問解釋一下盒模型寬高值的計算方式,邊界塌陷,負值作用,box-sizing概念
    答:盒模型 a. ie678怪異模式(不添加 doctype)使用 ie 盒模型,寬度=邊框+padding+內容寬度 b. chrome, ie9+, ie678(添加 doctype) 使用標准盒模型,寬度= 內容寬度 box-sizing content-box(默認) 布局所占寬度Width: Width = width + padding-left + padding-right + border-left + border-right 布局所占高度Height: Height = height + padding-top + padding-bottom + border-top + border-bottom border-box 布局所占寬度Width: Width = width(包含padding-left + padding-right + border-left + border-right) 布局所占高度Height: Height = height(包含padding-top + padding-bottom + border-top + border-bottom) 邊界塌陷 同一BFC下,相鄰快級元素邊界取最大值 負值作用 display:inline-block是什么呢?相信大家對這個屬性並不陌生,根據名字inline-block我們就可以大概猜出它是結合了inline和block兩者的特性於一身,簡單的說:設置了inline-block屬性的元素既擁有了block元素可以設置width和height的特性,又保持了inline元素不換行的特性。
  • window.onload和document.onload是否是同時執行,為什么;
  • JS中prototype、proto、super分別是什么?
    答: 這個我一臉懵逼,只說了prototype是原型,_proto_是隱式原型。
  • arguments是數組嗎?怎么實現用它調用數組方法?類數組和數組的區別是什么?arguments有length屬性嗎? 為什么要遍歷類數組取值組成數組,還有更簡單的方法嗎?
  • for…in 和for...of的區別
    答:for of 遍歷的是值,for in 遍歷的是索引。
  • 數組中的幾個替換/遍歷方法
  • 如何理解跨域;
  • 跨域你是怎么解決的,jsonp有什么缺點
    -> 瀏覽器的同源策略導致了跨域,用於隔離潛在惡意文件的重要安全機制
    -> [jsonp ,允許 script加載第三方資源]https://segmentfault.com/a/1190000008445998
    -> nginx 代理轉發(nginx 服務內部配置 rewrite proxy_pass)
    -> cors 前后端協作設置請求頭部,Access-Control-Allow-Origin 等頭部信息
    -> iframe 嵌套通訊,postmessage
  • cors請求和普通的http請求有什么區別
  • 問data-xxx 屬性的作用是什么?
    答:data- 屬性賦予我們在所有 HTML 元素上嵌入自定義 data 屬性的能力。 存儲的(自定義)數據能夠被頁面的 JavaScript 中利用,以創建更好的用戶體驗
  • promise、setTimeout、async/await的執行順序。
  • 用過NodeJS的EventEmitter模塊嗎,它是怎么實現功能的,步驟是什么;
  • events模塊只提供了一個對象:events.EventEmitter。EventEmitter的核心就是事件觸發和事件監聽器功能封裝。
  • 同源不同標簽之間的通信
  • 同源標簽之間如何通信;
  • hybrid 實現原理
    Hybrid App技術解析 -- 原理篇
  • hybrid 通信方式
    -> JSBridge
    Android的WebView中有一個WebChromeClient類,這個類其實就是用來監聽一些WebView中的事件的,我們發現其中有三個對應於js中的alert(警告框),comfirm(確認框)和prompt(提示框)方法,通過重寫WebView中WebChromeClient類的onJsPrompt()方法來進行js和java的通信。
    (1) 在js腳本中把對應的方法名,參數等寫成一個符合協議的uri,並且通過window.prompt方法發送給java層。
    (2) 在java層的onJsPrompt方法中接受到對應的message之后,通過JsCallJava類進行具體的解析。
    (3) 在JsCallJava類中,我們解析得到對應的方法名,參數等信息,並且在map中查找出對應的類的方法。

React

  • React16 有沒有使用過
  • react 怎樣提高性能;
    答:shouldComponentUpdate: react的每次render都是帶動整個項目一起render的,渲染性能消耗很大很大。要用shouldComponentUpdate更新生命周期函數優化。 當該函數默認返回true的時候,一旦prop或者state有任何變化,都會引起重新render。 shouldComponentUpdate(object nextProps, object nextState) : -boolean 當組件決定任何改變是否要更新到DOM時被調用。作為一個 優化 實現比較this.props 和 nextProps 、this.state 和 nextState ,如果React應該跳過更新,返回false。 當props、state發生變化時,React會根據shouldComponentUpdate方法來決定是否渲染整個組件。
  • React 的virtual dom 的了解和jquery的直接操作節點的渲染方式相比的優點;
  • React 的生命周期
  • componentWillReceiveProps componentShouldUpdate 區別
  • componentShouldUpdate 會做setState操作嗎
  • React之間組件通信的方式,兩個兄弟組件之間的通信方式
  • mobx和redux有沒有了解過
  • redux基本組成和設計
  • 介紹堆棧和隊列,如何用堆棧實現隊列

VUE

  • VUE的原理setter和getter相關知識
  • vue項目需要注意什么,可以優化的地方;
  • vue的computed實現原理;
  • vue-router的原理;

es6 面試題匯總

es6 面試題匯總

編程題

  • 快速排序
// 時間復雜度(nlogn), 空間復雜度O(n)
var quickSort = function(arr) {
    if(arr.length<=1) return arr;
    var left = [], right = [], point = Math.floor(arr.length/2);
    var middle = arr.splice(point, 1)[0];
    for(var i = 0; i < arr.length; i++){
        arr[i] < middle ? left.push(arr[i]) : right.push(arr[i]) ;
    }
    return quickSort(left).concat([middle], quickSort(right));
}
  • 數組去重
a.forEach(function(value, index){
  b.indexOf(value) === -1 && b.push(value);
})

a.map(function(value, index){
  b.indexOf(value) === -1 && b.push(value);
})

var c;
c = a.filter(function(value, index, array){
  return index === array.indexOf(value);
})

function unique(arr) {
  var ret = [];
  var tmp = {};
  
  for(var i = 0, len = arr.length; i < len; i++){
    if(!tmp[typeof arr[i] + arr[i]]) {
      tmp[typeof arr[i] + arr[i]] = true;
      ret.push(arr[i]);
    }
  }
  
  return ret;
}
  • 將多維數組平鋪;
1、 var myNewArray = [].concat.apply([], myArray);
2、 var myNewArray4 = [].concat(...myArray);
3、 var myNewArray = myArray.reduce(function(prev, curr) {
        return prev.concat(curr);
    });
  • 手寫簡易 EventEmiter
// 參照 vue 源碼實現
var EventEmiter = function (){
  this._events = {};
};
EventEmiter.prototype.on = function (event, cb){
  if (Array.isArray(event)){
    for (let i = 0, l = event.length; i < l; i++){
      this.on(event[i], cb);
    }
  } else {
    (this._events[event] || (this._events[event] = [])).push(cb);
  }
  return this;
};
EventEmiter.prototype.once = function (event, cb){
  function on () {
    this.off(event, cb);
    cb.apply(this, arguments);
  }
  on.fn = cb;
  this.on(event, on);
  return this;
};
EventEmiter.prototype.off = function (event, cb){
  if (!arguments.length){
    this._events = Object.create(null);
    return this;
  }
  if (Array.isArray(event)){
    for (let i = 0, l = event.length; i < l; i++){
      this.off(event[i],cb);
    }
    return this;
  }
  if (!cb){
    this._events[event] = null;
    return this;
  }
  if (cb){
    let cbs = this._events[event];
    let i = cbs.length;
    while(i--){
      if (cb === cbs[i] || cb === cbs[i].fn){
        cbs.splice(i, 1);
        break;
      }
    }
    return this;
  }
};
EventEmiter.prototype.emit = function (event){
  let cbs = this._events[event];
  let args = Array.prototype.slice.call(arguments, 1);
  if (cbs){
    for (let i = 0, l = cbs.length; i < l; i++){
      cbs[i].apply(this,args);
    }
  }
};
  • 寫一個url解析函數,解析出查詢參數;
function parseUrl(url){
    var result = [];
    var query = url.split("?")[1];
    var queryArr = query.split("&");
    queryArr.forEach(function(item){
        var obj = {};
        var value = item.split("=")[1];
        var key = item.split("=")[0];
        obj[key] = value;
        result.push(obj);
    });
    return result;
}
  • ['1.45.0','1.5','6','3.3.3.3']要求從小到大排序,注意'1.45'比'1.5'大;
// 使用的是選擇排序
const versionSort = version => {
  const temp = version.map(v => v.split('.'));
  for (let i = 0; i < temp.length; i++) {
    let minIndex = i;
    for (let j = i; j < temp.length; j++) {
      for (let k = 0; k < temp[j].length; k++) {
        const current = +temp[j][k],
        min = +temp[minIndex][k];
        if (current < min) {
          minIndex = j;
        }
        // 只要不等,就立刻結束最內層遍歷!
        if (current !== min) {
          break
        }
      }
    }
    [temp[i], temp[minIndex]] = [temp[minIndex], temp[i]];
  }
  return temp.map(v = > v.join('.'))
};
  • 隨意給定一個無序的、不重復的數組arr,任意抽取n個數,相加和為sum,也可能無解,請寫出該函數。

  • 節流函數怎么寫;

function debounce(fn, interval, immediate) {
    let timer;

    return function() {
        const context = this;
        const args = arguments;
        
        timer && clearTimeout(timer);

        if(immediate) {
            var callNow = !timer;
            timer = setTimeout(function() {
                timer = null;
            }, interval);
            callNow && fn.apply(context, args);
        } else {
            timer = setTimeout(function() {
                fn.apply(context, args);
            }, interval);
        }
    }
}
  • 手寫bind函數;
Function.prototype.bind = function(ctx) {
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);

    var F = function() {};

    var fBind = function() {
        var argsBind = Array.prototype.slice.call(arguments);
        return self.apply(this instanceof F ? this : ctx, args.concat(argsBind));
    }

    F.prototype = this.prototype;
    fBind.prototype = new F();

    return fBind;
}
function parseInt(s, radix = 10) {
    if (typeof s !== 'string') {
        return NaN;
    }
    if (typeof radix !== 'number' || radix < 2 || radix > 36) {
        return NaN;
    }
    let result = 0;
    for (let i = 0; i < s.length; i += 1) {
        let c = s.charCodeAt(i);
        // 小寫大寫字母轉換為數字
        if (c >= 97) {
            c -= 87;    // - 'a' + 10
        } else if (c >= 65) {
            c -= 55;    // - 'A' + 10
        } else {
            c -= 48;    // - '0'
        }
        // 如果字母轉化后的值大於進制數,則跳出循環返回之前的結果
        if (c >= radix) {
            if (i === 0) {
                return NaN;
            }
            break;
        }
        // 結果累加,和進制相關
        result = (result * radix) + c;
    }

    return result;
}
  • 正則表達式實現1000000中間加',';
function comma(num) {
    var source = String(num).split(".");
        source[0] = source[0].replace(new RegExp('(\\d)(?=(\\d{3})+$)','ig'),"$1,"); 
    return source.join(".");
}
  • 請使用數組的reduce方法實現數組的map方法;

  • 大數相加

function sumStrings(a,b) {  
    while(a.length < b.length){  
        a = "0" + a;  
    }  
    while(b.length < a.length){  
        b = "0" + b;  
    }  
    var addOne = 0;  
    var result = [];  
    for(var i=a.length-1;i>=0;i--){  
        var c1 = a.charAt(i) - 0;  
        var c2 = b.charAt(i) - 0;  
        var sum = c1 + c2 + addOne;  
        if(sum > 9){  
            result.unshift(sum - 10);  
            addOne = 1;  
        }  
        else{  
            result.unshift(sum);  
            addOne = 0;  
        }  
    }  
    if(addOne){  
        result.unshift(addOne);  
    }  
    if(!result[0]){  
        result.splice(0,1);  
    }  
    return result.join("");  
}  
  • 請用至少兩種方法判斷一個對象是否是數組,如何將非數組轉化為數組
a instanceof Array;
a.constructor === Array;
a.__proto__ === Array.prototype;
Array.prototype.isPrototypeOf(a);  // isProtoTypeOf()
Object.getPrototypeOf(a) === Array.prototype;  // Object.getPrototypeOf()
Object.prototype.toString.call(a) === '[object Array]'; // 首推 -> 前幾種繼承會擾亂, iframe 下 instance 失效
Array.isArray() // polyfill 就是調用字符串判斷法
var argsArray = Array.prototype.slice.call(arguments);

安全

  • xss和csrf攻擊;
    -> xss 跨站腳本攻擊,主要是前端層面的,用戶在輸入層面插入攻擊腳本,改變頁面的顯示,或則竊取網站 cookie,預防方法:不相信用戶的所有操作,對用戶輸入進行一個轉義,不允許 js 對 cookie 的讀寫
    -> csrf 跨站請求偽造,以你的名義,發送惡意請求,通過 cookie 加參數等形式過濾
    我們沒法徹底杜絕攻擊,只能提高攻擊門檻

  • cookie的有哪些安全的設置;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM