先筆試(4頁紙),筆試過程前臺小姐姐會幫你倒一杯咖啡(貼心),再面試(三個面試官轟炸式提問)css
1.js實現數組歸併排序:前端
歸併排序算法是一種分治算法。其主要思想是將原始的數組切分爲較小的數組,直到每一個數組中的元素只有一個位置,接着講小數組歸併爲一個而大的數組,直到最後只有一個大數組。vue
其算法的時間複雜度爲O(nlogn),是一種比較優越的排序算法。webpack
slice() 方法可從已有的數組中返回選定的元素 ;css3
Math.floor(x) 方法是向下取整計算,它返回的是小於或等於x,而且與x最接近的整數;web
shift() 方法用於把數組的第一個元素從其中刪除,並返回第一個元素的值; 面試
push() 方法可向數組的末尾添加一個或多個元素,並返回新的長度; 算法
concat() 方法用於鏈接兩個或多個數組(該方法不會改變現有的數組,而僅僅會返回被鏈接數組的一個副本)。 npm
1 //輔助函數(用來合併和排序小數組來產生大數組) 2 function merge(left, right) { 3 var result = []; 4 while (left.length > 0 && right.length > 0) { 5 if (left[0] < right[0]) { 6 result.push(left.shift()); 7 } else { 8 result.push(right.shift()); 9 } 10 } 11 return result.concat(left).concat(right); 12 } 13 //主要函數(遞歸調用) 14 function mergeSort(arr) { 15 if (arr.length == 1) { 16 return arr; 17 } 18 var middle = Math.floor(arr.length / 2), 19 left = arr.slice(0, middle), 20 right = arr.slice(middle); 21 return merge(mergeSort(left), mergeSort(right)); 22 }
23 var array = [9,8,7,6,5,4];
24 console.log(mergeSort(array));
2.從用戶輸入URL到頁面渲染都經歷了什麼:(經典中的經典)gulp
+DNS解析(實現了網址到IP地址的轉換)
+TCP鏈接
+發送HTTP請求(構建HTTP請求報文並經過TCP協議中發送到服務器指定端口。HTTP請求報文是由三部分組成: 請求行, 請求報頭和請求正文)
+服務器處理請求並返回HTTP報文(HTTP響應報文也是由三部分組成: 狀態碼, 響應報頭和響應報文)
+瀏覽器解析渲染頁面(瀏覽器在收到HTML,CSS,JS文件後,邊解析邊渲染)
reflow(迴流)--DOM節點中的各個元素都是以盒模型的形式存在,這些都須要瀏覽器去計算其位置和大小等,這個過程稱爲relow;
repain(重繪)--當盒模型的位置,大小以及其餘屬性,如顏色,字體,等肯定下來以後,瀏覽器便開始繪製內容,這個過程稱爲repain。
頁面在首次加載時必然會經歷reflow和repain。reflow和repain過程是很是消耗性能的,尤爲是在移動設備上,它會破壞用戶體驗,有時會形成頁面卡頓。因此咱們應該儘量少的減小reflow和repain。
+鏈接結束
3.前端如何優化頁面性能:
+DNS優化(設置DNS多級緩存,DNS負載均衡)
+HTTP(減小HTTP請求)
合併CSS文件,合併JS文件,雪碧圖(將一些小圖片製做成雪碧圖,只會請求一次),緩存(將一些CSS文件或者JS文件緩存下來),減小cookie中沒必要要的信息
+Web優化
CSS--儘可能不要在行內寫CSS ,使用link代替@import ,壓縮CSS,避免使用CSS表達式,CSS寫在HTML文件上部;
JavaScript--JS之外部文件形式引入 ,避免重複的JS代碼,減小JS對DOM的操做,避免無謂的循環,JS代碼(引入鏈接)放在頁面下部 ,壓縮JS代碼
HTML--若是可能減小頁面中的DOM元素
+圖片(圖片使用適當的格式,好比小圖片用GIF PNG8等這樣會減小圖片的大小)
4.如何製做雪碧圖:
photoshop(工做效率過低)
利用在線生成工具生成雪碧圖(https://www.toptal.com/developers/css/sprite-generator)
自動合成法:gulp、fis三、webpack打包合成 (面試官應該想讓你用回答這個)
+webpack打包合成:安裝webpack-spritesmith插件對文件進行打包便可生產css文件和png圖片
安裝webpack-spritesmith(npm i webpack-spritesmith –save-dev)
在webpack.config.js中配置plugins
1 //聲明插件 2 const SpritesmithPlugin = require('webpack-spritesmith'); 3 4 //配置插件 5 plugins:[ 6 new SpritesmithPlugin({ 7 src: { 8 cwd: path.resolve(__dirname,'src/ico'), 9 glob: '*.png' 10 }, 11 target: { 12 image: path.resolve(__dirname,'src/assets/sprites.png'), 13 css: path.resolve(__dirname, 'src/assets/_sprites.css') 14 }, 15 apiOptions: { 16 cssImageRef: './sprites.png' 17 } 18 }) 19 ]
webpack執行打包生成文件路徑‘src/assets’下有兩個文件sprites.png、_sprites.css即爲所得
5.你會切圖嗎
由於公司有美術組,因此不用本身作雪碧圖啊,切圖啊等等(本身真的好想忘記怎麼切圖了!),不過我仍是義正言辭的說:會!(反正只是面試。。。)
6. vue的雙向數據綁定是怎麼實現的
vue.js 是採用數據劫持結合發佈者-訂閱者模式的方式,經過Object.defineProperty()
來劫持各個屬性的setter
,getter
,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調
7. 講一下ES5的原型
在 JavaScript 中,每一個函數對象都有一個prototype屬性,這個屬性指向函數的原型對象。而原型對象他自己就是一個普通對象。
只有函數對象纔會擁有prototype屬性,可是每一個對象都擁有__proto__屬性(null除外)
不管是普通對象仍是函數對象,都有一個叫作__proto__
的內置屬性,用於指向建立它的構造函數的原型對象。當咱們訪問一個對象的屬性時,若是這個對象內部不存在這個屬性,那麼它就會去__proto__裏去找這個屬性,這個__proto__又會有本身的__proto__,因而就這樣一直找下去,這就是原型鏈的概念 (原型鏈的造成是真正是靠__proto__而非prototype)
Object.prototype
對象也有__proto__
屬性,但它比較特殊,爲 null 。由於 null 處於原型鏈的頂端,這個只能記住。
全部函數對象的__proto__都是指向Function.prototype,它是一個空函數;
在默認狀況下,全部的原型對象都會自動得到一個 constructor(構造函數)屬性,這個屬性(是一個指針)指向 prototype屬性所在的函數
8.你瞭解瀏覽器的兼容嗎?(百年老題)
常見兼容性問題:
不一樣瀏覽器的標籤默認的外補丁( margin )和內補丁(padding)不一樣 == css 裏增長通配符 * { margin: 0; padding: 0; }
IE6雙邊距問題;在 IE6中設置了float , 同時又設置margin , 就會出現邊距問題 == 設置display:inline;
當標籤的高度設置小於10px,在IE六、IE7中會超出本身設置的高度 == 超出高度的標籤設置overflow:hidden,或者設置line-height的值小於你的設置高度
圖片默認有間距 == 使用float 爲img 佈局
IE9如下瀏覽器不能使用opacity == opacity: 0.5;filter: alpha(opacity = 50);filter: progid:DXImageTransform.Microsoft.Alpha(style = 0, opacity = 50);
邊距重疊問題;當相鄰兩個元素都設置了margin 邊距時,margin 將取最大值,捨棄最小值 == 爲了避免讓邊重疊,能夠給子元素增長一個父級元素,並設置父級元素爲overflow:hidden;
hand 顯示手型在safari 上不支持 == 統一使用 cursor:pointer
兩個塊級元素,父元素設置了overflow:auto;子元素設置了position:relative ;且高度大於父元素,在IE六、IE7會被隱藏而不是溢出;== 父級元素設置position:relative
9.你日常本身封裝組件嗎?
做爲一名前端工程師,寫組件的能力相當重要(其實就是 面向對象 的能力)
10.你研究過jq源碼嗎?
我沒看過。。。嗚嗚嗚,可是我會裝逼啊(我還沒搞懂,看來我就是初級前端渣渣):
+ jQuery 總體框架(結構十分清晰,採用的是總--分的結構)
閱讀源碼很重要的一點是,摒棄面向過程的思惟方式,不要刻意去追求從上至下每一句都要在一開始弄明白。頗有可能一開始你在一個奇怪的方法或者變量處卡殼了,很想知道這個方法或變量的做用,然而可能它要到幾千行處才被調用到。若是去追求這種逐字逐句弄清楚的方式,頗有可能在碰壁幾回以後閱讀的積極性大受打擊。
+ jQuery 閉包結構
jQuery 具體的實現,都被包含在了一個當即執行函數構造的閉包裏面,爲了避免污染全局做用域,只在後面暴露 $ 和 jQuery 這 2 個變量給外界,儘可能的避開變量衝突。
+ jQuery 無new構造
jQuery.fn.init.prototype = jQuery.fn(這句真的算是 jQuery 的絕妙之處)
jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype ;
new jQuery.fn.init() 至關於 new jQuery() ;
jQuery() 返回的是 new jQuery.fn.init(),而 var obj = new jQuery(),因此這 2 者是至關的,因此咱們能夠無 new 實例化 jQuery 對象。
+ jQuery 方法的重載(方法的重載便是一個方法實現多種功能)
當解讀一個方法的時候感受到了明顯的困難,嘗試着跳出卡殼的那段代碼自己,站在更高的維度去思考這些複雜的邏輯是爲了處理或兼容什麼,是不是重載,爲何要這樣寫,必定會有不同的收穫。
+ jQuery.fn.extend 與 jQuery.extend
extend 方法在 jQuery 中是一個很重要的方法,jQuey 內部用它來擴展靜態方法或實例方法,並且咱們開發 jQuery 插件開發的時候也會用到它。
區分這兩個 extend 方法是理解 jQuery 的很關鍵的一部分。
jQuery.extend(object) 爲擴展 jQuery 類自己,爲類添加新的靜態方法;
jQuery.fn.extend(object) 給 jQuery 對象添加實例方法,也就是經過這個 extend 添加的新方法,實例化的 jQuery 對象都能使用,由於它是掛載在 jQuery.fn 上的方法(jQuery.fn = jQuery.prototype )。
+ jQuery 的鏈式調用及回溯(在要實現鏈式調用的方法的返回結果裏,返回 this ,就可以實現鏈式調用了)
回溯是經過 end() 方法終止在當前鏈的最新過濾操做,返回上一個對象集合。依靠添加了 prevObject 這個屬性(prevObject 保存了上一步的jQuery對象集合)
+ jQuery 正則與細節優化
+ jQuery 變量衝突處理
當須要處理衝突的時候,調用靜態方法 noConflict(),讓出變量的控制權
11.js的變量提高與函數提高
變量提高即將變量聲明提高到它所在做用域的最開始的部分
函數提高(函數聲明式和函數字面量式)只有函數聲明式才存在函數提高!
12.有用ES6作項目嗎
13.css3動畫的兩個屬性
14.會不會用小程序
15. call和apply的區別
apply:調用一個對象的一個方法,用另外一個對象替換當前對象。例如:B.apply(A, arguments);即A對象應用B對象的方法
call:調用一個對象的一個方法,用另外一個對象替換當前對象。例如:B.call(A, args1,args2);即A對象調用B對象的方法
apply:最多隻能有兩個參數——新this對象和一個數組argArray
call:它能夠接受多個參數,第一個參數與apply同樣,後面則是一串參數列表
16. 前端三層分別是
結構層 HTML 從語義的角度描述頁面的結構
樣式層 CSS 從審美的角度裝飾頁面
行爲層 JavaScript 從交互的角度提高用戶體驗