首页 程序笔记 带团队后的日常思考

带团队后的日常思考

一、日常问题
1)页面卡死

  QA 将一个页面放在客户端中访问,进行功能测试的时候,发现运行在 iOS 16.7 系统中时,网页会卡死。

  将页面地址复制到 Safari 浏览器中,访问也会卡死。而据 QA 描述,测试环境没有问题,其他 iOS 版本的系统以及安卓手机也没有问题。

  有问题的手机,其测试和线上的客户端版本都是相同的,初步断定和 iOS 系统有关。

  摇上 iOS 的人,让他们帮忙调试,发现卡在接口通信,接口通信中的响应一直在 loading,没有显示。

  让客户端排查,他们什么头绪也没有,说可能页面渲染被阻塞了。

  将接口换个路径,响应内容相同,但依然会被卡死。以为是接口请求时机的问题,那就加个延迟,依然有问题。

  将接口响应置空,这时,页面不会卡死,看来与响应内容有关。

  接下来将响应内容中的数组只返回一个,页面仍然不会卡死,尝试二分查找的思路,再返回 10 个,依旧正常,返回 15 个,出现卡死。

  那看来问题出在这 5 条记录中,一个一个排查,发现一个 emoji 的蘑菇表情会让页面异常,过滤后就正常了。

  又去摇客户端的人,他们排查半天也没发现问题,因为不是所有的 emoji 表情都异常,目前就一个,也找不出规律。

  此时,一名客户端的人说用相同系统的手机访问管理后台,可以正常显示这个表情,活动页面和后台的区别就是用了不同的框架。

  前者是 React 后者是 Vue,既然如此,那就查一下这个表情在 Vue 中输出的写法。

  使用的是模板语法,将其替换成 v-html 的写法后,一切恢复了正常,特地查了这个属性的原理。

  它会将变量内容赋给元素的 innerHTML 属性,而模板语法会经过很多复杂步骤,可能是某一步操作发生了死循环导致了卡死。

  遇到此类难以马上解决的问题,需要抽丝剥茧的分析自己获取到的线索,然后一步一步推导,最后得出结论,这有点像探案推理。

  总结上述这套过程就是寻线索,找差异,缩范围,给结论,如此递归反复,直到解决问题为止。

2)协作问题

  我们组的重点是活动和管理后台,版本涉及的都是比较边缘的需求,有时候都没有直接需求。

  最近就遇到,QA 在测版本需求时,临时找我们修改 BUG,这让我们很被动,安排的计划也被打乱了。

  剖析了下这个问题,发现来源于两个方面。第一是产品在设计文档时,缺失了我们要修改的那部分业务。

  但是人总归有盲区,漏掉点需求很正常。第二是技术评审不够详细,现在的评审流于形式,其他组我也控制不了。

  目前就是比较粗的过,然后经常在开发时,遇到问题再和产品测试等人讨论,这个流程目前破不了。

  想来想去,想到了 QA,是他们告诉我们有 BUG,那只需要求他们在设计测试用例时,涉及到我们这块的,就提前通知。

  即使在版本中,我们没有要修改的需求,也要同步给我们,这样就不至于在测试过程中那么被动,被赶着改 BUG。

  最近在做一个 Electron 客户端的项目,也遇到了两个协作问题。第一个就是协作团队的文档缺失,让我们吃了不少苦头。

  我们的任务是将客户端的一个功能,搬到 Electron 项目中,但是在开发过程中,没有技术文档,遇到问题只能口头讨论,很费时间。

  第二个就是第三方服务文档缺失,虽然他们会提供示例,但是每次都要过一点时间才能给到,无法第一时间拿到。

  这就会延缓我们的开发进度,很多时候只能干等。总结下来,就是不同团队的技术文档缺失影响了我们的开发。

  这也提醒我们自己组,技术文档要补充完善,以免影响他人。

二、工作优化

1)缺失的性能测试

  最近上了一个大活动,其中会调用服务端的一个内部接口,这个接口是这次活动新写的。

  刚上线的时候,发现了少量的慢响应,当时并没在意。正好赶上双休日,这两天慢响应一下子就上升了。

  周末在家排查,发现是服务端的那个新接口问题,但想到页面还能打开,只是响应慢点,也就没有组织人力去修复了。

  毕竟周末时间找人也比较困难,就这么拖到周一,他埋了日志,周二才做了一版修复,上线。

  结果周三零点,整个活动页面的接口都超时,被电话打醒,赶紧排查,马上摇人服务端。

  他说有个服务一直在告警,那你们居然没点反应,我真是醉了,运维我也摇了,过了半小时才来。

  他说那个服务的 CPU 一直居高不下,服务端也没找出问题,还是我点醒他重启下服务,才恢复,额。

  这么一折腾,运营都要跳起来了,在群里狂抱怨,我也很无奈。

  其实我这边的日志显示从周二的 21 点开始,慢响应持续上升,我也大意了。

  改了接口居然没关注,以为一切顺利,其实不然,今晚的日志一定要仔细关注了。

  服务器的配置也会让运维升级,其实这个接口也是让 QA 测试过的,并没有功能问题。

  但是却存在严重的性能问题,QA 之前自己也说以后得增加这块,这次的问题是三方都有责任,既有客观也有主观原因。

  公司在经历裁员之后,服务端有经验的员工都离职了,这个留下的小伙来了才 1 年,模块也刚接手,开发经验也缺乏。

  以后得完善测试流程,以及自己要多留心眼,就好像常说的不要完全信任用户的输入,协作时也有这点意思。

2)OKR

  公司要求我们每个双月要制订自己的 OKR,然后还要对齐上级的 OKR。

  我对齐了上级的双月高等级业务需求,不过我总觉得这个并不算 OKR,因为这些都是我们本月排进日程的任务。

  第二个 O 是质量相关,将线上因代码问题导致的高等级 BUG 或事故降低至 0,之前写的 KR 不够具体,无法明确 KR 与 O 之间的联系。

  那么这次又修改了一下,分析以往发生重大线上事故的原因,发现很多时候是因为慢 SQL 和数据库表太大撑满了整个数据库的容量。

  由此就马上将其作为一个 KR,组织排查与优化,保持数据库健康。还真找到不少潜在问题,例如已没有记录的一张表,还占用 29.12GB 容量,立刻释放掉。

  然后通过下面的 SQL 语句找到排名靠前的数据库表,清理不再需要的数据库表。

select
table_schema as '数据库',
table_name as '表名',
table_rows as '记录数',
truncate(data_length/1024/1024, 2) as '数据容量(MB)',
truncate(index_length/1024/1024, 2) as '索引容量(MB)'

from information_schema.tables

where table_schema='backend'order by data_length desc, index_length desc;

  另一个在使用的数据库是 MongoDB,用代码列出容量占用比较高的集合,发现可以释放掉 100G,每个月能减少 50 元的费用。

  第二个 KR 是定期 Code Review,包含细节、安全、边界等内容,保障代码健壮性。Code Review 在执行时,安全性往往会被忽略,仅仅是复查逻辑的合理性是不够的。

  还有些细节也应该放上台面,隔壁组服务端前段时间出现了非常严重的线上紧急 BUG,发生在 2 月 29 日那天,他们有段计算年龄的代码。

  会将当天推算到 18 年前的当天,但是 18 年前的 2 月没有 29 号,导致计算异常发生了 BUG。但其实算年龄,完全不必如此计算,若在 Code Review 中就将此问题抛出。

  那么就不会发生此类线上问题,关键发生在凌晨,都很难及时修正。

  对三个 KR 分析飞书告警,修复会对业务造成影响的潜在问题。我们会将线上的页面错误和接口错误实时通过飞书发出告警。

  这些告警可能不是最为紧急严重的,可能就是偶尔发生的,但是将它们修复,有助于避免潜在的风险。

站心网

一、日常问题1)页面卡死 QA 将一个页面放在客户端中访问,进行功能测试的时候,发现运行在 iOS 16.7 系统..

为您推荐

技术团队管理者的问题视角

团队基建考虑的因素- 人心稳定性- 团队技能分布:(每个人熟悉的技术栈,技能)- 团队职业规范方向:(谁去当架构师、技术专家、技术经理、交互专家)- 合作意识:(工程师的积极性:主动问询,共同协商)- 团队规范..

作为程序员的思考与反省

子曰:吾十有五而志于学,三十而立,四十而不惑,五十而知天命,六十而耳顺,七十而从心所欲,不逾矩。人生又有几个十年?距离三十还有7年。7年看似很长但也很短。或许有人说我过早的杞人忧天。三十岁对于一个程序员..

.NET 9 即将推出的功能Task.WhenEach

.NET 爱好者!我刚刚偶然发现了一个非常酷的新 PR,它被合并到 .NET 运行时存储库中,我想分享一个例子。希望您能为新的 .NET 版本大肆宣传!在即将到来的 .NET 9 版本中,我们预计会有一个名为 .它在这里让您的异步..

针对 Go 语言开发的 SQL 驱动模拟库

数据库交互是几乎所有应用程序不可或缺的一部分,开发者们常常需要对数据库进行各种操作,包括插入、更新、删除和查询等。然而,在开发过程中直接对真实数据库进行操作不仅耗时耗力,还可能带来数据一致性和安全性的..

DockerUI 中文可视化Docker管理工具使用示例

DockerUI 是由国内开发者打造的一款优秀的 Docker 可视化管理工具。该工具拥有简洁直观的UI界面,可以轻松进行Docker主机管理、集群管理,以及Docker任务的编排等操作。DockerUI不仅展示了资源利用率、系统信息和更..

Blazor的N种渲染模式原理和常见问题说明

我们从下面这幅图开始,下图显示了三种渲染模式,分别称之为静态SSR、交互式SSR(即之前的BlazorServer)、交互式CSR(即之前的BlazorWasm)。还有一种渲染模式BlazorHybrid,稍后说。一、先浅层理解一个图例静态SSR:经..

前端CSS常见的三种设计模式

CSS设计模式主要包括OOCSS、SMACSS和BEMCSS等。以下是对这些模式的具体介绍:OOCSS:面向对象的CSS,旨在编写高可复用、低耦合和高扩展的CSS代码。它将抽象(结构)和实现(样式)分离,抽离公共代码,以提高代码的..

WinToUSB | 把Windows塞进U盘里即插即用

不论是在外出差,还是在家临时办公,现在很多设备携带起来都不是那么方便,在这种情况下,有一个轻巧而高效的操作系统环境就显得格外关键。今天,要给大家介绍一款超级实用的便携式系统启动盘,凭借其独特功能和卓越..

.NET Framework被淘汰了吗?

.NET Framework并未完全被淘汰,但它的某些版本确实已经停止支持。微软在2023年11月10日停止了对.NET Framework 4.8之前的版本的支持。这一决策意味着使用这些旧版本的应用程序将不再获得安全更新和其他维护,从而可..

强大的 .NET Mock 框架 单元测试模拟库Moq使用教程

单元测试是确保代码质量和可靠性的重要手段。当我们的代码依赖于外部系统、数据库或第三方服务时,编写有效的单元测试可能会变得复杂且耗时。为了简化这一过程,模拟(Mocking)技术应运而生。在 .NET 生态系统中,M..

CLS 问题:超过 0.1(桌面设备) 是什么意思?

在网页设计和开发中,CLS(Cumulative Layout Shift)是指页面布局的累计偏移量。当一个用户与页面互动时,如果页面的某些元素突然改变位置或大小,导致整个布局发生偏移,就会产生布局偏移。这种偏移可能会影响用户..

Angular UT 模拟执行setTimeout

在 Angular 单元测试中,我们经常需要模拟异步操作,比如 setTimeout。提高测试速度: 真实环境下的 setTimeout 会阻塞测试,导致测试运行时间过长。确保测试的可靠性: 模拟 setTimeout 可以让我们更好地控制异步操..

JavaScript 的 sessionStorage 能否加锁?

直接给 sessionStorage 加锁是不可能的。sessionStorage 的本质: sessionStorage 是浏览器提供的一种用于在当前浏览器会话中存储数据的机制。它存储在客户端,数据仅在当前浏览器窗口或标签页中有效。加锁的必要性..

Redis 同步、击穿、穿透及雪崩简述

对Redis最常见的几个问题,简要的说下我的理解与解决方法。数据同步指Redis做为缓存,在数据变化时,怎么保持与数据库数据同步的。一般解决方案为:缓存双删(同步方案大都采用删除缓存,而不会更新新缓存。缓存击穿..

Vue 3.5引入新特性 还有与SSR相关的改进

Vue 3.5引入了响应式属性解构、useTemplateRef方法、useId实用函数、内部响应性重构等新特性。以下是具体介绍:响应式属性解构此功能允许开发者在defineProps宏中解构属性而不会失去响应性,这为组件间的属性传递提..

Asp.Net Core进程内托管 和 进程外托管的区别

在ASP.NET Core中,托管模型决定了应用程序如何运行及其与Web服务器交互的方式。主要有两种托管模式:进程内托管(In-Process Hosting)和进程外托管(Out-of-Process Hosting)。每种模式都有其独特的优势和适用场..

C# 使用Barrier进行多线程同步

在多线程编程中,同步是一个关键问题。Barrier 是 .NET 提供的一种同步机制,用于协调多个线程在执行某个阶段工作时进行等待,直到所有参与的线程都达到某个同步点后再继续执行。这对于需要在多个线程之间进行阶段性..

ASP.NET Core实现多语言本地化Web应用程序

构建全球可访问的网站和应用程序需要对内容进行适当的本地化,以吸引来自不同文化和地区的用户。ASP.NET Core 提供强大的本地化支持,以用户首选的语言和格式呈现内容。在本综合指南中,我们将探索 ASP.NET Core 中..

ASP.NET生成图片验证码

今天开始做一个新项目,包含完整的注册登陆流程,在登陆时需要输入验证码防止暴力破解。 制作思路是这样的: 准备使用handler一般处理程序来写,先随机从0-9和A-Z里随机取4个数字,将内容保存在Session中供验证时使..

C#发送邮件代码简洁示例(附源码下载)

C#发送邮件,主要使用的是System.Net.Mail命名空间下的方法实现,方法很简单,短短十几行代码即可完成发送,具体代码如下。 try { MailMessage myMail = new MailMessage(); myMail.From = new MailAddress..

发表回复

返回顶部