前端面試全部

1. 萬(wàn)能居中

1.margin: 0 auto;水平
2.text-align: center;水平
3.行高锐朴,垂直
4.表格赡矢,center,middle城侧;水平垂直
5.display:table-cell;模擬表格芜赌,all
6.絕對(duì)定位,50%減自身寬高
7.絕對(duì)定位冒冬,上下左右全0伸蚯,margin:auto
8.絕對(duì)定位加相對(duì)定位。不需要知道寬高
9.IE6简烤,IE7:給父元素設(shè)一個(gè)font-size:高度/1.14,vertical-align:middle

2. BFC優(yōu)化

塊格式化上下文, 特性:

  • 使 BFC 內(nèi)部浮動(dòng)元素不會(huì)到處亂跑剂邮;

  • 和浮動(dòng)元素產(chǎn)生邊界。

3. 盒模型哪兩種模式横侦?什么區(qū)別挥萌?如何設(shè)置

  • 標(biāo)準(zhǔn)模式: box-sizing: content-box; 寬高不包括內(nèi)邊距和邊框

  • 怪異模式: box-sizing: border-box

4. 常用清除浮動(dòng)的方法,如不清除浮動(dòng)會(huì)怎樣枉侧?

當(dāng)父元素不給高度的時(shí)候引瀑,內(nèi)部元素不浮動(dòng)時(shí)會(huì)撐開(kāi), 而浮動(dòng)的時(shí)候,父元素變成一條線, 造成塌陷.

  • 額外標(biāo)簽法(在最后一個(gè)浮動(dòng)標(biāo)簽后榨馁,新加一個(gè)標(biāo)簽憨栽,給其設(shè)置clear:both;)(不推薦)

  • 父元素添加overflow:hidden; (觸發(fā)BFC)

  • 使用after偽元素清除浮動(dòng)(推薦使用)

  • 使用before和after雙偽元素清除浮動(dòng)

5. 刪格化的原理

比如antd的row和col, 將一行等分為24份, col是幾就占幾份, 底層按百分比實(shí)現(xiàn); 結(jié)合媒體查詢, 可以實(shí)現(xiàn)響應(yīng)式

6. 純css實(shí)現(xiàn)三角形


.box {            
  width:0px;            
  height:0px;            
  border-top:50px solid rgba(0,0,0,0);            
  border-right:50px solid  rgba(0,0,0,0);            
  border-bottom:50px solid green;            
  border-left:50px solid  rgba(0,0,0,0);            
}

7. 高度不定翼虫,寬100%屑柔,內(nèi)一div高不確定,如何實(shí)現(xiàn)垂直居中珍剑?

  • verticle-align: middle;

  • 絕對(duì)定位50%加translateY(-50%)

  • 絕對(duì)定位掸宛,上下左右全0,margin:auto

8. 至少兩種方式實(shí)現(xiàn)自適應(yīng)搜索

  • rem, em

  • 百分比

  • 媒體查詢

  • bs, antd等的柵格布局

9. 設(shè)置一段文字的大小為6px

  • 谷歌最小12px, 其他瀏覽器可以更小

  • 通過(guò)transform: scale實(shí)現(xiàn)

10. css菊花圖

四個(gè)小圓點(diǎn)一直旋轉(zhuǎn)


animation: antRotate 1.2s infinite linear;

animation: antSpin 1s infinite linear;
@keyframe antSpin {  to {    opacity: 1   }}
@keyframe antRotate {  to {    transform: rotate(405)  }}

11. 關(guān)于em

 <div style="font-size: 20px">
      123
      <div style="font-size: 2em;width: 2em">456</div>
 </div>
// 此時(shí)子元素的font-size為40px, 寬度為80px(還要乘以子元素font-size的系數(shù))

12. 關(guān)于vh, vw

vw:viewpoint width招拙,視窗寬度唧瘾,1vw等于視窗寬度的1%。
vh:viewpoint height别凤,視窗高度劈愚,1vh等于視窗高度的1%。
vmin:vw和vh中較小的那個(gè)闻妓。
vmax:vw和vh中較大的那個(gè)菌羽。

13. Flex布局

  • flex-direction控制主副軸

  • flex-wrap控制換行(默認(rèn)不換行)

  • flex-flow是上兩個(gè)的結(jié)合

  • justify-content主軸對(duì)齊方式

  • align-items交叉軸對(duì)齊方式

14. overflow原理

  • overflow: hidden能清除塊內(nèi)子元素的浮動(dòng)影響. 因?yàn)樵搶傩赃M(jìn)行超出隱藏時(shí)需要計(jì)算盒子內(nèi)所有元素的高度, 所以會(huì)隱式清除浮動(dòng)

  • 創(chuàng)建BFC條件(滿足一個(gè)):

  • float的值不為none;

  • overflow的值不為visible由缆;

  • position的值為fixed / absolute注祖;

  • display的值為table-cell / table-caption / inline-block / flex / inline-flex。

15. 實(shí)現(xiàn)自適應(yīng)的正方形:

  • 使用vw, vh

  • width百分比, height: 0, padding-top(bottom): 50%

16. 標(biāo)準(zhǔn)模式和怪異模式

  • document.compatMode屬性可以判斷是否是標(biāo)準(zhǔn)模式均唉,當(dāng) document.compatMode為“CSS1Compat”是晨,是標(biāo)準(zhǔn)模式,“BackCompat”是怪異模式舔箭。

  • 怪異模式是為了兼容舊版本的瀏覽器, 因?yàn)镮E低版本document.documentElement.clientWidth獲取不到

  • 怪異模式盒模型: box-sizing: border-box; 標(biāo)準(zhǔn)模式: box-sizing: content-box

17. CSS3實(shí)現(xiàn)環(huán)形進(jìn)度條

兩個(gè)對(duì)半矩形遮罩, 使用rotate以及overflow: hidden進(jìn)行旋轉(zhuǎn)

18. css優(yōu)先級(jí)

選擇器的特殊性值表述為4個(gè)部分罩缴,用0,0,0,0表示蚊逢。

  • ID選擇器的特殊性值,加0,1,0,0箫章。

  • 類選擇器烙荷、屬性選擇器或偽類,加0,0,1,0檬寂。

  • 元素和偽元素终抽,加0,0,0,1。

  • 通配選擇器*對(duì)特殊性沒(méi)有貢獻(xiàn)桶至,即0,0,0,0昼伴。

  • 最后比較特殊的一個(gè)標(biāo)志!important(權(quán)重),它沒(méi)有特殊性值镣屹,但它的優(yōu)先級(jí)是最高的圃郊,為了方便記憶,可以認(rèn)為它的特殊性值為1,0,0,0,0女蜈。

1. ES5和ES6繼承方式區(qū)別

  • ES5定義類以函數(shù)形式, 以prototype來(lái)實(shí)現(xiàn)繼承

  • ES6以class形式定義類, 以extend形式繼承

2. Generator了解

ES6 提供的一種異步編程解決方案, Generator 函數(shù)是一個(gè)狀態(tài)機(jī)描沟,封裝了多個(gè)內(nèi)部狀態(tài)。

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator();

調(diào)用后返回指向內(nèi)部狀態(tài)的指針, 調(diào)用next()才會(huì)移向下一個(gè)狀態(tài), 參數(shù):

hw.next()
// { value: 'hello', done: false }

hw.next()
// { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

hw.next()
// { value: undefined, done: true }

3. 手寫(xiě)Promise實(shí)現(xiàn)

var myPromise = new Promise((resolve, reject) => {

  ...
  if () {
    resolve(value)
  } else if () {
    reject(error)
  }
})

myPromise.then((value) => {

}, (error) => {

})

4. Promise優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn): 解決回調(diào)地獄, 對(duì)異步任務(wù)寫(xiě)法更標(biāo)準(zhǔn)化與簡(jiǎn)潔化

  • 缺點(diǎn): 首先鞭光,無(wú)法取消Promise,一旦新建它就會(huì)立即執(zhí)行泞遗,無(wú)法中途取消; 其次惰许,如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯(cuò)誤史辙,不會(huì)反應(yīng)到外部; 第三汹买,當(dāng)處于pending狀態(tài)時(shí),無(wú)法得知目前進(jìn)展到哪一個(gè)階段(剛剛開(kāi)始還是即將完成).
    極簡(jiǎn)版promise封裝:

function promise () {
  this.msg = '' 
  this.status = 'pending'
  var that = this
  var process = arguments[0]

  process (function () {
    that.status = 'fulfilled'
    that.msg = arguments[0]
  }, function () {
    that.status = 'rejected'
    that.msg = arguments[0]
  })
  return this
}

promise.prototype.then = function () {
  if (this.status === 'fulfilled') {
    arguments[0](this.msg)
  } else if (this.status === 'rejected' && arguments[1]) {
    arguments[1](this.msg)
  }
}

5. 觀察者模式

又稱發(fā)布-訂閱模式, 舉例子說(shuō)明.
實(shí)現(xiàn): 發(fā)布者管理訂閱者隊(duì)列, 并有新消息推送功能. 訂閱者僅關(guān)注更新就行

6. 手寫(xiě)實(shí)現(xiàn)bind

Function.prototype.bind = function () {

  var self = this

  var context = Array.prototype.shift.call(arguments)

  var arg = Array.prototype.slice.call(arguments)

  return function () {

    self.apply(context, Array.prototype.concat.call(arg, Array.prototype.slice.call(arguments)))
  }
}

7. 手寫(xiě)實(shí)現(xiàn)4種繼承

