一面結束30min後HR打電話通知二面,但我想準備一下,因而約定兩天後參加二面,如下爲部分面試題。html
假設父元素class爲parent,子元素class爲child,以下:前端
1 .parent 2 position: relative 3 .child 4 position: absolute 5 top: 50% 6 left: 50% 7 width: w = 150px 8 height: h = 80px 9 margin-left: -(w / 2) 10 margin-top: -(h / 2)
追問:若是子元素不設置寬高呢?node
1 .parent 2 position: relative 3 .child 4 position: absolute 5 top:50% 6 left:50% 7 transform:translate(-50%,-50%)
或者面試
1 .parent 2 display: flex 3 justify-content:center 4 align-items:center
追問:怎麼判斷文檔內容沒有改變?數據庫
參考連接:https://blog.csdn.net/qq_37960324/article/details/83374855json
客戶端在請求一個文件的時候,發現本身緩存的文件有 Last Modified ,那麼在請求中會包含 If Modified Since ,這個時間就是緩存文件的 Last Modified 。所以,若是請求中包含 If Modified Since,就說明已經有緩存在客戶端。瀏覽器
服務端只要判斷這個時間和當前請求的文件的修改時間就能夠肯定是返回 304 仍是 200 。對於靜態文件,例如:CSS、圖片,服務器會自動完成 Last Modified 和 If Modified Since 的比較,完成緩存或者更新。可是對於動態頁緩存
面,就是動態產生的頁面,每每沒有包含 Last Modified 信息,這樣瀏覽器、網關等都不會作緩存,也就是在每次請求的時候都完成一個 200 的請求。所以,對於動態頁面作緩存加速,首先要在 Response 的 HTTP Header 中增安全
加 Last Modified 定義,其次根據 Request 中的 If Modified Since 和被請求內容的更新時間來返回 200 或者 304 。雖然在返回 304 的時候已經作了一次數據庫查詢,可是能夠避免接下來更多的數據庫查詢,而且沒有返回頁面內服務器
容而只是一個 HTTP Header,從而大大的下降帶寬的消耗,對於用戶的感受也是提升。當這些緩存有效的時候,經過 Fiddler 或HttpWatch 查看一個請求會獲得這樣的結果:
第一次訪問 200
按F5刷新(第二次訪問) 304
按Ctrl+F5強制刷新 200
3. 下面兩段代碼分別輸出什麼?
1 for(var i=0;i<3;i++){ 2 console.log(i); 3 setTimeout(function(){ 4 console.log(i); 5 },0) 6 }
輸出:0 1 2 3 3 3
解釋:setTimeout()是以異步的方式執行的。在執行for循環的時候,並非執行一次for循環就馬上執行一次setTimeout(),而會讓setTimeout()進入另外一條線程進行等待,當主線程(這裏就是for循環)執行完後,setTimeout()再依次
執行。當使用var聲明變量時,i會在全局做用域中找到它的值,此時i爲3。
1 for(let i=0;i<3;i++){ 2 console.log(i); 3 setTimeout(function(){ 4 console.log(i); 5 },0) 6 }
輸出:0 1 2 0 1 2
解釋:let和var不一樣,當使用let聲明變量時,是有塊級做用域的,let聲明的i都會存在於for塊級做用域中,每一次for循環都會生成一個塊級做用域。
追問:如何修改第一段代碼,使其定輸出結果和第二段代碼相同?
調用當即執行函數()()並傳入參數
1 for(var i=0;i<3;i++){ 2 console.log('b'+i); 3 (function fun(i){ 4 setTimeout(function(){ 5 console.log(i); 6 },0) 7 })(i); 8 }
輸出:0 1 2 0 1 2
4.談談本地儲存的過程
參考連接:http://www.javashuo.com/article/p-xlygpowh-hv.html
本地存儲主要有:cookie、localStorage和sessionStorage。利用本地存儲,把一部分數據保存在客戶端,減小對服務器的請求,下降服務器壓力,提高網頁加載速度。
優勢:
(1)給用戶更人性化的使用體驗,如記住「密碼功能」、老用戶登陸歡迎語;
(2)彌補了HTTP無鏈接特性;
(3)站點統計訪問人數的一個依據
缺點:
(1)它沒法解決多人共用一臺電腦的問題,帶來了不安全因素;
(2)Cookie文件容易被誤刪除;
(3)一人使用多臺電腦;
(4)Cookies欺騙。修改host文件,能夠非法訪問目標站點的Cookie;
(5)容量有限制,不能超過4kb;
(6)在請求頭上帶着數據安全性差。
(1)alStorage拓展了cookie的4k限制;
(2)alStorage能夠將第一次請求的5M大小數據直接存儲到本地,相比於cookie能夠節約帶寬;
(3)alStorage的使用也是遵循同源策略的,因此不一樣的網站直接是不能共用相同的localStorage。
(1)須要手動刪除,不然長期存在;
(2)大小不一,版本的支持也不同;
(3)alStorage只支持string類型的存儲,JSON對象須要轉換;
(4)alStorage本質上是對字符串的讀取,若是存儲內容多的話會消耗內存空間,會致使頁面變卡。
5.如何實現一個百度搜索框的功能?怎麼作輸入提示?
參考連接:https://blog.csdn.net/zyf19971112/article/details/82872955
1 function jsonp(url, options) { 2 // 建立script標籤 3 var $script = document.createElement('script'); 4 // 解決緩存問題 5 var f = url.indexOf('?') > - 1 ? '&' : '?'; 6 url += f + '_=' + Date.now(); 7 // 把參數拼接到url上面 8 for(var i in options) { 9 url += '&' + i + '=' + options[i]; 10 } 11 $script.src = url; 12 document.body.appendChild($script); 13 }
1 var baiduInput = (function(){ 2 var timer = null; 3 return { 4 init: function(ele) { 5 this.$ele = document.querySelector(ele); 6 this.$inputSearch = this.$ele.querySelector('input'); 7 this.$listTipsBox = this.$ele.querySelector('.search-list'); 8 this.event(); 9 }, 10 event:function(){ 11 var _this = this; 12 this.$inputSearch.onfocus = function() { 13 // 判斷文本內是否有文字,若是有就顯示下拉框 14 _this.checkInput(); 15 _this.getData(); 16 } 17 this.$inputSearch.oninput = function() { 18 //判斷文本內容爲空, 隱藏下拉框,若是有文字顯示下拉框 19 _this.checkInput(); 20 clearInterval(timer); 21 // 目的: 減小http請求, 下降對服務器的壓力 22 timer = setTimeout(function() { 23 _this.getData(); 24 }, 500) 25 // 根據輸入的內容,獲取下拉框數據, 並渲染到下拉框中 26 }, 27 document.onclick = function(e) { 28 if(e.target !== _this.$inputSearch) { 29 // 若是點擊的不是搜索框, 讓搜索框中的下拉框隱藏 30 _this.listShow(); 31 } 32 } 33 // this.$inputSearch.onblur = function() { 34 // } 35 // 利用事件委託給每個li添加點擊事件 36 this.$listTipsBox.onclick = function(e) { 37 e = e || window.event; 38 var target = e.target || e.srcElement; 39 if(target.nodeName === 'LI') { 40 // 把li上面的文本賦值給文本框 41 _this.$inputSearch.value = target.innerHTML; 42 _this.listShow(); 43 // 隱藏下拉框 44 } 45 } 46 }, 47 listShow: function(val) { 48 val = val || 'none'; 49 this.$listTipsBox.style.display = val; 50 }, 51 checkInput: function(val) { 52 // 獲取文本框的值 53 val = val || this.$inputSearch.value; 54 if(val === '') { 55 this.listShow(); 56 } else { 57 this.listShow('block'); 58 } 59 }, 60 getData: function(val) { 61 if (val === '') return; 62 val = val || this.$inputSearch.value; 63 var params = { 64 wd: val, 65 cb: "baiduInput.insertData" 66 } 67 jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su', params); 68 }, 69 insertData: function(data) { 70 data = data.s; 71 data = data.map(function(x) { 72 return "<li>" + x + "</li>"; 73 }) 74 this.$listTipsBox.innerHTML = data.join(''); 75 // console.log(data); 76 } 77 } 78 }())
函數add同時知足add(a,b)和add(a)(b),且輸出結果爲a+b,如:add(2,3)和add(2)(3)均獲得5。如下是個人代碼:
1 function add(a,b){ 2 if(typeof b=="undefined"){ //或者arguments.length==1 3 return function(b){ 4 return a+b; 5 } 6 }else{ 7 return a+b; 8 } 9 }
10 console.log(add(2,3)); //5
11 console.log(add(2)(3)); //5
追問:若是有傳入多個參數,怎樣實現上述函數。如:add(1)(2)(3)(4)
1 function add(a){ 2 function fun(b){ 3 a+=b; 4 return fun; 5 } 6 fun.toString=function(){ 7 return a; 8 } 9 return fun; 10 }
11 console.log(add(1)(2)(3)(4)); //10
console.log輸出函數時調用其toString方法,給函數fun指定了它本身的toString方法,而且指定了返回值爲a。
看得出來字節跳動很重視基礎,尤爲是原生JS,沒考過框架的問題。因爲接口和搜索框的問題沒回答上,再加上比較緊張有些會的也忘了,致使二面沒過。但我經過這兩次面試增長了經驗,查缺補漏鞏固了知識,仍是頗有收穫。