You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
varxhr=createXHR();xhr.onreadystatechange=function(){if(xhr.readyState==4){if((xhr.status>=200&&xhr.status<300)||xhr.status==304){alert(xhr.responseText);}else{alert("Request was unsuccessful: "+xhr.status);}}};xhr.open("get","example.txt",true);xhr.send(null);
functionFoo(){// 下边这句没有 var, let 或 const, 相当于 window.getName = xxxgetName=function(){console.log(1)}returnthis// 这里的 this 要看调用方式, 直接调用 Foo() 则 this 指向 window, new 调用, this 指向 new 出来的实例}
十道大厂面试题(含答案)总结
又到了跳槽季啦,该刷题走起了。这里总结了一些被问到可能会懵逼的面试真题,有需要的可以看下~
1.不借助变量,交换两个数
1. 算术交换
针对的是Number,或者类型可以转换成数字的变量类型
通过算术运算过程中的技巧,可以巧妙地将两个值进行互换。但是,有个缺点就是变量数据溢出。因为JavaScript能存储数字的精度范围是 -2^53 到 2^53。所以,加法运算,会存在溢出的问题。
2. 异或运算
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
此算法能够实现是由异或运算的特点决定的,通过异或运算能够使数据中的某些位翻转,其他位不变。这就意味着任意一个数与任意一个给定的值连续异或两次,值不变.
3. ES6的解构
更多参考:
2.实现sum(1,2,3)==sum(1)(2)(3)
更多参考:Advanced-Frontend/Daily-Interview-Question#134
3.观察者模式 vs 发布-订阅模式,说说区别
观察者模式的概念
观察者模式模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主体对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
发布订阅者模式的概念
发布-订阅模式,消息的发送方,叫做发布者(publishers),消息不会直接发送给特定的接收者,叫做订阅者。意思就是发布者和订阅者不知道对方的存在。需要一个第三方组件,叫做信息中介,它将订阅者和发布者串联起来,它过滤和分配所有输入的消息。换句话说,发布-订阅模式用来处理不同系统组件的信息交流,即使这些组件不知道对方的存在。
区别
我们把这些差异快速总结一下:
在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。
在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。
观察者 模式需要在单个应用程序地址空间中实现,而发布-订阅更像交叉应用模式。
更多:https://juejin.im/post/5a14e9edf265da4312808d86
PS:最好把对应的模式的模型代码也写一下
4.实现LRU算法
实现一个LRU过期算法的KV cache, 所有KV过期间隔相同, 满足如下性质:
巧妙地利用了Map结构的key是有序的这个特点。普通Object的key是无序的。
5.如何监控网页崩溃?
基于 Service Worker 的崩溃统计方案
随着 PWA 概念的流行,大家对 Service Worker 也逐渐熟悉起来。基于以下原因,我们可以使用 Service Worker 来实现网页崩溃的监控:
基于以上几点,我们可以实现一种基于心跳检测的监控方案:
更多:https://zhuanlan.zhihu.com/p/40273861
6.求代码输出,并说出为什么
答案:
obj有长度,相当于类数组,调用数组的push,会在数组的最后加一项,第一次调用,相当于长度变为3,那么下标为2的那一项被赋值为1,下标是2,当其作为对象的key值的时候,会隐式调用toString方法转为字符串2,则和obj本来有的key '2'相同,原来的key为2的value就被覆盖了。以此类推后面的2个push。
详情:LuckyWinty/fe-weekly-questions#48
7.node中的 setTimeout 和 setImmediate 有什么区别
setImmediate() 和 setTimeout() 很类似,但是基于被调用的时机,他们也有不同表现。
执行计时器的顺序将根据调用它们的上下文而异。如果二者都从主模块内调用,则计时器将受进程性能的约束。举个例子,有如下代码:
上面代码应该先输出1,再输出2,但是实际执行的时候,结果却是不确定,有时还会先输出2,再输出1。
这是因为setTimeout的第二个参数默认为0。但是实际上,Node 做不到0毫秒,最少也需要1毫秒,根据官方文档,第二个参数的取值范围在1毫秒到2147483647毫秒之间。也就是说,setTimeout(f, 0)等同于setTimeout(f, 1)。
实际执行的时候,进入事件循环以后,有可能到了1毫秒,也可能还没到1毫秒,取决于系统当时的状况。如果没到1毫秒,那么 timers 阶段就会跳过,进入 check 阶段,先执行setImmediate的回调函数。
但是,如果是这样的情况,输出顺序就固定了,例:
在上述代码中,一定是先输出2,再输出1。因为两个代码写在 IO 回调中,IO 回调是在 poll 阶段执行,当回调执行完毕后队列为空,发现存在 setImmediate 回调,所以就直接跳转到 check 阶段去执行回调了,执行完成后再去到 timers 阶段,然后执行setTimeout。
8.写一个正则,根据name取cookie中的值。
正则表达式中重点看这几句代码:
'([^;])', 意思是匹配str=后面的不为;
([^;]表示非集, 也就是所有不为;的字符都能被匹配)的字符串, 该字符串出现0或更多次(), 之后将匹配到的字符串放入第一个捕获组.
详情:LuckyWinty/fe-weekly-questions#32
9.在不改变html结构的情况下,写出至少7种方法实现以下布局。
要求:左边2列,右边1列,中间自适应
答案:
10.用css画一个扇形?
每周N题12月汇总
年底了,又到了跳槽季啦,该刷题走起了。这里总结了一些被问到可能会懵逼的面试真题,有需要的可以看下~
1. 说说JavaScript中有哪些异步编程方式?
1. 回调函数
回调函数是异步编程的基本方法。其优点是易编写、易理解和易部署;缺点是不利于代码的阅读和维护,各个部分之间高度耦合 (Coupling),流程比较混乱,而且每个任务只能指定一个回调函数。
2. 事件监听
事件监听即采用事件驱动模式,任务的执行不取决于代码的顺序,而取决于某个事件是否发生。其优点是易理解,可以绑定多个事件,每个事件可以指定多个回调函数,可以去耦合, 有利于实现模块化;缺点是整个程序都要变成事件驱动型,运行流程会变得不清晰。
3. 发布/订阅
假定存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行,这就叫做 "发布/订阅模式" (publish-subscribe pattern),又称 "观察者模式" (observer pattern)。该 方法的性质与"事件监听"类似,但其优势在于可以 通过查看"消息中心",了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。
4. promise对象
Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供 统一接口 ;思想是, 每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。其优点是回调函数是链式写法,程序的流程非常清晰,而且有一整套的配套方法, 可以实现许多强大的功能,如指定多个回调函数、指定发生错误时的回调函数, 如果一个任务已经完成,再添加回调函数,该回调函数会立即执行,所以不用担心是否错过了某个事件或信号;缺点就是编写和理解相对比较难。
2. 有哪些监控网页卡顿的方法?
卡顿
网页的 FPS
网页内容在不断变化之中,网页的 FPS 是只浏览器在渲染这些变化时的帧率。帧率越高,用户感觉网页越流畅,反之则会感觉卡顿。
监控卡顿方法
每秒中计算一次网页的 FPS 值,获得一列数据,然后分析。通俗地解释就是,通过 requestAnimationFrame API 来定时执行一些 JS 代码,如果浏览器卡顿,无法很好地保证渲染的频率,1s 中 frame 无法达到 60 帧,即可间接地反映浏览器的渲染帧率。
我们可以定义一些边界值,比如连续出现3个低于20的 FPS 即可认为网页存在卡顿。
3. 说说script 标签中的defer 和 async 异同点?
defer
这个属性的用途是表明脚本在执行时不会影响页面的构造。也就是说,脚本会被延迟到整个页面都解析完毕后再运行。因此,在script元素中设置defer属性,相当于告诉浏览器立即下载,但延迟执行。
HTML5规范要求脚本按照它们出现的先后顺序执行,因此第一个延迟脚本会先于第二个延迟脚本执行,而这两个脚本会先于DOMContentLoaded事件执行。在现实当中,延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoad时间触发前执行,因此最好只包含一个延迟脚本。
对于不支持的浏览器,如safari,并不会延迟执行,还是会阻塞浏览器渲染。
async
这个属性与defer类似,都用于改变处理脚本的行为。同样与defer类似,async只适用于外部脚本文件,并告诉浏览器立即下载文件。但与defer不同的是,标记为async的脚本并不保证按照它们的先后顺序执行。
第二个脚本文件可能会在第一个脚本文件之前执行。因此确保两者之间互不依赖非常重要。指定async属性的目的是不让页面等待两个脚本下载和执行,从而异步加载页面其他内容。
总结
async 和 defer 虽然都是异步的,不过还有一些差异,使用 async 标志的脚本文件一旦加载完成,会立即执行;而使用了 defer 标记的脚本文件,需要在 DOMContentLoaded 事件之前执行。
可以再扩展一下:link preload也可以用于js提前加载,和上述两者的区别? 还有应用场景上的建议
4. margin:auto 为什么可以实现垂直居中?
margin概念:
margin属性为给定元素设置所有四个(上下左右)方向的外边距属性。这是四个外边距属性设置的简写。四个外边距属性设置分别是: margin-top,margin-right,margin-bottom和margin-left。指定的外边距允许为负数。
margin的top和bottom属性对非替换内联元素无效,例如
span
和code
。实现垂直居中
想要实现垂直方向的居中可以用绝对定位:
为什么能实现垂直居中
块状水平元素,如div元素(下同),在默认情况下(非浮动、绝对定位等),水平方向会自动填满外部的容器;如果有margin-left/margin-right,padding-left/padding-right,border-left-width/border-right-width等,实际内容区域会响应变窄。
但是,当一个绝对定位元素,其对立定位方向属性同时有具体定位数值的时候,流体特性就发生了。具有流体特性绝对定位元素的margin:auto的填充规则和普通流体元素一模一样,含有以下特性:
如果一侧定值,一侧auto,auto为剩余空间大小;
如果两侧均是auto, 则平分剩余空间
5. Cdn有哪些优化静态资源加载速度的方法?
可以参考阿里云团队的《CDN之我见》。总结如下:
资源调度:CDN会根据用户接入网络的ip寻找距离用户最优路径的服务器。调度的方式主要有DNS调度、http 302调度、使用 HTTP 进行的 DNS 调度(多用于移动端);
缓存策略和数据检索:CDN服务器使用高效的算法和数据结构,快速的检索资源和更新读取缓存;
网络优化:从OSI七层模型进行优化,达到网络优化的目的。
L1物理层:硬件设备升级提高速度
L2数据链路层:寻找更快的网络节点、确保 Lastmile 尽量短
L3路由层:路径优化,寻找两点间最优路径
L4传输层:协议TCP优化,保持长连接、TCP快速打开
L7应用层:静态资源压缩、请求合并
6. fetch 和 ajax 的区别?
Ajax 技术的核心是XMLHttpRequest 对象(简称XHR)。
XHR 为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。
看一个调用例子:
fetch号称是ajax的替代品,它的API是基于Promise设计的,旧版本的浏览器不支持Promise,需要使用polyfill es6-promise,举个例子:
看起来好像是方便点,then链就像之前熟悉的callback。
在MDN上,讲到它跟jquery ajax的区别,这也是fetch很奇怪的地方:
7. 求代码输出值(函数/原型 指向问题)?
输出:
2
函数也是一个 object, 可以拥有属性和方法, Foo.getName 被赋值为一个输出 2 的函数, 所以输出 2
4
getName() 父级作用域为 window, 相当于调用 window.getName(), Foo() 还未被执行, 不需要考虑 Foo 函数体内对 getName 的影响, 剩下最后两个
函数声明会提升, 也就是即使在后边声明的函数, 在前别也能调用, 如:
但题中函数表达式会覆盖函数声明, 来看下边这段:
1
我们一步步拆解, 上边的语句相当于
来看 Foo 的声明:
仔细看上边的注释, Foo 函数体内对 window.getName 进行了改写, 这是下一个输出的关键
1
如上边分析的, Foo() 函数的执行, 对 window.getName 进行了改写, window.getName 此时已经变为
function () { console.log(1) }
2
该语句先执行 Foo.getName, 与第一个结论一致, 输出 2, 只是 new 会返回一个 object, 这个 object 指向 new 出来的实例, 但这里这个实例没被使用, 就不进一步分析了
3
拆解如下
如果你是一路看分析下来的, 就会明白 foo 这个实例, 就是 Foo 函数体里的 this. 从原型的知识中, 我们可以知道, 如果调用一个实例的方法, 在实例方法中找不到, 就会从实例原型中找.
也就是会找到下边这个方法, 并执行:
3
拆解如下
从上边
new Foo().getName()
的分析, 可以知道 foo.getName() 是在 foo 的原型里边的, 这里 new 了一下原型里边的函数, 相当于先执行了, 再返回了一个新的实例. 这里的执行, 也就是执行了下边这个方法:只是 new 额外返回一个实例, 实例没被使用, 没什么特殊的.
如果还有不明白的地方, 建议阅读 《JavaScript 语言精髓》第四章 (本人看的是修订版) 关于函数调用相关的内容. 相关电子书可以微信关注公众号 前端Q, 回复 ebook 阅读. 此外, 建议购买正版.
8. 如何判断左右小括号是否全部匹配。如 ( ( ))()((((()))))?
9. 用css画一个扇形?
10. 用css实现已知或者未知宽度的垂直水平居中?
11. 如何理解回流和重绘? ?
回流:
当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),然后再将计算的结果绘制出来。这个过程就是回流(也叫重排)。重绘:
当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式(跳过了上图所示的回流环节)。这个过程叫做重绘。 由此我们可以看出,重绘不一定导致回流,回流一定会导致重绘。常见的会导致回流的元素:
避免方式:
will-change
优点
注意:
部分浏览器缓存了一个 flush 队列,把我们触发的回流与重绘任务都塞进去,待到队列里的任务多起来、或者达到了一定的时间间隔,或者“不得已”的时候,再将这些任务一口气出队。但是当我们访问一些即使属性时,浏览器会为了获得此时此刻的、最准确的属性值,而提前将 flush 队列的任务出队。
12. 手写一个Promise?
答案太长,你可以参考这个issues:LuckyWinty/fe-weekly-questions#20
13. 谈谈web安全问题及解决方案
答案太长,你可以参考这个issues:LuckyWinty/fe-weekly-questions#1
14. HTTPS和HTTP有什么区别?
答案太长,你可以参考这个issues:LuckyWinty/fe-weekly-questions#2
15. Webpack性能优化你知道哪些?
答案太长,你可以参考这个issues:LuckyWinty/fe-weekly-questions#4
更多
本期汇总暂时到这里,更多题目,可以关注:
https://github.com/LuckyWinty/fe-weekly-questions
The text was updated successfully, but these errors were encountered: