面试问题总结
HTTP相关:
-
有几种方式可以实现存储功能,分别有什么优缺点?
- cookie已不适合用于存储,需注意安全问题
- localstorage用于不怎么改变的数据,否则用sessionstorage
- indexDB适用客户端存储大量的结构化数据,并且使用索引高效检索
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
- 浏览器渲染原理
- 浏览器有一个渲染引擎,会把接收到的html文件转换为DOM树
- 然后将css文件转换为CSSOM树(css应选择器避免过于具体,层级扁平,减少无意义标签,因为css渲染会递归CSSOM树)
- 将DOM和CSSOM整合生成渲染树,根据渲染树进行布局(回流),将需要显示的节点显示在页面,遇到script标签会阻塞
- 加载一个资源的过程
1. 浏览器根据DNS服务器获取域名的IP地址
2. 向这个IP的服务器发送http请求
3. 服务器收到,处理,并返回http请求
4. 浏览器得到返回内容
- window.onload和DOMContentLoaded有何区别?
window.onload是页面全部资源(包括图片, 视频)加载完才会执行
DOMContentLoaded是DOM渲染完即可执行
- 插入几万个dom,如何实现不卡顿?
- 重绘与回流
- 重绘是当节点需要更改外观而不会影响布局的,比如改变
color
就叫称为重绘 - 回流是布局或者几何属性需要改变就称为回流。
- 减少 重绘与回流
- 使用
transform
替代top
- 使用
visibility
替换display: none
- 不要把节点的属性值放在一个循环里当成循环里的变量
- 不要使用
table
布局,可能很小的一个小改动会造成整个table
的重新布局 -
动画实现的速度的选择,动画速度越快,回流次数越多,也可以选择使用
requestAnimationFrame
-
CSS 选择符从右往左匹配查找,避免节点层级过多
-
将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点。比如对于
video
标签来说,浏览器会自动将该节点变为图层;以下常用属性可以生成新图层: will-change
video
、iframe
标签
- 如何进行性能优化?
多使用内存 , 缓存 , 减少cpu计算 , 网络请求
静态资源压缩 , 合并 , 缓存 , 使用CDN
HTML:
CSS:
css放在head里 :先加载css 然后渲染 否则渲染两次
JS:
- JS放在body最下面:不会阻塞渲染过程 性能优化问题; 再执行JS script能拿到所有标签
- 减少DOM操作 , 对DOM查询进行缓存
- 多个操作尽量合并在一起执行
- 尽早在dom渲染完执行
图片:
- 修饰类图片用css
- 移动端图片尽量使用CDN加载(可以计算出屏幕适配宽度,请求相应裁切好的图片)
- 使用雪碧图
- 小图使用base64格式
- 选择正确的图片格式
- 照片使用jpeg
- 小图,图标类使用png或者svg
- 动图gif
DNS预解析:
DNS 解析也是需要时间的,可以通过预解析的方式来预先获得域名所对应的 IP。
<link rel="dns-prefetch" href="//baidu.com">
节流:
隔一段时间发送请求:如在用户输入时,用户输入过快会导致一直发送请求,这时候我们可以使用节流函数,使隔一小段时间发送请求.
var time; input.addEventListener('keyup',function(){ if(time) clearTimeout(time) time = setTimeout(function(){ console.log('111') },1500) })
防抖:
有一个按钮点击会触发网络请求,但是我们并不希望每次点击都发起网络请求,而是当用户点击按钮一段时间后没有再次点击的情况才去发起网络请求,对于这种情况我们就可以使用防抖。
// func是用户传入需要防抖的函数
// wait是等待时间
const debounce = (func, wait = 50) => {
// 缓存一个定时器id
let timer = 0
// 这里返回的函数是每次用户实际调用的防抖函数
// 如果已经设定过定时器了就清空上一次的定时器
// 开始一个新的定时器,延迟执行用户传入的方法
return function(...args) { if (timer) clearTimeout(timer) timer = setTimeout(() => { func.apply(this, args) }, wait) } }
预加载:
优点:降低首屏加载时间
缺点:兼容性不好
<link rel="preload" href="http://example.com">
预渲染:
要确保用户大概率打开这个页面
<link rel="prerender" href="http://example.com">
懒加载:
懒加载就是将不关键的资源延后加载。
对于图片来说,先设置图片标签的 src
属性为一张占位图,将真实的图片资源放入一个自定义属性中,当进入自定义区域时,就将自定义属性替换为 src
属性,这样图片就会去下载资源,实现了图片懒加载。
懒加载不仅可以用于图片,也可以使用在别的资源上。比如进入可视区域才开始播放视频等等。
- contenttype有哪几种类型?
json
xml
- Post请求和Get请求的区别是什么?主要作用在哪?
- get点击浏览器回退按钮不会再次提交.post会.
- get请求能缓存,post需要手动设置才可以
- get的参数可以保留在浏览器历史记录,post不会
- get传送参数长度是有限制的(2kb),post无限制
- get参数在url地址上,不能用来传敏感信息.post参数放在Request body
- get的url地址可以收藏,post不可以.
- 什么是跨域?为什么浏览器要使用同源策略?跨域方式都有哪些?
同源策略: 协议,域名,端口 (为了安全考虑)
- jsonp - (只能get请求) 通过script标签异步加载的特性指向访问地址然后再返回一个回调函数接收数据
- cors - 服务端设置(Access-Control-Allow-Origin)
- postmessage - (用于获取嵌入页面中的第三方页面数据)
- websocket
- hash
- iframe
- Ajax具体怎么实现?
var xmr=new XMLHttpRequest();
xmr.open('GET','url',false); xmr.onreadystatechange=function(){ if(xmr.readyState==4){ if((xmr.status>=200 && xmr.status<300)||xmr.status===304){ alert(xmr.responseText) } } } xmr.send(null)
- readyState状态码
0 - 未初始化 , 还没有调用send方法
1 - 载入 , 已调用send方法,正在发送请求
2 - 载入完成 , send()方法执行完成 , 已接收到全部响应内容
3 - 交互 , 正在解析响应内容
4 - 完成 , 响应内容解析完成 , 可以在客户端调用
- status状态码
2xx 表示成功处理请求 206表示接受到部分资源
3xx 重定向 304表示使用缓存
4xx 客户端请求错误 如404
5xx 服务器端错误
- 什么是 XSS 攻击?如何防范 XSS 攻击?
XSS 简单点来说,就是攻击者将可以执行的代码注入到网页中。(跨站请求攻击)
防范:转义输入输出的内容,对于引号、尖括号、斜杠进行转义
- 什么是 CSRF 攻击?如何防范 CSRF 攻击?
攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。
举个例子,假设网站中有一个通过 GET
请求提交用户评论的接口,那么攻击者就可以在钓鱼网站中加入一个图片,图片的地址就是评论接口
防范:
- Get 请求不对数据进行修改
- 不让第三方网站访问到用户 Cookie
- 阻止第三方网站请求接口
- 请求时附带验证信息,比如验证码或者 Token
HTML相关:
CSS相关:
- 如何用css实现一行文字后面...的情况?
ellipse();
overflow:hidden;
JS相关:
-
js内置函数是什么?作用是什么?
内置函数: Object, Array , Function , Boolean , Number , String , Date , RegExp , Error , Json .
作用: 作为构造器函数
- null和undefined的区别是什么?
null表示未创建的对象,
undefined表示未赋值的变量
它们在使用==会发生类型转换.导致相等
- 哪些情况下会发生类型转换?
== 字符串拼接 if 逻辑运算符
- W3C对js的规定有哪些?
DOM , BOM , 事件绑定 , ajax请求(包括http协议) , 存储
- DOM的本质?DOM是哪种数据结构?DOM常用API?Attribute 和 property有何区别?
本质: 浏览器拿到html代码后,DOM把html代码结构化结构化成浏览器以及js可识别的东西.
数据结构: 树
API:新增节点(document.createElement(none)) , 删除节点 (parentNode.removeChild(childNode)) , 获取父节点 (ChildNode.parentElement) , 获取子节点(parentNode.childNode)
区别: Attribute是对html标签属性进行获取修改, property是js对象属性的获取修改
- 怎么理解json?
是内置的js对象,也是一种数据格式
有两个方法:
JSON.stringify({a:10,b:11})//把对象变成字符串
JSON.parse('{a:10,b:11}')//把字符串变成对象
- 什么是同步(对比异步)?举个例子?
同步会阻塞代码运行,异步不会
alert同步,seTimeout异步
- 什么时候需要异步?
在发生等待的情况下 , 程序仍然需要执行其他操作
等待过程中不能像alert一样阻塞程序运行
- 异步使用场景有哪些?
定时任务
网络请求: ajax , img加载, 脚本等文件加载和下载
事件绑定
- this有哪些使用场景?
1.作为构造函数执行
2.作为对象属性执行
3.作为普通函数执行
4.call apply bind
- this指向如何判断?
- 函数直接调用指向window
- 对象调用,this指向调用的对象
- new方式直接指向它的实例对象
- 箭头函数无this,取决于包含箭头函数的普通函数this
- bind的this永远由第一次决定
- 什么是提升?什么是暂时性死区?var,let,const有什么区别?
let,const在声明前使用会报错,这个行为是因为暂时性死区
let,const声明不会挂载在window上,不能重复声明。const一旦声明不能再次赋值。
- 什么是作用域? 作用域链是什么?
一个函数的父级作用域是在它定义的时候的作用域,而非它执行时候的作用域。
自由变量一直像父级作用域寻找,即作用域链
- 什么是闭包呢?闭包存在的意义?有哪些优点和缺点?使用场景?
在函数A内嵌套函数B并返回,函数B可以访问到函数A的变量,函数B我们称之为闭包.
意义: 闭包是为了让我们间接的访问函数内部的变量.
优点: 封装性强,使得变量始终保持在内存中。
缺点: 内存的消耗导致的性能问题
使用场景: 函数作为返回值 函数作为参数传递
- instance的判断逻辑?
沿着__proto__一层一层向上找,看是否能找到对应的prototype
- typeof能正确判断类型吗?instance的原理?
typeof
只能判断原始类型,null除外 (js存在的bug,在最初版本为性能考虑,使用000开头表示对象,null表示全0,所以会错误的判断null为对象)
instance是通过判断对象的原型链中是不是能找到类型的 prototype
。
- 原型与原型链的理解,它们有什么特点?
对象的隐式原型指向构造函数的显示原型 , 原型是一个普通对象 , 所以存在一个原型类 , 对象不存在的属性到对象的隐式原型中去找,一直找到object为止
- new 的原理是什么?通过 new 的方式创建对象和通过字面量创建有什么区别
- 新生成了一个对象
- 链接到原型
- 绑定 this
- 返回新对象
使用 new Object()
的方式创建对象需要通过作用域链一层层找到 Object
,使用字面量的方式就没这个问题。
- 对象类型和原始类型的区别?函数参数是对象会发生什么?
对象类型存储的是地址(指针),而原始类型存储的是值
函数参数是对象指针的副本,当参数重新分配对象时,参数的指针会发生变化.两个变量的值也会不相同.
- 事件的触发过程是怎么样的?知道什么是事件代理嘛?
从window开始进行捕获>document>html(document.documentElement)>body>...>目标元素 >然后依次冒泡到window
stopPropagation阻止冒泡,也可以阻止捕获
stopImmediatePropagation阻止该事件目标执行别的注册事件。
事件代理:
把事件放在父节点,通过事件的target来访问
优势:
- 节省内存
- 不需要给子节点注销事件
- Class与普通的构造函数有什么区别?class本质?
- 本质是语法糖,使用prototype
- 在语法上更贴合面向对象的写法
- 在继承上更易读,理解
- 更易于写java后端语言
- es5中通过在一个函数内部用this来写,来生成一个类和实例
- es6通过class关键字声明,用constroctor生成 extends继承 super传递
class
实现继承的核心在于使用 extends
表明继承自哪个父类,并且在子类构造函数中必须调用 super
- 面向对象有哪几种形式?
- 构造函数
- 工厂模式
- 原型模式
- 混合模式(构造+原型)
- 什么是回调函数?回调函数的缺点?如何解决?
缺点:不利于维护阅读,嵌套函数过多会很难处理错误
- Es6常用的方法有哪些?
- let和const
- 块级作用域
- 解构赋值
- 扩展运算
- promise
- 模板字符串
- 箭头函数
- symbol
- set和map
- class
- Proxy和Reflect
- Generator
- Decorators
- Module(模块化)
- promise的使用及原理? promise特点, 优缺点, promise链, Promise 构造函数执行和 then 函数执行有什么区别?
使用:在函数内返回一个promise对象,通过then执行下一步
特点: promise有三种状态,一旦执行不可更改
- 等待中(pending)
- 完成了 (resolved)
- 拒绝了(rejected)
promise链: promise每次then调用后返回一个全新的promise,这样就可以形成链式调用
优点: 解决回调函数不停的嵌套,造成代码难以维护.
缺点: 无法取消promise, 错误需要回调函数捕获
- 说说深拷贝?浅拷贝?
- 浅拷贝是指只拷贝所有属性到新对象,如果属性值是对象,只拷贝地址.
- 浅拷贝通过object.assign(),扩展运算符...来解决
通过JSON.parse(JSON.stringify(object))来解决
但是:
- 会忽略
undefined
- 会忽略
symbol
- 不能序列化函数
- 不能解决循环引用的对象
- 为什么要使用模块化?都有哪几种方式可以实现模块化,各有什么特点?
- Proxy 可以实现什么功能?
- async 及 await 的特点,它们的优点和缺点分别是什么?await 原理是什么?
一个函数如果加上 async
,那么该函数就会返回一个 Promise
- Generator 是什么?
- 什么是执行栈?
存储函数调用的栈结构,遵循先进后出的原则
- vue如何做响应式?
通过object.definepropotype
- 如何对vue进行拦截?
- vue怎么实现阻止冒泡?
stop修饰符
- jquery和Vue的区别是什么?什么是 MVVM?比之 MVC 有什么区别?
view:视图 Model:数据 controller:控制器
jquery使MVP模型
传统的 MVC 架构通常是使用控制器更新模型,视图从模型中获取数据去渲染。当用户有输入时,会通过控制器去更新模型,并且通知视图进行更新。
vue使用的MVVM模型
vue不直接操作dom结构,只关注数据(model)和视图(view),中间层(viewmodel)Vue已经帮我们实现了
- 写一个clone函数,可以复制原始类型的值.
- 完善通用绑定事件函数
function on(elem, type, selector, fn) {
if (fn == null) {
fn=selector;
selector = null;
}
elem.addEventListener(type, function (e) {
var target;
if (selector) {
target = e.target;
if (target.matches(selector)) {
fn.call(target, e)
}
} else {
fn(e)
}
})
}
- 以下代码如何实现点击列表显示相应的index值?
<ul id="test">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
<script>
$('#test').on('click','li',function(e){ alert($(this).index()); })
- 说说你做过最复杂的js代码...
- 说说你做过最复杂的项目
- 做一下自我介绍
