寫在前面的話&前端日常面試問題合集

寫在前面的話

我開始記錄博客的原因?

身爲一個轉行從業IT的社畜,在剛開始小白時期是非常焦慮的,因爲並不是計算機專業出身,在剛開始在記憶和理解程序語言很喫力,所以基本就是面向對象編程(ps:我可不是自己new 出來的 ,驕傲叉腰)和麪向百度編程。

後來,被迫填鴨式的學習過程逐漸變成自主深入學習,慢慢的開始會new對象了,而且還會用,哈哈哈,除了面向百度也會面向谷歌、bing、stackoverflow…

在這個時候,突然就想着記錄一下自己日常工作中遇到的問題,整理自己學習前端開發中的過程。雖然深度也不是很深吧,但是也是竭盡所能(還是要努力啊!),如果自己踩過的坑能幫到別人當然更好了。

所以,纔有了之後的文章。

雖然我不是大佬,但對於其他和我一樣跨行業工作的IT民工,我有一些粗淺的建議:

  • 記錄博客,真的有助於記憶和學習,好記性不如爛筆頭這句老話誠不欺我,現在沒有本子筆,博客就是很好的工具;
  • 非計算機專業在剛開始開發時候確實很不友好,你根本不懂你爲什麼出BUG了,但是,不要害怕,程序開發最後都會轉化爲經驗,下一次你就可以自己獨立解決BUG了;
  • 這個行業學習很重要!而且不是淺顯的學,還需要逐漸深入,知其然也要知其所以然,這也是我記錄博客的一大原因,自己學老是忘記,跟着整理成博客就不會忘;
  • 最後還是加油吧!

我會持續更新,哈哈哈,畢竟人的一生就是在學習成長的過程~

勵志的話結束,剩下部分只記錄自己偶爾日常思考的問題和解決思路,排版什麼的就忽略哈。主要也是面試會問(不然面試過不了,唉,被生活壓彎了腰)!

最後,如果你還有什麼問題或者其他建議給我~可以在評論區裏留言哦 ~當然 ~如果有好的工作也可以推薦給我哦,座標北京!

前端問題

1. position有幾個屬性,各自的體徵是什麼?

relative:相對定位,相對於自身定位。不脫離文本流 。
absolute:絕對定位,相對於父集,如果父集沒有relative,就一層一層往上找,脫離文本流。
fixed:固定定位,相對於視口定位。脫離文本流,不佔位置 。
static:常規流式佈局,不脫離文本流 。
sticky:粘性定位,例:先給父元素設置高度,當父元素滾動100位置時候纔會顯示的。

2. vue中循環爲什麼要使用key?

1.key相當於唯一標識符,在渲染數組的時候,給原數組淺拷貝新增項或者刪除項,如果不加key,可能會出現選擇錯誤的bug。2.更有效的更新dom。
這個原因是:vue更新內層原理使用了diff算法,使用的是虛擬dom樹去一層層對比,就是取出同層結構的前後dom樹對比,如果一樣就更新,如果不一樣就把之前的dom替換掉然後更新。有了標識,就可以更好的定位到位置去操作虛擬dom.

淺顯來說就是:[1,2,3]–>[1,3]刪除了第二項,沒有唯一標識時計算機的理解是:1不變,2變成了3,3被刪除了。有了 key:計算機理解爲把key:2的項刪除了。

基於以上結論,如果是涉及到操作數據,最好不要用index作爲key,因爲索引會隨着數組的改變而改變,簡單的html展示還是可以使用index的。 以上:key == id==唯一標識!

3. cookie和session,還有webStorage之間的區別?各自保存在瀏覽器哪個地方?cookie必須去設置嗎?後臺可以自己去操作cookie嗎?

按功能分

