• 作者:老汪软件技巧
  • 发表时间:2024-09-04 07:03
  • 浏览量:

首先声明在下小菜鸟一只,今年初才开始学 Next,买了个 Next 掘金小册加看官网学了一会。然后开始简单重构自己博客(笔记的展示增删改查之类的),并参与了公司 Next 官网开发了两三个月吧。水平就大概这么个半吊子水平。

面试经过

面试的是一个 React 技术栈的公司,主要项目是 Nextjs 的。

先是做个机试题,然后两个面试官一起面试,问一下 ppt 上的问题和 nextjs 的东西。

简单机试

上来先是一个简单的 Todo 页面例子和手写防抖节流的机试题(限时一个钟)。

工具:使用macbook,一个干净的 vscode 和一个最简单结构的 react 工程文件。

Todo 页面大致如下吧,大致有状态,标题,描述这些信息,需要兼容移动端,实现一个有 add 功能的弹窗,样式大致对照给出的图片来实现,然后可以自由发挥一下(不能借助ai工具来生成)。

我一开始还很开心,这不是很简单吗,然后对照图片样式功能什么的基本还原完了。

因为以前面试也做过一些类似的机试题,后面会看你的代码习惯,问你的组件封装,甚至格式化之类的。所以当时把一小时都用完了,防抖节流实现了一个最简单的js版本的,Todo 页面在做时也是尽量把一些地方该抽组件的抽组件,把一些圆角,字重,背景色,溢出隐藏之类的都加上了...

然后到时间了,过来两个面试官,布置题目的面试官看了下页面说:好的,我们来看下 ppt 的题目。

此时我心想啊这就没了?

现在回想起来,或许面试官就只是想简单看看你能不能写页面而已,的确是不该做那么久的,因为当时面试官都说你看着图片,样式那些自由发挥就好了,毕竟用完了一个小时印象分应该没那么好吧。

ppt 的问题一、三维立体区域的填充(三维装箱算法)

在一个有长宽高的三维立体区域中,如何填充方块能把空间利用完成。

一开始看到的时候我直接被唬住了,思考了片刻,然后一个面试官说不要想太多,另一个面试官也提示说(贪心算法),但是贪心算法这个真不太懂,然后表示我不会...

下楼后回忆时,才发现起码应该简单说说的,这个不就是比我做的 华容道组件 多了个z坐标吗?就算不知道那些空间利用的算法,起码还能简单扯扯坐标比较,比如在二维时,比较两个点即可,那么在三维同样也是两个点,起码也不至于说是完全答不上...

二维三维

具体的算法解释可以看 这篇文章

现在了解后,我这里做出一点我个人的见解吧,贪心算法的原理是:在求解最优解问题时,每次都只选择在当前下最好或最优的策略,从而逐步推导出最优解的算法。

在这里的 三维装箱 场景下,就是有一堆长宽高体积不一样的方块,然后填进这个区域,这时需要判断方块放哪个区域是最优解,而判断的方式就是比较立方体的6个面方向上的剩余空间。

比如一开始放第一块时,整个空间都是空的,直接放到坐标轴的角落就行,放完之后计算得出这个块在6个面方向上的剩余空间,当然这些空间也会有重叠的部分。然后后面的每一块的放置的区域就是遍历每个方块获取6个面方向上的剩余空间,找到最大的空间来放置,然后每次放置完方块,所有方块在6个面方向上的剩余空间都需要更新一下。

当然实际这个问题还是很复杂的,比如还要考虑长宽高限制,支撑约束,重力约束等等,我这里只是了解了一点思想纸上谈兵罢了。

二、不同语言下的打包处理

英语,中文,俄语等语言的一个 json 字符串文件在项目的某些地方使用到,如何在打包部署多个语言项目时,一个语言对应一个项目,其他多余的字符串给他去掉。

具体怎么样的我也忘了,我这里简单模拟一份吧。

export defalut {
    en: {
        say: 'hello',
        // ...
    },
    zh: {
        say: '你好'
    },
    ru: {
        say: 'Здравствыйте'
    }
}

因为我只是简单的知道可以通过路由的处理来实现这些 国际化 的方式,但是这也不是题目要求。最后我回答的是:不同的 language 通过跑不同的 script 打包脚本,传递不同的环境变量来判断使用对应的字符串... (简直就是鸡同鸭讲) ,然后面试官表示不是这些,然后我说 webpack 上应该有一些类似的插件来解决的,但是举例不出来,中途面试官提示了就是跟 tree-shake 是类似的,但是我真没接触过,没办法只能下一题了。

这里考的应该是 webpack 打包时 tree-shake 或者 rollup 之类一些配置吧,实在不是很了解。这篇文章 就简单讲述了一些去除死代码的方法。当然我也还没找到题目要求的具体解决方法,大家感兴趣的话可以解决一下。

三、项目不同版本在前后端的处理

_面试问技术栈_栈面试题

具体题目咋样也有点忘了,大概就是项目有很多个版本,在前端和后端怎么区分处理。