function Father () {}
function Child () {}

Child.prototype = new Father()

function Child (name) {
  Father.call(this, name)
}

function Child (name) {
  Father.call(this, name)
}
Child.prototype = new Father()

function cloneObj (o) {
  var clone = object.create(o)
  clone.sayName = ...
  return clone
}

8. css菊花圖

四個(gè)小圓點(diǎn)一直旋轉(zhuǎn)


animation: antRotate 1.2s infinite linear;

animation: antSpin 1s infinite linear;
@keyframe antSpin {
  to {
    opacity: 1 
  }
}
@keyframe antRotate {
  to {
    transform: rotate(405)
  }
}

9. http狀態(tài)碼

  • 1**: 服務(wù)器收到請(qǐng)求, 需請(qǐng)求者進(jìn)一步操作

  • 2**: 請(qǐng)求成功

  • 3**: 重定向, 資源被轉(zhuǎn)移到其他URL了

  • 4**: 客戶端錯(cuò)誤, 請(qǐng)求語(yǔ)法錯(cuò)誤或沒(méi)有找到相應(yīng)資源

  • 5**: 服務(wù)端錯(cuò)誤, server error

  • 304: Not Modified. 指定日期后未修改, 不返回資源

10. Object.create實(shí)現(xiàn)(原型式繼承聊倔,特點(diǎn):實(shí)例的proto指向構(gòu)造函數(shù)本身)

11. async和await:

  • Generator函數(shù)的語(yǔ)法糖晦毙,將*改成async,將yield換成await耙蔑。

  • 是對(duì)Generator函數(shù)的改進(jìn), 返回promise见妒。

  • 異步寫(xiě)法同步化,遇到await先返回甸陌,執(zhí)行完異步再執(zhí)行接下來(lái)的.

  • 內(nèi)置執(zhí)行器, 無(wú)需next()

12. 算法和數(shù)據(jù)結(jié)構(gòu):

  • 算法:
    解決具體問(wèn)題所需要的解決方法须揣。執(zhí)行效率最快的最優(yōu)算法。時(shí)間復(fù)雜度钱豁。輸入耻卡,輸出,有窮性牲尺,確定性卵酪,可行性。冒泡排序,二叉樹(shù)遍歷溃卡,最長(zhǎng)回文溢豆,二分查找,指針塑煎,鏈表等沫换,堆棧,隊(duì)列等最铁。力扣讯赏,codewar,算法導(dǎo)論冷尉。

  • 數(shù)據(jù)結(jié)構(gòu):
    邏輯結(jié)構(gòu):集合漱挎、線性、樹(shù)形雀哨、圖形結(jié)構(gòu)
    物理結(jié)構(gòu):順序磕谅、鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)

13. 封裝JSONP

image

image

jsonp

function jsonp ({url, param, callback}) {
  return new Promise((resolve, reject) => {
    var script = document.createElement('script')
    window.callback = function (data) {
      resolve(data)
      document.body.removeChild('script')
    }
    var param = {...param, callback}
    var arr = []
    for (let key in param) {
      arr.push(`${key}=${param[key]}`)
    }
    script.src = `${url}?${arr.join('&')}`
    document.body.appendChild(script)
  })
}

14. 手動(dòng)實(shí)現(xiàn)map(forEach以及filter也類似)


Array.prototype.myMap = function () {
  var arr = this
  var [fn, thisValue] = Array.prototype.slice.call(arguments)
  var result = []
  for (var i = 0; i < arr.length; i++) {
    result.push(fn.call(thisValue, arr[i], i, arr))
  }
  return result
}
var arr0 = [1, 2, 3]
console.log(arr0.myMap(v => v + 1))

Array.prototype.myMap = function (fn, thisValue) {
  var result = []
  this.forEach((v, i, arr) => {
    result.push(fn.call(thisValue, v, i, arr))
  })
  return result
}
var arr0 = [1, 2, 3]
console.log(arr0.myMap(v => v + 1))

15. js實(shí)現(xiàn)checkbox全選以及反選

<body>
    <button id="other">反選</button>
    <input type="checkbox" id="all" />全選
    <input type="checkbox" class="check" />1
    <input type="checkbox" class="check" />2
    <input type="checkbox" class="check" />3
    <script>
      var checkbox = document.getElementsByClassName('check')
      var checkAll = document.getElementById('all')
      var checkOther = document.getElementById('other')
      checkAll.onclick = function() {
        var flag = true
        for (var i = 0; i < checkbox.length; i++) {
          if (!checkbox[i].checked) flag = false
        }
        if (flag) {
          for (var i = 0; i < checkbox.length; i++) {
            checkbox[i].checked = false
          }
        } else {
          for (var i = 0; i < checkbox.length; i++) {
            checkbox[i].checked = true
          }
        }
      }
      checkOther.onclick = function() {
        for (var i = 0; i < checkbox.length; i++) {
          checkbox[i].checked = !checkbox[i].checked
        }
      }
    </script>
  </body>

16. 對(duì)原型鏈的理解?prototype上都有哪些屬性

  • 在js里雾棺,繼承機(jī)制是原型繼承膊夹。繼承的起點(diǎn)是 對(duì)象的原型(Object prototype)。

  • 一切皆為對(duì)象捌浩,只要是對(duì)象放刨,就會(huì)有 proto 屬性,該屬性存儲(chǔ)了指向其構(gòu)造的指針尸饺。

  • Object prototype也是對(duì)象进统,其 proto 指向null。

  • 對(duì)象分為兩種:函數(shù)對(duì)象和普通對(duì)象浪听,只有函數(shù)對(duì)象擁有『原型』對(duì)象(prototype)螟碎。

  • prototype的本質(zhì)是普通對(duì)象。

  • Function prototype比較特殊迹栓,是沒(méi)有prototype的函數(shù)對(duì)象掉分。

  • new操作得到的對(duì)象是普通對(duì)象。

  • 當(dāng)調(diào)取一個(gè)對(duì)象的屬性時(shí)克伊,會(huì)先在本身查找叉抡,若無(wú),就根據(jù) proto 找到構(gòu)造原型答毫,若無(wú)褥民,繼續(xù)往上找。最后會(huì)到達(dá)頂層Object prototype洗搂,它的 proto 指向null消返,均無(wú)結(jié)果則返回undefined载弄,結(jié)束。

  • 由 proto 串起的路徑就是『原型鏈』撵颊。

  • 通過(guò)prototype可以給所有子類共享屬性

17. 為什么使用繼承

通常在一般的項(xiàng)目里不需要,因?yàn)閼?yīng)用簡(jiǎn)單,但你要用純js做一些復(fù)雜的工具或框架系統(tǒng)就要用到了,比如webgis宇攻、或者js框架如jquery、ext什么的,不然一個(gè)幾千行代碼的框架不用繼承得寫(xiě)幾萬(wàn)行,甚至還無(wú)法維護(hù)

18. setTimeout時(shí)間延遲為何不準(zhǔn)

單線程, 先執(zhí)行同步主線程, 再執(zhí)行異步任務(wù)隊(duì)列

19. 事件循環(huán)述倡勇,宏任務(wù)和微任務(wù)有什么區(qū)別逞刷?

  • 先主線程后異步任務(wù)隊(duì)列

  • 先微任務(wù)再宏任務(wù)

20. let const var作用域

塊級(jí)作用域, 暫時(shí)性死區(qū)

21. 節(jié)流和防抖

  • 函數(shù)節(jié)流是指一定時(shí)間內(nèi)js方法只跑一次。比如人的眨眼睛妻熊,就是一定時(shí)間內(nèi)眨一次夸浅。這是函數(shù)節(jié)流最形象的解釋。

var canRun = true;
document.getElementById("throttle").onscroll = function(){
    if(!canRun){

        return;
    }

    canRun = false;
    setTimeout(function(){
        console.log("函數(shù)節(jié)流");
        canRun = true;
    }, 300);
};

  • 函數(shù)防抖是指頻繁觸發(fā)的情況下扔役,只有足夠的空閑時(shí)間帆喇,才執(zhí)行代碼一次。比如生活中的坐公交亿胸,就是一定時(shí)間內(nèi)坯钦,如果有人陸續(xù)刷卡上車,司機(jī)就不會(huì)開(kāi)車侈玄。只有別人沒(méi)刷卡了婉刀,司機(jī)才開(kāi)車。

var timer = false;
document.getElementById("debounce").onscroll = function(){
    clearTimeout(timer); 

    timer = setTimeout(function(){
        console.log("函數(shù)防抖");
    }, 300);
};  

22. 實(shí)現(xiàn)一個(gè)sleep函數(shù)


function sleep(delay) {
  var start = (new Date()).getTime();
  while ((new Date()).getTime() - start < delay) {
    continue;
  }
}

function test() {
  console.log('111');
  sleep(2000);
  console.log('222');
}

test()

23. 閉包

  • 概念: 內(nèi)層函數(shù)能夠訪問(wèn)外層函數(shù)作用域的變量

  • 缺點(diǎn): 引起內(nèi)存泄漏(釋放內(nèi)存)

  • 作用:

  • 使用閉包修正打印值

  • 實(shí)現(xiàn)柯里化

  • 實(shí)現(xiàn)node commonJs 模塊化, 實(shí)現(xiàn)私有變量

  • 保持變量與函數(shù)活性, 可延遲回收和執(zhí)行

24. Immutable.js

Facebook出品, 倡導(dǎo)數(shù)據(jù)的不可變性, 用的最多就是List和Map.