因爲瀏覽器是無狀態的,他不會分辨你是哪個用戶,所以當你訪問一個網站的時候,服務器或客戶端會給你一個標識,你攜帶着這個標識就可以訪問當前網站的其他頁面,也不用登錄或者重新請求標識,或者在你下次訪問網站的時候來根據標識給你推送你之前存儲或瀏覽的一些信息,就好比是用戶的身份證,而這個標識可以分爲三種方式,來完成:

  • cookie客戶端可以去操作設置的標識,把cookie附在http請求頭中發送給服務器,以鍵值對形式存在,如果沒有設置過期時間,則存儲在內存中,瀏覽器關閉cookie就刪除掉。如果設置了過期時間,就存在硬盤中,下次訪問可以直接發送給服務器,直到時間過期。

  • session服務器端來設置標識,當客戶端首次請求的時候,服務器端給當前用戶新建一個session ID,並存儲在客戶端的cookie中,在隨後的請求頭中都攜帶session ID。當客戶端再次訪問網站,如果有這個id,服務器就根據id去操作,沒有則新建id給用戶。

    session存在服務器中,但是如果沒設置cookie失效時間,瀏覽器關閉cookie失效,ses隨即sion失效,但服務器並不會刪除,只是找不到了。但由於關閉瀏覽器不會導致session被刪除,迫使服務器爲session設置了一個失效時間通常爲20分鐘,當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就可以以爲客戶端已經停止了活動,纔會把session刪除以節省存儲空間

    由於:cookie可以被禁止,如果被禁後,可以重寫url,把sessionId拼接到url後。

  • token:是隨着單頁面的發展而出現的產物,當你登錄一個網站,每一個單頁面請求都需要驗證你是不是當前用戶,不是就退出,這樣頻繁驗證的方式很浪費,所以衍生出了token 令牌。
    通俗理解:當你登錄一個網站後,服務器會給當前客戶端簽發一個通行證,客戶端再每一個請求的時候把這個通行證攜帶上,服務器一看你的通行證是正確的,就讓你通過了。(就和進公司門衛看你工牌一樣),通常token存在localStorage或者cookie中

  • cookie和token的比較

    • 狀態:cookie是有狀態的必須同時保存在客戶端和服務器中。token無狀態,服務器只負責簽發和驗證。
    • 跨域:cookie是單域的,a.com和b.com不能共訪問同一個cookie。token可以跨域,服務器只要驗證成功,就可以給你信息。
    • 存儲信息:cookie通常存seesion Id,或者其他鍵值對形式的參數,還有限制,token可以存所有合規的json格式數據。
    • 兼容性:cookie web端支持,移動端部分不支持。token移動端都支持。
    • 安全性:token防止解決csrf 攻擊。cookie不是很安全,別人可以分析存放在本地的cookie並進行cookie欺騙。

按照存儲方式分

cookie:攜帶在請求頭中,單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
sessionStorage:存在本地內存,是用戶從打開回話窗到關閉會話窗這一段時間有效,關閉之後存的數據就會被刪除。
localStorage:存在本地內存,會一直存在瀏覽器中 除非人工清除。

Web Storage擁有setItem,getItem,removeItem,clear等方法。
cookie需要前端開發者自己封裝setCookie,getCookie。

4. csrf 和xss攻擊?

xss,跨站腳本攻擊,是一種代碼注入攻擊。攻擊者通過在目標網站上注入惡意腳本,使之在用戶的瀏覽器上運行。利用這些惡意腳本,攻擊者可獲取用戶的敏感信息如 Cookie、SessionID 等,進而危害數據安全。

csrf ,跨站點請求僞造,攻擊者盜用了你的身份,以你的名義發送惡意請求,對服務器來說這個請求是完全合法的,但是卻完成了攻擊者所期望的一個操作,比如以你的名義發送郵件、發消息,盜取你的賬號,添加系統管理員,甚至於購買商品、虛擬貨幣轉賬等。

5. 如何改變this的指向?

