写在前面
画个简图
前端面试题
其实没什么好说的,见到一题收一题,尽可能地附有答案,下面的问题都比较基础,如果答不上来,说明你基础确实该提升了
HTML相关
行内和块元素
块:address、 blockquote、 center、 dir、 div、 dl、 fieldset-form、form、 h1~h6、 hr、ol、 p、 pre、 table、 ul等
行内:a、abbr、acronym、b、bdo、bidi、override、big、br、cite、code、dfn、em、font、i、img、input、kbd、label、q、s、samp、select、small、span、strike、strong、sub、sup、textarea、tt、u、var
H5新标签
布局类section、article、aside、footer、header、nav 流媒体audio source video 图形:canvas
HTML标签语义化有何意义
1.利于SEO;2.使得页面在CSS未加载的时候,保持较为明晰的布局结构。
CSS相关
CSS 盒模型的理解
标准模型:content - 内边距 - border - margin,宽高为content尺寸
IE模型:content - 内边距 - border - margin,宽高为content+内边距+边框的 尺寸
box-sizing: content-box按照标准模型设置宽高 border-box按照IE模型设置宽高;
对于一个未知宽高的盒子,如何让它水平垂直居中于父元素
table,flex,grid
浮动有何影响,如何清除:
对一个元素设置float,其父元素无法撑开高度。
<div class="father">
<div class="son">son</div>
</div>
.son {
width:50px;
height:50px;
float:left;
}
最佳方法:对元素添加一个伪元素,加入清除浮动属性:
.son::before{
content:'';
clear:both;
}
flexbox 布局
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool
flex的缺点:浏览器调试工具支持不友好(主要表现为margin上)
CSS3 动画
animation
根据关键帧设置元素的渐变
div
{
animation: letscheckitout 5s;
-webkit-animation: myfirst 5s; /* Safari 与 Chrome */
}
@keyframes letscheckitout
{
0% {background: red;}
25% {background: yellow;}
50% {background: blue;}
100% {background: green;}
}
属性 | 作用 |
---|---|
@keyframes | 声明动画 |
animation | 所有动画属性的简写属性,除了 animation-play-state 属性 |
animation-name | 规定 @keyframes 动画的名称 |
animation-duration | 规定动画完成一个周期所花费的秒或毫秒。默认是 0 |
animation-timing-function | 规定动画的速度曲线。默认是 "ease" |
animation-fill-mode | 规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式 |
animation-delay | 延迟时间。默认是 0 |
animation-iteration-count | 规定动画被播放的次数。默认是 1 |
animation-direction | 规定动画是否在下一周期逆向地播放。默认是 "normal" |
animation-play-state | 规定动画是否正在运行或暂停。默认是 "running" |
transision
对单一属性进行渐变;
transition: 渐变属性 持续时间 变化速度曲线 延迟时间;
transition-property:渐变属性 CSS属性;
transition-duration:持续时间
transition-delay:变化速度曲线
transition-timing-function:延迟时间
其中,变化速度曲线有一下几个属性
transition-timing-function:
linear 恒定速度 等价于cubic-bezier(0,0,1,1)
ease 慢入慢出,中间快速 等价于cubic-bezier(0.25,0.1,0.25,1)
ease-in 慢入 等价于cubic-bezier(0.42,0,1,1)
ease-out 慢出 等价于cubic-bezier(0,0,0.58,1)
ease-in-out 慢入慢出,中间正常速度 等价于cubic-bezier(0.42,0,0.58,1)
cubic-bezier(n,n,n,n) 自定义贝塞尔曲线(参数为2个锚点的X,Y坐标)
http://www.w3school.com.cn/tiy/t.asp?f=css3_transition
div {
width:100px;
transision : width 2s ease;
}
div:hover {
width:300px;
}
DOM相关
浏览器存储方式:cookie、localStoreage和sessionStorage的区别
cookie使用最多且是与服务端通信的主要方式,但是长度有限制,容量小。
sessionStorage和localStorage,IE需要用userData做兼容,容量比cookie大很多session在用户关闭标签/窗口后失效,local关闭浏览器后依然保存,需要手动清除。
事件捕获和事件冒泡
用户点击、移动鼠标等一切事件,DOM元素及其父/子元素都能够监听得到,方式为:
事件捕获:从根元素到目标元素监听
事件冒泡:从目标元素到根元素监听
什么是事件委托,event.target event.currentTarget的区别
假设一个列表,有上百个子元素
<ul>
<li></li>
<li></li>
<li></li>
...100多条
</ul>
如果对每一个li绑定onclick事件,新建了很多函数,开销就会非常大。
使用事件委托方法,对父元素绑定事件,就可以通过target获取当前点击的元素li
ul.addEventListener('click',function(e){
var li = e.target;
})
target与currentTarget的区别:target是当前点击的元素,currentTarget是绑定事件的元素;
为什么移动端浏览普通网页,点击元素会有300毫秒延迟,如何解决
源于Safari浏览器的设定:用户点击后,为了判断用户是否双击缩放还是直接点击,会设置这个300ms延迟,Safari之后,各大主流浏览器都遵从这个约定,设置了延迟;
解决方式:如果禁用双击缩放,那么浏览器将不再检查,所以要将user-scalable=0加入视口meta中
<meta name="viewport" content="user-scalable=0">
除此之外,content的值若要兼容移动端视图,还需要加上width=device-width, initial-scale=1.0, maximum-scale=1.0属性
移动端1px问题
电脑端的1PX,在不同尺寸的移动端显示不一样
解决方式:同样通过视口标签调整
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
JavaScript相关
this的指向
https://www.jianshu.com/p/d0022f7c9e51
面向对象 - 原型链和基于原型链的继承
原型链:https://www.jianshu.com/p/10bb679b9044
继承:https://www.jianshu.com/p/368ca515de5d
什么是闭包
https://www.jianshu.com/p/e1c68bb7ac6e
异步相关
回调:https://www.jianshu.com/p/c8b94eeed75a
手写一个Promise: https://www.jianshu.com/p/d36f6f5f3372
async/await:语法https://www.jianshu.com/p/220b7f3469d5
MicroTask:微任务,如setImmidiate、Promise和nextTick
MacroTask: setTimeout、setInterval
事件循环:Micro/Macro任务全部执行完毕后,才会进行下一轮的任务;
ES6特性
class语法糖、解构赋值、模板语法、箭头函数、拓展运算符、Symbol、Promise、生成器、async/await函数、原生对象新方法如Array.of,Object.assign,新数据结构Set、Map、WeakMap、WeakSet
模块化和工程化
为什么需要模块化
目前浏览器运行的JavaScript没有模块的概念,随着Web应用规模不断扩大,模块的缺乏导致JavaScript代码越来越难以维护。具体表现为:
- 所有的变量、方法都在在全局作用域执行,容易造成变量名冲突
- 不同功能的代码杂糅在一起,难以进行维护
- 依赖关系不明确,即便可以将代码分为多个文件,但是各个功能之间的代码块依然能够相互影响,数据的变化难以追踪
所以我们希望通过模块化,达成一个目的:代码分开写,相互不影响,后期好维护
CommonJS、AMD和CMD标准
CommonJS规范:
随着Node.js的出现,运行在服务端的JavaScript比浏览器端更加复杂,加之Node.js提供了本地文件读取的相关API(fs),让JavaScript模块化成为可能。CommonJS规范具体为:
- 一个文件即是一个模块,例如:
src/
main.js <-入口文件
a.js <-模块a
b.js <-模块b
- 模块的导入需要调用require函数,传入模块名(文件路径或者依赖包名)同步加载
- 通过对
exports
或module.exports
赋值,暴露该模块的数据
AMD规范
浏览器的脚本需要网络请求获取,无法像node.js一般快速、同步加载,这时可以使用AMD(Asynchronous Modules Definition)规范,异步加载代码
require.js是遵循AMD规范的模块导入工具,我们可以在浏览器中引入
<script src="path/to/require.js"></script>
通过调用define定义一个模块,传入当前模块ID,依赖模块ID列表和工厂函数:
define(id?: string,?dependencies: string[], factory: Function)
define('moduleA', ['moduleB'], function(moduleB){
return {
getB :()=>moduleB
}
})
通过调用require函数,加载一个模块:
require(['moduleA','moduleB'],function(moduleA,moduleB) {
// handle moduleA, moduleB
})
CMD(Common Module Definition)
与AMD顶头依赖不同的是CMD遵循就近依赖原则(哪里用到点哪里)
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 依赖可以就近书写
var b = require('./b')
b.doSomething()
})
实现CMD 规范的工具是SeaJS,由玉伯大佬(现蚂蚁金服体验技术部leader)开发。
目前AMD,CMD规范已经逐步淡出模块化的舞台。
为什么需要工程化
- 模块化将代码拆分成许多文件,而运行在浏览器的端的代码却需要减少请求次数
- 人的精力是有限的,如果能通过机器去完成脚手架搭建、打包、发布等重复工作,能节省大量开发者的时间。
总结:工程化的目的是提高开发效率
目前市面上有Grunt、Gulp等构建工具 。现如今,越来越多的开发者选择↓
Webpack
是目前最流行的前端构建工具,能够将本地模块化的html/css/js打包成浏览器能够运行的html/css/js,解决了大型前端项目的几个痛点:
- 将开发代码和线上代码隔离开,开发时可以模块化地编写前端代码,Webpack自动将这些代码块聚合起来,供浏览器运行
- 不仅实现了模块化,通过loader接口和各种插件,使得开发者在开发时可以编写诸如JSX、Vue Template、TypeScript、ES6 module等需要预编译的脚本,甚至是SASS/LESS预编译样式。
- 通过配置,决定哪些文件需要参与构建、哪些需要单独导入,有较强的灵活性
webpack运行原理
https://zhuanlan.zhihu.com/p/52826586
https://zhuanlan.zhihu.com/p/53044886
前端框架
为什么需要框架
- 可以在构建复杂应用时少写很多行代码
- 如果不使用框架,开发者需要操作DOM来更新页面视图。框架能够让开发者专注于自己的业务数据而非过多地操作DOM
- 操作DOM有额外的性能开销,需要一些框架来统一地管理DOM
- 框架的引入,不仅促进了团队开发的统一和规范,同时还提升开发团队效率,更利于后期的维护和管理。
浅谈Vue、React和AngularJS的区别
- AngularJS:由google开发。工具链完整、开箱即用,provider、service和contoller分层的思想与服务端开发接近,缺点:文件体积较大,不适合小微web页面,1代的性能存在一定的问题(2代不深入)。
- ReactJS:由Facebook开发。与Angular不同,仅为view层的框架,使用JSX编写HTML模板,引入了虚拟DOM的思想,从而兼顾了性能和业务专注度,社区生态目前是最丰富的;
- Vue.js:同ReactJS框架一样为view层框架,声明式的HTML模板,轻量级,拓展性强,容易上手
三大框架如何实现数据绑定
并不是这三个框架都使用双向绑定
-
AngularJS:将用户交互事件($ng-click)、定时器($interval/$timeout)和Ajax请求($http)重新封装,调用了这些封装的函数,Angular会调用$apply触发脏检测,接着修改DOM。
-
ReactJS:使用State将数据渲染到试图中,当数据需要变化时调用setState方法,react将决定什么时候重新渲染视图(可以使用forceUpdate强制更新),这也是为什么setState是异步的原因
-
VueJS:通过Object.defineProperty劫持data数据,如此一来对象值发生变化,就会触发getter/setter函数,通React一样,vue也会将这些变化推入更新队列中,由vue自己决定什么时候更新视图(可以调用$nextTick传入更新完毕后的回调)。
Vue3.0:使用Proxy代替Object.defineProperty,O.d对于数组下标元素和length支持有问题
网络相关
如何解决跨域
https://www.jianshu.com/p/eb2f3d92b0ae
HTTP状态码
- 1xx:请求正在处理,一般不会返回给你
- 2xx:请求完成(200表示OK)
- 3xx: 重定向(301永久移动,302临时移动,304协商缓存,305需要代理)
- 4xx: 客户端错误(400参数错误,401授权失败,403拒接响应,404未找到,405请求方法错误,418劳资就是个茶杯 )
- 5xx: 服务端错误(500服务器内部错误,502网关有问题,504网关超时)
HTTP协议 TCP协议和UDP协议的区别
TCP和UDP是网络传输层中应用层的协议,HTTP是TCP的一种。
TCP连接效率低但是稳定,UDP速度快,开销低但不稳定(两者互补)
HTTPS
本质是:本使用非对称算法在客户端/服务端之间协商获得对称密钥
流程:
- client发起https请求
- server将申请过的、包含公钥的证书(CA)返回给client,自己保存私钥
- client通过服务端给的证书,查询CA该公钥是否合法。若合法,就用CA包含的公钥生成一个对称密钥
- clilent将用公钥加密后的对称密钥发给server
- server用私钥解密对称密钥
- server返回对称密钥加密的内容
- client使用对称密钥解密
- 此后客户端/服务端均用对称密钥通信
DNS是什么,用户从输入地址到浏览器返回页面,中间发生了什么
DNS基于UDP协议,是将url地址转换为IP地址的方式。解析方式为递归查询(这家没有找下家)或迭代查询(这级没有找上级)
输入页面 - DNS解析 - 找到目标服务器并发送HTTP请求 - 三次握手传输报文,数据到达链路层 - 服务器接收并响应结果 - 服务器返回内容 - 浏览器开始渲染文档;
网络请求方法
get post put delete等,一般来说,get是获取资源,因为get可以被浏览器自动缓存,post为添加,put为修改,delete为删除。get/delete没有body;post/put有;
性能相关
影响浏览器性能的因素(由高到低)
1.文件体积过大导致请求时间过长或者服务端接口响应过长(后端躺枪)
2.页面重绘与重排
3.过于频繁地访问/修改DOM或者调用其方法。
服务端渲染
服务端通过URL请求,直接返回HTML文档而不是JSON数据,这样做有一下优势:
1.利于SEO(搜索引擎优化)
2.极大提升首屏渲染速度,用户体验较好(网页打开时间消耗较大的是http请求时间)
安全相关
XSS攻击
网站对用户的输入不做任何限制,容易被人注入JavaScript脚本,如发表一则"<script>alert('666')</script>",服务端当成正常的数据保存,当这些数据展示到HTML页面时,这段文字就会当成JavaScript脚本执行。利用这个原理,向网站注入更复杂和危险的脚本,其危害和影响十分巨大。
CSRF攻击
跨站伪造请求。例子:用户登陆银行支付系统,却手贱点开了小广告(钓鱼页面),发起转账请求,钓鱼页面页面抓取该请求并伪造一份请求,如果服务端不做处理,会造成二次甚至多次转账,给用户造成损失。解决方法:token校验、验证码校验、短信校验等。
DDos攻击
使用多台机器,大量且频繁地向目标服务器发送无用请求,目标服务器的资源和带宽被DDos占用,无法处理正常请求甚至瘫痪。
SQL注入
原理通XSS,通过表单输入SQL语句,服务端直接拼接,注入内容当成SQL语句执行导致数据库数据泄露、篡改和删除等。
服务端开发
关系数据库、非关系数据库之间的区别
关系数据库:使用二维表组织、存储数据,遵循ACID原则(原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability)的数据库
代表:Oracle、SQLServer、MySQL、PostgreSQL
非关系数据库:使用key-value存储,数据结构灵活且不需要完全遵循ACID原则的数据库
代表:MongoDB、Redis、Memcache
RESTful接口
RESTful(Representational_state_transfer),是一种API接口的设计规范,参考:
http://www.ruanyifeng.com/blog/2014/05/restful_api.html
网友评论