25. js實(shí)現(xiàn)instanceof


function myInstanceof (l, r) {
  var R = r.prototype
  while (l.__proto__) {
    if (l.__proto__ === R) return true
  }
  return false
}

27. ES6的模塊引入和CommonJs區(qū)別

28. 嚴(yán)格模式


      'use strict'
      var a = 2
      var obj = {
        a: 1,
        b: function() {

          console.log(this)
        }
      }
      var c = obj.b
      c() 

29. fetch, axios區(qū)別

30. typescript缺點(diǎn)

  • 并不是嚴(yán)格意義的js的超集, 與js不完全兼容, 會(huì)報(bào)錯(cuò)

  • 更多的限制, 是一種桎梏

  • 有些js第三方庫(kù)沒(méi)有dts, 有問(wèn)題

31. 構(gòu)造函數(shù)實(shí)現(xiàn)原理

  • 構(gòu)造函數(shù)中沒(méi)有顯示的創(chuàng)建Object對(duì)象, 實(shí)際上后臺(tái)自動(dòng)創(chuàng)建了

  • 直接給this對(duì)象賦值屬性和方法, this即指向創(chuàng)建的對(duì)象

  • 沒(méi)有return返回值, 后臺(tái)自動(dòng)返回了該對(duì)象


var Book = function(name) {
          this.name = name;
        };

        var java = new Book(‘Master Java’);

        var python = {};
        python.__proto__ = Book.prototype;
        Book.call(python, 'Master Python');

32. for in 和 for of區(qū)別

  • for in遍歷數(shù)組會(huì)遍歷到數(shù)組原型上的屬性和方法, 更適合遍歷對(duì)象

  • forEach不支持break, continue, return

  • 使用for of可以成功遍歷數(shù)組的值, 而不是索引, 不會(huì)遍歷原型

  • for in 可以遍歷到myObject的原型方法method,如果不想遍歷原型方法和屬性的話序仙,可以在循環(huán)內(nèi)部判斷一下,hasOwnPropery方法可以判斷某屬性是否是該對(duì)象的實(shí)例屬性

33. JS實(shí)現(xiàn)并發(fā)控制:

使用消息隊(duì)列以及setIntervalpromise進(jìn)行入隊(duì)和出隊(duì)

34. ajax和axios突颊、fetch的區(qū)別

35. promise.finally實(shí)現(xiàn)

Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value  => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
  );
};

1. reflow(回流)和repaint(重繪)優(yōu)化

render

  • 瀏覽器渲染過(guò)程: DOM tree, CSS tree --> Render tree --> Paint

  • DOM tree根節(jié)點(diǎn)為html

  • 渲染從瀏覽器左上角到右下角

  • 第一次打開(kāi)頁(yè)面至少觸發(fā)一次重繪和回流, 結(jié)構(gòu)如寬高位置變化時(shí), 觸發(fā)reflow回流;非結(jié)構(gòu)如背景色變化時(shí), 觸發(fā)repaint重繪. 二者都會(huì)造成體驗(yàn)不佳

  • 如何減少重繪和回流?

  • 通過(guò)classname或cssText一次性修改樣式, 而非一個(gè)一個(gè)改

  • 離線模式: 克隆要操作的結(jié)點(diǎn), 操作后再與原始結(jié)點(diǎn)交換, 類似于虛擬DOM

  • 避免頻繁直接訪問(wèn)計(jì)算后的樣式, 而是先將信息保存下來(lái)

  • 絕對(duì)布局的DOM, 不會(huì)造成大量reflow

  • div不要嵌套太深, 不要超過(guò)六層

2.一個(gè)頁(yè)面從輸入 URL 到頁(yè)面加載顯示完成,這個(gè)過(guò)程中都發(fā)生了什么诱桂?

  • 瀏覽器根據(jù)請(qǐng)求的URL交給DNS域名解析,找到真實(shí)IP呈昔,向服務(wù)器發(fā)起請(qǐng)求挥等;

  • 服務(wù)器交給后臺(tái)處理完成后返回?cái)?shù)據(jù),瀏覽器接收文件(HTML堤尾、JS肝劲、CSS、圖象等)郭宝;

  • 瀏覽器對(duì)加載到的資源(HTML辞槐、JS、CSS等)進(jìn)行語(yǔ)法解析粘室,建立相應(yīng)的內(nèi)部數(shù)據(jù)結(jié)構(gòu)(如HTML的DOM Tree)榄檬;

  • 載入解析到的資源文件,渲染頁(yè)面衔统,完成鹿榜。

3.localStorage 與 sessionStorage 與cookie的區(qū)別總結(jié)

  • 共同點(diǎn): 都保存在瀏覽器端, 且同源

  • localStorage 與 sessionStorage 統(tǒng)稱webStorage,保存在瀏覽器,不參與服務(wù)器通信,大小為5M

  • 生命周期不同: localStorage永久保存, sessionStorage當(dāng)前會(huì)話, 都可手動(dòng)清除

  • 作用域不同: 不同瀏覽器不共享local和session, 不同會(huì)話不共享session

  • Cookie: 設(shè)置的過(guò)期時(shí)間前一直有效, 大小4K.有個(gè)數(shù)限制, 各瀏覽器不同, 一般為20個(gè).攜帶在HTTP頭中, 過(guò)多會(huì)有性能問(wèn)題.可自己封裝, 也可用原生

4.瀏覽器如何阻止事件傳播海雪,阻止默認(rèn)行為

  • 阻止事件傳播(冒泡): e.stopPropagation()

  • 阻止默認(rèn)行為: e.preventDefault()

5.虛擬DOM方案相對(duì)原生DOM操作有什么優(yōu)點(diǎn),實(shí)現(xiàn)上是什么原理舱殿?

虛擬DOM可提升性能, 無(wú)須整體重新渲染, 而是局部刷新.
JS對(duì)象, diff算法

6.瀏覽器事件機(jī)制中事件觸發(fā)三個(gè)階段

  • 事件捕獲階段: 從dom樹(shù)節(jié)點(diǎn)往下找到目標(biāo)節(jié)點(diǎn), 不會(huì)觸發(fā)函數(shù)

  • 事件目標(biāo)處理函數(shù): 到達(dá)目標(biāo)節(jié)點(diǎn)

  • 事件冒泡: 最后從目標(biāo)節(jié)點(diǎn)往頂層元素傳遞, 通常函數(shù)在此階段執(zhí)行.
    addEventListener第三個(gè)參數(shù)默認(rèn)false(冒泡階段執(zhí)行),true(捕獲階段執(zhí)行).
    阻止冒泡見(jiàn)以上方法

7.什么是跨域奥裸?為什么瀏覽器要使用同源策略?你有幾種方式可以解決跨域問(wèn)題沪袭?了解預(yù)檢請(qǐng)求嘛湾宙?

  • 跨域是指一個(gè)域下的文檔或腳本試圖去請(qǐng)求另一個(gè)域下的資源

  • 防止XSS、CSFR等攻擊, 協(xié)議+域名+端口不同

  • jsonp; 跨域資源共享(CORS)(Access control); 服務(wù)器正向代理等

    jsonp封裝

  • 預(yù)檢請(qǐng)求: 需預(yù)檢的請(qǐng)求要求必須首先使用 OPTIONS 方法發(fā)起一個(gè)預(yù)檢請(qǐng)求到服務(wù)器冈绊,以獲知服務(wù)器是否允許該實(shí)際請(qǐng)求侠鳄。"預(yù)檢請(qǐng)求“的使用,可以避免跨域請(qǐng)求對(duì)服務(wù)器的用戶數(shù)據(jù)產(chǎn)生未預(yù)期的影響

8.了解瀏覽器緩存機(jī)制嗎焚碌?

  • 瀏覽器緩存就是把一個(gè)已經(jīng)請(qǐng)求過(guò)的資源拷貝一份存儲(chǔ)起來(lái)畦攘,當(dāng)下次需要該資源時(shí),瀏覽器會(huì)根據(jù)緩存機(jī)制決定直接使用緩存資源還是再次向服務(wù)器發(fā)送請(qǐng)求.

  • from memory cache ; from disk cache

  • 作用: 減少網(wǎng)絡(luò)傳輸?shù)膿p耗以及降低服務(wù)器壓力十电。

  • 優(yōu)先級(jí): 強(qiáng)制緩存 > 協(xié)商緩存; cache-control > Expires > Etag > Last-modified

9.為什么操作 DOM 慢?

DOM本身是一個(gè)js對(duì)象, 操作這個(gè)對(duì)象本身不慢, 但是操作后觸發(fā)了瀏覽器的行為, 如repaint和reflow等瀏覽器行為, 使其變慢

10.什么情況會(huì)阻塞渲染知押?

  • js腳本同步執(zhí)行

  • css和圖片雖然是異步加載, 但js文件執(zhí)行需依賴css, 所以css也會(huì)阻塞渲染

11.如何判斷js運(yùn)行在瀏覽器中還是node中?

判斷有無(wú)全局對(duì)象global和window

12.關(guān)于web以及瀏覽器處理預(yù)加載有哪些思考鹃骂?

圖片等靜態(tài)資源在使用之前就提前請(qǐng)求
資源使用到的時(shí)候能從緩存中加載, 提升用戶體驗(yàn)
頁(yè)面展示的依賴關(guān)系維護(hù)

