【面试】2020年底面经
功夫不负有心人,【有赞】目标冲击完成,过个好年
# 结果
【有赞】 经历过五面,终于在年前最后一天发了 offer
# 原因
离职的原因无非就那几种,钱少事多不开心。
# 个人问题
- 个人话太多,容易抢话
- 回答问题容易跑题, 答非所问
- 算法薄弱
# 面试结果
# 微点科技(offer)
# 涂鸦智能(现场挂)
# 海康威视(电话挂)
# 端点科技(offer)
# 有赞(offer)
# 一面(电话 1h)
- 讲讲最近的项目
- 讲讲自己写的打印插件,vue-iframe-print,和其他打印方式对比。分页问题,默认背景图如何显示(知道有 css,但是记不住是那个),自定义样式等等
- 权限系统(RBAC),具体实现,接口权限校验。通用接口如何校验,可复用的业务接口如何校验
- OAuth 2.0 按照当前公司的一些单点登录流程来讲的,貌似不是标准的 oauth,得下去了解一下。
- 微前端(项目在用) 为什么要用微前端,和 iframe 对比了一下。微前端和容器之间的通信方式(目前 storage,也不是很好的办法)。
- 实现一个水平垂直居中
几种方式:flex,margin,absolute,table-cell,grid
flex:1 含义? 0 1 auto ,放大 缩小 基础宽度
改变主轴方向?(flex-direction)
主盒子 500px,三个子盒子:1 盒子 100px,2 盒子 flex:3,3 盒子 flex:1; 3 盒子的具体宽度是多少,100px
- margin 塌陷?有没有遇到过其他 css 问题?
BFC解决塌陷问题,其他的说了一个 inline-block 默认边距问题
- vue 响应式原理
从 data 开始,遍历 data 里面的属性,递归添加 get 和 set。在 get 的时候进行 dep 依赖收集,set 的时候进行派发更新,当触发了对应的 watcher,就会通知对应的 dep 进行 diff 和 patch,更新 dom
组件 data 为什么是一个函数?作用域
vue Object.defineProperty 缺陷?数组 7 个方法怎么重写的?
自己说的比较全,包括 vue 源码处理,重写数组 7 个方法,$set 原理。
重写 7 个原生数组方法,感觉自己描述的不清楚。
- dep 依赖搜集与 watcher 派发更新流程?dep 是发布者还是订阅者?怎么知道每一个 watcher 要通知哪一个 dep?
dep 和 watcher 这个基本和响应式描述差不多
dep 是订阅者
每个 watcher 都会有个 watcherId,可以找到对应的 dep
- keep-alive 原理?
缓存的 VNode,描述了一下简单用法。
LRU 算法直接说了下概念,具体怎么用的这个算法,直接说了自己不了解
- 讲一讲虚拟 dom
先描述下什么是虚拟 dom,回答了什么情况下快?什么时候慢?更多的是跨平台的作用,以及这种借用对象来描述一个事物的想法。
- vue diff 算法
先讲了一下没有 key 的情况,就地复用算法。
有 key 的情况,diff 的流程,广度优先遍历
和 react diff 对比了一下,包括 patch 的区别
- 为什么使用 key 能提升 diff 性能
通过 key 对比节点,更快
map 数据结构更快
vue-router hash 和 history 区别
vuex 主要解决了什么问题?跨组件通信,数据持久化,数据响应式
判断数据类型
typeof,instanceOf,Object.protoType.toString.call(), Array.isArray()
- this 指向的理解
声明时和运行时指向
箭头函数指向
修改 this 指向
- call,apply,bind 区别
call,apply 参数区别,会执行一下要改变的函数
bind 返回一个闭包,不会执行函数,而且返回的新函数 this 不可再次改变
讲一下实现一个 bind 的思路
- 函数柯里化概念,常用场景
简单讲了下什么是柯里化,场景说需要缓存的时候,没有深问,问了也不会。。。。
- Vue3 Reactivity API 有用过吗?
没有,然后讲了一下 vue3 proxy 的缺陷
- 浏览器事件循环描述一下
主线程执行,任务队列,宏任务,微任务等等
- 关于缓存的一些东西?如何提高缓存命中率?
强缓存,expire 和 cache-control
协商缓存,e-tag 和 last-modifed
DNS 缓存
缓存命中率这个刚开始没理解,后来面试小哥提醒了一下,自己讲了一下 webpack contenthash,回答到点上了。
- 详细描述一下输入 URL 到页面打开的过程,尽量详细
- DNS 解析,讲了 DNS 缓存查找的过程,浏览器缓存 》 服务器缓存 》 运营商缓存 》 域名公共服务
- TCP 三次握手建立连接,讲了三次握手的流程,syn -> syn + ack -> ack
- 服务器返回资源,浏览器下载完成开始渲染,css 树,dom 树,渲染树
- TCP 四次挥手断开连接,fin -> ack -> fin -> ack
TCP 连接是每次都要的吗?讲了一下 http 的 Connection: keep-alive nginx 默认开启的,也可以设置达到多少个连接以后就断开连接
- 数组和链表在计算机中存储的方式
数组:每个元素都会开辟一个内存,访问的时候也是自己就可以找到,时间复杂度是 O(1)
链表:单向链表与双向链表,查找的时候需要遍历,时间复杂度 O(n)
插入的时候,数组和链表那个性能更高? 链表,数组需要移动很多位
从内存空间上用计算机的方式,数组插入一个元素,push 这种不行。说了数组加 length 也不对。 不知道答案是啥
- 你有什么想问我的?
问了下自己面的那个部门(之前有猎头联系我说有赞教育比较急,所以问了下)。 得知有赞那边是先面过,然后根据个人情况分配。
问了下技术氛围(听人说,有赞前端技术很强,所以问了下) 技术分享有,比我们多了个技术方案评审,感觉这个挺重要的。
问了下工作节奏(猎头说 995,之前看新闻说 996) 995,周三周五 6 点走,不打卡,周六加班给调休。
然后约了二面,视频 coding
# 二面(视频 coding)
时间比较短,写了两道,写的也不全对,前两道思路写出来了。算法题看了一会,不会~~~
// Coding 须知:本次 Coding 时间限制为 45 分钟,共 3 道题,请量力答题
/**
* 1. 实现一个函数,判断两个变量值是否相等
*
* 注意
* - 数据类型不限于示例,尽可能考虑边界
* - function 引用相等即可
*/
const foo1 = {
a: 1,
b: "1",
c: NaN,
d: [
{
a: 1,
b: 2,
},
],
f: {
a: 1,
},
g: null,
};
const foo2 = {
a: 1,
b: "1",
c: NaN,
d: [
{
a: 1,
b: 2,
},
],
f: {
a: 1,
},
g: null,
};
function isEqual(target1, target2) {}
console.log(isEqual(foo1, foo2), "isEqual");
/**
* 2. 实现 getValue 函数来获取path对应的值
*/
var object = { a: [{ b: { c: 3 } }] }; // path: 'a[0].b.c'
var array = [{ a: { b: [1] } }]; // path: '[0].a.b[0]'
function getValue(target, valuePath, defaultValue) {}
console.log(getValue(object, "a[0].b.c", 0)); // 输出3
console.log(getValue(array, "[0].a.b[0]", 12)); // 输出 1
console.log(getValue(array, "[0].a.b[0].c", 12)); // 输出 12
/**
* 问题 3
* 将一天24小时按每半小划分成48段,我们用一个位图表示选中的时间区间,例如`110000000000000000000000000000000000000000000000`,
* 表示第一个半小时和第二个半小时被选中了,其余时间段都没有被选中,也就是对应00:00~01:00这个时间区间。一个位图中可能有多个不连续的
* 时间区间被选中,例如`110010000000000000000000000000000000000000000000`,表示00:00-1:00和02:00-02:30这两个时间区间被选中了。
*
* 要求:写一个函数timeBitmapToRanges,将上述规则描述的时间位图转换成一个选中时间区间的数组。
* 示例输入:`"110010000000000000000000000000000000000000000000"`
* 示例输出:`["00:00~01:00", "02:00~02:30"]`
*/
function timeBitmapToRanges(str) {}
console.log(
timeBitmapToRanges("110010000000000000000000000000000000000000000000")
);
console.log(
timeBitmapToRanges("110011000000110000000000000000000000000000001111")
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# 三面(现场 1h20mins)
上来就是两页纸,我人懵了。。。因为已经做过线上 coding 了,没做好心理准备~~~,也没复习这方面的。。。。自己这方面也比较薄弱,两题写了 20mins 左右。
- 大数相加: 给定两个字符串形式的非负整数 num1 和 num2 ,计算它们的和。
leetcode 415. 字符串相加 (opens new window)
写一个事件 Event 类,实现 on,off,emit,once 功能,同时 on 要支持 debounce。eg:on('click',function(){},500)
介绍下让自己成长最大的项目?
你觉得现在遇到的最难的问题是什么?
搞清楚面试官想问什么,当时自己感觉就是问题的解决方式?自己举例子来说明:医保 DLL 技术方案,首屏极致优化,自己通过 学习+总结+落地+分享 来论述了自己工作+学习的方法。也讲了一下当前自己在解决的一些问题,医院内网访问和微前端存在的一些问题等等
- 为什么要做微前端?
- 线上发布优势
- 和 iframe 对比:UI,加载速度,弹窗,通信,安全等等
- 回到写的第二道题,说到了 setTimeout 设定的时间,函数能准确按时执行吗?
讲了一下宏任务和微任务,接着问 MutaionObserver 有用过吗? 这个同事之前分享过,自己大概介绍了一下 rrweb 的使用,以及他是怎么用 MutaionObserver 监听 dom 节点变化的。
- setTimeout 怎么能做到准时?
没法完全准时,只能减少延迟。应该就是问 JavaScript 高精度计时器,之前去有赞之前看到过这个问题,就讲了下通过声明变量,没执行一个宏任务,变量+1,到需要高精度计时器的时候,计算时间差,减少 setTimeout 的延迟。面试官引导到把 setTimeout 换成微任务,当时自己说的是用 promise 和计数的方式做一个,但是时间这个怎么控制不太清楚。
- js 多线程
开始不太理解想问啥,就举例子说了 js 如果是多线程的,可能会造成页面 dom 操作冲突。然后面试官就问 js 支持不支持多线程,我说了是。面试官:以什么样的形式支持?我答:web worker(猜的。。。)接着问了:node 端的有没有?不知道。。。然后问了 web worker 的简单实用
- 进程和线程的区别
- 调度单位不同 (自己只答了这个,其他的大学学过,记不住。。。)
- 进程在执行过程中拥有独立的内存单元,而多个线程共享内存
- 不同进程间数据很难共享,同一进程下不同线程间数据很易共享
- 进程间不会相互影响,一个线程挂掉将导致整个进程挂掉
- 进程使用的内存地址可以上锁
- 进程内存计算机如何分配?线程资源如何分配?
猜了一个根据 IO 读取率来,就没说了~~~
- cookie、sessionStorage、localStorage 区别
可能前面俩问题答得不好,就问了个简单的。。。
- 跨域的解决方案
cors,jsonp,nginx 反向代理,possMessage
- em / rem / vh / vw 区别
简单,随便写写
设置一个盒子的高度永远比窗口可视高度小 100px
height: calc(100vh - 100px)
移动端 1px 边框
面试官大哥说了,看你项目 PC 端多一些,有个移动端的问题,我感觉还是要问一下,结果就是我不会,hhh
我只知道用 css3 的缩放,translate:scale(0.5),答得半对吧
参考下:移动端 1px 解决方案 (opens new window)
- html 可替换元素
当时我蒙蔽了,没听说过这个名词。不过面试官小哥还是蛮好的,会换种方式问你,和 img 相似的元素有哪些?引导到 audio,video 等等
- 一个图片对应多个 cdn 地址,如果第一个不能用了,需要换成下一个,怎么做?
面试官小哥提醒了下 img 标签的 onError 事件,我说了通过一个队列维护图片 cdn 地址的信息,然后通过 onError 事件做一些替换 src 的操作。实际上这里我感觉面试官更想问的是借助 promise.all 和 race 来实现,当时没想起来
- vue 生命周期
说了下每个生命周期,以及每个生命周期源码内部干了啥,以及我们开发的时候一般用于干啥。
- 改变组件 data 里面的东西会触发什么生命周期?
当时说,beforeUpdate,update 都会执行。实际上是 data 改变,beforeUpdate 会执行,但是只有 re-render 和 patch 之后,才会执行 update。
- vue2.x 响应式原理
和一面问题一样
- Object.defineProperty 参数;for in可以遍历出来那些东西
Object.defineProperty(obj, "key", {
enumerable: false,
configurable: false,
writable: false,
value: "static",
get() {
console.log(`读取 ${key} 属性`);
return value;
},
set(newVal) {
console.log(`设置 ${key} 属性为: ${newVal}`);
value = reactify(newVal);
},
});
2
3
4
5
6
7
8
9
10
11
12
13
14
- for in可以遍历数组吗?可以遍历出那些东西?
可以,拿到的是下标。
let a = [1,2,3,4,5]
for (let key in a) {
console.log(key,a[key]);
}
2
3
4
- Vue3为什么要使用Composition Api
和Options Api对比了一下,讲了一会
- vue组件 scoped作用;有没有了解过其他的css隔离方案?
组件的Css隔离,加了以后会变成
.example[data-v-xxxxx] {
color: red;
}
2
3
讲了下CSS隔离方案: css modules / css in js / style-component
- 图片懒加载
图片data-src替换src ,讲了下虚拟滚动,新增和删除DOM。
面试小哥问了下DOM节点复用,就不用删除和新增了,是个好办法~~~
- 用ES5 去实现ES6类的继承
说了下原型链继承。
问了下,怎么把两个原型关联起来,方法有很多,自己只说了直接赋值,其实构造函数也可以。得下去好好复习下继承
- 你个人觉得 eslint 有哪些规则比较有用?
说了下全局变量处理,以及严格模式下有些代码运行报错等
react hooks useState里面if判断这个应该说下的,忘记了
- http1.1和http2的区别
答了四点:
- 首部压缩
- 二进制分贞
- 多路复用
- 服务器推送
接着问了下,在http1.1中用的哪些优化手段,会在http2中失效?当时有点懵了,乱说了一通,这也是自己的毛病,答非所问。
看我说不出来,就问了下http1.1中我们做了哪些项目优化?讲了讲强缓存,协商缓存,DNS缓存,http长连接等等
然后问了下http2.0还存在什么问题?不知道~~~
接着问了http3,我问了下http3用UDP怎么保证安全性,面试官小哥说了应用层
接着换个问题,TCP和UDP的区别。说了连接方式,报文传输方式,其他的想不起来了
聊了近一个半小时,终于结束了~~~面试小哥说让我等会,告诉了我卫生间在那,就走了,面试体验还是挺不错的,有些不知道的问题。面试官会换种问法,实在答不出来也会跟你说为什么?
# 四面(主管50mins)
自我介绍
说一说最近一年多做的最好的业务?你觉得你做的最出彩的地方是哪里?
拿了纸和笔,画了画系统流程。说了说医保及打印的方案
- 项目优化?
提到了客户端存放前端静态代码,开机自动启动拉取最新代码。用户打开时,只需要从本地获取前端静态资源。
接着问到,用户如果正在操作,这个时候本地缓存才获取成功,怎么办?
说了通过mutationObserver监听dom节点有没有在变化,来判断用户是否在操作,决定要不要使用缓存资源。
- 处方打印,不同格式如何设置?
通过模板化,将标准版本和自定义版本分开,通过医院配置设置当前医院需要的模板内容。
离线缓存 存在什么问题?
讲一讲权限系统?除了RBAC,还了解哪些权限设计吗?RBAC的优点?
给你一个需求:除了预设角色,某个人可以单独做其他的事情?怎么办
开始自己理解是自定义角色,说了以后,面试官说不是这个。
然后就有点懵了.我们的权限系统更多的是从某一个点来出发,要实现上面的需求,自定义角色就可以。应该还有其他的方式,得扩展下视野,研究一波。
- 讲一讲你们做的微前端? 父应用如何加载多个子应用? 路由整合是如何做的?
single-spa自己了解的不多,简历里写的也是参与了微前端建设。得研究下,路由之间是如何加载的?这个确实完全没思路,不然还能吹两句。。。
讲一讲局部打印的实现?
api-proxy是如何实现的?业务越来越复杂,nginx是不是每次都要改?怎么解决?
有赞有一个开源的zan-proxy。优化方面,说到了用node统一服务进行中转,不再借助于nginx。
- 对项目不侵入,除了chrome插件,还有什么办法做这个?怎么做一个全局代理?
这个问题有的尴尬,之前想过这个问题,但是说实话,不知道怎么做,视野太狭隘。。。。
- 在本地如何调试线上代码?
直接就说了,暂时还没搞过。。。这是个大问题,记下来
- 讲一下项目中定制化需求如何处理?
现在我们的形式都是一套代码里面改,通过权限+医院模式去做各种判断,说实话这种方式很难维护。我们项目体量小,我自己感觉都已经不好维护了。后面越来越多的迭代怎么办? 这也是我需要思考的问题,如何区分标准化产品和定制化产品?
面试官举了一个有赞的场景例子:关于不同商家后台,某个商家多了一个菜单?某个商家在通用页面A中有特殊的两个按钮?如何处理这种个性化的问题?深入一点,如何把个性化需求开放给其他商家自己开发?
刚开始自己更多的还是想着权限点来控制(现有业务就是,启发自己需要多去看看外界的解决方案,眼界不能狭隘),但是这种情况对标准化产品代码是侵入的,而且需要自己的人力来开发。后面自己又临时想了一种通过留坑的形式,把个性化菜单交给其他开发者,通过url带一些个性化参数来判断页面展示逻辑。
在问到如何做成一个开放平台的时候,自己有点懵,没接触过,没想太多这种。确实现在的业务场景没有那么复杂,考虑不到这些问题。害,多看看其他公司的解决方案吧,不能局限于一家公司
- 如果让你写一个single-spa,你怎么做?两个子应用的app.js如何切换?
关于single-spa自己了解的很少。。。简历也只是提到参与了。。。确实是自己准备的不足。害,好好学习吧、
接着问到了js、css如何隔离?说了js通过proxy,css隔离通过添加子应用名称的class
接着问了,作为攻击者,如何突破用proxy实现的一个沙箱环境,或者说子应用如何才能访问父应用的window对象?
面试官笑了笑,我也笑了笑。
想了半天,吹了下 子应用往整个body里面插入script脚本来访问全局window。
面试官说:ok,这是一个办法。那现在我把这个路子封了,怎么办?
想了一会,开始说胡话了。。。。然后面试官就终止了这个话题。得去了解下proxy能不能被突破?或者这个想问的仅仅是proxy handler?
- 讲一讲项目中的全键盘操作?keyup监听怎么做的?
说到了addEventListener第三个参数,然后问了冒泡和捕获的流程,自己举了一个ul和li的例子。
接着问题,页面中一个点击事件,先捕获还是先冒泡? 因为想到addEventListener第三个参数默认是false,就说了先冒泡,搞错了。事件机制应该是捕获-》目标阶段-》冒泡
接着问题,如何阻止冒泡事件?e.stopPropagation 那如果是你这个全键盘操作,怎么阻止部分按键?通过keycode拦截
- oAuth 2.0 工作流程
讲了一下我现在工作接入AC单点登录的一个流程。clientId+URI跳转到AC,用户登录完成,通过URI带上Code,返回原应用。前端拿code和后端换token,后端去AC校验token有效性。
貌似我们用的不是标准oAuth 2.0
- 你为什么想出来看机会?
和自己组长聊过,组长的话,问我在现在公司以后的成长之路怎么样,我自己反思了一遍,感觉不大。也是通过身边有有赞的同事,感觉他们很强,所以来有赞试试的
说了很多啰嗦话,可能聊得比较久了,面试官开始了下一个问题
- 对下一份工作期望是怎么样的?
自己说了技术栈,希望自己能用用react做pc,丰富自己的技术栈或者vue做toC,更加锻炼人。
- 你现在是怎么学习的?
学习+总结写文章+落地+分享(团队、外部)
基础知识啃书,新技术看视频,然后再去看官方文档。经常看一下前端大会,前端早早聊,D2等
博客+学习打卡,自己约束自己。
说完之后,面试官给了一个建议,多去看看MDN。自己也说了一般会在搜索api的时候会用到,面试官的意思是直接去看MDN的文章,我可能看的很多知识都是二手的,要自己多去研究研究。 20. 你有什么想问的?
对我有什么建议? 多去看MDN,业务多多理解
对我现在水平的评价?我有没有达到一年半前端的一个标准水平?
可能问这个问题不太好,因为当时自己面了好久了,中午也没吃饭,整个人有的晕,也有点抖,感觉要挂了~~~有点害怕。
然后面试官说我现在成长的空间很大,一年半前端的水平还行。我当时心里的活动就是完了,可能要凉。。。接着就让我等一下,估计是去讨论去了,自己也知道,接下来如果有hr来,就80%过了。找个理由说hr不在的,基本就凉了。。。
# 五面(HRBP40mins)
等待的时间是非常煎熬的~ 一会(忘记了是多久,差不多10分钟?),HR小姐姐来了,换了个位置,开始面对面谈。
刚刚聊下来感觉怎么样? 自己感觉还是有些不足,就实话实说了。甚至都说了,不管怎么样,什么样的结果,自己都还会去好好学
对自己1-3年的规划
介绍一下你在微医的工作
做的业务,最大的风险是什么?
说了医保相关,hr小姐姐问我,前端如何做容灾处理?
项目容灾处理是提前考虑到的还是后续遇到自发提出来的?
前端方面有没有犯过比较大的故障?
说了一个前端判断的问题,和hr小姐姐解释了挺久,可能是自己描述的不清楚。
- 有没有什么问题会因为前端人手不够,没有去解决的?
我还是那个毛病,罗里吧嗦,然后胡说。说到最后自己都不知道自己在说啥。。。
- 绩效好的情况下为什么要考虑机会?
还是说了自己成长的问题,想要一个成长的环境。
你是想要更复杂的业务域吗?你们组没有其他复杂的业务域吗?
你觉得自己还能在现在的业务中成长多少?或者说你还能为现在的业务做什么?
当前业务还有哪些问题需要去处理?
标志产品和定制化产品区分
平时除了工作上的东西,自己还有什么学习方式?
你希望自己3年以后能达到什么水平?你觉得自己和P6差距在哪?
平时的工作节奏? 早上8点+ 到 晚上8+
项目管理?做这个笔记对自己的成长?
用手机给hr小姐姐看了下,我做的一些项目管理,有道云笔记
你对加入有赞的一些期待是什么?薪资是怎么样的期待?有没有其他offer?
你有什么想问的?
问了下工作节奏:995,不打卡,加班给调休,五险一金全额。
问了下面的部门:业务技术前端
问了下什么时候能给结果?也说了自己有三个offer,年前需要给答复,HR小姐姐说,明天尽快。
等我到门口的时候,又问了下离职时间。这个时候自己才感觉有戏~~~~
# 离职
等待还是最煎熬的,害怕自己挂掉~~~
终于,第二天中午给我电话了,下午发了满意的offer。接着自己就去找领导提离职了,领导说有点突然,他要开车回家,就搁置了一下,到晚上的时候,自己又主动找了下领导,当时也没说出结果。
# 过年准备
- 01
- 2023/07/03 00:00:00
- 02
- 2023/04/22 00:00:00
- 03
- 2023/02/16 00:00:00