|
August 2007
August 23, 2007
The first rule of debugging
If you've been programming for more than, oh, a few minutes, you've discovered that your programs don't always work as you intended.
Most beginners' first reaction when they make such discoveries is to think that there is something wrong with the compiler. After being disabused of that notion, they will reluctantly go looking for the problem.
However, my experience is that many programmers, especially beginners, make a critical mistake when they go on their bug hunts.
The mistake is in failing to be sure that the program that they are trying to debug is actually the program that they are running.
For example, before you ran your program, did you compile it? Are you sure? Are you sure that you compiled every piece of source code that you're using? With the same compiler? Are you sure that you saved the code before you compiled it.
I've lost track of how many times I've had a program crash on me, then removed all object and executable files, then recompiled everything from scratch, and had it work perfectly.
Oh yes, one other thing. Many operating systems have a notion of a search path, which is a list of places where the system should look for a program when you run it. Sometimes, the system is set up in such a way that when you try to execute a program, you are unwittingly getting a program with the same name from somewhere else. For example, on many Unix systems, typing a.out might execute a file named a.out wherever in the search path it happens to be, whereas typing ./a.out will insist on executing a.out in the current directory.
Whatever facilities your operating system happens to have, you will save yourself a lot of time if you remember the first rule: Before you go to fix it, be sure you're fixing the right thing.
Posted by Andrew Koenig at 11:00 AM Permalink
|
August 22, 2007
A whopper of a lesson in user-interface design, part 3
To recap: I wanted to upgrade my computer's graphics card. First the computer manufacturer recommended a card that wouldn't fit, then they replaced it with a card that fit but required a power-supply upgrade, and the new power supply didn't fit.
Is the third time the charm?
To figure out what to do about the non-fitting power supply, I contacted the vendor's tech support yet again. I explained that on their recommendation, I had just purchased a graphics card that said (on the box) that it required a 350-watt power supply, but my machine had only a 250-watt one and the replacement didn't fit.
The response: "We checked your machine's configuration; it has a 305-watt power supply, which is adequate for this graphics card." I said that the label on the power supply said it was 250 watts, but they insisted that their records showed that it was 305 watts.
I did not ask how they managed to get from 305 watts to 350 watts. Instead, I reasoned that the graphics card's power-supply requirements were not absolute. After all, how could the graphics card's manufacturer know what other devices were on the machine. The manufacturer's technical-support people had assured me that this card would work with my existing power supply; if I tried it and it did not work, it would be their problem. Bad reasoning based on wishful thinking, I know, but so be it. I was worried that if I tried to return the card after tech support had said it would work, they would charge me a restocking fee, or--still worse--refuse the return altogether.
So I tried the new graphics card. Somewhat to my surprise, it appeared to work, though the speed of my computer's cooling fan reminded me that the power supply was now working hard. Nevertheless, I thought I'd contact tech support again to ask about that gap between 305 and 350 watts, and to see if there was another power supply available.
The second tech-support rep's story flatly contradicted the first: (1) This graphics card requires a 350-watt power supply, not 305; (2) 305 watts is the largest power supply that could be installed in this machine, and therefore (3) I had to send back the graphics card that I had just installed and buy another one with smaller capacity.
We've already seen lesson one: Making incorrect recommendations is worse than making no recommendations at all. We can now add to that as lession eight: Once you've made an incorrect recommendation, correcting it later doesn't help much because there's no reason to believe the correction.
Anyway, I asked for a recommendation for an appropriate graphics card. Silly me. But then I had an idea: I phoned the manufacturer of the graphics card, described the situation to them, and asked for their recommendation. They recommended the same model. Now, at last, I had independent corroboration.
So I ordered the new card, hoping that my machine wouldn't fry itself before it arrived. This time, I got lucky: When I installed the new card, it worked just fine, and the machine was significantly quieter too.
Now, let's look at what would have happened had the computer manufacturer refrained from advising me about graphics cards. I would probably have rummaged around the web and come up with the same card I eventually bought. The chances of doing so would be even greater if the computer manufacturer had a web page saying something like "Here are the different types of graphical interfaces," "Here is how to find out what will fit on your machine," and other such general advice.
I would probably have been slightly annoyed that they didn't know enough about their own products to make specific recommendations, but that annoyance would be nothing compared with how I ultimately wound up feeling. In effect, by trying to be helpful, they wasted my time and their own, and damaged their reputation.
Now let's see how these lessons might apply to other aspects of system design.
First and foremost is the idea of thinking about systems from the user's viewpoint rather than from the designer's viewpoint. I am fond of saying that when a company's representative explains why the company can't help me by describing the company's organization chart, the company is in trouble. When I have a problem with a company's products, and I call their customer-service number, I expect to be connected with someone who can help me solve my problem--not with someone who listens at length to my problem and then tells me that I need to contact someone in another department.
The other important idea is that incorrect information is worse than no information at all. This notion usually extends to other aspects of system design as well. For example, it is usually better for a program to refuse to produce output at all than it is for the program to produce incorrect output without complaint. Moreover, once a program has produced incorrect output, correcting it after the fact may not make things any better.
The third idea, and perhaps the most important one, is that complexity is an ever-present problem. Think about all of the details involved in these transactions, and all the specialized knowledge that was necessary to arrange for them in the first place. Such complexity seems to have been creeping for decades into every aspect of every computer system I encounter. It is so pervasive that it has no chance at all of going away--the best we can hope for in practice is to find useful ways of managing it.
Managing complexity is, of course, another huge topic, so let's save that one for later.
Posted by Andrew Koenig at 02:06 PM Permalink
|
August 10, 2007
A whopper of a lesson in user-interface design, part 2
In Part 1, I tried to upgrade my graphics card, only to be steered wrong by my computer manufacturer's website. The saga continues with my trying to swap the wrong card they had sold me for the right one.
The first step was a call to technical support, explaining the problem. After a fair amount of time on hold (or maybe an unfair amount), I reached someone who quickly and apologetically acknowledged that the company had indeed sold me a graphics card that would not fit my computer, and who equally quickly told me that the same manufacturer made an equivalent card with the right kind of interface for my machine.
"So how do I arrange for you to take this one back and send me the right one?"
"Oh, I can't help you there; I just answer technical questions. But I'll connect you to customer service."
Lesson three (Lessons one and two are in Part 1): When someone explains to you why the company's organization chart means that someone else has to help you, there is trouble ahead.
Lesson four: When you're designing a system that deals with customers, think about how the system looks from the customer's viewpoint, not just from the company's.
So it was off to customer service, and another fair (or unfair) amount of time on hold. When I eventually got to the front of the line, I had to explain my problem again, after which the customer-service rep arranged for me to return the inappropriate graphics card.
Lesson five: Design your system so that when your customer tells you something, the system remembers it and doesn't make the customer repeat the information.
Lesson six: If one of your people has to hand a customer off to someone else, put the customer at the head of the line.
So far so good: I had arranged to send back the inappropriate graphics card. Now the real question:
"How do I arrange to purchase the correct card for my machine?"
"Oh, I can't help you there; I'll have to transfer you to sales."
See lessons three and four, above.
Sales, of course, answered the phone much more quickly than customer service or returns. However, I had to tell the whole story again (See lesson five). The sales rep was happy to sell me a new graphics card. Not only that, but she double-checked whether that card would work with my machine.
It turned out, she said, that it wouldn't work either. The problem is that the card has a higher-capacity processor than my old one, and therefore requires more power than my machine's power supply can deliver. Fortunately, we can solve the problem if I buy and install a new power supply. Moreover, because I would be buying the power supply at the same time as the graphics card, she would offer me a discount on the combination, making the bottom line not much more expensive than the graphics card I was returning.
I checked the box for the graphics card I was returning. Sure enough, it said that it required a 350-watt power supply, and my machine had less than that. So she wasn't just trying to extract more money from me. Instead, the tech-support guy had failed to notice the power-supply requirement. See lesson one again.
So I shrugged my shoulders, took out my credit card, and ordered the new graphics card and power supply.
A few days later, they showed up. Being a cautious sort of fellow when it comes to hardware, I decided I would install the new power supply first, then verify that the machine worked the same way with the new power supply as it did with the old one, and only then would I install the new graphics card.
So I shut down my machine (having backed up all of its files the day before), took out the old power supply, unpacked the new power supply--and found that it didn't fit.
I mean that it physically didn't fit: The power cord from the wall plugs into a socket on the power supply, and the new power supply's socket was in a different place than the old power supply's socket. Which meant that if I were to install it in my machine, I would have to cut a hole in the metal panel on the back of the machine to allow the power cord to plug into it.
Lesson seven: When a customer calls you to replace something that doesn't work, and you sell him a replacement, you had really better make sure that the replacement works. Otherwise your customer is going to be very, very angry.
To be continued...
Posted by Andrew Koenig at 01:09 PM Permalink
|
August 07, 2007
A whopper of a lesson in user-interface design, part 1
A few months ago, I posted a note about a disk problem, and how, despite the designers' best of intentions, so many users couldn't figure out how to use the hardware that the vendor effectively behaved in a way that made the hardware irrelevant.
Well, that's nothing compared with what happened recently. Again, a frustrating experience turns out to have some lessons in system design--lessons that I think are useful enough to be worh reporting.
For some time, I had been using an old CRT monitor. It was huge and heavy, but it worked, and I figured that the longer I waited before replacing it, the cheaper the replacement would be. Moreover, one of my cats liked to sleep on top of it.
A couple of weeks ago, it started acting flaky: Every once in a while, the image on the screen would flicker and flash, accompanied by a crackling sound. I know enough about CRT monitors to know that the symptom suggested a problem in the high-voltage section, and I also know enough to realize that messing with the high-voltage section could well be injurious to my health; so I decided it was time to retire the monitor and buy a new one.
A few days later, the new monitor arrived. It was gorgeous! Excitedly, I hooked it up to my computer, started it up--and my stomach figuratively dropped through the floor when I saw how wretched the image looked. Scratch that: Images looked fine; it was just that any text on the screen was screwed up. The only way I can describe it was "smushed" -- letters were the wrong shape, partially overlapping, and almost impossible to read.
I've had enough debugging experience to know that the worse a problem looks at first, the easier it usually is to find. Indeed, in this case, the problem had a trivial reason: My four-year-old video card couldn't support the new monitor's full resolution, so it selected the largest resolution available. This resolution was not an integral multiple of the monitor's native resolution, so when the text was downsampled for display, it looked terrible. Of course, I could solve this problem by going to a still lower resolution, but what on earth was the point of buying a new monitor only to decrease image quality?
I thought for a while about returning this monitor and buying a smaller one instead--but first, I figured it would be a good idea to see what it would cost to replace the video card in my computer with a more powerful one.
So I went to my computer manufacturer's website. I told it what model I had, and it gave me a page with a list of recommended graphics-card upgrades. The card with the highest capacity cost only about 1/5 what the monitor had cost, so I figured that that card would work if anything would, and ordered it.
A few days later, the video card showed up, and I excitedly went to install it--only to find that it didn't fit. The connector on the card did not match any of the connectors on my computer's motherboard, even after I had removed the old video card.
That's when I started doing the research I would have done earlier, were it not that the manufacturer had recommended a list of video cards for my specific computer. I learned that there are three main ways of interfacing video cards to computer motherboards, and the particular one on my computer's motherboard did not match the video card I had purchased.
Lesson one: When you design a system that makes recommendations to your customers, you do more harm when you give incorrect recommendations than when you give no recommendations at all.
Lesson two: When you ask a vendor's website for recommendations, you may be able to save some time by verifying those recommendations for yourself.
So now it was off to my computer manufacturer's customer-service people to find out what I really needed and how to swap what I had for it.
To be continued...
Posted by Andrew Koenig at 10:36 AM Permalink
|
|