面试时项目没有难点?给你举 15 个例子
hi 大家好,我是双越老师
背景
最近我一直在开发一个 Node 全栈 AIGC 项目 划水AI,技术栈是 Nodejs + Next.js + pgsql 数据库 + React + Tiptap 编辑器 + ChatGPT API
这个项目(一期功能)计划 7 月上线,现还在公开测试中,想报名参与的可私聊我。
我开发的 2-3 个月期间,遇到了很多问题,踩了很多坑,本文分享一些比较典型的。这些都是非常宝贵的项目经验。
而且,这些问题都是真实上线的项目才能遇到的,你在本地开发一个 demo 练手是遇不到这些问题的。
PS:现在项目公开测试中,就是真实的线上环境(预发环境),托管在阿里云 Serverless 函数计算 FC 服务中。
问题1:next-theme 切换黑白主题的 warning
项目使用了 shadcn-ui 组件库,其中使用 next-theme 来切换黑白主题,文档参考 ui.shadcn.com/docs/dark-m...
但当代码运行时会有一个浏览器警告,如下图
通过查询 shadcn-ui GitHub issue 可找到一个解决方案,在 html
标签添加<html lang="en" suppressHydrationWarning>
属性即可。
根据 React 相关文档,这个问题是因为客户端内容和服务端渲染的内容不一致,而导致的一个警告,某些情况下这是难免的,所以它给出了这样的属性来避免。
问题2: prisma 连接 pgsql 的小问题
Prisma 是 Nodejs 非常流行的 ORM 工具,用于连接和操作各种数据库,划水AI 项目用的是 pgsql 数据库。
当用 prisma 连接 pgsql 数据库的时候,遇到了很多小问题。例如密码尽量不要选择特殊字符,否则需要替换
还有参与 划水AI 项目的其他同学,在项目 wiki 中分享的他自己遇到的一些问题,例如
问题3: Next.js middleware 只能运行在 Edge 运行时
Edge runtime (边缘运行时)是用于快速计算和分布式计算,和 Nodejs 运行时有区别,它更轻量级,支持的 API 更少。
Next.js middleware 是运行在 Edge runtime 的,一般用于根据 Request 请求做一些判断和处理。
所以,项目中想要在 middleware 中使用 Prisma 请求数据库的时候,Next.js 就报错了,如下图:
由于 Vercel 在国内没法访问,我们后来使用了其他方式来处理这个问题,暂时没用 middleware 。
问题4: docker build 导致服务器宕机
划水AI 线上环境部署到阿里云 Serverless 函数计算 FC ,但测试环境是用 Github Action + Docker 部署的,部署在一台云服务器上。体验不同的部署方法。
由于我买的这个云服务器配置有点低(价格便宜)所以执行 docker build
时候经常会导致服务器宕机,连接不上,报错 255
后来换了一种思路解决这个问题。先在 Github action 中构建 docker image ,然后推送到 docker hub
最后再在云服务器上 docker pull 这个镜像。这样免去了在云服务器上执行 docker build
也就不会再出现宕机的情况了。
这个过程说来简单,其实操作起来细节挺多的,这些我都记录在项目的 wiki 中,想了解的可以私信找我。
问题5: docker hub 被限制访问
上个问题解决后,又遇到 docker hub 访问不了的问题。今年 6 月才发生的,我正好赶上。
现在从 docker hub 下载的 docker 镜像非常不稳定,目前也没有找到合适的解决方案。只能先手动操作部署,等过一阵看看网络情况再说吧。在国内做个程序员太难了...
问题6: NextAuth 登录校验的一些问题
NextAuth 提供了丰富的登录校验功能,配置方便,在 nodejs 框架 Next 和 Nest 中使用都非常方便。但我在使用它过程中也遇到了几个问题
- 频繁使用 github 登录时,会报错 (这也许是 GitHub OAuth 服务的机制)
- 邮箱登录有时候会报错,可能是网络问题,例如我线上就需要用 gmail ,用 163 就不行
- 频繁访问数据库获取 session ,没有缓存机制
问题7: Next.js 14 页面缓存的问题
Next.js Cache 缓存机制 是为了提高网页性能,减少数据请求和重复渲染的。但缓存了带来了很多问题。
例如,需要手动执行 revalidatePath(pathName)
才能导致页面缓存失效,重新刷新数据。如果忘记了 revalidatePath
你就会很困惑:为啥页面不刷新呢?
再例如,Next.js 页面缓存失效是全部刷新,没法部分数据刷新,这块只能自己通过客户端组件来解决。
划水AI 点击左侧文档列表跳转页面,这里我就使用了 pushState
H5 history 方式来解决的。没法用 Next.js 自带的路由跳转,否则会被缓存机制搞的乱七八糟的。
所以,Next.js 15 RC 去掉了缓存。
问题8: 网络配置对访问速度的影响
由于项目域名 huashuiAI.com
还没有备案(当前使用 GPT 接口,备案有困难),所以服务器和 CDN 不能选择国内的。当前 CDN 的网络情况测速效果不好,因为节点都在国外(下图右侧)
如果选择香港地区,效果会好很多,如下图。后面会备案,选择国内的 CDN ,速度就全在 10ms 之内,起飞!
对于 Web 项目的性能优化,前端的作用非常小,最重要的是网络、其次是服务端响应速度。前端优化那几十 几百 kb,对于现代的网速来说都不叫事。
所以,作为一个项目的技术负责人,得有全局思维和全栈思维,不能只盯着前端这一亩三分地。
问题9: 前端压缩图片,节省空间和带宽
现在手机拍照、电脑截图,一张图片就 1Mb 甚至几 Mb ,体积太大了。图片要存储在 OSS 服务,体积大了占用空间、浪费带宽,这都是钱。
所以,图片得压缩。一张图片压缩到几百 kb 就可以满足网页的浏览需求,同时提高了网页的加载性能。
压缩可以从两方面入手。
第一,上传图片时压缩,可以使用 browser-image-compression 插件,用它给出的 demo 可以看到一个普通图片可以压缩到 1/3 体积。
使用也非常简单
js
const imageCompressionOptions = {
maxSizeMB: 1,
maxWidthOrHeight: 1200,
useWebWorker: true,
}
// 压缩图片
const blob = await imageCompression(file, imageCompressionOptions)
const compressedFile = new File([blob], file.name)
// 上传文件
第二,加载时压缩图片。阿里云 OSS 自带压缩图片的尺寸的功能,文档 help.aliyun.com/zh/oss/user...
一个图片 url 后面加上 ?x-oss-process=image/resize,w_800,m_lfit
就可以把图片宽度设置为 800px
经过图片的压缩和其他优化操作,最终效果非常好。一张图片原图 2M ,最终在编辑器中加载是 422Kb
问题10: 阿里云 Serverless 遇到 maxMemoryUsage
问题
"本地没问题,但发布以后就报错" ------ 这种情况很常见,一个高级程序员要能独立解决这种功能问题,而不是束手无策。
但想要学习和体验这种问题,你就需要找一个真实线上项目去学习和参与。划水AI 项目就经常遇到这种功能问题。
项目本地运行没问题,docker 发布到测试机也没问题,但是发布到阿里云 Serverless 函数计算 FC 后遇到了 maxMemoryUsage
问题,是在登录跳转时发生的。
这个报错信息,一开始以为真的是内存问题,但是看服务器的内存监控,并没有出现内存暴增的情况,而且光点击个登录按钮,也不能触发消耗内存的操作。所以应该不是内存相关的问题。
后来通过 N 次分析和其他同学的讨论,发现是 NextAuth 跳转路由的问题,使用 Next.js 自带的 redirect
方法跳转就会遇到这个问题。
于是,就换了一种方式:点击登录按钮就用普通的跳转方式,不用 redirect
,就不会在出现这个问题。
这个问题的详细原因我至今尚未找到,看报错是 Next.js 提示的,但又只在阿里云 FC 环境下才报错,很迷惑。
但这个不重要,重要的是我把问题解决了,可以在线上使用了,可以和老板(如有)交代了。至于原因以后可以慢慢分析。
问题11: OpenAI Rate limit 规避限制
OpenAI API 服务有 Rate limit 请求频率限制,文档 platform.openai.com/docs/guides...
文档中对 Rate limit 的原因也说的很清楚:防止滥用,更公平,更好的管理 ------ 这没问题。
如果项目用户多了,大家高频请求 AI 接口,就可能触发 OpenAI Rate limit ,这些都得提前考虑,如何规避。
我考虑了好久,发现最有效的方式是:用多个实例轮流请求,分摊请求,就不容易达到 Rate limit 。而且这种设计扩展性非常好,可以扩展多个 key 和实例。
问题12: 关于 ChatGPT 的 token 和计算
项目的 AI 写作功能可以免费使用,但是也不能无限制的使用。毕竟 AI 接口是需要花钱购买的,用户多了成本太高。
限制使用,有的网站会限制次数,如 notion ,新用户试用 30 次 AI 功能。而我们是限制 token 数量,这样会更加公平,因为每次请求的 token 都不一样。
限制 token 就需要计算每次请求的 token 数量,token 不是 char length ,它有单独的计算方法。
我查询了好久该如何计算 token ,最后发现 OpenAI 的接口直接可以给返回 ...... 白费功夫。但查询过程中让我深刻理解了什么是 token ,也算是一种学习过程。
问题13: AI 请求中止时,无法得到 token 数量
接着上一个问题,但我们中止 AI 请求时,它就不返回 token 数量了。因为 token 数量是在最后返回的。
此时本应该去手动计算 token 数量的,但是这样做成本太高,因为计算起来很麻烦。所以我暂时没有做,中止了就干脆不去计算 token ,也不影响用户使用。
对于一个完整的项目来说,有些问题解决不了(或优先级比较低)就可以先不解决,只要不影响用户使用即可。毕竟精力有限,问题得一个一个解决,按优先级顺序来。
问题14: OpenAI key 政策不稳定
前几天 OpenAI 对 API key 进行了政策调整,导致很多 key 不能使用了,直接报 429
错误
划水AI 的重要接口都有监控和报警,如遇到某个 key 不能使用会立刻报警,并用其他的 key 代替
既然 OpenAI 的使用难度越来越大,那我们就要考虑接入国内的 AI 服务,例如 Coze deepseek 。待有结论了我会继续写文章分享。
问题15: AI 支持 markdown 格式
最开始 AI 是不支持 markdown 格式的,只支持纯文本。但当 AI 输出 markdown 格式时,就只能按照纯文本输入,很别扭。
划水AI 使用的是 tiptap 编辑器,而 tiptap insertContent
不支持 markdown 格式,文档 tiptap.dev/docs/editor...
所以得先把 markdown 转换为 html 格式,再插入编辑器。使用 markdown-it www.npmjs.com/package/mar...
现在 划水AI 可生成各种富文本格式,如大纲、代码块、表格等。
总结
经常有同学说:面试时感觉项目没有难点,没啥可说的。
其实无论是工作项目,还是业余项目,只要你认真做,当个正式的项目来做,你肯定会遇到很多很多的问题,积累下来面试时就有的说。
重点是正式项目,你在本地开发一个 demo 玩耍一下,那肯定遇不到啥困难。