2021前端高频面试题整理,附答案

大家好,我是若川。最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12
若川视野原意是若川的前端视野。但太长了就留下了四个字,不知道的以为关注的不是技术公众号。

今天分享一篇慕课网精英讲师河畔一角的好文章~

废话不多说,上货!

手写Promise

这道题说实话已经老掉牙了,但是还是有不少公司会问,而且还有相当一部分前端写不出来

function Promise(callback){const pending = 'pending';const fulfilled = 'fulfilled';const rejected = 'rejected';// 当前状态this.state = pending;// 当前值this.value = null;// 失败原因this.reason = null;// 成功和失败数组对象this.fulfilledCallback = [];this.rejectedCallback = [];// 成功处理this.resolve = (data)=>{setTimeout(()=>{if(this.state == pending){this.state = fulfilled;this.value = data;this.fulfilledCallback.map(fn=>fn(this.value));}})}// 失败处理this.reject = (reason)=>{setTimeout(()=>{if(this.state == pending){this.state = rejected;this.reason = reason;this.rejectedCallback.map(fn=>fn(this.reason));}})}// 捕获成功和失败,扔到成功和失败数组this.then = function(succesFn,errorFn){this.fulfilledCallback.push(succesFn);this.rejectedCallback.push(errorFn);}// 捕获异常,直接扔到异常数组中this.catch = (errorFn)=>{this.rejectedCallback.push(errorFn);}// 默认需要执行一次resolve和rejectcallback(this.resolve,this.reject);
}// 验证结果
new Promise((resolve,reject)=>{setTimeout(()=>{resolve(10);},1000)
}).then((data)=>{console.log(data);
},(error)=>{console.log(error);
})

注意事项:

  • Promise要暴露then/catch方法

  • Promise构造函数接收一个立即执行的函数callback

  • then/catch只负责把回调放入数组即可

  • resolve/reject负责执行

  • resolve/reject 需要添加宏任务(setTimeout)

compose组合函数实现

  1. 后一个函数作为前一个函数的参数

  2. 最后一个函数可以接受多个参数,前面的函数只能接受单个参数;后一个的返回值传给前一个

// Demo:
const add = num => num  + 10
const multiply = num => num * 2
const foo = compose(multiply, add)
foo(5) => 30
// 聚合函数
export default function compose(...funcs) {// 如果是空,直接返回空函数并接受一个参数if (funcs.length === 0) {return arg => arg}// 如果有一个,直接执行并返回结果if (funcs.length === 1) {return funcs[0]}// 如果对reduce不了解,可以先去看下技术文章return funcs.reduce((a, b) => (...args) => a(b(...args)))
}

注意事项:

  • compose是一个聚合函数

  • compose执行后返回一个函数(所以这就是为什么当func.length==0的时候,要return一个箭头函数)

  • reduce始终返回一个箭头函数,后一个函数先执行并把结果作为前一个函数的参数,依次进行

数组柯里化Curry(求和)

阿里面试题

实现如下效果:
sum(1,3).sumOf()  4
sum(1,3)(2,4).sumOf() 10
function sum(){var arr = [].slice.apply(arguments);var fn = function(){arr = arr.concat([].slice.apply(arguments))return fn;}fn.sumOf = function(){return  arr.reduce((total,num)=>total+num,0);}return fn;
}

实现一个LazyPig

阿里面试题

实现一个LazyPig,可以按照以下方式调用:

LazyPig("Peggy") 
// 输出:
> Hello,I'm Peggy!
LazyPig("Peggy").sleep(10).eat("dinner")
// 输出
> Hello,I'm Peggy!
//等待10秒..
Wake up after 10
Eat dinner~
function LazyPig(name){console.log(`Hello,I'm ${name}`)var fn = {}fn.sleep = function(time){console.log(`Wake up ${time}`)let start = Date.now()while(Date.now()-start<=time){}console.log(`Wake up down`)return fn;}fn.eat = function(food){console.log(`Eat ${food}`)return fn;}return fn;
}

数组扁平化

let list = [1, 5, [9, 8], [2, [1, 9]], 7];
// 第一种方法:
console.log(list.toString().split(','));// 第二种方法:
function flatten(list) {return list.reduce((prev, item) => {return prev.concat(Array.isArray(item) ? flatten(item) : item);}, [])
}
console.log(flatten(list));

对象扁平化

