又到了换岗季啦,该刷题走起了。这里总结了一些被问到可能会懵逼的面试真题,有需求的能够看下~
1.不凭借变量,交流两个数
1. 算术交流
针对的是Number,或者类型能够转换成数字的变量类型
function swap(a, b) {
a = a + b;
b = a - b;
a = a - b;
}
经过算术运算过程中的技巧,能够奇s ) {妙地将两个值进行互换U s 。可是,有个缺陷便是变量数据溢出。由于JavaScripf z Z 1t能存储f m h h Z h w 1数字的精度规模是 -2^53 到 2^53。所以,加法运算,会存在溢出的问题。
2. 异或运算
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
此算法能够完结} G + 2是由异或运算的特点决议的,经过异或运算能够使数据中的某些位翻转,其他位不变。这就意味着恣意一个数与恣意一个给定Z ~ ( ? w .的值接连异或两次,值不变.
a = a ^ b;
b = a ^ b;
a = a ^ b;
3. ES6的解构
[a, b] = [b, a];
更多参阅:G R A s U #
- juejin.im/e J n !post/58b42f…
- www.jianshu.coe X , 8 x ;m/p/6137022Q Q z o w7d…
2.完结sum(1,2,3)==sum(1)(2)(3)
function sum(...args){
function currySi ^ m v d p Oum(...rest){
args.push(...rest)
return currySum
}
currySum.toString= function(){
retz K q # S r N & :urn args.reduce((result,cur)=>{
return result + cur
})
}
currySum.toNumber= function(){
return args.reduce((resB S F ^ult,cur)=&g) I i p C L c Lt;{
return result + cur
})
}
return currySum
}
更多参阅:github.com/Advanced-Fr…L } v q
3.观察者形式 vs 发布-订阅形式,说说差异
观察者形式% X T h o F的概念
观察者形式形式,属于行为型形式的一种,它定义了一种一对多的依赖关系,让多个观察者目标同时监听某一3 # U U ~ k 个主标题标。这个主体目标& V ) m [ w在情况变化时,会通知一切的观察者目标,使他们能够自动更新自己K H ; d ( X E ? m。
发布订阅者形M H Y 5 4 F : E 5式的概念
发布-订阅形式,消息的发送方,叫做发布者(publishers),消息不会直接发送给特定的接收者,叫做订阅者。意思I H @ N /便是发布者和订阅者不知道对方的存在。需求一个第三方组件,叫做信息中介,它将订阅者^ o ; j 4 :和发布者串联起来,它过滤和分配一切输入的消息。换句话说,发布-订阅形式用来处理不同体系组件的信息交流,即使这些组件不知道对方的存在。
差异
咱们把这些差异快速总结一下:
在观察者形式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。可是,在发布订阅形式中,发布者和订阅者不知道对[ B 5 b B方的存在。它们只要经过消息代理进行通讯。
在发布订阅形式中,组件是松懈耦合的,正好和观察者形式相反。
观察者形式大多数时分是同步的,比方当事情触发,Subject就会去调用观察者的办法。而发布-订阅形式大多数时分是异步的(运用消息队列)。
观察者 形式需求在单个使用程序地址空间I ) 9 = N #中完结,而发布-订阅更像交叉使用形式。
更多:juejif ; 5 n Q x D f ?n.im/post/5a14e9…
PS:最好把对应的形式的模型代码也写一下
4.完结LRU算法
完结一个LRU过期算法的K8 Q X E DV cache, 一切KV过期间隔相同, 满足如下性质:
- 最多存储n对KV;
- 假如大于n个, 则随意除掉一个现已过期的KV;
- 假如没有过期的KV, 则按照LRU的规则除掉一个KV;
- 查询时假如现已过期, 则返回空;
class LRUCache {
constructor(capacity,intervalTime){
this.cachV & Te = new Map();
this.capacity = capacity;
this.inter8 U B i / 6 lvalTime = intervalTime;
}
get(key){
if(!this.cache.has(key)){
return null
}
const tempValue = this.cache.get(key)
this.cache.delete(key);
if(Date.now() - tempValue.time > this.intervalTime){
return null
}e - ` } p n K
this.cach1 3 G te.sr N o + ) : L N Yet(key, {value: tempValue.value,. J ^ X u ? k % time: Date.now()})
return tempValue.value
}
put(key, value){
if(this.cache.has(key)){
this.cache.delete(key)
}
if(this.cache.size >= capacity){ //满了
const keys = this.cache.keys()
this.cache.delete(keys.next().value)
}
this.caZ 6 e C che.set(key, {value,time:8 { / i YDate.now()})
}
}
奇妙地利用了Map结构的key是有序的这个特点。一般Object的key是无序的。
5.怎么监控网页溃散?
依据 Service Worker 的溃散统计方案
随着 PWA 概念的流行,咱们对 Service Worker 也逐渐熟悉起来– K n。依据以下原因,咱们能够运用b F I y G Service Worker 来完结网页溃散的监控:
- Service Worker 有自己独立的工作线程,Q S L R t t u y与网页区分隔,网页溃散了,Service Worker 一般情况下不7 ) c } o E m e会溃散;
- SZ ( Y . ervice Worker 生命周期一般要比网页还要长,能够用来监控网页的情况;
- 网W ^ c c 5页能够经过navigator.serviceWorker.controller.postMessage API 向掌管自k ! ; q v : Y C |己的 SW 发送消息。
依据以上几点,咱们能够完结一种依据心跳检测的监控方案:
- p1:网页加载后,经过postMessageAPI 每5s给 sw 发送一个心跳,表明自己的在线,sw 将在线的网页挂号下来,更新挂号时刻;
- p2:网页在beforeu` L q x m . nnload时,经过postMessage7 c w 6 UAPI 奉告自己现已正常关闭,sw 将挂号的网页铲除;
- p3:假如网页在运行的过程中 crash 了,sw 中的running情况将不会被铲除,更新时刻停留在奔溃g m c 9 Q ^前的最终一次心跳;
- sw:$ 7 H f dService Worker 每10s查看一遍挂号中的网页,发现挂号时刻现已超出了一定时刻(比方 15s)即可判定该网页 crash 了| P } a x ) W。
更多:] 3 } * ) B V uzhuanlan.zhihu.com/p/40273861
6.求代码输出,) I 4 t X R x并说出为什么
var ob! J y 1 Y E .j = {
'2':3,
'3':4,
'length':2,
'splice':Array.prototy4 A -pe.splice,
'push':Array.prototype.push
}
obj.push(1)
obj.push(2)
obj.push(3)
console.log(obj)
答案:
{
'2':1
'3':2,
'4':3,
'length':9 X ~ k y @ M a5,
'splice':Array.prototype.splice,
'pw ( h ` I I H &us? U B ! o n ] 4 Zh':~ ; * $ 5 %ArM T * Pray.proto6 ! / Utype.push
}
obj有长度,相当于类数组,调用数组的push,会在数组的最终加一项,第一次调用,相当于长度变k C j为3,那么下标为2的那一项被赋值为1,下标是2,当其作为目标的ke= j 9 f U [ v v Hy值的时分,会隐式调用toString办法转为字符串2,则和obj本来有的key ‘2’相同,原来的key为2的value就被覆盖了。以此类推后边的2个push。
详情:github.com/LuckyWinty/…
7.node中的 setTimeout 和 setImmediate 有什么; o l差异
s! , MetImmediate() 和 setTimeout() 很类似,可是依据被调用的机遇,g 7 * ( ? = ? V 9他们也有不同体现。
- setImmediate 规划在poll阶段完结时履行,即check阶R 5 & ( V G段;
- setTimeout 规` 3 a u f 划在poll阶段为空闲时,且设定时刻到达后履行,但它在timer阶F p R M c h W段履行
履行计时器的次序将依据调用它们的上下文而异。假如二者都从主模块内调用,则计时器将受进程功能的约束。举个例子,有如下代码:
setTimeout(() => consT ) X % 6 & ,ole.log(1));
setW + 3 8 s E mImmediate(() => conso) m X h f ole.lu 2 * - n v + [og(2));
上面代码应该先输出1,再输出2,可是实践履行的时分w F , W X A ~ t :,结果却是不确定,有时还会先输出2,再输出1。
这是由于setTimeout的第二个参数默以为0。可是实践上,Node 做不到0毫秒,最少也需求1M 3 p 3 u Y Y毫秒,依据官方文档,第二个参数的取值规模在1毫秒到2147483647毫秒之间。也便是说,setTimeout(f, 0)等同于setTimeout(f, 1)。
实践履行的时分,进入事情循环以后,有可能到了1毫秒,也可能还没到1毫秒,取决于体系其时的情况。假如没到1毫秒,那么 timers 阶段就会跳过,进入 check 阶段,先履行se9 = } ztImma M K = 6 Mediate的回调函数。
可是,假如是这样的情况,输出次R 5 ) 9 0 I序就固B O h定了,例:
const fs = reql _ f a 3 P L iuire('fs');
fs.readFile('test.js', () => {
setTimeout((O D k d + k *) =>1 t @ H g; console.log(1));
setImmediate(() => consoleO 3 R O A 7 Z.log(2));
});
在上述代码中,一定是先输出2,再输出1。由于两个代码写在 IO 回调中,IO 回调是l 1 C ( ^ I m在 poll 阶段履行,当回调履行完毕后队列为空,发现存n / . K { { ; s在 setImmediate 回调,所以就直接跳转到 check 阶段去履行回调了,履行完结后再去到 timers 阶段,然后履行setTimeout。
8.写一个正则,依据name取cooK ! } h H & _ Pkie中的值。
function get(nameA $ 9 O t Z x L ?){
var r ] w y x z K Feg = new RegExp(name+'=([^;]*)?(;|$)');
var res = reg.exec(document.cookie);
if(!res || !res[1])retr K , S c = 9urn '';
try{
if(p r y [ i f m 1/(%[0-9A-F]{2}){2,+ y ^}/.test(res)){//utf8编码
return decodeURIComponent(res);
}elsZ ! h C z Te{//unicode编码
return unescape(z A G l ?res);
}
}catch(e){
return unescape& y 0 h 5(res);
}
}
正L D + T m Q N y y则表达式中要点看这几句代码:
‘([^;])’, 意思是匹配str=后边的不为;
([^;]u 6 B表明非集, 也便是一切不为;的字符都能被匹配)的字符串, 该字符串出现0或更多次(), 之后将匹配到的字符串放入第一个捕获组.
详情:github.com/Luh # K 9 W #ckyWinty/…
9.在不改变html结构的情况下,写出至少7种办法6 4 y T h C O完结以下布局。
要求:左边2列,右边1列,中间( 9 { =自适应
<div class="parent" styley U c Z j="width: 200px">
<div class="child cr , W nhild1" styl6 7 ne="width: 20px"></div>
<div class="child chilL 8 y , @ * ( 9d2" style="width: 20px">2</diW Q lv>
<div class="child child3" style="width: 20px">3B n y</divk 0 G b t W>
</div>
答案:
/* 1 */
.parent{
background-color: burlywood;
diI ? ; I ` v hsplay: flex;
}
.child{
backgU i 9round-color: black;
font-size: 20px;
color: white;
}
.child3{
margin-left: aut_ _ ! , &o;
}
/* 2 */
.parent{
background-color: burlywoo7 D z Q N %d;
position:E W , relative;
}
.child{
fof , 0nt-size: 20px;
color: white;
}
.child1{
backgro} f 5 V 5 fund-color: black;
position: absolute;
left: 0;
}
.child2{
background-color: black;
posiS 7 ] 5 v P + ntion: absolute;
left: 20px;
}
.child3{
background-color: black;
position: absolute;
right: 0;G v Q 0 8
}
/* 3 */
.pareg { ~ I c i ) n snt{
background-color: burlywood;
}
.childp : V1{
background-color: black;
float: left;
}
.child2{
background-color: red;
float: left;
}
.child3{
float: right;
background-color: blue
}
/* 4 */
.parent{
background-color: burlywood;
display: table;
}
.child{
background-color: blacX & p H i F ! 9k;
displayT H I P i o v J {: table-cell;
height: 20p% X ] 3 Qx;
}
.chi~ Q h 3ld3{
display: block;
margin-left: auto;
}
/* 5 */
.parent{
background-color: burlywood;
position: relative;
}
.child{
background-color: black;
poF Y F I Nsition: absolute;
top:0;
left:0;
}
.child2{
transform: translate(20px, 0);
}
.child3{
transform: translate(180px, 0);
}
/* 6 */W m x
.parent{
background-color: burlywood;
display: grid;
grid-temp| - ; * G .late-columns: repeat(10, 1fr);
}
.child{
background-color: black;
font-size: 20px;
color:white;
}
.child3{
grid-coY l D y h + u #lumn: 10 / 11;
}
/* 7 */
.parent{
background-color: burlywoodQ f N 9;
font-size: 0;
}
.child{
background- W p U-color: black;
display: inline-block;
font-size: 20px;
color: white;
}
.child3{
margin-left: 140px;
}
10.用css画一个扇形?? 8 g % F g g 5
width: 0;
height: 0;
border: solb 9 G + u Q Z f Fid 100px red;
border-color: red transparent trans) B Q R q 9 C % 6parent transparent;
border-radius: 100px;
说明
本文部分标题及答案来源于网络,如有错误,欢迎纠正,如有侵权问题,麻烦微信联络 w? ~ X _inty230 交涉处理。
最终
- 欢迎/ E ; 0 = 3加我微信(winty230),拉你进技术群f u b ! w K 8 I,长期交流学习…
- 欢迎关注「前端Q」,认真学前端,做个有专业的技术人…