分类 技术志 下的文章

QA人员一定要有实际项目经验

最近一段时间正处于项目策划阶段,这个阶段势必要和部门QA打交道,咨询问题并获取支持。按照我们公司的软件开发流程,策划阶段要输出一系列文档的。这些文档都是有公司模板或者是经部门裁剪后模板作为基础的,所以现在项目前期策划基本上就是按照自己的思路填写文档,估计很多公司也都是这么做的。

好不容易花了一个星期的时间把这些文档'填全'了。提交给QA,让之帮忙审审。QA的一封邮件回来,问题多多。

当我看到这些QA提出的问题时,我的第一个念头就是"QA人员一定要有实际项目经验"或者说这些体系文档QA自己按照流程一个一个的实践一下,自己填一遍。这样就能体谅这些问题是为什么发生的了。比如说:QA建议每个项目阶段前都要有一个任务叫"策划xx阶段",用过MS Project的人都会了解,如果分配给一个人的任务散布在整个Project甘特图的各个部分,十分不利于人员的任务分配,你要考虑到任务间的依赖关系,还要考虑到'资源工作表'中每个资源不能'变红(过载了)'。这些阶段性策划在实际项目过程中都是在一个集中的时间段完成的,大可集中放到一处。还有,对于多人参与的任务也是很难分配的,也是要考虑依赖关系和资源过载的。

部门的QA没有实际项目经验,隶属学院派的,工作很认真,并且有坚定的过程改善的信念,唯一缺乏的就是实际的项目经验。如果能到一线锻炼一下,相信她会发现更多待改善的问题,也就不用我们不断的提意见、沟通、反驳、再沟通、再达成一致了。谈到QA,我的理解是:QA一定要有坚定的信念,很好的执行力,丰富的项目经验,相信通过良好的不断改进的过程一定能让项目管理更加精确、准时。否则如果没有这份坚定,做起工作来那简直就毫无乐趣而言了。很多大公司的QA都是由一线开发人员、测试人员或者是项目管理人员转型后来做的,他们在项目里待过,知道改善的地方在哪里,同理心更强,知道开发人员为了达到某个项目管理的目标需要付出的代价。有项目经验的QA能大大减少纸上谈兵的概率,提高自己的说服力。

还有很多问题原因不在QA,而是模板的问题。填写模板时我们也希望要填写自己能控制、能想到的东西,如果在自己控制力之外的一些东西非要填,那就很头疼了。其实这也和部门角色定位有关系。部门的项目负责人与传统意义上的项目经理不甚相同,部门的项目负责人在一定意义上是偏技术类的。如果让偏技术类的负责人去填写什么"信息资产管理"、"共利益者管理"、"客户资产管理"、"项目采购计划"这类的表格显然是"门不当户不对"。

做项目也是做事,应该本着一个原则'简单'。把一些与项目目标不相关的事情也牵扯进来似乎费力费神,毫无意义。记得在上一个项目总结会上提到过一个成本目标的问题,项目初期策划时需要填写一个成本估计,然后结项时收集实际成本数据做比对,看目标是否达成。可是项目总结时根本无处获取这样一个成本数据,财务那面根本就不会给我们技术负责人出这种报表的,类似这样的'估计'估之作甚呢。

意见和建议已经提交给QA了,估计明天又会有一次激烈讨论。^_^

也谈’SIGBUS和SIGSEGV’

SIGBUS和SIGSEGV也许是我们在平时遇到的次数最多的两个内存错误信号。内存问题一直是最令我们头疼的事情,弄清楚两个信号的发生缘由对我们很好的理解程序的运行是大有裨益的。

我们来看两段程序:
//testsigsegv.c
int main() {
        char *pc = (char*)0×00001111;
        *pc = 17;
}

//testsigbus.c
int main() {
        int *pi = (int*)0×00001111;
        *pi = 17;
}

上面的代码那么的相似,我们也同样用gcc编译(加上-g选项,便于gdb调试;平台Solaris Sparc),执行结果也都是dump core。但通过GDB对core进行观察,你会发现细微的不同。第一个例子出的core原因是:Program terminated with signal 11, Segmentation fault. 而第二个例子的core则提示:Program terminated with signal 10, Bus error. 两者有什么不同呢?这两段代码的共同点都是将一个非法地址赋值给指针变量,然后试图写数据到这个地址。

如果要说清楚这个问题,我们就要结合汇编码和一些计算机的体系结构的知识来共同分析了。

先来看testsigsegv.c的汇编码:
… …
main:
        !#PROLOGUE# 0
        save    %sp, -120, %sp
        !#PROLOGUE# 1
        sethi   %hi(4096), %i0
        or      %i0, 273, %i0
        st      %i0, [%fp-20]
        ld      [%fp-20], %i1
        mov     17, %i0
        stb     %i0, [%i1]
        nop
        ret
        restore
… …

我们关注的是这句:stb     %i0, [%i1]
从计算机底层的执行角度来说,过程是如何的呢?%i0寄存器里存储的是立即数17,我们要将之存储到寄存器%i1的值指向的内存地址。这一过程对于CPU来说其指挥执行的正常过程是:将寄存器%i0中的值送上数据总线,将寄存器%i1的值送到地址总线,然后使能控制总线上的写信号完成这一向内存写1 byte数据的过程。

我们再看testsigbus.c的汇编码:
… …
main:
        !#PROLOGUE# 0
        save    %sp, -120, %sp
        !#PROLOGUE# 1
        sethi   %hi(4096), %i0
        or      %i0, 273, %i0
        st      %i0, [%fp-20]
        ld      [%fp-20], %i1
        mov     17, %i0
        st      %i0, [%i1]
        nop
        ret
        restore
… …

同样最后一句:st      %i0, [%i1],CPU执行的过程与testsigsegv.c中的一致(只是要存储数据长度是4字节),那为什么产生错误的原因不同呢?一个是SIGSEGV,而另一个是SIGBUS。这里涉及到的就是对内存地址的校验的问题了,包括对内存地址是否对齐的校验以及该内存地址是否合法的校验。

我们假设如果首先进行的内存地址是否合法的校验(是否归属于用户进程的地址空间),那么我们回顾一下,这两个程序中的地址0×00001111显然都不合法,按照这种流程,两个程序都应该是SIGSEGV导致的core才对,但是事实并非如此。那难道是先校验内存地址的对齐?我们再看这种思路是否合理?

testsigsegv.c中,0×00001111这个地址值被赋给了char *pc;也就是告诉CPU通过这个地址我们要存取一个字节的值,对于一个字节长度的数据,无所谓对齐,所以该地址通过对齐校验;并被放到地址总线上了。而在testsigbus.c里,0×00001111这个地址值被赋给了int *pi;也就是告诉CPU通过这个地址我们要存取一个起码4个字节的值,那么对于长度4个字节的对象,其存放地址起码要被4整除才可以,而0×00001111这个值显然不能满足要求,也就不能通过内存对齐的校验。也就是说SIGBUS这个信号在地址被放到地址总线之后被检查出来的不符合对齐的错误;而SIGSEGV则是在地址已经放到地址总线上后,由后续流程中的某个设施检查出来的内存违法访问错误。

一般我们平时遇到SIGBUS时总是因为地址未对齐导致的,而SIGSEGV则是由于内存地址不合法造成的。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats