一面结束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,没考过框架的问题。因为接口和搜索框的问题没回答上,再加上比较紧张有些会的也忘了,致使二面没过。但我经过这两次面试增长了经验,查缺补漏巩固了知识,仍是颇有收获。