精华内容
下载资源
问答
  • 每天写bug是一种怎样的体验?

    万次阅读 2018-02-10 00:00:00
    本文转载自公众号 小象源 | 小象 文 | 小象君“哥们,又在写bug呢?”据说这是对程序员杀伤力最大的一句话没有之一!之所以如此,那是因为这是句大实话啊!程序员的人生就是bug和debug交织在一起的悲歌尽管...

    点击上方“程序员小灰”,选择“置顶公众号”

    有趣有内涵的文章第一时间送达!


    本文转载自公众号  小象


     | 小象      | 小象君

    “哥们,又在写bug呢?”

    据说

    这是对程序员杀伤力最大的一句话

    没有之一!

    之所以如此,那是因为

    这是句大实话啊!

    程序员的人生

    就是bug和debug交织在一起的悲歌

    尽管每天都要和Bug打交道

    可你是否知道

    Bug这个叫法是怎么来的吗?

    上图中那个黑乎乎的东西

    就是史上第一个程序Bug——

    一只烧糊的蛾子

    1947年

    哈佛大学的计算机Harvard Mark II

    突然停止了工作

    程序员们费尽周折

    终于找到了问题的关键

    就是这只死掉的蛾子

    这就是Bug这种叫法的来由

    那时

    哈佛二代没有二极管和晶体管

    是继电器计算机

    靠无数个噼啪作响的电子元件运作

    时常有电弧闪光出现

    这只蛾子被闪光所吸引

    毅然决然地扑了上去……

    从此

    从此永垂不朽

    其实

    Bug虽然人人能写

    但也有高低之分

    总体来说

    水平越高的程序员

    Bug写得越是牛逼…

    不信?

    我们来看看这些大神级的Bug

    吊炸天的Google APP

    前阵子

    谷歌推出了一个好玩的App

    Google Arts & Culture

    用户可以上传自己的自拍照

    系统会将照片与艺术画作进行对比

    匹配出一张

    和用户长得很像的

    画作中的人物肖像

    社交网络顿时沸腾了!

    人们纷纷晒出自己的自拍匹配成果

    有些效果确实不错

    有些就比较尴尬了

    画面太美不敢直视

    不得不说

    这哥们确实长得很屌…

    出现这样的Bug

    只能归咎于脸部识别技术尚不完全成熟了

    希望Google能早点改掉这些bug

    让他们重新做人…

    Bumblebee惊天bug

    如果不是Bumblebee开源项目

    你会相信

    一个空格也能导致系统瘫痪吗?

    安装后,

    usr/会被删掉

    至于后果有多严重?

    看下图…

    怎么样?怕了吧?

    500英里的Bug

    来源:知乎用户郭智明

    信用卡关联Bug

    对这位仁兄的遭遇

    小象君深表同情…

    见怪不怪的微软Bug

    敢问Outlook

    你究竟干了什么伤天害理的事?

    连亲妈都不认你了!

    ……

    那些匪夷所思的Bug

    有些Bug的出现让人百思不得其解

    fix后除了无奈

    更让人哭笑不得

    我叫刘伟楠,凭啥屏蔽我?

    这位刘伟楠童鞋

    想以实名注册新浪微博

    但他发现只要涉及“刘伟楠”三个字

    甭管加怎样的前缀后缀

    都会注册失败

    即便以其他名称注册成功后

    更改昵称为“刘伟楠”也同样无法实现

    该童鞋万般无奈之下发了帖子

    一时间响应者无数

    最终在网友齐齐声讨下

    新浪微博取消了该项屏蔽

    不过至于为什么会出现这样的bug

    新浪微博并没有给出解释……

    飙高音造成笔记本死机

    最终解决方案:

    把固定硬盘的螺丝紧了紧

    固有频率改变

    硬盘就不共振了

    X射线带来的Bug

    Quora上有位程序员

    讲述了这样一个经历

    他为医院急救设计了一个相关程序

    在实验室运行良好

    但是每次在医院调试都出 bug

    作者只好到医院去现场调试

    经过漫长的测试终于发现

    是由于医院使用的X射线

    导致电脑内存总是丢失几个 bit 的信息

    致使程序出问题!

    最终的解决方案是

    把电脑的内存用铅板隔起来!

    硬盘分区搞死人

    故事发生在工厂

    工厂里有14条线

    其中一条线的zebra打印机

    在打印标签时

    比其它线要多耗时3秒左右

    即便打印的东西完全一样

    因为产线一直在生产

    所以没法在线debug

    只能在线外模拟

    但模拟结果一直都显示正常

    问题始终无法解决

    后来干脆换了电脑,fix了!

    最后看了下硬盘的分区格式

    服务器是NTFS

    这台电脑的D盘是NTFS

    而E盘居然是FAT32!!!

    谁特么这么干的!

    粗来!保证不打死你!

    中文和英文符号的差异

    请童鞋们看看

    如上两段代码有什么不同?

    一模一样是吧?

    但实际上第二行可以运行

    第一行却无法运行

    至于原因

    分享的童鞋最后说了

    中文的-和英文的-外表没有不同

    但编码就是不一样……

    微信大小写坑爹

    一位程序员自述

    3月份负责公司微信公众号开发

    当时的后台是技术领导写的,c#

    公众号支付的预定单和加密全在后台

    后来后台改版本

    由c#改为Java

    结果调了一晚上

    显示签名错误

    技术领导看了好久也不知道怎么回事

    c#的代码和Java的代码对了一遍

    发现没问题

    又把微信公众号配置也看了一遍

    也没问题

    各种百度、各种猜想

    各种验证,都不对……

    几乎把网上的说的问题都查了一遍

    还是不对……

    最后去微信官网看了开发者文档

    发现上面预定单的appId的i是大写

    但支付的时候是小写!

    于是,fix了……

    不是Bug的Bug

    有些程序员习惯了bug与debug的节奏

    遇到问题

    往往第一时间进行debug处理

    结果好不欢乐

    下面我们来听听

    他们和Bug的那些事

    Bug是Wifi

    刚进公司做iPad应用

    公司给了两台测试机:

    一台iPad4

    一台iPad Air

    应用里面有个资源下载功能

    同一个资源用同一段代码

    不过在iPad Air上下得飞快

    在iPad4上面就慢如龟爬

    一直搞不懂是什么问题

    两边程序都是一模一样

    但到底为什么会有这么大的差别呢?

    曾天真的设想

    是不是两台不同型号的设备内部

    某个网络相关的硬件不一样

    导致下载速度不一样呢?

    然后不断Google、百度查资料

    看帖看论坛看博客

    希望找到看有没有前辈遇到这种怪问题

    然而找了3天还是找不到……

    到了最后……

    特么发现

    那台iPad4连的

    是楼下咖啡店的WiFi……

    图像为啥黑屏

    直播伴侣

    是给主播用的视频美颜的工具

    眼下各大直播平台都普遍采用

    有一次程序作了大的架构调整

    结果发现图像黑屏了

    就下断点一步一步查

    先检查采集SDK给我的数据是否有问题

    再看看GPU图像数据缓冲区

    最后终于找到了问题

    fix了

    但第二天这个问题又出现了

    摄像头又一次黑屏了

    于是又开始设断点

    检查采集的图像数据

    检查GPU里的缓存数据

    检查经过美颜

    经过图像识别处理后的数据

    但是反复检查

    就是没有发现任何问题!

    心急如焚之际

    突然发现

    摄像头的正面扣在地上

    直挺挺的竖在那儿

    于是把摄像头拿起

    问题解决……

    游戏Bug

    作为程序员

    每次玩游戏遇到Bug

    总会设身处地地想

    这哥们到底怎么搞的?

    猎魔人

    魔兽世界

    质量效应

    人物和画面出现问题

    是游戏Bug基本的表现形式

    不过这还算好的

    起码情节没耽误

    下面这种情况就让人无奈了:

    我是团里里最厉害的大神

    今天要打团战

    突然我连人带马嵌到了鼓里

    怎样也甩不掉 

    想通过栅栏与鼓分离

    结果栅栏也甩不掉了

    没时间了,出城吧!

    栅栏比城门宽,出不去

    无法从城门走

    那用轻功吧!

    结果……

    连人带马嵌入了城墙里

    无奈只得联系客服

    说人能下来,但——

    打团战怎能没坐骑?

    然后客服给了我——

    生活中遇到的Bug

    浸淫行业数年

    练就了一双火眼金睛

    对于各类Bug最是敏感

    比如:

    弱弱地问下

    这趟是星际高铁吗…

    受宠若惊!

    您这是跨省来接我的吗……

    ……

    每次遇到这种情况

    小象君总会幻想

    如果我中意的妹子遇到Bug

    憋慌!

    除了写Bug

    我们更擅长Debug!


    —————END—————




    喜欢本文的朋友们,欢迎长按下图关注订阅号程序员小灰,收看更多精彩内容




    展开全文
  • 教你如何写BUG票 Bug Report Techniques
  • 点击上方蓝字设为星标下面开始今天的学习~2020 年到来以后,全世界不同地方的软件系统,出现了一些 bug。纽约街边的停车收款机,突然从 2020 年的第一天开始,不能正常接收信用卡支付...

    点击上方蓝字设为星标

    下面开始今天的学习~

    2020 年到来以后,全世界不同地方的软件系统,出现了一些 bug。

    纽约街边的停车收款机,突然从 2020 年的第一天开始,不能正常接收信用卡支付了。

    这使得人们只能使用硬币或者纽约市的专属停车收费 app:ParkNYC 进行付款。但是,都 2020 年了,很少有人会随身携带一堆硬币。至于这个停车收费 app,因为必须要预先存进去 25 美元才可以使用,引来了很多人,尤其是游客的不满。

    一时间,纽约市怨声载道。现在,纽约的交通部正在抓紧处理这个问题,然而,他们需要为整个城市的近 14000 个停车收款机升级软件程序。

    波兰的一家公司 Novitus,在 2020 年来临的第一天,所有的收银机,都不能正常地打印票据了。如今,公司也正在紧急地修复这个问题。

    一款著名的拳击类游戏:WWE 2k20,在 2020 年的第一天,突然无法正常运行了。然而,如果用户把系统时间修改为 2020 年以前的任何一天,游戏都能正常运行。

    德国汉堡市的地铁,在新年来临的第一天,延误了一段时间。据报道是因为一次软件升级失败导致的。大概率的,这次升级失败,也是因为时间走到了 2020 年。

    splunk 是一家硅谷的创业公司,专门分析服务器产生的数据,从而快速完成业务分析、安全事件审计、DDoS 攻击监控等等服务。2019 年 11 月,splunk 发现自己的软件系统在 2020 年到来的时候,将无法正常运作。所以,splunk 强制他的所有客户——包括美国前 100 强企业的 92 家,来升级系统,以避免这一“灾难”。


    为什么有那么多软件系统在 2020 年到来的时候,会产生 bug?这个问题,和本世纪初的千年虫 bug 的原理,是一模一样的。

    所谓的千年虫 bug,是指当时间走到 2000 年的时候,很多软件系统会崩溃。

    为什么时间走到 2000 年的时候,软件系统会崩溃?因为在很多软件系统中,年份是使用两位数字来存储的。

    如果是 98,或者 99,我们可以很安全地认为,时间是 1998 年或者 1999 年,规则就是在这两位数字前面加上 19。但是,对于 00,加上 19,就是 1900 年,而不是 2000 年。于是,时间发生了错误,整个软件系统将不能正常运转。

    工程师们很早就意识到了千年虫 bug 的存在,于是,在新世纪来临之前,各个软件公司都在全力解决这一问题。甚至,在那个年代,有一个专门的职位,叫“千年虫工程师”,顾名思义,就是专门解决千年虫问题的。

    在当年,千年虫工程师是平均薪资最高的工程师。据报道,和千年虫相关的“修补”工作,大约造成了全世界 3000 亿到 5000 亿美元的损失。

    讽刺的是,在 2000 年以后,千年虫工程师这个职位都不复存在了。


    时间来到今天,2020 年之所以会发生这一系列的 bug,和千年虫的原理一样:系统使用两位数字存储年份。

    但这一回,对于这些软件系统,18 或者 19 可以被系统正确地认为是 2018 年或者 2019 年。不过,当时间走到了 20,系统懵逼了,会误以为是 1920 年。

    为什么?因为 1920 年,是很多系统的“标定年”,英文叫做 pivot year。也就是系统会自动在 00 到 19 这些年分之前加上 20,表示 21 世纪的年份;而会给 20 到 99 这些年份之前加上 19,表示 20 世纪的年份。

    为什么会将 1920 年作为“标定年”?这又牵扯到一段计算机科学的历史。

    熟悉“时间戳”的同学都知道,UNIX 系统定义起始时间为 1970 年 1 月 1 日 0 时 0 分 0 秒。所以,这个时间是 UNIX 世界的起始时间。

    随着 UNIX 在服务端的普及和流行,这个起始时间甚至超越了 UNIX 系统,成为了整个计算机世界的起始时间。就算没有接触过 UNIX 的同学,无论是在数据库中,还是在各个语言的时间戳转换的函数中,都应该接触过这个“知识点”:0 这个时间戳,表示 1970 年 1 月 1 日 0 时 0 分 0 秒。

    这也解释了为什么大家在处理和时间相关的程序的时候,有的时候,一不小心,显示的时间是 1970 年 1 月 1 日 0 时 0 分 0 秒。如果在国内的同学,可能会经常看到 1970 年 1 月 1 日 08:00。这是因为,UNIX 定义的起点时间,是以格林威治时间为准的。而由于中国时间以北京时间为准,而北京在东八区,所以,对应 UNIX 起点时间,就是 1970 年 1 月 1 日 08:00。

    这和 1920 年有什么关系?答案是,1970 年前后各取 50 年,就是 1920 和 2020 年。所以,很多计算机系统都以 1920 年作为“标定年”,来转化两位数字表示的年份。而这种转换,到了 2020 年,就失败了。


    2020 年 bug 的一个简单解决方案,就是使用四位数字,而非两位数字来表示年份。这么简单的一个方案,为什么当时不采用?

    答案是,如果回头看 20 年前,甚至 30 年前的计算机系统,存储空间还是极度紧张的。100 以内的两位数字,只需要一个字节就可以表示;而 4 位数字,则需要两个字节,整整多了一倍。

    这个存储空间的差距,现在看起来简直不值一提。但是,在二三十年前,事情可完全不一样。

    我是 1998 年拥有的第一台个人电脑的,那个时候的硬盘容量,我印象很清楚,只有 512 MB,还算高配了。而那时的主要移动存储介质,是一种叫做软盘的介质。每片软盘,只能存储 1.44 MB 的内容。

    1998 年尚且如此,更不用提 1990 年了。而个人电脑处理的数据和资料毕竟有限。如果是服务器,每天处理成千上万的数据,在时间存储上,使用两位数而非四位数,绝对是一个重要的优化。如果大家能找到那个年代的服务器开发教程,甚至会特意强调这个优化。

    然而,这个曾经的优化,如今成为了 bug 的源泉。

    另一个重要原因,在于很多人并不认为某个程序或者某段代码能运行 20 年,30 年之久。甚至,多数人不认为自己写的程序能运行 5 年时间。

    虽然,在大多数情况下,这个结论是正确的。软件发展的速度出奇的快,大多数代码很快就会淘汰掉。但是,仍然有少部分代码,坚强地一直运行着。

    而且,每一个软件工程的开发,并非都是从 0 开始的。以 MacOS 系统为例,我们看其中的 API 命名,包括部分框架的设计模式,就能明白这其中包含着多少遗留的历史代码了。

    所以,即使某一个软件产品退出了历史舞台,但是其中的代码片段,很有可能继续以一种不为大众所知的方式,存在于现代世界中。这些代码片段中的 bug,好像从“远古时期”乘坐时间机器来到今天,成为当下的安全隐患。

    有意思的是:这种事情能完全避免吗?答案是不能的。

    因为,这样的 bug,本质不是逻辑错误,而是假设错误。然而,这样的假设错误,站在当年的视角看,不仅不是错误,甚至可以叫做是“优化”。

    可是,短短 20 年,这就变成了一个错误。

    这就好比,如今,我们不可能选择使用五位数去存储年份一样。然而,到了 9999 年,这将成为一个大问题。

    这件事非常好地向我们阐述了软件工程的复杂性。软件工程本身不是绝对的数学公式推导。在软件工程的很多实现方案中,是没有绝对的“对”和“错”的,而是具有相应的时代特点的。

    然而,在一个时代中,绝对正确的事情,到了另一个时代,很有可能是存疑,甚至是绝对错误的。

    这样的事情,在人类的文明历史中,时常发生。比如封建君主制,比如希特勒,比如冷战思维。如今,这样的事情,也发生在了软件的世界中。

    这说明了什么?

    软件本身,已经毫无疑问地,成为了人类文明的一种体现形式。和书籍,音乐,电影,雕塑,等等等等,是一样。

    而软件工程师,则是这种人类文明体现的书写者。

    嗯,反正我就是这么“骗”自己的:)

    大家加油!


    展开全文
  • 哟,写BUG呢!

    2018-11-11 21:53:25
    哟,写BUG呢! 很有趣的一个表情包,描述了一个普通程序员的日常。 不管目前程序员主流的水平如何,至少我仍处在这个阶段。写出来的东西,总是有缺陷,总是考虑不周全。 在学习了软件测试这门课程之后,再去看代码...

    问题描述

    哟,写BUG呢!

    clipboard.png

    很有趣的一个表情包,描述了一个普通程序员的日常。

    不管目前程序员主流的水平如何,至少我仍处在这个阶段。写出来的东西,总是有缺陷,总是考虑不周全。

    在学习了软件测试这门课程之后,再去看代码,仿佛境界有所提升。

    找缺陷

    随机数

    /**
     * 获取随机字符串
     * @param length 待获取的长度
     * @return 指定长度的随机字符串
     */
    static String randomString(int length) {
        // 生成随机字符串
        StringBuilder sb = new StringBuilder( length );
        for( int i = 0; i < length; i++ )
            sb.append( source.charAt( random.nextInt(source.length()) ) );
        return sb.toString();
    }
    @Test
    public void randomStringTest() {
        logger.debug("初始化长度");
        final int length = 20;
    
        logger.debug("获取随机字符串");
        String string = CommonService.randomString(length);
    
        logger.debug("断言");
        Assertions.assertThat(string.length()).isEqualTo(length);
    }

    一个普通的随机字符串程序,StackOverflow上找的,以及为这个方法配的单元测试。

    看起来没什么毛病,注释齐全,缩进正确,空格也都有。

    输入

    至少,我们不会作到在自己的方法里写出个BUG来。BUG,往往都是我们未料及的输入产生的。

    我们不能期望用户或别人调用我们方法时总是给我们传入合法的参数。

    就拿刚才的代码来说,如果给个-1的长度会怎样呢?不妨一起来作一下。

    clipboard.png

    报错了,负的数组长度异常。

    clipboard.png

    完善

    就像异常处理的规则一样,如果本级可以处理,那就在本级处理,如果不能处理,则给上级抛异常,让上级处理。

    这里本级可以处理,你调用我的randomString方法,肯定是想获取随机字符串,既然非法,我就返回一个空字符串吧!

    /**
     * 获取随机字符串
     * @param length 待获取的长度
     * @return 指定长度的随机字符串
     */
    static String randomString(int length) {
        // 如果长度非正数,则返回空串
        if (length <= 0) {
            logger.error("传入了非法的长度参数");
            return "";
        }
        // 生成随机字符串
        StringBuilder sb = new StringBuilder( length );
        for( int i = 0; i < length; i++ )
            sb.append( source.charAt( random.nextInt(source.length()) ) );
        return sb.toString();
    }
    @Test
    public void randomStringTest() {
        logger.debug("初始化长度");
        final int length1 = 20;
        final int length2 = -1;
        final int length3 = 0;
    
        logger.debug("获取随机字符串");
        String string1 = CommonService.randomString(length1);
        String string2 = CommonService.randomString(length2);
        String string3 = CommonService.randomString(length3);
    
        logger.debug("断言");
        Assertions.assertThat(string1.length()).isEqualTo(length1);
        Assertions.assertThat(string2.length()).isZero();
        Assertions.assertThat(string3.length()).isZero();
    }

    登录

    登录方法:

    @Override
    public boolean login(User user) {
        logger.debug("获取相关用户");
        User persistUser = userRepository.findByUsername(user.getUsername());
    
        logger.debug("用户名不存在");
        if (null == persistUser) {
            return false;
        }
    
        logger.debug("用户名存在,密码不正确");
        if (!persistUser.getPassword().equals(user.getPassword())) {
            return false;
        }
    
        return true;
    }

    校验用户名和密码的登录方法,其实也是有可以完善的地方的。

    clipboard.png

    user上调用getUsername,如果传一个NULL进来,不就空指针异常了吗?

    假设我们先不考虑前台的验证,我们就是要我们的api没毛病,先用notNull对数据进行校验。

    clipboard.png

    notNull方法会抛出IllegalArgumentException(非法参数异常),写个RestControllerAdviceExceptionHandler全局处理该异常,然后返回参数非法,加上该异常的提示信息。这就显得完美了。

    clipboard.png

    同样的可能造成空指针异常,在NULL上调用equals方法。

    clipboard.png

    为密码添加校验,保证持久化的User,其password都不为空!

    总结

    1. 写方法时,一定要在该方法的最前面对所有的输入进行校验。
    2. 本级能推测出传入该参数的意图,可在本级中处理,不能推测,则抛出异常交给上级处理。
    3. 编码时勤思考,减少BUG产生的可能。
    展开全文
  • 我们做开发的应该都会有深刻的体会,有时候会遇到一些莫名奇妙的BUG不知所措,解决BUG到近乎崩溃,更有甚者有人居然会在梦中解决掉BUG。下面我们看几个有意思的解决Bug的故事:知乎网友李幼萌:08年的时候,我所在的...


    我们做开发的应该都会有深刻的体会,有时候会遇到一些莫名奇妙的BUG不知所措,解决BUG到近乎崩溃,更有甚者有人居然会在梦中解决掉BUG。下面我们看几个有意思的解决Bug的故事:



    知乎网友李幼萌:

    08年的时候,我所在的公司调试三星的一款新的arm9 CPU,型号是S3C2416,是S3C2450的简配版。开发板刚入手的时候还是热乎的,因为三星的这个芯片刚刚出来,国内的代理商一共就几块开发板。各公司评估开发板都是分时使用的,只能预约几天。开发板入手的时候,三星那面连BSP都没有准备好,没有test code,没有u-boot,没有linux-kernel,甚至连Spec都是错误百出。还好我公司虽然小,研发能力在本地区还算不差,没有的东西可以自己移植。  

    公司急着要出新品,在没有完全验证处理器的情况下,已经layout好了PCB,并且去打样了(当时竞争确实比较激烈,400M主频处理器而且这么低的价格绝对非常有诱惑力,所以公司决定冒这个险了)。在没黑没白的工作两周后,硬件和软件做的都差不多稳定了。这时候经理说,功能上问题不大了,我们来调一调休眠时的功耗吧(我们的产品一直以待机时极低功耗作为产品的卖点之一)。然而这却是噩梦的开始……


    公司的指标是待机时休眠电流500~800uA(电源电压4V)之间。以前所有的产品都在这个范围之内,三星方面的技术支持也明确表示,他们的解决方案达到这个指标。

    在我们调试过程中发现,整个系统休眠时的功耗在1800uA左右,一直降不下来。我们重新核对了所有的IO和外围电路的所有连接,以及IO口的电平配制,都没有问题。这时,我们决定测试每一个单元的功耗,用电流表分别串联进每一个外围电路,每个单元都很正常,就是系统总体偏大1000uA。


    我们连flash和ram的待机电流都测过了,仍然正常。好了,通过排除法已经确定了就是CPU的功耗过大。但是在开发板上调试休眠的时候,CPU功耗却是正常的。


    我们怀疑是开发板上CPU批号和拿到的CPU样品的批号之间有区别导致的,因为三星那面也在同步修正CPU的BUG,所以我们“大胆地”把开发板上的CPU用风枪吹下来,换到我们的PCB上,把我们的CPU贴到了开发板上进行交叉验证。结果是开发板仍然功耗正常,我们自己的板子上功耗偏大,还是大了1000uA。

    CPU周边的核心电路设计出现了问题!这是我们一致的判断!但是问题出在哪里,我们反复核对开发板的原理图和我们自己板子的原理图,简直就是一模一样!因为整个核心电路这部分就是从开发板上抄过来的,实在没有什么可比对的。我们转而又去怀疑PCB的问题了。 


    我是做系统移植和软件的,纯电气的问题我就无能为力了。闲着没事,我就反复检查我在linux中对系统休眠的IO引脚配置。然后挂着电流表做反复测试。电流表也对的起我,每次都是那个数。在一次系统待机的时候,我实在忍无可忍,一把抓起了板子。突然之间,电流表的读数飞快下降,降到了300uA!我松开手电流表的读数就又爬回来了。我把我这个惊奇的发现告诉了同事——一个硬件工程师。同事说可能是哪儿摸短路了,让我试试还能不能唤醒系统。我给了一个外部中断,系统神奇的正常唤醒了!

    “难道这就是问题?”,我想重现一下。但是再次在待机的时候抓起电路板的时候,读数并没有显著发生变化。“可能是手法不好”,我这么想着,用手在板子上继续抚摸着。果然!当我的手指按到PCB中的某一个位置时,电流又降了下来!反复试了几次,都是这样,就是在我手指按压的这一片,只要是用手指按着,电流就正常!


    这回同事开始重视了,打开PCB图,拿着电路图和万用表,查查我摸的到底是那块电路。硬件工程师觉得不可思议,因为我摸的部分并没有连接任何的电路——焊盘是空的。他于是用万用表的表笔去检查是不是PCB制版的问题,测一下这些空焊盘到底哪一个有电压。但是万用表中没有读数,这块都没有电。但是当万用表的表笔落在一处空焊盘的时候,电流表的读数又降下来了!

    这可是重大发现,我们对照了一下电路图。这处空焊盘是CPU中USB-Host模块的D+信号。由于我们的产品不需要USB的主机功能,所以这一块儿没有做任何处理。多亏了画原理图和PCB的同事,多留了一手,把USB Host的引脚都在PCB上做了个引出。谁也没想到是这个引脚出现了问题,辛亏这个信号引出来了,要是没有引出来,一辈子也查不出问题。我们给D+信号加了一个下拉电阻后,系统的功耗瞬间正常了。


    事后分析,三星自己开发板上有USB-Host的功能,所以USB-Host的外围电路也是完备的,所以功耗不会有问题。但是我们自己的产品上不使用USB-Host功能,没有相关外围电路,所以出了问题。这是因为在CPU休眠的时候,D+信号内部被悬空了!一句话,是三星CPU自己的BUG。我们修改了我们的PCB,增加了一个下拉电阻,同时将问题反馈给了三星。        

     一个月后,当我们的产品量产时,三星也及时的解决了这个问题。那个下拉电阻也不需要再贴上去了。



    知乎网友辛晓晨

    每次想起这个bug,虽然很多很多年了,我仍然满脸都是泪水啊!当年做x86 BIOS,客户是长城电脑。有一回我们的新版本发布给他们后进行系统重启测试,就是安装好操作系统后反复不停的重启机器,看看重启几百上千次后情况如何。原因是客户买了电脑每天用,至少得保障人家用个俩三年没事吧。结果我们的新版本重启到一百多次的时候挂了,现象就是开机黑屏,没有任何输出,就和当年的CIH病毒发作一模一样,经验判断系统压根还没有boot OS就跑飞了,我们自己测试也是这样,而且一旦出现问题就只能重新刷BIOS这个bug非常难调,因为当时我们的版本将近300万行源代码,大概2%的汇编与98%的C,几千个源文件,光是用来参与build过程的工具就有十几个。而且这些工具都是自己写的,构建项目的时候先编译这些工具,再去用这些工具加编译器来生成最后的ROM文件并且更加恼人的是,我们当时没有source level的debug tool,甚至连汇编级别的单步调试工具也没有,压根没法对代码做step into/over,更没法加个断点。。。

    当时可以用来调试BIOS的工具有两个,一个是Intel自己内部用的ITP,这个是人家公司自己的,一般不给外面人用,当时我们公司与I公司的关系尚处蜜月期,给了我们两个,但是当时被Chipset team霸占着做porting用;另一个工具就是American Arium(这家鸟公司不知道现在还活着不),这个东西说白了就是商品化的ITP,因为目标客户少,所以价格巨贵巨贵!一套系统价格几万美金,而且每一代CPU都要换一个插座上的适配器,这个适配器又是一万美金好像,还不太稳定,用着用着就挂了。。。我们公司当时有俩,但是因为没有买新一代处理器的适配器,于是只能吃灰了于是我们唯一的调试手段就是serial debug,就是系统启动的时候会通过port 80把一些重要信息打出来,然后我们根据这些信息判断执行到哪里了,系统的情况如何。这类似原始的printf打印。如果要看一个变量的值或者验证一下我们的判断,就得重新写代码,在需要的地方加入调试语句,然后花上半个小时rebuild bios,再重新烧录,再上电运行看看打出来的到底是啥。如果有疑问,或者发现这里没有问题,又或者有了新的思路,重复上述过程。记忆中整整一个礼拜,我们都在不停的看debug info,反复烧录bios 哭啊!简直不是人过的日子!最后发现系统可以成功的跑过PEI,到了DXE阶段的某个环节,突然就像心脏骤停一样,跑飞了!去看疑似跑飞的DXE Driver,是个很普通的平台硬件初始化程序,没什么疑点,压根没有头绪。那段时间,几乎每时每刻都在想着这个bug,实在是茶饭不思,根本没心情做任何事!就这样差不多过了俩礼拜,经过了无数次的重启与烧录bios,以及猜测,验证,被否定,再猜测,再验证,再否定。。。。。的过程后,我们终于发现了问题的原因:大家可能还记得电脑主板上有个CMOS,传统上用来存bios设置,但是现代的系统已经逐渐弃用这个东西。我们现在的bios芯片都是可擦写的,也就是用程序可编程。bios大小是8MB,里面会规划好,哪里是code,哪里放设置等等,然后代码里有专门写flash的函数,让大家可以保存一些东西,比如你想用硬盘还是光驱启动等等。同时系统每次启动也都会自己写一点没什么鸟用的信息进来。问题就出在这个写flash的函数上,我们后来发现,这哥们算错了存储区域的地址,导致写很多次后终于越界,误写到了人家代码区,把人家好端端的代码给写的乱七八糟,就如同当年CIH破坏系统的方法一模一样,照这样哪个机器能点亮才怪呢!又因为每次系统写的信息不一样,比如启动时间就不太一样,所以越界需要的次数不是恒定,更加重了我们排错的难度,泪啊!


    知乎网友林铠鹏

    差不多10年前,我们做了一个ARM核的芯片,据说还是国内第一批用ARM7做的,还挺高端,带有很多安全功能,当然安全就意味着难以调试,整个系统全部打散,不能分块。俺负责前端设计,系统,硬件软件驱动等杂七杂八一堆工作。    然后芯片流出来了,封装回来,几天几夜的调试,功能都正常了,那个高兴呀,第一个芯片就成功,奖金有了!

    不过做稳定性测试时候有一个问题一直困扰着,这系统总是莫名其妙的有时候启动不起来,概率有个百分之几左右。上电就是不LOAD。而一旦起来之后,就很容易了。

    反正功能设计,硬件,驱动都是俺的,那就调呗,软件,硬件,电路,仿真,研究了好几天,抓狂,无解。又整个系统不能分块,我都开始怀疑是不是ARM核的问题。

    又做了一个不断重启的测试系统,不断啪啪响上电断电,针对上电的情况作了统计。得出结论就是,上午不启动的概率高,下午不启动的概率低,晚上不启动的概率高,深夜不启动的概率低。。。。。和饥饿程度快挂钩了。。。

    那时候那个抓狂啊,怀疑是什么干扰的,连屏蔽房,隔离电源啥都整出来了。就是没头绪,而公司给客户演示的时间快到了,要是现场挂掉就丢脸了,心里那个急啊。那段时间,每个深夜,公司里就是我座位上啪啪啪的声音------继电器的啪啪声。      接下来一个周日测试,公司空调坏了,汗流浃背,脾气极坏,几乎就要摔板子了。不过发现这天运气非常好,成功概率很高。没头绪,直接抽上烟,看着板子发呆,不知那根神经搭错,直接把烟头对着芯片戳上去!咱第一个亲生芯片!!如果不行了就掐死它!!!结果发现怪了,戳了烟头,启动哗哗的,每次都OK。遂怀疑是尼古丁过敏或者是温度原因。拿着烙铁烫着它,每次必成。于是送进高低温箱,做温度曲线测试,发现环境温度40度以上,成功概率极高,刚好碰见今天加班没空调,平均温度高,所以表现良好。而启动起来因为系统一发热,所以后面启动就容易了,温度一凉下来表现惨不忍睹,敢情这芯片是非洲来的。

    有了方向就好说,先解决DEMO,给领导好看。遂做了一个电热丝发热电路,贴在芯片上,用单稳开关控制,一上电就加热,然后不断自动啪啪啪对芯片重启,一旦芯片重启成功了就断开发热电路和重启电路。进入正常运行情况。系统搭起来一测,效果杠杠的!!!基本都能保证几秒钟内就能启动,公司上下一片赞誉。 于是,领导拿着这套带着电炉丝的系统去做报告,销售拿着这个电炉丝Demo去给客户演示,取得极好成功,老板都在准备后续的销售计划了。俺心里急啊,总不能出货产品也带着电炉丝吧。。。

    静下心好好分析,和温度有关,又是随机故障,应该很可能是哪个地方悬空,存在不定态的问题,外面的电路是不可能了,前端模拟加入随机量也不能重现,那很大可能是后端的人搞的鬼,遂拉来后端人员(暂且称为C公司),检查扫描链和测试电路,果然发现有一个寄存器没有初始化复位。于是后面的情况就简单了,往扫描链中灌入一串数据,把未知量洗出来。成功!!!

    所以我们第一代的产品,主芯片旁有一个奇怪的芯片。据线人报告,有竞争对手和盗版者都认为这是安全反盗版电路,因为拆掉这一块,系统工作就时不时的异常,抓不到规律,可能包含短时间正版验证,长时间正版验证,随机正版验证等高精尖反盗版措施。反正无法破解。。。。俺笑而不语。

    至于说为什么寄存器没有初始化复位没检查出来,我也不知道,这是人家C公司做的后端,他们的软件自己加进去的电路。而据说这C公司虽然牛,但那时候后端服务还是新的,软件也是新的,刚进国内,给我们一个特惠价做白老鼠。。。


    知乎网友Xiang Liu

    之前用xilinx一块比较高端的开发板验证一个高速信号的功能,发现有一路输出幅度是其他的1/10,感觉很诧异,于是和师弟翻了一天手册文档,难不成这货还有配置幅度的功能。最后无解,用万用表在BGA焊盘和走线上一点一点地量,过了一个小时,发现....


    (Bug微距图)

    尼玛一万多的板子 表贴SMA接头漏焊!中间大概有0.5mm的距离,高速信号空间耦合过去10%。

    于是默默用热风枪吹上,一切正常了。

    这个bug的恐怖之处在于,高速信号可以从断点发射出去,然后让人误以为卧槽这有输出啊,不会想到根本就是个直流的断路,直到你用了万用表。


    知乎网友包治百病的板蓝根

    读大学的时候,第一次接触嵌入式编程,当时目标是从一个传感器中读取温度变化,当温度达到某个阈值后发送短信到指定机器。由于芯片厂商给的官方编辑器很难用,当时我们是在VC上编写好,再用官方工具烧录到芯片里。

    VC里环境和芯片专用的环境各种不兼容的问题前前后后折腾了不少时间,当终于把程序烧录进去并成功运行后,却总不能收到短信。嵌入式平台无法做单步调试这种事情,于是我们只能无奈用最基本的方式排除问题。先是一众人review代码,但显然并不能检查出什么问题,在模拟环境中确实是可以跑通的。接下来软硬兼施,隔离各个方法,烧录进去运行并查看芯片的引脚电压变化作判断。大作业经费有限。由于芯片很贵,我们整个专业也没多少套这个平台。芯片烧录次数也是有限制的,我们并不能无限次的烧进去测试。整个过程大家都很小心谨慎,痛苦得想死。但最后都检查不出个所以然。直到作业结束,我们仍然没能把发短信这步完成。


    不过老师检查过我们代码后仍然给出了个很高的分数,算是对我们这波努力的肯定。然后高潮来了,助教,就是老师带的研究生,清理我们上交的机器,把机器里的电话卡回收,于是我们知道了一直发不出去短信的原因。欠!费!


    来源:ADI 工程师

    BUG: 为什么我的处理器这么耗电?

    这是我遇到过得解决起来比较费劲一个BUG了,写的略微详细了一些,希望能够帮助到大家。

    记得有一次,客户拿着处理器板走进我的办公室,说它的功耗太大,耗尽了电池电量。由于我们曾骄傲地宣称该处理器属于超低功耗器件,因此举证责任在我们这边。我准备按照惯例,一个一个地切断电路板上不同器件的电源,直至找到真正肇事者,这时我想起不久之前的一个类似案例,那个案例的“元凶”是一个独自挂在供电轨和地之间的LED,没有限流电阻与之为伍。LED最终失效是因为过流,还是纯粹因为它觉得无聊了,我不能完全肯定,不过这是题外话,我们暂且不谈。从经验出发,我做的第一件事是检查电路板上有无闪闪发光的LED。但遗憾的是,这次没有类似的、昭示问题的希望曙光。另外,我发现处理器是板上的唯一器件,没有其他器件可以让我归咎责任。客户接下来抛出的一条信息让我的心情更加低落:通过实验室测试,他发现功耗和电池寿命处于预期水平,但把系统部署到现场之后,电池电量快速耗尽。此类问题是最难解决的问题,因为这些问题非常难以再现“第一案发现场”。这就给数字世界的问题增加了模拟性的无法预测性和挑战,而数字世界通常只是可预测的、简单的1和0的世界。

    在最简单意义上,处理器功耗主要有两方面:内核和I/O。当涉及到抑制内核功耗时,我会检查诸如以下的事情:PLL配置/时钟速度、内核供电轨、内核的运算量。有多种办法可以使内核功耗降低,例如:降低内核时钟速度,或执行某些指令迫使内核停止运行或进入睡眠/休眠状态。如果怀疑I/O吞噬了所有功耗,我会关注I/O电源、I/O开关频率及其驱动的负载。

    我能探究的只有这两个方面。结果是,问题同内核方面没有任何关系,因此必然与I/O有关。这时,客户表示他使用该处理器纯粹是为了计算,I/O活动极少。事实上,器件上的大部分可用I/O接口都没有得到使用。

    “等等!有些I/O您没有使用。您的意思是这些I/O引脚未使用。您是如何连接它们的?”

    “理所当然,我没有把它们连接到任何地方!”

    “原来如此!”

    这是一个令人狂喜的时刻,我终于找到了问题所在。虽然没有沿路尖叫,但我着实花了一会工夫才按捺住兴奋之情,然后坐下来向他解释。

    典型CMOS数字输入类似下图:

    图1.典型CMOS输入电路(左)和CMOS电平逻辑(右)

    当以推荐的高(1)或低(0)电平驱动该输入时,PMOS和NMOS FET一次导通一个,绝不会同时导通。输入驱动电压有一个不确定区,称为“阈值区域”,其中PMOS和NMOS可能同时部分导通,从而在供电轨和地之间产生一个泄漏路径。当输入浮空并遇到杂散噪声时,可能会发生这种情况。这既解释了客户电路板上功耗很高的事实,又解释了高功耗为什么是随机发生的。

    图2.PMOS和NMOS均部分导通,在电源和地之间产生一个泄漏路径

    某些情况下,这可能引起闩锁之类的状况,即器件持续汲取过大电流,最终烧毁。可以说,这个问题较容易发现和解决,因为眼前的器件正在冒烟,证据确凿。我的客户报告的问题则更难对付,因为当您在实验室的凉爽环境下进行测试时,它没什么问题,但送到现场时,就会引起很大麻烦。

    现在我们知道了问题的根源,显而易见的解决办法是将所有未使用输入驱动到有效逻辑电平(高或低)。然而,有一些细微事项需要注意。我们再看几个CMOS输入处理不当引起麻烦的情形。我们需要扩大范围,不仅考虑彻底断开/浮空的输入,而且要考虑似乎连接到适当逻辑电平的输入。

    如果只是通过电阻将引脚连接到供电轨或地,应注意所用上拉或下拉电阻的大小。它与引脚的拉/灌电流一起,可能使引脚的实际电压偏移到非期望电平。换言之,您需要确保上拉或下拉电阻足够强。

    如果选择以有源方式驱动引脚,务必确保驱动强度对所用的CMOS负载足够好。若非如此,电路周围的噪声可能强到足以超过驱动信号,迫使引脚进入非预期的状态。

    我们来研究几种情形:

    1.在实验室正常工作的处理器,在现场可能莫名重启,因为噪声耦合到没有足够强上拉电阻的RESET(复位)线中。

    图3.噪声耦合到带弱上拉电阻的RESET)引脚中,可能引起处理器重启

    2.想象CMOS输入属于一个栅极驱动器的情况,该栅极驱动器控制一个高功率MOSFET/IGBT,后者在应当断开的时候意外导通!简直糟糕透了。

    图4.噪声过驱一个弱驱动的CMOS输入栅极驱动器,引起高压总线短路

    另一种相关但不那么明显的问题情形是当驱动信号的上升/下降非常慢时。这种情况下,输入可能会在中间电平停留一定的时间,进而引起各种问题。

    图5.CMOS输入的上升/下降很慢,导致过渡期间暂时短路

    我们已经在一般意义上讨论了CMOS输入可能发生的一些问题,值得注意的是,就设计而言,有些器件比其他器件更擅长处理这些问题。例如,采用施密特触发器输入的器件能够更好地处理具有高噪声或慢边沿的信号。

    我们的一些最新处理器也注意到这种问题,并在设计中采取了特殊预防措施,或发布了明确的指南,以确保运行顺利。例如,ADSP-SC58x/ADSP-2158x数据手册清楚说明了有些管脚具有内部端接电阻或其他逻辑电路以确保这些管脚不会浮空。

    最后,正如大家常说的,正确完成所有收尾工作很重要,尤其是CMOS数字输入。


    好了就分享这么多,接下来就看大家留言补充了,评论往往更精彩!

    文章版权归原作者所有,转载仅供学习使用,不用于任何商业用途,如有侵权请留言联系删除,感谢合作。

    展开全文
  • Python 可以做任何事情,这不就有大佬用来民俗科学项目了吗?多个库多条路。
  • (为了方便描述把服务器以及客户端都简称为程序) 简单地说,报告bug的目的是为了让策划以及程序员看到程序的错误。...在bug报告里,要设法搞清什么是事实(例如:“我点击了XX”和“XX出现了”)什么是推测
  • BugFree软件.zip

    2020-01-23 16:00:15
    BugFree是借鉴微软的研发流程和Bug管理理念,使用PHP+MySQL独立出的一... 命名BugFree 有两层意思:一是希望软件中的缺陷(Bug)越来越少直到没有;二是表示它是免费且开放源代码的,大家可以自由使用传播(Free)。
  • BUG描述规则

    千次阅读 2019-09-27 11:25:46
    1. Bug的基本概念 2. Bug的生命周期 3. BUG的描述规范 4. BUG的跟踪规范 5. BUG的审核
  • Bug系列

    千次阅读 2014-03-10 17:25:34
    Bug之一——bug的前世今生 Bug这个名词已经很老了,从网络上查到的资料: >>>>>> 1946年,Grace Hopper在发生故障的MarkⅡ计算机的继电器触点里,找到了一只被夹扁的小飞蛾,正是这只小虫子“卡”住了机器的运行...
  • 程序的bug排查流程总结

    千次阅读 2015-07-17 14:37:47
    只要是人的程序,不可能没有bug,那么解决bug,将伴随程序员的一生:Ø 只会代码,但不会排查bug的程序员,只能算是业余程序员Ø 能解决一般bug的,只能算是初级程序员Ø 代码的质量较好,还能查找较难bug的,...
  • CSDN博文周刊第3期 |程序员如何出没有Bug的代码?

    千次阅读 多人点赞 2018-12-29 16:39:36
    CSDN每周都会产生大量的博客文章,...2、发现bug是一种什么样的心情 3、编程语言印象集 小白:听说你会七门语言? 王二:是啊,口语听力都没问题。 小白:敢问是哪些国家的语言? 王二:秦齐楚魏韩赵燕。 4、...
  • 用HBuilder前端页面常见Bug解决思路

    千次阅读 2017-10-05 00:45:02
    三步走加两明确 * 前端问题的一般体现:预期结果... 一明确:明确自己的每一步是什么意思,然后再跟着代码一步步的进行分析,这样大部分的错误都能够被解决。  二明确:明确程序流是怎样的从上往下执行的。
  •  之前深入bug产生原因分析(一),这里主要从实际的项目bug中,总结出了实际bug的根源的几个方面。这些问题的解决不但没有对最终交付的产品有所裨益,反而耽误了不少测试时间。现在就简要做下梳理,并汇总自己在...
  • 正在拼命的代码,突然线上出现了一个bug,需要立刻解决,但是目前的工作空间代码改动挺大的,怎么解决?方法如下: 方法1:在当前主分支修改bug 暂存当前的改动的代码,目的是让工作空间和远程代码一致: git ...
  • BugFree与禅道

    千次阅读 2014-09-23 11:46:35
    BugFree是借鉴微软的研发流程和Bug管理理念,使用PHP+MySQL独立出的一个Bug... 命名BugFree 有两层意思:一是希望软件中的缺陷越来越少直到没有,Free嘛;二是表示它是免费且开放源代码的,大家可以自由使用传播。
  • Bug是属于前端还是后台

    千次阅读 2018-11-04 21:32:26
    (常见的: 1xx 2xx 3xx 4xx 5xx 状态码分别是什么意思?200服务器相应成功、400请求参数浏览器处理不了、500服务器异常、401 Unauthorized 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用) ...
  • Bug等级权重分配

    千次阅读 2016-11-17 19:49:03
    随着测试行业的发展,测试队伍的不断壮大,测试规范也变得越来越完善周一上午开周例会,大家讨论一个了确定一个很有意思的问题,那就是Bug的权重分配问题。几年前,公司对于测试人员的工作评估主要是依据该测试人员...
  • 软件测试之BUG描述

    千次阅读 2019-06-18 15:32:20
    最主要的就是要描述好bug,一个好的bug描述,能让开发人员,更快的定位到问题产生的原因,能够更快的解决bug,而,如果描述的很模糊,有可能开发人员在看这个bug的时候,要花费很长的时间去猜测这个bug意思,甚至...
  • 1024程序员节前夕,Bug与Debug的随笔

    千次阅读 2019-10-20 12:21:06
    bug的本意是指昆虫、小虫、损坏、缺陷等意思,在互联网时代还有一种引申意义,用来形容某人/物超乎想象的厉害,那简直就是开挂的人生,系统的bug! 一般地,在码农的世界了,bug是在电脑系统或程序代码中隐藏着的...
  • Bug系列

    千次阅读 2010-03-17 16:48:00
    Bug系列 2009-11-19 作者:吴朝东 来源:吴朝东的BLOG Bug之一——bug的前世今生 Bug这个名词已经很老了,从网络上查到的资料:>>>>>> 1946年,Grace Hopper在发生故障的MarkⅡ计算机的继电器触点里,找到了一只被...
  • 十年生死两茫茫,程序,到天亮。 千行代码,Bug何处藏。 纵使上线又怎样,朝令改,夕断肠。 领导每天新想法,天天改,日日忙。 相顾无言,惟有泪千行。 每晚灯火阑珊处,程序员,又加班,工作狂。
  • 命名BugFree 有两层意思:一是希望软件中的缺陷越来越少直到没有,Free嘛;二是表 示它是免费且开放源代码的,大家可以自由使用传播。  如何有效地管理软件产品中的 Bug,是每一家软件企业必须面临的问题。遗憾的...
  • bug和debug的定义

    千次阅读 2018-03-15 10:11:01
    了九年的博客,我猜测至少有一半的内容是围绕代码质量或调试进行的。... 我想我是还是有对什么是bug以及debug代码意味着什么的通常的理解的。 意识到这可能并非如此,我想出了一个定义来解释b...
  • 项目管理、Bug管理软件工具:禅道,BugFree,Redmine  ... 命名BugFree 有两层意思:一是希望软件中的缺陷越来越少直到没有,Free嘛;二是表 示它是免费且开放源代码的,大家可以自由使用传播。
  • 修改BUG心得

    万次阅读 2013-01-14 22:06:52
    3、修改BUG代码的人都很厉害,不管是界面还是底层。不要以人做的模块的难易来断定人。     二、 今天让项目经理找到些bug,但都是无关紧要的,最主要是因为在作页面的时候,业务逻辑不是很清晰,需求...
  • 浅谈bug描述

    千次阅读 2018-04-08 16:55:33
    我相信大部分人都会碰到以下这种情况: 我们提交上去的BUG在某些特定的环境下存在,这时候如果没有清楚具体产生BUG的前提条件的话,BUG难以重现,这个时候开发就会说: 为什么我测试的时候没有出现这个问题呀? ...
  • bugfree介绍

    千次阅读 2006-04-05 15:03:00
    官方网站:http://bugfree.1zsoft.com/index.html1. BugFree 简介1.1 BugFree的来源 BugFree是借鉴微软的研发流程和Bug管理理念,使用PHP+MySQL独立出的一个Bug管理 系统。简单实用、免费并且开放源代码(遵循GNU ...
  • 编写Bug,Report Bug注意事项

    千次阅读 2009-08-07 13:50:00
    1.Bug的Description的描述Report Bug时,描述有效的Description的关键点: Condense-精简,清晰而简短; Accurate-准确,确定是Bug;Neutralize-用中性的语言描述事实,不带偏见,不用幽默或者情绪化的语言; ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 100,898
精华内容 40,359
关键字:

写bug是什么意思