总结,又杂又多
crypto
1、事件循环
g(x) f(x) g(21)
start promise setTimeOut
2、选择排序 归并排序 快速排序
3、hooks
4、graphQL resful
5、深克隆,map,promise 手动实现
6、看过什么书
7、0 100 300 200 200 async/await实现
腾讯
头条
笔试
四个题型
单选:比较简单,有问etag不太了解
填空:一个事件循环,一个this指针
编程:数组深度,大数相加
问答:性能优化
一面
react diff算法
-
tree diff :DOM节点跨层级移动较少,忽略
(1)React通过updateDepth对Virtual DOM树进行层级控制。
(2)对树分层比较,两棵树 只对同一层次节点 进行比较。如果该节点不存在时,则该节点及其子节点会被完全删除,不会再进一步比较。
(3)只需遍历一次,就能完成整棵DOM树的比较。
添加删除会导致跨层级,所以官方建议少删除添加,而用隐藏显示 component diff:拥有相同类的两个组件,生成相似树形结构
component diff
React对不同的组件间的比较,有三种策略
(1)同一类型的两个组件,按原策略(层级比较)继续比较Virtual DOM树即可。
(2)同一类型的两个组件,组件A变化为组件B时,可能Virtual DOM没有任何变化,如果知道这点(变换的过程中,Virtual DOM没有改变),可节省大量计算时间,所以 用户 可以通过 shouldComponentUpdate() 来判断是否需要 判断计算。
(3)不同类型的组件,将一个(将被改变的)组件判断为dirty component(脏组件),从而替换 整个组件的所有节点。element diff :同一层级的一组子节点,通过唯一id区分
当节点处于同一层级时,diff提供三种节点操作:删除、插入、移动。
插入:组件 C 不在集合(A,B)中,需要插入
删除:(1)组件 D 在集合(A,B,D)中,但 D的节点已经更改,不能复用和更新,所以需要删除 旧的 D ,再创建新的。
(2)组件 D 之前在 集合(A,B,D)中,但集合变成新的集合(A,B)了,D 就需要被删除。
移动:组件D已经在集合(A,B,C,D)里了,且集合更新时,D没有发生更新,只是位置改变,如新集合(A,D,B,C),D在第二个,无须像传统diff,让旧集合的第二个B和新集合的第二个D 比较,并且删除第二个位置的B,再在第二个位置插入D,而是 (对同一层级的同组子节点) 添加唯一key进行区分,移动即可。
在开发过程中,尽量减少类似将最后一个节点移动到列表首部的操作,当节点数量过大或更新操作过于频繁时,会影响React的渲染性能。
在原型上手写map,reduce
前端缓存
service worker>memory cache>disk cache>请求
1.根据 Service Worker 中的 handler 决定是否存入 Cache Storage (额外的缓存位置)。
2.根据 HTTP 头部的相关字段(Cache-control, Pragma 等)决定是否存入 disk cache
3.memory cache 保存一份资源 的引用,以备下次使用。
cookies: HTML5之前本地储存的主要方式,大小只有4k,HTTP请求头会自动带上cookie,兼容性好
localStorage:HTML5新特性,持久性存储,即使页面关闭也不会被清除,以键值对的方式存储,大小为5M
sessionStorage:HTML5新特性,操作及大小同localStorage,和localStorage的区别在于sessionStorage在选项卡(页面)被关闭时即清除,且不同选项卡之间的sessionStorage不互通
IndexedDB: NoSQL型数据库,类比MongoDB,使用键值对进行储存,异步操作数据库,支持事务,储存空间可以在250MB以上,但是IndexedDB受同源策略限制
Web SQL:是在浏览器上模拟的关系型数据库,开发者可以通过SQL语句来操作Web SQL,是HTML5以外一套独立的规范,兼容性差
数组数学方法
map,reduce,filter,foreach,sort,reverse,slice,splice
网络安全,哪几种攻击方式
1、 XXS: 脚本注入攻击,用户输入可执行JS代码
输入框,URL,img,$.append嵌入<script>脚本,导致cookie信息泄露
防范方式:
- 输入内容转移
- httpOnly,核心的用户身份标示或token保存在Cookie中,Cookie中一定要加“HTTPOnly”在结尾,保证只有在html操作时才能将cookie中的内容发送出去,在JS中无法获得用户的Cookie信息
- 禁止用户在输入的过程中输入"<",">","引号","$","_",
2、 XSRF/CSRF:跨站脚本攻击,网站提交表单被利用,操作到其他网站
来源
- 携带业务特性参数的GET 请求
- 被隐藏和伪造的POST 请求
导致用户不知情的情况下对其他网站接口进行了提交。
主要防范方式为 - 使用验证码
- get请求不对数据进行修改,请求附带token
- 使用唯一的session作为接口校验规则
- 减少在cookie,不让第三方网站访问cookie
- 中存储客户核心内容比如用户的token、ID、access_token等,将和信息存在前端的storage中
3、网络劫持:网站的访问并非进入目标服务器,而是中间被转移到其他网站了
解决方法
- 使用https
- 使用非对称加密方式RSA进行数据加密
4、钓鱼网站:高仿引诱提交表单
5、中间人攻击:中间人攻击是攻击方同时与服务端和客户端建立起了连接,并让对方认为连接是安全的
- 用https
总结:
提防用户自己生产内容,对表单进行验证
对服务器传入的内容进行转义输出,大部分框架已经集成了这个功能
重要的用户数据要进行加密,使用HTTPS传送或者使用RSA加密
规范使用POST/GET请求,原则上,有用户数据的部分统一使用POST
哪几种设计模式
1、单例模式
var single = (function(){
let instance;
function getInstance(){
// 如果该实例存在,则直接返回,否则就对其实例化
if( instance=== undefined ){
instance= new Construct();
}
return instance;
}
function Construct(){
// ... 生成单例的构造函数的代码
}
return {
getInstance : getInstance
}
})();
2、工厂模式
//安全模式创建的工厂方法函数
let UserFactory = function(role) {
if(this instanceof UserFactory) {
var s = new this[role]();
return s;
} else {
return new UserFactory(role);
}
}
//工厂方法函数的原型中设置所有对象的构造函数
UserFactory.prototype = {
SuperAdmin: function() {
this.name = "超级管理员",
this.viewPage = ['首页', '通讯录', '发现页', '应用数据', '权限管理']
},
Admin: function() {
this.name = "管理员",
this.viewPage = ['首页', '通讯录', '发现页', '应用数据']
},
NormalUser: function() {
this.name = '普通用户',
this.viewPage = ['首页', '通讯录', '发现页']
}
}
//调用
let superAdmin = UserFactory('SuperAdmin');
let admin = UserFactory('Admin')
let normalUser = UserFactory('NormalUser')
3、观察者模式
4、装饰器模式
5、适配器模式
6、代理模式
回流重绘
回流:长宽等发生变化,会引起布局变化
重绘:颜色,显示变化
1、使用transform代替
2、visibility代替display:none
3、避免table布局
4、css层级减少
5、动画用在position为absolute或fixed,复杂元素绝对定位脱离文档流
6、css3硬件加速,transform\opacity,filter不引起
7、js少操作dom,样式
原型继承
ip mac
虚拟(一个地址可以对应多个IP),物理(网卡)
位运算
加法,找出数组中唯一出现的数
二面
vue @click
jQuery 事件代理
rem如何实现
跨域
同源策略,协议域名端口都一致
1、后端加Access-Control-Allow等字段,不安全
2、脚手架webpack,node正向代理,proxy
3、nginx反向代理,proxy_pass
4、jsonp,script标签没有同源限制