「本文已參與好文召集令活動,點擊查看:後端、大前端雙賽道投稿,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,好好學習不會差,你們一塊兒進步!
最後的最後,求內推!地點深圳,但願大佬們積極留言啊!