Friday, 15 April 2022

Effective Knowledge and Experience Handovers

Over the last two months I’ve been working my way through a handover process as I prepared to leave the company where I’ve been working for the last eight years. This got me thinking a lot about what is a handover and how can it best be executed…

What is a handover?

The traditional view of a handover is where the employee who is leaving directly trains their replacement(s) in all the aspects of their job. However, for me this raises a number of questions and concerns:

  • Why is the knowledge and experience of the leaver not already spread among multiple people in the company? Running with silos of knowledge owned by a single employee is a high risk strategy: that employee may suddenly be taken critically ill or suffer a serious accident.
  • Why is much of the knowledge and experience of the leaver not already documented in diagrams, playbooks or procedures? Having details stored only in employees’ heads and in their rough form notes prevents the easy transfer and preservation of that knowledge and experience.
  • What if there aren’t any direct replacements to handover to? It may have been impossible to recruit a replacement in time or the department may be restructuring and the leaver’s role may no longer exist going forward.
  • What if the replacement has a different set of skills, experience and perspective on how to undertake the role? There may be better ways to do the job that the leaver hasn’t explored and just indoctrinating the replacement to do exactly what the leaver did is likely not the most effective approach to move forward with.

Clearly this traditional approach of taking someone new and just showing them how to do your job isn’t effective. So, is there a better approach and what should it be? Having gone through the process, my definition of an effective handover is now:

To ensure that knowledge and experience are preserved and communicated in such a way that they are accessible to everyone within an organisation, even those that arrive after the source of that knowledge and experience has departed.

Therefore, by definition this suggests that handover is more about producing durable materials and resources (as well as conducting direct knowledge transfer between individuals).

Types of knowledge and experience

While working through how best to communicate and preserve my knowledge and experience it became very obvious that this information was divided into two very clear categories:

  • Explicit knowledge and experience - that which is clear and without vagueness or ambiguity.
  • Implicit knowledge and experience - that which is understood but not described clearly or directly, and often using implication and assumption.

How these two types of knowledge and experience are identified and dealt with in a handover are very different.

Explicit knowledge and experience

Ideally in a well functioning engineering team this explicit knowledge should already be captured and widely used, so there should be a minimal need for handover in this area.

Examples of how this explicit knowledge is captured include things like:

  • Having architecture diagrams and descriptions that are kept up-to-date as the system landscape changes.
  • Having a record of key architectural decisions, why they were made and what alternatives were considered.
  • Having documented processes where these are necessary. Examples of these include:
    • Processes for onboarding new team members
    • Definitions of done
    • Process for releasing code to production
    • Escalation processes for any production incidents
  • Having Engineering Guides and Playbooks that detail things like how to configure systems, housekeeping tasks, build pipelines and so forth.
  • Readme files in code repositories that detail what they do, how to build and use them, key dependencies etc.

If these are not already available then the first stage of handover work should always be to ensure that any of this explicit knowledge that the leaver is holding is captured. This likely involves a fair bit of document writing, updating knowledge bases and so forth. It’s also wise going forward to ensure mechanisms are in place within the team to ensure that this situation doesn’t occur in the future!

There is also great value to just surfacing and sharing this explicit knowledge. Some members of the team may not be aware of certain topics, others may have forgotten. There may also be team members who perhaps learn better from verbal communication and interactive sessions than from reading documents.

I found great value in being able to do interactive handover sessions, drawing on whiteboards, looking through code and so forth. This provides the team with good context on each subject which they can now use as a primer for diving into the more detailed information captured in the diagrams and documents.

An additional benefit I found when doing interactive sessions was that often a question or discussion topic would arise that I realised wasn’t already captured somewhere. This then highlighted the need to go back and improve on the store of knowledge, to ensure that assumptions or omissions became part of this explicit information set.

With hindsight there would have been great value to recording these interactive sessions and including them within the explicit knowledge set as well so that people not yet part of the team could utilise them as part of their onboarding process.

Implicit knowledge and experience

This part of the handover process is much more challenging. Most people, after working in a job for a long time, will have things that they just ‘know’ without realising that other team members may not ‘know’ the same things.

Some examples of this implicit knowledge and experience include:

  • Handling a support issue and being immediately able to point to the cause of the problem.
  • Seeing a particular error line in a log and being able to go to the exact module and piece of code that is the likely root cause of this issue.
  • Getting a vague requirement from a customer and immediately understanding exactly what it is they are asking for, because someone asked the exact same thing in the past.
  • Doing an admin task that seems so trivial that it just never occurred to write it down anywhere.
  • Subconsciously following a process from the past that may not have been effectively communicated to newer team members.

