编程导航Bug总结话题讨论

Bug总结

6 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

这么晚了,睡不着,让友友们笑一笑,煮波实习到现在也有两个多月了,今天17点产品发我对应公告要更正式环境,那么就由我和我组长负责。那个分支主要的任务就是去调用第三方接口,然后做各种动态,微信小程序,微信公众号,企业微信消息卡片推送(这个做了,但没有正式上使用),这里面大部分接厂商接口都是由友友根据接口文档然后煮波写的代码,基本上在测试环境都测试过是没问题的。到点了煮波就把自己的分支和另外一个分支(这个分支是煮波之前搞错了,测试给的任务,结果煮波建了一个新分支,而且名字和我当前分支区别只有一个大小写之差,然后去改一个小bug),将master也一起合到我当前要发版的分支,然后就是到gitlab cicd一顿操作,构建发版提交,到堡垒机上svn拉代码,由于是煮波的组是使用tomcat(springboot项目)+nginx部署的,煮波也是去看了负载均衡的节点,然后去更新当前未使用的节点,因为煮波不是第一次发版,所以还是比较的熟练。由于18点下班,但是向公司申请了饭卡,很想冲快点去楼下吃顿好的,所以并没有看catalina日志,导致可能某些节点还没启动完煮波就去去更新nginx配置文件,然后reload了,就直接在群上和测试和产品说可以了。因为这次更了四个端,其他一个端好像整寄了,搞得只能导师帮我改了。这个是第一个出问题的地方。之后由于前端又改了东西,导师让煮波拉下对应端的新代码,这个时候煮波也没多想,当然也问了导师说不用切节点吗?导师也说不用。因为煮波没想到前端构建打包后都是静态代码(但其实煮波是懂的),就是偶尔脑子会不好使,由于导师说不用切节点,煮波就直接重启当前 端的tomcat,又给整出问题了,影响用户使用了,我就把我的操作说出来,组长就和我讲了前端打包后是静态代码,是不用重启tomcat的,我们Java代码要重启相当于重新编译代码走jvm那套(煮波实力有限无法还原原话),然后问了导师说是不是放手放太快了就让我实习生自己整,还有问我导师有没有和我讲这些,其实导师是很负责的,煮波也很崇拜他,所以煮波还是说是自己的问题,但是组长还是逼问说导师有没有讲和我讲这些,要慢点来,看完日志再去reload nginx配置文件等等。这个是第二个出错点。然后煮波看了日志还出现很多空指针,测试环境是没问题的,然后发现是正式环境很多secret,appid都没加到数据库导致的,这个煮波就自己解决了,但是呢后面又出现几个问题,有些消息推送失败,这个煮波也想了想有可能是参数的问题,因为厂商其实做的也不够好,文档写的内容他们改后也不及时更新都是我们错了才找他们,而且有点要命的是煮波把一些数据库配置调用厂商url或者accesskey,secret加成是测试环境的(因为查出来cv很快),导致有些调用失败,没仔细去回顾接口文档导致的(这个分支任务距离现在有一个多月了),然后就是和导师一起解决问题,主要还是导师来,晚上10点50+才下班,回家已经11点多了。有些是厂商问题,有些是我们自己的问题。补充其中有一个问题煮波怀疑是把大写字母分支合到小写字母分支覆盖原有代码导致的,然后仔细想想合的时候也没出现代码冲突问题,所以应该不是这个原因,但是煮波还是傻傻的更完代码才想起来的,哎。 总结:做的时候还是不够细心,不能静下心来,导致犯很多不该犯的错误,这次也给自己提个醒。煮波其实很多细节没讲太困了,明天有空再更。 回家也是把鱼总oj优化成微服务了,终于可以做新的了,最近因为学校和自己原因,已经快有10天没写日志了,也是被导师说了,后续要好好写。 顺便带上导师的话,也能让大家在实习中得到成长。最近看过这样一句话感触很深,人生嘛,就是笑笑别人,偶尔也让别人笑笑。 休息。

uniapp运行在app端如何使用缓存

