某银行前端一年半经验进字节面经

316次阅读  |  发布于3年以前

一面

  1. 高阶组件是什么?你设计这么一个水印组件,为什么用高阶组件。组件设计思路。
  2. 说一下水印组件的业务场景。如果有人要在控制台里通过删除 dom 的方式去除水印,怎么防范?(监听键盘事件 F12 禁止打开控制台)假设用户在控制台中通过 disable js 来禁用 js,监听事件无效了,又该怎么防范?(说了一下思路,比如点击 disable js 这个动作本身是可以监听到的,那么可以监听这个动作并且拦截,然后可以做一些自定义的操作,比如直接关闭掉页面)
  3. Dvajs 和 umijs 区别。
  4. Dvajs 中 redux 用处(展开聊聊状态管理的必要性和合理使用不滥用的思考)
  5. React 和 redux 是独立的,怎么关联起来使用(react-redux 中的 connect 和 provider 作用)
  6. react-redux 的性能问题(?)
  7. this 指向问题(箭头函数定义时确定,普通函数执行时确定)
class Student {
  constructor(name) {
    this.name = "Tom";
  }

  getInfo() {
    return {
      name: "Jerry",
      getName() {
        return this.name;
      },
    };
  }
}
let s = new Student();
console.log(s.getInfo().getName()); // Jerry
// 如何打印出Tom,只能修改class中代码
//(箭头函数,展开说一下this指向的问题)

8 . obj 实例化,修改属性和重新实例化的指针问题

function changeObjProperty(o) {
  o.siteUrl = "http://a.com";
  o = new Object();
  o.siteUrl = "http://b.com";
}

let s = new Object();
changeObjProperty(s);
console.log(s.siteUrl);

9 . 0.1 + 0.2 !== 0.3(精度丢失问题:IEEE 754。如何解决?比如按小数点拆分整数部分与小数部分,分别按位相加,注意进位处理。)

10 . 简述一下 SPA 与前端路由(扩展讲一下 ajax -> pjax -> history api 的 pushState, popState, replaceState。浏览器 url 的出栈入栈与这些 api 的关系,路由映射管理与组件渲染。)

11 . 编码:

/* 
 实现一个randomString函数,返回一个数组,
 该数组内有一千个字符串,
 每串字符串为6位数0-9的随机验证码,不可重复。
*/
function randomString() {
  //  write your code here
}

12 . 编码:

/*
  实现一个sum函数,接收一个arr,
  累加arr的项,只能使用add方法,
  该方法接收两个数,
  模拟异步请求后端返回一个相加后的值
*/
function add(a, b) {
  return Promise.resolve(a + b);
}

function sum(arr) {
  // 思路可以二分,切成两部分beforeSum, afterSum。
}

/*
变种:如果后端设置了并发限制,
一次不能请求超过三个,怎么办?
*/

二面

  1. css 题:实现一个 chrome 浏览器的后退按钮,鼠标移入有深色的圆形背景,内部是一个 90 度的角。
  2. 需求题:假设有 A 页面有一些 query 参数 点击打开 B 页面 要把 A 的参数带过去 然后 B 页面跳转到 C 页面 如果是 B 页面本身带的参数 就带到 C 页面 如果 B 页面的参数是 A 页面带过来的 那么就不带到 C 页面。(这一题基本花去了大部分时间,和面试官讨论了可行的思路,然后进行编码。主要是 query 参数的 merge 处理,跳转拦截之类的实现。)
  3. 常规题:把 123456789,变成金钱模式,即:12,345,678(思路有很多,比如 reverse 之后利用模除手动插入逗号...)
  4. 简历相关的内容不在这里记录了。

三面

  1. 编码题:
/*
  请实现抽奖函数rand,保证随机性
  输入为表示对象数组,对象有属性n表示人名,w表示权重
  随机返回一个中奖人名,中奖概率和w成正比
*/
let peoples = [
  { n: "p1", w: 100 },
  { n: "p2", w: 200 },
  { n: "p3", w: 1 },
];
let rand = function (p) {};

2 . 开放题:一个 html 引入一个超大 JS,js 中是一个乱序数字数组(长度巨大),从中找到最大值显示出来,遇到这种需求你该怎么做? 3 . 项目相关的问题不在这里记录了。

三轮技术面其实可以感觉出来一面会考察一些前端基础和源码相关的知识,二面三面还会问很多项目经验、管理方面的内容。比如 git 工作流、CI/CD 相关实践、重构的一些思考、选型的影响因素、自己平时学习的方式。因为我在银行里还会进行数据开发以及会一点 node 开发,这些也算是加分项吧。

