Imagine you're deeply focused on building a tower of cards, where each card placement demands precision and attention. Would it not be frustrating if every distraction risked toppling your carefully arranged structure? Consider how vital maintaining that tower is to your overall productivity.
This metaphor was shared with me by a friend some years ago. Intrigued by its simplicity and effectiveness in illustrating the need for focus, I've since used it frequently as a quick visual aid. Building a card tower requires patience and delicate adjustments to the environment. So, when a simple action like a door closing sends a draft that knocks down your tower, it's understandably aggravating.
In a similar vein, a developer's concentration is meticulously built with various elements and can be easily disrupted, just like a card tower.
It takes a lot of thinking to code. Every day is an opportunity to attain flow, or a state of complete focus, even though some days are better than others.
I want to stay in flow for as long as possible once I'm there. It's fun to be totally absorbed in my work, but it's not voodoo magic or anything.
Although many people have varied perspectives on flow, most agree that it's a moment when your finest work is produced. See for yourself by looking at some of the top Google search results for "software achieving flow." The significance of flow in software development is covered. Flow in Agile Software Development: What, Why, and How; How To Enter Flow State | Become A Productive BEAST!.
According to the articles, flow is the state in which you produce your finest work. From my experience, it can be the only thing I get done in a day, but it's not always when I do my best work.
It takes concentration to get into flow, and it's a challenging topic. A number of things can affect flow, such as how much sleep I've gotten, how demanding my work is, how much I get paid, the company's mission, and even whether or not I get along with my coworkers.
I've chosen to focus it only on the procedure of obtaining context (or information) on a defect in a piece of code in order to somewhat simplify the flow. Context gathering is an arduous and time-consuming task. I've tried to walk through the steps involved in a normal coding session in order to provide examples. Constructing a Tower of Focus is the first step.
The tower is composed of a peak, middle tier, and foundation. There are 15 cards in a basic 3-layer card tower. There are eight cards for the base, five for the centre, and two for the peak. The levels are titled "The WHY," "Trade-offs," and "Verify," in that order.
These cards all provide context for the work I'm doing. One card at a time, carefully leaning them against each other, I construct these layers.
The foundation layer stands for figuring out "the why," or the initial plan. I think that is the most difficult context to gather. I must ascertain the original idea behind the code before I can confidently make any changes.
What then does it look like to search for intent? Let's examine a segment of code.
It's very clear that the original author learned a few things while composing this. They've included a bunch of lines with comments (lines that start with //), so I can tell. I will begin to ask myself, why did they spend so much time and energy on this?
The realisation that this code is a little piece of a larger system and that any changes made to it may have unforeseen consequences higher up the chain is what initially surprises you. (It runs inside several for loops and is called from a spaghetti of methods).
I will need to read over each line if I am looking at a bug with this code. Variable names like n and reader, the minute variations in each if statement, etc. I am adding cards to my concentrate tower as I go.
To try to grasp what the original author was attempting to do, I'll look through tests, commit messages, or even have a conversation with them (if they're still alive). Determining original intent bears similarities to solving a murder case.
The exception to the rule is the above. It did, in fact, have comments. Typically, I'm presented with code that is similar to what was described above, except it lacks comments and has pointless commit notes. Since the code is triple nested for loop-heavy, my only option is to read it all to comprehend it.
It's only moderately tested, which makes things worse and leaves me in a difficult situation. If I alter it, I won't know if I'm detonating a land mine at the worst possible moment later on.
Do I put a lot of effort into making the tests better, or do I just cross my fingers, give it a quick test, and move on?
Every new discovery I make adds cards to my focus tower's foundation tier. I'm preparing to construct a 4-layer or even a 5-layer focus tower if the coding is even remotely complex. Assume for the moment that I just required three triangle bases, or three layers total.
Finding out what needs to be changed or what is broken and how to remedy it is the next layer.
Keeping with the bug-fixing example, I'll now delve into the specific code segments where specific log messages were printed. If you're a detective, you could think of a log message as the blood on the carpet—evidence or a record of a program's behaviour. Logs can provide a whole picture at times, but they frequently lack details and are partial.
I'll have to attempt to replicate the bug. I'll either use a debugger tool, which allows you to go through a programme line by line, or I'll add extra log messages. I'll add a few remarks or notes regarding its operation. I might adjust one or two variables to observe how they affect the program's output. I can usually identify or isolate the specific part of the code that is broken by repeating these steps a few times.
In the event that I'm fortunate enough to obtain a reliable reproduction of the defect, I'll need to identify a few compromises or workarounds. The more challenging issues can be resolved to varied degrees, but they basically boils down to 2 options:
An actual fix (which is time-consuming)
A hotfix, which is extremely quick but may break later
Most of the time, the company accepts the hotfix in order to expedite the resolution of the issue (that's a whole other blog article). It all stacks the cards higher in my tower, making it a real balancing act.
Making sure everything functions in production is the last layer. The software component that interacts with customers is referred to as production. Although adding tests is best practice, a developer's computer dry run of the code can occasionally suffice. It's crucial to keep going while the background is still clear in your mind and the layers are still piled on top of one another. You are the one with the most knowledge of the code at that moment, and you know how to fix it when something goes wrong.
In an ideal world, there would be no obstacles in my path as I went from the base layer to the intermediate layer and finally the peak. However, the truth is that my day is interrupted or filled with meetings.
Honeycomb's CTO, Charity Majors, sums up their practice philosophy well when she states, "15 minutes or bust."
Imagine that after a few hours of building my concentrate tower, a gust of wind strikes. A pause in action. I received a page to assist in resolving issue X, and it's quite "urgent" (using @channel in Slack to alert others and suggest urgency).
They've used the @channel signal, which indicates that an enemy has arrived and that war is likely to break out, so I feel immediately forced to assist.
In my opinion, @channel is superfluous 95% of the time and greatly contributes to the collapse of focus towers. The majority of tasks can be deferred until support meetings or given to the one person designated to assist that day. To distribute the work among several team members, shifts can be arranged on a rotation (see Pagerly for a simple approach to rotate @mentions in Slack).
My concentration tower starts to weaken as soon as these disruptions take me away from my task. You might as well simply point to a hair dryer if I'm going to be gone for an hour or more.
To be clear, brief disruptions lasting a few minutes are normally acceptable. I won't even notice if I go back to my work. Though I would contend that even with a slight prod, there's a good chance I won't immediately return to my previous behaviour. I'm going to check my email or see what people like on Twitter. The level of the decay increases with the amount of time it takes me to return to my original task.
What then are our options? The most crucial thing to remember is that disruptions are not free. Your coworker most likely set up do not disturb times or put a block in their schedule for a purpose. Treat each other with kindness.
On the other hand, when it comes to diversions, I'm frequently my own worst enemy. I've put up a list of items that have helped me concentrate.
If you deal with Slack interruptions in particular, check out my suggestions for minimising Slack disruptions for your team. It discusses how to distribute the interruption burden among your internal team members by collaborating with your frontline support teams. From there, I would advise making plans for disruptions by utilising Pagerly to create an on-call rotating shift schedule.
Moving my primary distractions, such Slack, Twitter, LinkedIn, or email, to a new desktop caused a small amount of friction. I have to hit a few keys to switch whenever I feel like looking at those items. It works nicely; the friction reminds me that I needed to focus. By reducing or completely closing the window, I've also increased friction even further.
One thing I find difficult is continuously monitoring my company's analytics. I made an off-limits red Chrome tab group to help me achieve this goal.
The group includes my analytics pages, Twitter, Slack, LinkedIn, and communities that I am a member of. I am aware that while I am deeply focused, I shouldn't open the group. Yes, I am aware that I could dismiss all tabs, but I often open websites again. I can better remember that they're my main sources of distraction when they're confined together.
I've also been attempting to follow Michael Lynch's advice to monitor metrics only once a week on Friday at the conclusion of the workday.
Lastly, I find that taking notes as I go helps prevent context erosion. My preference is to place a bash script with the extension ".zing" in every directory. I can put them next to the code I'm working on because my global git-ignore ignores it. Here's an illustration of one I worked on last week.
I use my.zing file for two things. It maintains a history of the last command I performed in addition to a list of tasks and notes. Upon my return in the morning, I may run the script, view the code's output, and immediately resume my previous tasks.
I use the command ",z" to run the script from my terminal or Vim using https://github.com/jewel/zing. I can also expedite my iterations with its usefulness.
It's a daily struggle to keep my attention tower intact and unimpeded by the torrential wind of outside distractions. It takes a team to put an end to needless disruptions, but when done well, it may significantly boost developer odds of attaining flow and increase productivity.