/**
* 对象扁平化
* 说明:请实现 flatten(input) 函数,input 为一个 javascript 对象(Object 或者 Array),返回值为扁平化后的结果。
* 示例:
* var input = {
* a: 1,
* b: [ 1, 2, { c: true }, [ 3 ] ],
* d: { e: 2, f: 3 },
* g: null,
* }
* var output = flatten(input);
* output如下
* {
* "a": 1,
* "b[0]": 1,
* "b[1]": 2,
* "b[2].c": true,
* "b[3][0]": 3,
* "d.e": 2,
* "d.f": 3,
* // "g": null, 值为null或者undefined,丢弃
* }
*/
解答:
```js
let result = {};
var flatten = (data, key) => {if (data instanceof Array) {data.forEach((param, index) => {if (param instanceof Object) {flatten(param, `${key}[${index}]`);} else {result[`${key}[${index}]`] = param;}});} else if (data instanceof Object) {for (var itemKey in data) {const itemValue = data[itemKey];if (itemValue instanceof Object) {flatten(itemValue, itemKey);} else if (itemValue) {if (key) {result[`${key}.${itemKey}`] = flatten(itemValue, itemKey);} else {result[itemKey] = itemValue;}}}} else {return data;}
};
flatten(input);
console.log(result)

数组转换为Tree

// 数组转换成Tree
var list = [{id: 1, name: 'jack', pid: 0},{id: 2, name: 'jack', pid: 1},{id: 3, name: 'jack', pid: 1},{id: 4, name: 'jack', pid: 2},
]    const getTree = (root, result, pid) => {for (let i = 0; i < root.length; i++) {if (root[i].pid == pid) {let item = { ...root[i], children: [] }result.push(item)getTree(root, item.children, item.id)}}
}let array = [];
getTree(list, array, 0)
console.log(JSON.stringify(array))

对象深拷贝

// 对象深度克隆
let obj = {name: 'jack',age: 10,fn: () => {return this.name;},list: ['fe', 'node', 'small'],all: {child: true}
}
// 方法一:(面试官不想要)
JSON.parse(JSON.stringify(obj))
// 方法二:
function deepClone(obj){let result;if(typeof obj === 'object'){result = Array.isArray(obj) ? [] : {}for(let i in obj){result[i] = typeof obj[i] === 'object' ? deepClone(obj[i]):obj[i];}}else{result = obj;}return result;
}

贪心算法(找零)

商店老板有1、2、5、10面额的纸币,小伙买东西给了100花了80,计算如何找零是最佳(阿里面试题)

function MinCoinChange(coins) {return function(amount) {let total = 0, change = []for(let i= coins.length; i>=0; i--) {let coin = coins[i]while(total + coin <= amount) {change.push(coin)total += coin}}return change}
}MinCoinChange([1,2,5,10])(20)返回:10,10

数组去重(两次以上去重)

常规去重大家都知道Set

// 已知数组
var arr = [1,1,1,1,1,1,1,3,3,3,3,3,5,5];
// 方法一
function delRepeat(){arr = arr.sort();//先排序for(let i=0;i<arr.length;i++){if(arr[i] == arr[i+2]){arr.splice(i,1);i--;}}return arr;
}
// 方法二
function delRepeat(){var newArr = [];var obj = {};arr.map(item=>{if(obj[item]){obj[item] +=1 ;}else{obj[item] = 1;}obj[item]<=2?newArr.push(item):''})return newArr;
}

大数相加算法

大数相加有很多考题形式,有整数、小数、平方根等(腾讯考题)

已知:let a = "12345.12123",b="987654.92";

function sum(a,b){let arr1 = a.split(''),arr2 = b.split('');let count = 0;let arr = [];let a1 = a.split('.')[1],b1 = b.split('.')[1];let len = a1.length - b1.length;if(len>0)arr2.push(’0’.repeat(len))if(len<0)arr1.push(’0’.repeat(Math.abs(len)))while(arr1.length || arr2.length){let m = arr1.pop() || 0,n = arr2.pop() || 0;if(m != '.'){let num = Number(m) + Number(n) + count;if(num > 9){count = 1;num%=10;}else{count = 0;} arr.unshift(num);}else{arr.unshift('.');}}if(count>0)arr.unshift(count);let res = arr.join('');console.log(res);
}

如果是正整数,BigInt会更方便处理

二叉树求和

var treenode = {value: 1,left: {value: 2,left: {value: 4,},right: {value: 5,left: {value: 7,},right: {value: 8,},},},right: {value: 3,right: {value: 6,},},
}function sum(root) {let list = []if (root) list.push(root.value);if (root.left) {list = list.concat(sum(root.left));}if (root.right) {list = list.concat(sum(root.right));}return list;
}
console.log(sum(treenode));

爬楼梯

/*
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
思路:
f(1) : 1
f(2) : 11 , 2
f(3) : 12, 111, 21
f(4) : 121, 1111, 211, 112, 22
f(n) = f(n-1) + f(n-2)
*/
function fn(n) {if (n == 1) return 1;if (n == 2) return 2;return fn(n - 1) + fn(n - 2);
}
console.log(fn(4))

简易模板引擎

const template = '嗨,{{ info.name.value }}您好,今天是星期 {{ day.value }}';const data = {info: {name: {value: '张三'}},day: {value: '三'}
};function render(template, data) {return template.replace(/{{\s+?([\w.]+)\s+?}}/g, function ($0, $1) {return eval(`data.${$1}`)})
}const result = render(template, data); 
// 嗨,张三您好,今天是星期三
console.log(result)

前端模拟并发请求

已知当前有100个请求,每次只能同时调用5个,设计一个并发函数。

function send(){// 初始化数组let list = Array.from({length:100}).map((k,i)=>i)// 最大并发次数const limit = 5;//定义异步函数const asyncGet =async (item)=>{return item;}// 初始化100个异步请求函数,当闭包被执行的时候会执行一个请求,当请求执行完后,会获取下一个并执行const arr = []const handlers = ()=>{list = list.map(item=>{return ()=>{return asyncGet(item).then((res)=>{console.log('res:'+res)let next = list.shift();if(next){next()}else{console.log('全部执行完成')}})}})}handlers();// 一次性取出最大并发数并执行for(let i=0;i<limit;i++){let fn = list.shift();arr.push(fn())}Promise.all(arr).then((res)=>{})
}send();

防抖和节流(最经典的闭包案例)

/*
防抖:
定义:规定时间内,只触发一次,如果规定时间内再次调用,会清空继续创建新的任务。
场景:widow.onresize或者onscroll,或者搜索框
*/
function debounce(fn, wait) {var timeout = null;return function() {if(timeout !== null){clearTimeout(timeout);timeout = setTimeout(fn, wait);}else{timeout = setTimeout(fn, wait);}}
}
window.addEventListener('scroll', debounce(()=>{
// TO-DO
}, 500));
/*
节流:固定时间内,只触发一次。
场景:搜索框
*/
function throttle(fn,delay){let valid = truereturn function() {if(!valid){//休息时间 暂不接客return false }// 工作时间,执行函数并且在间隔期内把状态位设为无效valid = falsesetTimeout(() => {fn()valid = true;}, delay)}
}

以上就是本次给大家整理分享的前端算法面试题,绝不是从网上随意找的,很多都是我经历过的以及朋友面试的,希望对大家有帮助。


最近组建了一个江西人的前端交流群,如果你是江西人可以加我微信 ruochuan12 私信 江西 拉你进群。

推荐阅读

1个月,200+人,一起读了4周源码
我历时3年才写了10余篇源码文章,但收获了100w+阅读

老姚浅谈:怎么学JavaScript?

我在阿里招前端,该怎么帮你(可进面试群)

0ae3892a88d6d1d28cc746ea798df80e.gif

················· 若川简介 ·················

你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列
从2014年起,每年都会写一篇年度总结,已经写了7篇,点击查看年度总结。
同时,最近组织了源码共读活动

23cc9dfab77c5b35e42a5705b67dc50e.png

识别方二维码加我微信、拉你进源码共读

今日话题

略。欢迎分享、收藏、点赞、在看我的公众号文章~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/275277.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OO第二单元作业小结

总结性博客作业 第一次作业 (1)从多线程的协同和同步控制方面&#xff0c;分析和总结自己三次作业的设计策略。 第一次作业为单电梯傻瓜调度&#xff0c;可以采用生产者——消费者模型&#xff0c;是一个有一个生产者&#xff08;标准输入电梯请求&#xff09;&#xff0c;一个…

dribbble加速vpn_关于Dribbble设计的几点思考

dribbble加速vpn重点 (Top highlight)I’d like to start with the following quote from Paul Adam’s “The Dribbbilisation of Design,” a powerful read that examines the superficiality of modern product design portfolios, often containing Dribbble posts that l…

尤雨溪推荐神器 ni ,能替代 npm/yarn/pnpm ?简单好用!源码揭秘!

1. 前言大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以加我微信 ruochuan12想学源码&#xff0c;极力推荐之前我写的《学习源码整体架构系列》jQuery、underscore、lodash、vuex、sentry、axios、redux、koa、vue-devtools、vuex4、koa-compose、…

如何了解自己的认知偏差_了解吸引力偏差

如何了解自己的认知偏差Let me introduce you the attractiveness bias theory known as cognitive bias.让我向您介绍称为认知偏差的吸引力偏差理论。 Think about a person with outstanding fashion. It will draw our attention, and maybe encourage us to interact with…

隐马尔可夫模型(HMM)及Viterbi算法

HMM简介 对于算法爱好者来说&#xff0c;隐马尔可夫模型的大名那是如雷贯耳。那么&#xff0c;这个模型到底长什么样&#xff1f;具体的原理又是什么呢&#xff1f;有什么具体的应用场景呢&#xff1f;本文将会解答这些疑惑。  本文将通过具体形象的例子来引入该模型&#xf…

尤大直播分享:vue3生态进展和展望

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以加我微信 ruochuan12前言10月23日&#xff0c;参加了前端早早聊组织的【vue生态专场】&#xff0c;准备写一波分享方便大家学习。早上有4个话题&#xff1a;volar开发&#xff0c;搭建平台组件开发…

利用Python查看微信共同好友

思路 首先通过itchat这个微信个人号接口扫码登录个人微信网页版&#xff0c;获取可以识别好友身份的数据。这里是需要分别登录两人微信的&#xff0c;拿到两人各自的好友信息存到列表中。 这样一来&#xff0c;查共同好友就转化成了查两个列表中相同元素的问题。获取到共同好友…

女生适合学ux吗_UX设计色彩心理学,理论与可访问性

女生适合学ux吗Colour is an interesting topic, which I feel is often overlooked and sometimes under-appreciated. One of the first things I was taught was the power of colour, how it can have an impact on human emotion, and that there should be purpose behin…

初学者也能看懂的 Vue2 源码中那些实用的基础工具函数

1. 前言大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以加我微信 ruochuan12想学源码&#xff0c;极力推荐之前我写的《学习源码整体架构系列》jQuery、underscore、lodash、vuex、sentry、axios、redux、koa、vue-devtools、vuex4、koa-compose、…

视觉测试_视觉设计流行测验

视觉测试重点 (Top highlight)I often discuss the topic of improving visual design skills with junior and mid-level designers. While there are a number of design principles the designers should learn and practice, one important skill that is not often consid…

如何给开源项目提过 PR 呢?其实很简单

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以加我微信 ruochuan12源码共读群里有小伙伴聊到如何给开源项目提PR&#xff0c;所以今天分享这篇文章。你有给开源的库或者框架提过 PR 吗&#xff1f;如果没有&#xff0c;那么今天的文章会教你怎么…

一次回母校教前端的经历

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以加我微信 ruochuan12已进行了三个月&#xff0c;很多小伙伴都表示收获颇丰。分享一篇武大毕业的耀耀大佬的文章。有些时候会受限于环境影响&#xff0c;特别是在校大学生。所以要融入到积极上进的环…

设计插画工具_5个强大的设计师插画工具

设计插画工具As Product Designers, most likely, we have come across illustrative work. Visual design is one important element in enhancing the user experience. As many gravitate toward attractive looking products, designers are also adapting to the changing…

figma下载_切换到Figma并在其中工作不必是火箭科学,这就是为什么

figma下载We have seen Elon Musk and SpaceX making Rocket Science look like a child’s play. In the same spirit, should design tools be rocket science that is too hard to master? Not at all.我们已经看到埃隆马斯克(Elon Musk)和SpaceX使Rocket Science看起来像是…

npm、yarn、cnpm、pnpm 使用操作都在这了

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以加我微信 ruochuan12有时候想查个命令&#xff0c;或者换个镜像找了几篇文章才找到&#xff0c;最近闲着没事干&#xff0c;干脆整理一篇文档&#xff0c;以后就不用在网上瞎搜有的还写不全。Usage…

每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器,100行源码揭秘!

1. 前言大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以加我微信 ruochuan12 参与&#xff0c;已进行三个月了&#xff0c;大家一起交流学习&#xff0c;共同进步。想学源码&#xff0c;极力推荐之前我写的《学习源码整体架构系列》 包含jQuery、…

初级爬虫师_初级设计师的4条视觉原则

初级爬虫师重点 (Top highlight)Like many UXers, I got into the industry from a non-visual background (in my case it was Business and later on Human Cognition). Even though I found great benefits coming from those backgrounds, it also meant I had no UI/Visua…

开源监控解决方案OpenFalcon系列(一)

OpenFalcon是由小米的运维团队开源的一款企业级、高可用、可扩展的开源监控解决方案&#xff0c;&#xff0c;在众多开源爱好者的支持下&#xff0c;功能越来越丰富&#xff0c;文档更加的完善&#xff0c;OpenFalcon 已经成为国内最流行的监控系统之一。小米、美团、金山云、快…

如何利用 webpack 在项目中做出亮点

大家好&#xff0c;我是若川。最近这几年&#xff0c;在前端代码打包器领域内&#xff0c;webpack 算得上是时下最流行的前端打包工具。它可以分析各个模块的依赖关系&#xff0c;最终打包成我们常见的静态文件&#xff1a;.js 、 .css 、 .jpg 、.png&#xff0c;极大地提升了…

Github 王炸功能!Copilot 替代打工人编程?

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以加我微信 ruochuan12 参与&#xff0c;已进行三个月了&#xff0c;大家一起交流学习&#xff0c;共同进步。大家好&#xff0c;我是皮汤。最近组里在讨论一个有意思的工具 Github Copilot&#xff…