记一次难堪的笔试经历
本文记录为非技术类文章,旨在记录一个让我无地自容的故事,鞭笞自己能知耻而后勇。
背景
故事要从 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 分钟,但接下来所发生的事就打破了我所有的预期、或则说幻想。
- 路灯的模拟数据要是数组,所以我拆分了组件
TrafficLight
和TrafficLightItem
,并且按照我记忆中我看过的 JSX 语法使用了 for 循环去生成多个TrafficLightItem
,但这一步报错了...一个 TS 的报错,而我明明使用的是 js...(截图为笔试后自己复现) 这个问题我试了很多方法:
- vscode 提示
lights
是any
类型,我想是不是需要明确定义为 Array 才不会报错,但 js 并不能定义类型 - 我怀疑是否是 HMR 有问题,编辑器也胡乱报了一个错,所以我重启工程,在浏览器上仍然报错
- 我怀疑是否是
lights
prop 没有传递过来,所以我直接把lights
定义在当前组件,甚至不定义变量直接使用模拟数据(一个Array)执行map
方法
- vscode 提示
- 要动态切换颜色,我需要知道 react 如何动态修改 style 样式,我尝试了几种写法,最终还是靠 Google 解决
- 要动态切换颜色,我需要知道 react 如何更新视图,事实上我知道是通过
setState
函数,但该函数如何调用,state
肯定又不能是普通变量,所以我又只能去 Google ,并且花了很长时间去调整、尝试setState
应该放到哪里去调用的问题(起初我放到render
函数中,视图卡住无法加载,我才意识到不能这么做),最终通过这篇文章才解决了我的各种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);
/** 2. 寻找特定 IP
IPV4 的 IP 地址是32位的二进制数,为增强可读性,通常我们以8位为1组进行分割,
用十进制来表示每一部分,并用点号连接,譬如 192.168.1.1。显然,存在这样的 IP 地址,
0到9十个数字各出现一次。具备这样特征的 IP 地址里,表示成二进制数时,二进制数左右对称
(也就是“回文”,表示成32位二进制不省略0)的情况有几种,分别是哪些?要求性能尽可能高
*/
function findPalindromeIPAddresses() {
// code goes here
}
// test
console.log(findPalindromeIPAddresses());
反思
15分钟也没解出的 bug 其实很简单,尘埃落定之后很快就发现了问题,有两个:
- 我用
await
去等待宏任务 - 闪烁函数中逻辑有些混乱,定义了
cur
却没修改他的值。
导致第一个问题的原因恐怕还是我写得太少,如此离谱的、用当朝剑去斩前朝官的事,我想不到还能找什么借口。等歉意和客套处理妥当,事实上我也很快解决了问题——新增了一个用于实现异步等待的 wait
函数。
第二个问题就不反思了。
总结与感悟
决定写这篇文章时,我心中还满是羞愧和难过,羞愧在于走了特殊通道,但表现得像一个小丑,难过在于,辜负了别人的信任。所以我想把不堪记录下来,督促自己今后学习稍多一点尽量避免这样的事故,也是想要写出来告诉和我接触的**和##,不要因为个例而沮丧,请一如既往相信应聘者。
正视自己的不堪,我才能变得强大。
2021/02/20 02:20
额外说明:本文无意拐弯抹角碰瓷阿里,在此也保证本次换工作不会再寻求任何阿里工作机会
转载自:https://juejin.cn/post/6931035465818570760