The big question I focussed on as part of my handover was how to actually identify this implicit knowledge. In the end I came up with two specific techniques that I felt worked well for me:

The first approach was a forensic analysis of emails and our issue tracking system. I found great value in the ‘sent mail’ folder looking for conversations that I might have contributed ideas or opinions in. The history of tickets in the issue tracking system was also incredibly useful. In particular I focussed on tickets raised by support and internal defect tickets; those where I had collaborated but not directly owned were a particularly good source of implicit knowledge.

The second approach was much more of a meditative one. Firstly I spent time thinking over all of the tasks that I carry out on a day-to-day basis, with a focus on both periodic and adhoc items. Replaying questions from the support team was also very useful. Secondly I made a list of all the projects that I had worked on and did the same exercise, thinking over any previous admin, support work and conversations with customers.

A small number of items that came up from these approaches were clearly explicit knowledge that just wasn’t captured, so this was added to the appropriate places. The remainder were very much things that were known, but vague and rather undefined. Clearly people should be aware of and have a ‘starter’ should it become necessary to work on them. However none of these additional items were clear enough to make explicit or significant enough to require dedicated interactive handover work.

Capturing these implicit items was where Playbooks really came into their own. For each identified item I was able to create a section that considered:

  • How does the item get noticed, reported or spotted?
  • Are there any particular times or schedules that are appicabvle to the item?
  • What are the symptoms that might point to the item? How might these manifest themselves?
  • Has this item or question occurred in the past? How was it resolved then?
  • What resources or information are needed to investigate or diagnose?
  • Where should someone start looking?
  • What are the possible answers or solutions? Have any been considered or discounted in the past?
  • Are there any new processes that could be documented?
  • What further information would be useful to capture so that implicit items could be converted into more explicit knowledge?

At the end of the process I was able to provide a Playbook of ‘starters’ to help future team members who encounter similar or closely related items from having to start from scratch.

Conclusions

A quality handover should include three elements: make sure all explicit knowledge and experience is captured; carry out interactive sessions to provide context and an entry point to this explicit content (ideally record them and add them to the content); and identify implicit knowledge and experience as record this as Playbook ‘starters’ that are available for team members to build on in the future.

My handover process was also a welcome reminder to make sure that explicit knowledge and experience is captured and updated continually. Don’t leave it until someone is leaving the team before you start generating diagrams, documenting processes and creating Playbooks for important activities.

Saturday, 12 March 2022

The Value of a Safe and Open Interview Process

I’ve recently been interviewing for a new role. During this time I went through the interview process with three different companies. Two of these I already had in progress before finding the third role (which was the one I really wanted). Each offered a very different approach to the way they structured and conducted their interviews.

At the end of these processes I had very different emotional feelings about each of the three companies and roles. This got me thinking about what factors resulted in these different emotional responses.

Company A - Traditional Interview Process

This company had a fairly traditional interview process divided into four stages:

  • An initial short chat with a member of the Talent Team to make sure that the role was a good fit. There’s no point in pursuing an expensive and time consuming series of interviews if the role is not a good fit for the candidate or visa-versa.
  • A technical interview with two Engineering Team members talking through experience, knowledge and approach, with a few technical and design questions along the way. This also acted as a chance to discuss and ask about engineering culture.
  • A problem interview, which for this company was conducting a code review on an example pull request. This was carried out in a low-pressure way where I was given time to do the review without the interviewers being present, followed by a short discussion of the points I had identified at the end. (Kudos to the person who wrote the code to review, it was a masterpiece of how to cram as much bad coding and design practice as possible onto a single page!).
  • A final chat with the Engineering Manager (which I didn’t complete as I had already accepted one of the other roles by this time).

Overall I came away from this interview process feeling fairly neutral about both the company and the role. There was nothing that made me feel uncomfortable or unsettled, but at the same time I didn’t come away from any of the interviews feeling super excited or energised by the process.

They created an environment where I was able to feel fairly open to answering their questions, but still feeling that there were certain questions that they wanted to hear me give model answers to and others where the answers had to be correct.

I expect that this is the default experience for many people as they go through the process of finding their next role, but is this really the best we can do?

