问题1
requestAnimationFrame
和setTimeout
比照劣势
- 当页面暗藏或者最小化时,setTimeout依然在后盾执行动画,此时页面不可见或者是不可用状态,动画刷新没有意义,而言节约CPU。
- rAF不一样,当页面解决未激活的状态时,该页面的屏幕绘制工作也会被零碎暂停,因而跟着零碎步调走的rAF也会进行渲染,当页面被激活时,动画就从上次停留的中央继续执行,无效节俭了 CPU 开销。
标准中仿佛是这么去定义的:
在从新渲染前调用。
很可能在宏工作之后不去调用
与节流比照
长处
- 动画放弃 60fps(每一帧 16 ms),浏览器外部决定渲染的最佳时机
- 简洁规范的 API,前期保护成本低
毛病
- 动画的开始/勾销须要开发者本人管制,不像 ‘.debounce’ 或 ‘.throttle’由函数外部解决。
- 浏览器标签未激活时,所有都不会执行。
- 只管所有的古代浏览器都反对 rAF ,IE9,Opera Mini 和 老的 Android 还是须要打补丁。
- Node.js 不反对,无奈在服务器端用于文件系统事件。
问题2 DNS解析
- 首先查看是否有对应的域名缓存,有的话间接用缓存的ip拜访
- 如果缓存中没有,则去查找hosts文件, 个别在
c:\windows\system32\drivers\etc\hosts
- 如果hosts文件里没找到想解析的域名,则将域名发往本人配置的dns服务器,也叫本地dns服务器
ipconfig/all
- 如果本地dns服务器有相应域名的记录,则返回记录。
- 如果电脑本人的服务器没有记录,会去找根服务器。根服务器寰球只有13组,会去找其中之一,找了根服务器后,根服务器会依据申请的域名,返回对应的“顶级域名服务器”
- 顶级域服务器收到申请,会返回二级域服务器的地址
- 以此类推,最终会发到负责锁查问域名的,最准确的那台dns,能够失去查问后果
- 本地dns服务器,把最终的解析后果,返回给客户端。
问题3 XSS CSRF
XSS是指黑客往 HTML 文件中或者 DOM 中注入歹意脚本,从而在用户浏览页面时利用注入的歹意脚本对用户施行攻打的一种伎俩。
注入歹意脚本能够实现这些事件:
- 窃取Cookie
- 监听用户行为,比方输出账号密码后之间发给黑客服务器
- 在网页中生成浮窗广告
- 批改DOM伪造登入表单
个别的状况下,XSS攻打有三种实现形式
- 存储型 XSS 攻打
- 反射型 XSS 攻打
- 基于 DOM 的 XSS 攻打
阻止 XSS 攻打的策略
对输出脚本进行过滤或转码
利用 CSP,该安全策略的实现基于一个称作 Content-Security-Policy
的 HTTP 首部。
- 限度加载其余域下的资源文件,这样即便黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无奈被加载的;
- 禁止向第三方域提交数据,这样用户数据也不会外泄;
- 提供上报机制,能帮忙咱们及时发现 XSS 攻打。禁止执行内联脚本和未受权的脚本;
利用 HttpOnly。服务器能够将某些 Cookie 设置为 HttpOnly 标记,HttpOnly 是服务器通过 HTTP 响应头来设置
CSRF 英文全称是 Cross-site request forgery,所以又称为“跨站申请伪造”,是指黑客诱惑用户关上黑客的网站,在黑客的网站中,利用用户的登录状态发动的跨站申请。简略来讲,CSRF 攻打就是黑客利用了用户的登录状态,并通过第三方的站点来做一些好事。
防护策略
- 验证码机制,验证起源站点。次要通过HTTP申请头中的两个Header,Origin只蕴含域名信息,而Referer蕴含了具体的 URL 门路
Origin Header
Referer Header - 利用Cookie的SameSite属性
SameSite能够设置为三个值,Strict、Lax和None。
在Strict模式下,浏览器齐全禁止第三方申请携带Cookie。
在Lax模式只能在 get 办法提交表单况或者a 标签发送 get 申请的状况下能够携带 Cookie
在None模式下,Cookie将在所有上下文中发送,即容许跨域发送 - CSRF Token
问题4 开发一个loader和Plugin
- loader实质上就是一个函数,这个函数会在咱们在咱们加载一些文件时执行
- 开发loader函数,这个函数必须返回一个buffer或者string
- 应用这个loader,咱们应用resolveLoader配置项,指定loader查找文件门路,应用loader时候能够间接指定loader的名字
resolveLoader: { // loader门路查找程序从左往右 modules: ['node_modules', './'] }, module: { rules: [ { test: /\.js$/, use: 'myLoader' } ] }
plugin通常是在webpack在打包的某个工夫节点做一些操作,咱们应用plugin的时候,个别都是new Plugin()这种模式应用,所以,首先应该明确的是,plugin应该是一个类。
plugin类外面须要实现一个apply办法,这个办法承受一个compiler作为参数,这个compiler是webpack实例.
比方
class DemoPlugin { constructor () { console.log('plugin init') } // compiler是webpack实例 apply (compiler) { // 一个新的编译(compilation)创立之后(同步) compiler.hooks.compile.tap('DemoPlugin', compilation => { console.log(compilation) }) // 生成资源到 output 目录之前(异步) compiler.hooks.emit.tapAsync('DemoPlugin', (compilation, fn) => { console.log(compilation) compilation.assets['index.md'] = { // 文件内容 source: function () { return 'this is a demo' }, // 文件尺寸 size: function () { return 10 } } fn() }) }}module.exports = DemoPlugin
问题5
TCP/IP / 如何保障数据包传输的有序牢靠
对字节流分段并进行编号而后通过 ACK 回复
和超时重发
这两个机制来保障。
问题6
粘包问题剖析与对策
TCP粘包是指发送方发送的若干包数据到接管方接管时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
粘包呈现起因
简略得说,在流传输中呈现,UDP不会呈现粘包,因为它有音讯边界
粘包状况有两种,一种是粘在一起的包都是残缺的数据包,另一种状况是粘在一起的包有不残缺的包。
一种比拟周全的对策是:接管方创立一预处理线程,对接管到的数据包进行预处理,将粘连的包离开。试验证实这种办法是高效可行的。
问题7
如何防止重绘或者重排?
- 集中扭转款式,不要一条一条地批改 DOM 的款式。
- 不要把 DOM 结点的属性值放在循环里当成循环里的变量。
- 为动画的 HTML 元件应用 fixed 或 absoult 的 position,那么批改他们的 CSS 是不会 reflow 的。
- 不应用 table 布局。因为可能很小的一个小改变会造成整个 table 的从新布局。
- 尽量只批改position:absolute或fixed元素,对其余元素影响不大
- 动画开始GPU减速,translate应用3D变动
- 晋升为合成层
问题8
- 浏览器一帧做了哪些事件
- 承受输出事件
- 执行事件回调
- 开始一帧
- 执行 RAF (RequestAnimationFrame)
- 页面布局,款式计算
- 渲染
- 执行 RIC (RequestIdelCallback)
问题9
webpack中hash、fullhash、chunkhash和contenthash的区别
- hash--编译产生,每次编译的时候都会实例化一个对象compilation, 该对象掌控着从编译开始到编译完结文件,模块的加载,关闭,优化,分块,哈希,重建等等都是由其负责, 此时的hash是由compilation来创立。跟整个我的项目的构建相干,只有我的项目里有文件更改,整个我的项目构建的hash值都会更改,并且全副文件都共用雷同的hash值
- fullhash--全量的hash,是整个我的项目级别的。只有我的项目中有任何一个的文件内容产生变动,打包后所有文件的hash值都会产生扭转。
- chunkhash-- chunk,每个入口文件都是一个chunk,每个chunk是由入口文件与其依赖所形成,异步加载的文件也被视为是一个chunk。hunkhash是由每次编译模块,依据模块及其依赖模块形成chunk生成对应的chunkhash,文件未被扭转时,chunkhash没变,浏览器能够利用缓存机制疾速加载,然而, 每个chunk都是有css与js组成, 也就是说当其中一个文件发生变化,这个chunk都会从新编译,比方配置成
filename: 'bundle.[name].[chunkhash].js'
,一个js文件中引入了css,批改后js,css文件的hash值都会变。 - contenthash--针对文件内容生成不同的hash, 只有当文件内容发生变化此hash才会从新生成,利用mini-css-extract-plugin插件取提取出每个chunk的css文件,将css与js隔离开,而后将css更改,改变了哪个文件,哪个文件hash值才会变,比方配置成
new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: "css/[name].[contenthash].css", chunkFilename: "css/[name].[contenthash].css" })
问题10
6.toString()
转换报错6.
的点有歧义,计算机不晓得是get符号还是小数点。括号把6括起来就不会报错{}.toString()
转换报错,{}
计算机不晓得是代码块还是一个对象,括号括起来输入[object Object]
[].toString()
数组中每一个元素以字符串模式输入,这里输入空
[]==[]
false,比拟援用,援用值不一样[]==![]
true []
地址不为空,![]
为false
1.如果两个值类型雷同,则比拟他们的值或者援用地址
2.如果两个值类型不同,他们可能相等。依据上面规定进行类型转换再比拟:
- 1.如果一个是null、一个是undefined,那么相等。
- 2.如果一个是字符串,一个是数值,把字符串转换成数值再进行比拟。
- 3.如果任一值是 true,把它转换成 1 再比拟;如果任一值是 false,把它转换成 0再比拟。
- 4.如果一个是对象,另一个是数值或字符串,把对象转换成根底类型的值再比拟。对象转换成根底类型,利用它的toString或者valueOf办法。
问题11 SVG Canvas
SVG
- 不依赖分辨率(矢量图)
- 每一个图形都是一个 DOM元素
- 反对事件处理器
- 适宜大型渲染区域的应用程序(谷歌地图)
- 能够通过脚本和CSS进行批改
- 只能通过脚本批改对象数量较小 (<10k)、图面更大时性能更佳
- 不适宜游戏利用
Canvas
- 依赖分辨率(位图)
- 单个HTML元素,相当于<img>
- 不反对事件处理器
- 文本渲染能力差
- 图面较小,对象数量较大(>10k)时性能最佳
- 适宜图像密集型的游戏利用
问题12 '1'.toString()为什么能够调用?
var s = new Object('1');s.toString();s = null;
- 创立Object类实例。因为Symbol和BigInt的呈现,对它们调用new都会报错,目前ES6标准也不倡议用new来创立根本类型的包装类。
- 调用实例办法。
- 执行完办法立刻销毁这个实例。
整个过程体现了根本包装类型的性质,而根本包装类型恰好属于根本数据类型,包含Boolean, Number和String。
问题13 Object.is
Object在严格等于的根底上修复了一些非凡状况下的失误,具体来说就是+0和-0,NaN和NaN。
function is(x, y) { if (x === y) { //运行到1/x === 1/y的时候x和y都为0,然而1/+0 = +Infinity, 1/-0 = -Infinity, 是不一样的 return x !== 0 || y !== 0 || 1 / x === 1 / y; } else { //NaN===NaN是false,这是不对的,咱们在这里做一个拦挡,x !== x,那么肯定是 NaN, y 同理 //两个都是NaN的时候返回true return x !== x && y !== y; }
问题14,浏览器不反对Promise.allSettled
当浏览器不反对 Promise.allSettled ,能够如此 polyfill
if (!Promise.allSettled) { const rejectHandler = reason => ({status: "rejected", reason}) const resolveHandler = value => ({status: "fulfilled", value}) Promise.allSettled = promises => Promise.all( promises.map((promise) => Promise.resolve(promise) .then(resolveHandler, rejectHandler) ) // 每个 promise 须要用 Promise.resolve 包裹下 // 以防传递非 promise );}
问题15
如何让 (a == 1 && a == 2 && a == 3) 的值为true?
部署[Symbol.toPrimitive]
接口
let a = { [Symbol.toPrimitive]: (function (hint) { let i = 1; return function () { return i++; }; })(),};
或者数据劫持
let i =1let a = new Proxy({},{ i:1, get:function(){ return ()=>this.i++ }})