web前端常见面试题总结
1.为何选择前端这个方向?
- 对前端很感兴趣,之前也接触过其他语言,但是直到接触前端才发现真的有兴趣做下去,兴趣是一个人最好的老师。
- 前端很有前途,像现在node.js,rn,微信小程序这类工具和框架可以让前端进行后端和移动开发,所以我觉得前端的前途会更多一点。
2.谈谈你对前端的理解?
- 目前前端工程师最核心的技能还是:Html,CSS,JS。前端负责的是用户可以看到的部分,所以也是最接近用户的工程师,同时在产品研发流程中前端要同时与产品,设计,后端等很多人合作。
3.Vue双向数据绑定的实现?
- vue.js则是采用数据劫持结合开发者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者(文本节点则是作为订阅者),在收到消息后执行相应的更新操作。
4.react和vue有哪些不同,说说你对这两个框架的看法?
- 都用了virtual dom 的方式,性能都很好
- ui上都是组件化写法,开发效率很高
- vue是双向数据绑定,react是单项数据绑定,当工程规模比较大时双向数据绑定会很难维护
- vue适合不会持续的小型web应用,使用vue.js能带来短期内较高的开发效率,否则采用react
5.let和const的区别?
- let声明的变量可以改变,值和类型都可以改变,没有限制。
- const声明的变量不得改变值
6.平时用了es6的那些特性?
- let,const,箭头函数,字符串模板,class类,模板化promise
7.浏览器原生支持module吗?如果支持会带来那些遍历?
8.介绍一下你对webpack的理解,和gulp有什么不同?
- Webpack是模块打包工具,他会分析模块间的依赖关系,然后使用loaders处理它们,最后生成一个优秀化并且合并后的静态资源。
- gulp是前端自动化工具,能够优化前端工作流程,比如合并压缩。
9.Webpack打包速度慢,你觉得可能的原因是什么?该如何解决模块太多?
- Webpack可以配置externals来将依赖库指向全局变量,从而不再打包这个库
10.http响应中content-type包含哪些内容?
请求中的消息主体是用何种方式编码
application/x-www-form-urlencoded
这是最常见的 POST 提交数据的方式 按照 key1=val1&key2=val2 的方式进行编码
application/json
告诉服务端消息主体是序列化后的 JSON 字符串
11. position:absolute和float属性的异同?
- 共同点 :对内联元素设置float和absolute属性,可以让元素脱离文档流,并且可以设置其宽高。
- 不同点 :float仍可占据位置,不会覆盖在另一个BFC区域上,浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。absolute会覆盖文档流中的其他元素。
12:平时是怎么学新技术的
13:Node,Koa用的怎么样
- koa是一个相对于express来说,更小,更健壮,更富表现力的Web框架,不用写回调
- koa是从第一个中间件开始执行,遇到next 进入下一个中间件,一直执行到最后一个中间件,在逆序async await 语法的支持
14:使用模块化加载时,模块加载的顺序是怎样的,如果不知道,根据已有的知识,你觉得顺序应该是怎么样的
- commonjs 同步 顺序执行
- AMD 提前加载,不管是否调用模块,先解析所有模块 requirejs 速度快 有可能浪费资源
- CMD 提前加载,在真正需要使用(依赖)模块时才解析该模块 seajs 按需解析 性能比AMD差
15: 介绍一下闭包和闭包常用场景
- 闭包是指有权访问另一个函数作用域中的变量的函数. 创建闭包常见方式,就是在一个函数内部创建另一个函数.
- 应用场景 设置私有变量和方法
- 不适合场景:返回闭包的函数是个非常大的函数
- 闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
16: 为什么会出现闭包这种东西,解决了什么问题
- 受JavaScript链式作用域结构的影响,父级变量中无法访问到子级的变量值,为了解决这个问题,才使用闭包这个概念
17: 介绍一下你所了解的作用域链,作用域链的尽头是什么,为什么
- 每一个函数都有一个作用域,比如我们创建了一个函数,函数里面又包含了一个函数,那么现在 就有三个作用域,这样就形成了一个作用域链。
- 作用域的特点就是,先在自己的变量范围中查找,如果找不到,就会沿着作用域链往上找。
18: 简述Ajax的过程?,主要用到哪些状态码
- 创建XMLHttpRequest对象,也就是创建一个异步调用对象.
- 创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
- 设置响应HTTP请求状态变化的函数.
- 发送HTTP请求.
- 获取异步调用返回的数据.
- 使用JavaScript和DOM实现局部刷新.
当前状态readystate
0 代表未初始化。 还没有调用 open 方法
1 代表正在加载。 open 方法已被调用,但 send 方法还没有被调用
2 代表已加载完毕。send 已被调用。请求已经开始
3 代表交互中。服务器正在发送响应
4 代表完成。响应发送完毕
常用状态码status
404 没找到页面(not found)
403 禁止访问(forbidden)
500 内部服务器出错(internal service error)
200 一切正常(ok)
304 没有被修改(not modified)(服务器返回304状态,表示源文件没有被修改)
18:对自己未来的规划是怎样的
- 对于刚毕业的人来说,前两年是很重要的,先打好基础,多提升js能力。三至四年在提升JS能力的同时,开始要往多方面发展,前端工程师远远不仅是JS而已。制作一个性能高、交互好、视觉美的页面,需要从前端框架选型、架构设计、构建工具,到后端通信机制、设计与交互、网络和浏览器优化等各方面的知识。一专多长才是前端工程师的终极目标。
19: 说说你知道JavaScript的内存回收机制
- 垃圾回收器会每隔一段时间找出那些不再使用的内存,然后为其释放内存。
- 一般使用标记清除方法 当变量进入环境 标记为进入环境,离开环境标记为离开环境
- 还有引用计数方法
- 堆栈
- stack 为自动分配的内存空间,它由系统自动释放;而 heap 则是动态分配的内存,大小不定也不会自动释放。
- 基本数据类型存放在栈中
- 引用类型 存放在堆内存中, 首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据
20:UMD规范和ES6模块化,Commonjs的对比
- CommonJS是一个更偏向于服务器端的规范。用于NodeJS 是同步的
- AMD是依赖前置的
- CMD推崇依赖就近,延迟执行。可以把你的依赖写进代码的任意一行
- AMD和CMD都是用difine和require,但是CMD标准倾向于在使用过程中提出依赖,就是不管代码写到哪突然发现需要依赖另一个模块,那就在当前代码用require引入就可以了,规范会帮你搞定预加载,你随便写就可以了。但是AMD标准让你必须提前在头部依赖参数部分写好(没有写好? 倒回去写好咯)。这就是最明显的区别。
- UMD写一个文件需要兼容不同的加载规范
ES6通过import 、export 实现模块的输入输出。其中import命令用于输入其他模块提供的功能,export命令用于规定模块的对外接口。
21:http请求头
- get post delete put head options trace connect
- OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法
22.框架问题
什么是 MVVM , 和 MVC 是什么区别, 原理是什么?
- mvc的界面和逻辑关联紧密,数据直接从数据库读取,必须通过Controller来承上启下,通信都是单向的。mvvm的View 和 ViewModel可以互相通信,界面数据从viewmodel中获取。
父子组件怎么通信的?
- vue:父组件是通过props属性给子组件通信 ,子组件是通过$emit,$on通信
- react:props传递 父给子传一个回调函数 将数据传给父亲处理
兄弟组件怎么通信的?
- vuex 建立一个vue实例 emit触发事件 on监听事件
redux 子A -> 父 -> 子B
生命周期有哪些, 怎么用?
- beforecreated :el 和 data 并未初始化
- created :完成了 data 数据的初始化,el没有
- beforeMount :完成了 el 和 data 初始化
- mounted :完成挂载 updated;destroyed
- react:初始化阶段、运行中阶段、销毁阶段
- 初始化getDefaultProps() 和getInitialState()初始化
- componentWillMount() 在组件即将被渲染到页面render() 组件渲染
- componentDidMount() 组件被渲染到页面上,
- 运行中shouldComponentUpdate() componentWillUpdate() render() componentDidUpdate()
- 销毁componentWillUnmount()
23:清除浮动
(1)、利用clear属性进行清理
具体的实现原理是通过引入清除区域,这个相当于加了一块看不见的框把定义clear属性的元素向下挤
父容器结尾插入空标签
利用CSS伪元素:
.clearfix:after {
content: ".";
height: 0;
visibility: hidden;
display: block;
clear: both;
}
通过将这个类添加到父容器当中,会在父容器的末尾增加了一个高度为0、具有清除属性的、不可见的块级元素。
(2)、将父容器形成BFC
BFC能清理浮动主要运用的是它的布局规则:
- 内部的Box会在垂直方向,一个接一个地放置。
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box重叠。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算
浮动清理利用的主要是第六条规则,只要将父容器触发为BFC,就可以实现包含的效果。
那么触发BFC有哪几种方法?
1.根元素
2.float属性不为none
3.position为absolute或fixed
4.display为inline-block, table-cell, table-caption, flex, inline-flex
5.overflow不为visible
24.前端性能优化
- 减少http请求 使用sprite图、合并js和css文件
- 使用cdn 将用户安排在近的服务器上
- 使用缓存 缓存ajax 使用外部的css和js以便缓存 使用expire cach-control etag
- 压缩资源 使用gzip压缩js和css文件
- 代码层面 避免使用样式表达式、通配符选择器、样式放在顶部、脚本放在底部
25.事件模型和事件代理
- 事件三个阶段:事件捕获,目标,事件冒泡(低版本ie不支持捕获阶段)
- w3c绑定事件target.addEventListener(event,handler,false)
- 解绑target.removeEventListener(eventType, handler, false )
- ie绑定 target.attachEvent(on+event, handler)
- 解绑target.detachEvent("on"+eventType, handler)
事件代理优点:
- 可以大量节省内存占用,减少事件注册,比如在table上代理所有td的click事件就非常棒
- 可以实现当新增子对象时无需再次对其绑定事件,对于动态内容部分尤为合适
26.将url的查询参数解析成字典对象
function getQueryObject(url) {
url = url == null ? window.location.href : url;
var search = url.substring(url.lastIndexOf("?") + 1);
var obj = {};
var reg = /([^?&=]+)=([^?&=]*)/g;
search.replace(reg, function (rs, $1, $2) {
var name = decodeURIComponent($1);
var val = decodeURIComponent($2);
val = String(val);
obj[name] = val;
return rs;
});
return obj;
}
getQueryObject("http://www.cnblogs.com/leee/p/4456840.html?name=1&dd=ddd**")
Object {name: "1", dd: "ddd**"}
27.position的值, relative和absolute分别是相对于谁进行定位的?
- relative :相对定位,相对于自己本身在正常文档流中的位置进行定位。
- absolute :生成绝对定位,相对于最近一级定位不为static的父元素进行定位。
- fixed : 生成绝对定位,相对于浏览器窗口或者frame进行定位。
- static :默认值,没有定位,元素出现在正常的文档流中。
28.CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算? CSS3新增伪类有那些?
选择符 :
- id选择器(#myId);
- 类选择器(.myClassName);
- 标签选择器(div,p,h1);
- 相邻选择器(h1 + p);
- 子选择器(ul > li);
- 后代选择器(li a);
- 通配符选择器(*);
- 属性选择器(button[disabled="true"]);
- 伪类选择器(a:hover,li:nth-child);表示一种状态
- 伪元素选择器(li:before、:after,:first-letter,:first-line,:selecton);表示文档某个部分的表现
优先级 :
!important > 行内样式(比重1000) > id(比重100) > class/属性(比重10) > tag / 伪类(比重1);
伪类和伪元素区别 :
- 伪类:a:hover,li:nth-child;
- 伪元素:li:before、:after,:first-letter,:first-line,:selector;
39.两个数组合并成一个数组排序返回
先依次比较两个数组,按照小的就传入新的数组。当这次比较完之后可能有一个数组的长度很长,留下一些数组,然后在新数组的末尾插入即可。
functiongetRes(arr1, arr2){
var len1 = arr1.length,
len2 = arr2.length,
i = 0,
j = 0,
k = 0,
res = new Array(len1+len2);
while(i < len1 && j
res[k++] = arr[(arr[i] > arr[j]) ? j++ : i++];
}
While(i < len1) res[k++]= arr1[i++];
While(j < len2) res[k++]= arr2[j++];
Return res;
}
40.zepto和jquery区别
- zepto比jquery体积小很多,移动端的兼容性不需要要考虑很多,jquery中的很多功能都没有。
- width()和height()不一样 解决用.css('width')
41.css3动画和jquery动画的差别
- css3中的过渡和animation动画都是基于css实现机制的,属于css范畴之内,并没有涉及到任何语言操作。效率略高与jQuery中的animate()函数,但兼容性很差。
- jQuery中的animate()函数可以简单的理解为css样式的“逐帧动画”,是css样式不同状态的快速切换的结果。效率略低于css3动画执行效率,但是兼容性好。
42.如何解决ajax无法后退的问题
HTML5里引入了新的API,即:history.pushState, history.replaceState
可以通过pushState和replaceState接口操作浏览器历史,并且改变当前页面的URL。
onpopstate监听后退
43.实现一个once函数
function test () {console.log('test')}
var once = function (fn) {
var isFirst = true;
return function () {
if (isFirst) {
isFirst = !isFirst;
fn();
}
};
};
var b = once(test);
b(); // 'test'
b(); // nothing
44.分域名请求图片的原因和好处
- 浏览器的并发请求数目限制是针对同一域名的,超过限制数目的请求会被阻塞
- 浏览器并发请求有个数限制,分域名可以同时并发请求大量图片
45.页面的加载顺序
html顺序加载,其中js会阻塞后续dom和资源的加载,css不会阻塞dom和资源的加载但是会阻塞js的加载。
浏览器会使用prefetch对引用的资源提前下载
- 没有 defer 或 async,浏览器会立即加载并执行指定的脚本
- 有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(下载异步,执行同步,加载完就执行)。
- 有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。
46.生成10个20-50之间的随机数,存在数组中,常见排序方法,数组乱序方法
var arr = [];
for(var i = 0;i<10;i++){
var num = Math.random()*30 + 20;
num = parseInt(num, 10);
arr.push(num);
}
arr.sort(function(a,b){
return 0.5 - Math.random();
})
47.计算机网络的分层概述
- tcp/ip模型:从下往上分别是链路层,网络层,传输层,应用层
- osi模型:从下往上分别是物理层,链路层,网络层,传输层,会话层,表示层,应用层。
48.jscss缓存问题
浏览器缓存的意义在于提高了执行效率,但是也随之而来带来了一些问题,导致修改了js、css,客户端不能更新
都加上了一个时间戳作为版本号
49.setTimeout,setInterval,requestAnimationFrame之间的区别
- setInterval如果函数执行的时间很长的话,第二次的函数会放到队列中,等函数执行完再执行第二次,导致时间间隔发生错误。
- 而settimeout一定是在这个时间定时结束之后,它才会执行
- requestAnimationFrame是为了做动画专用的一个方法,这种方法对于dom节点的操作会比较频繁。
50.webpack常用到哪些功能
- 设置入口 设置输出目 设置loader extract-text-webpack-plugin 将css从js代码中抽出并合并 处理图片文字等功能 解析jsx解析bable
51.介绍sass
- sass是一门编程语言,css是一门标记语言,sass是一种css开发工具,可以预编译css,sass提供了很多遍历的写法:例如自定义变量,if语句,循环,嵌套,继承,混合
52.websocket和ajax轮询
Websocket是HTML5中提出的新的协议 ,注意,这里是协议,可以实现客户端与服务器端的通信,实现服务器的推送 功能。
其优点就是,只要建立一次连接,就可以连续不断的得到服务器推送的消息,节省带宽和服务器端的压力。
ajax轮询模拟长连接就是每个一段时间(0.5s)就向服务器发起ajax请求,查询服务器端是否有数据更新
其缺点显而易见,每次都要建立HTTP连接,即使需要传输的数据非常少,所以这样很浪费带宽
53.tansition和margin的百分比根据什么计算
- transition是相对于自身,margin相对于参照物
54.冒泡排序、快速排序、去重、查找字符串最多值
//冒泡排序
var bubbleSort = function(arr) {
for (var i = 0; i < arr.length-1; i++) {
for (var j = i+1; j < arr.length; j++) {
if (arr[i]>arr[j]) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr;
};
//快速排序
var quickSort = function(arr) {
if (arr.length <= 1) {
return arr;
}
var len = arr.length;
var midIndex = Math.floor(len/2);
var mid = arr.splice(midIndex,1);
var left = [];
var right = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] < mid) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quickSort(left).concat(mid,quickSort(right))
}
// 去重
var distinct = function(arr) {
var map = {};
var result = [];
for (var i = 0; i < arr.length; i++) {
if (!map[arr[i]]) {
map[arr[i]] = true;
result.push(arr[i]);
}
}
return result;
}
//查找字符串中最多的值
var search = function(str) {
var json = {};
var max = 0;
var char;
for (var i = 0; i < str.length; i++) {
if (!json[str[i]]) {
json[str[i]]=1;
} else {
json[str[i]]++;
}
}
console.log(json);
for(var i in json){
if(json[i]>max){
max = json[i];
char = i;
}
}
console.log(max, char);
}
55.函数组合继承
原型继承、构造函数继承、call aplly继承
var Super = function(name){
this.name = name;
}
Super.prototype.func1 = function() { console.log('func1'); }
var Sub = function(name,age) {
Super.call(this, name);
this.age = age;
}
Sub.prototype = new Super();
56.事件绑定
var addEvent = function(e, type, handler, capture ) {
if (e.addEventListener) {
e.addEventListener(type, handler, capture);
} else if (e.attachEvent) {
e.attachEvent('on'+type, handler);
} else {
e['on'+type] = handler;
}
}
57.浅克隆和深度克隆
//浅克隆
function extendCopy(p) {
var c = {};
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
return c;
}
//深度克隆
var clone = function(v) {
var o = v.constructor === Array ? [] : {};
for (var i in v) {
o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i];
}
return o;
}
58.实现一个秒针绕一点转动的效果
animation: move 60s infinite steps(60);
/*设置旋转的中心点为中间底部*/
transform-origin: center bottom;
/*旋转从0度到360度*/
@keyframes move {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
59.移动端兼容问题
- IOS移动端click事件300ms的延迟响应一些情况下对非可点击元素如(label,span)监听click事件,ios下不会触发,css增加cursor:pointer就搞定了
60.对前端界面工程师这个职位是怎么理解的?
- 前端是最贴近用户的程序员,前端的能力就是能让产品从90分进化到100分,甚至更好
- 参与项目,快速高质量完成时限效果图,精确到1px
- 与团队成员,UI设计,产品经理沟通
- 做好页面结构,页面结构和用户体验
- 支队服务器的优化,拥抱最新的前端技术