Company B - Toxic Interview Process

The second company I interviewed with had an interview process that I can only describe as toxic. I made it to almost the final stage of these interviews, but after my experience, there was no way I would have wanted to go and work for them anyway (even though they were the most high profile and highest paying of the three roles).

First off, before you could even enter their interview process you had to complete an online, timed, coding exercise. This involved two tasks where you are presented with a short problem statement, an empty code template and a set of unit tests (most of which you can’t see the inputs or expected outputs for). You then have to code up a solution that solves the problem and makes all the unit tests pass. All this takes place in an environment with a big countdown clock in the corner that ticks away your remaining time.

In my experience, there are very few people who can just sit down and pick up coding kata problems like these and produce great results. In order to be successful you have to have practised many times on similar tasks before actually taking the test. These practices also get you familiar with how the site doing the testing works, how it describes its problems, what sort of things it tests for and so forth. The net result is that to be able to pass the 90 minute test you also have to additionally invest a number of hours of practice time as well, and this is before you even know if the company or role is a good fit or not.

I also have some very specific complaints about these sort of logic/coding puzzle timed tests:

  • All they prove is that you are good at logic/coding puzzles - they bear little resemblance to most of the engineering you will actually be doing in your job.
  • A lot of them require you to just ‘see’ the solution, and, if for that particular problem, you don’t have that immediate insight, then it’s almost impossible to complete a solution, as you just don’t have enough time to work through it and create working quality code.
  • Some people who are great engineers just don’t thrive in situations where there’s a countdown timer or someone watching their every keystroke.
  • These tests may also exclude people who feel less confident or a bit anxious from even being able to access the interview process at all.
  • They can create stress and discomfort, especially if the candidate is struggling with the particular problem they have been presented with and the clock is draining away.
  • Unit tests where you cannot see the input or the expected output, only that they are failing provide minimal value or oppertunity to improve your solution and just add additional stress and pressure.

So, I did manage to pass this initial screening test. Even though my first impressions weren’t great, I decided to continue with the process just to find out more about the role, team and company - you never know, it may just have been some poorly considered HR requirement.

The next steps were multiple technical interviews with various Engineering Team members that all followed a similar pattern:

  • A brief discussion about the role or some aspects of the project or engineering culture.
  • A bunch of fairly detailed technical questions covering skills and previous experience.
  • Yet more logic/coding exercises carried out live with the interviewer(s) watching and commenting on every line you wrote and expecting you to both code and narrate your thought processes as you did so.

There were a number of aspects to these interviews that turned them into a hostile and stressful environment:

  • When discussing projects or processes the interviewing engineers came across as acting in an incredibly superior way, sometimes sneering if your answer wasn’t perfect or you previously haven’t been working to the specific ‘variation’ of scrum that their teams have adopted.
  • They presented a demeanour of making you feel small or unworthy if you didn’t immediately know the Big O notation for a specific sort algorithm or couldn’t immediately code out a fully working, super efficient implementation of their chosen logic/coding problem.
  • I got the feeling that often they were trying to catch me out and just waiting for the moment to pounce: especially if I gave a slightly wrong or incomplete answer to one of their questions.

The result of this sort of interview approach is that I started to feel stressed and pressured. Every question became a panic decision between do I give the answer I thought was right vs the risk that the answer might be wrong vs admitting that was something that I didn’t fully know. Rather than opening up to them I was being forced to close down. Ultimately I just didn’t feel safe or supported in that interview environment, started to doubt my own abilities and began to become flustered and unable to answer or write code any more.

At the end of each interview, the overwhelming emotion that I experienced was one of relief that the ordeal was over. No excitement about the role or the company was generated: just relief. After the final interview with them I was left visibly shaking from the release of stress tension built up over the duration of the interview.

Edit: Having thought about this more, I'm sure that this company didn't set out to create an interview process that created these emotions. I believe they probably have the goal of selecting only the very best technical candidates. Their selected solution for doing this was to focus heavily on processes that test primarily for technical skills. The unintended side-effect of this being that they have less time to focus on cultural fit and empathy for the candidates. /end

If that’s their process for finding the ‘right’ people, what would they be like to work for? A culture that encourages that sort of pressure on interview candidates surely isn’t an enjoyable, safe and supportive place to work? Would the type of people who were actually able to make it through the recruitment process be the kind of people I would want as my future colleagues?