13.http多路復(fù)用

  • Keep-Alive: Keep-Alive解決的核心問(wèn)題:一定時(shí)間內(nèi)台盯,同一域名多次請(qǐng)求數(shù)據(jù),只建立一次HTTP請(qǐng)求畏线,其他請(qǐng)求可復(fù)用每一次建立的連接通道静盅,以達(dá)到提高請(qǐng)求效率的問(wèn)題。這里面所說(shuō)的一定時(shí)間是可以配置的寝殴,不管你用的是Apache還是nginx蒿叠。

  • 解決兩個(gè)問(wèn)題: 串行文件傳輸(采用二進(jìn)制數(shù)據(jù)幀); 連接數(shù)過(guò)多(采用流, 并行傳輸)

14. http和https:

  • http: 最廣泛網(wǎng)絡(luò)協(xié)議,BS模型蚣常,瀏覽器高效市咽。

  • https: 安全版,通過(guò)SSL加密抵蚊,加密傳輸施绎,身份認(rèn)證,密鑰

  1. https相對(duì)于http加入了ssl層, 加密傳輸, 身份認(rèn)證;

  2. 需要到ca申請(qǐng)收費(fèi)的證書(shū);

  3. 安全但是耗時(shí)多贞绳,緩存不是很好;

  4. 注意兼容http和https;

  5. 連接方式不同, 端口號(hào)也不同, http是80, https是443

15. CSRF和XSS區(qū)別及防御

16. cookie可設(shè)置哪些屬性谷醉?httponly?

chrome控制臺(tái)的application下可查看:

cookie

  • name  字段為一個(gè)cookie的名稱。

  • value  字段為一個(gè)cookie的值冈闭。

  • domain  字段為可以訪問(wèn)此cookie的域名俱尼。

  • path  字段為可以訪問(wèn)此cookie的頁(yè)面路徑。比如domain是abc.com,path是/test萎攒,那么只有/test路徑下的頁(yè)面可以讀取此cookie号显。

  • expires/Max-Age   字段為此cookie超時(shí)時(shí)間臭猜。若設(shè)置其值為一個(gè)時(shí)間,那么當(dāng)?shù)竭_(dá)此時(shí)間后押蚤,此cookie失效蔑歌。不設(shè)置的話默認(rèn)值是Session,意思是cookie會(huì)和session一起失效揽碘。當(dāng)瀏覽器關(guān)閉(不是瀏覽器標(biāo)簽頁(yè)次屠,而是整個(gè)瀏覽器) 后,此cookie失效雳刺。

  • Size  字段 此cookie大小劫灶。

  • http  字段 cookie的httponly屬性。若此屬性為true掖桦,則只有在http請(qǐng)求頭中會(huì)帶有此cookie的信息本昏,而不能通過(guò)document.cookie來(lái)訪問(wèn)此cookie。

  • secure   字段 設(shè)置是否只能通過(guò)https來(lái)傳遞此條cookie

17. 登錄后枪汪,前端做了哪些工作涌穆,如何得知已登錄

  • 前端存放服務(wù)端下發(fā)的cookie, 簡(jiǎn)單說(shuō)就是寫(xiě)一個(gè)字段在cookie中表明已登錄, 并設(shè)置失效日期

  • 或使用后端返回的token, 每次ajax請(qǐng)求將token攜帶在請(qǐng)求頭中, 這也是防范csrf的手段之一

18. http狀態(tài)碼

  • 1**: 服務(wù)器收到請(qǐng)求, 需請(qǐng)求者進(jìn)一步操作

  • 2**: 請(qǐng)求成功

  • 3**: 重定向, 資源被轉(zhuǎn)移到其他URL了

  • 4**: 客戶端錯(cuò)誤, 請(qǐng)求語(yǔ)法錯(cuò)誤或沒(méi)有找到相應(yīng)資源

  • 5**: 服務(wù)端錯(cuò)誤, server error

  • 301: 資源(網(wǎng)頁(yè)等)被永久轉(zhuǎn)移到其他URL, 返回值中包含新的URL, 瀏覽器會(huì)自動(dòng)定向到新URL

  • 302: 臨時(shí)轉(zhuǎn)移. 客戶端應(yīng)訪問(wèn)原有URL

  • 304: Not Modified. 指定日期后未修改, 不返回資源

  • 403: 服務(wù)器拒絕執(zhí)行請(qǐng)求

  • 404: 請(qǐng)求的資源(網(wǎng)頁(yè)等)不存在

  • 500: 內(nèi)部服務(wù)器錯(cuò)誤

19. # Http請(qǐng)求頭緩存設(shè)置方法

Cache-control, expire, last-modify

20. 實(shí)現(xiàn)頁(yè)面回退刷新

  • 舊: window.history.back() + window.location.href=document.referrer;

  • 新: HTML5的新API擴(kuò)展了window.history,使歷史記錄點(diǎn)更加開(kāi)放了雀久∷尴。可以存儲(chǔ)當(dāng)前歷史記錄點(diǎn)、替換當(dāng)前歷史記錄點(diǎn)赖捌、監(jiān)聽(tīng)歷史記錄點(diǎn)onpopstate, replaceState

21. 正向代理和反向代理

  • 正向代理:

    正向代理

    (1)訪問(wèn)原來(lái)無(wú)法訪問(wèn)的資源祝沸,如google
    (2) 可以做緩存,加速訪問(wèn)資源
    (3)對(duì)客戶端訪問(wèn)授權(quán)越庇,上網(wǎng)進(jìn)行認(rèn)證
    (4)代理可以記錄用戶訪問(wèn)記錄(上網(wǎng)行為管理)罩锐,對(duì)外隱藏用戶信息

  • 反向代理:

    反向代理

    (1)保證內(nèi)網(wǎng)的安全,可以使用反向代理提供WAF功能卤唉,阻止web攻擊大型網(wǎng)站涩惑,通常將反向代理作為公網(wǎng)訪問(wèn)地址,Web服務(wù)器是內(nèi)網(wǎng)搬味。
    (2)負(fù)載均衡境氢,通過(guò)反向代理服務(wù)器來(lái)優(yōu)化網(wǎng)站的負(fù)載

22. 關(guān)于預(yù)檢請(qǐng)求

在非簡(jiǎn)單請(qǐng)求且跨域的情況下蟀拷,瀏覽器會(huì)自動(dòng)發(fā)起options預(yù)檢請(qǐng)求碰纬。

23. 三次握手四次揮手

  • 開(kāi)啟連接用三次握手, 關(guān)閉用四次揮手

