日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

胡哥面试视频手录

發布時間:2023/12/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 胡哥面试视频手录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

胡哥面試視頻手錄

    • 胡哥面試手錄
      • 1. 如何提高工作效率?
      • 2. 面試的時候怎么自我介紹比較好?
      • 3. 面試官問:“你還有什么想問的嗎?”,這個時候該怎么回答?
      • 4. 面試的簡歷,應該從這五大方面去寫:
      • 5. 你的近期和長期的職業規劃是怎樣的?
      • 6. 前端工作中該如何與同事相處、溝通?
      • 7. 面試官問,入職之后將如何開展工作,應該怎么回答?
      • 8. 面試官:對于加班你怎么看?
      • 9. 請描述一下,你以前公司的開發流程是怎么樣的?
      • 10. Web 前端崗位工資的基本構成和發放。
      • 11. 公司面臨一些問題,我們該何去何從?
      • 12. 前端找工作,被公司工資壓價怎么辦?
      • 13. async 和 await 的區別
        • 1. 區別
        • 2. 優點
        • 3. 補充
      • 14. 打包之后 dist 目錄過大,該如何解決
      • 15. 接口安全該如何回答
        • aes加密工具:crypto.js 對稱加密
        • rsa加密工具:jsencrypt 算法
        • 對稱加密與非對稱加密的區別是什么
      • 16. keep-alive
      • 17. vuex 如何回答?
      • 18. 防抖節流
      • 19. 時間復雜度和空間復雜度(非胡哥)
      • 20. webpack的工作原理(打包原理)
        • webpack的核心概念(天禹+熊鍵)
      • 21. 數組扁平化算法
      • 22. setTimeout時間為0_,程序發生了什么?
      • 23. setTimeout時間誤差的解決辦法
      • 24. js面向對象的相關總結
        • es5:
        • es6:
      • 25. 高階函數
      • 26. 瀏覽器引擎Chrome(v8)
      • 27. 瀏覽器是如何渲染頁面的
      • 28. js程序的執行順序是怎樣的?
      • 29. vue-loader的作用
      • 30. node可以通過哪些方法可以防止程序奔潰
      • 31. http 和 https的區別
      • 32. XSS攻擊是什么?如何避免?
      • 33. csrf 攻擊(非胡哥)
      • 34. css hack
      • 35. src和href的區別
      • 36. link和@import的區別?(非胡哥)
      • 37. 胡哥快排
      • 38. 邊界塌陷(外邊距重合)
      • 未完待續。。。

胡哥面試手錄

1. 如何提高工作效率?

我是做前端工作的,我會把工作分為三個部分。