In the end they decided not to continue with the final stages of the interview process with me. I wouldn’t have gone for another interview with them anyway. I’ve never been happier to drop out of the running for a new job!

Company C - Safe and Open Interview Process

The final company I interviewed with followed a process that was a world apart from my other two experiences. This process was probably the most detailed and time consuming of the three, but every aspect of it was thoroughly enjoyable, engaging and enlightening.

First off was a chat with the Engineering Manager who I would be working with. This was about as far away from a technical interview as you can get. We just chatted. He spent a lot of time telling me about the company, the product and the culture. Then I was asked a simple question (I can’t remember the exact words, but it was something along the lines of): “What’s your first impression, what excites you about this role?”. What a great way to assess a candidate. If they aren’t excited by what they’ve heard then why would you want them in your team? As a candidate, if the role and culture aren’t exciting then would you really enjoy working there? Would you grow? After that we just chatted generally about experiences, background and so on.

Particularly interesting was that the chat was conducted in a way that felt safe. It was easy to open up, admit answers I didn’t know; ask questions that might seem strange; talk about times when things I did went wrong. The overall feeling was that the interview was about getting to know each other rather than trying to judge. I finished this step excited and already knowing that I really wanted this job.

The next stage of their process was a take-home exercise. I know some people aren’t a fan of these, but I’ve always found them to be quite an enjoyable way to demonstrate my abilities. If they are structured right then they allow you to show problem solving, technical approach and code that is realistic to what you would typically produce (as opposed to trivial/funky/clever code that solves a specific logic problem).

In this particular case the exercise was closely related to their product, so it almost felt like you were already working on something related to the job. The exercise was timeboxed to three hours (which is often a criticism of take home exercises that are open ended and thus candidates feel they have to dedicate a huge chunk of their life to completing them). I spent a day mulling over the problem in my head then sat down over a couple of sessions and produced my submission. I was really enjoying the problem so I even carried on for a few more hours after submission to improve my solution and solve a couple of little areas that I hadn’t quite got right.

My submission was reviewed and I was invited back to the next stage of the interview, which was to talk about what I had done. This was carried out with two members of the Engineering Team that I would be working with if successful. Again this was conducted in a way that was structured to be entirely safe and open. They seemed really interested in what I had done and how I had done it - not some kind of faked interest, but genuinely interested. At no point was there ever any judgement on the approach taken, it was always a discussion on the reasons and the thinking behind a particular approach or technique.

Feeling comfortable and secure, I found it easy to be open and honest about where I had made good or bad decisions and how I would do things differently as I iterated over the solution. This enabled much more discussion rather than it being a question/answer driven session. I was not only able to get a sense of how they worked as a team and how strong their engineering practices were, but also who they were as people - something that’s generally really hard to get during a typical interview.

Next up was another session, this time on talking through how I would go about solving a particular engineering problem. Again this was a problem relevant to their domain and product so it felt like I was actually working with the team rather than being assessed. This was also another great example of creating a safe interview space where it was easy to be open and explore different avenues. No suggestion was wrong or dismissed, I was free to explore avenues that didn’t go anywhere or solutions that might be a bit unusual. It was easy to ask questions about what might or might not be possible. The discussions were all about the directions taken to solve the problem, why they might work or not and how my thinking process worked to get there. Again this was very much a two-way process of how I would fit in with the team but also how the team would work with me.

I left both of the above sessions feeling even more excited about the role, excited about the people I would be working with and with a sense of comfort that I would be able to bring skills and ideas that would enrich the team and that I would get the same in return. That’s a really positive feeling to leave a technical interview with!

The final interview stage was back with the Engineering Manager again, this time with the Product Owner involved as well. Again this worked as much more of a discussion process rather than an interview. The PO was able to enthusiastically talk about the product and the vision for the future. There were ample opportunities to ask detailed questions and discuss thoughts. Finally there were questions around how I think about products, user experiences, technology and so forth. Again this was all conducted in a safe space where I felt at ease opening up with my thoughts and where I felt comfortable giving detailed answers and my reasoning behind them.

Overall this interview process was amazing. At every point in the process I felt able to give open and truly honest answers. After each interview I felt energised and excited. Suffice to say, when they offered me the position I jumped at the opportunity and I can’t wait until I join the team. In fact, I already feel part of the team just from the interview process and that’s a great feeling.

Conclusions