24. TCP和UDP協(xié)議

  • TCP(Transmission Control Protocol:傳輸控制協(xié)議;面向連接问芬,可靠傳輸

  • UDP(User Datagram Protocol):用戶數(shù)據(jù)報(bào)協(xié)議悦析;面向無(wú)連接,不可靠傳輸

25. 進(jìn)程和線程的區(qū)別

  • 進(jìn)程:是并發(fā)執(zhí)行的程序在執(zhí)行過(guò)程中分配和管理資源的基本單位此衅,是一個(gè)動(dòng)態(tài)概念强戴,競(jìng)爭(zhēng)計(jì)算機(jī)系統(tǒng)資源的基本單位亭螟。

  • 線程:是進(jìn)程的一個(gè)執(zhí)行單元,是進(jìn)程內(nèi)科調(diào)度實(shí)體骑歹。比進(jìn)程更小的獨(dú)立運(yùn)行的基本單位预烙。線程也被稱為輕量級(jí)進(jìn)程。

  • 一個(gè)程序至少一個(gè)進(jìn)程道媚,一個(gè)進(jìn)程至少一個(gè)線程扁掸。

1. 生命周期

生命周期

2 .雙向數(shù)據(jù)綁定v-model。這個(gè)最好也是自己實(shí)現(xiàn)一下 理解更深

通過(guò)v-model
VUE實(shí)現(xiàn)雙向數(shù)據(jù)綁定的原理就是利用了 Object.defineProperty() 這個(gè)方法重新定義了對(duì)象獲取屬性值(get)和設(shè)置屬性值(set)的操作來(lái)實(shí)現(xiàn)的最域。


var obj = { }
var name

Object.defineProperty(obj, "data", {

  get: function () {
    return name
  },

  set: function (val) {
    name = val
    console.log(val)
  }
})

obj.data = 'aaa'

console.log(obj.data)

 myVue.prototype._obverse = function (obj) { 
    var value;
    for (key in obj) {  
      if (obj.hasOwnProperty(key)) {
        value = obj[key]; 
        if (typeof value === 'object') {  
          this._obverse(value);
        }
        Object.defineProperty(this.$data, key, {  
          enumerable: true,
          configurable: true,
          get: function () {
            console.log(`獲取${value}`);
            return value;
          },
          set: function (newVal) {
            console.log(`更新${newVal}`);
            if (value !== newVal) {
              value = newVal;
            }
          }
        })
      }
    }
  }

3.vue父子組件傳遞參數(shù)

  • 父 -->子: 通過(guò)props

  • 子 -->父: 通過(guò) refs 或emit

4.vue傳遞參數(shù)方法

  • 父子組件傳參如上, v-bind : v-on @

  • 兄弟組件傳參:(通過(guò)EventBus事件總線實(shí)現(xiàn))


import Vue from 'vue'
export default new Vue

Vue.prototype.$EventBus = new Vue()

import eventBus from 'eventBus.js'
eventBus.$emit()
eventBus.$on()

this.bus.$emit()
this.bus.$on()

eventBus.$off()

5.vue自定義組件

可以使用獨(dú)立可復(fù)用的自定義組件來(lái)構(gòu)成大型應(yīng)用, 采用帕斯卡命名法或橫線連接, 通過(guò)以上方式進(jìn)行組件間通信. 每一個(gè)組件都是Vue實(shí)例, 可以使用生命周期鉤子.

6. vue自定義指令

  • 除核心指令之外的指令, 使用directive進(jìn)行注冊(cè).

  • 指令自定義鉤子函數(shù): bind, inserted, update, componentUpdated, unbind

7.vuex組成和原理

  • 組成: 組件間通信, 通過(guò)store實(shí)現(xiàn)全局存取

  • 修改: 唯一途徑, 通過(guò)commit一個(gè)mutations(同步)或dispatch一個(gè)actions(異步)

  • 簡(jiǎn)寫(xiě): 引入mapState谴分、mapGetters、mapActions

8.vue-router的原理镀脂,例如hashhistory和History interface這些東西要弄明白牺蹄。其實(shí)看一下源碼就好了,看不懂可以直接看解析的相關(guān)技術(shù)博客薄翅。

  • vue-router用法:
    在router.js或者某一個(gè)路由分發(fā)頁(yè)面配置path, name, component對(duì)應(yīng)關(guān)系

  • 每個(gè)按鈕一個(gè)value, 在watch功能中使用this.$router.push實(shí)現(xiàn)對(duì)應(yīng)跳轉(zhuǎn), 類似react的this.history.push

  • 或直接用router-link to去跳轉(zhuǎn), 類似react的link to

  • vue-router原理: 通過(guò)hash和History interface兩種方式實(shí)現(xiàn)前端路由

  • HashHistory: 利用URL中的hash(“#”);replace()方法與push()方法不同之處在于沙兰,它并不是將新路由添加到瀏覽器訪問(wèn)歷史的棧頂,而是替換掉當(dāng)前的路由

  • History interface: 是瀏覽器歷史記錄棧提供的接口匿刮,通過(guò)back(), forward(), go()等方法僧凰,我們可以讀取瀏覽器歷史記錄棧的信息,進(jìn)行各種跳轉(zhuǎn)操作. pushState(), replaceState() 這下不僅是讀取了熟丸,還可以對(duì)瀏覽器歷史記錄棧進(jìn)行修改

9.vue的seo問(wèn)題

seo關(guān)系到網(wǎng)站排名, vue搭建spa做前后端分離不好做seo, 可通過(guò)其他方法解決:

  • SSR服務(wù)端渲染: 將同一個(gè)組件渲染為服務(wù)器端的 HTML 字符串.利于seo且更快.

  • vue-meta-info, nuxt, prerender-spa-plugin頁(yè)面預(yù)渲染等

10.預(yù)渲染和ssr
以上

11.生命周期內(nèi)create和mounted的區(qū)別

  • created: 在模板渲染成html前調(diào)用训措,即通常初始化某些數(shù)據(jù),然后再渲染成視圖光羞。

  • mounted: 在模板渲染成html后調(diào)用绩鸣,通常是初始化頁(yè)面完成后,再對(duì)html的dom節(jié)點(diǎn)進(jìn)行一些需要的操作和方法纱兑。

12.監(jiān)聽(tīng)watch

對(duì)應(yīng)一個(gè)對(duì)象呀闻,鍵是觀察表達(dá)式,值是對(duì)應(yīng)回調(diào)潜慎。值也可以是methods的方法名捡多,或者是對(duì)象,包含選項(xiàng)铐炫。在實(shí)例化時(shí)為每個(gè)鍵調(diào)用 $watch()

13.登錄驗(yàn)證攔截(通過(guò)router)

  • 先設(shè)置requireAuth:
routes = [
    {
        name: 'detail',
        path: '/detail',
        meta: {
            requireAuth: true
        }
    },
    {
        name: 'login',
        path: '/login'
    }
]

  • 再配置router.beforeEach:
router.beforeEach((from, to, next) => {
    if (to.meta.requireAuth) { 
        if (store.state.token) { 
            next() 
        } else {
            next({
                path: '/login',
                query: {redirect: to.fullPath} 
            })
        }
    } else {
       next()
    }
})

14. v-for key值

不寫(xiě)key值會(huì)報(bào)warning, 和react的array渲染類似. 根據(jù)diff算法, 修改數(shù)組后, 寫(xiě)key值會(huì)復(fù)用, 不寫(xiě)會(huì)重新生成, 造成性能浪費(fèi)或某些不必要的錯(cuò)誤

15. vue3.0的更新和defineProperty優(yōu)化

  • 放棄 Object.defineProperty 垒手,使用更快的原生 Proxy (訪問(wèn)對(duì)象攔截器, 也成代理器)

  • 提速, 降低內(nèi)存使用, Tree-shaking更友好

  • 支持IE11等

  • 使用Typescript

15. vue使用this獲取變量

正常要通過(guò)vm.[圖片上傳失敗...(image-bd2cdd-1605778364068)]

root傳參取值

16. jQuery的優(yōu)缺點(diǎn),與vue的不同,vue的優(yōu)缺點(diǎn)?

  • jq優(yōu)點(diǎn): 比原生js更易書(shū)寫(xiě), 封裝了很多api, 有豐富的插件庫(kù); 缺點(diǎn): 每次升級(jí)與之前版本不兼容, 只能手動(dòng)開(kāi)發(fā), 操作DOM很慢, 不方便, 變量名污染, 作用域混淆等.

  • vue優(yōu)缺點(diǎn): 雙向綁定, 虛擬DOM, diff算法, MVVM, 組件化, 通信方便, 路由分發(fā)等

17. vue解除雙向綁定

let obj = JSON.parse(JSON.stringify(this.temp1));

18. vue異步組件

為了簡(jiǎn)化篷店,Vue 允許你以一個(gè)工廠函數(shù)的方式定義你的組件敏沉,這個(gè)工廠函數(shù)會(huì)異步解析你的組件定義琴许。Vue 只有在這個(gè)組件需要被渲染的時(shí)候才會(huì)觸發(fā)該工廠函數(shù)檐春,且會(huì)把結(jié)果緩存起來(lái)供未來(lái)重渲染

Vue.component(
  'async-webpack-example',

  () => import('./my-async-component')
)

19. MVC與MVVM

  • model-數(shù)據(jù)層 view-視圖層 controller-控制層

  • MVC的目的是實(shí)現(xiàn)M和V的分離助琐,單向通信符隙,必須通過(guò)C來(lái)承上啟下

  • MVVM中通過(guò)VM(vue中的實(shí)例化對(duì)象)的發(fā)布者-訂閱者模式實(shí)現(xiàn)雙向綁定憎账,數(shù)據(jù)綁定套硼,dom事件監(jiān)聽(tīng)

  • 區(qū)別:MVC和MVVM的區(qū)別并不是VM完全取代了C,ViewModel存在目的在于抽離Controller中展示的業(yè)務(wù)邏輯胞皱,而不是替代Controller熟菲,其它視圖操作業(yè)務(wù)等還是應(yīng)該放在Controller中實(shí)現(xiàn)。也就是說(shuō)MVVM實(shí)現(xiàn)的是業(yè)務(wù)邏輯組件的重用

20. vue漸進(jìn)式

小到可以只使用核心功能朴恳,比如單文件組件作為一部分嵌入抄罕;大到使用整個(gè)工程,vue init webpack my-project來(lái)構(gòu)建項(xiàng)目于颖;VUE的核心庫(kù)及其生態(tài)系統(tǒng)也可以滿足你的各式需求(core+vuex+vue-route)

1. 新舊生命周期

  • 舊: will, did; mount, update...

  • 新: 16版本之后:

  • getDerivedStateFromProps: 虛擬dom之后呆贿,實(shí)際dom掛載之前, 每次獲取新的props或state之后, 返回新的state, 配合didUpdate可以替代willReceiveProps

  • getSnapshotBeforeUpdate: update發(fā)生的時(shí)候,組件更新前觸發(fā), 在render之后森渐,在組件dom渲染之前做入;返回一個(gè)值,作為componentDidUpdate的第三個(gè)參數(shù)同衣;配合componentDidUpdate, 可以覆蓋componentWillUpdate的所有用法

  • componentDidCatch: 錯(cuò)誤處理

  • 對(duì)比: 棄用了三個(gè)will, 新增兩個(gè)get來(lái)代替will, 不能混用, 17版本會(huì)徹底刪除. 新增錯(cuò)誤處理

2. react核心

  • 虛擬DOM, Diff算法, 遍歷key值

  • react-dom: 提供了針對(duì)DOM的方法竟块,比如:把創(chuàng)建的虛擬DOM,渲染到頁(yè)面上 或 配合ref來(lái)操作DOM

  • react-router

3. fiber核心(react 16)

  • 舊: 瀏覽器渲染引擎單線程, 計(jì)算DOM樹(shù)時(shí)鎖住整個(gè)線程, 所有行為同步發(fā)生, 有效率問(wèn)題, 期間react會(huì)一直占用瀏覽器主線程耐齐,如果組件層級(jí)比較深浪秘,相應(yīng)的堆棧也會(huì)很深,長(zhǎng)時(shí)間占用瀏覽器主線程, 任何其他的操作(包括用戶的點(diǎn)擊埠况,鼠標(biāo)移動(dòng)等操作)都無(wú)法執(zhí)行

  • 新: 重寫(xiě)底層算法邏輯, 引入fiber時(shí)間片, 異步渲染, react會(huì)在渲染一部分樹(shù)后檢查是否有更高優(yōu)先級(jí)的任務(wù)需要處理(如用戶操作或繪圖), 處理完后再繼續(xù)渲染, 并可以更新優(yōu)先級(jí), 以此管理渲染任務(wù). 加入fiber的react將組件更新分為兩個(gè)時(shí)期(phase 1 && phase 2)耸携,render前的生命周期為phase1,render后的生命周期為phase2, 1可以打斷, 2不能打斷一次性更新. 三個(gè)will生命周期可能會(huì)重復(fù)執(zhí)行, 盡量避免使用

4. 渲染一個(gè)react

  • 分為首次渲染和更新渲染

  • 生命周期, 建立虛擬DOM, 進(jìn)行diff算法

  • 對(duì)比新舊DOM, 節(jié)點(diǎn)對(duì)比, 將算法復(fù)雜度從O(n^3)降低到O(n)

  • key值優(yōu)化, 避免用index作為key值, 兄弟節(jié)點(diǎn)中唯一就行

5. 高階組件

高階組件就是一個(gè)函數(shù)辕翰,且該函數(shù)(wrapper)接受一個(gè)組件作為參數(shù)夺衍,并返回一個(gè)新的組件。
高階組件并不關(guān)心數(shù)據(jù)使用的方式和原因喜命,而被包裹的組件也不關(guān)心數(shù)據(jù)來(lái)自何處.

  • react-dnd: 根組件, source, target等
    export default DragSource(type, spec, collect)(MyComponent)

  • 重構(gòu)代碼庫(kù)使用HOC提升開(kāi)發(fā)效率

6. hook(v16.7測(cè)試)

在無(wú)狀態(tài)組件(如函數(shù)式組件)中也能操作state以及其他react特性, 通過(guò)useState

7. redux和vuex以及dva:

  • redux: 通過(guò)store存儲(chǔ)沟沙,通過(guò)action唯一更改,reducer描述如何更改壁榕。dispatch一個(gè)action

  • dva: 基于redux矛紫,結(jié)合redux-saga等中間件進(jìn)行封裝

  • vuex:類似dva,集成化护桦。action異步含衔,mutation非異步

8. react和vue的區(qū)別

  • 數(shù)據(jù)是否可變: react整體是函數(shù)式的思想煎娇,把組件設(shè)計(jì)成純組件二庵,狀態(tài)和邏輯通過(guò)參數(shù)傳入贪染,所以在react中,是單向數(shù)據(jù)流催享,推崇結(jié)合immutable來(lái)實(shí)現(xiàn)數(shù)據(jù)不可變; vue的思想是響應(yīng)式的杭隙,也就是基于是數(shù)據(jù)可變的,通過(guò)對(duì)每一個(gè)屬性建立Watcher來(lái)監(jiān)聽(tīng)因妙,當(dāng)屬性變化的時(shí)候痰憎,響應(yīng)式的更新對(duì)應(yīng)的虛擬dom∨屎總之铣耘,react的性能優(yōu)化需要手動(dòng)去做,而vue的性能優(yōu)化是自動(dòng)的以故,但是vue的響應(yīng)式機(jī)制也有問(wèn)題蜗细,就是當(dāng)state特別多的時(shí)候,Watcher也會(huì)很多怒详,會(huì)導(dǎo)致卡頓炉媒,所以大型應(yīng)用(狀態(tài)特別多的)一般用react,更加可控昆烁。

  • 通過(guò)js來(lái)操作一切吊骤,還是用各自的處理方式: react的思路是all in js,通過(guò)js來(lái)生成html静尼,所以設(shè)計(jì)了jsx白粉,還有通過(guò)js來(lái)操作css,社區(qū)的styled-component鼠渺、jss等; vue是把html蜗元,css,js組合到一起系冗,用各自的處理方式奕扣,vue有單文件組件,可以把html掌敬、css惯豆、js寫(xiě)到一個(gè)文件中,html提供了模板引擎來(lái)處理奔害。

  • 類式的組件寫(xiě)法楷兽,還是聲明式的寫(xiě)法: react是類式的寫(xiě)法,api很少; 而vue是聲明式的寫(xiě)法华临,通過(guò)傳入各種options芯杀,api和參數(shù)都很多。所以react結(jié)合typescript更容易一起寫(xiě),vue稍微復(fù)雜揭厚。

  • 擴(kuò)展不同: react可以通過(guò)高階組件(Higher Order Components--HOC)來(lái)擴(kuò)展却特,而vue需要通過(guò)mixins來(lái)擴(kuò)展

  • 什么功能內(nèi)置,什么交給社區(qū)去做: react做的事情很少筛圆,很多都交給社區(qū)去做裂明,vue很多東西都是內(nèi)置的,寫(xiě)起來(lái)確實(shí)方便一些太援,
    比如 redux的combineReducer就對(duì)應(yīng)vuex的modules闽晦,
    比如reselect就對(duì)應(yīng)vuex的getter和vue組件的computed,
    vuex的mutation是直接改變的原始數(shù)據(jù)提岔,而redux的reducer是返回一個(gè)全新的state仙蛉,所以redux結(jié)合immutable來(lái)優(yōu)化性能,vue不需要碱蒙。

9. react單向數(shù)據(jù)流怎么理解

React是單向數(shù)據(jù)流捅儒,數(shù)據(jù)主要從父節(jié)點(diǎn)傳遞到子節(jié)點(diǎn)(通過(guò)props)。如果頂層(父級(jí))的某個(gè)props改變了振亮,React會(huì)重渲染所有的子節(jié)點(diǎn)巧还。

10. React算法復(fù)雜度優(yōu)化

react樹(shù)對(duì)比是按照層級(jí)去對(duì)比的, 他會(huì)給樹(shù)編號(hào)0,1,2,3,4.... 然后相同的編號(hào)進(jìn)行比較坊秸。所以復(fù)雜度是n麸祷,這個(gè)好理解。

關(guān)鍵是傳統(tǒng)diff的復(fù)雜度是怎么算的褒搔?傳統(tǒng)的diff需要出了上面的比較之外阶牍,還需要跨級(jí)比較。他會(huì)將兩個(gè)樹(shù)的節(jié)點(diǎn)星瘾,兩兩比較走孽,這就有n2的復(fù)雜度了。然后還需要編輯樹(shù)琳状,編輯的樹(shù)可能發(fā)生在任何節(jié)點(diǎn)磕瓷,需要對(duì)樹(shù)進(jìn)行再一次遍歷操作,因此復(fù)雜度為n念逞。加起來(lái)就是n3了困食。

11. React優(yōu)點(diǎn)

聲明式, 組件化, 一次學(xué)習(xí), 隨處編寫(xiě). 靈活, 豐富, 輕巧, 高效

1. 移動(dòng)端兼容適配

  • <meta name="viewport" content="width=device-width, initial-scale=1.0">

  • rem, em, 百分比

  • 框架的柵格布局

  • media query媒體查詢

  • 手淘團(tuán)隊(duì)的一套flexible.js, 自動(dòng)判斷dpr進(jìn)行整個(gè)布局視口的放縮

2. flexible如何實(shí)現(xiàn)自動(dòng)判斷dpr

判斷機(jī)型, 找出樣本機(jī)型去適配. 比如iphone以6為樣本, 寬度375px, dpr是2

3. 為什么以iPhone6為標(biāo)準(zhǔn)的設(shè)計(jì)稿的尺寸是以750px寬度來(lái)設(shè)計(jì)的呢?

iPhone6的滿屏寬度是375px翎承,而iPhone6采用的視網(wǎng)膜屏的物理像素是滿屏寬度的2倍硕盹,也就是dpr(設(shè)備像素比)為2, 并且設(shè)計(jì)師所用的PS設(shè)計(jì)軟件分辨率和像素關(guān)系是1:1。所以為了做出的清晰的頁(yè)面叨咖,設(shè)計(jì)師一般給出750px的設(shè)計(jì)圖瘩例,我們?cè)俑鶕?jù)需求對(duì)元素的尺寸設(shè)計(jì)和壓縮啊胶。

