应用场景
2. border-box属性在form上的使用
当咱们在要作一个登录页面的时候,这时候就须要表单和按钮这些元素
首先咱们在div中设置两个表单,一个用来输入用户名,一个用来输入密码,同时还有一个登陆按钮, 当咱们想让这两个表单和一个登陆按钮的长度相同时,咱们试着把她们三个的width的值设置为100%
但她们的长度并不一致,表单和按钮的padding,border值不统一,这时咱们给表单的属性中添加一个box-sizing:border-box,此时表单和按钮的长度保持一致
当不给表单添加box-sizing:border-box时,而是添加一个padding值会发现表单的长度都有所增长
当给按钮添加padding时,她的长度并不会改变,由此能够看出表单默认为content-box,按钮submit默认为border-box,button的默认值也为border-boxjavascript
border-box属性在盒子中的使用
当咱们设置一个宽度为500px的盒子,在里面放入四个盒子,分别为上(width:100%),中左(width:60%),中右(width:40%),下(width: 100%),此时在大盒子里面四个盒子排列的很整齐
这是咱们给上盒子设置一个padding或者border为5px,这时上盒子的长度就会超出大盒子的宽度,此时咱们给上盒子添加box-sizing:border-box,就可使他的宽度不超出css
说到这里你应该就能看到,box-sizing:border-box这个属性值可使dom元素的padding和border属性值做用于自身,而不对同级的兄弟元素形成影响html
参考连接 box-sizing的使用场景java
flex布局是什么?
flex布局意为弹性布局,任何一个容器均可以指定为flex布局(display: flex
),行内元素也可使用flex布局(display: inline-flex
),webkit内核的浏览器,必须加上(diaplay: -webkit-flex
),设为flex布局后,子元素的float,clear,vertical-align属性将失效node
基本概念
采用flex布局的元素,成为flex容器,她的全部子元素自动成为容器成员,称为flex项目
容器默认存在两根轴,水平的主轴(main axis)和垂直的交叉轴(cross axis),默认沿主轴排列,单个项目占据的主轴空间叫作main sizereact
容器的属性
这6个属性设置在容器上,flex-direction,flex-wrap, flex-flow, justify-content, align-items, align-contentgit
flex-direction决定主轴的方向,即项目排列的方向
flex-direction:row | row-reserve | column | column-reservegithub
flex-wrap决定项目在一条轴线上排不下时,如何换行
flex-wrap: nowrap | wrap | wrap-reserveweb
flex-flow是flex-direction属性和flex-wrap属性的简写,默认为row nowrap面试
justify-content决定项目在主轴上的对齐方式
justify-content: flex-start | flex-end | center | space-between | space-around
align-items决定项目在交叉轴上如何对齐
align-items:flex-start | flex-end | center | baseline | stretch
ailgn-content决定多根轴线的对齐方式,若是项目只有一根轴线,该属性不起做用
align-content: flex-start | flex-end | center | space-between | space-around | stretch
项目的属性 这6个属性设置在项目上,order,flex-grow,flex-shrink,flex-basis,flex,algin-self
order定义项目的排列顺序,数值越小,排列越靠前,默认为0
order:<integer
>
flex-grow定义项目的放大比例,默认为0,即若是存在剩余空间,也不放大
flex-grow:<number
>
若是全部项目的flex-grow属性都为1,则他们将等分剩余空间(若是有的话)
flex-shrink定义项目的缩小比例,默认为1,即若是空间不足,该项目将缩小
flex-shrink: <number
>
若是一个项目的flex-shrink属性为0,其余项目为1,则空间不足时,前者不缩小
flex-basis定义项目在分配多余空间以前,项目占据的主轴空间,默认为auto,能够设置为width或height同样的值
flex-basis:<length
> | auto
flex属性是flex-grow,flex-shrink,flex-basis的简写,默认为0 1 auto
默认存在两个快捷值auto(1,1,auto)和none(0,0,auto)
align-self容许单个项目和其余项目不同的对齐方式,可覆盖align-items属性,默认值为auto
align-self:auto | flex-start | flex-end | center | baseline | stretch
参考连接 flex布局教程:语法篇
参考连接 flex布局教程:实战篇
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
复制代码
display: flex;
align-items: center;
justify-content: center;
复制代码
display: table;(父)
display: table-cell;(子)
text-align: center;
vertical-align: middle;
复制代码
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
复制代码
参考连接 未知宽高元素水平居中
javascript函数的new关键字究竟是干什么的
不用建立临时对象,由于new会帮你作
不用绑定原型,由于new会帮你作
不用return临时对象,由于new会帮你作
不要给原型想名字了,由于new指定名字为prototype
对象与原型链(__proto__和prototype)
每一个JS对象必定对应一个原型对象,并从原型对象继承属性和方法
对象__proto__属性的值就是他所对应的原型对象
只有函数才有prototype属性,当你建立函数时,JS会为这个函数自动添加prototype属性,值是一个有constructor属性的对象,不是空对象,而一旦你把这个函数看成构造函数调用时,那么JS就会帮你建立该构造函数的实例,实例继承构造函数prototype的全部属性和方法
对象的__proto__指向本身构造函数的prototype
Object.prototype是原型链的顶端,Object自己是构造函数,继承了Function.prototype,Function也是对象,继承了Object.prototype
Object.prototype.proto === null,说明原型链到Object.prototype终止
null表示‘没有对象’,即此处不应有值
Function自己就是函数,Function.__proto__是标准的内置对象Function.prototype,而Function.prototype.__proto__是标准的内置对象Object.prototype
构造函数和原型
原型:每个JS对象(除null外)在建立的时候就会与之关联另外一个对象,这个对象就是咱们说的原型,每一个对象都会从原型继承属性
proto:每个JS对象(除null外)都具备的一个属性,叫__proto__,这个属性会指向该对象的原型
constructor:每个原型都有一个constructor属性指向关联的构造函数
参考连接 js的new究竟是干什么的
参考连接 从__proto__和prototype来深刻理解JS对象和原型链
参考连接 javascript深刻之从原型到原型链
参考连接 从探究Function.proto===Function.prototype过程当中的一些收获
html中直接绑定
html中绑定事件叫作内联绑定事件,不利于分离
js中直接绑定
js中直接绑定称为赋值绑定函数,缺点是只能绑定一次
addEventListener
target.addEventListener(type, listener[, useCapture])
target表示要监听事件的目标对象,能够是一个文档上的元素DOM自己,Window或者XMLHttpRequest
type表示事件类型的字符串
listener为当指定的事件类型发生时被通知到的一个对象
useCapture为设置事件的捕获或者冒泡
true为捕获,false为冒泡(默认)
addEventListener能够给同一个dom元素绑定多个函数,而且执行顺序按照绑定顺序执行,且执行顺序与useCapture无关
给一个dom元素绑定同一个函数,最多只能绑定useCapture类型不一样的两次
addEventListener只支持到IE9,为兼容性考虑,在兼容IE8及一下浏览器能够用attachEvent函数,和addEventListener函数表现同样,但它绑定函数的this会指向全局
事件的解绑
经过dom的on***属性设置的事件,能够用dom.onclick = null
来解绑
经过addEventListener绑定的事件可使用removeEventListener来解绑,接受参数同样
对于使用removeEventListener函数解绑事件,须要传入的listener,useCapture和addEventListener彻底一致才能够解绑事件
事件冒泡
事件开始时由最具体的元素接受,而后逐级向上传播到较为不具体的节点
事件捕获
事件捕获的思想是不太具体的DOM节点应该更早接收到事件,而最具体的节点应该最后接收到事件,与事件冒泡顺序相反
DOM事件流
DOM事件流包括三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,首先发生的是事件捕获,为截获事件提供机会,而后是实际的目标接受事件,最后一个阶段是事件冒泡阶段,能够在这个阶段对事件做出响应
stopPropagation()和stopImmediatePropagation()
stopPropagation()既能够阻止事件冒泡,也能够阻止事件捕获,也能够阻止处于目标阶段
stopImmediatePropagation()既能够阻止事件冒泡,也能够阻止事件捕获,还会阻止该元素其余事件的发生
参考连接 从一个事件绑定提及-DOM
http2.0和http1.1的区别
由于全部的http2的请求都在一个TCP链接上,因此在http1中的自动化合并文件和Sprite合图等资源合并减小请求的优化手段对于http2来讲是没有效果的
二进制分帧
http2在应用层和传输层之间增长一个二进制分帧层,http2会将全部传输的信息分割成更小的消息和帧,并对他们采用二进制格式的编码,其中http1的首部信息会被封装成Headers帧,而咱们的request body则封装到Data帧里面
首部压缩
http请求和响应都是由状态行,请求/响应头部,消息主题三部分组成,通常而言,消息主题都会通过gzip压缩,或者自己传输的就是压缩后的二进制文件,但状态行和头部却没有通过任何压缩,直接以纯文本传输,浪费流量资源
原理:头部压缩须要在支持http2的浏览器和服务端之间,维护一份相同的静态字典,包含常见的头部名称与值的组合,维护一份相同的动态字典,能够动态的添加内容,支持基于静态哈夫曼码表的哈夫曼编码
http2支持服务器推送
服务端推送是一种在客户端请求以前发送数据的机制,当代网页使用了许多资源:html,样式表,脚本等,在http1.x中这些资源每个都必须明确的请求,这多是一个很慢的过程,由于服务器必须等待浏览器作的每个请求,网络常常是空闲和未充分使用的
为了改善延迟,http2引入了server push,它容许服务端推送资源给浏览器,在浏览器明确请求以前,一个服务器常常知道一个页面须要更多的附加资源,在他响应浏览器第一个请求时,能够开始推送这些资源,这容许服务端去彻底充分利用一个可能空闲的网络,改善页面加载的时间
有了http2的服务端推送,http1时代的内嵌资源的优化手段也变得没有意义了,使用服务端推送更高效,由于客户端能够缓存起来,甚至能够不一样页面之间共享
并行双向字节流的请求和响应
在http2上,客户端和服务端能够把http消息分解成回不依赖的帧,而后乱序发送,最后再在另外一端把她们从新组合起来,同一连接上能够有多个不一样方向上的数据在传输,客户端能够一边乱序发送stream,也能够一边接收着服务端的响应,在服务端同理
把http消息分解为独立的帧,交错发送,而后在另外一端从新组装是http2最重要的一项加强,这个机制会在整个web技术栈中引起一系列的连锁反应,从而带来巨大的性能提高,由于
http2的请求优先级
每一个http2流里面有个优先值,这个优先值肯定着客户端和服务端处理不一样的流采起不一样的优先级策略,高优先级的流应该优先发送,但又不是绝对的准守,可能又会引入首队阻塞的问题,高优先级的请求慢致使阻塞其余文件的交付,分配处理资源和客户端与服务器间的带宽,不一样优先级的混合是必须的
https
http协议传输的数据都是未加密的,也就是明文的,所以使用http协议传输隐私信息很是不安全,为了保证这些隐私数据能加密传输,因而网景公司设计了SSL协议用于对http协议传输的数据进行加密,从而诞生了https,如今的https使用的都是TSL协议
https在传输数据以前须要客户端和服务端之间进行一次握手,在握手的过程当中将确立双方加密传输数据的密码信息,TSL/SSL协议不只仅是一套加密传输的协议,TSL/SSL中使用了非对称加密,对称加密以及hash算法
握手过程:
浏览器将本身支持的一套加密规则发送给网站
网站从中选出一组加密算法和hash算法,并将本身的身份信息以证书的形式发回给浏览器,证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息
得到网站证书后浏览器要作如下工做
网站接收浏览器发来的数据以后要作如下工做
浏览器解密并计算握手信息的hash,若是与服务端发来的hash一致,此时握手过程结束,以后全部的通讯数据将由以前浏览器生成的随机密码并利用对称加密算法进行加密
这里浏览器与网站互相发送加密的握手信息并验证,目的是为了保证双发都得到了一致的密码,而且能够正常的加密解密数据
其中非对称加密算法用于在握手过程当中加密生成的密码,对称加密算法用于对真正传输的数据进行加密,而hash算法用于验证数据的完整性
因为浏览器生成的密码是整个数据加密的关键,所以在传输的时候使用了非对称加密算法对其进行加密,非对称加密算法会生成公钥和私钥,公钥只能用于加密数据,所以能够随意传输,而网站的私钥用于对数据进行解密,因此网站都会很是当心的保管本身的私钥,防止泄漏
TSL握手的过程当中若是有任何错误,都会使加密链接断开,从而阻止了隐私数据的传输,正是因为https很是的安全,攻击者没法从中找到下手的地方,因而更多的是采用了假证书的手法来欺骗客户端,从而获取明文信息
webSocket概述
http协议是一种无状态的协议,要实现有状态的会话必须借助一些外部机制如session和cookie,这或多或少或带来一些不便,尤为是服务端和客户端须要实时交换数据的时候
webSocket容许服务器和客户端进行全双工通讯,传统的http是单工通讯的,它只容许客户端向服务端发出请求,服务端被动返回数据,而不能主动向客户端传递数据
webSocket的请求头部
Connection: Upgrade //通讯协议提高
Upgrade: websocket //传输协议升级为websocket
Sec-WebSocket-Key: ********** //握手协议密钥,base64位编码的16字节的随机字符串
复制代码
webSocket的响应头部
Connection: Upgrade //通讯协议提高
Upgrade: websocket //传输协议升级为websocket
Sec-WebSocket-Accept: ********** //将客户上报的Sec-WebSocket-Key和一段GUID(258EAFA5-E914-47DA-95CA-C5AB0DC85B11)进行拼接,再将这个拼接的字符串作SHA-1 hash计算,而后再把获得的结果经过base64加密,最后再返回给客户端
复制代码
WebSocket,ajax轮询和long poll
参考连接 http2.0协议你应该准备的面试题
参考连接 面试时如何优雅的谈论http
参考连接 http2.0的奇妙平常 参考连接 浅谈WebSocket协议及其实现
说说对洗牌算法的理解和如何验证其正确性
洗牌算法以前没了解过,刚面到的时候好蒙,闲话很少说,这里说下洗牌算法的js实现
Fisher-Yates
这是最经典的洗牌算法,其算法思想是从原数组中随机抽取一个新的元素到新数组中
从还没处理的数组(假如还剩n个)中,产生一个[0,n]之间的随机数random
从剩下的n个元素中把第random个元素取出到新数组中
删除原数组第random个元素
重复第2 3步直到全部的元素取完
最终返回一个新的打乱的数组
代码实现
function shufle(arr){
var result = [],
random;
while(arr.length > 0){
random = Math.floor(Math.random() * arr.length);
result.push(arr[random])
arr.splice(random, 1)
}
return result;
}
复制代码
这种算法的时间复杂度是O(n2)
参考连接 洗牌算法的js实现
参考连接 Fisher–Yates shuffle 洗牌算法
说一下你对事件委托和事件代理的理解?
什么是事件委托?它还有一个名字叫事件代理,JavaScript高级程序设计上讲:事件委托就是利用事件冒泡,只指定一个事件处理程序,就能够管理某一类型的全部事件,当咱们须要对不少元素添加事件的时候,能够经过事件添加到他们的父节点二将时间委托给父节点来触发处理函数
为何要使用事件委托?
通常来讲,dom须要有事件处理程序,咱们都会直接给它设置事件处理程序就行了,那若是是不少的dom须要添加事件处理呢?好比咱们这里有100个li,每一个li都有相同的click事件,那么咱们会用for循环的方法来遍历全部的li,而后给他们添加事件,那么这样会存在什么问题呢?
在JavaScript中,添加到页面上的事件处理程序的数量将直接关联到页面总体的运行性能,由于须要不断的与dom节点进行交互,访问dom的次数越多,引发浏览器重绘与重排的次数就越多,就会延长整个页面交互就绪时间,这就是为何性能优化的主要思想是减小dom操做的缘由,若是使用事件委托,就会将全部的操做放到js程序里面,与dom的操做就只须要交互一次,这样就能大大的减小与dom的交互次数,提升性能
每一个函数都是一个对象,是对象就会占用内存,内存占用率就越大,天然性能就差了,好比上面的100个li,就要占用100个内存空间,若是是1000个,10000个呢,若是使用事件委托,那么咱们就能够只对它的父级这一个对象(若是只有一个父级)进行操做,这样咱们就须要一个内存空间就够了,是否是省了不少,天然性能就会更好
事件委托的原理?
事件委托是利用事件的冒泡机制来实现的,何为事件冒泡呢?这里介绍下浏览器dom事件处理的过程,dom2.0模型将事件流程分为三个阶段:事件捕获阶段,事件目标阶段,事件冒泡阶段。
事件捕获:当某个元素触发某个事件,顶层对象document就会发出一个事件流,随着dom树的节点向目标元素节点流去,直到到达事件真正发生的目标元素,在这个过程当中,事件相应的监听函数是不会被触发的
事件目标:当到达目标元素以后,执行目标元素该事件相应的处理函数,若是没有绑定监听函数,那就不执行
事件冒泡:从目标元素开始,往顶层元素传播,途中若是有节点绑定了相应的事件处理函数,这些函数都会被一次触发,若是想阻止事件冒泡,可使用event.stopPropgation()或者event.cancelBubble=true来阻止事件的冒泡传播
事件委托怎么实现:
Event对象提供了一个属性叫target,能够返回事件的目标节点,咱们称为事件源,也就是说,target就能够表示为当前事件操做的dom,可是不是真正操做的dom,固然,这个是有兼容性的,标准浏览器用event.target,IE浏览器用event.srcElement,此时知识获取了当前节点的位置,并不知道是什么节点名称,这里咱们用nodeName来获取具体是什么标签名,这个返回的是一个大写的,通常转化为小写再进行比较
若是你想将事件委托给父元素来处理,但每一个子元素的事件内容又不相同时,这里咱们能够给每一个子元素添加一个惟一的key来做标识,而后在父元素中对其进行分别的处理
const list = document.querySelector('#list) const lists = list.querySelector('#list > li')
for(let i=0; i<lists.length; i++){
lists[i].dataset.key = 'list-' + i
}
list.addEventListener('click',function(e){
const event = e || window.event
const target = event.target || event.srcElement
if(target.nodeName.toLocaleLowerCase() === 'li'){
switch(target.dataset.key){
case 'list-1':
do something-1
break
case 'list-2':
do something-2
break
...
default:
do something-3
break
}
}
})
复制代码
参考连接 JavaScrip事件代理和委托
参考连接 JS的事件委托和事件代理详解
说一下你对css重绘和重排的理解,两个有什么不一样?
这一题考的实际上是网页性能的问题,咱们先理解下对网页性能产生影响到因素,了解下网页是怎么生成的
网页生成的过程,大体能够分为五步:
在这五步里面,第一步和第三步都很是快耗时的是第四步和第五步
其中生成布局flow和绘制paint这两步,合称为渲染render
重绘和重排
网页生成的时候,至少会渲染一次,用户访问的过程当中,还会不断的从新渲染
如下三种状况,会致使网页从新渲染
从新渲染,就须要从新生成布局和从新绘制,前者叫作重排reflow,后者交货重绘repaint
须要注意的是,重绘不必定须要重排,好比改变某个网页元素的颜色,就只会触发重绘,不会触发重排,由于布局没有改变,可是,重排必定会致使重绘,好比改变一个网页元素的位置,就会同时触发重排和重绘,由于布局改变了
对于性能的影响
重绘和重排会不断触发,这是不可避免的,可是,他们是很是耗费资源的,是致使网页性能低下根本缘由
要提升网页性能,就是要下降重排和重绘的频率和成本,尽可能少触发从新渲染
提升性能的九个技巧
参考连接 网页性能管理详解
大概就这些吧,从年后初八面试到如今,磕磕碰碰花了挺多精力的,前段时间过了腾讯三面,让我等hr电话,欣喜若狂的觉得能进鹅厂了,等了一个多礼拜,杳无音信,处处找人问,获得的结果是等四月中下旬的校招再通知我面试,瞬间一盆冷水浇下来,我基础比较差,算法功底也不强,自知够不上大厂的门,认了,本身本事不够,怨不得别人,这段时间在v2ex这个社区收获挺多的,写篇本身的面经给你们看看,各位都是大佬,有什么写错的地方,多多指教,不喜勿喷,谢谢