| 九月 | ||||||
|---|---|---|---|---|---|---|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
| 30 | 31 | 1 | 2 | 3 | 4 | 5 |
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 | 1 | 2 | 3 |
对方法和工具的依赖
o6z几年前好像就说CSDN软工版都是侃爷,光说不练只知道些理论没有实践经验。
我很惭愧。几年来也就是偶尔上去看看,处理一些违规帖。
确实,问一些很二,很无聊问题的人很多,同时,很二,很无聊的回答也很多。
有时挺让人看着生气。
譬如这个问题:何保证软件质量呢?一般都用什么方法或工具?
我的回答是:我也想知道有什么工具能保证牛奶的质量。
下面是一个我觉得很二的回答,而这个回答可能会得到这个帖子全部20分的一半以上,在那里往往是写字越多,得分越多:
好大的题目啊
质量问题现在越来越受关注
不同的人有不同的看法,不同的人有不同的作用
客户,系统设计人员,项目经理,开发工程师,QA人员,测试人员
PS:突然发现这几个角色我都扮演过,哈哈哈
总之把各个阶段的缺陷控制住就相当不容易了
个人觉得,需求理解和设计阶段是最重要的,此时引入的缺陷,在分析设计阶段被发现了还ok,真正到了后面就闹大了
慢慢总结,关于质量真的有很多话题可以说
说到工具和方法,缺陷跟踪工具,缺陷围堵方法,同级评审,技术评审,需求评审,总之评审是个很好的方法~~就是太花时间和精力
一家之言仅供参考
祝你成功
初学Perl之二
程序有问题,有关字符串匹配。会用index函数去查找字串,那就能找到正确的行。可是运行总是报错,看不懂报错信息。怀疑是语法错误,却不知道错在哪儿。不像C,编译就排查了语法错误。CSDN上乱翻贴,看到有人推荐一个工具Komodo(下载)。装了后打开我的程序源文件,看到一行波浪线,太好了,这里有问题:
可是什么问题呢?书上说模式匹配函数(m//)是这样用的:
-
m/pattern/;
还说m后的第一个字符是模式分隔符。在一个例子里用!做分隔,我没有正确理解,这是把缺省分隔符(/)换成其他的(!)。因此这样才对:
现在的程序可以跑,但是结果不对。问题还是在这一行。我要取出所需要的字串。哪里不对?应该怎么写?没人可问,继续琢磨。
初学Perl之一
开始学习Perl,起由是想做个小工具,用C也可以,一则不急,二则不忙,那就慢慢做。
先下载ActivePerl,5.10.0 Build 1004。CSDN上看人介绍又下了个perl-lint-mode,也不知道怎么用,先放着。再下载EditPlus做编辑器。
我的第一个perl程序问题是:global symbol requires explicit package name at xxx。
google这个报错信息,知道了问题所在。程序里用了use strict之后,就必须用our或者my声明变量。为什么呢?找到了这个介绍:Use Strict And Warnings。
程序很简单,我只是想试一下命令行参数。
代码之美 - 081104
《当你与世界的联系只有一个按钮时》,Arun Mehta讲的是给霍金教授设计写字和说话的软件。Mehta是一个印度人。
这一篇的翻译一般,也许是译者看原文看得很枯燥,译文让我读得也枯燥。
由于输入只能通过对一个按钮的点击,软件的设计煞费苦心。主要以树型结构为基础,用表实现预测,用缓存提高命中。
有兴趣的可以去这个讨论列表。
P535有一个错误,“在界面的右下方显示了两个数字(参见图30-2)”,应该是图30-1。可我查了英文版,也错为30-2了。
代码之美 - 081022
《漂亮的调试》,Andreas Zeller以ddd的一个bug为引,介绍了增量调试(Delta Debugging),主要思想类同二分,算法好理解,可是程序看不大明白。
程序如下。
-
def dd(c_pass, c_fail, test):
-
"""Return a triple (DELTA, C_PASS', C_FAIL') such that
-
- C_PASS subseteq C_PASS' subset C_FAIL' subseteq C_FAIL holds
-
- DELTA = C_FAIL' - C_PASS' is a minimal difference
-
between C_PASS' and C_FAIL' that is relevant with respect
-
to TEST."""
-
-
n = 2 # Number of subsets
-
-
while 1:
-
assert test(c_pass) == PASS # Invariant
-
assert test(c_fail) == FAIL # Invariant
-
assert n >= 2
-
-
delta = listminus(c_fail, c_pass)
-
-
if n > len(delta):
-
# No further minimizing
-
return (delta, c_pass, c_fail)
-
-
deltas = split(delta, n)
-
assert len(deltas) == n
-
-
offset = 0
-
j = 0
-
while j < n:
-
i = (j + offset) % n
-
next_c_pass = listunion(c_pass, deltas[i])
-
next_c_fail = listminus(c_fail, deltas[i])
-
-
if test(next_c_fail) == FAIL and n == 2:
-
c_fail = next_c_fail
-
n = 2; offset = 0; break
-
elif test(next_c_fail) == PASS:
-
c_pass = next_c_fail
-
n = 2; offset = 0; break
-
elif test(next_c_pass) == FAIL:
-
c_fail = next_c_pass
-
n = 2; offset = 0; break
-
elif test(next_c_fail) == FAIL:
-
c_fail = next_c_fail
-
n = max(n - 1, 2); offset = i; break
-
elif test(next_c_pass) == PASS:
-
c_pass = next_c_pass
-
n = max(n - 1, 2); offset = i; break
-
else:
-
j = j + 1
-
-
if j >= n:
-
if n >= len(delta):
-
return (delta, c_pass, c_fail)
-
else:
-
n = min(len(delta), n * 2)
-
1,第三行注释翻译成:“C_PASS是C_PASS'的子集,C_FAIL'是C_FAIL的子集”。想了一想,没错,函数是逐步缩小c_pass和c_fail之间的差异,在书中例子里,也是通常情况下,c_pass是空的,c_fail是“失败全集”。
2,在 j < n 这个循环里,n = 2, i = 0, 把全集分成两部分,如果第一个 if 成立,c_fail等于其中一部分,n = 2, offset = 0, break是否是跳出这一堆if-elif-else?跳出的话回到循环开始,j 没有机会改变,i 也就仍然等于0。我尝试着模拟几种情况,n等于2、4、8,似乎程序跑步到 else 里,j = j + 1 没有机会被执行,i 的值也就得不到改变。也许我对 test 函数的返回理解有误。摇头叹息看不懂看不懂。
作者说在这本书的O'Reilly网页上也有这段代码,于是去下载,下载的代码和书上的不大一样,算法是一致的,清楚多了,一看就明白。再回头看上面这一段,还是觉得不大对。作罢作罢。
文中还提到Continuout Testing。作者说他开了一门课,专门讲授科学方法和增量调试,课程幻灯片和参考文献在:http://www.whyprogramsfail.com/,可是我打不开这个网页。还有增量调试的主页:http://www.st.cs.uni-sb.de/dd/。
代码之美 - 081017
《代码如散文》。Yukihiro Matsumoto自然对Ruby大夸特夸。作者用简洁的一篇散文谈了谈漂亮代码的几个因素,简洁,保守,简单,灵活。
有两句话应该时时记住:
程序中不应该包含无用的信息。
不要重复代码,不要把相同的东西编写两次。
代码之美 - 081016
《优雅代码随硬件发展的演化》,因为题目的诱人,选择读这一章,开了头就发现上当。
磕磕巴巴把前面的问题描述读完,被示例程序14-1难倒了。且不说MATLAB的奇怪写法,LU因式分解我也没搞清楚,于是,这个30多行的程序,来来回回多少遍也看不明白。自然也就不明白作者说的这个代码如何地漂亮。
了解了一下LU因式分解,再去看程序,还是头晕。于是决定放弃看代码,包括后面的FORTRAN代码和C代码。
马马虎虎看完这一章的汉字,一知半解的,大约知道Jack Dongarra和Piotr Luszczek(他的主页上links提供了很多好看链接)在说漂亮的代码如何高效地利用存储器层次结构获得高性能。
代码之美 - 081008
《Linux内核驱动模型:协作的好处》这章篇幅不大,可读得费劲。
上来就有两句话没看懂:在2.4版本的内核中,每一个设备的物理部分都由一段总线特定的代码来控制。总线代码负责各种不同类型的任务,而每一种具体总线的代码之间则没有交互。
后一句的原文是:This bus code was responsible for a wide range of different tasks, and each individual bus code had no interaction with any other bus code.
这里,总线特定代码(bus-specific code)是什么意思?
然后,Greg Kroah-Hartman提出两个问题,1是在解决电源管理问题时,内核需要知道不同设备的连接关系;2是不论哪一台USB打印机先启动,两台打印机的名字永不变。
其他系统的一般解决方法,1是内核中放一个处理设备名的小数据库,2是通过文件系统中可以直接访问设备的devfs类型来导出设备的所有信息。
对Linux来说,内核里放数据库是不能接受的,同时,Linux的devfs文件系统实现中“存在一些众所周知的且难以消除的竞争条件,导致几乎所有的Linux发布的版本中都不能依赖它。”这句话怎么理解?
再然后,作者用一个“简单”的例子展现了,展现了什么呢,我觉得是展现了C语言的复杂用法。如作者所说:是的,非常强大,只要你清楚地知道你正在做什么。
不信就看看这个宏吧:
-
#define container_of(ptr, type, member) ({ \
-
const typeof( ((type *)0) ->member ) * _mptr = (ptr); \
-
(type *)( (char *)_mptr - offsetof(type, member) );})
作者通过介绍Linux内核中解决前面提到的两个问题所需的数据结构和支持函数的演变,来说明协作给Linux带来的好处,还好文末有个总结,否则我又要忘了他要说什么。
代码之美 - 081007
《漂亮的测试》这一章很容易阅读,Alberto Savoia介绍如何写测试用例,漂亮的。
他举例说明如何写漂亮的测试代码,这个过程又是如何使被测代码变得更好。其实,更加强调的是程序员本来就应该测试自己的代码。
有多少程序员像画家一样,常常放下笔,站远点,从不同角度,在不同光线下,审视自己的作品呢?
我很少编写程序去测试自己写的函数,我的同事也一样。我们更多依赖运行整个程序检查结果是否正确,依赖测试组的同事们。
作者介绍的是Java程序员常用的JUnit。
不要给自己找借口,只要想做,办法总是有的。
挑了几个错误,填写到这里。
代码之美 - 081003
收到了《代码之美》,把目录翻来翻去,在33章里找我最容易能看懂的,似乎并没有哪一章让我觉得可以顺畅阅读不用多加以思索的。
最后挑选了第24章《美丽的并发》,作者是Simon Peyton Jones,他用Haskell语言来介绍STM(Software transactional memory),看得我很头大。注意力几乎全被Haskell语言占据了,3、5行的程序段却费了不少脑筋去思量。以至于文章最后作者在总结的时候,我都没有感觉到他说的所有的好处到底在哪里。回头想想,似乎是那么回事,可一到细节,脑子里搅和的还是语言的细节。
反正我记住了,最大的好处是使并发程序的模块性更好。还避免了不少常犯的错误。
这一章里的代码有下载。
我还想知道,Haskell多用在什么地方?记录下Haskell的官方网站,那里可以找到很多信息,下载很多东西。
再记下这本书的英文版勘误信息。
说不清,写下来
很多时候,人们并不打算为其口头的表述承担责任。因为“说得轻巧”,往往就脱口而出。
事后如果出了问题,可能确实记不确切自己曾经是如何说的,也可能不承认的效益更大。
而人们对于必须写下来的东西,会慎重很多。其程度是纸笔写下 > email/电子文档 > 口头表述。
所以在承担责任的扯皮中我建议无论接受上级的任务指派,还是和其他同事关于工作内容的交流,使用email。
重要事宜,打印,签字。
如果同事不愿意回复email,只是口头传达。告诉他口头之外,再发一封email,以免你遗忘。发给他的询问email同时cc给你的上级和他的上级。
责任承担的扯皮
组织结构:
Z是内容部员工,B是技术部员工,A是B的上司,同时也是总管。就是说,A也是Z的上司。
事例:
一个特殊任务,A口头告诉Z可以使用免费代码,具体代码问B。
Z口头问B,B口头告知是F代码。
Z使用了F代码。
次日,发现出错了。
A追究是Z做错了,先声称自己从来没说过可以这样做。
Z回答B告知使用F代码。
A说B称从未说过。B事后称其说的是FX代码。
怎么办:
1)与B当面澄清,是否有曾去询问一事。有则是如何回答的。
2)以后,对于上司口头交代的任务,听完后说:“好,我知道了,请你再发一封email给我。”如果不愿意发email,就把接受到底任务写一封email发给上司,问他是这样吗。发出后电话或口头告知。
3)对于在和其他部门同事合作中,任何需要对方确认的事,务必使用email。记录下合作过程中每个人对自己的工作内容所做的判断和选择。
PHP初学——字符串
PHP的语法也实在是搞,表示字符串可以用双引号",也可以用单引号'。
和C一样也是用'\'转义,如果串里要显示'\',双引号得这样'\\';单引号,'\'就可以了。
既然'\'表转义,如果要表达单引号',在使用单引号的情况下,这样写:
-
'this string has a \' quote.'
就是说,在单引号内的'\'是转义字符还是'\'它自己,取决于它后面的内容。
这不是找麻烦嘛。
rgb to yuv
-
void RGB2YUV(BYTE *in, BYTE *out, DWORD len)
-
{
-
int r,g,b;
-
int y, cb,cr;
-
int i;
-
int data;
-
-
for(i=0; i<len; i=i+4)
-
{
-
r = *(in+2);
-
g = *(in+1);
-
b = *(in);
-
-
y= (0.257*r + 0.504*g + 0.098*b + 16);
-
cb = -0.148*r - 0.291*g + 0.439*b + 128;
-
cr = 0.439*r - 0.368*g - 0.071*b + 128;
-
if(y <16)
-
{
-
y = 16;
-
}
-
else if(y>235)
-
{
-
y = 235;
-
}
-
-
if(cb <16)
-
{
-
cb = 16;
-
}
-
else if(cb>240)
-
{
-
cb = 240;
-
}
-
-
if(cr <16)
-
{
-
cr = 16;
-
}
-
else if(cr>240)
-
{
-
cr = 240;
-
}
-
*(DWORD *)out = 0x7f000000 + ((DWORD)cr<<16) + ((DWORD)cb<<8) + (DWORD)y;
-
-
in += 4;
-
out += 4;
-
}
-
}
Windows 98 源代码
-
/*
-
微软最高机密——Windows 98 源代码
-
项目:Chicago(tm)
-
项目发行日期:1998年夏天
-
*/
-
-
#include "win31.h"
-
#include "win95.h"
-
#include "evenmore.h"
-
#include "oldstuff.h"
-
#include "billrulz.h"
-
#define INSTALL = HARD
-
-
char make_prog_look_big[1600000]; /*使程序看起来很大*/
-
-
void main()
-
{
-
while(!CRASHED) { /*如果不崩溃*/
-
display_copyright_message(); /*显示版权信息*/
-
display_bill_rules_message(); /*显示比尔的规则的信息*/
-
do_nothing_loop(); /*进行空循环*/
-
if (first_time_installation) { /*如果是第一次安装*/
-
make_50_megabyte_swapfile(); /*创建50M的交换文件*/
-
do_nothing_loop(); /*进行空循环*/
-
totally_screw_up_HPFS_file_system(); /*将HPFS文件系统完全搞乱*/
-
search_and_destroy_the_rest_of_OS/2(); /*搜寻并删除OS/2的所有残余信息*/
-
hang_system(); /*挂起系统*/
-
}
-
write_something(anything); /*随便写一些信息*/
-
display_copyright_message(); /*显示版权信息*/
-
do_nothing_loop(); /*进行空循环*/
-
do_some_stuff();
-
if (still_not_crashed) { /*如果还没崩溃*/
-
display_copyright_message(); /*显示版权信息*/
-
do_nothing_loop(); /*进行空循环*/
-
basically_run_windows_3.1(); /*基本上运行Windows 3.1*/
-
do_nothing_loop(); /*进行空循环*/
-
do_nothing_loop(); /*进行空循环*/
-
}
-
}
-
-
if (detect_cache()) /*如果检测到缓存*/
-
disable_cache(); /*使缓存失效*/
-
-
if (fast_cpu()) { /*如果CPU很快*/
-
set_wait_states(lots); /*设置等待状态*/
-
set_mouse(speed, very_slow); /*设置鼠标(速度很慢)*/
-
set_mouse(action, jumpy); /*设置鼠标(动作跳跃)*/
-
set_mouse(reaction, sometimes); /*设置鼠标(有时反应)*/
-
}
-
-
/* printf("Welcome to Windows 3.11"); */
-
/* printf("Welcome to Windows 95"); */
-
-
-
if (system_ok()) /*如果系统正常*/
-
crash(to_dos_prompt); /*崩溃(到DOS提示符)*/
-
else
-
system_memory = open("a:\swp0001.swp", O_CREATE);
-
/*否则打开a:\swp0001.swp作为系统内存*/
-
-
while(something) {
-
sleep(5); /*睡眠5秒钟*/
-
get_user_input(); /*接收用户输入*/
-
sleep(5); /*睡眠5秒钟*/
-
act_on_user_input(); /*对用户输入起反应*/
-
sleep(5); /*睡眠5秒钟*/
-
}
-
-
create_general_protection_fault(); /*产生一般保护错误*/
-
blue_screnn(); /*蓝屏*/
-
}
-
补充编译警告
在实际的工程中,往往会出现callback函数的参数类型,定义和实际使用的并不一致。要注意强制类型转换。
在某个 struct 定义中使用了 union,而此 union 中定义了两个结构,第一个结构包含5个 UINT8 类型的成员,第二个结构包含1个指针类型成员,1个 UINT16 类型成员,1个 UINT8 类型成员。工程中两个结构都会使用到,而编译器无法知道程序使用的是 union 中的哪一个成员,默认为第一个。由此产生类型不匹配的编译警告,这里有产生错误的隐患。
一些资源
http://digilander.libero.it/robang/rubrica/serial.htm -- Serial Programming Guide for POSIX Operating Systems
http://www.embed.com.cn/bbs/index.asp -- 嵌入开发网
http://www.lysator.liu.se/c/ANSI-C-grammar-y.html -- ANSI C Yacc grammar
http://www.51eda.com/bbs/index.asp -- 中国EDA技术网
http://bbs.driverdevelop.com/columns.php?action=columns -- 驱动开发网
http://www.linuxpilot.net.cn/ -- Linux Pilot
http://www.linuxworld.com/ -- linux world
http://www.linuxjournal.com/ -- linux journal
http://www.salon.com/tech/special/opensource/ -- the free software story
http://www.gentoo.org/ -- gentoo linux
http://www.linuxfocus.org/ -- linux focus
http://www.debian.org/intl/zh/mailing_lists -- Debian 中文计划邮件列表
http://www.debian.org/MailingLists/ -- debian Mailing Lists
http://www.sgi.com/tech/stl/ -- Standard Template Library Programmer's Guide
一些资源
方便自己经常看看。
http://home.lzu.edu.cn/cjj/ -- 一个C/C++学习小站
http://www.qaforums.com/ -- sqaforums
http://www.testage.net/html/index.html -- 测试时代
http://www.soft.com/ -- software research
http://www.sqe.com/stareast/ -- software testing
http://student.zjzk.cn/course_ware/data_structure/web/main.htm -- 数据结构
http://blog.csdn.net/jinhao -- C++
http://blog.csdn.net/gigix -- 透明
http://blog.csdn.net/kathywp -- DirectX
http://fanqiang.chinaunix.net/ -- 永远的UNIX
http://www.iu.hio.no/~mark/unix/unix_toc.html -- The unix programming environment
http://www.chinalinuxpub.com/ -- linux php mysql
http://cvsbook.red-bean.com/cvsbook.html -- Open Source Development with CVS, 3rd Edition
http://www.gnu.org/software/libc/manual/ -- The GNU C Library
http://www.menuetos.net/ -- Menuet OS
编译警告
一个项目,编译出近千条warning。
大部分大部分大部分是下面这四条导致的。
1)局部变量定义后使用前没有初始化。
2)函数体在调用处后,调用前没有声明。
3)类型转换。
4)比较运算符两边变量的类型不同。
计划啥?
有人问:“在做测试计划时,如何估计软件的缺陷数量?”
这实在是一个很二的问题。
做计划的时候干吗要去估计Bug有多少?
有人回帖说:“作测试计划的时候,是应该估计一下该软件的BUG数量,BUG集中点,以及修改该BUG的难度与时间,如果这些不估计,那编写测试用例的时候无法对某些重要模块作出着重测试”。
神了,做测试计划的时候都能估计出修改Bug的难度和时间了,也别计划了,赶紧解Bug去吧。