TA的每日心情 | 无聊 昨天 09:05 |
---|
签到天数: 1050 天 连续签到: 1 天 [LV.10]测试总司令
|
相信大家在工作中面试过程中经常被问到,让你印象最深刻的一个bug是什么,这是一个开放性的题目,并没有标准答案,每个人接触过的系统都不一样,遇到过的问题也不一样,可能面试官只是想看一下你的表达能力,以及平常在工作中是否会进行总结。这类问题可以挑选容易被人忽略的场景,难以想到的场景,特殊机型的兼容性或者特殊操作下才会出现的问题等。
接下来为大家分享第一个我遇到的一个问题:由于缓存中key的设置不合理导致的bug
相信大家经常遇到这样一种情况:页面加载和访问很慢,请求接口后要好几秒的时间才能返回结果,有的时候为了优化用户体验。或者有些公共接口频繁被调用,后端可能会加缓存,当使用相同的查询条件再次查询时,直接从缓存中查询结果返回给客户端,从而提升用户体验。
第二个bug的现象:
同一个接口,在手机上设置不同的时区后,在app上进行请求时,接口返回的数据中,有一个时间字段的值不一致。比如 在国内看到的某个字段值是2022-04-25,在国外看到的却是2022-04-24。
说明:
一般测试接口的时候,随便挑选几条数据去验证接口返回的话 ,字段值对应的上一般就没去太在意。
但是,一旦当你项目中的业务涉及到国外的业务时,如果相关的接口国内国外都会要调用同一个接口的话,可能一些特殊的字段处理如果稍不注意的话,就有可能会导致bug的产生。有些日期格式的字段,接口会转成0时区对应的时间返回,如果不清楚客户端和接口之间的一些处理的细节,像这种类似的问题就有可能会出现。
第三个Bug的现象:
之前在描述的是一个由于开发缓存的key设置的不合理导致的缺陷,现在还是围绕这个现象来展开描述。
先来看一下为什么要加缓存?
比如我们访问一个网站的时候,页面是不是经常会去加载一些图片以及js之类的静态文件,访问网站到加载完的这个过程中耗时可能比较长,对用户的体验不太好,如果每次都要这么长的时间,那久而久之用户是不是就会失去耐心呢,因此,[url=]浏览器[/url]一般会将这种访问过的静态资源缓存起来,下次再需要加载的时候,就直接从缓存中去取,这样会提高页面渲染的速度。
同理,相同的一个接口,如果同样的查询条件,返回的都是同样的数据,那为什么在一个比较短的时间内,每次都要从数据库去查数据呢?为了减轻数据库的压力,也为了提高接口的性能,针对一些访问量比较大并且数据变化比较小的数据,接口会将查询结果缓存起来。其中一种可选的方案就是将结果缓存到redis中。
接口加了缓存之后,测试的时候有什么要注意的?
接口加缓存之后,会有什么显著的效果呢?比如原来一个接口查询需要1分钟才能返回结果,那么第二次用相同的条件查询的时候,可能就只需要1秒不到了。看上去缓存很方便,但是使用不当的话,容易造成重大的问题。
1、测试人员在测试接口的时候,要跟开发确认一下接口是否有缓存,缓存失效/刷新的时间是多长,以及缓存是以哪几个关键字段去设置唯一key的。尤其要检查这个唯一的key设置的规则是否合理 ,一般相同的条件会命中缓存,但如果设置错误,就会返回错误的数据。
2、做压测的时候,要确认下缓存的开关是否关闭。
3、测试人员要了解缓存的设计和实现的大致细节,便于更好的测试这块相关的业务是否均合理,返回的数据是否正确。
举例说明缓存的key设置不合理可能会出现的bug
假设现在有一个查询部门每个月使用的成本的接口,入参的话要传入token以及部门id进行查询。
那如果在这个接口上加上缓存,并且设置部门id是缓存的key,理论上不同的用户去查询相同的部门id的数据时,应该返回相同的数据。
但是,实际上,可能业务场景并不是你想的这样,假设你和你的上级领导都要查本部门的成本数据,你觉得你看到的数据和你上级看到的数据会一样吗?有可能接口层面还会有数据权限的概念,也就是说,你看到的数据和你领导看到的数据可能不一样,领导看到的是整个部门所有员工的数据汇总,而你作为下属只能看到自己的数据,因此,像这种接口的话 ,最起码设置key的时候,可能还得把userid加进去了。
看到这,当面试官下次问你缓存相关的问题或者问你有没有什么印象深刻的bug时,你的心中有思路了吗?
第四个这是一个由于时区转换的问题带来的bug。
背景:公司的业务涉及到国外的用户,在客户端有针对接口返回的一些时间字段根据用户手机的时区进行对应日期的转换。
bug的现象:
数据库某类数据存储的是yyyy-mm-dd的日期字符串格式,比如今天的数据,存储的就是“2022-05-26”,然后接口在输出的时候,之前跟下游约定好的是接口返回date的格式: "2022-03-22T00:00:00.000+0000",在做接口重构的时候,只关注了页面上展示的日期跟数据库的是否一致,对之前的业务也不是很了解,然后不知道客户端会根据手机当前设置的时区将接口返回的日期做一个转换后再展示到页面上,正好晚上验证同一个功能的时候,同事的一个手机上设置的是美东时区,我们俩在各自的手机上查看同一条数据展示的日期相差了一天,经过排查才发现是之前客户端有做时区转换的逻辑。
给自己积累的经验就是:有时候做功能测试也不能只关注最终的结果正确就行,也得结合接口一起去看一下返回,尤其像这种数据库里面存的是yyyy-mm-dd,接口返回的日期带了时分秒格式的,要特别注意一下是否有涉及国外的业务,会不会出现类似的这种bug。
第五个:遇到了一个线上的bug,也是跟缓存加载有关,下面简单地描述一下场景。
背景:
有一个缓存服务cache-services,里面提供了一个对外的接口,可以根据id进行查询,返回一系列的数据,其中有一个字段的返回值,在客户端会根据这个字段的值做一些校验处理,比如字段值为A的时候,就显示某个按钮。上线后过了几天,发现app上某个按钮本应该显示的,突然之间不显示了,这个就是问题的现象。
问题原因:
出现问题的时候,首先是下游找过来我们排查问题,初步定位是因为某个接口没有返回一个字段的值,导致客户端没有展示这个按钮。
下面再来简单的讲一下缓存的加载设计:
假设现在有两张表,t1和t2,他们通过一个叫id的字段进行关联。由于表里面的数据量比较大,因此接口会从缓存中去查询数据,不会直接查库,然后数据库里面的数据有更新的时候,每1分钟会去刷新一次缓存中增量变化的数据。
假设数据库表设计如下:
由于t1表是之前就已经存在的,已经会加载到缓存中去,并且之前的逻辑是每次t1的数据有更新时,会把对应id的数据覆盖掉。
最近,由于开发新的功能,加入了t2的表,换了一个人开发,在设计的时候,开发设计的是:在t2表里面有数据的时候,新增/更新数据时,把对应的字段source追加到之前对应id的数据的缓存中。由于我一开始测的时候,不清楚整个缓存加载的逻辑和设计,没有考虑到t1的数据有更新的时候,会覆盖之前的缓存,结果线上有一天t1的数据发生了变化,然后没有把source字段重新加到缓存中去。
问题解决的措施:
在加载主表缓存的时候,同时把其他附属表的相关字段也重新加载一遍。
|
|