Woozle Wuzzle
Time dependent bugs

I just about pulled my hair out over the weekend on a bug that was time dependent. The code roughly looked like:

final int index = (int)(System.currentTimeMillis() / intervalPerFrame) %
                   numberOfFrames;
final Frame frame = frames[index];

This is perfectly legimate code and ran just fine a few months ago but was now throwing ArrayIndexOutOfBoundsException since the index was getting set to -2.

So how could a series of positive values return a negative number? Well, it just so happens that on Saturday, January 10th at 7:37:04AM 2004 the time in milliseconds goes from 1073741823999L to 1073741824000L which just so happens to correspond to 2147483647 and -2147483648 respectively when cast to an integer.

Lesson learned: be much more careful casting long to int when dealing with times. Also, when your test manager says that he's going to perform "date testing" don't balk since Y2K's already over. There are a lot more issues in dealing with time than just two digit dates.

CMMI: Live it. Love it.

If you're unsure of what the CMMI is, here is a nice introduction.

Most managers I encounter are caught up in the tactical day-to-day activities of management: finish the project plan; prod so-and-so to finish the thing-a-ma-bob; update the timelines; etc. When asked what they are attempting to achieve, most respond tactically: get the product out on time; reduce the quality risks; etc.

Where are the strategic components to all of this? If the managers are only focused on the tactical and the developers are certainly focused on the tactical, who's focused on the strategic? The upper management? Probably not. They're typically heads down in the tactial morass too; reduce the bottom line; increase profits for the board; get better products out; and so on.

(Quick disclaimer: of course there are companies out there that have a strong strategic component to them. But what fun would it be to talk about them? *grin*)

My bother-in-law recently finished his MBA at a top-notch university. Given my interests in management, we have had a number of lively discussions about both the strategic and tactical sides of management. I would relate a number of our discussions back to the CMMI as a blanket way of understanding how the topics would relate to one another. Much to my surpise, he had never heard of the CMMI.

To me, the CMMI is a roadmap or set of guide posts against which you can gauge progress. It presents the over-arching strategic goals that the day-to-day tactical tasks should be geared towards. Without the vision that it provides, it's nearly impossible to judge the effect and quality of the processes that are employed.

If our management producing machines (i.e. universities) are not presenting a strategic road map, how can we expect our companies to extend beyond the tactical?

A thank you goes out to Christoph Cemper for the link to the "What is the CMMI?" article.

Submit bug reports!

I would periodically run into a developer associate of mine and ask him how things are going. Invariably he would complain about a bug in an open source UML modelling tool whereby he could not cut and paste large diagrams. This went on for over a year. On one such encounter I asked him in jest "Did you file a bug report for it?". I had assumed that someone that would complain and have to work around a problem for over a year would have certainly filed a bug. To my horror his response was "No" -- and not just a normal "No" but one that dripped with "Why should I be the one that has to do it? Don't they know what's wrong with their own product?!?" I finally managed to convinced him that he should file the bug. The next time I saw him (about 2 weeks later) he was elated! They had fixed the bug and he was able to finally work at a reasonable pace.

The moral to this story is that it is the responsibility of every user of a project to file concise and reporducable bug reports. Developers of a project do not always encounter the cases that a user may encounter -- you may be the only one that has a particular use case. Don't fall into the trap of believing that "someone else will do it" or "the developers must have this problem and are just ignoring it".

File a bug today!

Software QA

Lately I have been preparing the engineering infrastructure for a technology startup. I have been liberally sprinking QA across this infrastructure (remember: QA is a process).

For anyone that is in need of an excellent reference on QA, I recommend: Software Quality Assurance: From theory to implementation by Daniel Galin. It is well worth the heafty price tag.

QA vs. Testing

I constantly hear developers calling testing QA. "Send the build to QA". Based on ANSI/IEEE standards:

  • Testing: The process of executing a system with the intent of finding defects including test planning prior to the execution of the test cases.
  • Quality Control: A set of activities designed to evaluate a developed working product.
  • Quality Assurance: A set of activities designed to ensure that the development and/or maintenance process is adequate to ensure a system will meet its objectives.

The key difference to remember is that QA is interested in the process whereas testing and quality control are interested in the product. Having a testing component in your development process demonstrates a higher degree of quality (as in QA).


Testing links


Testing / QA FAQs


Test Interview Questions

General interview tips

For those of you who also want the answers to these questions I offer you the following advice: if you spend the time to look up the answers yourself then it is much more likely that you will have a greater understanding of the answer and you will be more confident when talking with the interviewer or when taking the test.


I cannot stress enough to everyone to spend some time looking for answers through Google before posting your questions here. I enjoy answering the occasional difficult or obtuse question, but when I'm swamped with a hundred questions whose answers are easily found via Google then it's hard to become motivated.

For example, someone asked: "please explain how to test a web application with winrunner or with any other testing tool". If I go to Google and type in "testing web application", I find Downloadable Reference Library Testing Web Applications which has more information than I know what do to with.