Thinking over my interview experiences there’s a few good takeaways that should be part of every organisations’ interview process:

  • If an organisation can’t excite a candidate or the candidate can’t excite the team then the two may not be a good fit.
  • Creating a safe interview space will encourage candidates to be more open and honest with their answers, offer up more details and be more likely to ask deeper questions. Both parties learn so much more about each other.
  • Conversely, creating an interview environment that is hostile and stressful will discourage candidates sharing honest answers, will limit how much you can learn about them and ultimately will prevent them wanting to join your organisation
  • Some exploration of technical skills and experience is always relevant but ensuring the candidate is a great fit to the team culture personality wise is far more important,
  • During the interview, make the candidate part of the team and work with them as such. You will learn much more about who they are, how they work and whether they are a great fit than if you treat them as an outsider to interrogate.
  • Empathy with the candidate shows that the team they will be joining cares, and for great people that’s often a far bigger selling point than financial rewards or interesting technologies.

Tuesday, 4 March 2014

The Importance of a Good Shard Key

In MongoDB (and many other database solutions) scalability is achieved by dividing your database into a number of smaller portions. Each portion is stored on a separate set of database nodes. The theory is that this approach allows your database to scale horizontally beyond the capacity of a single node and allows load to be spread more evenly across multiple clusters of nodes. In MongoDB this approach is known as sharding (many other databases call a similar concept partitioning).

When you deploy shards in MongoDB you have to select a field (or fields) that are present in each document as the shard key. The value of this field determines which set of database nodes holds a specific document. If you get this key selection wrong then the impacts on your system can be huge.

As an example of how shard key selection is vital, consider this real-world, non-IT example, which clearly highlights how a poorly selected shard key can massively impact performance of a system:

At the weekend I participated in a large Half Marathon event, with about 20,000 other runners. The number of bags to be stored while the race was on was too large for a single baggage tent, so the organisers had wisely decided to introduce a sharded approach by having two tents, each holding half the bags. Additionally, each tent was further sub-divided into separate evenly-sized sharded collections of bags, each managed by its own team of helpers.

Now, as a shard key the organisers had decided to use race number: a seemingly sensible choice given that this would be the single unique piece of information that every runner would have. The bag tents were therefore arranged so that tent 1 was for numbers 1 to 10,000 and tent 2 was for numbers 10,001 to 20,000. The sub divisions inside the tents were further broken down into 1000 number blocks (i.e. 1 to 1000, 1001 to 2000 and so on).

For pre-race bag drop off this sharding approach worked really well (the write scenario). Runners dropping off bags were nicely distributed across both time and the full range of values, so each tent and sub-division could work in parallel for the maximum write performance. This was clearly an excellent shard key selection for the write case.

The problem occurred at the end of the race when runners returned to the tents to collect their bags (the read scenario). Now, the organisers of the race had issued the numbers based on predicted finish time (1 for the fastest predicted finisher, 20,000 for the slowest): the result being that runners finished roughly in number order.

So, what happened then is that there was a initially massive read queue at tent 1 for the 1 to 2000 numbers, while the other shard nodes were almost completely idle. Then the queue moved to the 2001 to 4000 shards, and so on. Towards the end of the race, tent 1 was idle while tent 2 now had the read queues as the later numbered runners all finished.

We have a perfect case of a shard key that seems quite sensible by design but is actually fundamentally broken by the usage scenario of the system, in this case the (near) sequential arrival of numbers for retrieving the bags.

So, how can we solve this? Issuing the race numbers in a different order is one option, but a sequential numbering system based on predicted finish time is quite sensible for many other race organisation requirements. A better option is to change the shard key used by the baggage tents.

Basing the shard key around race number is still a good approach as this is the one piece of information guaranteed to be unique for each runner and the range of possible values is clearly defined and well distributed. Bag drop off (write performance) is never going to be a problem as runners will arrive fairly well distributed across both time and the race number range.

The challenge is coming up with a way of better distributing the bag retrieval (read performance). Fortunately with a sequential numbering system this is pretty easy. Rather than shard by the whole number, just shard by the last digit of the number: tent 1 – numbers ending 0 to 4; tent 2 – numbers ending 5 to 9. Then in each tent further divide into five separate shards, one for each ending digit. If finer granularity is required then within each shard it should be easy enough to sort and index by full race number.

Selecting a good shard key is hard. Considering both the write and read scenarios, and how the shard key will be utilised within these scenarios is critical. It can make a huge difference between a well-functioning system and one that fails to gain the benefits of the sharded approach.

