I use spikes, periods of code-changing activity that end with no pushes, all the time, at small scale and large, as a way to develop my path. It’s a vital technique, and it’s often underplayed, so let’s spend some time with it.
What’s are spikes?
A spike is a stretch of time I spend mucking about in code, and that stretch of time has one rule: "Do anything you want, because you can’t keep it."
We originally used the term to describe a certain kind of story. We’d be facing some task without the slightest clue of how to perform it. So we’d put a story in place whose goal was "figure out how to do X". But we explicitly separated "figure out how" from "do".
The rationale here was based around our sense that practicing XP meant a certain rigor in our behavior. But maintaining that XP level of self-control can be difficult at times, and the most particularly difficult times to do that were times when we felt we had literally no clue.
We were basically authorizing "off-road" activity, and allocating space for it in our (now discarded) story-point-bucket planning approach. But if you’re going off-road, our reasoning was, that’s it. You don’t get to bring off-road artifacts back into the codebase.
Why were we so strong on "no off-road artifacts"? Because every one of us had been through the pain of having what we were told was a "proof of concept" or "prototype" shipped to the field and causing massive heartache.
So, in those days, a spike meant something at a large enough scale that it would be a blip on our productivity radar. "Figure out how/whether we could use multiple CPU’s to distribute the load". "Figure out whether NOSQL would be more performant." That kind of thing.
There’s an important idea embedded there, and letting it have its full flex actually brings me to my modern practice, of having many small spikes on a more or less daily basis. That idea is in this question: "If we don’t bring back code, what are we bringing back?"
Well, we’re bringing back "mind stuff". When we return from off-road, what we now have, what we didn’t have before, is a loose but real confidence in our path.
Now, at this point, I should say, I’ve been suggesting that all spikes yield positive confirmations. That’s, of course, nonsense. Sometimes when I do a spike, what I bring back is negative confirmation: "I now know this path won’t work."
Remember the Edison story, tho, where he says they didn’t fail 10,000 times in solving the filament problem, they succeeded 10,000 times in eliminating candidate solutions. Positive or negative, the point holds: we return with a better sense of path, a clue.
So let’s turn to my modern sense of spike. It’s really much smaller scale, not usually a story at all. It’s the idea of "go off-road, get a clue, throw away the typing".
I recently wrote a somewhat comical thread about spending 12 hours solving a problem that should have been trivial to solve. (It was by way of helping juniors understand that seniors are both more and less than we’re cracked up to be.)
What I actually did in those twelve hours, was run — not exaggerating here — about 30 spikes. Some were a few minutes long, some were nearly an hour.
Each time, I’d be making a code change, seeing if it helped at all. If it felt like it was close, I’d stick with it for a little while, tweaking it and running it. And then, every single time of those 30 times, I threw the change away. Literally, "git reset –hard".
Thirty is a lot. I don’t usually confront problems that were both this trivial and this hard to find a path for. I was pretty aggravated by the end.
A thing that may surprise you, about that end. On my 30th try, I got it. And you know what I did? "git reset –HARD".
That may trouble some of you, that I threw away the solution. If we stop the story right there, it sounds stupid and wasteful. But the 30th spike was the last spike, not the last action. The 31st step was to return to my on-road style and use it to create my on-road solution.
The value of declaring an activity a "spike" is in the freedom it gives you. While spiking, I’ll do anything. Add a variable called "x". copy/paste the same 3 lines five times. not write a test for something eminently testable. Really, anything.
But I don’t put just anything in my codebase. The internal quality of my code directly correlates to my productivity. The most important and readily controllable term of my equation for "what will I finish today" is nearly always "what will I start with".
That’s called the correlation premise, and you can see more about it here:
Five Underplayed Premises Of TDD | Video
So a spike, to me, is a technique I use for "pathing". It is the figuring out of how to do, not the doing itself. When I spike, I am, basically, thinking with code. And I don’t keep the code, I keep the thinking.
So, a couple of further points, then I’ll let you go.
1) I sometimes spike in a whole other app than the one I’m working on.
This weekend’s learning about splines was all done in a build I keep laying around just for this purpose.
This kind of thing can be useful to me when the eventual destination app has a bunch of parts that aren’t really relevant to my current problem. By working the problem outside that app, I get to skip dealing with all those parts.
2) I often roll an entire spike in a single test in my microtesting rig, JUnit in my most common case.
I’m using the test rig as an easy way to invoke code, not as a TDD thing.
I’ve been known to write five or six classes, inline in the test file, plopping it altogether so I can see it and change it rapidly, which, given its immature state, is helpful.
3) I (internally) declare a spike before I start it.
That is, it’s a conscious decision I make going in. I find that active choosing somehow calms my internal asshole. "It’s just a spike, not worth my time to tell him how stupid and ugly he is until he does the real thing."
But that’s not a pure rule. I watch my clock a lot when I’m working on-road. Sometimes, it runs long, in kotlin, say, 45 minutes between pushes. Occasionally, I’ll say, "okay, bam, this just became a spike, tho I thought it was on-road."
4) I spike refactorings, too, maybe even more often than I do in feature work.
To do anything, even at moderate scale let alone large, I rely heavily on a "green to green" approach. We talked about that with steps and value the other day.
The point of spiking a refactoring is to set the "green to green" path in my head. During the spike, I change anything in any order I think of. What I bring back from the spike is my sense of which of those changes clump into steps, and what order will be easiest for me to do.
So there you go. That’s me and spikes.
All of this is really implicit, btw, in the simple and charming apothegm: "Typing is not the bottleneck."
When I spike, which I do a lot, I go off-road, holding only one rule: you can’t keep any artifact you made off-road.
It’s a kind of "thinking with code", and I use it mostly to help me develop a loose but real sense of path, the steps I want when I return to the road.
The GeePaw Podcast
If you love the GeePaw Podcast, show your support with a monthly donation to help keep the content flowing. Support GeePaw Here. You can also show your support by sending in voice messages to be included in the podcasts. These can be questions, comments, etc. Submit Voice Message Here.