4. 如何處理異形屏iphone X

  • safe area: 默認(rèn)放置在安全區(qū)域以避免遮擋, 但會(huì)壓縮

  • 在meta中添加viewport-fit=cover: 告訴瀏覽器要講整個(gè)頁(yè)面渲染到瀏覽器中,不管設(shè)備是圓角與否垛贤,這個(gè)時(shí)候會(huì)造成頁(yè)面的元素被圓角遮擋

  • padding: constant(env): 解決遮擋問(wèn)題

5. 移動(dòng)端首屏優(yōu)化

  • 采用服務(wù)器渲染ssr

  • 按需加載配合webpack分塊打包, 通過(guò)entry和commonChunkPlugin

  • 很有必要將script標(biāo)簽?異步

  • 有輪播圖 最好給個(gè)默認(rèn) 另外要處理圖片懶加載

  • 打包線上也要注意去掉map 文件

  • 組件, 路由懶加載

  • webpack的一切配置 肯定是必須的

  • 壓縮圖片 https://tinypng.com/

  • 建議還是用webpack的圖片壓縮插件

  • 骨架屏

  • Loading頁(yè)面

6. PWA全稱Progressive Web App焰坪,即漸進(jìn)式WEB應(yīng)用

一個(gè) PWA 應(yīng)用首先是一個(gè)網(wǎng)頁(yè), 可以通過(guò) Web 技術(shù)編寫(xiě)出一個(gè)網(wǎng)頁(yè)應(yīng)用. 隨后添加上 App Manifest 和 Service Worker 來(lái)實(shí)現(xiàn) PWA 的安裝和離線等功能
解決了哪些問(wèn)題?

  • 可以添加至主屏幕南吮,點(diǎn)擊主屏幕圖標(biāo)可以實(shí)現(xiàn)啟動(dòng)動(dòng)畫(huà)以及隱藏地址欄

  • 實(shí)現(xiàn)離線緩存功能,即使用戶手機(jī)沒(méi)有網(wǎng)絡(luò)誊酌,依然可以使用一些離線功能

  • 實(shí)現(xiàn)了消息推送
    它解決了上述提到的問(wèn)題部凑,這些特性將使得 Web 應(yīng)用漸進(jìn)式接近原生 App。

