
最近在面试,说实话,每次看到 精通 这俩字,我这心里就咯噔一下。不是我不信你,是这俩字太重了。这不仅仅是自信,这简直就是给面试官下战书😥。
你写 熟悉,我问你 API 怎么用,能干活就行。
你写 精通,那我身体里的胜负欲瞬间就被你点燃了:既然你都精通了,那咱们就别聊怎么写代码了,咱们聊聊尤雨溪写这行代码时在想啥吧😒。
结果呢?三个问题下去,我看对面兄弟的汗都下来了,我都不好意思再问。
今天真心给大伙提个醒,简历上这 精通 二字,就是个巨大的坑,谁踩谁知道。
来,我给你们复盘一下,什么叫面试官眼里的精通。
你别只背八股文
我上来通常先问个简单的热身:
Vue3 到底为啥要用 Proxy 换掉 Object.defineProperty?
大部分人张口就来:因为 defineProperty 监听不到数组下标,还监听不到对象新增属性。Proxy 啥都能拦,所以牛逼。
这话错没错?没错。
但这只是 60 分的回答,属于背诵全文🤔。
敢写精通的,你得这么跟我聊:
老哥,其实数组和新增属性那都是次要的。最核心的痛点是 性能,特别是初始化时候的性能。
Vue2 那个 defineProperty 是上来就得递归,把你对象里里外外每一层都给劫持了。对象一深,初始化直接卡顿。
Vue3 的 Proxy 是 惰性的。你访问第一层,我劫持第一层;你访问深层,我再临时去劫持深层。我不访问,我就不干活。
而且,这里面还有个 this 指向 的坑。Vue3 源码里用 Reflect.get 传了个 receiver 参数进去,就是为了保证有继承关系时,this 能指对地方,不然依赖收集就乱套了。
| 能力 | Vue2(defineProperty) | Vue3(Proxy) |
|---|---|---|
| 监听对象新增/删除 | ❌ | ✅ |
| 监听数组索引/length | ❌ | ✅ |
| 一次性代理整个对象 | ❌ | ✅ |
| 性能上限 | ❌ 越大越慢 | ✅ 更平滑 |
| Map / Set | ❌ | ⚠️ 部分支持 |
| 实现复杂度 | 高 | 低 |
你要能说到 懒劫持 和 Reflect 的 receiver 这一层,我才觉得你可能看过源码🙂↔️。
Diff 算法别光扯最长递增子序列
第二个问题,稍微上点强度:
Vue3 的 diff 算法快在哪?
别一上来就跟我背什么最长递增子序列,那只是最后一步。
你得从 编译阶段 开始聊。
Vue2 是个老实人,数据变了,它就把整棵树拿来从头比到尾,哪怕你那是个静态的写死的 div,它也要比一下。
Vue3 变聪明了,它搞了个 动静分离。
在编译的时候,它就给那些会变的节点打上了标记,叫 PatchFlag。这个是文本变,那个是 class 变,都记好了。
等到真要 diff 的时候,Vue3 直接无视那些静态节点,只盯着带标记的节点看。
这就好比老师改卷子,以前是从头读到尾,现在是只看你改过的错题。这效率能一样吗?
这叫 靶向更新。能扯出这个词,才算摸到了 Vue3 的门道。
Ref 的那些坑说一说?
最后问个细节,看你平时踩没踩过坑:
Ref 在模板里不用写 .value,在 reactive 里也不用写。那为啥有时候在 Map 里又要写了呢?
很多人这就懵了:啊?不都是自动解包吗?
精通 的人会告诉我:
Vue 的自动解包是有底线的。
模板里那是亲儿子待遇,帮你解了。
reactive 对象里那是干儿子待遇,get 拦截器里帮你解了。
但是 Map 和 Set 这种数据结构,Vue 为了保证语义不乱,是不敢乱动的。你在 Map 里存个 ref,取出来它还是个 ref,必须得手写 .value。👇
js
const count = ref(0)
const map = new Map()
map.set('count', count)
map.get('count') // 拿到的是 ref 对象
map.get('count').value // 这是正确取值
Map / Set / WeakMap 不是 Vue 的响应式代理对象
这种细枝末节,没在真实项目里被毒打过,是很难注意到的。
面试其实就是一场 心理博弈。
你写 精通 ,我对你的预期就是 行业顶尖。你答不上来,落差感太强,直接挂。
你写 熟练掌握 或者 有丰富实战经验,哪怕你答出上面这些深度的 50%,我都觉得这小伙子爱钻研,是个惊喜🥱。
在这个行业里,精通 真的不是终点,而是一个无限逼近的过程。
我自己写了这么多年代码,现在简历上也只敢写 熟练🤷♂️。
把 精通 换成 实战案例 吧,比如 我在项目中重写了虚拟列表 ,或者 我给 Vue 生态贡献过 PR。
这比那两个干巴巴的汉字,有力一万倍。
听哥一句劝,Flag 别乱搞,Offer 自然就会来😒。
你们说呢?
