「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2 万元奖池等你挑战」javascript
在今年一月份,颇有幸参加了人生中的第一次阿里巴巴的面试,记忆尤新前端
在一面的时候,面试官没有过多的提问,一上来就是三道笔试题,一个小时完成java
前两题是数组的题目,用了半个小时,就 A 出来了,当时写得挺爽,因而没有记录题目web
在第三题,楼主就败北了,写了一半,就卡思路了,最后仍是没能写完整 🙃。最后趁面试官不注意把问题记录一下了面试
这个题目在待办里边挂了整整半年,这几天花了挺多时间来研究这题,最后终于搞定,接下来就是原题目和个人解题过程(面对疾风吧!✨)后端
实现一个EatMan
说明:实现一个EatMan,EatMan能够有如下一些行为
示例:
1. EatMan('Hank')输出:
Hi! This is Hank!
2. EatMan('Hank').eat('dinner').eat('supper')输出
Hi! This is Hank!
Eat dinner~
Eat supper~
3. EatMan('Hank').eat('dinner').eatFirst('lunch')输出
Eat lunch~
Hi! This is Hank!
Eat dinner~
4. EatMan('Hank').eat('dinner').eatFirst('lunch').eatFirst('breakfast')输出
Eat breakfast~
Eat lunch~
Hi! This is Hank!
Eat dinner~
复制代码
(ps: 解题篇幅较长,但愿你们耐心看完)数组
咱们分析题目的第一个和第二个测试用例markdown
1. EatMan('Hank')输出
Hi! This is Hank!
2. EatMan('Hank').eat('dinner').eat('supper')输出
Hi! This is Hank!
Eat dinner~
Eat supper~
复制代码
思路分析app
不难发现题目是想考察的是函数
eat
这个方法看作是 EatMan 实例的一个属性)咱们尝试写一写代码
代码实现
/* * @Date: 2021-07-15 13:49:04 * @LastEditors: cunhang_wwei * @LastEditTime: 2021-07-15 14:08:34 * @Description: eatMan的初步尝试 */
class MyEatMan {
constructor(name) {
this.name = name
this.printName(this.name)
}
// 打印名字
printName(name) {
console.log(`Hi! This is ${name}!`)
}
eat(thing) {
console.log(`Eat ${thing}~`)
// 返回 this 传递指针实现链式调用
return this
}
}
// 实例化
function EatMan(name) {
return new MyEatMan(name)
}
复制代码
// 测试用例1
EatMan('Hank')
/** * 输出 * Hi! This is Hank! */
// 测试用例2
EatMan('Hank').eat('dinner').eat('supper')
/** * 输出 * Hi! This is Hank! * Eat dinner~ * Eat supper~ */
复制代码
进行一下测试
发现返回了咱们想要的答案
是否是有点小成就感了 😀,那咱们继续!
分析第三个和第四个测试用例
3. EatMan('Hank').eat('dinner').eatFirst('lunch')输出
Eat lunch~
Hi! This is Hank!
Eat dinner~
4. EatMan('Hank').eat('dinner').eatFirst('lunch').eatFirst('breakfast')输出
Eat breakfast~
Eat lunch~
Hi! This is Hank!
Eat dinner~
复制代码
思路分析
咱们发现题目有了一个很大的改变,eatFirst
会改变函数执行的顺序
有经验的大佬们一看到顺序,立马就悟了
对~ 考察的就是任务队列的知识
楼主以前就是在这个地方卡了思路,最后没有作出来 😅
咱们得对咱们第一步写的代码进行一个大改造,那就是增长任务队列
代码实现
class MyEatMan {
constructor(name) {
this.name = name
// 任务队列,将须要执行的函数入队
this.tasks = []
// 第一个任务
const task = this.printName(this.name)
// 放入任务队列
this.tasks.push(task)
// 执行
this.run()
}
// 打印名字
printName(name) {
return function() {
console.log(`Hi! This is ${name}!`)
}
}
// eat函数,每次调用都入队一个任务
eat(thing) {
const task = function() {
console.log(`Eat ${thing}~`)
}
this.tasks.push(task)
this.run()
return this
}
// run执行任务
run() {
// 出队
const currTask = this.tasks.shift()
// 执行
currTask && currTask()
}
}
复制代码
进行一下测试
// 测试用例1
EatMan('Hank')
/** * 输出 * Hi! This is Hank! */
复制代码
// 测试用例2
EatMan('Hank').eat('dinner').eat('supper')
/** * 输出 * Hi! This is Hank! * Eat dinner~ * Eat supper~ */
复制代码
发现输出结果和答案一致,那说明咱们的改造是 OK 的
最后,咱们来实现eatFirst
函数
思路分析
eatFirst
函数有插队的功能,执行到了eatFirst
以后,才能把该任务插入到任务队列的队头new MyEatMan()
的时候不能当即执行任务队列,而是在任务进队完毕以后才执行代码实现
class MyEatMan {
constructor(name) {
this.name = name
// 任务队列,将须要执行的函数入队
this.tasks = []
// 第一个任务
const task = this.printName(this.name)
// 放入任务队列
this.tasks.push(task)
// 为了保证任务都能在进队完毕以后再执行,建立一个宏任务,让执行任务的时机放到 下一个事件循环里
let self = this
setTimeout(function () {
// console.log('tasks', self.tasks)
self.run()
}, 0)
}
// 打印名字
printName(name) {
let self = this
return function () {
console.log(`Hi! This is ${name}!`)
self.run()
}
}
// eat函数,每次调用都入队一个任务,并且还能实现链式调用
eat(thing) {
let self = this
const task = function () {
console.log(`Eat ${thing}~`)
self.run()
}
this.tasks.push(task)
return this
}
// eatFirst函数,谁最后初始化,谁先执行,并且还能实现链式调用
eatFirst(thing) {
let self = this
const task = function () {
console.log(`Eat ${thing}~`)
self.run()
}
// 插入到队列的头部
this.tasks.unshift(task)
return this
}
// run执行任务
run() {
// 出队
const currTask = this.tasks.shift()
// 执行
currTask && currTask()
}
}
function EatMan(name) {
return new MyEatMan(name)
}
复制代码
咱们使用测试用例进行测试
// 测试用例3
EatMan('Hank').eat('dinner').eatFirst('lunch')
/** * 输出 * Eat lunch~ * Hi! This is Hank! * Eat dinner~ */
复制代码
// 测试用例4
EatMan('Hank').eat('dinner').eatFirst('lunch').eatFirst('breakfast')
/** * 输出 * Eat breakfast~ * Eat lunch~ * Hi! This is Hank! * Eat dinner~ */
复制代码
输出结果和答案彻底一致!
大工告成了!
关于面试,面试官大发慈悲,让我进入了二面,可是本身当时没有充分地准备,回答得不是很好,二面就挂掉了🤦♂️
但愿你们看完这个文章都有所收获,若是能帮助屏幕前的你,解决了这个题目,那就最好不过了
我是970,好好学习不会差,你们一块儿进步!
最后的最后,求内推!地点深圳,但愿大佬们积极留言啊!