本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
来源:公众号【前端从进阶到入院】
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. 寻找特定 IPIPV4 的 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 有问题,编辑器也胡乱报了一个错,所以我重启工程,在浏览器上仍然报错
我怀疑是否是
lightsprop 没有传递过来,所以我直接把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 函数。
总结与感悟
决定写这篇文章时,我心中还满是羞愧和难过。
羞愧在于走了特殊通道,但表现得像一个小丑,难过在于,辜负了别人的信任。
所以我想把不堪记录下来,督促自己今后学习稍多一点尽量避免这样的事故,也是想要写出来告诉和我接触的东明和绝云,不要因为个例而沮丧,请一如既往相信应聘者。
正视自己的不堪,我才能变得强大。
额外说明:本文无意拐弯抹角碰瓷阿里,在此也保证本次换工作不会再寻求任何阿里工作机会
ssh 注:
金三银四来了,可能部分同学会有换坑的想法,本文是一个相对反面的教材,希望能让大家吸取一些经验。
准备好之前不要轻易接受面试,不要冲动,大公司面试都会留下评价记录。
对于自己不熟悉的技术不要过分自信,可以尝试要求面试官切换到自己熟悉的技术栈上。
最后
欢迎关注【前端瓶子君】✿✿ヽ (°▽°) ノ✿
回复「算法」,加入前端算法源码编程群,每日一刷(工作日),每题瓶子君都会很认真的解答哟!
回复「交流」,吹吹水、聊聊技术、吐吐槽!
回复「阅读」,每日刷刷高质量好文!
如果这篇文章对你有帮助,「在看」是最大的支持
》》面试官也在看的算法资料《《
“在看和转发” 就是最大的支持