This page has links to a Winrunner 7.0 tutorial, users guide, and TSL (Test Script Language) reference. It should be very helpful for those of you that are interested in learning this tool. A WinRunner FAQ is located here.

Which is better?

Which is a better choice?

  1. Use a technology that decreases the ability to introduce bugs (e.g. restrict the domain) but takes more time to use and maintain.
  2. Use a more raw technology where more care is needed to ensure that bugs are not introduced but is much easier to perform changes.

There is no clear-cut answer to this: "it depends".

Let's throw out numbers to attempt to make sense of this. It takes 5 man days to implement a change using technology number one that has an average bug rate of 1 bug per week. It takes 0.2 man days to implement a change using technology number two but it has a bug rate of 10 bugs per week. This means that technology #2 is 10x more error prone but takes 25x less effort to use it. From this, it appears that it is better to use the more bug-prone technology than it would be to use the restrictive technology.

This is obviously a contrived case. The gedankenexperiment behind all of this is to determine when one should introduce a technology into a project in order to reduce risk (in this case, bugs). If a technology has high costs associated with its use (e.g. time, training, personnel) then it may not reduce the overall project risk.

Bottom line: Understand all risks associated with a new technology and appropriately factor those into the over-all risk of the project. If the risk increases, it may not be worth while to use technology. If the risk decreases, then the technology will likely provide the desired returns. If there is no appreciable change in risk, then look at other factors such as long-term benefits, project duration, and cost.

Hanlon's Razor
"Never attribute to malice that which is adequately explained by stupidity."
Robert A. Heinlein
Managing change

It has been my experience that most people respond to change as they do to loss or grieving. Elisabeth Kubler-Ross first identified the five stages of grieving: denial, bargaining, anger, despair, and acceptance. (These five stages have been humorously portrayed in the Simpsons.)

Effectively managing a team through change requires recognizing the reaction and guiding individuals though the steps as they occur. In most scenarios providing adequate time and an having an "open door policy" where people are encouraged to discuss their feelings is sufficient. For the more difficult cases, human resources may need to be brought in.

Sounds like ...

I have been doing to research lately into natural language processing (NLP) and information extraction (IE) when I stumbled on The Double Metaphone Search Algorithm and phonetic distance. This is a good starting point for reference information.

NAP's and WAD's

I was just working with some of the testing folks and they were talking about NAPs and WADs. I had never heard these TLAs (three letter acronyms) before so I had to look them up:

  • NAP: Not A Problem
  • WAD: Works As Designed

You learn something new every day.

Do development skills scale?

A colleague of mine and I were chatting around the proverbial water cooler this morning when we ventured onto the topic of developer skills. Do developer skills scale with increasing complexity and project size?

Personally, I have witnessed excellent small project programmers completely fall apart on large projects. I have also seen programmers get barreled over by a complex software suite. Is this a marking of cognitive ability, a lack of developed or necessary skills, or do the possessed skills simply not scale?

What do you think?

Code Comments

How many time have I heard a programmer say: "If the code is written well enough, there's no need for comments". This statement could not be farther from the truth. The code, sans comments, obviously defines the what and how: what does the code do and how does it do it. But what is missing from this is the why: under what conditions and what assumptions were made.

Comment Types and Categories

Before discussing commenting practices let's break down the various types of comments. Some of these are specific to Java and javadoc but it should be an easy exercise for the reader to extrapolate to other langauges.

  • File comment: a comment at the top (or just below the package statement) of each file that typically contains the name of the file, the date it was created and any copyright or license information for that file.
  • Type comment: a comment for the type or class that contains the purpose and functionality as well as any global information about the class.
  • Member (method or field) comment: a comment for each field and method of a class. All member comments will contain a description of its use. For methods, expected and allowed argument values as well as any expcetions that are thrown are listed. For fields, value ranges and expected or not allowed values are listed.
  • Block comment: a comment before an algorithm or section of code elaborating on its use. A block comment may contain only a single line. (This definition varies from what is traditionally used.)
  • Inline comment: a comment contained on the same line as a program statement typically used to describe the need for or use of that statement.
  • Exclusion comment: a comment delineating a section of code that is not to be executed. (This is typically called "commented out code".)

These comment types can be divided into categories:

  • For using the code / API: These comments assume that the code will not be present. Type and member comments are in this category and are typically contained in javadoc-style comments.
  • For maintainers of the code: The code is present but a greater understanding of the code is necessary. Block and inline comments are for maintainers of the code.
  • For Housekeeping: File and exclusion comments and portions of the type comments contain information that is used purely as meta-data for the code.

