Live data from Hacker News

Only solve one new problem at a time

bennadel.com

61–70 of 73 posts

Re: Only solve one new problem at a time

#61
post #14

As a general rule, successful programmers have been doing this forever: - It works. You added 2 things. It doesn't work. Which thing broke it? - It doesn't work. You changed 2 things. It works. Which thing fixed it? - It works. Two people changed it. It doesn't work. Who broke it? - One donut left. 2 programmers went into break room. No donuts left. Who ate it? Now change "2" to "1" in all of the above examples. See…

- It works. You need to add 16 things. You add 1 thing at a time. 16 operations later you are good but the deadline has passed. Fired. - It works. Add 16 things. It doesn't work. Remove 8 things. It works. You've eliminated 8 culprits. 4 operations later done. Delivered on time. Get a promotion. - One donut left. 2 programmers went into the break room. No donuts left. Who ate it? Not any of the 30 programmers outside…

Having done this for a number of years now, I’d argue that your first point is based on a false premise. Adding each thing one at a time feels slower because you don’t get the frantic rush from doing 16 things at the same time on a tight deadline, but most of the time end-to-end it takes the same amount of time or less, because when something does break it’s super easy to look at the one thing you did and fix it without having to suck in the entire context of the 16 things.

If you’re doing all 16 at the same time and they’re not one liner trivial things, how do you even know where exactly the 8 from your divide-and-conquer strategy are? And can you actually back them out without further breaking things?

Re: Only solve one new problem at a time

#62
post #3

I slightly disagree with one point. There's not a better time/way to learn a new language than on a new/real project.

It depends on whether you're the one paying for someone's learning curve. You'll be much better off if you learn the fundamentals then use a real project to polish your skills than trying to learn from scratch with a deadline looming.

> It depends on whether you're the one paying for someone's learning curve.

When I was consulting, I would occasionally make a time box deal with the client. One project sticks out to me: I thought their project was perfectly suited to Rails at the time, but the majority of my projects had been done in Django. “I’m going to try building this in Rails. When I hit a 40h timebox, I’m going to stop, look at progress so far with a critical eye, and assess whether we’re getting value from this or not. If I don’t think so, I’ll abandon the Rails project and start over for free with Django.”

As it turned out, the whole thing was done in about 30h with Rails and we didn’t need to have the rest of that conversation.

Re: Only solve one new problem at a time

#64
Local: Transaction failed. Notified offshore team.

Offshore(next day): I see.

Local(next day): Process ABC threw an error.

Offshore(next day): We will look at A.

Serialize as much as possible. Take advantage of time zone opposition and asynchronous communication.

Re: Only solve one new problem at a time

#65
post #14

As a general rule, successful programmers have been doing this forever: - It works. You added 2 things. It doesn't work. Which thing broke it? - It doesn't work. You changed 2 things. It works. Which thing fixed it? - It works. Two people changed it. It doesn't work. Who broke it? - One donut left. 2 programmers went into break room. No donuts left. Who ate it? Now change "2" to "1" in all of the above examples. See…

My corollary to this is that bugs are a sort-of conserved quantity. For every 1,000 real* bugs found, 1,000 bugfixes are required. Bug report in, bug fix out.

The longer you delay fixing bugs, the more concurrent issues are present in the codebase. So then when you add a feature, instead of either having 0 errors or diagnosing a bug in 1 new thing, you now have to diagnose n+1 bugs, where 'n' is the number of unresolved bugs.

The more this is allowed to fester, the worse this becomes, to the point of hopelessness. I've seen a codebase with ~1K open crash bugs, and hundreds of memory corruption bugs. Developers were making things worse and convincing themselves that they were fixing things because randomly the memory corruption was less bad on that test run.

*) To make things simple, just ignore false bug reports for now. Pretend all bugs are real, such as "makes the program crash".

Re: Only solve one new problem at a time

#66
post #42

Although I agree with the general view of the article, the rule "If It Can't Be Done Incrementally, Don't Do It" does not always apply. I once had to refactor a large application from non-currency-aware to currency-aware. This means every single database field and every single operation involving prices had to be touched. Of course, I did not randomly jump around the code and instead tried to do it systematically. Bu…

> instead tried to do it systematically Exception proving the rule. Yes, sometimes for something as deep as adding currency you do just need to fully refactor BUT I think you're still doing it in the spirit of "One Problem At a Time" You were adding currency, not adding currency AND updating the date library AND touching up the unit testing mocking AND adjusting that CSS for the checkout button (or whatever equivalen…

Hm. All your examples depent heavily on the circumstances. For instance, if you have a team of coders working on the same code base, it might be preferable to do all these things in parellel and role them out together. I just think that "Do things incrementally" is not so an important advice as the formulation "If It Can't Be Done Incrementally, Don't Do It" suggests. I would rather say: "Prefer to do things incrementally unless you have a good reason to do it differently."

Re: Only solve one new problem at a time

#67
post #39

This post actually doesn't resonate with me at all (and I've always respected Ben). I feel like I'm constantly solving a multitude of problems and actively look for opportunities where I can introduce new tech that hits on multiple disparate streams at once (I have neither the bandwidth as an org or the personal time to operate in a different manner), typically coupled with other new tech; even that is orthogonal to…

I have the same reaction. Sometimes there's multiple problems that can all be solved at once, and it is like a force multiplier. Often it's from what you could call "outside the box" thinking, where you maybe take a totally different approach. For example, there's a bug in the login system, again. Ok, we could probably fix it, but this is an old system built by outside contractors (aka "built cheaply, but expensive t…

Doing things incrementally almost always feels more expensive. And sometimes it is. But it is always a net positive in the long run.