this指向的優先級:new綁定 > 顯式綁定 > 隱式綁定 > 默認綁定
函數引用方式轉化: a(x,y)–>a.call(undefined,x,y), obj.b(x,y)–>obj.b.call(obj,x,y)。
隱式綁定:this的指向通俗理解,就是誰調用它就指向誰。一直往上找,沒有調用就指向window。
顯示綁定:

  • call和apply都是function原型的方法,會直接調用:
    thisArg:this的指向,後續的傳的參數,call是連續,apply是數組。如果參數是數組或者字符串,這兩個方法,會默然把參數轉化爲對象類型。
func.call(thisArg, arg1, arg2, ...)        // call 用法
func.apply(thisArg, [arg1, arg2, ...])     // apply 用法

var number = 1, string = '1111';
function getThisType () {
    var number = 3;
    console.log('this指向內容',this);
    console.log(typeof this);
}
getThisType.call(number);
getThisType.apply(string);
> "this指向內容" 1
> "object"
> "this指向內容" String{"11111"}
> "object"
  • bind 方法:會創建一個函數,函數的第一個參數就是this的指向,之後的一序列參數將會在傳遞的實參前傳入作爲它的參數。
func.bind(thisArg[, arg1[, arg2[, ...]]]) // bind 用法

var publicAccounts = {
    name: '小明',
    author: 'koala',
    subscribe: function(subscriber) {
        console.log(subscriber + this.name)
    }
}

publicAccounts.subscribe('小紅')   // 輸出結果: "小紅 小明"
var obj = { name: '小黃', author: '考拉' }
var subscribe1 = publicAccounts.subscribe.bind(obj, '小剛 ')
subscribe1()  // 小剛 小黃
  • new 構造函數
    1.新建一個對象 2.將新對象的proto指向源對象的prototype,3.執行構造函數內部代碼,4.返回新對象。這樣在構造函數內部就改變了this的 指向。
function study(name){
    this.name = name;
    
}
var studyDay = new study('koala');
console.log(studyDay);
console.log('Hello,', studyDay.name);

在new study(‘koala’)的時候,會改變this指向,將this指向指定到了studyDay對象。
其他:es6箭頭函數中,this總是指向調用函數時上一層運行的對象。而且箭頭函數沒有構造函數,不能用call,bind,apply…

6. requestAnimationFrame和settimeout(0)最快多少ms最慢多少ms?

requestAnimationFrame:電腦顯示器的刷新頻率60hz,每秒刷新60次:1000ms/60 = 16.6ms

settimeout(0):同步代碼結束後,立即執行。HTML5標準規定了setTimeout()的第二個參數的最小值(最短間隔),不得低於4毫秒,如果低於這個值,就會自動增加。在此之前,老版本的瀏覽器都將最短間隔設爲10毫秒。另外,對於那些DOM的變動(尤其是涉及頁面重新渲染的部分),通常不會立即執行,而是每16毫秒執行一次。這時使用requestAnimationFrame()的效果要好於setTimeout()。

7. 從前端角度解析—— 從輸入URL到頁面加載的全過程?

  1. 瀏覽器對這個url 解析,看是本地路徑還是http協議的路徑;
  2. 查瀏覽器內部緩存,系統緩存,路由器(有時候也叫DNS緩存)緩存,看是否需要發送全部請求;
  3. 解析域名,通過DNS服務器解析返回正確的IP地址;
  4. 建立tcp連接,三次握手
  5. 服務器處理http請求,瀏覽器拿到服務器的返回數據
  6. 瀏覽器渲染,如果302或者301重定向就跳轉頁面,重新開始,如果正常渲染,則步驟:
    • 主資源(index.html):解析html字節生成相對應的節點node,關聯起來組成Dom樹
    • 派生資源(index.html中所用到的其他資源):優化點:可以對派生資源使用緩存!
    • css-異步加載css資源,解析生成cssom規則;
    • DOM+CSSOM == Render Tree,瀏覽器對可視的dom樹從根節點開始遍歷匹配對應的css規則從而形成渲染樹;
    • 解析js,動態改變DOM樹;注意:如果把js放在頭部,解析js的時候,瀏覽器就會暫停dom的構建,等js完成後纔會繼續構建DOM樹,嚴重影響到渲染速度,
    • 繪製:遍歷render樹進行佈局映射爲可視的圖形,通常爲流式佈局;
  7. 在渲染的過程中可能會牽扯到:重繪迴流
    • 迴流:瀏覽器窗口變化,滾動條滾動,元素的位置發生變化都會造成迴流,當一個元素變化時,html由於流式佈局,其他元素也跟着變化,這個 重新進行流式佈局就爲迴流。迴流發生在Render樹上。常說的脫離文檔流,就是指脫離渲染樹Render Tree;
    • 重繪:元素視覺相關的屬性改變時,變成了新的樣式,這個過程爲重繪。
    • 優化點:爲了避免迴流和重繪,可以優化:1.不要直接操作dom樣式,而是改變cssname,style;2.對於一個元素進行復雜的操作時,可以先隱藏它,操作完成後再顯示;3.儘量不適用table佈局;4.把多次重繪的元素單獨設置渲染層,比如absolute。

