当前位置 博文首页 > LuckyWinty的博客:十道大厂面试题(含答案)总结
又到了跳槽季啦,该刷题走起了。这里总结了一些被问到可能会懵逼的面试真题,有需要的可以看下~
PS:点击阅读原文即可进入前端Q题库,每周N题,来刷题吧~
针对的是Number,或者类型可以转换成数字的变量类型
function?swap(a,?b)?{
???a?=?a?+?b;
???b?=?a?-?b;
???a?=?a?-?b;
}
通过算术运算过程中的技巧,可以巧妙地将两个值进行互换。但是,有个缺点就是变量数据溢出。因为JavaScript能存储数字的精度范围是 -2^53 到 2^53。所以,加法运算,会存在溢出的问题。
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1 此算法能够实现是由异或运算的特点决定的,通过异或运算能够使数据中的某些位翻转,其他位不变。这就意味着任意一个数与任意一个给定的值连续异或两次,值不变.
a?=?a?^?b;
b?=?a?^?b;?
a?=?a?^?b;
[a,?b]?=?[b,?a];
更多参考:
https://juejin.im/post/58b42fcc5c497d006793cd04
https://www.jianshu.com/p/61370227d096
function?sum(...args){
??function?currySum(...rest){
????args.push(...rest)
????return?currySum
??}
??currySum.toString=?function(){?
????return?args.reduce((result,cur)=>{
??????return?result?+?cur
????})
??}
??currySum.toNumber=?function(){?
????return?args.reduce((result,cur)=>{
??????return?result?+?cur
????})
??}
??return?currySum
}
更多参考:https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/134
观察者模式模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主体对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
发布-订阅模式,消息的发送方,叫做发布者(publishers),消息不会直接发送给特定的接收者,叫做订阅者。意思就是发布者和订阅者不知道对方的存在。需要一个第三方组件,叫做信息中介,它将订阅者和发布者串联起来,它过滤和分配所有输入的消息。换句话说,发布-订阅模式用来处理不同系统组件的信息交流,即使这些组件不知道对方的存在。
我们把这些差异快速总结一下:
在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。
在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。
观察者 模式需要在单个应用程序地址空间中实现,而发布-订阅更像交叉应用模式。
更多:https://juejin.im/post/5a14e9edf265da4312808d86?
PS:最好把对应的模式的模型代码也写一下
实现一个LRU过期算法的KV cache, 所有KV过期间隔相同, 满足如下性质:
最多存储n对KV;
如果大于n个, 则随意剔除一个已经过期的KV;
如果没有过期的KV, 则按照LRU的规则剔除一个KV;
查询时如果已经过期, 则返回空;
class?LRUCache?{
????constructor(capacity,intervalTime){
????????this.cache?=?new?Map();
????????this.capacity?=?capacity;
????????this.intervalTime?=?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
????????}
????????this.cache.set(key,?{value:?tempValue.value,?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.cache.set(key,?{value,time:Date.now()})
????}
}
巧妙地利用了Map结构的key是有序的这个特点。普通Object的key是无序的。
随着 PWA 概念的流行,大家对 Service Worker 也逐渐熟悉起来。基于以下原因,我们可以使用 Service Worker 来实现网页崩溃的监控:
Service Worker 有自己独立的工作线程,与网页区分开,网页崩溃了,Service Worker 一般情况下不会崩溃;
Service Worker 生命周期一般要比网页还要长,可以用来监控网页的状态;
网页可以通过navigator.serviceWorker.controller.postMessage API 向掌管自己的 SW 发送消息。
基于以上几点,我们可以实现一种基于心跳检测的监控方案:
p1:网页加载后,通过postMessageAPI 每5s给 sw 发送一个心跳,表示自己的在线,sw 将在线的网页登记下来,更新登记时间;
p2:网页在beforeunload时,通过postMessageAPI 告知自己已经正常关闭,sw 将登记的网页清除;
p3:如果网页在运行的过程中 crash 了,sw 中的running状态将不会被清除,更新时间停留在奔溃前的最后一次心跳;
sw:Service Worker 每10s查看一遍登记中的网页,发现登记时间已经超出了一定时间(比如 15s)即可判定该网页 crash 了。
更多:https://zhuanlan.zhihu.com/p/40273861
var?obj?=?{
????'2':3,
????'3':4,
????'length':2,
????'splice':Array.prototype.splice,
????'push':Array.prototype.push
}
obj.push(1)
obj.push(2)
obj.push(3)
console.log(obj)
答案:
{
????'2':1
????'3':2,
????'4':3,
????'length':5,
????'splice':Array.prototype.splice,
????'push':Array.prototype.push
}
obj有长度,相当于类数组,调用数组的push,会在数组的最后加一项,第一次调用,相当于长度变为3,那么下标为2的那一项被赋值为1,下标是2,当其作为对象的key值的时候,会隐式调用toString方法转为字符串2,则和obj本来有的key '2'相同,原来的key为2的value就被覆盖了。以此类推后面的2个push。
详情:https://github.com/LuckyWinty/fe-weekly-questions/issues/48
setImmediate() 和 setTimeout() 很类似,但是基于被调用的时机,他们也有不同表现。
setImmediate 设计在poll阶段完成时执行,即check阶段;
setTimeout 设计在poll阶段为空闲时,且设定时间到达后执行,但它在timer阶段执行
执行计时器的顺序将根据调用它们的上下文而异。如果二者都从主模块内调用,则计时器将受进程性能的约束。举个例子,有如下代码:
setTimeout(()?=>?console.log(1));
setImmediate(()?=>?console.log(2));
上面代码应该先输出1,再输出2,但是实际执行的时候,结果却是不确定,有时还会先输出2,再输出1。
这是因为setTimeout的第二个参数默认为0。但是实际上,Node 做不到0毫秒,最少也需要1毫秒,根据官方文档,第二个参数的取值范围在1毫秒到2147483647毫秒之间。也就是说,setTimeout(f, 0)等同于setTimeout(f, 1)。
实际执行的时候,进入事件循环以后,有可能到了1毫秒,也可能还没到1毫秒,取决于系统当时的状况。如果没到1毫秒,那么 timers 阶段就会跳过,进入 check 阶段,先执行setImmediate的回调函数。
但是,如果是这样的情况,输出顺序就固定了,例:
const?fs?=?require('fs');
fs.readFile('test.js',?()?=>?{
?setTimeout(()?=>?console.log(1));
?setImmediate(()?=>?console.log(2));
});
在上述代码中,一定是先输出2,再输出1。因为两个代码写在 IO 回调中,IO 回调是在 poll 阶段执行,当回调执行完毕后队列为空,发现存在 setImmediate 回调,所以就直接跳转到 check 阶段去执行回调了,执行完成后再去到 timers 阶段,然后执行setTimeout。
function?get(name){
??var?reg?=?new?RegExp(name+'=([^;]*)?(;|$)');
??var?res?=?reg.exec(document.cookie);
??if(!res?||?!res[1])return?'';
????try{
??????if(/(%[0-9A-F]{2}){2,}/.test(res)){//utf8编码
??????return?decodeURIComponent(res);
????}else{//unicode编码
??????return?unescape(res);
????}
??}catch(e){
????return?unescape(res);
??}
}
正则表达式中重点看这几句代码: '([^;])', 意思是匹配str=后面的不为; ([^;]表示非集, 也就是所有不为;的字符都能被匹配)的字符串, 该字符串出现0或更多次(), 之后将匹配到的字符串放入第一个捕获组.
详情:https://github.com/LuckyWinty/fe-weekly-questions/issues/32
要求:左边2列,右边1列,中间自适应
????<div?class="parent"?style="width:?200px">
????????<div?class="child?child1"?style="width:?20px"></div>
????????<div?class="child?child2"?style="width:?20px">2</div>
????????<div?class="child?child3"?style="width:?20px">3</div>
????</div>
答案:
/*?1?*/
????.parent{
????????background-color:?burlywood;
????????display:?flex;
????}
????.child{
????????background-color:?black;
????????font-size:?20px;
????????color:?white;
????}
????.child3{
????????margin-left:?auto;
????}
/*?2?*/
????.parent{
????????background-color:?burlywood;
????????position:?relative;
????}
????.child{
????????font-size:?20px;
????????color:?white;
????}
????.child1{
????????background-color:?black;
????????position:?absolute;
????????left:?0;
????}
????.child2{
????????background-color:?black;
????????position:?absolute;
????????left:?20px;
????}
????.child3{
????????background-color:?black;
????????position:?absolute;
????????right:?0;
????}
/*?3?*/
????.parent{
????????background-color:?burlywood;
????}
????.child1{
????????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:?black;
????????display:?table-cell;
????????height:?20px;
????}
????.child3{
????????display:?block;
????????margin-left:?auto;
????}
/*?5?*/
????.parent{
????????background-color:?burlywood;
????????position:?relative;
????}
????.child{
????????background-color:?black;
????????position:?absolute;
????????top:0;
????????left:0;
????}
????.child2{
????????transform:?translate(20px,?0);
????}
????.child3{
????????transform:?translate(180px,?0);
????}
/*?6?*/
??.parent{
????????background-color:?burlywood;
????????display:?grid;
????????grid-template-columns:?repeat(10,?1fr);
????}
????.child{
????????background-color:?black;
????????font-size:?20px;
????????color:white;
????}
????.child3{
????????grid-column:?10?/?11;
????}
/*?7?*/
????.parent{
????????background-color:?burlywood;
????????font-size:?0;
????}
????.child{
????????background-color:?black;
????????display:?inline-block;
????????font-size:?20px;
????????color:?white;
????}
????.child3{
????????margin-left:?140px;
????}
width:?0;
height:?0;
border:?solid?100px?red;
border-color:?red?transparent?transparent?transparent;
border-radius:?100px;
本文部分题目及答案来源于网络,如有错误,欢迎纠正,如有侵权问题,麻烦微信联系 winty230 交涉处理。
最后
欢迎加我微信(winty230),拉你进技术群,长期交流学习...
欢迎关注「前端Q」,认真学前端,做个专业的技术人...
原创不易,点个在看支持我吧