When you're starting those "replace X system" projects, what you're not anticipating is that half of those projects fail: they're either end up taking way longer than planned, or they don't get finished at all because they miss some critical requirements. The bigger the project, the more risky it is.

Your login system has two problems:

1. It has a specific bug

2. It has tech debt

The issue is that you're using current bugs as a justification to remove tech debt. Because, let me guess, you want to refactor, but you can't sell refactoring to the management.

Here's how management might look at your arguments:

> password resets work in a way that allows an attacker to effectively lock out accounts and do a DoS

Did it actually happen? I worked at a SaaS startup that had over 50K users, it had the same potential problem. It never happened. Side note: some security standards actually require this DoS vector to exist.

> Looking forward we have customers asking

And how far in the future are we looking? It might be years before it becomes a real problem.

You might be absolutely right in your desire replace the login system. Or you might be a perfectionist that's eager to solve problems that don't matter. The great thing about incremental process is that for a relatively small cost those risks go away.

Re: Only solve one new problem at a time

#68
post #67
post #39

Earlier quoted context omitted.

I have the same reaction. Sometimes there's multiple problems that can all be solved at once, and it is like a force multiplier. Often it's from what you could call "outside the box" thinking, where you maybe take a totally different approach. For example, there's a bug in the login system, again. Ok, we could probably fix it, but this is an old system built by outside contractors (aka "built cheaply, but expensive t…

Doing things incrementally almost always feels more expensive. And sometimes it is. But it is always a net positive in the long run. When you're starting those "replace X system" projects, what you're not anticipating is that half of those projects fail: they're either end up taking way longer than planned, or they don't get finished at all because they miss some critical requirements. The bigger the project, the mor…

> When you're starting those "replace X system" projects, what you're not anticipating is that half of those projects fail: they're either end up taking way longer than planned, or they don't get finished at all because they miss some critical requirements. The bigger the project, the more risky it is.

Totally agree! However, there are ways to do them successfully. I've done it many times.

There's no need to ever get into a position where you miss a critical requirement, let alone having it prevent completion. My favorite method is building replacement systems in parallel, leaving the existing stuff in place. Often there's a good opportunity to do a totally new feature this way first (maybe allowing you to increase your total addressable market), before you start adding existing features from the old system.

> Because, let me guess, you want to refactor, but you can't sell refactoring to the management.

Ugh. This statement grates at my soul.

First, let's deal with "want to refactor". Up front, as a technologist, I'll admit I do sometimes want to refactor bad code/systems/whatever purely because they're bad. However, as a professional, I know I need to justify that work.

This brings to the second part, "sell refactoring to the management". This is just not a conversation that I ever have.

If I am (or my team is) being slow due to constantly refactoring code, management is going to question what I'm doing and hold me accountable.

If we're slow and causing customer complaints because every time we touch code we add more bugs and start a break-fix cycle... management is going to question what I'm doing and hold me accountable.

What I do is look for spots where there's a provable return on investment (justification), and simply make that part of the next bug or feature we're working on. If you can take a system/component/whatever that is constantly getting bug fixes, spend slightly longer on the next fix (because you're refactoring) and then have fewer bugs after and/or be able to implement features faster, that's a win. Do it a couple times, and you'll never be questioned about this type of work.

The discussion around doing a large-scale replacement is entirely different, and the ways to justify it are using real numbers such as: potential to hit new market; time spent on support; time spent fixing (repeat) bugs; time it takes to implement changes; time spent fixing new bugs anytime someone modifies the system. Just like above, if you can't prove this, you shouldn't be doing it.

>> Looking forward we have customers asking

> And how far in the future are we looking? It might be years before it becomes a real problem.

Let me clarify my sentence: "Looking forward in the backlog, we currently have open customer requests.."

I agree with the sentiment I think you're getting at, which is you shouldn't build to unknown future requirements. You'll pretty much always get it wrong. I teach this to juniors with an analogy like: If you build a foundation for a skyscraper before you actually need a skyscraper, what you'll often find is it needs one more underground parking level than you thought and to be rotated by 15° -- so everything you built is not just wrong but is actively blocking you from building what you need.

> You might be absolutely right in your desire replace the login system. Or you might be a perfectionist that's eager to solve problems that don't matter.

Let me just be clear, because I wasn't originally, that my "login system" was a fictional example. The real examples I have require too much time to explain adequately.

> The great thing about incremental process is that for a relatively small cost those risks go away.

The point is sometimes a rewrite makes more sense because it solves several problems at once. This is where I take issue with the original article.

You hit on the reasons a full out rewrite fails: Not understanding all requirements. Doing a switch without backwards-compatibility. Going months/years without delivering value.

At least I think this is where we align again: The key to a successful rewrite is building incrementally, delivering value as quickly as possible.

Re: Only solve one new problem at a time

#69
post #14

As a general rule, successful programmers have been doing this forever: - It works. You added 2 things. It doesn't work. Which thing broke it? - It doesn't work. You changed 2 things. It works. Which thing fixed it? - It works. Two people changed it. It doesn't work. Who broke it? - One donut left. 2 programmers went into break room. No donuts left. Who ate it? Now change "2" to "1" in all of the above examples. See…

- It works. You need to add 16 things. You add 1 thing at a time. 16 operations later you are good but the deadline has passed. Fired. - It works. Add 16 things. It doesn't work. Remove 8 things. It works. You've eliminated 8 culprits. 4 operations later done. Delivered on time. Get a promotion. - One donut left. 2 programmers went into the break room. No donuts left. Who ate it? Not any of the 30 programmers outside…

I like this, especially the first point. I would just like to point out that the "fired." part doesn't have to be a real threat, a perceived (or even subconscious) threat is sufficient to generate the effect.
Post reply on HN