Guest Post: How to Neglect a Product to Death
By: Dan Reese
My friend and former co-worker Matt Ryan recently commented on the impending death of Novell Forge. A message on the Novell Forge site confirms that Novell will be shutting things down soon. I can corroborate some of Matt's story as I was on the Forge team for about a year during its heyday.
But what really interests me about the situation are the implied instructions on how to neglect a successful product into a slow death that can be blamed on the product itself.
- Avoid rewarding or recognizing any of the people involved. Even better, reward someone else.
- Do not feed its success. Withhold funding, staffing and career growth opportunities.
- Provide poor support. Delay fixing problems.
- Set unrealistic goals and expectations. Blame the product or team for failure.
- Find excuses to kill the project. Focus on the negative in all meetings with executives.
This was a particular worry at Mozy when it was acquired by EMC. They promised that EMC did not want to be the lumbering elephant that accidentally squashed its shiny new purchase. And it was true. But we worried about accidental squashing anyway.
It has been two years, and I have seen projects and executives come and go. Though I do not believe it was intentional, at times it felt like Mozy was being neglected. But the core of Mozy has remained strong and continues to grow.
Based on my experience, here is what to do to keep a successful product moving forward:
- Execute anyway. Deliver a quality product in the face of neglect.
There is precious little a neglected production team can do other than produce. I heard something once I have always remembered: nothing succeeds like success. It is much harder to produce in the face of neglect, but it is also nearly impossible to ignore or argue with.
Mozy is clearly not perfect, but despite occasional neglect it continues to provides a valuable, profitable service. Working with smart people helps. Working for smart people helps. Working with people you like helps. Working on something you care about helps. Working with cool technology helps. But over time, delivering a useful, profitable product is what matters.
(This guest post is originally authored by Dan Reese and reprinted by permission. It is subject to the copyright terms at the original location.)
Fudging Complete
Are you guilty of this?
If you have kids, I bet they do it. You tell one of your kids to mow the lawn or do the dishes. After a while you see them playing XBox or watching TV. You ask, "Did you mow the lawn/finish the dishes?" "Yeah, I'm done," they claim. Then you go to check out the handiwork, only to find that there's a good 100 square feet of lawn that simply got skipped, or that all the dirty pots are still sitting on the countertop.
Don't get so high and mighty: You probably did it when you were a kid, too.
Apparently, as we grow up, we change. Some people don't, I guess. Some people continue to knowingly lie about this stuff even as adults (e.g., presidents of the USA). But most of us change a bit. Perhaps we don't like getting caught. Or we don't like the idea that we failed to do something we said we'd do.
The problem is, even though most of us change, it doesn't mean we are all delivering what we committed to.
If you've been given a task, completing the task means completing the work pertaining to that task. All of it. Not "the bulk" of it, or "the majority" of it, or "everything except a few odds and ends." It means the whole thing.
That's what Fudging Complete is. It's when, either because you are afraid of the consequences of not finishing, or because you don't like to admit failure, or because you don't want to lie, you try to convey a sense of "complete" when you aren't really complete. You redefine "done" to mean "mostly done". Or you change the definition of the task so that it matches the work that has been done, even though now the task doesn't match its intended purpose.
It's when you knowingly check in code that hasn't been fully tested in order to meet your feature complete date. You know the feature isn't actually done, because you haven't completely tested it. Or maybe you've done some preliminary testing on it, but you haven't written your unit tests. You know if you do what you should, you will miss the date, and that looks bad. So instead you can make your date by checking in today. You are knowingly incurring test debt, but at least you made your date. But you aren't really complete.
It's when you are at the end of a sprint and you take a look at the committed items, and notice that all but one of the committed items are done, and report your sprint status as having met your commitments anyway. In the footnotes you make note of the fact that the sprint is complete, except for one or two small tasks that didn't get finished, but other than that the sprint is complete. But you aren't really complete.
If you do this, you are Fudging Complete. You are like the movie rated PG-13 for "partial nudity." What does it mean to be partially nude? You are either nude or you aren't! A movie either has nudity in it or it doesn't.
Of course, "partial nudity" technically makes sense and is in fact quite common. I am partially nude as I type this post: My forearms are fully exposed. But the term doesn't really mean what it implies. Saying a movie contains "partial nudity" is simply one person's way of trying to deceive you about what is really in the movie. It doesn't have nudity! It only has partial nudity!
Fudging Complete has the same effect. Telling your manager that your project is complete, except for one or two loose ends, conveys the wrong sense to your manager. It is technically possible to be partially complete, but saying it doesn't convey the right message. It tries to convince your manager that you are complete, and you aren't.
When we do our work, we need to approach it the way a basketball player approaches shooting a basket. When you're playing basketball, whether you will take the shot depends on a number of things: Whether you actually have the ball, whether you are near enough to your basket that you think you can make the shot, whether anyone on your team is open closer to the basket, whether you are open to take the shot, etc. However, you know as you shoot the shot that there's a chance you will miss. Missing the shot is no big deal; every basketball player misses shots. If you miss, it is not that big of a deal. You quickly regroup and get ready for your next opportunity to shoot.
Working on software projects needs to be like this. It is okay to miss. Everyone misses. Sometimes software engineers are afraid to fail, so I don't call it "failing" — I call it "missing." If you miss, learn from your mistake and do better next time.
What you shouldn't do, however, is be dishonest about missing. Everyone misses. You are not perfect. Good teams and companies and managers know you will miss and will appreciate you being frank with them about what happened, instead of trying to redefine what completion means to make yourself look good. Don't do that. Don't fudge complete.
So You Want To Be A Software Engineer?
Ever had a conversation with someone who wanted to be like you?
Yeah, it's kinda weird. There's a young man in my neighborhood, a friend of mine, who recently told me that he is planning to be a software engineer. This of course interested me, so I asked a little about his plans. He's a pretty smart kid, and is planning to finish about two years of college before he finishes high school. Then he plans to finish up his degree within about two more years. Seems like a good plan, but there's a few other details:
- He's planning to pursue a computer engineering degree, not a computer science degree. He likes this plan because he will learn how to program but it doesn't require so many difficult courses in CS theory, math, and science.
- He's planning to obtain his degree from a brand new program that lacks reputation in the industry.
- After he gets his degree he plans to take a couple of years off for religious service, then return and go straight into the workforce.
When I asked him what he hopes to do with his degree once he gets it, he said his plan is to work on computer games.
Well, I care about this young man, but he won't listen to me. So I thought I'd write him a letter, right here on this blog, where he's sure to read it:
Dear (x),
It was great to hear about your goal to go into the software engineering field. Of course I'm very interested in that, because I've been doing that for almost 15 years. I'd love for you to be successful in your pursuit and think you've got a great future ahead of you.
Even though I'm excited about your goal, I'm concerned about your plan. First off, if you want to be a software engineer, there is only one option for your major: Computer Science. I know it is harder than other majors that also teach you how to program, but that is exactly why you should choose it — it will set you apart from the rest. The other degrees are excellent and meant to train you well for a career, but if the career you want is a software engineer, the major you should be taking is Computer Science, preferably from a school with a highly respected program.
I'm also concerned about you taking two years off after you finish your major. I know why you are taking the time off, and I completely agree with you doing that. But what you don't understand is that those two years will make your degree mostly obsolete. For most companies, a "college hire" is only a recent graduate; when you've been out two years, they'll expect you to have two years of experience. You'd be better off to do your two years, then wrap up, say, the last year of your degree after your religious service is done. You'll meet the hiring guidelines of the companies looking at you, and you'll be that much the better person for having done the religious service in addition to getting your CS degree.
I hope you'll consider what I'm trying to tell you. I can't tell you how many times I've met with people finishing up college that want to go into software engineering, only to find out after they were done that they chose the wrong field. And if there is any job in software engineering that requires a CS degree, it is in game development.
I realize you're young and think that what I'm telling you is dumb. All I can say is, I didn't invent the rules. You don't have to like the rules, but it doesn't mean you can break them and still win.
What I really can't figure out is, where are the advisors in all of this? When you're attending high school or college, aren't there advisors that are supposed to be helping you align your educational plans with your career goals?
Regardless, I simply had to say something. He'll probably never read what I wrote, or listen to me if I end up telling him. But I've seen too many discouraged college graduates to let it go any longer.
Discipline as a Prerequisite to Critical Code Contribution
Merriam-Webster's dictionary defines discipline as: "..."
Nah. Just kidding.
Most software teams I've worked on have had some degree of discipline around what code changes go into the codebase. This tends to take the form of:
- Any change should be associated with a defect or feature that is documented somewhere.
- Commit small, isolated, related changes, all associated with a single defect or feature, that can be easily rolled back.
- Test changes before committing them; avoid breaking the build at all costs.
That last one seems most obvious, but it is so critical that it has to be stated anyway. Think of it this way: If you work for me on an already functioning product, I would rather have you do NO WORK AT ALL than to break the build.
Of course, I would not pay you to do no work at all, either. But breaking the build is taking the product in the opposite direction from where we want it to go.
Some time ago I worked on a software team* where a team member had a problem with this kind of discipline. Details don't matter too much, but the net effect was that whenever this person made a commit, the rest of the team would tense up and hold their breath as they integrated the updates. This person had broken the build enough that his/her commits weren't trusted by the rest of the team. And even if the code would compile and run, you still didn't trust the changes because this person would often sprinkle in little changes hither and yon that were not tied to a documented defect or feature, and often wouldn't even call out the changes in the commit message.
(As a slight distraction here, I'll point out how frustrating this is when the team member works in the same office as you, as cited above. When that person works remotely, it becomes MUCH MUCH WORSE.)
I discussed this with my boss one day who wasn't sure what to do. We had a person on the team who was obviously very talented, but who was just not following good practice despite repeated requests to do so. I offered up the suggestion that I'm restating here, which is basically the following:
Disciplined software engineering should be a prerequisite to having the rights to make critical code contributions.
In other words, no matter how talented a programmer is, they shouldn't be allowed to contribute code to critical parts of the product if they do not exhibit sufficient discipline to be there. So what are the "critical parts" and what is the "sufficient discipline"? The critical parts are the parts that, if they are broken, the software doesn't perform it's primary function. For a product like Firefox, the "Help" dialog is almost certainly not critical, but the HTML parsing engine definitely is. The sufficient discipline is what I outlined above, but primarily centered around not breaking the build.
So to summarize, what it means is, someone who continually breaks the build should be disallowed to commit changes directly to the critical parts of the product until they earn that right back by adopting the discipline required. Of course, if you are that free-spirited maverick, there's a pretty strong incentive now to change your approach. You may not be paid to be disciplined, but you are paid to deliver software, and if you can't deliver software because your approach is irresponsible, this should encourage you to get on track.
Some teams choose to approach this by building elaborate systems that enforce proper behavior. I could build a complex checkin proxy that automatically merges my changes with the latest changes in the repository, builds the product, and then runs the tests (there are tests, right?), and then only makes my commit once all of that passes acceptably. That's nice and all, I suppose. But it seems like a lot of infrastructure, overhead, and process to impose upon the whole team, when to me it seems reasonable to expect that professional software engineers have enough discipline to do this on their own.
So if you aren't doing this now, how do you go about changing?
Well, you've gotta have a suite of automated tests in order to do any of this - a "broken" build is defined as one that does not pass the automated tests. If you do not have any automated tests, it is time for you to repent, my son. I do not have time to go into this here, but you must confess your grievous sin and atone by writing an automated test and adding it to your build process. Just one test is enough to get started - but it MUST be available as a part of the normal build process. Then every time a build passes the test suite but is, in fact, broken, update your test suite.
Now that you have automated tests, insist that your developers do the following before they commit:
- Update.
- Build.
- Test.
See? It's easy. If the tests pass, they can commit.
Now it is time for you to be disciplined. Committing code that does not pass the tests is a naughty thing to do. Do not let your developers be naughty. Take immediate action. I think I'd take the following approach:
- First time is a meeting with the boss. Go over the process. Make sure they understand the process and what happened. Personally, it seems like it would be tough to misunderstand, but hey, things happen. Don't be presumptuous or condescending. This meeting alone might be enough to get most people in line.
- If the problem continues, require peer review before checkin.
- If the problem continues, another meeting. This time, express that all of their current assignments have been reassigned to other members of the team, and they are being reassigned work that is not critical to the functionality of the project. Let them know that you are concerned about the impact this will have on their performance, because they are expected to contribute at a higher level than what their new assignments will allow. They have to demonstrate changed behavior and commitment to discipline in order to earn the right to do the important work again.
- If the problem continues after that, it is probably performance-improvement-plan time. Or mutual-agreement-that-they-find-a-different-employer time.
Actions Speak Louder Than Code
It took me a while, but I finally settled into my routine and got to where I'm reading my RSS feeds most days again. I was going through the posts of the past month or so, since the job change, and ran across this article on the "Making Good Software" blog about things that keep someone from being a good software engineer, outside of (and often in spite of) an ability to engineer software.
I'll summarize here. It isn't my intent to plagiarize; if you are remotely interested go read the article. Here are the things:
- Lack of discipline
- Big ego
- Poor communication
- Forgetting the customer
- Lack of proper work prioritization
I have known many of these people during my career. Indeed, I was one of them. I remember coming to Novell from IBM almost ten years ago. I thought I was pretty hot stuff and I made sure my team knew it. In fact, I actually said (this is embarrassing to admit) on more than one occasion, "There are people who know C++ better than I do, but I haven't met any of them." My ego surely made me hard to work with. It definitely was a cause of friction between myself and my management chain, and ended up being a (deserved) source of frustration and difficulty for me, until I recognized the problem and started working to address it.
I'm pretty ashamed of having behaved that way back then. I hope I'm better than that today. I guess recognizing the weakness is a good first step. Fortunately for me, back then I was on a really great team with a lot of very capable, patient, and talented engineers that waited for me to learn from my mistakes and to grant them the mutual respect they deserved. I consider myself pretty fortunate to have been able to learn from them what real software engineering is about.
Over my career I've had to work with people like this from time to time, software engineers that manifest one or more of these traits. Sometimes these guys are pretty talented technically. I've felt sorry for them as I've observed, realizing that these weaknesses are going to hold their career back until they recognize them and work to overcome them. No amount of programming prowess will compensate for it. And what's even worse is, often because these people have the personality issues they have, you don't get anywhere by trying to bring these weaknesses to their attention; they are often unreceptive to this type of feedback. Like I said, you just have to wait until they recognize it themselves.
I can imagine being in a performance review with someone like this, having them explain to me all the technical awesome they did, and me replying, "Your poor soft skills are shouting so loudly that I cannot hear your technical awesomeness." Or, as I said in the title, actions speak louder than code.
I really believe this is true. To write software professionally, of course you must have technical ability; however, this is a necessary but not sufficient condition for greatness. The best software engineers I've had the fortune to work with in my career, past and present, not only had awesome technical ability but did not exhibit weakness in these areas. And I'll tell you what: Those teams are wonderful teams to be a part of. Those teams create strong. uplifting work environments and are able to deliver great products that meet customer demand.
Another way to say this is, in order to be a good software engineer, you must first be a good employee.
In fact, I'll tell you how important I think this is. The ability to mitigate or eliminate these defects from a software engineer's persona is so important to me that, if I had my own company and were making the hiring decisions, I would not hire a candidate that I knew had these problems, no matter how incredible their technical ability.
A person with these weaknesses is really only suited to be set to the side to work on a special side R&D project where interaction with other employees is limited, and they don't have to interact with customers at all. Problem is, those kind of projects are either a) strategically important to the long-term future of the company, or b) of little to no real value, or c) a combination, often high potential value but with a lot of inherent risk that causes the real value to be low. If the project is strategically important or of high value, do you really want to reward the biggest jerk in your company by giving him the highest profile assignment, leaving your best engineers to maintain the legacy project? Wouldn't you want to have someone working on that high profile assignment that knows how to collaborate with others and assemble all the best ideas to solve the problem the best way, even if that solution isn't his/her own? Contrariwise, if the project is of little real value or has so much risk that it offsets the real value, why even do it at all?
Nope. In my company, if I were ever to have one, I wouldn't hire or keep an employee who had these weaknesses and was not committed to addressing them. I've seen the difference, both in morale and productivity, between teams where they don't have these problems and teams that do.
Programmers are Typists – And More
After reading Jeff Atwood's blog post "We Are Typists First, Programmers Second" on Coding Horror, I thought I'd better go see what my typing speed was.
I took the same online typing test that Jeff Atwood took, and managed to beat him:

We'd kinda hope that someone who writes software for a living could type with a reasonable speed. I'm curious to know if my mom, who types as part of her profession but is a non-programmer, could beat me.
Even more, I'm curious to know what my typing speed is when writing code. If you were to do a test like that, "mistakes" could be calculated by the number of syntax errors your code generates if you try to compile/run it. However, I'm not sure what a "word" would be, in calculating words per minute.
Surely your familiarity with the language would make a difference in your "speed." What I find a bit interesting about this discussion is that your typing speed in this case does not necessarily equate to your delivery speed.
For example, if you, like much of the computing world, are a Javahead, in my opinion you have a bit of baggage to overcome in order to attain a reasonable delivery speed. Java's mantra seems to be, "Why do something in one step when it can be done in two - or five?" Thus if you are a Java programmer, you've got some verbosity to overcome in order to attain productivity. Fast typing speed matters for you.
On the other hand, if you are a bit more sane and prefer a language like Python, the language is actually helping you out here. It is so easy to arrive at functional code in Python that perhaps the language makes up for typing shortcomings that a programmer might have.
What about a language like C? C is admittedly terse, but it doesn't do a lot for you because it is comparatively low-level. If you don't have libraries in hand to do what you need, writing them yourself kinda removes any advantage you may have gained because of the terseness of the language. Of course C is excellent based on other factors.
I do agree with the post though - typing is important to programmers. It is important for an additional reason - and that is because good software engineers should be expected to generate documentation - design documents, API documents, test cases, and SDK documents like tutorials and explanations of sample code. In short, there's a lot more typing to be done in a software engineer's job than just the typing of code.
Now, many of you are asking, so what does it mean if you type nearly 90 words per minute AND are not handicapped by a blind adoration for Java? What if you are a fast typist AND you prefer Python?
Well! That describes me quite clearly! And apparently, it means little. Sorry.