8. 三次握手和四次揮手

三次握手(Tree-Way-Handshake)即建立TCP連接,是指建立一個TCP連接時,需要客戶端和服務端總共發送3個包以確認連接的建立。

客戶端:你能收到我的請求嗎?
服務端:我可以收到,你能聽到我的響應嗎?
客戶端:我可以的,那麼我們現在開始溝通吧。。。

四次揮手(Four-Way Wavehand)即終止TCP連接,就是指斷開一個TCP連接時,需要客戶端和服務端總共發送4個包以確認連接的斷開。在socket編程中,這一過程由客戶端或服務端任一方執行close來觸發。

客戶端:給你我的FIN報文,之後我不再給你發送數據了但是還能接收數據。
服務端:收到,給你簽發我的ACK序號,我已經進入等待關閉狀態,但還有點數據發給你。
。。。
服務端:好了,我也沒數據給你了,給你我的FIN報文,之後我不再給你發送數據了。
客戶端:收到,給你我的ack序號,那我們這次的連接關閉吧!服務端:好嘞!

9. 防抖 & 節流

防抖:利用定時器來延時執行要跑的代碼,頻繁觸發事件的時候,當在時間間隔內又觸發,則清除掉之前的定時器,保證延時處理相關事件。

function debounce(func, wait) {
    let timeout;
    return function () {
        let context = this;
        let args = arguments;
        if (timeout) clearTimeout(timeout);
        
        timeout = setTimeout(() => {
            func.apply(context, args)
        }, wait);
    }
}

節流:一定時間內js代碼只執行一次,多用在頁面滾動效果,或者重複點擊按鈕的時候。

function throttle(func, wait) {
    let previous = 0;
    return function() {
        let now = Date.now();
        let context = this;
        let args = arguments;
        if (now - previous > wait) {
            func.apply(context, args);
            previous = now;
        }
    }
}

10. js數組中去除重複對象及去除空對象的方法

(function(){//去除數組中重複對象
    var unique = {};
    arr.forEach(function(a){ unique[ JSON.stringify(a) ] = 1 });
    arr= Object.keys(unique).map(function(u){return JSON.parse(u) });
    return arr
})(arr)

let newArr=[];//去除空對象
for(let j in arr){
  for(let prop in arr[j]){
      if(prop!=''||arr[j][prop]!=''){
          newArr.push(arr[j]);
      }
  }
};

11. js有幾種數據類型?分別存放在哪裏?理解symbol?

…這裏好像可擴展的東西太多了,專門寫篇文章記錄
https://blog.csdn.net/weixin_43216105/article/details/101024025

12. v8引擎中的垃圾回收機制?

https://blog.csdn.net/weixin_43216105/article/details/101024025

13. canvas和svg的應用場景?

14. vue服務器渲染ssr和單頁面渲染和jsp渲染?

15. Proxy ?

16. defineproperty ?

17. vue2.x和vue 3.0的區別?

18.Vue中計算屬性、方法與偵聽屬性的區別?

Vue中計算屬性、方法與偵聽屬性的區別

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章