Wednesday, 4 December 2013

Scala's Maturing Community

I've been involved in the Scala community and attending Scala conferences for about four years now. I've just come back from 2013 Scala eXchange, hosted by Skillsmatter in London. It was a great conference, one of the best I’ve been to, and the organisers and speakers should be thoroughly pleased with their efforts. One thing that I did think quite interesting was a significant change in emphasis from all of the previous Scala conferences that I’ve attended.

When I first started going to Scala conferences four years ago, the emphasis was definitely on an introduction to Scala. The talks focused on basic language features, how to use the collections libraries and core functional programming concepts. There were also some side talks about interesting libraries built in Scala, like Akka and Lift.

Last year the focus moved to a higher level, with more time spent on talking about where Scala was going and on more advanced functional programming concepts. There were talks focusing on things like Lenses and Monads and lots of detail about highly functional libraries developed using Scala. Presentaions about Akka and Lift were still present and people were starting to talk about Futures. In all of these talks, however, functional programming was the primary focus.

At Scala eXchange this year the emphasis was almost entirely flipped around. Most talks were about reactive programming using asynchronous approaches. Loads of stuff about Akka, actors, futures, events and the like. Some talks focused on Scala features such as macros and using type classes. However, there was very little direct talk of functional programming: it was just assumed that everyone present was using immutable data and following a functional programming approach. A huge shift in perspective from just a year ago.

I believe that this represents a massive shift in the maturity of the Scala community. We have moved from an immature group learning about how to use this exciting new language, how to work with immutable data and how to blend functional approaches into our code. We have instead become a group who are using this fantasic language and a set of fairly mature products and reactive techniques to build highly scalable systems. A huge leap in just a couple of years.

I remember a similar transition in the Java community when conferences went from talking about basic Java concepts like POJOs, collections and design patterns to talking about building complex solutions using advanced libraries like Spring and JMS. The Scala community seems to have made this leap much more quickly than the Java community did.

The one thing that worries me slightly about this change is that using immutable data and functional programming has almost become an unwritten assumption. Each presentation just seemed to assume that you would be programming in this way by default. While this is great for those of us in the community who have made this transition, I think we need to be careful not to skip this step for those people just transitioning into the Scala world.

The worst case would be developers transitioning from a language like Java straight into an asynchronous reactive programming model without first going through the transformation of thinking in terms of immutable data and functional programming. Bringing the concepts of mutable state and imperative code straight into an async world is a recipe for disastrous software projects. These in turn could tarnish Scala's representation and significantly complicate the life of those of us trying to bring Scala into traditionally conservative organisations and companies.

It's great the the Scala community has come so far and matured so fast. But, let's not forget the core concepts that underly this transformation. We must ensure that we continue to emphasise their importance as we move forward into the brave new world of highly scalable, asynchronous, reactive systems that Scala seems to the targeting so directly and successfully.

Monday, 15 April 2013

Coaching: How Not What

Yesterday evening I was playing a game of 5-a-side football (soccer to my American readers) with some friends. One of the players on my team was a particularly competent player who was also very vocal in offering advice to his team mates on what to do.

For example, when a player from the opposing team was approaching me with the ball he would offer sage advice such as "Don't let them get past you!". This was rather stating the obvious, as I was quite clearly not planning on letting the opponent go past me and take a clear shot on goal.

In this particular situation my challenge was not in knowing what I should do, but in having the skill and experience necessary to carry out the task. No amount of shouted commands were suddenly going to increase my skill to a level beyond that which I currently possess.

This got me thinking about how we coach people in programming and agile practices. How often do we say to someone something like "that needs to be refactored" or "you need to keep your functions small"? Or, we might say to an agile team "don't overcommit yourselves this sprint". All of these are instructions to do something, made with the assumption that the people receiving them have the skill and experience necessary to carry out the actions.

What if, like me on the football field, the recipients of these instructions knows what they should do, but not how to do it. Clearly we are not being successful coaches in these cases. We need to focus much more on the how rather than the what. Advice offered should be enabling, providing the recipient with a way of learning and gaining experience.

For example, "if you pull this bit of code out into a separate function then this loop becomes much simpler" is much more helpful than "that needs to be refactored".

As coaches we need to be mindful of how we communicate in order to improve the people under our guidance. It's very easy to let it slip and just become another player shouting advice to those who haven't yet gained the skill necessary to implement that advice.