<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【秋招求職之路】字節(jié)跳動一面復(fù)盤總結(jié)

          共 14149字,需瀏覽 29分鐘

           ·

          2021-06-11 02:34

          往期精彩文章推薦



          字節(jié)跳動廣告系統(tǒng) 面經(jīng)

          一面

          自我介紹

          手撕防抖(如果滾動條判斷一個div是否存在會用什么來做?節(jié)流)

          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>實現(xiàn)防抖</title>
              <style>
                .container {
                  width200px;
                  height200px;
                  background-color: aqua;
                  font-size30px;
                  line-height200px;
                  text-align: center;
                }
              
          </style>
            </head>
            <body>
              <div class="container"></div>
              <script>
                var btn = document.getElementsByClassName('container')[0]
                // let cnt = 0
                // let timeId = null
                // btn.onmouseover = () => {
                //   clearTimeout(timeId)
                //   timeId = setTimeout(() => {
                //     btn.innerHTML = ++cnt
                //   }, 2000)
                // }
                let cnt = 0
                let doSomething = () => {
                  btn.innerHTML = ++cnt
                }
                let debounce = (fn,time,triggerNow) => {
                  let timeId = null
                  let debounced = (...args) => {
                    if(timeId){
                        clearTimeout(timeId)
                      }
                    if(triggerNow){
                      let exec = !timeId
                      timeId =setTimeout(()=>{
                        timeId = null
                      },time)
                      if(exec){
                        fn.apply(this,args)
                      }
                    }else{
                      timeId = setTimeout(()=>{
                        fn.apply(this,args)
                      },time)
                    }
                  }
                  debounced.remove = () => {
                    clearTimeout(timeId)
                    timeId = null
                  }
                  return debounced
                }
                btn.onmouseover = debounce(doSomething,2000,false)
              
          </script>
            </body>
          </html>

          CSS實現(xiàn)三角形

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>畫三角形</title>
              <style>
                  .triggle{
                      width0px;
                      height0px;
                      border-top40px solid transparent;
                      border-left40px solid transparent;
                      border-bottom40px solid red;
                      border-right40px solid transparent;
                      margin40px;
                  }
              
          </style>
          </head>
          <body>
              <div class="triggle"></div>
          </body>
          </html>

          了解偽元素和偽類嗎?

          參考:CSS偽類和偽元素的區(qū)別 - Web前端工程師面試題講解

          盒模型

          div
          width=100px;
          border: 10px;
          padding: 15px;
          margin: 10px;
          height=100px;

          content-box => 100px

          border-box => 150px

          Vue雙向綁定實現(xiàn) Object.defineProperty()  它有哪些不足點?

          • 只能監(jiān)聽某個屬性,不能對全對象進行監(jiān)聽
          • 需要 for in遍歷找對象中的屬性
          • 不能監(jiān)聽數(shù)組,需要單獨的對數(shù)組進行特異性操作
          • 會污染原對象
          data : {
          name; 'abc';
          age: 23,
          },


          this.name = 'brown';
          this.gender = '男';

          如何讓 gender 改變也會讓視圖變化(面試官意思是如何用Vue動態(tài)新增對象屬性,觸發(fā)dom渲染)

          背景:項目中因為一些需求需要在JSON中新增一個屬性,也能console出來,但是就是不能在頁面渲染,即不能觸發(fā)視圖更新

          其實在vue 中新增屬性應(yīng)該用 $set 這個方法的

          1. 添加單個屬性

          $set()方法,既可以新增屬性,又可以觸發(fā)視圖更新。

          this.$set(this.data,”key”,value)

          2.添加多個屬性

          使用 Object.assign()用原對象與要混合進去的對象的屬性一起創(chuàng)建一個新的對象。

          this.obj = Object.assign({}, this.obj, {
            age18,
            name'Chocolate',
          })

          詢問輸出結(jié)果

          function Foo({
              getName = function ({ alert (1); };
              return this;
          }
          Foo.getName = function ({ alert (2);};
          Foo.prototype.getName = function ({ alert (3);};
          var getName = function ({ alert (4);};
          function getName({ alert (5);}

          //請寫出以下輸出結(jié)果:
          Foo.getName();
          getName();
          Foo().getName();
          getName();
          new Foo.getName();
          new Foo().getName();
          new new Foo().getName();

          參考:一道常被人輕視的前端JS面試題

          第一問

          先看此題的上半部分做了什么,首先定義了一個叫「Foo的函數(shù)」,之后為Foo創(chuàng)建了一個叫getName「靜態(tài)屬性」存儲了一個匿名函數(shù),之后為Foo的「原型對象」新創(chuàng)建了一個叫getName的匿名函數(shù)。之后又通過「函數(shù)變量表達(dá)式」創(chuàng)建了一個getName的函數(shù),最后再聲明一個叫getName函數(shù)。

          第一問的Foo.getName 自然是訪問Foo函數(shù)上存儲的「靜態(tài)屬性」,自然是2,沒什么可說的。

          第二問

          第二問,直接調(diào)用 getName 函數(shù)。既然是直接調(diào)用那么就是訪問「當(dāng)前上文作用域內(nèi)」的叫getName的函數(shù),所以跟1 2 3都沒什么關(guān)系。此題有無數(shù)面試者回答為5。此處有兩個坑,「一是變量聲明提升,二是函數(shù)表達(dá)式。」

          「變量聲明提升」

          所有聲明變量或聲明函數(shù)都會被提升到當(dāng)前函數(shù)的頂部。例如下代碼:

          console.log('x' in window);//true
          var x;
          x = 0;

          代碼執(zhí)行時js引擎會將聲明語句提升至代碼最上方,變?yōu)椋?/p>

          var x;
          console.log('x' in window);//true
          x = 0;

          「函數(shù)表達(dá)式」

          var getNamefunction getName 都是聲明語句,區(qū)別在于var getName「函數(shù)表達(dá)式」,而function getName「函數(shù)聲明」。關(guān)于JS中的各種函數(shù)創(chuàng)建方式可以看 大部分人都會做錯的經(jīng)典JS閉包面試題 這篇文章有詳細(xì)說明。

          函數(shù)表達(dá)式最大的問題,在于js會將此代碼拆分為兩行代碼分別執(zhí)行。例如下代碼:

          console.log(x);//輸出:function x(){}
          var x=1;
          function x(){}

          實際執(zhí)行的代碼為,先將 var x=1拆分為var x;x = 1;兩行,再將 var x;function x(){}兩行提升至最上方變成:

          var x;
          function x(){}
          console.log(x);
          x=1;

          所以最終函數(shù)聲明的x覆蓋了變量聲明的x,log輸出為x函數(shù)。同理,原題中代碼最終執(zhí)行時的是:

          function Foo({
              getName = function ({ alert (1); };
              return this;
          }
          var getName;//只提升變量聲明
          function getName({ alert (5);}//提升函數(shù)聲明,覆蓋var的聲明

          Foo.getName = function ({ alert (2);};
          Foo.prototype.getName = function ({ alert (3);};
          getName = function ({ alert (4);};//最終的賦值再次覆蓋function getName聲明

          getName();//最終輸出4

          第三問

          第三問的Foo().getName(); 先執(zhí)行了Foo函數(shù),然后調(diào)用Foo函數(shù)的返回值對象的getName屬性函數(shù)。

          Foo函數(shù)的第一句  getName = function () { alert (1); }; 是一句函數(shù)賦值語句,注意它沒有var聲明,所以先向當(dāng)前Foo函數(shù)作用域內(nèi)尋找getName變量,沒有。再向當(dāng)前函數(shù)作用域上層,即外層作用域內(nèi)尋找是否含有getName變量,找到了,也就是第二問中的alert(4)函數(shù),將此變量的值賦值為 function(){alert(1)}

          「此處實際上是將外層作用域內(nèi)的getName函數(shù)修改了。」

          注意:此處若依然沒有找到會一直向上查找到window對象,若window對象中也沒有g(shù)etName屬性,就在window對象中創(chuàng)建一個getName變量。

          簡單的講,「this的指向是由所在函數(shù)的調(diào)用方式?jīng)Q定的」。而此處的直接調(diào)用方式,this指向window對象

          遂Foo函數(shù)返回的是window對象,相當(dāng)于執(zhí)行 window.getName() ,而window中的getName已經(jīng)被修改為alert(1),所以最終會輸出1

          此處考察了兩個知識點,一個是「變量作用域問題」,一個是「this指向問題」

          第四問

          直接調(diào)用getName函數(shù),相當(dāng)于 window.getName() ,因為這個變量已經(jīng)被Foo函數(shù)執(zhí)行時修改了,遂結(jié)果與第三問相同,為1

          第五問

          new Foo.getName(); ,此處考察的是js的運算符優(yōu)先級問題。

          js運算符優(yōu)先級:通過查上表可以得知點(.)的優(yōu)先級高于new操作,遂相當(dāng)于是:

          new (Foo.getName)();

          所以實際上將getName函數(shù)作為了構(gòu)造函數(shù)來執(zhí)行,遂彈出2

          第六問

          第六問 new Foo().getName(),首先看運算符優(yōu)先級「括號高于new」,并且?guī)?shù)的new操作符是優(yōu)先級最高的,實際執(zhí)行為

          (new Foo()).getName()

          遂先執(zhí)行Foo函數(shù),而Foo此時作為構(gòu)造函數(shù)卻有返回值,所以這里需要說明下js中的「構(gòu)造函數(shù)返回值問題」

          原題中,返回的是this,而this在構(gòu)造函數(shù)中本來就代表當(dāng)前實例化對象,遂最終Foo函數(shù)「返回實例化對象」。之后調(diào)用實例化對象的getName函數(shù),因為在「Foo構(gòu)造函數(shù)中沒有為實例化對象添加任何屬性」,遂到當(dāng)前對象的原型對象(prototype)中尋找getName,找到了。

          遂最終輸出3。

          第七問

          最終實際執(zhí)行為:

          new ((new Foo()).getName)();

          先初始化Foo的實例化對象,然后將其原型上的getName函數(shù)作為構(gòu)造函數(shù)再次new。

          遂最終結(jié)果為3

          答案

          function Foo({
              getName = function ({ alert (1); };
              return this;
          }
          Foo.getName = function ({ alert (2);};
          Foo.prototype.getName = function ({ alert (3);};
          var getName = function ({ alert (4);};
          function getName({ alert (5);}

          //答案:
          Foo.getName();//2
          getName();//4
          Foo().getName();//1
          getName();//1
          new Foo.getName();//2
          new Foo().getName();//3
          new new Foo().getName();//3

          promise相關(guān),下面代碼輸出結(jié)果

          Promise.reject(2).catch(e => e).then(d => {
          console.log(d);
          });
          // 輸出2

          一般總是建議,Promise 對象后面要跟catch方法,這樣可以處理 Promise 內(nèi)部發(fā)生的錯誤。「catch方法返回的還是一個 Promise 對象,因此后面還可以接著調(diào)用then方法。」

          參考:你真的完全掌握了promise么?

          Promise 必知必會(十道題)

          關(guān)于 Promise 的 9 個面試題

          cookie 和 session 區(qū)別(session 存放哪)

          http是一個無狀態(tài)協(xié)議

          什么是無狀態(tài)呢?就是說這一次請求和上一次請求是沒有任何關(guān)系的,互不認(rèn)識的,沒有關(guān)聯(lián)的。這種無狀態(tài)的的好處是快速。壞處是假如我們想要把www.zhihu.com/login.htmlwww.zhihu.com/index.html關(guān)聯(lián)起來,必須使用某些手段和工具

          cookie和session

          由于http的無狀態(tài)性,為了使某個域名下的所有網(wǎng)頁能夠共享某些數(shù)據(jù),session和cookie出現(xiàn)了。客戶端訪問服務(wù)器的流程如下:

          • 首先,客戶端會發(fā)送一個http請求到服務(wù)器端。
          • 服務(wù)器端接受客戶端請求后,建立一個session,并發(fā)送一個http響應(yīng)到客戶端,這個響應(yīng)頭,其中就包含Set-Cookie頭部。該頭部包含了sessionId。Set-Cookie格式如下:Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
          • 在客戶端發(fā)起的第二次請求,假如服務(wù)器給了set-Cookie,瀏覽器會自動在請求頭中添加cookie
          • 服務(wù)器接收請求,分解cookie,驗證信息,核對成功后返回response給客戶端

          「注意」

          • cookie只是實現(xiàn)session的其中一種方案。雖然是最常用的,但并不是唯一的方法。禁用cookie后還有其他方法存儲,比如放在url中
          • 「現(xiàn)在大多都是Session + Cookie」,但是只用session不用cookie,或是只用cookie,不用session在理論上都可以保持會話狀態(tài)。可是實際中因為多種原因,一般不會單獨使用
          • 用session只需要在客戶端保存一個id,實際上「大量數(shù)據(jù)都是保存在服務(wù)端」。如果全部用cookie,數(shù)據(jù)量大的時候客戶端是沒有那么多空間的。
          • 如果只用cookie不用session,那么賬戶信息全部保存在客戶端,一旦被劫持,全部信息都會泄露。并且客戶端數(shù)據(jù)量變大,網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量也會變大

          拓展:token

          token 也稱作令牌,由uid+time+sign[+固定參數(shù)] token 的認(rèn)證方式類似于「臨時的證書簽名」, 并且是一種服務(wù)端無狀態(tài)的認(rèn)證方式, 非常適合于 REST API(表現(xiàn)層狀態(tài)轉(zhuǎn)換) 的場景. 所謂無狀態(tài)就是服務(wù)端并不會保存身份認(rèn)證相關(guān)的數(shù)據(jù)。

          「組成」

          • uid: 用戶唯一身份標(biāo)識
          • time: 當(dāng)前時間的時間戳
          • sign: 簽名, 使用 hash/encrypt 壓縮成定長的十六進制字符串,以防止第三方惡意拼接 固定參數(shù)(可選): 將一些常用的固定參數(shù)加入到 token 中是為了避免重復(fù)查庫

          「存放」

          token在客戶端一般存放于localStorage,cookie,或sessionStorage中。在服務(wù)器一般存于數(shù)據(jù)庫

          token認(rèn)證流程

          token 的認(rèn)證流程與cookie很相似

          • 用戶登錄,成功后服務(wù)器返回Token給客戶端。
          • 客戶端收到數(shù)據(jù)后保存在客戶端
          • 客戶端再次訪問服務(wù)器,將token放入headers
          • 服務(wù)器端「采用filter過濾器校驗」。校驗成功則返回請求數(shù)據(jù),校驗失敗則返回錯誤碼

          token可以抵抗csrf,cookie+session不行

          假如用戶正在登陸銀行網(wǎng)頁,同時登陸了攻擊者的網(wǎng)頁,并且銀行網(wǎng)頁未對csrf攻擊進行防護。攻擊者就可以在網(wǎng)頁放一個表單,該表單提交src為http://www.bank.com/api/transfer,body為count=1000&to=Tom。倘若是session+cookie,用戶打開網(wǎng)頁的時候就已經(jīng)轉(zhuǎn)給Tom1000元了.因為「form 發(fā)起的 POST 請求并不受到瀏覽器同源策略的限制」,因此可以任意地使用其他域的 Cookie 向其他域發(fā)送 POST 請求,形成 CSRF 攻擊。在post請求的瞬間,cookie會被瀏覽器自動添加到請求頭中。但token不同,token是開發(fā)者「為了防范csrf而特別設(shè)計的令牌」,瀏覽器不會自動添加到headers里,攻擊者也無法訪問用戶的token,所以提交的表單「無法通過服務(wù)器過濾」,也就無法形成攻擊。

          分布式情況下的session和token

          負(fù)載均衡多服務(wù)器的情況,不好確認(rèn)當(dāng)前用戶是否登錄,因為多服務(wù)器不共享session。該解決方案是 session 數(shù)據(jù)持久化「寫入數(shù)據(jù)庫或別的持久層」。各種服務(wù)收到請求后,都向持久層請求數(shù)據(jù)。這種方案的優(yōu)點是架構(gòu)清晰,缺點是工程量比較大。另外,持久層萬一掛了,就會單點失敗。

          而token是無狀態(tài)的,token字符串里就「保存了所有的用戶信息」

          客戶端登陸傳遞信息給服務(wù)端,服務(wù)端收到后把用戶信息加密(token)傳給客戶端,客戶端將token存放于localStroage等容器中。客戶端每次訪問都傳遞token,服務(wù)端解密token,就知道這個用戶是誰了。通過cpu加解密,服務(wù)端就不需要存儲session占用存儲空間,就很好的解決負(fù)載均衡多服務(wù)器的問題了。這個方法叫做JWT(Json Web Token)

          Json web token (JWT), 是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn)((RFC 7519).該token被設(shè)計為緊湊且安全的,特別適用于分布式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務(wù)提供者間傳遞被認(rèn)證的用戶身份信息,以便于從資源服務(wù)器獲取資源,也可以增加一些額外的其它業(yè)務(wù)邏輯所必須的聲明信息,該token也可直接被用于認(rèn)證,也可被加密。

          參考:阮一峰 JSON Web Token 入門教程

          總結(jié)

          • session存儲于服務(wù)器,可以理解為一個狀態(tài)列表,擁有一個唯一識別符號sessionId,通常存放于cookie中。服務(wù)器收到cookie后解析出sessionId,再去session列表中查找,才能找到相應(yīng)session所依賴cookie
          • cookie類似一個令牌,裝有sessionId,存儲在客戶端,瀏覽器通常會自動添加。
          • token也類似一個令牌,無狀態(tài),用戶信息都被加密到token中,服務(wù)器收到token后解密就可知道是哪個用戶。需要開發(fā)者手動添加。
          • jwt只是一個跨域認(rèn)證的方案

          如何保護cookie

          Secure和HttpOnly

          Secure屬性意味著把cookie通信限制在加密傳輸中,指示瀏覽器只能通過安全/加密連接使用cookie。然而如果一個web服務(wù)器在非安全連接中給cookie設(shè)置了一個secure屬性,這個cookie在發(fā)送給用戶時仍然可以通過「中間人攻擊」攔截到。因此,為了安全「必須通過安全連接」設(shè)置cookie的Secure屬性。

          HttpOnly屬性指示瀏覽器除了HTTP/HTTPS請求之外不要顯示cookie。這意味著這種cookie不能在客戶端通過腳本獲取,因此也不會輕易的被跨站腳本竊取。

          瀏覽器設(shè)置

          大部分瀏覽器都支持cookie,并且允許用戶禁止掉他們。下面是一些常用的選項:

          • 完全允許或者禁止cookie,以便瀏覽器總是接受或者總是阻止cookie
          • 通過cookie管理器查看或者刪除cookie
          • 徹底清除所有的隱私數(shù)據(jù),包括cookie

          HTTPS中 TLS握手過程簡述

          參考:三元博客 (傳統(tǒng)RSA版本)HTTPS為什么讓數(shù)據(jù)傳輸更安全?

          參考:TLS1.2 握手的過程是怎樣的?

          Koa 中間件 passport

          仿美團項目登錄怎么實現(xiàn)的

          瀏覽器緩存 強緩存 和 協(xié)商緩存 狀態(tài)碼

          結(jié)果

          一面通過

          小獅子有話說

          我是小獅子團隊的【一百個Chocolate】,全網(wǎng)同名,周更的前端博主,分享一些前端技術(shù)干貨與程序員生活日常,歡迎各位小伙伴的持續(xù)關(guān)注,一起變優(yōu)秀~



          學(xué)如逆水行舟,不進則退

          點擊【在看】可能會有紅包福利出現(xiàn)~

          瀏覽 39
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  先锋影音AV资源站 | www.日本色 | 日本男女拍拍视频 | 黄片www在线观看 | 国产精品视频在线免费观看 |