點擊上方“藍色字體”,選擇“設爲星標”
做積極向上的前端人!
來源:公衆號【前端從進階到入院】
https://mp.weixin.qq.com/s/8Gnx2d_Zo4Rwm2en0UOetg
本文記錄爲非技術類文章,旨在記錄一個讓我無地自容的故事,鞭笞自己能知恥而後勇。
背景
故事要從 2020 年末講起,屆時正值我司方向變動期,以往工作內容或將永遠捨棄,我多少也有些失望和迷茫,於是起了挪窩的心思。
恰巧,釘釘團隊的東明在不久後(2021年初)從簡歷庫中撈到了我,問我是否有換工作的意願,我欣然告訴他年後會考慮換工作。
期間偶爾準備...時間來到2021年二月19號(今天),春節前兩天首面的字節跳動,與我談好了 offer。我在感慨字節效率時,忽然想到如果還不內推阿里,或許在入職前沒辦法面完。
於是我匆匆忙忙地聯繫了東明,希望他幫我內推簡歷,並告訴他已經拿到了字節的 offer(不算節假日就幾天時間),他非常上心並願意幫我加急內推,我有些感動,告訴他如果流程來得及、或則加急比較麻煩就不需要加急。
他依然幫我加急了,但我沒想到的是,這在幾個小時後會成爲我無比羞愧的原因之一。
一刻鐘後,成都文檔這邊的前端負責人絕雲聯繫了我,詢問我什麼時間方便在線筆試,我有些受寵若驚,就像是特意爲我開了一個獨立的跑道,他們爲一個應聘者勞心勞力。
於是我略作思索,就把筆試時間定在了今晚9點。
歷程
閱題
9點左右,我收到了筆試題連接,一個半小時兩道筆試題,題目如下:
/** 1. 信號燈控制器
用 React 實現一個信號燈(交通燈)控制器,要求:
1. 默認情況下,
1.1. 紅燈亮20秒,並且最後5秒閃爍
1.2. 綠燈亮20秒,並且最後5秒閃爍
1.3. 黃燈亮10秒
1.4. 次序爲 紅-綠-黃-紅-綠-黃
2. 燈的個數、顏色、持續時間、閃爍時間、燈光次序都可配置,如:
lights=[{color: '#fff', duration: 10000, twinkleDuration: 5000}, ... ]
*/
import React from 'react'
import ReactDOM from 'react-dom'
class TrafficLightItem extends React.Component {
}
/** 2. 尋找特定 IP
IPV4 的 IP 地址是32位的二進制數,爲增強可讀性,通常我們以8位爲1組進行分割,
用十進制來表示每一部分,並用點號連接,譬如 192.168.1.1。顯然,存在這樣的 IP 地址,
0到9十個數字各出現一次。具備這樣特徵的 IP 地址裏,表示成二進制數時,二進制數左右對稱
(也就是“迴文”,表示成32位二進制不省略0)的情況有幾種,分別是哪些?要求性能儘可能高
*/
我查閱了題目,很快就發現了對我而言的難點:
-
第一道題要使用 react ,而我幾乎沒有使用過,但我相信這並不會成爲太大的阻礙,因試題並不複雜 -
第二道題比較晦澀,我一時沒有好的思路去解決
所以我制定好了我的答題計劃:
-
完成第一道題 -
第二道做一部分,來不及做的部分註釋思路
做題
我想首先要能跑得起來 react ,才能知道哪些語法能寫,所以我 Google 了 react ,在官網找到了快速起步 npx create-react-app test1
。
我打開項目,粗略看了下結構便快速地新建了 components/
和 .js/.css
文件,但下一刻我就遇到了第一個預料之外的問題,初始化的項目使用的是 function 組件,而題目使用的卻是 class 組件,我想模仿腳手架模板寫的心思有些許受挫。
還好我記得我看過 react 使用 class 組件的視頻,我不用像無頭蒼蠅一樣去翻文檔,於是我打開慕課網,找到了我歷史記錄中的 react 入門視頻,從中我找到了我想要的 class component 的寫法(藉助 vscode 的一個 react snippet 的插件),並且快速瀏覽了我之後會用到的 props 寫法。
由於初始化階段出了意外,所以我一直注意着時間,發現等我寫好主體結構、props 傳參後,才過了十餘分鐘,所以並沒有認爲事態有過失控。
我發現題目提供的數據結構並不能保證路燈完全可配置,因爲燈光顏色存在三種狀態,各個燈光的時間也應該單獨控制,所以我擴展了 props 傳參和模擬數據,並且完成了無邏輯狀態下組件的展示。
雖然有些不順利,但此時我並未感到焦急,因爲餘下的時間還有將近 70 分鐘,但接下來所發生的事就打破了我所有的預期、或則說幻想。
TS 報錯
-
路燈的模擬數據要是數組,所以我拆分了組件 TrafficLight
和TrafficLightItem
,並且按照我記憶中我看過的 JSX 語法使用了 for 循環去生成多個TrafficLightItem
,但這一步報錯了...一個 TS 的報錯,而我明明使用的是 js...
截圖爲筆試後自己復現) 這個問題我試了很多方法:
-
vscode 提示 lights
是any
類型,我想是不是需要明確定義爲 Array 纔不會報錯,但 js 並不能定義類型 -
我懷疑是否是 HMR 有問題,編輯器也胡亂報了一個錯,所以我重啓工程,在瀏覽器上仍然報錯 -
我懷疑是否是 lights
prop 沒有傳遞過來,所以我直接把lights
定義在當前組件,甚至不定義變量直接使用模擬數據(一個Array)執行map
方法
最終嘗試在 return 中加一個根節點,就不再報錯了...
動態修改樣式
-
要動態切換顏色,我需要知道 react 如何動態修改 style 樣式,我嘗試了幾種寫法,最終還是靠 Google 解決
更新視圖
要動態切換顏色,我需要知道 react 如何更新視圖,事實上我知道是通過 setState
函數。
但該函數如何調用,state
肯定又不能是普通變量,所以我又只能去 Google ,並且花了很長時間去調整、嘗試 setState
應該放到哪裏去調用的問題(起初我放到 render
函數中,視圖卡住無法加載,我才意識到不能這麼做)。
最終通過這篇文章[1]才解決了我的各種 this
、setState
、state
問題
以上種種處理完畢,時間已然沒了大半,還剩半個小時我焦急無比。
但我並沒有放棄,或許當時的我認爲我已然能做好第一題,或許只是沒有足夠的時間做第二道題而已。
但事實往往更加殘酷,之後 10 分鐘,我寫好了三個狀態切換相關的函數:閃爍函數twinkle
、初始化狀態函數 init
和循環進行初始化的函數 lightInterval
,並處理定時器中 this 指向的問題,但我想要的路燈狀態切換並沒有出現。
而後 15 分鐘便是我最最煎熬的調試時間,我焦急又麻木的一次又一次的嘗試,但就是沒有解決一個問題。我的狀態切換一直沒有出現,我知道是異步導致的問題,但我並不知道爲什麼會這樣,我的思維似乎在寫完關鍵函數後就進入了停滯狀態...
10點25分,面試官提醒我準備交卷,我還精神恍惚地掙扎了兩分鐘,最終在10點28交卷,並通過釘釘艱難地向面試官提出放棄。
代碼
以下就是一個工作將近五年,自詡功底不錯的前端交出的試卷原樣:
/** 1. 信號燈控制器
用 React 實現一個信號燈(交通燈)控制器,要求:
1. 默認情況下,
1.1. 紅燈亮20秒,並且最後5秒閃爍
1.2. 綠燈亮20秒,並且最後5秒閃爍
1.3. 黃燈亮10秒
1.4. 次序爲 紅-綠-黃-紅-綠-黃
2. 燈的個數、顏色、持續時間、閃爍時間、燈光次序都可配置,如:
lights=[{color: '#fff', duration: 10000, twinkleDuration: 5000}, ... ]
*/
import React from 'react'
import ReactDOM from 'react-dom'
class TrafficLightItem extends React.Component {
constructor(props) {
super(props);
const {
stopColor = "red",
passColor = "green",
pendingColor = "yellow",
stopDuration = 20000,
stopTwinkleDuration = 5000,
passDuration = 20000,
passTwinkleDuration = 5000,
pendingDuration = 10000,
} = this.props.config;
this.stopColor = stopColor
this.passColor = passColor
this.pendingColor = pendingColor
this.stopDuration = stopDuration
this.stopTwinkleDuration = stopTwinkleDuration
this.passDuration = passDuration
this.passTwinkleDuration = passTwinkleDuration
this.pendingDuration = pendingDuration
this.state = {
coolr: this.stopColor
};
}
// initial
async init() {
// stop color
await setTimeout(() => {}, this.stopDuration - this.stopTwinkleDuration);
// stop color twinkle
await this.twinkle(this.stopColor, this.stopTwinkleDuration)
// switch to pass color
this.setState({
color: this.passColor,
});
await setTimeout(() => {}, this.passDuration - this.passTwinkleDuration);
// pass color twinkle
await this.twinkle(this.passColor, this.passTwinkleDuration)
// switch to pending color
this.setState({
color: this.pendingColor,
});
}
// interval
async lightInterval() {
this.init()
let totalDuration = this.stopDuration + this.passDuration + this.pendingDuration;
setInterval(this.init, totalDuration);
}
// 閃爍
async twinkle(color, duration) {
let _timer
await setTimeout(() => {
let cur = color
_timer = setInterval(() => {
if (cur === color) {
this.setState({
color: 'black'
})
} else {
this.setState({
color
})
}
}, 1000);
}, duration)
clearInterval(_timer)
}
componentDidMount() {
this.timer = this.lightInterval();
}
componentWillUnmount() {
clearInterval(this.timer);
}
render() {
return (
<div class="light" style={{ backgroundColor: this.state.color }}></div>
);
}
}
class TrafficLight extends React.Component {
render() {
const lights = this.props.lights;
return (
<div>
{lights.map((light, index) => (
<TrafficLightItem key={index} config={light}></TrafficLightItem>
))}
</div>
);
}
}
ReactDOM.render(<TrafficLight/>, document.body);
反思
15分鐘也沒解出的 bug 其實很簡單,塵埃落定之後很快就發現了問題,有兩個:
-
我用 await
去等待宏任務 -
閃爍函數中邏輯有些混亂,定義了 cur
卻沒修改他的值。
導致第一個問題的原因恐怕還是我寫得太少,如此離譜的、用當朝劍去斬前朝官的事,我想不到還能找什麼藉口。
等歉意和客套處理妥當,事實上我也很快解決了問題——新增了一個用於實現異步等待的 wait
函數。
總結與感悟
決定寫這篇文章時,我心中還滿是羞愧和難過。
羞愧在於走了特殊通道,但表現得像一個小丑,難過在於,辜負了別人的信任。
所以我想把不堪記錄下來,督促自己今後學習稍多一點儘量避免這樣的事故,也是想要寫出來告訴和我接觸的東明和絕雲,不要因爲個例而沮喪,請一如既往相信應聘者。
正視自己的不堪,我才能變得強大。
額外說明:本文無意拐彎抹角碰瓷阿里,在此也保證本次換工作不會再尋求任何阿里工作機會。
點擊關注下方卡片關注我👇👇
如果覺得這篇文章還不錯,來個【分享、點贊、在看】三連吧,讓更多的人也看到~
本文分享自微信公衆號 - 前端佈道師(honeyBadger8)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。