# uniapp运行在app端如何使用缓存 ​ 众所周知,**uniapp**可以一套代码,多端运行。但是需要注意的是,**window**对象以及**document**是浏览器特有的(所以app端无法使用**localStorage**等api),因此,**uniapp**贴心的为我们准备了**getStorage**以及**setStorage**等操作缓存的api。除此以外,还有**vue**官方推荐的**pinia**也可以操作缓存。那么当这两者同时存在于一个项目时,我们应该是他们完美结合起来呢? ## 为什么uniapp提供了所需的api之后还要用到pinia呢? ​ 有这么一个场景:在程序启动时我需要轮询服务器接口获取是否新数据的产生,如果有,则将hasRead字段设为true,又因为这个hasRead字段我需要在程序启动时就能拿到值,因此我是用`setStorage`api将其写进缓存。那么,问题来了,我如何将缓存的字段变为响应式的呢?为什么需要响应式?因为当有新数据产生时,我需要在界面中提示用户,而这个字段我是设置在缓存当中的。最开始我是用了以下2种方式来达到响应式的结果。 ~~~js // 第一种 const cache = uni.getStorageSync('hasRead') const hasRead = ref(cache) watch(() => hasRead.value, (newval) => { if (newval) { hasRead.value = newval } }) // 第二种 const hasRead = ref(true) const hasReadCache = computed(() => { const cache = uni.getStorageSync('hasRead') if (cache) { return cache } return hasRead.value }) ~~~ 答案显而易见,以上2种方案都无法使缓存变化的同时响应到页面当中(有小伙伴知道原因的话,评论区留言告诉我一下为什么不可以),于是,我秉着试一试的想法使用了`pinia`以及`pinia-plugin-persistedstate`。 ~~~js import { defineStore } from 'pinia' import { ref } from 'vue' export const useSettingStore = defineStore('setting', () => { const hasRead = ref(true) const setHasRead = (value) => { hasRead.value = value } }, { persist: { storage: localStorage, pick: ['hasRead'] } }) ~~~ 通过pinia,我成功实现的数据的响应式,并且能够将数据存于缓存。那么,问题解决了吗?并没有。为什么呢?因为程序最终时需要运行在**Android**以及**IOS**环境的,而以上环境并没有**window**对象,因此也不会有**localStorage**。那么应该怎么办呢?机缘巧合之下,当我鼠标移入`persist`钟的storage对象时,编辑器跳出来他的类型为**StorageLike**,直译一下就是像Storage,那么是不是可以理解为我声明一个Storage对象,只要具有像localStorage对象的api也可以呢?刚好**uniapp**也提供了类似的api,说干就干,我创建了一个类,如下: ~~~js // utils/storage.js class Storage { /** * 设置缓存 * @param {string} key 缓存键 * @param {any} value 缓存值 * @param {number} [expire] 过期时间(单位:秒) * @returns {boolean} 是否设置成功 */ setItem(key, value, expire) { try { const data = { value, // 计算过期时间戳(如果设置了过期时间) expireTime: expire ? Date.now() + expire * 1000 : null, }; uni.setStorageSync(key, data); return true; } catch (e) { console.error('Storage setItem error:', e); return false; } } /** * 获取缓存(自动处理过期数据) * @param {string} key 缓存键 * @returns {any|null} 缓存值或null */ getItem(key) { try { const data = uni.getStorageSync(key); if (!data) return null; // 检查是否过期 if (data.expireTime && Date.now() > data.expireTime) { this.removeItem(key); return null; } return data.value; } catch (e) { console.error('Storage getItem error:', e); return null; } } /** * 删除指定缓存 * @param {string} key 缓存键 */ removeItem(key) { try { uni.removeStorageSync(key); } catch (e) { console.error('Storage removeItem error:', e); } } /** * 清空所有缓存 */ clear() { try { uni.clearStorageSync(); } catch (e) { console.error('Storage clear error:', e); } } /** * 检查缓存是否存在 * @param {string} key 缓存键 * @returns {boolean} */ has(key) { return this.keys().includes(key); } /** * 获取所有缓存键 * @returns {string[]} */ keys() { try { const { keys } = uni.getStorageInfoSync(); return keys; } catch (e) { console.error('Storage keys error:', e); return []; } } /** * 获取缓存信息 * @returns {{ * keys: string[], * currentSize: number, * limitSize: number * }} */ getInfo() { try { return uni.getStorageInfoSync(); } catch (e) { console.error('Storage getInfo error:', e); return { keys: [], currentSize: 0, limitSize: 0 }; } } /** * 设置缓存过期时间 * @param {string} key 缓存键 * @param {number} expire 过期时间(单位:秒) * @returns {boolean} */ setExpire(key, expire) { const value = this.getItem(key); if (value === null) return false; return this.setItem(key, value, expire); } /** * 检查并清理所有过期缓存 */ checkExpire() { this.keys().forEach((key) => { // 通过getItem自动触发过期检查 this.getItem(key); }); } } // 创建单例实例 export const storage = new Storage(); ~~~ 利用**storage**对象,我将**store**变成以下代码: ~~~js import { defineStore } from 'pinia' import { ref } from 'vue' import { storage } from '@utils' export const useSettingStore = defineStore('setting', () => { const hasRead = ref(true) const setHasRead = (value) => { hasRead.value = value } }, { persist: { storage: { getItem: (key) => storage.getItem(key), setItem: (key, value) => storage.setItem(key, value), removeItem: (key) => storage.removeItem(key), }, pick: ['hasRead'] } }) ~~~ 通过以上思路,我成功解决了uniapp的**storage**与**pinia**的结合,并解决了缓存的响应式问题。 最后,虽然这个轮询的方案被我废弃了,但是我还是从其中学到了之前我从未接触到的东西。还有就是如果小伙伴学到了的话,也请点赞,关注。感谢您的支持!!

Next.js 项目太坑了,一个简单的样式库,就把项目玩坏了