HR 面

个人感觉 hr 面其实会带有一些博弈的成分,但是和 hr 聊天,尽量真诚就行,工作本来就是双方互相选择的,在目前公司的现状以及与自己职业规划产生的偏差,自己的期望发展、待遇其实可以真诚的说出来。最终字节给的待遇是令我感到满意的,我也很开心可以到更好的平台发展。(毕竟银行的技术底蕴确实没法和字节比,还是需要一个更好的平台提升自己,光靠自己实在不太行...)

感想

记得是三月底开始,那时候个人遭受了比较大的打击,工作也浑浑噩噩的,看不到出路,每天晚上失眠,白天工作状态也不好,还吃不下东西。字节那边联系过来问有没有时间面试,我就说了个日子开始面试了。就这样强迫自己开始看资料查漏补缺,心里反倒好受了一点。

还记得是那一个周日,窗外阳光很好,我和一面面试官聊了一个多小时。感觉氛围很轻松,有编程题但是确实难度不会高,边读题边把思路和面试官说了,然后开始编码。问的一些内容基本都可以答上,面试官每次听我说完就会点头然后说一句“好的,没问题。恩恩。我们看下一个。”我很感谢他让我久违地感受到,交流技术的愉悦。一面的末尾我问了一些职业规划的问题,他也很耐心的和我说了一些自己的经验,最后很感谢我可以在周末抽出时间面试。

一面的结果很快就出来了,当晚 hr 和我说的时候我其实还不太敢相信。因为我从毕业前就有尝试过投大厂,但是无一例外全部都是一轮游,我深深地怀疑自己的能力是否确实与这些大厂的岗位不匹配。毕业了进入银行其实也有点像逃避。接下来我和 hr 约定了下一轮面试的时间,并决定抛开那些不愉快的回忆,工作之余把全部精力投入到二面的准备中去。

然后我和之前实习时候带我的启蒙老师聊到我过了字节的一面,她还是像以往那样对我的求助耐心解答,也给了我一些资料让我查漏补缺。后来我又在 github 翻到了字节这边的同学编写的一份前端面试资料。时间一天天过去,这段时间的专注让我想起了那个高三,很明确的目标与每天的工作、加班、复习,出乎意料的让我心情很平静。

二面的时候,面试官对我说的第一句话就是“一面面试官对你的评价很不错,希望你继续努力。”。二面其实问了很多简历上的项目,包括一些实现细节,还有项目的使用场景、解决的痛点与技术实现上的难点。看得出来面试官也在尝试尽可能深入了解我以前做的东西,讨论过程中也不断提出了一些问题。而后就是一些常规的题,上面面经里写的那个路由跳转拦截传参的问题,面试官应该是考察我的编码能力,这道题应该花去了四十几分钟的时间,不断的提出自己的问题明确需求,不断的提出自己的思路讨论可行性,然后尝试编码。

其实我对二面的表现并不满意,忐忑地等待结果,最终还是等来了三面。三面前问了很多本来就在字节的同学,也在那时候加了昊神微信,到了宇宙条小分队,群里到处都是大佬,每天都能学到新东西,可开心了!

三面的面试官可能所处层次不一样,不太喜欢我说话的时候讲的太细或者举具体的例子,希望我说话可以简练、抽象。面试过程中被打断了好几次发言,让我不要展开讲很多,总结就可以了。编码题一直在和面试官讨论,因为当时真的一点思路都没有,当时就感觉这次是不是凉掉了... ...好在最后还是勉强写出来了,不过被说代码太复杂了。开放题如上面面经,还问了很多比较抽象的问题,感觉偏管理一些。

最后等来 hr 面的时候我突然感觉,我没自己想象中的差劲。和 hr 聊了现在的工作,以后的规划还有期望得到的待遇。之后走流程和 hrbp 谈妥薪资,拿到 offer 之后我和现在的领导聊了聊。其实我还是不太习惯离别,他问我要走的原因,和现在有哪些不满意的地方,然后恭喜我可以到更大的,技术底蕴更深的公司去。目前我在整理手头上的工作,交接完之后就要搬离这个待了快两年的地方,开始一段新的生活了。其实一个人在外漂泊,从一个地方到另一个地方,遇见一些人,告别一些人或者成为被告别的人。总是需要不停的想一想,这条路我想要通到哪儿。

祝愿大家都获得让自己满意的 offer!

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8