约的10月17日下午三点,14:42 进直播间,此时室友都还在睡觉。面试官大概三点过了几分才进来。简单的介绍了一下(没听清他说自己姓啥了)糊了一下就开始面试了。尽量还原一下情景,顺序可能有偏差。
幸好看了一下 moy 的面经,拿出了提前准备好的稿子开始吟唱
虽然没有提前准备过,但好歹都是自己亲生的娃,拿机房监控的项目吹了一下。中间问了几个技术问题,比如用了什么框架之类的。
当然,提到用 Websocket 传输视频的时候面试官两眼发光,给后面的问题打下了坚实的伏笔
一群背时研究生学长,跑的识别的代码不晓得在哪的 tutorial 改的,rtmp 识别完就变成 rawvideo 了。我在网上找了一堆方案最后拼出来了一个免去可以用的(flv.js + node-fluent-ffmpeg + 给学长的代码插了一段 socket 传 rawvideo 到 node的 py)
TCP,双向连接,持久不断开,兼容有问题
伏笔很快的就冒了出来,要不是用了好几次 Websocket 还写过一个同构的 json-websocket 工具怕是要遭
有个网站
MDN,刚刚那个网站是 canIuse
十分尴尬的忘了丢出来 StackOverflow 和 Google
ws
难不成我还会说用的是 express-ws 是因为别人给的 demo 是用的这个库
当然不是,前面要走 HTTP 来升级
101 Switching Protocol
还好之前写浏览器同构 WS 的时候看了一眼
仅限项目用到的
除了找怎么直播的时候看过一点各种直播方案以外还真没看过,可以看出来面试官是经常用 Websocket 而且还对视频直播很熟悉的,说不定是抖音那边的前端
[...arr]
, Array.from(arr)
写个 for 循环一个一个 push
直到写文的时候才想起来 ES5 通篇的都是 Array.prototype
Array.isArray()
, arr instanceof Array
,
“类数组判断不了吧”“判断不了吗”
当然判断不了啊,类数组都是一些名字都叫不出来的特殊类
大概讲了下同步会阻塞 UI 影响用户体验
宏任务和微任务那个吗(都讲一下吧) 开始口胡一通,这种东西看一下文档就会了,你问我他是啥我还真讲不出来
之前写 funcode 的时候就魔改过引擎的背时事件循环(加了一个用时间戳的事件系统),也被 Unity 背时的多重循环(Unity 应该是跑了好几个线程的循环)搞过,但是没怎么看过浏览器和 libuv 的东西。(突然想起自己还是看过一点背时的 epoll)。只能拿着宏任务和微任务吹一吹
console.log('script start') //1
async function async1() {
await async2()
console.log('async1 end')//5
}
async function async2() {
console.log('async2 end')//2
}
async1()
setTimeout(function() {
console.log('setTimeout')//8
}, 0)
new Promise(resolve => {
console.log('Promise')//3
resolve()
}).then(function() {
console.log('promise1')//6
}).then(function() {
console.log('promise2')//7
})
console.log('script end')//4
console.log('script start') //1
async function async1() {
await async2()
console.log('async1 end')//5
}
async function async2() {
console.log('async2 end')//2
}
async1()
setTimeout(function() {
console.log('setTimeout')//8
}, 0)
new Promise(resolve => {
console.log('Promise')//3
resolve()
}).then(function() {
console.log('promise1')//6
}).then(function() {
console.log('promise2')//7
})
console.log('script end')//4
在纸上画队列的时候面试官怀疑我在切 tab 搜答案,安逸牛客网,lose focus 了都不得通知
不清楚不知道没用过
大二做二手市场的时候用的,之后就一直在用
用的 Object.defineProperty(不过没说变异数组方法和后面改成 Proxy 了)
define 了 setter,然后变动的时候触发了 setter 更新 vDOM,再和 DOM 比较渲染
不知道,也有可能是和上一个时刻的 vDOM 吧
不知道,不清楚,没看过
不知道,不清楚,没用过
var x = 3;
var y = 4;
var obj = {
x: 1,
y: 6,
getX: function () {
var x = 5;
return function () {
return this.x;
}();
},
getY: function () {
var y = 7;
return this.y;
}
}
console.log(obj.getX());//5
console.log(obj.getY());//6
var x = 3;
var y = 4;
var obj = {
x: 1,
y: 6,
getX: function () {
var x = 5;
return function () {
return this.x;
}();
},
getY: function () {
var y = 7;
return this.y;
}
}
console.log(obj.getX());//5
console.log(obj.getY());//6
“5 和 7 吧”
“是吗”
“不对感觉是 5 和 6”
“5 和 6 对吧”
“应该是吧”
“那 this 指向的是哪呢”
”getX 的作用域吧”
“作用域吗,好吧”
后来在console里面跑了一下发现是 3 和 6,return 的函数 this 指向的是 window。
背时函数,安逸箭头函数。
不做
给定一个数组代表某支股票连续多个交易日的价格。你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
Input: [2, 3, 5, 1, 4]
Output: 3
Input: [ 5, 3, 2, 1]
Output: 0
一眼就看出来肯定是解法肯定是 O(n) 的,然后陷进 DP 列状态转移出不来了
非常无奈的写了暴力,面试官非常努力的鼓励我也想不出来
我用的多的 flex 和绝对定位,但是也可以 table-cell 和 margin
面试官:“margin 啊...”
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
“这个团队有多少人呢”
“不清楚,我不是他们团队的”
感觉表现的并不咋样,有好多东西都没有想起来。算法一如既往的垃圾,我太菜了罢。面试大概 50 分钟,结束后一个小时 HR 电话通知一面过了,约了二面。
二面的面试官好像在家里,但是又会时不时左右望一下,让人十分迷惑。但是周日加班也太惨了。跟一面一样面试官晚了几分钟才进房间。
掏出简介开始吟唱
跟一面几乎一样的梦幻开头,拿出二手市场开始吹
二手市场讲了讲记录查看位置,压缩图片之类的,然后又抱着智慧课堂那个直播讲了一遍
我 + 俩 java 后端 + python
是的
没有的(实际上 socket 的 url 都是后端返回拼出来的)
“配上 java 后端吗”“是的” 那就 java 登陆后返回 token,前端带着 token 去请求 websocket 面试官想了一会,非常不情愿的说好像可以 看起来他有一个别的方案,但是带 token 不是单点登陆的正常操作么
(实际上没做过)硬着头皮糊了个 XSS
一瞬间仿佛看见了 moy 面后端写的面经,脱口而糊
实际上拿了之前在 CTF 看 XSS 看到的一段背了出来
背时,没写过 XSS,现在 CTF 都不咋流行了
想起刚看的面经里面有一个跨域(虽然算不上啥安全问题),赶紧糊了上去试图转移话题
只记得两个,实际上有三四个
后端加跨域头
JSONP,但是没用过 还有我们用的 Websocket 也不会受跨域限制,因为鉴权是手动实现的,Websocket 后端可以随时断开连接
if (!Function.prototype.bind){
Function.prototype.bind = function (o) {
if (typeof this !== 'function') {
throw TypeError("Bind must be called on a function");
} else {
//Write here
let args = [...arguments].slice(1)
return () => this.apply(o, [...args, ...arguments])
}
}
if (!Function.prototype.bind){
Function.prototype.bind = function (o) {
if (typeof this !== 'function') {
throw TypeError("Bind must be called on a function");
} else {
//Write here
let args = [...arguments].slice(1)
return () => this.apply(o, [...args, ...arguments])
}
}
一开始写的时候写的return () => this.apply(this, [...args, ...arguments])
被面试官提醒参数 o 没有用到才改回来
(而且还忘了绑 prototype, 但面试官似乎没有发现)
面试官似乎短暂的理解不能,解释了一下 this 指向的是调用 bind 的函数之后反应过来
“嗯,应该也可以”
那是当然,毕竟我提前写了一下,在浏览器稍微调试过
这算法简直完全不用脑子,跟上一轮的一比就是 Easy 嘛
function findMaxDuplicateChar(str) {
let maxChar = '', maxValue = 1;
//Write here
let dict = {}
for(let i=0; i<str.length; i++) {
if(str[i] !== ' ')
dict[str[i]] = dict[str[i]] ? dict[str[i]] + 1 : 1
}
for(let c in dict) {
if(maxValue < dict[c]) {
maxValue = dict[c]
maxChar = c
}
}
return {
maxChar,
maxValue
};
}
const str = 'this is a fe test at toutiao on September';
console.log(findMaxDuplicateChar(str)) // output: { maxChar:"t", maxValue:7 }
function findMaxDuplicateChar(str) {
let maxChar = '', maxValue = 1;
//Write here
let dict = {}
for(let i=0; i<str.length; i++) {
if(str[i] !== ' ')
dict[str[i]] = dict[str[i]] ? dict[str[i]] + 1 : 1
}
for(let c in dict) {
if(maxValue < dict[c]) {
maxValue = dict[c]
maxChar = c
}
}
return {
maxChar,
maxValue
};
}
const str = 'this is a fe test at toutiao on September';
console.log(findMaxDuplicateChar(str)) // output: { maxChar:"t", maxValue:7 }
第一次遍历出来是空格(8 次),确认了一下不算空格以后写了一下
''.join(str.split(' '))
发现跑不起来
背时 JS,连 join 都没有
然后在循环里面加了个 if 判断
“这个跑的起来吗”
我在 QQ 里面回了一下消息发现面试官毫无反应
点了一下提交运行结果是对的
“跑的起来”
“那行吧”
面试官似乎不是非常擅长算法,倒是 moy 那个面试官相反
问了一下是啥部门的(广州的效率工程) 干什么的(to B) “我们会在一周之内通知你结果”
在听到一周之内通知的时候都感觉要凉了,毕竟前面答的很糊,而且上次一面之后一个小时就收到了电话。周一上午在厕所里的时候接到面试过了的电话,约了周四电话面。