Commenting Guildelines

  • Commenting is not an after thought. Commenting should occur before each code block is written. All functionality, potential limits and problems should be completely described before the code is written. There should be no surprises when you actually begin coding a block. All functionality should be understood and described in the comment before the code is written.
  • Comments are in part for you, but are most commonly used by others. Ensure that the content and style are such that someone who has never seen the code before understands the "why"s of the code. Have some compassion for the poor clod that has to maintain the code ... because that poor clod may be you in tweleve months!
  • Work from the outside in. When creating a new class, begin by explaining the function of the class and why it is needed (and, for example, why another class wasn't used in its place). For each member field and method added, descibe its function clearly and concisely as well as its reason for being. Given that javadoc comments are used to produce API documentation, limit the explaination of the internal functioning of the method in the comment. Having such verbosity tends to confuse readers who simply want to use the function. Save the verbose description for inside the method itself.
  • Comments should be written as if you are new to the code. Do not assume anything. Attempt to reference the reader to as much pertinent information as possible.
  • It is more important to explain the "why"s rather than the "what"s or "how"s Most often, the "what"s and "how"s can be determined from the code itself, but the "why"'s can never be derived. Each decision that is made and the reasons for it, should be explained clearly and concisely in comments. Refer to the entry What about the "Why"? for more information.
  • Comments should be clear and concise. You're not writing War and Peace and you're not going to win a Pulitzer for your work.
  • Try to limit replication of comments, but also remember that you do not know where and how another developer will begin looking at the code. Use "see <other>" to inform the developer where to go for related information or use roll-up documentation such as the package.html file.
  • Keep the language to 3rd person as much as possible. Other developers, many times removed, will not know who "I" or "we" are. If "I" is necessary for describing a "why", include your initials to give some context and make sure that you have been added to the author list of the file. For example, "(RG)".
  • Always keep comments up to date. If a comment described undesired functionality and that functionality is reparied, leaving the comment in place will cause loss of productivity while another developer attempts to understand the "problem" and fix it. Always check the code to ensure that any changes are reflected in the comments. It does not need to be commented that the problem was fixed (that is what version control is for). Simply remove comments that no longer apply and replace with comments describing the new or changed functionality.
  • Perform a code walk-through of your own code before you submit it. You should be able to read the comments and understand completely what (and why!) the code is doing without ever reading a single line of code. Then, ensure that the code matches the comments exactly.
  • Exclusion comments must have an accompanying explanation and that comment must be added at the time when the exclusion is made. The number of times that a section of code is commented out for debugging purposes only to be checked in in that state is staggering. Unless there is a comment associated with the exclusion, there is no way to distinguish if that code is broken, unneeded, an example, or removed for debugging.
  • Before each logical block of code, there should exist a block comment completely describing the code section. Inline comments are used to describe the action or reason for a particular line. For example:

    int size = array.length;        // purely a convenience variable
    
  • Clearly state expected, allowed and disallowed values as well as scope for fields.

    /**
     * The user of the application.  This value is only allowed to be null
     * between construction and when the value is set (via 
     * {@link #setUser(User)}).  If null when used an exception should 
     * be thrown.  This value may only be set once and if reset an 
     * exception should be thrown.
     */
    private User user;
    
  • Comment all non-explicit else or default statements. Because a significant number of bugs are the result of not understanding the implication of an else or default, the extra time spent thinking though them and commenting them are time well spent. For more information, refer to the entry: Coding Defensively.
  • Comments are not editorials. Be professional and refrain from writing editorials.

Comment Notifiers

It is common to see XXX or FIXME in code. But there are more notifiers that can be used:

  • NOTE describes a situation which is not obvious from reading the code directly but is desired behavior or describes assumptions or constraints that are not explicit.

    Ex: "NOTE: this will not work with values less than zero."
    Ex: "NOTE: this function was added as a work around for the bug found "
  • FIXME denotes code that simply does not work. Describe the symptoms or whatis broken.

    Ex: "FIXME: values greater that 10 cause this function to fail."

  • TODO describes functionality that still needs to be added or describes code that performs a function, but work still needs to be done.

    Ex: "TODO: multi-auth is not implemented"

  • CHECK describes functionality that at initial overview does not appear to be correct but does perform the necessary fuction.

    Ex: "CHECK: can 'j' be less than zero here?"

  • BUG followed by an identifier marks a section of code that is in place or has been fixed because of a bug report.

    Ex: "BUG #8452: the value much be checked for null before using"

  • REQ followed by an identifier is a reference to the requirements documentation.

    Ex: "REQ 5.7.1a: non-logged in users are not allowed"

  • PERF is essentially a NOTE but is specific to a performance optimization. For all intents and purposes NOTE can be used in its place.

  • Ex: "PERF: ArrayList is explicitly used (rather than List) to minimize the overhead of polymorphism"

At times the modifiers can be ambiguous; a CHECK may represent a FIXME that needs to be TODO'ed and NOTE'ed. It is always better to use a more servere marker such as FIXME rather than CHECK for tracking purposes.

Creative Commons License Unless otherwise expressly stated, all original material of whatever nature created by Rob Grzywinski and included in this weblog and any related pages, including the weblog's archives, is licensed under a Creative Commons License.