7. 離線包方案

現(xiàn)在 web 頁(yè)面在移動(dòng)端的地位越來(lái)越高碧浊,大部分主流 App 采用 native + webview 的 hybrid 模式涂邀,加載遠(yuǎn)程頁(yè)面受限于網(wǎng)絡(luò),本地 webview 引擎箱锐,經(jīng)常會(huì)出現(xiàn)渲染慢導(dǎo)致的白屏現(xiàn)象比勉,體驗(yàn)很差,于是離線包方案應(yīng)運(yùn)而生驹止。動(dòng)態(tài)下載的離線包可以使得我們不需要走完整的 App 審核發(fā)布流程就完成了版本的更新

8. 自適應(yīng)和響應(yīng)式布局的區(qū)別

  1. 自適應(yīng)布局通過(guò)檢測(cè)視口分辨率浩聋,來(lái)判斷當(dāng)前訪問(wèn)的設(shè)備是:pc端、平板臊恋、手機(jī)衣洁,從而請(qǐng)求服務(wù)層,返回不同的頁(yè)面抖仅;響應(yīng)式布局通過(guò)檢測(cè)視口分辨率坊夫,針對(duì)不同客戶端在客戶端做代碼處理,來(lái)展現(xiàn)不同的布局和內(nèi)容撤卢。

  2. 自適應(yīng)布局需要開(kāi)發(fā)多套界面环凿,而響應(yīng)式布局只需要開(kāi)發(fā)一套界面就可以了。

  3. 自適應(yīng)對(duì)頁(yè)面做的屏幕適配是在一定范圍:比如pc端一般要大于1024像素放吩,手機(jī)端要小于768像素智听。而響應(yīng)式布局是一套頁(yè)面全部適應(yīng)。

  4. 自適應(yīng)布局如果屏幕太小會(huì)發(fā)生內(nèi)容過(guò)于擁擠渡紫。而響應(yīng)式布局正是為了解決這個(gè)問(wèn)題而衍生出的概念瞭稼,它可以自動(dòng)識(shí)別屏幕寬度并做出相應(yīng)調(diào)整的網(wǎng)頁(yè)設(shè)計(jì)。

1. babel和polyfill

  • Babel: Babel 是一個(gè)廣泛使用的 ES6 轉(zhuǎn)碼器腻惠,可以將 ES6 代碼轉(zhuǎn)為 ES5 代碼环肘。注意:Babel 默認(rèn)只轉(zhuǎn)換新的 JavaScript 句法(syntax),而不轉(zhuǎn)換新的 API

  • Polyfill: Polyfill的準(zhǔn)確意思為集灌,用于實(shí)現(xiàn)瀏覽器并不支持的原生API的代碼悔雹。

2. jpg, jpeg和png區(qū)別

  • jpg是jpeg的縮寫(xiě), 二者一致

  • PNG就是為取代GIF而生的, 無(wú)損壓縮, 占用內(nèi)存多

  • jpg犧牲圖片質(zhì)量, 有損, 占用內(nèi)存小

  • PNG格式可編輯复哆。如圖片中有字體等,可利用PS再做更改腌零。JPG格式不可編輯

3. git rebase和merge區(qū)別

git rebase

git merge

  1. 減少HTTP請(qǐng)求(合并css梯找、js,雪碧圖/base64圖片)

  2. 壓縮(css益涧、js锈锤、圖片皆可壓縮,使用webpack uglify和 svg)

  3. 樣式表放頭部,腳本放底部

  4. 使用CDN(這部分闲询,不少前端都不用考慮久免,負(fù)責(zé)發(fā)布的兄弟可能會(huì)負(fù)責(zé)搞好)

  5. http緩存

  6. bosify圖片壓縮: 根據(jù)具體情況修改圖片后綴或格式 后端根據(jù)格式來(lái)判斷存儲(chǔ)原圖還是縮略圖

  7. 懶加載, 預(yù)加載

  8. 替代方案: 骨架屏, SSR

  9. webpack優(yōu)化

1.JSBridge通信原理, 有哪幾種實(shí)現(xiàn)的方式?

JsBridge給JavaScript提供了調(diào)用Native功能扭弧,Native也能夠操控JavaScript阎姥。這樣前端部分就可以方便使用地理位置、攝像頭以及登錄支付等Native能力啦鸽捻。JSBridge構(gòu)建 Native和非Native間消息通信的通道呼巴,而且是 雙向通信的通道。

  • JS 向 Native 發(fā)送消息 : 調(diào)用相關(guān)功能御蒲、通知 Native 當(dāng)前 JS 的相關(guān)狀態(tài)等衣赶。

  • Native 向 JS 發(fā)送消息 : 回溯調(diào)用結(jié)果、消息推送厚满、通知 JS 當(dāng)前 Native 的狀態(tài)等屑埋。

2.實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 JSBridge,設(shè)計(jì)思路痰滋?

1. 二分查找和冒泡排序

  • 二分查找: 遞歸(分左右, 傳遞start,end參數(shù))和非遞歸(使用while(l < h))

  • 冒泡排序: 兩個(gè)for循環(huán)

2. 快速排序

function quickSort (arr) {
  if (arr.length < 2) return arr
  var middle = Math.floor(arr.length / 2)
  var flag = arr.splice(middle, 1)[0]
  var left = [],
        right = []
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] < flag) {
      left.push(arr[i])
    } else {
      right.push(arr[i])
    }
  }
  return quickSort(left).concat([flag], quickSort(right))

3. 最長(zhǎng)公共子串

function findSubStr(str1, str2) {
        if (str1.length > str2.length) {
          [str1, str2] = [str2, str1]
        }
        var result = ''
        var len = str1.length
        for (var j = len; j > 0; j--) {
          for (var i = 0; i < len - j; i++) {
            result = str1.substr(i, j)
            if (str2.includes(result)) return result
          }
        }
      }
      console.log(findSubStr('aabbcc11', 'ppooiiuubcc123'))

4. 最長(zhǎng)公共子序列(LCS動(dòng)態(tài)規(guī)劃)

另一篇


function LCS(str1, str2){
        var rows =  str1.split("")
        rows.unshift("")
        var cols =  str2.split("")
        cols.unshift("")
        var m = rows.length
        var n = cols.length
        var dp = []
        for(var i = 0; i < m; i++){ 
            dp[i] = []
            for(var j = 0; j < n; j++){ 
                if(i === 0 || j === 0){
                    dp[i][j] = 0
                    continue
                }

                if(rows[i] === cols[j]){ 
                    dp[i][j] = dp[i-1][j-1] + 1 
                }else{
                    dp[i][j] = Math.max( dp[i-1][j], dp[i][j-1]) 
                }
            }
            console.log(dp[i].join(""))
        } 
        return dp[i-1][j-1]
    }

function findValue(input1,input2,n1,n2,T){
    var i = n1-1,j=n2-1;
    var result = [];
    console.log(i);
    console.log(j);
    while(i>0 && j>0){
        if(input1[i] == input2[j]){
            result.unshift(input1[i]);
            i--;
            j--;
        }else{

            if(T[i-1][j]>T[i][j-1]){

                i--;
            }else{

                j--;
            }
        }

    }

    console.log(result);
}

5. 數(shù)組去重摘能,多種方法

  • 雙for循環(huán), splice剔除并i--回退

  • indexOf等于index

  • filter indexOf === index

  • 新數(shù)組indexOf === index

  • 使用空對(duì)象等

6. 實(shí)現(xiàn)一個(gè)函數(shù)功能:sum(1,2,3,4..n)轉(zhuǎn)化為 sum(1)(2)(3)(4)…(n)


function curry ( fn ) {
  var c = (...arg) => (fn.length === arg.length) ? 
          fn (...arg) : (...arg1) => c(...arg, ...arg1)
  return c
}

7. 反轉(zhuǎn)二叉樹(shù)

var invertTree = function (root) {
  if (root !== null) {
    [root.left, root.right] = [root.right, root.left]
    invertTree(root.left)
    invertTree(root.right)
  }
  return root
}

8. 貪心算法解決背包問(wèn)題

var items = ['A','B','C','D']
var values = [50,220,60,60]
var weights = [5,20,10,12]
var capacity = 32 

greedy(values, weights, capacity) 

function greedy(values, weights, capacity) {
        var result = 0
        var rest = capacity
        var sortArray = []
        var num = 0
        values.forEach((v, i) => {
          sortArray.push({
            value: v,
            weight: weights[i],
            ratio: v / weights[i]
          })
        })
        sortArray.sort((a, b) => b.ratio - a.ratio)
        sortArray.forEach((v, i) => {
          num = parseInt(rest / v.weight)
          rest -= num * v.weight
          result += num * v.value
        })
        return result
      }

9. 輸入一個(gè)遞增排序的數(shù)組和一個(gè)數(shù)字S,在數(shù)組中查找兩個(gè)數(shù)敲街,使得他們的和正好是S团搞,如果有多對(duì)數(shù)字的和等于S,輸出兩個(gè)數(shù)的乘積最小的多艇。

