“This article has participated in the good article summoning order activity, click to view: back end, big front double track submission, 20,000 yuan prize pool for you to challenge”
background
In January this year, I was very lucky to participate in the first interview of Alibaba in my life
In one side, the interviewer did not ask too many questions, the first is three pen questions, an hour to complete
The first two questions are array of questions, with half an hour, A out, at that time write very cool, so did not record the question
In the third question, the building Lord failed, wrote half, card train of thought, finally still did not write complete 🙃. Finally, I took note of the question when the interviewer wasn’t looking
This topic in the backlog inside hang for half a year, these few smallpox a lot of time to study this problem, finally solved, the next is the original problem and my problem solving process (in the face of the wind! ✨)
Topic describes
To implement an EatMan, EatMan can have some examples of the following behaviors:1. EatMan('Hank') Output: Hi! This is Hank!2. EatMan('Hank').eat('dinner').eat('supper'Output) Hi! This is Hank! Eat dinner~ Eat supper~3. EatMan('Hank').eat('dinner').eatFirst('lunch'Output Eat lunch~ Hi! This is Hank! Eat dinner~4. EatMan('Hank').eat('dinner').eatFirst('lunch').eatFirst('breakfast'Output Eat breakfast~ Eat lunch~ Hi! This is Hank! Eat dinner~Copy the code
Train of thought analysis and hand tear code
(PS: The answer is long, I hope you can read it patiently.)
Step 1: Give it a try 🐱🏍
We examine the first and second test cases of the problem
1. EatMan('Hank'Output) Hi! This is Hank!2. EatMan('Hank').eat('dinner').eat('supper'Output) Hi! This is Hank! Eat dinner~ Eat supper~Copy the code
Thought analysis
It’s not hard to see what they want to examine
- The use of JavaScript classes (why classes? Because we can take
eat
This method is considered a property of the EatMan instance. - Implementation of chained calls
Let’s try to write some code
Code implementation
/* * @Date: 2021-07-15 13:49:04 * @LastEditors: cunhang_wwei * @LastEditTime: 2021-07-15 14:08:34 * @Description: EatMan's initial attempt */
class MyEatMan {
constructor(name) {
this.name = name
this.printName(this.name)
}
// Print the name
printName(name) {
console.log(`Hi! This is ${name}! `)}eat(thing) {
console.log(`Eat ${thing}~ `)
// Return this. Pass the pointer to implement the chained call
return this}}/ / instantiate
function EatMan(name) {
return new MyEatMan(name)
}
Copy the code
// Test case 1
EatMan('Hank')
/** * output * Hi! This is Hank! * /
// Test case 2
EatMan('Hank').eat('dinner').eat('supper')
/** * output * Hi! This is Hank! * Eat dinner~ * Eat supper~ */
Copy the code
Let’s test it out
Discovery returns the answer we’re looking for
Is a little small sense of achievement 😀, that we continue!
Step 2: Advanced 🐱👓
Analyze the third and fourth test cases
3. EatMan('Hank').eat('dinner').eatFirst('lunch'Output Eat lunch~ Hi! This is Hank! Eat dinner~4. EatMan('Hank').eat('dinner').eatFirst('lunch').eatFirst('breakfast'Output Eat breakfast~ Eat lunch~ Hi! This is Hank! Eat dinner~Copy the code
Thought analysis
We see a big change, eatFirst changes the order in which the functions are executed
Experienced bosses see the order and get it right away
The knowledge of task queues is examined
Building Lord before was in this place card train of thought, did not make finally 😅
We had to make a big change to the code we wrote in the first step, and that was to add the task queue
Code implementation
class MyEatMan {
constructor(name) {
this.name = name
// Queue the functions that need to be executed
this.tasks = []
// The first task
const task = this.printName(this.name)
// Put it in the task queue
this.tasks.push(task)
/ / execution
this.run()
}
// Print the name
printName(name) {
return function() {
console.log(`Hi! This is ${name}! `)}}// the eat function queues one task each time it is called
eat(thing) {
const task = function() {
console.log(`Eat ${thing}~ `)}this.tasks.push(task)
this.run()
return this
}
// run Executes the task
run() {
/ / out of the team
const currTask = this.tasks.shift()
/ / execution
currTask && currTask()
}
}
Copy the code
Let’s test it out
// Test case 1
EatMan('Hank')
/** * output * Hi! This is Hank! * /
Copy the code
// Test case 2
EatMan('Hank').eat('dinner').eat('supper')
/** * output * Hi! This is Hank! * Eat dinner~ * Eat supper~ */
Copy the code
If the output is consistent with the answer, then our transformation is OK
Step 3: Perfect 👏
Finally, we implement the eatFirst function
Thought analysis
eatFirst
Function has a queue-jumping functioneatFirst
Then the task can be inserted into the queue head of the task queuenew MyEatMan()
The task queue cannot be executed immediately, but is executed after the task has been queued- When each task is completed, the next task is triggered to ensure the continuity of tasks
Code implementation
class MyEatMan {
constructor(name) {
this.name = name
// Queue the functions that need to be executed
this.tasks = []
// The first task
const task = this.printName(this.name)
// Put it in the task queue
this.tasks.push(task)
// To ensure that all tasks are executed after they have been queued, create a macro task and place the time to execute the task in the next event loop
let self = this
setTimeout(function () {
// console.log('tasks', self.tasks)
self.run()
}, 0)}// Print the name
printName(name) {
let self = this
return function () {
console.log(`Hi! This is ${name}! `)
self.run()
}
}
// the eat function queues one task at a time and implements chained calls
eat(thing) {
let self = this
const task = function () {
console.log(`Eat ${thing}~ `)
self.run()
}
this.tasks.push(task)
return this
}
// eatFirst function, who initializes last, who executes first, and can implement chain calls
eatFirst(thing) {
let self = this
const task = function () {
console.log(`Eat ${thing}~ `)
self.run()
}
// Insert into the head of the queue
this.tasks.unshift(task)
return this
}
// run Executes the task
run() {
/ / out of the team
const currTask = this.tasks.shift()
/ / execution
currTask && currTask()
}
}
function EatMan(name) {
return new MyEatMan(name)
}
Copy the code
We use test cases to test
// Test case 3
EatMan('Hank').eat('dinner').eatFirst('lunch')
/** * output * Eat lunch~ * Hi! This is Hank! * Eat dinner~ */
Copy the code
// Test case 4
EatMan('Hank').eat('dinner').eatFirst('lunch').eatFirst('breakfast')
/** * output * Eat breakfast~ * Eat lunch~ * Hi! This is Hank! * Eat dinner~ */
Copy the code
The output is exactly the same as the answer!
The job is done!
The last
About the interview, the interviewer is very merciful, let me into the second interview, but I was not fully prepared at that time, the answer is not very good, the second interview on the hang 🤦♂️
I hope you have learned something after reading this article, if it can help you in front of the screen, to solve this problem, that would be the best
I am 970, good good study will not be bad, we make progress together!
And finally, finally, push in! Place shenzhen, I hope the big guys positive message ah!