前言
2年工作經(jīng)驗(yàn)的頁(yè)面仔豁辉,最近參加了幾家杭州大廠的面試令野,順利的拿到了自己心儀的offer,積累了一些高頻重點(diǎn)面試題徽级,記錄給有需要的同學(xué)們气破。
我把面試題歸納整理分為兩類,一種是基礎(chǔ)試題: 主要考察前端技基礎(chǔ)是否扎實(shí)餐抢,是否能夠?qū)⑶岸酥R(shí)體系串聯(lián)现使。一種是開(kāi)放式問(wèn)題: 考察業(yè)務(wù)積累,是否有自己的思考旷痕,思考問(wèn)題的方式碳锈。
基礎(chǔ)題
題目的答案提供了一個(gè)思考的方向,答案不一定正確全面欺抗,有錯(cuò)誤的地方歡迎大家請(qǐng)?jiān)谠u(píng)論中指出售碳,共同進(jìn)步。
Q: 怎么去設(shè)計(jì)一個(gè)組件封裝
1. 組件封裝的目的是為了重用,提高開(kāi)發(fā)效率和代碼質(zhì)量
2. 低耦合贸人,單一職責(zé)间景,可復(fù)用性,可維護(hù)性
3. [前端組件化設(shè)計(jì)思路](ijse blog ijser.cn/2017-06-25-…)
Q: js 異步加載的方式
1. 渲染引擎遇到 script 標(biāo)簽會(huì)停下來(lái)灸姊,等到執(zhí)行完腳本拱燃,繼續(xù)向下渲染
2. defer 是“渲染完再執(zhí)行”,async 是“下載完就執(zhí)行”力惯,defer 如果有多個(gè)腳本碗誉,會(huì)按照在頁(yè)面中出現(xiàn)的順序加載,多個(gè)async 腳本不能保證加載順序
3. 加載 es6模塊的時(shí)候設(shè)置 type=module父晶,異步加載不會(huì)造成阻塞瀏覽器哮缺,頁(yè)面渲染完再執(zhí)行,可以同時(shí)加上async屬性甲喝,異步執(zhí)行腳本(利用頂層的this等于undefined這個(gè)語(yǔ)法點(diǎn)尝苇,可以偵測(cè)當(dāng)前代碼是否在 ES6 模塊之中)
Q: css 動(dòng)畫和 js 動(dòng)畫的差異
1. 代碼復(fù)雜度,js 動(dòng)畫代碼相對(duì)復(fù)雜一些
2. 動(dòng)畫運(yùn)行時(shí)埠胖,對(duì)動(dòng)畫的控制程度上糠溜,js 能夠讓動(dòng)畫,暫停直撤,取消非竿,終止,css動(dòng)畫不能添加事件
3. 動(dòng)畫性能看谋竖,js 動(dòng)畫多了一個(gè)js 解析的過(guò)程红柱,性能不如?css 動(dòng)畫好
Q: XSS 與 CSRF 兩種跨站攻擊
1. xss 跨站腳本攻擊,主要是前端層面的蓖乘,用戶在輸入層面插入攻擊腳本锤悄,改變頁(yè)面的顯示,或則竊取網(wǎng)站 cookie嘉抒,預(yù)防方法:不相信用戶的所有操作零聚,對(duì)用戶輸入進(jìn)行一個(gè)轉(zhuǎn)義,不允許 js 對(duì) cookie 的讀寫
2. csrf 跨站請(qǐng)求偽造些侍,以你的名義握牧,發(fā)送惡意請(qǐng)求,通過(guò) cookie 加參數(shù)等形式過(guò)濾
3. 我們沒(méi)法徹底杜絕攻擊娩梨,只能提高攻擊門檻
Q: 事件委托沿腰,目的,功能狈定,寫法
1. 把一個(gè)或者一組元素的事件委托到它的父層或者更外層元素上
2. 優(yōu)點(diǎn)颂龙,減少內(nèi)存消耗习蓬,動(dòng)態(tài)綁定事件
3. target 是觸發(fā)事件的最具體的元素,currenttarget是綁定事件的元素(在函數(shù)中一般等于this)
4.?JavaScript?事件委托詳解
Q: 線程措嵌,進(jìn)程
1. 線程是最小的執(zhí)行單元躲叼,進(jìn)程是最小的資源管理單元
2. 一個(gè)線程只能屬于一個(gè)進(jìn)程,而一個(gè)進(jìn)程可以有多個(gè)線程企巢,但至少有一個(gè)線程(一般情況)
3. 一個(gè)進(jìn)程對(duì)應(yīng)多個(gè)線程最為常見(jiàn)枫慷,Linux、Windows等是這么實(shí)現(xiàn)的浪规。其實(shí)理論上這種關(guān)系并不是一定的或听,可以存在多個(gè)進(jìn)程對(duì)應(yīng)一個(gè)線程,例如一些分布式操作系統(tǒng)的研究使用過(guò)這種方式笋婿,讓線程能從一個(gè)地址空間轉(zhuǎn)移到另一個(gè)地址空間誉裆,甚至跨機(jī)器調(diào)用不同的進(jìn)程入口(感謝AlienZHOU補(bǔ)充)
Q: 負(fù)載均衡
1. 當(dāng)系統(tǒng)面臨大量用戶訪問(wèn),負(fù)載過(guò)高的時(shí)候缸濒,通常會(huì)使用增加服務(wù)器數(shù)量來(lái)進(jìn)行橫向擴(kuò)展足丢,使用集群和負(fù)載均衡提高整個(gè)系統(tǒng)的處理能力
2. 服務(wù)器集群負(fù)載均衡原理?
Q: 什么是CDN緩存
1. CDN 是一種部署策略庇配,根據(jù)不同的地區(qū)部署類似nginx 這種服務(wù)服務(wù)斩跌,會(huì)緩存靜態(tài)資源。前端在項(xiàng)目?jī)?yōu)化的時(shí)候捞慌,習(xí)慣在靜態(tài)資源上加上一個(gè) hash 值滔驶,每次更新的時(shí)候去改變這個(gè) hash,hash 值變化的時(shí)候卿闹,服務(wù)會(huì)去重新取資源
2.?(CDN)是一個(gè)經(jīng)策略性部署的整體系統(tǒng),包括分布式存儲(chǔ)萝快、負(fù)載均衡锻霎、網(wǎng)絡(luò)請(qǐng)求的重定向和內(nèi)容管理4個(gè)要件
3. CDN_百度百科
Q: 閉包的寫法,閉包的作用揪漩,閉包的缺點(diǎn)
1. 使用閉包的目的——隱藏變量旋恼,間接訪問(wèn)一個(gè)變量,在定義函數(shù)的詞法作用域外,調(diào)用函數(shù)
2. 閉包的內(nèi)存泄露奄容,是IE的一個(gè) bug冰更,閉包使用完成之后,收回不了閉包的引用昂勒,導(dǎo)致內(nèi)存泄露
3. 「每日一題」JS 中的閉包是什么蜀细?
4. 閉包造成內(nèi)存泄露的實(shí)驗(yàn)
Q: 跨域問(wèn)題,誰(shuí)限制的跨域戈盈,怎么解決
1. 瀏覽器的同源策略導(dǎo)致了跨域
2. 用于隔離潛在惡意文件的重要安全機(jī)制
3. jsonp 奠衔,允許 script 加載第三方資源
4. nginx 反向代理(nginx 服務(wù)內(nèi)部配置 Access-Control-Allow-Origin *)
5. cors 前后端協(xié)作設(shè)置請(qǐng)求頭部谆刨,Access-Control-Allow-Origin? 等頭部信息
6. iframe 嵌套通訊,postmessage
Q: javascript 中常見(jiàn)的內(nèi)存泄露陷阱
1. 內(nèi)存泄露會(huì)導(dǎo)致一系列問(wèn)題归斤,比如:運(yùn)行緩慢痊夭,崩潰,高延遲
2. 內(nèi)存泄露是指你用不到(訪問(wèn)不到)的變量脏里,依然占居著內(nèi)存空間她我,不能被再次利用起來(lái)
3. 意外的全局變量,這些都是不會(huì)被回收的變量(除非設(shè)置 null 或者被重新賦值)迫横,特別是那些用來(lái)臨時(shí)存儲(chǔ)大量信息的變量
4. 周期函數(shù)一直在運(yùn)行番舆,處理函數(shù)并不會(huì)被回收,jq 在移除節(jié)點(diǎn)前都會(huì)员淫,將事件監(jiān)聽(tīng)移除
5. js 代碼中有對(duì) DOM 節(jié)點(diǎn)的引用合蔽,dom 節(jié)點(diǎn)被移除的時(shí)候,引用還維持
6.?JavaScript?中 4 種常見(jiàn)的內(nèi)存泄露陷阱
Q: babel把ES6轉(zhuǎn)成ES5或者ES3之類的原理是什么
1. 它就是個(gè)編譯器介返,輸入語(yǔ)言是ES6+拴事,編譯目標(biāo)語(yǔ)言是ES5
2. babel 官方工作原理
3. 解析:將代碼字符串解析成抽象語(yǔ)法樹(shù)
4. 變換:對(duì)抽象語(yǔ)法樹(shù)進(jìn)行變換操作
5. 再建:根據(jù)變換后的抽象語(yǔ)法樹(shù)再生成代碼字符串
Q: Promise 模擬終止
1. 當(dāng)新對(duì)象保持“pending”狀態(tài)時(shí),原Promise鏈將會(huì)中止執(zhí)行圣蝎。
2. return new Promise(()=>{});? // 返回“pending”狀態(tài)的Promise對(duì)象
Q: promise 放在try catch里面有什么結(jié)果
1. Promise 對(duì)象的錯(cuò)誤具有冒泡性質(zhì)刃宵,會(huì)一直向后傳遞,直到被捕獲為止徘公,也即是說(shuō)牲证,錯(cuò)誤總會(huì)被下一個(gè)catch語(yǔ)句捕獲
2. 當(dāng)Promise鏈中拋出一個(gè)錯(cuò)誤時(shí),錯(cuò)誤信息沿著鏈路向后傳遞关面,直至被捕獲
Q: 網(wǎng)站性能優(yōu)化
1. http 請(qǐng)求方面坦袍,減少請(qǐng)求數(shù)量,請(qǐng)求體積等太,對(duì)應(yīng)的做法是捂齐,對(duì)項(xiàng)目資源進(jìn)行壓縮,控制項(xiàng)目資源的 dns 解析在2到4個(gè)域名缩抡,提取公告的樣式奠宜,公共的組件,雪碧圖瞻想,緩存資源压真,
2. 壓縮資源,提取公共資源壓縮蘑险,提取 css 滴肿,js 公共方法
3. 不要縮放圖片,使用雪碧圖佃迄,使用字體圖表(阿里矢量圖庫(kù))
4. 使用 CDN嘴高,拋開(kāi)無(wú)用的 cookie
5. 減少重繪重排竿音,CSS屬性讀寫分離,最好不要用js 修改樣式拴驮,dom 離線更新春瞬,渲染前指定圖片的大小
6. js 代碼層面的優(yōu)化,減少對(duì)字符串的計(jì)算套啤,合理使用閉包宽气,首屏的js 資源加載放在最底部
Q: js 自定義事件實(shí)現(xiàn)
1. 原生提供了3個(gè)方法實(shí)現(xiàn)自定義事件
2. createEvent,設(shè)置事件類型潜沦,是 html 事件還是 鼠標(biāo)事件
3. initEvent? 初始化事件萄涯,事件名稱,是否允許冒泡唆鸡,是否阻止自定義事件
4. dispatchEvent? 觸發(fā)事件
Q: angular 雙向數(shù)據(jù)綁定與vue數(shù)據(jù)的雙向數(shù)據(jù)綁定
1. 二者都是 MVVM 模式開(kāi)發(fā)的典型代表
2. angular 是通過(guò)臟檢測(cè)實(shí)現(xiàn)涝影,angular 會(huì)將 UI 事件,請(qǐng)求事件争占,settimeout 這類延遲燃逻,的對(duì)象放入到事件監(jiān)測(cè)的臟隊(duì)列,當(dāng)數(shù)據(jù)變化的時(shí)候臂痕,觸發(fā) $diget 方法進(jìn)行數(shù)據(jù)的更新伯襟,視圖的渲染
3.?vue 通過(guò)數(shù)據(jù)屬性的數(shù)據(jù)劫持和發(fā)布訂閱的模式實(shí)現(xiàn),大致可以理解成由3個(gè)模塊組成握童,observer 完成對(duì)數(shù)據(jù)的劫持姆怪,compile 完成對(duì)模板片段的渲染,watcher 作為橋梁連接二者澡绩,訂閱數(shù)據(jù)變化及更新視圖
Q: get與post 通訊的區(qū)別
1. Get 請(qǐng)求能緩存稽揭,Post 不能
2. Post 相對(duì) Get 安全一點(diǎn)點(diǎn),因?yàn)镚et 請(qǐng)求都包含在 URL 里肥卡,且會(huì)被瀏覽器保存歷史紀(jì)錄溪掀,Post 不會(huì),但是在抓包的情況下都是一樣的召调。
3. Post 可以通過(guò) request body來(lái)傳輸比 Get 更多的數(shù)據(jù),Get 沒(méi)有這個(gè)技術(shù)
4. URL有長(zhǎng)度限制蛮浑,會(huì)影響 Get 請(qǐng)求唠叛,但是這個(gè)長(zhǎng)度限制是瀏覽器規(guī)定的,不是 RFC 規(guī)定的
5. Post 支持更多的編碼類型且不對(duì)數(shù)據(jù)類型限制
Q: 有沒(méi)有去研究webpack的一些原理和機(jī)制沮稚,怎么實(shí)現(xiàn)的
1. 解析webpack配置參數(shù)艺沼,合并從shell傳入和webpack.config.js文件里配置的參數(shù),生產(chǎn)最后的配置結(jié)果蕴掏。
2. 注冊(cè)所有配置的插件障般,好讓插件監(jiān)聽(tīng)webpack構(gòu)建生命周期的事件節(jié)點(diǎn)调鲸,以做出對(duì)應(yīng)的反應(yīng)。
3. 從配置的entry入口文件開(kāi)始解析文件構(gòu)建AST語(yǔ)法樹(shù)挽荡,找出每個(gè)文件所依賴的文件藐石,遞歸下去。
4. 在解析文件遞歸的過(guò)程中根據(jù)文件類型和loader配置找出合適的loader用來(lái)對(duì)文件進(jìn)行轉(zhuǎn)換定拟。
5. 遞歸完后得到每個(gè)文件的最終結(jié)果于微,根據(jù)entry配置生成代碼塊chunk。
6. 輸出所有chunk到文件系統(tǒng)青自。
Q: ES6模塊與CommonJS模塊的差異
1. CommonJs 模塊輸出的是一個(gè)值的拷貝株依,ES6模塊輸出的是一個(gè)值的引用
2. CommonJS 模塊是運(yùn)行時(shí)加載,ES6模塊是編譯時(shí)輸出接口
3. ES6輸入的模塊變量延窜,只是一個(gè)符號(hào)鏈接恋腕,所以這個(gè)變量是只讀的,對(duì)它進(jìn)行重新賦值就會(huì)報(bào)錯(cuò)
Q: 模塊加載AMD逆瑞,CMD荠藤,CommonJS Modules/2.0 規(guī)范
1. 這些規(guī)范的目的都是為了 JavaScript 的模塊化開(kāi)發(fā),特別是在瀏覽器端的
2. 對(duì)于依賴的模塊呆万,AMD 是提前執(zhí)行商源,CMD 是延遲執(zhí)行
3. CMD 推崇依賴就近,AMD 推崇依賴前置
Q: Node 事件循環(huán)谋减,js 事件循環(huán)差異
1. Node.js 的事件循環(huán)分為6個(gè)階段
2. 瀏覽器和Node 環(huán)境下牡彻,microtask 任務(wù)隊(duì)列的執(zhí)行時(shí)機(jī)不同
3. Node.js中,microtask 在事件循環(huán)的各個(gè)階段之間執(zhí)行
4. 瀏覽器端出爹,microtask 在事件循環(huán)的 macrotask 執(zhí)行完之后執(zhí)行
5. 遞歸的調(diào)用process.nextTick()會(huì)導(dǎo)致I/O starving庄吼,官方推薦使用setImmediate()
Q: 淺拷貝和深拷貝的問(wèn)題
1. 深拷貝和淺拷貝是只針對(duì)Object和Array這樣的復(fù)雜類型的
2. 也就是說(shuō)a和b指向了同一塊內(nèi)存,所以修改其中任意的值严就,另一個(gè)值都會(huì)隨之變化总寻,這就是淺拷貝
3. 淺拷貝, ”O(jiān)bject.assign() 方法用于將所有可枚舉的屬性的值從一個(gè)或多個(gè)源對(duì)象復(fù)制到目標(biāo)對(duì)象梢为。它將返回目標(biāo)對(duì)象
4. 深拷貝渐行,JSON.parse()和JSON.stringify()給了我們一個(gè)基本的解決辦法。但是函數(shù)不能被正確處理
開(kāi)放性問(wèn)題
開(kāi)放性問(wèn)題主要是考察候選人業(yè)務(wù)積累铸董,是否有自己的思考矿瘦,思考問(wèn)題的方式刹衫,沒(méi)有標(biāo)準(zhǔn)答案。不過(guò)有些問(wèn)題挺刁鉆的,哈哈哈哈躏精,比如:"? 你見(jiàn)過(guò)的最好的代碼是什么哩至? ",懵逼臉,總之提前準(zhǔn)備下沒(méi)錯(cuò)站蝠。
1. 先自我介紹一下,說(shuō)一下項(xiàng)目的技術(shù)棧卓鹿,以及項(xiàng)目中遇到的一些問(wèn)題
2. 從整體中菱魔,看你對(duì)項(xiàng)目的認(rèn)識(shí),框架的認(rèn)識(shí)和自己思考
3. 項(xiàng)目中有沒(méi)有遇到什么難點(diǎn)减牺,怎么解決
4. 如果你在創(chuàng)業(yè)公司你怎么從0開(kāi)始做(選擇什么框架豌习,選擇什么構(gòu)建工具)
5. 說(shuō)一下你項(xiàng)目中用到的技術(shù)棧,以及覺(jué)得得意和出色的點(diǎn)拔疚,以及讓你頭疼的點(diǎn)肥隆,怎么解決的
6. 一個(gè)業(yè)務(wù)場(chǎng)景,面對(duì)產(chǎn)品不斷迭代稚失,以及需求的變動(dòng)該怎么應(yīng)對(duì)栋艳,具體技術(shù)方案實(shí)現(xiàn)
7. 你的學(xué)習(xí)來(lái)源是什么
8. 你覺(jué)得哪個(gè)框架比較好,好在哪里
9. 你覺(jué)得最難得技術(shù)難點(diǎn)是什么
10. 你見(jiàn)過(guò)的最好的代碼是什么
擴(kuò)展閱讀
一位程序猿面試螞蟻金服后端的經(jīng)驗(yàn)總結(jié)句各!
來(lái)源:https://juejin.im/post/5b9770056fb9a05d2f3692ce