function FindNumbersWithSum(array, sum)
{
    var index = 0
    for (var i = 0; i < array.length - 1 && array[i] < sum / 2; i++) {
        for (var j = i + 1; j < array.length; j++) {
            if (array[i] + array[j] === sum) return [array[i], array[j]]
        }

    }
    return []

10. 二叉樹(shù)各種(層序)遍歷

深度廣度遍歷


function reConstructBinaryTree(pre, vin)
{
    var result = null
    if (pre.length === 1) {
        result = {
            val: pre[0],
            left: null,
            right: null
        }
    } else if (pre.length > 1) {
        var root = pre[0]
        var vinRootIndex = vin.indexOf(root)
        var vinLeft = vin.slice(0, vinRootIndex)
        var vinRight = vin.slice(vinRootIndex + 1, vin.length)
        pre.shift()
        var preLeft = pre.slice(0, vinLeft.length)
        var preRight = pre.slice(vinLeft.length, pre.length)
        result = {
            val: root,
            left: reConstructBinaryTree(preLeft, vinLeft),
            right: reConstructBinaryTree(preRight, vinRight)
        }
    }
    return result
}

function prevTraverse (node) {
  if (node === null) return;

  console.log(node.data);
  prevTraverse(node.left);
  prevTraverse(node.right);
}

function middleTraverse (node) {
  if (node === null) return;

  middleTraverse(node.left);
  console.log(node.data);
  middleTraverse(node.right);
}

function lastTraverse (node) {
  if (node === null) return;

  lastTraverse(node.left);
  lastTraverse(node.right);
  console.log(node.data);
}

function preTraverse(tree) {
        var arr = [],
          node = null
        arr.unshift(tree)
        while (arr.length) {
          node = arr.shift()
          console.log(node.root)
          if (node.right) arr.unshift(node.right)
          if (node.left) arr.unshift(node.left)
        }
      }

function middleTraverseUnRecursion (root) {
  let arr = [],
      node = root;

  while (arr.length !== 0 || node !== null) {
    if (node === null) {
      node = arr.shift();
      console.log(node.data);
      node = node.right;
    } else {
      arr.unshift(node);
      node = node.left;
    }
  }

}

var result = []
var stack = [tree]
var count = 0
var bfs = function () {
  var node = stack[count]
  if (node) {
    result.push(node.value)
    if (node.left) stack.push(node.left)
    if (node.right) stack.push(node.right)
    count++
    bfs()
  }
}
bfs()
console.log(result)

function bfs (node) {
  var result = []
  var queue = []
  queue.push(node)
  while (queue.length) {
    node = queue.shift()
    result.push(node.value)
    node.left && queue.push(node.left)
    node.right && queue.push(node.right)
  }
  return result
}

11. 各種排序


function insertSort(arr) {
        var temp
        for (var i = 1; i < arr.length; i++) {
          temp = arr[i]
          for (var j = i; j > 0 && temp < arr[j - 1]; j--) {
            arr[j] = arr[j - 1]
          }
          arr[j] = temp
        }
        return arr
      }
      console.log(insertSort([3, 1, 8, 2, 5]))

function mergeSort(array) {
        var result = array.slice(0)
        function sort(array) {
          var length = array.length
          var mid = Math.floor(length * 0.5)
          var left = array.slice(0, mid)
          var right = array.slice(mid, length)
          if (length === 1) return array
          return merge(sort(left), sort(right))
        }
        function merge(left, right) {
          var result = []

          while (left.length || right.length) {
            if (left.length && right.length) {
              if (left[0] < right[0]) {
                result.push(left.shift())
              } else {
                result.push(right.shift())
              }
            } else if (left.length) {
              result.push(left.shift())
            } else {
              result.push(right.shift())
            }
          }
          return result
        }
        return sort(result)
      }
      console.log(mergeSort([5, 2, 8, 3, 6]))

function twoSort(array) {
        var len = array.length,
          i,
          j,
          tmp,
          low,
          high,
          mid,
          result
        result = array.slice(0)
        for (i = 1; i < len; i++) {
          tmp = result[i]
          low = 0
          high = i - 1
          while (low <= high) {
            mid = parseInt((high + low) / 2, 10)
            if (tmp < result[mid]) {
              high = mid - 1
            } else {
              low = mid + 1
            }
          }
          for (j = i - 1; j >= high + 1; j--) {
            result[j + 1] = result[j]
          }
          result[j + 1] = tmp
        }
        return result
      }
      console.log(twoSort([4, 1, 7, 2, 5]))

12. 使用尾遞歸對(duì)斐波那契優(yōu)化

遞歸非常耗費(fèi)內(nèi)存逻恐,因?yàn)樾枰瑫r(shí)保存成千上百個(gè)調(diào)用幀,很容易發(fā)生“棧溢出”錯(cuò)誤(stack overflow)峻黍。但對(duì)于尾遞歸來(lái)說(shuō)复隆,由于只存在一個(gè)調(diào)用幀,所以永遠(yuǎn)不會(huì)發(fā)生“棧溢出”錯(cuò)誤姆涩。


function Fibonacci (n) {
  if ( n <= 1 ) {return 1};

  return Fibonacci(n - 1) + Fibonacci(n - 2);
}

Fibonacci(10) 
Fibonacci(100) 
Fibonacci(500) 

function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
  if( n <= 1 ) {return ac2};

  return Fibonacci2 (n - 1, ac2, ac1 + ac2);
}

Fibonacci2(100) 
Fibonacci2(1000) 
Fibonacci2(10000) 

13. 兩個(gè)升序數(shù)組合并為一個(gè)升序數(shù)組

function sort (A, B) {
  var i = 0, j = 0, p = 0, m = A.length, n = B.length, C = []
  while (i < m || j < n) {
    if (i < m && j < n) {
      C[p++] = A[i] < B[j] ? A[i++] : B[j++]
    } else if (i < m) {
      C[p++] = A[i++]
    } else {
      C[p++] = B[j++]
    }
  }
  return C
}

1. node的router是什么

2. 數(shù)據(jù)庫(kù)索引是啥

  • 狹義上: 索引是數(shù)據(jù)庫(kù)針對(duì)每條數(shù)據(jù)自動(dòng)生成的內(nèi)部唯一id標(biāo)識(shí), 用以快速搜索定位數(shù)據(jù)

  • 廣義上: 是數(shù)據(jù)庫(kù)根據(jù)每條數(shù)據(jù)形成的關(guān)鍵字, 將劃分為樹(shù)形結(jié)構(gòu), 便于sql語(yǔ)句對(duì)數(shù)據(jù)的查找, 使算法復(fù)雜度降低到O(logn)

3. 瀏覽器的事件循環(huán)和node事件循環(huán)有什么區(qū)別挽拂?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市骨饿,隨后出現(xiàn)的幾起案子亏栈,更是在濱河造成了極大的恐慌台腥,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绒北,死亡現(xiàn)場(chǎng)離奇詭異黎侈,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)闷游,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門峻汉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人脐往,你說(shuō)我怎么就攤上這事休吠。” “怎么了钙勃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵蛛碌,是天一觀的道長(zhǎng)聂喇。 經(jīng)常有香客問(wèn)我辖源,道長(zhǎng),這世上最難降的妖魔是什么希太? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任克饶,我火速辦了婚禮,結(jié)果婚禮上誊辉,老公的妹妹穿的比我還像新娘矾湃。我一直安慰自己,他們只是感情好堕澄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布邀跃。 她就那樣靜靜地躺著,像睡著了一般蛙紫。 火紅的嫁衣襯著肌膚如雪拍屑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天坑傅,我揣著相機(jī)與錄音僵驰,去河邊找鬼。 笑死唁毒,一個(gè)胖子當(dāng)著我的面吹牛蒜茴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播浆西,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼粉私,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了近零?” 一聲冷哼從身側(cè)響起毡鉴,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤崔泵,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后猪瞬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體憎瘸,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年陈瘦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了幌甘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡痊项,死狀恐怖锅风,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鞍泉,我是刑警寧澤皱埠,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站咖驮,受9級(jí)特大地震影響边器,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜托修,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一忘巧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧睦刃,春花似錦砚嘴、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至兴泥,卻和暖如春工育,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背郁轻。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工翅娶, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人好唯。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓竭沫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親骑篙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蜕提,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 一、CSS問(wèn)題 web前端全棧資料粉絲福利(面試題靶端、視頻谎势、資料筆記凛膏、進(jìn)階路線) 1.flex布局 display:...
    PHP9年架構(gòu)師閱讀 1,596評(píng)論 1 15
  • 1. HTML 1. 必考:你是如何理解 HTML 語(yǔ)義化的? 荒野階段:最開(kāi)始是 PHP 后端寫(xiě) HTML脏榆,不會(huì)...
    Qingelin閱讀 695評(píng)論 0 0
  • https://github.com/haizlin/fe-interview[https://github.co...
    Poppy11閱讀 398評(píng)論 0 0
  • 腦子里陸陸續(xù)續(xù)過(guò)出來(lái)的一些面試題項(xiàng)目相關(guān) 自我介紹:職業(yè)經(jīng)歷猖毫,項(xiàng)目經(jīng)歷 選一個(gè)你覺(jué)得印象最深的項(xiàng)目講一講,然后會(huì)從...
    易恒_033a閱讀 336評(píng)論 0 0
  • 夜鶯2517閱讀 127,712評(píng)論 1 9