我当时回答得也是非常不好,就说以前项目中后端接口升级,会做 v1 v2 的接口区分,然后请求不同的api;而前端项目中的版本号,也携带到请求的 header 中来给到后端的,后端方面会针对不同版本号处理。然后面试官就想问的是后端方面具体是怎么处理呢(因为他们是相当于全栈开发的),然后我说后端人员具体怎么处理的我也不太清楚...

聊着聊着引申 Next 项目中图片的处理,比如首页加载小图,详情页加载大图之类的;然后问有没有做过根据不同屏幕尺寸下展示不同尺寸图片等等。

四、Next 中 fetch 的请求缓存

答:在服务端相同的 fetch 是自带缓存的,在正常的 fetch 中可以打上 tag ,然后在一些页面如果更新了内容,可以用 revalidateTag 来清除对应的 fetch 的缓存数据...

面试官:如果让你来自己封装 fetch,怎么实现这样的缓存机制,比如有多个组件发起相同的 fetch 请求?

答:一开始回答得乱七八糟,当时想起以前好像看过一个什么方法可以取消请求的但是想不起来了(XMLHttpRequest.abort()),就回答了什么浏览器发起的请求把它取消掉之类的;面试官表示像这样很麻烦,还不如不发起,算是提示了一下吧意思就是问我如何在请求发出去前处理,然后就回答使用 map 集合比如将 api 作为 key 值,然后 value 里面保存个发起 fetch 的函数,在多次调用的时候,只实际触发一次请求完成,在 value 里面保存下返回的结果,时间之类的供下次使用或者时间失效后重新请求...

五、如何在 client component 里面 fetch 时使用 server component fetch 的数据缓存

面试官:比如同一份组件代码里面有 fetch 的功能,然后它在 server component 里面已经请求过了,然后现在这份组件代码在 client component 里面再次使用,如何用回之前 fetch 过的缓存。

因为在我的认知里面一个是保存在服务端的,另一个是在浏览器的,实在不太了解,回答得也是一塌糊涂。

现在的我也不知道该怎么做,因为具体 ppt 上的题目我也基本忘了,都是通过录音来大致回忆还原的,现在回忆后我不知道面试官想问我的是不是想通过 children 来传递这个服务端组件给客户端组件的意思,其实用的还是服务端中 fetch 的缓存。反正我当时一开始遇到这个问题的时候,是彻底不知怎么搞的。要是有懂的大佬求教一下。

面试官:浏览器是怎么做缓存的,有哪些缓存机制?

这也算常见的面试题了,但是最近也没怎么看过,当时刚面完前面的,都答得不太好,一时也记不太起来了。

强缓存:告诉浏览器一个具体的使用缓存的时间。

协商缓存:当缓存过期或者需要验证资源是否发生变化时,浏览器会向服务器发送请求。

Cache-Control :no-cache 绕过浏览器直接询问服务器资源是否过期。no-store 直接不管缓存,重新请求。

六、server component 的整个渲染过程是怎么样的?在这个渲染过程中 server component 和 client component 有什么区别。

当时的确没过多了解,我那时就回答了 SSR 的渲染过程了,他问 RSC 我答 SSR,然后面试官表示你这说法那跟 SSR 有什么区别之类的,反正还有更多的对话内容,面试的过程就更加的惨烈了。

现在回来一顿搜索后简单说说我的理解吧,主要是看了 的解释才大概了解 RSC。

server component 出现的目的是为了更靠近服务器能更快速的拿到请求的数据,而服务端的渲染的过程中,会构建一个未完成渲染的可序列化的 React tree ,然后里面会包含 client component 的节点,而这些节点会被 bundler 处理为只有id,props的属性和保留对客户端组件的引用的这么一个节点,又因为所有的 props 都必须是可序列化的,所以像 onClick 这些事件处理方法自然也不能给到服务器组件了。

图片继续采用 的了。

当浏览器收到服务器返回的 JSON 后,会重新构建 React 树,通过 bundler 将之前的节点引用,替换成对应的客户端组件。

而当 React 组件需要 promise 等待数据的获取时,需要用到 suspense 来包裹,所有在一开始生成 RSC 时,遇到时会通过一个占位符(fallback)来先占据这棵构建树的节点,当完成 promise 请求后会再次调用服务端组件函数,完成后再将其流式的传递到浏览器,替换掉原来的占位符。

七、水合是一个怎样的东西,有没有什么常见的问题

答:client component 在 state 给初始值时用了 date 之类的东西会导致水合不一致出现问题

面试官:打断,你找到问题的关键点了,问这个水合是有什么意义的?

答:... (答案: 水合是指客户端渲染时,React会尝试重用服务端渲染生成的 HTML 结构,然后在其上进行事件绑定和状态恢复,以提高性能和用户体验。)

面试官:继续说一下你前面说到的问题吧

答:水合时两次出现内容的不一致,导致出现 react 的警告报错。

面试官:为什么要求水合的结果是一样的呢?

答:... (其实就是上面水合的意义)

总结

整个面试的过程吧,对 nextjs 不懂的东西,越答越错,现在回听录音,都感觉自己的回答可笑之极。

平时打螺丝打多了,只关注怎么去实现,怎么解决问题,但是对一些东西的实现过程和底层原理还是了解的不够充分,而且相关的面试题也没看多少,理论知识还待提高,webpack打包的一些东西也还不够掌握。