David McKnight on Firefighting no more
My team has recently grown much bigger. I decided we needed to make sure our daily standup stays productive and happy and smell-free.
There’s loads of reading to be done on how to do this – just google “scrum smells”. Here’s my advice. I’m pleased to say my team is doing most of this pretty well. I’ve been in some horrific standups in my day, so I’m pleased to see it working well, and I’d like to keep it that way.
My top points for avoiding a smelly standup:
1) Don’t talk to the Scrum Master!
He doesn’t care. Well, he does, but this isn’t a report to Sir. It’s an update to the team. If only the Scrum Master is interested, tell him afterwards. If what you’re saying isn’t of interest to the team, stop talking.
Practice making eye contact with team members. They’re nice people! Probably.
Following on from the above – when someone’s talking, it’s for your benefit. Make an effort to understand how it fits in with your work.
If it’s about “server stuff”, this is a great time to learn about server stuff; you might be working on it next week.
3) Stay concise.
My team is good at this, actually. But it’s easy to ramble off the track. We have to remember that it’s an update, not a problem-solving session. We’re lucky enough to be co-located, so we can easily carry on a technical conversation after the standup’s done.
4) Be prepared.
If nothing else, check the scrum board five minutes beforehand and make sure you know which tasks you’ve been working on, and what you could pick up next.
If the tasks don’t match reality, change them, either before or after the standup. Adjust estimates. Add new tasks. Check with someone before making big changes, but the board should update reality as far as possible.
If you’re going to miss a standup, tell someone on the team what you’ve been doing, so they can speak in your stead.
5) Everything else.
Here’s some links with more words on, some of them are interesting:
There comes a point in a software project where the developers swap their keyboards for hoses, their chairs for fire engines, and their scruffy shirts for full-on protective gear and a nice shiny yellow helmet. Yes, it’s time to go firefighting.
It doesn’t always happen, but I bet pretty much every programmer has experienced it. Usually, it’s just before the first big release of something. Your product’s been specced out and dev tested, incrementally developed, and the product owner is delighted. Then, a week before it goes live, someone notices something nasty. They look in more detail – it doesn’t meet the requirements. They notice some bugs, and a security flaw nobody’d thought of.
Back to the team, interrupt the current sprint. Each bug is urgent, some are really complicated. People start talking in low, urgent voices. The fix to the first problem has raised some others – functionality needs altering. The team probably switches to Kanban for a few days, or a few weeks, or a month. Each one coming in is triaged, assessed, and
This is firefighting – not developing, just stopping it all falling apart. Any fix will do if it works (the smarter teams will at least log Technical Debt tasks, I hope) but we have to get this out the door, so man the hoses and get firefighting.
So, what’s the problem? It’s that this type of work is not good. We joke that for every fire we put out, we make two more – dark humour, because it’s actually true. We’re making technical debt. We know very well that this situation was avoidable (exercise for the reader: ten ways to avoid firefighting).
Real life firefighting, however, is brilliant. It’s done by brave women and men who put their lives on the line, usually because of someone else’s problem. Firefighters are cool. They’re fit, and sexy. We all want to be firefighters.
But we’re not firefighters. What we’re doing isn’t saving kittens from car wrecks or toddlers from house fires. We’re doing something monotonous, pointless, wasteful, avoidable, and ultimately, if we don’t get out of it soon, futile.
From now on, the term “firefighting” is banned. What we are doing is *mole-whacking*.
Whack those moles all you like, there will be more. And nobody will be impressed.
Rules of the Scrumweasel
- The Scrumweasel sniffs out Weasel Words.
- The Scrumweasel says nothing – just looks at you with its beady little eyes.
- Only you know if the Scrumweasel is looking at you.
- No team members should acknowledge the Scrumweasel.
- The Scrumweasel is not interested in your excuses – even if they’re perfectly valid.
- Keep the Scrumweasel happy – just don’t make eye contact!
Beware the Scrumweasel!
Nobody knows, in truth, where the Scrumweasels comes from. Some say they are drawn to the positive energy created by a team trying to succeed in the turbulent world of Agile development. Others believe they feed on the remains of abandoned Post-It notes.
Imprinted in the Scrumweasel’s brain are the Rules of the Daily Scrum. Just as a pig can hunt for truffles and a chicken lays eggs, a Scrumweasel understands the three questions that each team member must answer:
- What did you do yesterday which advanced the project?
- What will you achieve today?
- What hurdles stand in your way?
Their highly developed noses sniff out Weasel Words in the Daily Scrum. Words such as:
- “Nearly done” (which means “not done”)
- “soon”, or “probably later today” (which means “tomorrow”)
- “I’ll see what’s on the board” (which means “I haven’t looked at the backlog for a while”)
Upon hearing Weasel Words, the Scrumweasel does not react – at most, it will glare at you for a while. It’s not interested in your excuses, of course – even if they’re valid.
But if the Scrumweasel turns its eyes on you, then you – and you alone – will know.
It’s difficult – nay impossible – to avoid the Scrumweasel’s gaze entirely. But you can keep it placated. Try some of these:
- “This task is not yet done. I still have to do the unit tests. It’ll be done by lunchtime.”
- “This task is not yet done. I’m stumped. Can anyone help me?”
- “By the end of the day I will have finished the coding, but not the testing.”
- “I’ll pick up the logging bug, if it’s still available.”
There’s always room for improvement – the Scrumweasel understands this – and it visits good teams as well as bad. Ultimately, just like a little whiskered Avatar of Agile, it hopes to inspire us all to be just a little bit better than we were before.
Working with a new company presents a million subjects which would be great material for a blog post. From the trivial (when to go for a coffee, and how often) through the important (differing implementations of agile development) to the absolutely vital (what’s the least ironing I can get away with without seeming scruffy?).
Our new project gave us the opportunity to start a fresh code base; using C# was an obvious and clever move. Despite being much younger than C++ it’s more of a “grown-up” language; still providing flexibility whilst removing some of the painful tedium.
It’s been barely a week since I hit the coal face. Here are just some of the things I’m getting to grips with:
- “internal” keyword. It smells nasty … but it sounds so useful! I’ve used it, but it makes me feel dirty. Sure, it’s better than “friend”, but does that make it OK? Rabbit poo is better than cow poo, but they’re both still poo. When is it acceptable, and when does it just break patterns?
- Unassigned objects are still null. OK, the compiler will catch it, but “MyObject object;” will not be useable without either assignment or a null check. Why? Do I really have to type “MyObject object = new MyObject()” every time? Isn’t this the common case?
- … although the whole concept of null in C# is pretty handy. Gets you 90% of the useful functionality of having a null pointer in C++ with a fraction of the pain.
- System.CollectionsGeneric, and specifically List<>. For better or worse I’ve been in the habit of habitually using std::vector for everything under the sun in C++. Is List<> better? I guess so, but I don’t yet understand the differences with any real subtlety.
- “using”. Namespaces bring back bad memories of Python. I suppose they have a purpose, but I’m not yet familiar with them. What do I need to be “using”? It’s never clear; with “include”, you can be confident that if you want to use the Starbuck class you just need “#include starbuck.h”.
None of these things are criticisms of the language – more an expression of exasperation. I think I’m coping well though – I’m pleased to finally be making the transition, and it shouldn’t be hard to get up to speed.
Ask me in a year’s time and I’m sure I’ll understand more – and also some of the many Rumsfeldian “Unknown Unknowns”. I lack the knowledge to even ask some of the questions.
But that’s good. Like a scarred, leather-clad Carthaginian warlord, turning up to the first ever Atlantean Annual, I’ve got a lot to learn – but half the fun is in finding out just what it all actually is.
There’s things I can do to be more confident in my learning. An emphasis on unit testing, for example, or encouraging more functional and automated testing in all aspects of our new project. I could go on to talk about the advantages of comprehensive code tests & reviews for a new starter, or for fluid development roles within a team more generally … but maybe that argument can wait for a week or two.
“Nothing endures but change”, wrote Heraclitus in around 500 BC. I doubt he anticipated modern software engineering practices, but the man had a point. Teams change, requirements change, products change. Our process as software engineers must also change. We talk of “Agile development”, which conjures images of responding to outside change – but our practices themselves must also be constantly reviewed, to cope with external changes as well as to strive towards perfection.
Heraclitus also wrote: “You cannot step twice into the same river; for other waters are ever flowing in”. In my case, I’m stepping out of one river and into another. Tomorrow is my last day with my current employer.
I’ve been here for 11 years, which at the same time seems like forever and no time at all. It’s been a real pleasure working with my excellent colleagues. I’m proud of what we’ve achieved together – we’ve made some really cutting-edge software. I’ve played a small part in the process of revolutionising scientific discovery (and made some pretty pictures along the way).
I’ve been writing this blog in order to put my own opinion out for discussion, and I see no reason to stop now. Talking about stuff is the first step towards changing; discussing the last river can help us anticipate the next.
So, what do I hope my colleagues will do after I’ve left?
- Communicate. Talk more, consider everything, let nothing be so sacred that it can’t be discussed. I don’t mean argue (although a good argument, well managed, can be a good thing). I mean, challenge current behaviour. Talk about it in chatrooms, in blog posts, in the kitchens, in the pub. Come up with new ideas and write them down. Get people invested in a product and its processes.
“Opposition brings concord. Out of discord comes the fairest harmony.”
- Be adventurous. We’ve done our best work when we’ve stuck our necks out. Talk about it first … then do it.
Nobody gets excited by blandness. Choose not to do things because they are easy, but because they are hard (and I bet Heraclitus never anticipated the moon landings).
- Don’t be good enough. That’s not good enough. Be good.
Writing software to a list of specifications is not sufficient. Do you have a list of checkboxes, features which your software must have? Don’t do that. It leads to software which is described as “functional”. The stuff that gets given away free with hardware.
Think instead: Is this good? Will the user be pleased? Will they laugh at their colleagues when they complain about inferior software? Will they barely notice all your hard work, because your software just does it right? That’s good software.
Well, if nothing endures but change, then all art is transient. My own opinions are just a voice from the past to my colleagues, so ignore them or consider them as you will (I’m sure you were going to anyway).
It just remains for me to thank everyone who’s been reading this blog, and listening to my meanderings, for your time and attention. It’s been great having a platform, and I encourage you all to do the same.
Talk; take risks; be amazing. Cheerio!
Jenga has its time and place. It makes a great drinking game; we’ve played it (dry) at a recent Company Mandated Funtime day outside the office. I’ve played a brilliant variant involving improvised storytelling and poetry (better than it sounds).
But it’s a rubbish game to play in conjunction with computer programming.
The fun of Jenga is the anticipation. It’s going to end in disaster (especially the drinking variant, natch). With each turn we hope our brick will balance perfectly, and that another player’s will not. There’s some skill involved, but ultimately it’s about waiting for someone to make a mess of it. Then follows laughing, pointing, and occasional appearances of that “Loser” hand-on-forehead thing (depending on company).
Working with old, legacy code brings with it the spectre of Jenga Methods. This concept has been around in the programming community for literally hours (at time of writing), and we came across one such Jenga Method during our Bugs Postmortem session this morning.
The method is old, long, and complicated. It’s also vital. It’s responsible for displaying almost all of our images, in dozens of key customer-facing parts of our software. It’s called many times a second and without it our application wouldn’t function.
This weight of expectation is felt by every developer who has touched it over the past ten years. It’s grown more complicated, full of comments and convoluted logic paths. Each developer has made the minimum changes to fix the problem, then held their breath, waiting for the wooden blocks to fall.
A logic path contained an error that was uncovered in our last sprint. The developer fixing the problem fixed the error, but didn’t touch the rest of the method – a Jenga player touches one brick at a time.
This isn’t great in the short term, and it’s terrible in the long term. The method needs refactoring, rewriting and redesigning. This is a difficult task that’s always made easier with a comprehensive suite of unit tests, covering all the expected functionality in all circumstances.
You can probably see where I’m going here – we don’t have that suite. The method isn’t covered. Just typing that sentence makes me nervous. Why not? There’s some complications, of course. The method deals with rendering images, although that’s not the killer – the objects are such that we could pass in dummy images and render them to a dummy context.
Rather, the unit test framework just doesn’t exist for that part of the software. It’s something we just “haven’t got round to”.
So … no happy ending, not yet. The best we can do is accelerate our unit test coverage; add the mechanisms for unit testing this bit of code; and add tasks to our feature tracking system to make sure we refactor this code when we can feel confident to do so.
Today, it’s just one more brick on top of the tower. Careful, now.