离大谱,我引入一个库,然后就成功把 Next.js 项目干卡死,而且通过容器化部署,实例达到了惊人的 4 个,什么概念,后端服务的实例也就才三个。前端竟然 4 个。下面看看我的干了什么吧! ## 背景 最近在开发 Next.js 项目。有一个需求是把之前一个项目的功能搬到另外一个项目。写好的代码是 antd + tailwindcss 写的页面。新的项目是 Next.js + 没有tailwindcss 的。我就想能不能通过一个库直接把 tailwind 样式转为原生的样式。这样我就省事多了,确实是“省事”呢! ## 开发 于是我就去找 tailwind css 转为行内样式的库。还真让我找到了 [tw-to-css](https://www.npmjs.com/package/tw-to-css) 。看了它的简介,我就更加开心了。 <img src="https://pic.code-nav.cn/post_picture/1619930914211520514/tOfpoK9yTDj0Klrc.webp" alt="image-20240816085714940" width="100%" /> 兼容客户端和服务端,而且减少构建时间,多好啊!我赶dajia 紧引入来使用它。使用它确实是很快就把原来的代码搬运到了新的项目,不需要再去定义 css 类,再创建 css 文件,写样式。但是我本地开发就发现,点击进入我的那个页面非常卡。最长达到了 13 秒, <img src="https://pic.code-nav.cn/post_picture/1619930914211520514/TkbFgwZIL5MjQnni.png" alt="企业微信截图_119ad3f1-1bcf-4790-bc60-d87ec077a95b" width="100%" /> 然后。我还专门去前端小分队群里问了一下,大家会不会,他们也说服务器端渲染会有点问题 但是大家的意思就是可能是正常的,**这也是我为什么一直都没有怀疑我的代码有问题的原因**,啊啊啊啊啊,如果是正常项目,我肯定会先检查我的代码是不是出问题了,但是,我刚启动这个项目的时候,这个 Next.js 项目就经常卡死,点击反应很慢,导致我以为我开发的这个新页面这么慢也是正常的,是 Next.js 的服务端渲染的问题。 ## 发现问题、找出问题 我就忍着这么卡,开发完成,直到上线,通过容器化部署,上线后,实例数达到了 4 ,我那个时候差不多就肯定,一定是我的代码写的有问题了,然后我就赶紧去紧急回滚到之前的代码再部署。然后我就去对比我这个新的页面和其他不卡的服务端渲染页面的区别。最终锁定了 `tw-to-css` ,我就把所有 `tw-to-css` 方法去掉,然后刷新,结果不到一秒就响应了。太快啦! ## 最小复现 我写一个代码进行最小复现,使用 tw-to-css 后,客户端组件和服务器组件都会卡死,我去看一下源码,它依赖了 tailwind css 库,下次必须要看看引入新的库的源码了,不能简单看一下简介就好,感兴趣可以去看看:https://github.com/coderPerseus/nextjs-with-antd/tree/tw-to-css-bug-show <img src="https://pic.code-nav.cn/post_picture/1619930914211520514/nxnDEiarngCBuuKg.webp" alt="image-20240816084628119" width="100%" /> ## 反思 & 总结 1. 引入新库时要谨慎评估其性能影响。仅仅依赖库的描述是不够的,应该进行充分的测试 2. 不能忽视明显的性能问题。即使其他人认为可能是正常现象,也要深入调查 3. 在开发过程中引入新的库要进行性能检查和打包部署验证,不要等到部署后才发现问题 4. 对于 Next.js 项目,要特别注意服务端渲染的性能。某些库可能在客户端运行良好,但在服务端会造成严重的性能问题 5. 保持代码的简洁和模块化,这样在遇到问题时更容易定位和解决 不知道你们在开发 Next.js 的时候遇到了什么样的坑,分享一下,大家互相转发,不再吃这种亏

友友们,搞了一下午愣是打不开laocalhost:8080终于找到原因,能试的都试了一下,竟然神奇好了,欢迎参考↓ https://blog.csdn.net/weixin_45822011/article/details/123583079?utm_source=app&app_version=5.1.1&code=app_1562916241&uLinkId=usr1mkqgl919blen 技术

Uim UI白屏问题 具体流程如图 在 C:\Windows\System32\drivers\etc\host 中添加如下信息即可 151.101.64.133 raw.githubusercontent.com

Linux中运行shell命令出现'\r'符号格式不匹配的问题

<html> <head></head> <body> <div class="content ql-editor"> <p>今天使用ubuntu进入windows系统中的文件跑命令时出现了如下错误:</p> <p></p> <p><strong>原因:</strong>windows格式的shell多了个\r,需要替换。在linux终端下,输出\r会什么都不显示,只是把光标移到行首。于是终端虽然输出了/usr/bin/env bash,但是碰到\r后,光标会被移到行首,接着输出了:No such file or directory把前面的覆盖掉了</p> <p><strong>解决办法</strong>:</p> <p>1.使用vim进入moltemplate.sh文件中</p> <blockquote> vim moltemplate.sh </blockquote> <p>2.键盘输入`:</p> <blockquote> :set ff # 然后回车, </blockquote> <blockquote> :set ff=unix # 然后保存退出, </blockquote> <blockquote> :wq!#回车,问题解决。 </blockquote> </div> </body> </html>

下载 APP