比如說:項目前、項目中期和項目后期。

  • 在項目前期,我們作為前端一定要和 UI 和產品經理進行深度的溝通,爭取把每一個需求都弄明白。這樣做的好處是避免了咱們后邊分工。分工其實是最大的成本的浪費。
  • 項目中期,在項目開始的時候,不僅僅是個人編寫的現有的代碼,我們需要把以前的工具包、插件、組件等等跟工作相關的一系列常用的東西都收集好,這樣在工作中效率就會提高很多。在工作中,先做重要的工作,再做次要的工作,先實現功能,再進行優化,可以避免期限到了功能還沒有實現的局面。
  • 在項目后期,最重要的是項目的維護,以及項目 bug 的修改。在這個過程當中,如果咱們前期和中期弄得不錯,溝通得好、解決得好,那么其實到了項目后期,bug 的出現會明顯的降低。即使產生了,解決速度也會變快。后期一定要和后臺人員進行充分的溝通,把項目爭取用最短的時間部署到咱們的服務器上。
  • 這樣的話,我們在前、中、后期三個節點上面的效率就會得到最大的提升。

    2. 面試的時候怎么自我介紹比較好?

    注:你做自我介紹的時候,興趣愛好、學歷啥的簡歷上都有,不用拿來介紹。

    我叫xxx,我掌握的技能有哪些?如:H5、C3、js、element-plus、node、vue等等。

    在工作中我的打包工具用的是什么?如:webpack、vite。

    我的版本控制工具(分布式)用的是什么?如:git

    說完這些之后,最好加一些,在以前的工作當中,我們前端經常遇到的是什么問題?比如說接口安全的問題、常見的一些攻擊的問題、適配的問題等等。

    3. 面試官問:“你還有什么想問的嗎?”,這個時候該怎么回答?

    在這個時候,對于成熟的前端人員來說的話,想問的相對來說多一些:

  • 咱們公司除了工資以外,還有沒有什么補助?
  • 公司節假日是怎么安排的?
  • 考勤是怎么計算的?
  • 五險一金是怎么來計算的?
  • 咱們公司大概有多少技術部的同事在一起工作?
  • 4. 面試的簡歷,應該從這五大方面去寫:

  • 個人信息:以簡潔明了為主。姓名、學歷、畢業院校、電話、郵箱,不要超過6項。

  • 專業技能:以充實為主。把會的技能多寫上一些。

  • 過往的經歷:過往的公司和時間要搭配,不要有空窗。

  • 項目介紹:一到兩年(包裝2-3個項目)、三年(3-4個項目)。你工作3年就只有這3個項目嗎?回答:我放到簡歷上的項目,是我認為比較好的,其實其他的一些小的項目,有一些雷同的地方,我沒有往上寫,所以從中挑選了基本較好的項目。

    注意點:

  • 一定要有前綴,比如說:京東商城項目。
  • 針對人群,客戶群是什么?
  • 開發項目的周期?(四個月?五個月?)
  • 項目中用到的技術棧有哪些?(vue?三個項目可以都用vue,不是三個項目一定要選擇三個不同的技術棧)
  • 寫完以上四點內容之后,底下要寫150字-200字的項目總述。
  • 最后,再把你項目中的各個模塊,或者你做了哪些模塊,你的崗位職責是什么什么樣的,你做的模塊實現了什么功能?等等這些東西你要寫進去。
  • 自我評價:本人比較善于溝通,團隊協作能力比較強,能夠完成領導交待前端相關的工作任務。

  • 5. 你的近期和長期的職業規劃是怎樣的?

    注意:聊的時候,一定不要跟人家談年限,最近兩年要干什么。。。

    回答:我作為一個前端來說,我近期的職業規劃是把咱們公司的項目做好,另外呢,學無止境,把我的技術得以提升。多學一些組件、插件,多學一到兩款框架。

    對于中長期的規劃來說的話,我打算呢將來我再研究一門后臺語言,比如說像Java、PHP、Python這些我研究一門,爭取研究一門之后,可以更加方便咱們前端跟后端去溝通,為咱們公司更好的去服務。另外呢,我也相信,咱們公司有合理的晉升機制和制度。所以呢,如果將來公司有這樣的機會,這種機會放在我跟前,我也是會毛遂自薦,服務好公司。

    這就是我近期、中期和長期的一個職業規劃。

    6. 前端工作中該如何與同事相處、溝通?

  • 如果工作中遇到問題了,需要和 UI、后臺人員去溝通,那么注意了,如果人間幫助你解決了問題了,那你無論如何下班要請人家吃頓飯,而且馬上就得兌現,俗話說:“報恩不隔夜”。
  • 如果是在平時,UI 那小伙子跟我關系不錯,后臺某個小帥哥跟你關系也不錯,平時怎么和人家溝通呢?盡量組織或者參與一些這樣同事之間的社交活動,以加深同事之間的友誼。
  • 7. 面試官問,入職之后將如何開展工作,應該怎么回答?

  • 如果公司錄用我了,我將會帶著我以前的技術和經驗,把這些東西帶到咱們的項目中,讓咱們的項目更好,更人性化。

  • 我會快速的掌握咱們現在所寫的項目。包括它的路由是怎么架構的,接口的請求是怎么來處理的,還有它里面的一些難點重點的技術,我以前有沒有處理過。
    這些都是我們前端人員在剛入職的時候要做的事情。以避免后邊在開展工作中遇到這些問題,再去處理就比較難處理了。

  • 要考慮我是不是需要后臺或者其他的技術人員去配合,這個也要有一個正確的評估。為啥要評估這個呢?如果問題到了跟前再去跟后臺溝通,這樣的話,很可能會打亂后臺的工作計劃。

  • 進入公司以后,我打算基于以上三個方面開展工作。

    8. 面試官:對于加班你怎么看?

    注意點:

  • 咱們互聯網 IT 公司加班是一種常態,包括有些公司執行的996或者大小周。
  • 咱們國家在 IT 行業,一般來說所有人加班基本上都是免費的。可能在一些少數的一些大公司中加班是有加班費的。
  • 回答:

    我可以接受加班,不管是自己的原因還是其他的一些什么原因,都是可以免費接受的。

    9. 請描述一下,你以前公司的開發流程是怎么樣的?

    在我們公司以前技術部分這么幾個角色:

    產品經理、UI、前端人員、后臺(后臺是一個統稱:Java、PHP、Android、iOS都是在寫后臺的業務邏輯),以上這些角色去進行項目開發。

    前端在項目中的地位和工作流程:

    產品經理: 當一個項目進來,最先跟這個項目客戶去接觸的一般是產品經理,產品經理的作用是:和客戶進行聊天,聊天的過程中,他會做一個產品需求文檔(說白了,就是客戶想要什么?),在這里面有一個重要的職責,有時候客戶很盲目,他不知道自己的需求到底是什么(比如說他想做一個賣菜的網站,他可能不知道什么是APP,但是他們會使用),這個時候產品經理要做的就是正確引導客戶需求。然后,產品經理需要把這些需求跟UI、前端等技術人員去講明白。

    UI: 出了需求文檔之后,產品經理會把文檔給到UI、前端、后臺各一份。UI 把需求文檔做成原型圖(黑白的,像黑白照片)和設計圖,UI在整個工期里面大概要占到三分之一。當設計稿出來后,同時交給前端和后臺,因為基本上前端和后端干活是并行的。

    前端: 開始根據頁面去制作各種各樣的效果。或者是DIA(diagram 圖表)或者是小程序。在這個過程中后臺也在干活。

    后臺: 后臺就要開發它對應的數據管理部分。除此之外,后臺還需要去做 API 接口的東西,這個接口是為前端去開發的。

    等到前端的頁面布局完了,后臺的接口也寫完了,剩下的就是前端去渲染數據,調用接口里面相對應的數據就可以了。這些完了之后,就是一個測試階段。

    測試階段: 測試階段是 UI、前端、后臺都需要參與的,如果有專業的測試,他們的工作量就稍微會少一點。都參與可以保證出現問題可以及時得到處理。

    部署: 測試完成之后,再把這個項目部署到客戶的服務器上去。

    基本上整個工作流程就是這樣子的。

    10. Web 前端崗位工資的基本構成和發放。

    如:10k為例,我上家公司是這樣發放的:

  • 基本工資:5000

  • 崗位工資:如前端 3000

  • 績效工資:2000左右(總工資的15%-20% )

    績效工資是一個考核標準,干得好才有,你負責的部分出了問題會扣一部分或者扣除全部。

  • 補貼補助:1000以內(話補、餐補、車補等等)。

  • 社保公積金:一般情況下公積金+社保占 10%左右。

  • 扣稅:5000以上需要交稅

  • 真正到手的大概是九千左右的一個范圍

    11. 公司面臨一些問題,我們該何去何從?

  • 如果這個時候我走了,我會得到什么,我會失去什么?

    我得到了:我得到的肯定是一份新工作,需要吃飯穿衣嘛這個很正常。

    我失去了:我會失去老板和領導對我的信任,俗話說:“患難見真情”,如果我跟他們共渡難關,在工作中共同努力克服了困難,挺過這一關,那我在這個公司的價值會大大提升。而且我的口碑也會好很多。

  • 每一個員工應該各司其職,盡職盡責把自己的工作做好,做好之后,才能夠讓公司踏踏實實,放心去解決問題。當然在自己的事情完成得很好的情況下,在力所能及的范圍之內去幫助其他的同事。如果一個團隊、一個公司的人都有這樣的想法,我覺得老板和領導一定會想盡辦法去解決公司的困難。

  • 12. 前端找工作,被公司工資壓價怎么辦?

    注:我說15000,HR壓榨成9000

    做兩手準備:

    這個時候跟 HR 去較勁,很大概率是會談崩的。

  • 回復HR:行,咱們公司既然覺得我是值這個價,那肯定是沒有問題的,我也相信我進入公司之后,我會用技術去把咱們的項目做得更好,這個時候我相信公司也會給我漲工資的。
  • 如果入職了,繼續觀望市場,如果有更好的機會擺在面前,立馬跳槽。
  • 13. async 和 await 的區別

    1. 區別

    Async:

    async 用來定義函數的,異步函數,打印函數名會得到一個promise對象。可以使用函數名稱來調用.then方法,如:函數名稱.then

    async 內部實現,有返回值。其實是內部調用了 promise.resolve(),然后把它轉換成一個promise對象。如果出錯的話,調用的是promise.reject()。它用catch捕獲了一下

    Await:

    await 理論上來說后面可以跟任意的表達式。但是一般是跟promise的表達式

    async function add() {const res = await 123console.log(res) // 123return res } console.log(add()) // 成功的promise,值是123

    await 等待后邊的promise對象執行完畢,拿到了promise.resolve()的返回值之后,在往后繼續去執行后邊的代碼,所以await有一個等待的意思。

    await關鍵字只能寫在async的函數里。

    await 后邊的表達式可能是失敗的,await 只能拿到成功的結果,如果失敗會向瀏覽器控制臺拋出錯誤。所以建議把await的代碼放到try…catch語句中捕獲錯誤會比較好。

    async function test() {const res = await Promise.reject(123)return res } console.log(test()) // Uncaught (in promise) 123 async function test() {try {const res = await Promise.reject(123)} catch (error) {console.log('error', error) // 2. error 123} } console.log(test()) console.log(111) // 1. 111

    2. 優點

    • async和await屬于ES2016(ES7)的語法。
    • async和await是異步執行的,但是寫代碼的時候是同步的
    • async和await方式更容易讓開發人員維護

    3. 補充

    promise 和 async await 區別:

    • promise 屬于es6的語法,promise是鏈式調用的
    • promise中包含了catch,而async和await是在函數內自己定義catch
    • promise 提供方法要多一些。如:all, race, any, finally(原型方法), then(原型方法), catch(原型方法)

    ?

    14. 打包之后 dist 目錄過大,該如何解決

    命令:npm run build

    需要在vue.config.js中配置 entry, output

    處理方案:

  • 打包后,會在dist下生成.map文件,那么這個文件其實是不必要的

    解決:在vue.config.js中配置文件中:productionSourceMap: false。這樣就不會生成.map文件了。

  • 使用組件和路由懶加載

    組件和路由懶加載是按需加載的,這樣會降低一些文件的大小。

  • 對于文件和圖片,最好壓縮一下。可以使用這個組件(此組件需要安裝):compression-webpack-plugin

  • 導入組件:compression-webpack-plugin

  • 配置:

    • 最小化代碼配置 minisize(true)
    • 分割代碼 splitChunks
    • 超過限定值的文件進行壓縮 threshold: 文件大小(字節為單位)
  • 15. 接口安全該如何回答

    安全問題是一個很寬泛的問題,如:xss和csrf攻擊等等。

    這里主要談論的是接口的安全問題。

    接口安全:防止傳輸過程中,數據被抓包。我們會在數據傳輸的時候(前臺傳給后臺,后臺傳給前臺)進行加密和解密。

    常用的加密算法:

    aes rsa SHA1 SHA256 md5 … 有很多的算法

    胡哥用過的有 aes rsa

    aes加密工具:crypto.js 對稱加密

    aes加密工具的使用:

  • 安裝:npm i crypto-js –save -dev

  • 在utils工具文件夾下創建crypto.js文件

  • crypto.js中寫入

    import cryptojs from 'crypto-js' export default {encrypto(str) { // 加密// 生成秘鑰// 秘鑰是前端和后端都知道的,但是網絡上是不知道的,所以他們截取去了也沒有用。比如說我們前端生成秘鑰是11111,那么后端也要用11111去解密let key = crytojs.enc.utf8.parse('11111') // 生成偏移量 --- 一般都是傳進來的字符串// 生成偏移量作用:如果字符串內容長度不夠,會自動補齊let srcs = cryptojs.enc.utf8.parse(str)// 加密 --- 參數:偏移量,秘鑰,配置加密的參數let encrypted = cryptojs.AES.encrypt(str,key,{mode: cryptojs.mode.ECB, // 加密模式// ECB 表示等量加密,就是說長度跟你的str相同padding: crytojs.pad.pkcs7 // 加密、解密的標準})return encrypted.toString()},decrypto(str) { // 解密let key = crytojs.enc.utf8.parse('11111') // 解密不需要偏移量// 加密 --- 參數:偏移量,秘鑰,配置加密的參數let decrypted = cryptojs.AES.decrypt(str,key,{mode: cryptojs.mode.ECB, // 加密模式// ECB 表示等量加密,就是說長度跟你的str相同padding: crytojs.pad.pkcs7 // 加密、解密的標準})return decrypted.toString()} }

    注意:

  • 前端不論加密還是解密都是padding: crytojs.pad.pkcs7,而后端是padding: crytojs.pad.pkcs5
  • 秘鑰長度是8的整數倍(8 的倍數)
  • 秘鑰前后端統一
  • 詳細使用步驟看這個文檔,步驟不多
  • rsa加密工具:jsencrypt 算法

    jsencrypt 算法是一種非對稱加密算法,它得生成一對秘鑰,即公鑰和私鑰。前后端一樣的,加密的時候使用公鑰,解密的時候使用私鑰

    長度可以能是1024也可能是2048。已知破解的密碼長度為:768位。

    rsa加密工具的使用:

  • 安裝:npm i jsencrypt

  • 在utils工具文件夾下創建jsencrypt.js文件

  • jsencrypt.js文件中寫入:

    這里是生成公鑰 - 加密

    function enjsencrypt(str) {var jsObj = new jsencrypt()var pubkey = ""jsObj.setPublicKey(pubkey)return jsObj.encrypt(str) }

    這里是生成私鑰 - 解密

    function denjsencrypt(str) {var jsObj = new jsencrypt()var prikey = ""jsObj.setPublicKey(prikey)return jsObj.dencrypt(str) }
  • 詳解博客地址

  • 對稱加密與非對稱加密的區別是什么

  • 對稱加密中加密和解密使用的秘鑰是同一個;非對稱加密中采用兩個密鑰,一般使用公鑰進行加密,私鑰進行解密。
  • 對稱加密解密的速度比較快,非對稱加密和解密花費的時間長、速度相對較慢。
  • 對稱加密的安全性相對較低,非對稱加密的安全性較高。
  • 16. keep-alive

    keep-alive 組件緩存,刷新的時候保持狀態。

    keep-alive 緩存組件,避免組件內的數據重復渲染,直接可以在頁面中調用。

    注意看描述:我有一個導航欄,一級導航欄新聞、房產兩個。二級導航欄,新聞下有體育、財經。我給整個一級導航欄新聞做了組件緩存。如:<keep-alive includes="News"></keep-alive>。

    問題:我先點擊新聞,然后點擊體育,我再點擊房產。當我點擊新聞的時候,我希望它能回到上一次的狀態體育。但是它不會。直接停留到新聞頁面了。

    需求:點擊新聞–》點擊體育–》點擊社會–》回到新聞下的體育頁面

    解決:

    當點擊新聞的時候,有兩個方法會觸發:activated 和 deactivated

    在新聞組件中寫:

    let url; beforeRouteLeave() {url = this.$route.path } activated() {this.$router.push(url) }

    胡哥當前視頻地址

    17. vuex 如何回答?

    vuex存放數據的狀態

    需要安裝:npm i vuex

    state 公共數據 組件中this.$store.state.變量名

    mutations 同步方法 更新state中的數據

    actions 異步方法,組件通過this.$store.dispatch(‘方法名’, 參數)

    getters 讀取state中的數據

    commit 狀態提交,對mutation進行提交

    vuex頁面刷新,數據會重置。這里涉及到持久化的問題

    解決:

  • 把vuex中的數據放到localStorage中

  • 插件vuex-persistedstate 這個插件需要安裝,然后在vuex中添加配置。

    plugins: [createPersistedState({storage: window.sessionStorage })]

    persistedstate 本質是使用了localStorage

  • 18. 防抖節流

    返回頂部:到達一定距離才會出現。

    監聽瀏覽器的滾動時間,返回當前滾動條與頂部的距離。

    <div>里面的內容足夠多,讓其有滾動條出現</div> <script> function showTop() { // 兼容獲取滾動條位置var scrollTop = document.body.scrollTop || document.documentElement.scrollTopconsole.log('滾動條位置', scrollTop) }window.onscroll = showTop <script>

    問題:滾動條滾動時,方法觸發太頻繁

  • 防抖

    第一次觸發事件,不要立即執行,給出一個事件間隔,比如200ms

    <= 200ms 大于等于200毫秒,沒有觸發,那就執行函數

    <= 200ms 大于等于200毫秒,再次觸發滾動,當前的計時取消,重新計時

    思路:如果短時間內,大量執行事件,那就執行一次

    實現:setTimeout + 閉包

    <div>里面的內容足夠多,讓其有滾動條出現</div> <script>function showTop() {// 兼容獲取滾動條位置var scrollTop = document.body.scrollTop || document.documentElement.scrollTopconsole.log('滾動條位置', scrollTop)}function debounce(fnName, delay) { // 實現間隔調用showToplet timer = nullreturn function() {// 1000毫秒以內,這個timer存在了,那么就清除timerif(timer) {clearTimeout(timer)}// 1000毫秒以內,這個timer不存在。setTimeout 返回的是一個ID號,從1開始timer = setTimeout(fnName, delay) // setTimeout(showTop, 1000)} }window.onscroll = debounce(showTop, 1000) </script>
  • 節流

    個人感覺這里用節流會更好(沛華的代碼)

    原理:在一定時間內只執行一次,降低觸發頻率

    實現:閉包

    <div>里面的內容足夠多,讓其有滾動條出現</div> <script>function showTop() {// 兼容獲取滾動條位置var scrollTop = document.body.scrollTop || document.documentElement.scrollTopconsole.log('滾動條位置', scrollTop)} function throttle(fnName, delay) { // 實現間隔調用showToplet lastTime = 0return function() {// 獲取當前時間let nowTime = Date.now()// 如果當前時間 - 上一次的時間 < 傳進來的時間 // 如:100 - 0 < 1000 嗎?如果小于1000,那就直接return了if(nowTime - lastTime < time) {return}// 大于傳進來的時間就會執行下面的代碼fnName.call(this)lastTime = nowTime} }window.onscroll = throttle(showTop, 1000) <script>
  • 19. 時間復雜度和空間復雜度(非胡哥)

    定義:

  • 時間復雜度:指一個算法從開始執行到結束所消耗的時間。
  • 空間復雜度:指對一個算法在運行過程中臨時占用存儲空間大小的一個量度。
  • 20. webpack的工作原理(打包原理)

  • 從入口文件開始出發,根據入口文件的依賴關系找到所有的模塊

  • 調用各種loader進行處理,如果遇到處理不了的調用babel進行語法轉換。(babel-loader core preset)

  • 如果一些功能性的,如壓縮等這個時候就要調用plugins中相應的插件來進行處理

  • 編輯階段 —》根據出口的路徑,打包多個chunk,如果把css和html等都摘出去了,那么就會打包多個chunk,最后統一生成一個bundle

  • loader plugin babel 的區別

    • loader用于處理各種類型文件的
    • plugin是用于loader處理不了的,一些功能性的插件
    • babel 是一個 JavaScript 編譯器。將es6+的語法轉換成瀏覽器所認識的js代碼。babel是一個獨立的工具,可以不在webpack中使用。
  • 工程化:

    狹義上的理解: 將開發階段的代碼發布到生產環境,包含:構建,分支管理,自動化測試,部署

    廣義上理解: 前端工程化應該包含從編碼開始到發布,運行和維護階段

  • webpack的核心概念(天禹+熊鍵)

  • 什么是 webpack(熊鍵)

    • Webpack 是一個模塊打包器(bundler)。
    • 在 Webpack 看來, 前端的所有資源文件(js/json/css/img/less/…)都會作為模塊處理。
    • 它將根據模塊的依賴關系進行靜態分析,生成對應的靜態資源。
  • 五大“護法”(熊鍵)

    • Entry:入口起點(entry point)指示 webpack 應該使用哪個模塊,來作為構建其內部依賴圖的開始。
    • Output: output 屬性告訴 webpack 在哪里輸出它所創建的 bundles,以及如何命名這些文件,默認值為 ./dist。
    • Loader: loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只能解析 JavaScript)。
    • Plugins:插件則可以用于執行范圍更廣的任務。插件的范圍包括,從打包優化和壓縮,一直到重新定義環境中的變量等。
    • Mode:模式,有生產模式 production 和開發模式 development。
  • 理解 Loader

    • Webpack 本身只能加載 JS/JSON 模塊,如果要加載其他類型的文件(模塊),就需要使用對應的 loader 進行轉換/加載。
    • Loader 本身也是運行在 node.js 環境中的 JavaScript 模塊。
    • 它本身是一個函數,接受源文件作為參數,返回轉換的結果。
    • loader 一般以 xxx-loader 的方式命名,xxx 代表了這個 loader 要做的轉換功能,比如 json-loader。

    loader常處理的文件類型(天禹)

    • 【file-loader】:提取源代碼圖片資源,到指定位置,可修改文件名等操作。
    • 【url-loader】:與file-loader功能幾乎一致,優勢是可以對圖片進行動態轉換base64編碼(控制limit屬性值可以控制閾值)。
      備注:上述兩個loader中url-loader應用比file-loader廣泛。
    • 【eslint-loader】:對項目中的js語法進行檢查。
    • 【babel-loader】:將es6語法轉換為es5語法
      備注1:直接使用只能處理簡單的語法,Promise等無法處理。
      備注2:借助polyfill完成高級es6語法的轉換,缺點:所有都轉換,無法按需轉換,生成的js體積大。
      備注3:使用core-js配合polyfill完成按需轉換。

    常用的 loader 有(熊鍵):

    • eslint-loader:審查代碼是否存在語法錯誤。
    • babel-loader:將 es6 以上的語法編譯成 es5 及以下的語法。
    • style-loader:是將 css-loader 打包好的 css 代碼以<style>標簽的形式插入到 html 文件中。
    • css-loader:用于解釋 @import 和 url(),并通過 import 后進行解析,通常和 style-loader 結合使用。
    • less-loader:將 less 語法編譯成 css 語法。

    問題:

    eslint-loader 配置:“0” “1” "2"代表什么?

    • eslint 要想工作,必須定義配置文件,配置文件有兩種寫法
      • .eslintrc.*
      • package.json 文件中 eslintConfig
    • 我們以第一種為例,項目根目錄新建.eslintrc.js
  • plugin常用插件

    • 【extract-text-webpack-plugin】:用于提取項目中的css, 最終合并為一個單獨的文件。

      備注:上述插件需要配合:css-loader、less-loader兩個loader使用,css-loader、less-loader處理之后,交給extract-text-webpack-plugin處理。

    • 【html-webpack-plugin】:自動創建html文件,且自動引入外部資源。配置項如下:

  • title:"webpack", filename:"index.html", template:"./src/index.html" //用于壓縮html minify: {removeComments: true, //移除注釋collapseWhitespace: true } //移除換行
    • 【clean-webpack-plugin】:清空webpack的輸出目錄,防止其他文件“亂入”。

    • 【MiniCssExtractPlugin 】:用于提取css為單獨文件

    21. 數組扁平化算法

    如:let arr = [1, [2], [3], [4]]

    多維數組轉成一維數組,遞歸:逐層遍歷數組,數組的每個元素取出,拼接成新數組

    // 數組扁平化 let arr = [1, [2, [3, [4]]]] // 方法一:使用es6的flat() // console.log(arr.flat(Infinity))// 方法二:使用遞歸 function flat(arr) { let result = [] // 判斷是否傳進來是數組 if (!Array.isArray(arr)) {// 不是數組,就把數據壓入result中result.push(arr) } else {for (let i = 0; i < arr.length; i++) {// console.log(arr[i])// 第一次進來這樣寫:result = result.concat(arr[0])// 第二次進來,又是一個數組,那又得調用flat(),重新從上往下執行函數:result = result.concat(arr[1])result = result.concat(flat(arr[i]))} } return result } console.log(flat(arr))

    視頻鏈接

    22. setTimeout時間為0_,程序發生了什么?

    // setTimeout(fun, 時間) setTimeout(() => {console.log(11) }, 0) console.log(22)

    分析:

    • 代碼從上往下執行,當執行到setTimeout的時候,setTimeout是同步代碼,setTimeout里面的回調是異步代碼。
    • 此時會把setTimeout里面的回到函數放入到計時器管理模塊中。
    • 同步代碼執行完成后,當過了0秒(馬上),會把當前的回調放入到宏隊列中,如果微隊列的代碼執行完成后,會執行宏隊列中的代碼,然后依次執行宏隊列中的定時器回調。

    事件輪詢中有個重要模塊:郎金杰

    • 事件管理模塊
    • 定時器管理模塊。
    • dom 時間管理模塊。
    • ajax 管理模塊。
    • MutationsObserver 管理模塊。
    • 回調對列:
      • 宏任務:
        • setTimeout,setInterval,ajax,dom事件監聽等。
      • 微任務
        • promise中的.then函數,async/await,mutationsobserver等。

    23. setTimeout時間誤差的解決辦法

    setTimeout(fun, 1000) 間隔1000毫秒執行

    代碼的執行:

  • 同步代碼執行時間:會先等待同步代碼執行完成,開始執行異步代碼。

  • 異步代碼執行時間:在執行異步代碼的時候,會有等待的時間,因為要等前面隊列中的代碼都執行完成之后,才會執行這個setTimeout中的回調。

  • 響應時間:比如你在美國訪問了京東setTimeout的倒計時,那么美國看到的京東倒計時一定有問題,響應過去都得3秒至少,setTimeout沒法1秒就執行。

  • 在現實中setTimeout在執行的時候:等待時間 + 執行時間 + 響應時間。所以在現實中執行基本是大于1000毫秒的。

  • 統計誤差時間:

    /* 獲取時間戳的四種方式let start = new Date().valueOf()let start = new Date().getTime()let start = Date.now()let start = +new Date() */ setInterval(() => {let n = 0while (n++ <= 1000000) {} }, 1000) // 統計誤差 // 開始時間 let start = new Date().getTime() // 程序執行的秒數 let count = 0 // 間隔時間 let inits = 1000 let timer = setTimeout(fun, inits)function fun() {count++// 誤差時間 = 現在的時間 - (開始時間 + count * 1000)// 如果 誤差時間 = 計算出來的時間,那就沒有誤差。let errorTime = new Date().getTime() - (start + count * 1000) + 'ms'console.log(errorTime)// 解決思路:誤差時間累加(當誤差達到1000ms之后,不要count++,而是+2)。 }

    24. js面向對象的相關總結

    面向對象(Object Oriented Programming, OOP),是一種編程思想

    es5:

    創建對象:

  • function 函數名(){} ==》new 函數名 ==》得到對象(類的實例對象)

  • 字面量 {}

  • new Object()

  • 面型對象的三大特征:

  • 封裝:將對數據的操作細節隱藏起來,只暴露對外的接口。外界調用不需要(也不可能)知道細節,就能通過對外提供的接口來訪問該對象,同時也保證了外界無法任意更改對象內部的數據

  • 繼承:子類可以繼承父類的屬性和方法

  • 多態:同一個方法,在子類和父類中都可以定義,只是內容不同。

    由繼承而產生了相關的不同的類,對同一個方法可以有不同的響應。比如 Cat 和 Dog 都繼承自 Animal,但是分別實現了自己的 eat 方法。此時針對某一個實例,我們無需了解它是 Cat 還是 Dog,就可以直接調用 eat 方法,程序會自動判斷出來應該如何執行 eat

  • OOP的優勢:

  • 維護方便:采用面向對象思想設計的結構,可讀性高,由于繼承的存在,即使改變需求,那么維護也只是在局部模塊
  • 代碼質量高
  • 模塊化:封裝可以定義對象的屬性和方法的訪問級別,通過不同的訪問修飾符對外暴露安全的接口,防止內部數據在不安全的情況下被修改
  • 易擴展:通過繼承,我們可以大幅減少多余的代碼,并擴展現有代碼的用途
  • **遍歷對象:**for … in

    對象轉化成字符串:

    • {} ==> string 使用 JSON.stringify()

    • string ==> {} 使用 JSON.parse()

    繼承:

  • 構造函數繼承(屬性繼承)

    /* 屬性繼承:在子類調用父類函數,用call改變this指向 */function Father(uname, age){this.uname = uname;this.age = age;console.log('Father-this',this); }// var o = new Father('張三豐', 22); // 這里的this是Father // console.log('o', o);// 繼承 function Son(uname, age, score){// Father(uname, age);這樣寫的this指向不同,此時Father里面的this指向的是window// Father(uname, age);// 如果調用Father函數,并且能夠把Father里面的this指向兒子的實例對象,此時Father中的this指向的是SonFather.call(this, uname, age);this.score = score; }var obj = new Son('erzi', 19, 66); console.log('obj', obj);
  • 原型鏈繼承(方法繼承)

    /*原型鏈:Son.prototype -> Father.prototype -> Object.prorotype -> nullES6中的extends關鍵字實現繼承,底層仍然用的是原型 */// 方法繼承 -- 就是原型繼承 function Father() {Father.prototype.say = function () {console.log('say方法');} }// 繼承 function Son() { } Son.prototype = new Father(); Son.prototype.eat = function () {console.log('吃飯'); }// 如果繼承下來父類的方法,那么要把父類實例對象賦值給子類的原型對象,指回構造函數本身 Son.prototype.constructor = Son;console.log(Son.prototype); console.log(Father.prototype);var obj = new Son(); obj.say(); obj.eat();
  • 組合繼承

    /*1. 原型繼承:繼承屬性和方法,屬性值會重復2. 借用構造函數繼承:繼承屬性,解決屬性值重復的問題,但是父類的方法不會被繼承3. 組合繼承:原型繼承 + 借用構造函數繼承 */function Person(name, age, sex) {this.name = name;this.age = age;this.sex = sex; }; Person.prototype.sayHi = function () {console.log('啊捏哈賽有'); }; function Student(name, age, sex, score) {// 借用構造函數Person.call(this, name, age, sex);this.score = score; }; // 改變原型指向 --- 實現繼承 Student.prototype = new Person(); // 不傳值 Student.prototype.eat = function () {console.log('吃東西'); };// 如果繼承下來父類的方法,那么要把父類實例對象賦值給子類的原型對象,指回構造函數本身 Student.prototype.constructor = Student;var stu = new Student('小黑', 20, '男', 100); console.log(stu.name, stu.age, stu.sex, stu.score); stu.sayHi(); stu.eat();var stu2 = new Student('小黑2', 20, '女', 1010); console.log(stu2.name, stu2.age, stu2.sex, stu2.score); stu.sayHi(); stu.eat();// 這樣就做到了屬性和方法都被繼承了
  • 設計模式:

    沿用了java中的設計模式,一共有23種。

  • 單例模式:一個類只能有一個實例,假如這個實例存在,那么就會沿用當前實例,如果不存在那就創建。
  • 工廠模式:批量創建對象。
  • 觀察者模式:設立一個觀察員或者哨兵,觀察是否有值更新。通過Object.defineProperty方法來修改其它的屬性。
  • 訂閱模式:發布者通過中間層通知那些訂閱者,訂閱者收到通知,然后更新相應的數據變化。
  • es6:

    用class作為類名稱。主要是js向后臺語言靠近。

    static 定義靜態屬性

    constructor 構造函數

    super 父類構造函數,super必須寫在子類的屬性前面

    extends 繼承關鍵字

    25. 高階函數

    定義:指一個函數的參數是函數或者返回值是函數,滿足其中一種情況就算是高階函數。

    funA可以接受funB為參數,那么funA就是一個高階函數。

    // add() 就是一個高階函數 function add(x, y, fun) {return fun(x) + fun(y) }function fun(x) {return Math.abs(x) }console.log(add(-2, 3, fun))

    常見的高階函數:map, reduce, filter, sort

    還有一個函數柯里化的問題:

    定義:柯里化是把接收多個參數的函數轉換成多個只接收一個參數的函數。

    作用:參數復用

    function add(a, b) {return a + b; } add(1, 2) // 3 普通做法 一次傳入兩個參數// 假設有一個 curring 函數可以做到柯里化 function curring(){} curring(1)(2) // 我們通過這樣的方式來接受參數,這樣就實現了柯里化 function curring(x) {return y => x + y // 返回一個函數,然后函數的x+y作為最終的返回值 } curring(1)(2) // => 3

    參數復用:

    // 我們平時的寫法 --- 非參數復用的寫法 function myInfo(inf, name, age) {return `${inf}${name}${age}` } const myInfo1 = myInfo('個人信息', 'ljc', '19') console.log(myInfo1); // 個人信息:ljc19 // 函數柯里化的寫法 --- 參數復用的寫法 復用了inf function myInfoCurry(inf) {return (name, age) => {return `${inf}${name}${age}`} } let myInfoName = myInfoCurry('個人信息') const myInfo1 = myInfoName('ljc', '19') const myInfo2 = myInfoName('ljcc','19') console.log(myInfo2); // 個人信息:ljcc119 console.log(myInfo1); // 個人信息:ljc19

    博客地址

    26. 瀏覽器引擎Chrome(v8)

    v8引擎對內存有限制:

  • v8引擎是對瀏覽器設計的,不太可能大規模使用內存
  • v8垃圾回收也限制了內存
  • nodejs中對v8引擎的內存限制

    • 64位的操作系統是1.4G
    • 32位操作系統是0.7G

    拿官方的一個案例為例,官方是以1.5G內存來進行參考的,1.5G如果要進行垃圾回收,大概是時間是50ms。

    如果node要進行一些大內存對象的操作,可以使用buffer來緩沖對象的內存。因為buffer不受限制,因為buffer基于的邏輯是c++的,c++的內存是不受v8引擎限制的。

    v8 如何來劃分內存和垃圾回收的?

    分代回收機制,新生代和老生代

    新生代老生代
    32位內存大小限制是16M內存大小限制是700M
    64位內存大小限制是32M內存大小限制是1.4G
    適合周期短的對象(如:操作某個DOM對象)。一般短期對象較多,占用80%以上周期長的對象(如:new Vue() , document, window等,它就一直存在)
    垃圾回收采用了Scavenge算法進行操作的。在算法實現時主要采用Cheney算法。Scavenge的缺點:可用內存只有一半,另一半永遠是等待的。Scavenge的優點:只保留活躍的對象,不活躍的就消滅了。就是部分清空。先用Mark-Sweep(標記清除,就是現在不清楚,等下一次進行掃描的時候發現還在,就會被清除掉,內容清除掉后,會留下一個空間),后用Mark-Compact(標記整理,就是把標記清楚后的空間合并起來。)

    27. 瀏覽器是如何渲染頁面的

    cssom: Css Object Model 采用css代碼,并將每個選擇器呈現為樹狀結構,是對css樣式表的對象化表示。同時還提供了api來操作css。

    w3c標準中:

    cssom 包括兩個部分

  • Model:描述樣式表和規則的模型。如style標簽、link標簽都定義了css Model
  • View:和元素視圖相關的api
  • 下面是熊鍵的筆記

  • DNS 查詢/解析
    • 作用:將域名地址解析為 ip 地址
    • 過程:
      • 讀取 4 個緩存
        • 瀏覽器 DNS 緩存
        • 計算機 DNS 緩存
        • 路由器 DNS 緩存
        • 網絡運營商 DNS 緩存
      • 1 個遞歸查詢
        • 13 個根域名服務器
  • TCP 連接:TCP 三次握手
    • 第一次握手:客戶端發起,我將要發送請求了,你準備一下

    • 第二次握手:服務端發起,我知道了,準備好了,放馬過來

    • 第三次握手:客戶端發起,我也知道了,等著

    • 為什么要三次握手?

      • 目的:確保客戶端和服務端收、發能力都是正常的
      • 第一次握手:服務端知道客戶端發送能力是正常的
      • 第二次握手:客戶端知道服務端發送和接受能力是正常的
      • 第三次握手:服務端知道客戶端接受能力是正常的
  • 發送請求
    • 客戶端發送請求給服務器

    • 請求報文

      • 請求首行
        • 請求地址
        • 請求方式
        • 查詢字符串參數
      • 請求頭
        • 攜帶 cookie(cookie)
        • 攜帶 token(authorization)
      • 空行
      • 請求主體
        • 請求體參數(POST)
  • 接收響應
    • 服務端返回響應給客戶端

    • 響應報文

      • 響應首行
        • 響應狀態碼
          • 1xx
          • 2xx
          • 3xx
          • 4xx
          • 5xx
      • 響應頭
        • set-cookie 設置 cookie
        • 緩存 cache-control
      • 空行
      • 響應主體
        • 響應數據
  • 渲染頁面
    • 最開始返回 index.html 頁面,瀏覽器解析 html 文件
    • 遇到 DOM 標記,調用 HTML 解析器,將元素解析 DOM 樹
    • 遇到 css 標記,調用 css 解析器,解析成 CSSOM 樹
      • style 不阻塞
      • link 阻塞(防止閃屏)
    • 遇到 js 標記(script 阻塞),調用 js 引擎,解析 js 代碼
      • 可能會操作 DOM,重新調用 HTML 解析器,將元素解析 DOM 樹
      • 可能會操作 CSS,重新調用 css 解析器,解析成 CSSOM 樹
      • 這個過程就會導致頁面重排重繪
    • 將 DOM 樹和 CSSOM 樹組合生成 render 樹
    • 布局 layout
    • 渲染 render
  • TCP 斷開連接:TCP 四次揮手
    • 斷開 TCP 連接需要 4 次:客戶端發送請求斷開兩次,服務端返回響應斷開兩次
    • 第一次揮手:客戶端發起,客戶端數據發送完畢了,準備斷開了
    • 第二次揮手:服務端發起,服務端數據接收完畢了,可以斷開了
    • 第三次揮手:服務端發起,服務端數據發送完畢了,準備斷開了
    • 第四次揮手: 客戶端發起,客戶端數據接收完畢了,可以斷開了

    28. js程序的執行順序是怎樣的?

    外部js文件先加載還是window.onload先加載?

    外部js文件與body的位置有關

    • 如果js是放在body里,是按照body的先后順序進行加載的。

    • 如果js在body外(一般指head中),是在body加載完畢后,才加載js。

    外部js文件不論是在head中還是在body中,都要優先于window.onload = function(){}執行。如果外部js有定時器等異步代碼,就會滯后執行。

    29. vue-loader的作用

    vue-loader的用法:用來解析和轉換vue文件,提取出其中的script、style、template,把他們交給對應的loader去處理。

    vue-loader的特性:

  • 允許為vue的組件的每個部分去使用其他loader。
  • 允許在vue文件中使用自定義模塊和自定義的loader。
  • 將style和template引用的資源當做模塊依賴處理。為每個這樣的組件,都模擬出一個scope。
  • 在開發過程中允許使用熱重載。
  • 熱重載:"熱重載"不是當你修改文件的時候簡單重新加載頁面。啟用熱重載后,當你修改 .vue 文件時,所有該組件的實例會被替換,并且不需要刷新頁面。它甚至保持應用程序和被替換組件的當前狀態!當你調整模版或者修改樣式時,這極大的提高了開發體驗。

    使用場景:

  • 編譯template將編譯用作vue的template選項,url轉換成webpack的模塊請求。
  • 可以用loader進行預處理(babel scss less等)
  • 可以允許熱重載
  • 30. node可以通過哪些方法可以防止程序奔潰

    node 速度比較快,node是單線程的,不穩定,不適合處理復雜業務。

    單線程,產生未處理異常,會捯飭程序奔潰。

    問題:

    調用了req.params

    let http = require('http') let server = http.creawteServer(function(req, res){let ok = req.params.ok; // params 是undefined。如果是未定義就會導致程序奔潰res.writeHead(200,{'content-type': 'text/plain'})res.end('hello world') }).listen(8080, '127.0.0.1')

    解決方案1:

    uncaughtException 來全局捕獲Error,捕獲之后,可以防止node奔潰 process.on(‘uncaughtException’, function(err){打印錯誤 })

    解決方案2:加上try-catch

    let http = require('http') let server = http.creawteServer(function(req, res){// let ok = req.params.ok; // 把這個未定義的代碼拿到外面去try {handler(req, res)} catch(e) {console.log(e)}res.writeHead(200,{'content-type': 'text/plain'})res.end('hello world') }).listen(8080, '127.0.0.1')let handler = function(req, res) {let ok = req.params.ok; // 同樣是未定義,會報錯 }

    31. http 和 https的區別

    http:

    http(Hyper Text Transfer Protocol) 超文本傳輸協議,用于在瀏覽器和服務器之間傳遞信息的,http協議以明文的形式傳輸內容的,數據是不加密的。不適合傳輸敏感信息。比如:身份證、賬號、密碼等。

    https:

    https:(Hyper Text Transfer Protocol over Secure Socket Layer) 即基于SSL的HTTP協議,簡單地說就是HTTP的安全版。https是在http的基礎上加上了SSL協議。SSL是依靠證書來驗證服務器的身份的,它對瀏覽器和服務器之間通信是加密的。

    https協議是由SSL+ http構成的,是可加密的,身份認證的網絡安全,比http更安全。

    區別:

  • https協議需要Ca(Certificate Authority 數字認證機構)申請證書,一般情況下免費的證書很少,證書是需要費用的。
  • http是明文傳輸的,https是加密傳輸的。
  • 端口不同,http是80,https是443。
  • 32. XSS攻擊是什么?如何避免?

    定義:

    XSS攻擊又叫CSS(Cross Site Script)跨站腳本攻擊。惡意攻擊者往web頁面中插入html代碼,用戶請求該頁面,嵌入其中的該代碼將會被執行,從而達到攻擊用戶的目的。

    一般有三種攻擊類型:

  • 存儲型(這個攻擊危害很嚴重)
  • 反射型
  • DOM型
  • 解決:

  • 對用戶輸入的內容進行過濾,過濾所有的非法字符。
  • html轉義(html轉義是將特殊字符或html標簽轉換為與之對應的字符),內容太多的話要轉義的內容會過多,所以有局限性。
  • 對于鏈接跳轉,要進行內容檢測。如:<a href="xxx"/>
  • 限制輸入長度。
  • 數據進行加密。
  • http only 只允許http請求的方式。
  • 博客地址

    33. csrf 攻擊(非胡哥)

    CSRF概念:CSRF跨站點請求偽造(Cross—Site Request Forgery),跟XSS攻擊一樣,存在巨大的危害性,你可以這樣來理解:

    攻擊者盜用了你的身份,以你的名義發送惡意請求,對服務器來說這個請求是完全合法的,但是卻完成了攻擊者所期望的一個操作,比如以你的名義發送郵件、發消息,盜取你的賬號,添加系統管理員,甚至于購買商品、虛擬貨幣轉賬等。如下:其中Web A為存在CSRF漏洞的網站,Web B為攻擊者構建的惡意網站,User C為Web A網站的合法用戶。

    解決:

    為了防止CSRF攻擊,Token要求不能重復,需要含有時間戳信息、簽名信息。

    如:token = base64(msg)格式化…base64(sha256(“密鎖”, msg))

    token產生:

  • token構成。Token要求不能重復,需要含有時間戳信息、簽名信息。
  • token加密:當用戶向服務提出訪問請求時,產生Token再提交給服務器的時候,服務器需要判斷token的有效性(是否過期,簽名有效)
  • token校驗
    • token解包
    • 比對簽名
    • 判斷時間是否過期
  • 博客地址

    34. css hack

    條件Hack:用來調整頁面的兼容性的。css hack 這個兼容性主要是針對IE來說的,因為IE一開始沒有遵循W3C的標準。

    // 條件Hack的寫法 // if條件共包含6種選擇方式:是否、大于、大于或等于、小于、小于或等于、非指定版本 <!--[if <keywords>? IE <version>?]> HTML代碼塊 <![endif]-->

    兼容性:瀏覽器品牌不同,在解釋css的時候,解釋方式不一樣,所以樣式不兼容的問題。

    注意:盡可能減少對CSS Hack的使用。Hack有風險,使用需謹慎

    博客地址

    35. src和href的區別

    請求資源類型不同

  • href是Hypertext Reference的縮寫,表示超文本引用。用來建立當前元素和文檔之間的鏈接。常用的有:link、a。<link href="reset.css" rel=”stylesheet“/>
  • src是source的縮寫,在請求src資源時會將其指向的資源下載并應用到文檔中,常用的有script、img、iframe。
  • 作用結果不同

  • href 用于文檔和資源之間確立聯系。
  • src 用于替換當前內容。
  • 瀏覽器解析方式不同

  • 用href,瀏覽器會識別該文檔為css文件,就會并行下載資源并且不會停止對當前文檔的處理。
  • 用src,會暫停其他資源的下載和處理,知道將該資源加載、編譯、執行完畢,將所指向資源應用到當前內容。這也是為什么建議把js腳本放在底部而不是頭部的原因。
  • 36. link和@import的區別?(非胡哥)

  • link屬于html標簽,而@import是css提供的。
  • 頁面被加載時,link會同時被加載,而@import引用的css會等到頁面被加載完再加載的。
  • 兼容性問題:@import只在IE5以上才能識別,而link是html標簽,無兼容性問題。
  • 權重問題: @import的權重要高于link。
  • DOM操作: DOM可以操作link中的樣式,而不可以操作@import中的樣式。
  • 37. 胡哥快排

    function quickSort(arr) {if (arr.length < 1) {return arr} // 基準值(得到一個整數) --- 使用Math.floor是為了處理除不盡的情況 let provotIndex = Math.floor(arr.length / 2) // 求得基準值對應的元素 --- 從基準下標開始截取,截取一個 var provot = arr.splice(provotIndex, 1)[0]// 遍歷數組和基準數進行對比 let left = [] let right = [] for (let i = 0; i < arr.length; i++) {if (arr[i] < provot) {left.push(arr[i])} else {right.push(arr[i])} } // console.log(left, right)return quickSort(left).concat([provot], quickSort(right)) } let arr = [2, 3, 4, 5, 3, 2, 1, 5] const result = quickSort(arr) console.log(result)

    38. 邊界塌陷(外邊距重合)

    同時給兄弟/父子設置上下邊距,理論上是兩者之和,實際上只有一半,這種現象叫作邊界塌陷。

    如:給box1的margin-bottom: 20px,給box2的margin-top: 20px; 理論上應該是40的邊距,實際上只有20px的邊距。

    <head><style>.box1 {width: 100px;height: 100px;border: 1px solid red;margin-bottom: 20px;}.box2 {width: 100px;height: 100px;border: 1px solid green;margin-top: 20px;}</style> </head> <body><div class="box1"></div><div class="box2"></div> </body>

    注意:

  • 浮動元素和定位元素是不會發生邊界塌陷的。

  • 這種現象一般發生在塊級元素的垂直方向

  • 解決方案:

    • margin 同為正數或者同為負數的時候,取的是絕對值大的數。

    • 如果一正一負的時候,求的是和,如給box1的margin-bottom: 20px,給box2的margin-top: -20px; 那么最終邊界值為0。

    2022年8月24日10: 17: 30

    未完待續。。。

    總結

    以上是生活随笔為你收集整理的胡哥面试视频手录的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。