One of the more misunderstood parts of the software life cycle is the estimate. All methodologies have estimates, and it seems that all management mis-uses estimates. The rough estimate asked for at the beginning of the project rapidly turns into the contracted-delivery-date-with-penalties used to justify 80+ hour weeks.
One difficulty is that information deteriorates upwards in an organization - no matter how clear you are to your boss that it will take 3-8 weeks, +/- 2 weeks, he will summarize that as 1-10 weeks, his boss will split the difference at 6 weeks, and his boss will think 3 weeks, "because everyone knows programmers pad their estimates", so you end up with and already compromised schedule.
One of my early colleagues in the industry said that the minimum estimate for anything was 2 weeks. Bigger projects got longer estimates, but the floor meant that you always had some spare time to cover where management cut your times.
One brave tactic that I have used on occasion is to tacitly refuse overtime. I had a task once where I was asked to estimate the time it would take. I guessed 2 weeks (sic), and turned that estimate in to my boss on a Wednesday morning. That Friday at a status meeting I was informed that I was already 2 days behind schedule; imagine my surprise, since I was not told that my estimate had become my deadline. I was especially peeved because I was working on a customer issue, so I had no re-prioritization to let me know the new project was my primary task.
So I just worked M-F, 8 hour days. I did not stay late unless there was more customer site interaction, which often required staying until their staff went home at their local 5pm. I was lucky in that my estimate was only slightly above the real effort. But had it required more effort, I was going to stick to my routine, since it was not I who made the mistake in scheduling and priorities.
If you are unlucky enough to be in a Death March shop, there may be little recourse but to risk failure. If you can form a cadre of programmers who are willing to hold the line on estimates, you might get your bosses to stop ignoring the laws of physics.
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Developing software in the Real World is different from all the theory. I'll attempt to explain my insights into this process, based on 25+ years in the industry in a number of different companies.
Thursday, February 05, 2009
Wednesday, February 04, 2009
What's The Rush?
My Real World job has been hectic lately, with customer and internal issues colliding, and my individual time being a very valuable commodity for the various release managers. Since some of the issues affect fielded releases, the Program Managers are keen to tell the customers when we will have a fix available for them. So keen, in fact, they are telling them dates by which we will deliver said fixes.
Read that again. The Program Managers are setting a schedule by which developers are to find, analyze, and fix a bug, and test that fix.
How do you handle something like this? A total perversion of all that is Good and Holy in software development!
In better times, the best advice would be to look for another job. As I'm writing this, that's not such good advice, so you have to tell your managers something, and do something in your process to handle this. (Kudos to you if you have a process that acknowledges bugs will exist)
For the upward information flow, address it like car repairs - it doesn't matter how often the vehicle makes that funny noise if the mechanic isn't there to hear it - bugs need to be replicated where a developer can apply tools to extract information. If you broke down on the highway, called your mechanic and asked him to diagnose the problem over the phone, she'd tell you to wait until the tow truck got the car back to the shop and she was able to hook up the analyzer. Likewise with a bug in code, we need more data in most cases.
In addition, you need to make sure to emphasize that unless the software is very well factored, changes may have far-reaching side effects that need to be tested for. This is especially important for complex programs, such as multi-threaded ones, or highly performance-optimized ones.
Once a bug is found, you sometimes find it's the loose thread in a knitted tangle disguised as a sweater. It make take a long time to refactor the code to eliminate the root cause of the problem. I can't say I've ever had success in getting this point across to anyone more than one level above me in any organization.
If all else fails, revert to the old proverb, "Haste makes waste"
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Read that again. The Program Managers are setting a schedule by which developers are to find, analyze, and fix a bug, and test that fix.
How do you handle something like this? A total perversion of all that is Good and Holy in software development!
In better times, the best advice would be to look for another job. As I'm writing this, that's not such good advice, so you have to tell your managers something, and do something in your process to handle this. (Kudos to you if you have a process that acknowledges bugs will exist)
For the upward information flow, address it like car repairs - it doesn't matter how often the vehicle makes that funny noise if the mechanic isn't there to hear it - bugs need to be replicated where a developer can apply tools to extract information. If you broke down on the highway, called your mechanic and asked him to diagnose the problem over the phone, she'd tell you to wait until the tow truck got the car back to the shop and she was able to hook up the analyzer. Likewise with a bug in code, we need more data in most cases.
In addition, you need to make sure to emphasize that unless the software is very well factored, changes may have far-reaching side effects that need to be tested for. This is especially important for complex programs, such as multi-threaded ones, or highly performance-optimized ones.
Once a bug is found, you sometimes find it's the loose thread in a knitted tangle disguised as a sweater. It make take a long time to refactor the code to eliminate the root cause of the problem. I can't say I've ever had success in getting this point across to anyone more than one level above me in any organization.
If all else fails, revert to the old proverb, "Haste makes waste"
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Malaria.exe
Looks like Microsoft is branching out from being a vector of computer viruses into being one of real-world viruses.
I wonder if any CxOs from RedHat, IBM, or Apple were in attendance that day......
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
I wonder if any CxOs from RedHat, IBM, or Apple were in attendance that day......
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Tuesday, February 03, 2009
Logging in Your System
Logging is one of the more controversial aspects of a large system. There are some who hold that you should not need to have log file - everything should be presented in some UI or other. Others take it to the other extreme, logging every action at almost the code line level.
Not surprisingly, the answer lies in between. You need to log enough to be able to track what is going on, and save enough info about the error conditions to make it clear what went on, but you don't want to flood your logfiles with chaff.
One common thing is to make your logging dynamic - you can adjust it on the fly, so that if an error is recurring, you can turn it up to get more detail. For this to work, you need to define various levels of logging to present, and have a means to store the current level of presentation. Another facet of logging is the files the logs are written to. UNIX system have the syslog() facility, which is good for serious issues - ones that may shut down the system, or cause complete failure, like full disks, etc.
But it can be a pain to fill up a system file with the minutae of your most verbose debug level, so the best is probably to route logs to a file under your control. Of course, it goes without saying that you should have a file aging system in place to keep the file from growing too large, and having too many old ones.
There is usually a debate about how logging levels should be managed - as increasing levels, or as bit flags to cover areas like disk I/O, database access, RPC communications, etc. It's something of a judgment call, but make a set of categories and enforce it across all processes in the system, or you'll have chaos.
If you go with levels, you'll have the question of how many levels. There are a number of logging systems that use levels, and if you are using a language with such a facility, use those levels. If not, look to one of them for suggestions.
Have a command-line utility to adjust logging levels, so that if you have to go in remotely you can change things - there's nothing worse than having to wake up a site staffer just to navigate to a single GUI and click one button.
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Not surprisingly, the answer lies in between. You need to log enough to be able to track what is going on, and save enough info about the error conditions to make it clear what went on, but you don't want to flood your logfiles with chaff.
One common thing is to make your logging dynamic - you can adjust it on the fly, so that if an error is recurring, you can turn it up to get more detail. For this to work, you need to define various levels of logging to present, and have a means to store the current level of presentation. Another facet of logging is the files the logs are written to. UNIX system have the syslog() facility, which is good for serious issues - ones that may shut down the system, or cause complete failure, like full disks, etc.
But it can be a pain to fill up a system file with the minutae of your most verbose debug level, so the best is probably to route logs to a file under your control. Of course, it goes without saying that you should have a file aging system in place to keep the file from growing too large, and having too many old ones.
There is usually a debate about how logging levels should be managed - as increasing levels, or as bit flags to cover areas like disk I/O, database access, RPC communications, etc. It's something of a judgment call, but make a set of categories and enforce it across all processes in the system, or you'll have chaos.
If you go with levels, you'll have the question of how many levels. There are a number of logging systems that use levels, and if you are using a language with such a facility, use those levels. If not, look to one of them for suggestions.
Have a command-line utility to adjust logging levels, so that if you have to go in remotely you can change things - there's nothing worse than having to wake up a site staffer just to navigate to a single GUI and click one button.
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Monday, February 02, 2009
Test Driven Design examples
I had a post planned out to cover TDD in some detail, but I got about halfway into it when I realized that since I don't get to do enough of it, I'd be better off (actually, you'd be better off) if I pointed you at someplace where it gets done more often, recent events notwithstanding.
Two of the big problems I have with TDD are
Now, some languages make it a little easier - Java and Python, for example, allow you to add a main() to every file, so that you can invoke each class with a set of test parameters from the start. This will serve to bootstrap your test scaffolding in most cases, since you can make all your classes callable from their own main(), and have some tests there. As your application grows, you can eliminate the test main() from more of the classes as you pull methods into patterns, allowing you to move the tests from the original file to the new one.
If you're using C++. however, you're in a bind. You can't have more than one main, and you need it for your actual program. A way around this is to make a class that is the core of the process, and have the main() be a shell, calling the constructor of that class, and possibly a start method, as the whole of the function. Again, as your codebase grows, you can move the test code around as necessary.
If you've got a mess of code already, with now tests, your best bet is to start with the interfaces. Anywhere there is a API - RPC, SOAP, TCP/IP, etc - you can write a program to provide either end of the connection, and start building a test harness from that. Use scripts to run the basics, testing every message with good and bad data. If you have an API at each end of the process, you can connect both end to a single program to allow it to confirm success/failure of any given message. A tool like netcat can be useful for this - your individual test programs can have a socket sending text datagrams to each other with results.
A caution - this can get interesting enough to consume all your spare time - it's a lot more fun to make things that you can see working than to be wading through spaghetti code that needs refactoring but lacks tests for checking functionality, so enforce some limits on your test scaffold building, unless you have a mandate from your management to build the test sets.
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Two of the big problems I have with TDD are
- How to get started on a project with it, and
- How to get it going if you've got a mess of code already
Now, some languages make it a little easier - Java and Python, for example, allow you to add a main() to every file, so that you can invoke each class with a set of test parameters from the start. This will serve to bootstrap your test scaffolding in most cases, since you can make all your classes callable from their own main(), and have some tests there. As your application grows, you can eliminate the test main() from more of the classes as you pull methods into patterns, allowing you to move the tests from the original file to the new one.
If you're using C++. however, you're in a bind. You can't have more than one main, and you need it for your actual program. A way around this is to make a class that is the core of the process, and have the main() be a shell, calling the constructor of that class, and possibly a start method, as the whole of the function. Again, as your codebase grows, you can move the test code around as necessary.
If you've got a mess of code already, with now tests, your best bet is to start with the interfaces. Anywhere there is a API - RPC, SOAP, TCP/IP, etc - you can write a program to provide either end of the connection, and start building a test harness from that. Use scripts to run the basics, testing every message with good and bad data. If you have an API at each end of the process, you can connect both end to a single program to allow it to confirm success/failure of any given message. A tool like netcat can be useful for this - your individual test programs can have a socket sending text datagrams to each other with results.
A caution - this can get interesting enough to consume all your spare time - it's a lot more fun to make things that you can see working than to be wading through spaghetti code that needs refactoring but lacks tests for checking functionality, so enforce some limits on your test scaffold building, unless you have a mandate from your management to build the test sets.
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Sunday, February 01, 2009
How DO You Get To Carnegie Hall?
I've mentioned Code Katas before, and practice, and I found this recently, from ORA, and while it wanders into general learning theory, it covers the idea that you need to practice code to get better, and that you need to be reviewing your code to see where you went wrong (rather like sports teams reviewing the game footage for pointers, or fighter pilots reviewing dogfight radar records).
So when you have a moment, try rewriting a small module of your current project, using a new data structure, or with only library functions.
(Also, a milestone for the blog - 100 posts!)
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
So when you have a moment, try rewriting a small module of your current project, using a new data structure, or with only library functions.
(Also, a milestone for the blog - 100 posts!)
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Pithy Sayings
Here's a few good quotes about software. I especially like #s 1, 3, and 6, notwithstanding #6 is from Bill Gates
Given Microsoft's code bloat, I wonder if he's changed his mind?
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Given Microsoft's code bloat, I wonder if he's changed his mind?
Technorati Tags --
Software, SoftwareDevelopment, Computers, Programming
HTTP
Subscribe to:
Posts (Atom)