一次羞愧難當的阿里前端筆試經歷(比PUA更難受!)

點擊上方“藍色字體”,選擇“設爲星標

做積極向上的前端人!

來源:公衆號【前端從進階到入院】

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 ,而我幾乎沒有使用過,但我相信這並不會成爲太大的阻礙,因試題並不複雜
  • 第二道題比較晦澀,我一時沒有好的思路去解決

所以我制定好了我的答題計劃:

  1. 完成第一道題
  2. 第二道做一部分,來不及做的部分註釋思路

做題

我想首先要能跑得起來 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 報錯

  1. 路燈的模擬數據要是數組,所以我拆分了組件  TrafficLight 和  TrafficLightItem,並且按照我記憶中我看過的 JSX 語法使用了 for 循環去生成多個  TrafficLightItem,但這一步報錯了...一個 TS 的報錯,而我明明使用的是 js...


截圖爲筆試後自己復現) 這個問題我試了很多方法:

  • vscode 提示  lights 是  any 類型,我想是不是需要明確定義爲 Array 纔不會報錯,但 js 並不能定義類型
  • 我懷疑是否是 HMR 有問題,編輯器也胡亂報了一個錯,所以我重啓工程,在瀏覽器上仍然報錯
  • 我懷疑是否是  lights prop 沒有傳遞過來,所以我直接把  lights定義在當前組件,甚至不定義變量直接使用模擬數據(一個Array)執行  map 方法

最終嘗試在 return 中加一個根節點,就不再報錯了...


動態修改樣式

  1. 要動態切換顏色,我需要知道 react 如何動態修改 style 樣式,我嘗試了幾種寫法,最終還是靠 Google 解決

更新視圖

要動態切換顏色,我需要知道 react 如何更新視圖,事實上我知道是通過 setState 函數。

但該函數如何調用,state 肯定又不能是普通變量,所以我又只能去 Google ,並且花了很長時間去調整、嘗試 setState 應該放到哪裏去調用的問題(起初我放到 render 函數中,視圖卡住無法加載,我才意識到不能這麼做)。

最終通過這篇文章[1]才解決了我的各種 thissetStatestate 問題

以上種種處理完畢,時間已然沒了大半,還剩半個小時我焦急無比。

但我並沒有放棄,或許當時的我認爲我已然能做好第一題,或許只是沒有足夠的時間做第二道題而已。

但事實往往更加殘酷,之後 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 = {
      coolrthis.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({
      colorthis.passColor,
    });
    await setTimeout(() => {}, this.passDuration - this.passTwinkleDuration);

    // pass color twinkle
    await this.twinkle(this.passColor, this.passTwinkleDuration)

    // switch to pending color
    this.setState({
      colorthis.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 其實很簡單,塵埃落定之後很快就發現了問題,有兩個:

  1. 我用  await 去等待宏任務
  2. 閃爍函數中邏輯有些混亂,定義了  cur 卻沒修改他的值。

導致第一個問題的原因恐怕還是我寫得太少,如此離譜的、用當朝劍去斬前朝官的事,我想不到還能找什麼藉口。

等歉意和客套處理妥當,事實上我也很快解決了問題——新增了一個用於實現異步等待的 wait 函數。

總結與感悟

決定寫這篇文章時,我心中還滿是羞愧和難過

羞愧在於走了特殊通道,但表現得像一個小丑,難過在於,辜負了別人的信任

所以我想把不堪記錄下來,督促自己今後學習稍多一點儘量避免這樣的事故,也是想要寫出來告訴和我接觸的東明和絕雲,不要因爲個例而沮喪,請一如既往相信應聘者。

正視自己的不堪,我才能變得強大。

額外說明:本文無意拐彎抹角碰瓷阿里,在此也保證本次換工作不會再尋求任何阿里工作機會。


點擊關注下方卡片關注我👇👇




我是怎麼倒在字節第二輪面試上的...
漫畫 | 如何憑實力炒老闆魷魚,並喜提N+1~
漫畫 | 再見 Java,再見Java之父
面試官:Vue3.0的設計目標是什麼?做了哪些優化?
面試官問 Vue 性能優化,我該怎麼回答?
Vue3.0 高頻出現的幾道面試題
面試官問 Vue 性能優化,我該怎麼回答?
漫畫 | 從西遊記看產品經理和程序員的關係!

如果覺得這篇文章還不錯,來個【分享、點贊、在看】三連吧,讓更多的人也看到~


本文分享自微信公衆號 - 前端佈道師(honeyBadger8)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章