Feedback

The past few months I have been fortunate enough to have been training for a very specific and challenging role in our organisation, and the journey has been tough. The role requires you to maintain and protect consistent standards and facilitate important decision making involving groups of people from all over the organisation. I am extremely grateful to have this opportunity though, because, apart from being very rewarding, I also learned an incredible amount about coaching and feedback. I’m going to dump a summary of my musings on feedback here both from the perspective of the coach and the coachee.

On being coached

I think it is part of the human condition to need validation of your strengths as well as your mental model of how the world works and your function in it. We seek out affirmation and recognition from our peers rewarding us by giving us affirmative messages.

This mental model, though, needs to change if you are to grow as a person, and shifting or invalidating your mental model and your function in it is inherently a very uncomfortable experience. Receiving critical feedback challenges your mental model and your self-belief – it requires emotional work on your part to facilitate a shift (if necessary, of course) and defining what the resulting shift should look like.

My first year as a software developer, for example, was a massive learning curve – adjusting to a profession and learning how to navigate teams and function within an organisation.

Going through this most recent training was tough, because it involves being shadowed by people already in that role and receiving in-detail feedback on everything you did and could improve on. On top of that, the role is extremely qualitative or fungible – it isn’t as simple as learning a process or improving code quality. It requires you to learn how to facilitate a group of people, drive a complex conversation, and ensuring the right outcome for the organisation. I don’t think anyone in the world can teach you how to do that by just explaining the steps to you. The only way you can really teach someone how to do this is by exposing them to the situation, letting them practice and providing feedback with every iteration.

The more you grow in your career, the more qualitative and intuitive the skills become that dictates your impact. As a junior engineer your value lies in producing good quality code at healthy volume. The more senior you become, the larger and more ambiguous the problems become. Your impact on team and organisational culture becomes more important when you start delivering through others and driving the direction your team takes. The blast radius of getting it wrong also increases. Coaching at this level becomes proportionally harder, because it becomes more qualitative – these are attributes and behaviour you can’t just explain to someone over a coffee.

Being coached at this level is not easy, but I have devised a framework for myself in which to process feedback:

Have respect for how hard it is for others to coach you

Coaching is hard. Remember, you might be going through the learning curve of mastering a difficult skill – the person coaching you is going through the learning curve of learning how to coach others that skill. You might just be one of the eggs they need to make their omelet.

Have empathy with yourself – allow yourself to iterate on it and fail

I think this is something especially women struggle with – I know I do. I started doing ballet a few years back and initially I was extremely frustrated. It took a few months for me to realise that the practice of ballet means constant pursuit of mastery through failure. The only bloody way to learn how to do a pirrouette is by falling over hundreds of times repeatedly until you get that first turn. You also have to realise that the immediate next turn after that first successful one is going to be a faceplant again. Mastery is not linear and not binary. It takes repeated practice.

Seek out diverse opinions

The first thing I learned going through this training was that you are going to get conflicting feedback. They can both be right – ask them why and find the underlying value of their advice. Everyone needs to develop their own flavour of doing something, and you need to define your own way as well.

Own it

This is your learning curve. You are not uncomfortable for someone elses benefit, but for your own mastery. You are doing this because you want to grow. This means that you carry the responsibility for getting the feedback required and actioning that feedback to facilitate your growth. Your development is not the responsibility of anyone else. If you receive feedback you don’t understand or you don’t know how to action, carry it with you and have conversations with the people coaching you until you do.

On Coaching

Giving critical feedback is one of the hardest things to do as a human, often to the extent where people shy away, rather walking away from the conflict. I believe that learning how to give critical feedback is a critical skill everyone needs to learn, no matter how uncomfortable it is. I am very grateful to have been on the receiving end of coaching by a few masters of the trade recently, allowing me to observe how they did it and the way I received it. Similarly I have been the egg in the omelet of a few less successful coaching attempts, highlighting to me a few things to avoid. Here are my few cents worth.

Distinguish between punishment and feedback

Never, ever try punish someone under the guise of ‘giving feedback’. If you resent the person and do not engage with the emotional intent of improving their experience, walk away and rather go throw around weights in the gym.

Allow them to bitch about it

Receiving important feedback is an extremely uncomfortable experience. Allow the person on the receiving end to express this to you. Sit there and listen, nod and smile and acknowledge that you empathise with how they feel, regardless of whether you agree or not. Successful coaching requires a willing recipient, and you need to create a high trust environment to coach successfully.

If necessary, let them run off and lick their wounds before catching up again.

Don’t overload the person with too much in one go

I recall having read somewhere that the human brain can only retain up to seven ideas in short term memory before needing to offload it to long term memory. I am pretty sure that this number drops to two or three in stressful situations. Anticipate that a feedback session is a high stress situation for the recipient so rather give diverse feedback points over multiple shorter sessions, allowing the person to process one idea at a time. Overloading a person with a grocery list of areas of improvement will overwhelm them. They will then need to do so much emotional work having to overcome a sense of failure that they will have little capacity left to actually respond to the feedback.

Recognise growing pains

Understand that people only have a limited capacity for working at personal growth. If you see a person regress or stagnate, maybe back off on introducing other areas for growth, allowing them to complete the learning curve they are currently in.

Make it concrete

You are not kind when trying to soften the blow by saying “sometimes you can possibly do something like…”. Rather stick to “On this day, in that situation, you did…”. That gives the person context on where and when behaviour took place.

Explain why

If you need someone to change their behaviour, you need to explain to them why. Explain what the risk is of not changing, or the advantages gained by changing.

Make sure they recognise it

I recently received feedback that I tend to ‘give too much of my own voice to a conversation’. I couldn’t understand it, because I was intentionally trying not to do that – until someone told me that they thought the feedback referred to my verbal summary in a conversation. I would repeat what I heard someone say in summary, trying to validate that I understood their intent, and in doing so, I could become floral and instill my own interpretation in the message. As soon as they said it, I understood what they meant, and I could change my style.

Make it actionable

Work with the person to identify ways in which they can try address the feedback. Help them identify concrete outcomes to measure their success in doing so.

Make sure they receive it

Giving feedback via someone else – a manager or a mentor – is easy, right? What if that person decides not to pass on the message? You start resenting that person because you don’t see any attempts to respond to the feedback, and they become frustrated because they don’t know why you are suddenly frustrated with them. Make sure feedback reaches someone – preferably give it yourself.

Limit the hops (broken telephones suck)

The more hops there are between you and the recipient, the easier it becomes to give critical feedback. You email a manager who has a chat with another manager who asks that person’s mentor to deliver the message. By the time that message reaches the poor recipient, if it even makes it that far, the feedback has been so diluted that it loses its impact, context and actionability. This is extremely frustrating to the recipient, because now they know 1. Someone out there thought they didn’t do a good job, 2. Their whole management chain (chain of trust) knows about it, so well, that is awkward, and 3. they have no idea what to do about it other than go home and feel bad about it.

Close the loop – reward recipients for mastering the bloody thing

Close the loop on the feedback by celebrating with a person when they get it. Tell them when you see an improvement, thank and congratulate them for working at it.

 

Advertisements

Kibibytes and the missing bits

Right, I just had a noob moment in the office. I was reading about MemInfo metrics, and came across this sentence:

MemTotal — Total amount of usable RAM, in kibibytes, which is physical RAM minus a number of reserved bits and the kernel binary code.

Wait, a what?!

Sarah – “What is a kibibyte?”

Ian – “It is 1024 bytes.”

How did I not know this? It is a thing!

Pretty JSON formatting in Sublime Text on Mac

I like using Sublime Text for ruby/json/ad hoc stuff on my Mac, it has a good balance between ide-like text editing, but still lightweight enough for you to muck around.

JSON formatting options are a dime a dozen, but this one was quick to install and is very usable – SublimePrettyJSON GitHub page

To install:
cd ~/Library/Application\ Support/Sublime\ Text\ 2/Packages

git clone https://github.com/dzhibas/SublimePrettyJson.git

To use:

  1. Select Text
  2. cmd+ctrl+j

Hard conversations – Burn the ships

I want to tell you a story.

Paul* started as a junior engineer at a sexy tech company shortly after completing his BSc CS Masters. He worked hard, wrote good code, and got promoted. He developed a reputation very quickly as a rising star and soon got put onto teams doing tough projects.

Let’s move to introducing John*. John moved to Paul’s company after learning the ropes at another very good development shop, and came with a good reputation. John and Paul are now two mid-level engineers with a great track record, and are given a big ‘prove-yourself’ project and a handful of young engineers to lead. Here things fall apart. The team is morbidly unhappy, sprint goals are missed week after week, the team starts slipping on delivery dates like a toddler in a skating rink. Internal conflicts start picking up and people area leaving not only the team, but the company.

I have encountered this team in different levels of disfunction in various environments, either as a team member or an observer, and it is a pattern I have started to recognise in our industry. Let’s unpack some symptoms I have observed in the past:

  • Code reviews are scathing and personal. “Are you THIS stupid?!”, “????!!!!!” or paragraphs of passive aggressive criticism are the norm.
  • A senior engineer holds the big model in his head and hands out little chunks of micro-managed work to other engineers. When questioned, he answers with a ‘well, why do you need to know everything, I know what we are working towards, you just do your bit’. No one knows how the project is tracking or how to even find out how the project is tracking.
  • When someone throws a white-board across the room, you can just as well disband the team and go on holiday.
  • Newer team members are not allowed to contribute to a conversation, and are shut down with the “well, once you have been here as long as we have, you will learn how we do things around here.”
  • The one who talks the loudest, wins.

Let’s head back to Paul and John and see how they are doing. Unfortunately, the constant praise they are used to have now de-generated into increasing pressure from senior management to get their team and project in order. In the past, Paul and John got where they are because they were smarter than everyone else AND they had the grit to push harder to get the work done. They have been rewarded for this repeatedly throughout their careers. It is just a case of doing this once again, right?

Unfortunately the strengths required from Paul and John right now are completely orthogonal to being the smartest and most hard-working engineer in the room. What no one told them was that they now suddenly have to empower other engineers to be the smartest and grittiest workers in the room. In order to do this, Paul and John suddenly have a steep learning curve ahead – they need to create a high conflict, high trust space in which younger engineers feel safe enough to deliver stretch work despite high ambiguity and self-doubt, probably while experiencing all of this themselves. This is a very steep learning curve and I have seen engineers fail in this space either by getting themselves fired (the white board incident was anectodal) or leaving out of frustration.

I have good news and bad news.

The bad news is that most engineers are a John or Paul at some point in their career, and for some this is a wall they can’t overcome.

The good news is that I believe that this is fixable.

A legitimate strategy can be to isolate technical experts and buffer a team from their emotional toxicity by separating a technical visionary role from a generalist team lead role. I am personally not a fan of this, because this means you have very senior brittle engineers and team success relies on inter-person collaboration between people known for EQ as a weakness.

Another strategy is to foster a culture in which Paul and John is introduced to this learning curve earlier in their career and are given mentors who are successful at facilitating team cultures like this. I can name people I regard as these role models I have had in my career – Malcolm Hall, Mylo Mannya, Anthony Robinson, James Greenfield and, most recently, Ian Davies.

I have, to date, chosen my career opportunities based on the presence of such people in a space – this is very important to me.

I don’t like throwing more and more critical feedback at John and Paul – this makes them more anxious about their inability to succeed and probably leads to worse leadership behaviour and more general angst. If we don’t empower John and Paul to succeed in this learning curve, we risk losing great engineers.

This brings me to burning the ships. Captain Hernán Cortés arrived at Veracruz in 1519, and had to capture new territory. He instructed his troops to burn the ships – he knew the only way to instill enough motivation to succeed was if there was no option to turn back. I have walked away from professional spaces with problems in the past, as many people do. We are fortunate (or unfortunate) enough to be in an industry where development skills are in high demand, so we always have the ‘ah, I have options open’ in the back of our minds. The accessible back door is a psychological safety tool that all people tend to leverage. The problem with this is that we don’t tend to take ownership for the problems in the space we are in now.

We need to burn the ships psychologically and commit wholly to taking ownership for the culture of the space we find ourselves in right now. The great working environment we all want won’t exist except if someone intentionally builds it.

How am I taking responsibility for building the kind of working environment I would like to work in? By opening up the tough conversations, while making sure people around me are emotionally safe. By rewarding the quiet rock stars vocally. By advocating and sponsorship of engineers who might find themselves in tough conflict situations. By talking about problematic behaviour I observe and building allies through conversation. Reward the good, don’t attack the bad. Ride out the tough times to stay long enough to see the good emerge.

Go burn your ships.

Sarah

Keep your call path primed

I recall asking my Mom as a kid on Winter mornings why she always turns the key before starting the engine, and her response was “I need to prime the engine, because it is cold.”

My team is working on something that is common in a service-based environment – writing a replacement for an existing service that we intend to hot-swap without taking an outage. If something goes haywire (initially) we retain the ability to flip traffic back to the legacy call path as a backup, right?

My concern is this: As soon as you reroute traffic from the legacy call path, you will have to assume that that service’s ability to serve that call volume immediately starts to degrade. The team that owns it becomes disincentivised to maintain that service to accommodate the call volume capacity it is carrying today. Since they don’t serve production call volumes anymore, they won’t notice if their service degrades, and in our eco-system, that happens in a matter of days.

I recommend a new migration design pattern – keep your call path primed by routing traffic through ALL call paths until you are comfortable retiring a call path completely. You can do this by routing production traffic through shadow call paths, generate mock service calls that hits extraordinary paths frequently or rely on integration test/black box test coverage. This also includes validating backup restores and tasks you rely on in operational crises.

Hostage Work

I am fortunate enough to work on a team where we are able to address about 30% (thumbsuck) of the needs in our backlog. I know this sounds incongruous but it means that everything I work on is really, really important – important enough to trump other work not making it into sprint.

I am also fortunate to work on a team with people who are constantly driving for improvement. We need to improve the technical debt incurred by existing bugs and badly implemented service architecture. If we were to whip our code base into the shape we would want it in, we wouldn’t be delivering feature work for at least a year, but isn’t that the case for all developers?

In our environment we use a code review tool – all commits need to be reviewed and shipped by your peers before it is allowed to be committed. This is awesome. It serves both as a quality control measure and a mechanism for continuous knowledge sharing.

The problem, however, comes in when people start holding off on shipping submissions with a’I just spotted this bug/potential refactor in the peripheral code, could you just fix it?’.

In our last sprint I picked up a task to implement a set of integration tests to validate new filtering behaviour. I implemented them and found similar integration tests for a similar test case that had been written by a colleague of mine. In the process of writing my tests I found a bug in his integration tests, so I fixed the bug and submitted it as one code review. This took me a day. On that code review a senior engineer on my team saw that the other tests I had fixed was using an enum that was placed in a service layer package instead of a common shared package and asked me to move it ‘while I am at it’. Sure, sounds good, moving it. This started unravelling and the next thing I saw was four days of uncovering architectural pain points that didn’t behave incorrectly but needed some refactoring in the long term and had nothing to do with the original integration tests I was supposed to write. I asked whether I could get a ship it on the bug fix and my integration tests and create a new task to do this refactoring? Resounding silence and no ship its. Until I have a ship it on my code, my work is not done, so I can’t just walk away from it. This scenario brought the idea of ‘hostage work’ to mind.

Sure, I am a firm believer in the boy scout rule. I am also a firm believer in working on the most important stuff first. By holding out on a ship it, this senior engineer was forcing me to do internal improvements (on code he had written a few weeks prior, as commit history proved, by the way) that was not on the sprint board. This is a very effective way to introduce work by circumventing the democratic prioritisation process that makes SCRUM successful. What you are actually saying is that this refactoring work is more important than what was placed on the sprint board as well as what was left out of sprint due to limited capacity. This is not fair. There are mechanisms for introducing discovered work into sprint. If it is a thirty minute improvement the boy scout rule applies. For more substantial refactoring and improvements, even discovered bugs – create a separate fire story on the sprint and make the work visible to the team. This creates the opportunity for the importance of this work to be prioritised properly by the team and it also does not skew the perceived effort of the original work. The story I was working on had an actual effort of one day, including a boy scout bug fix. The effort reflected on the board leaned towards five days. In a team where we estimate effort by benchmarking it against known other work, this introduces additional risk. The team also runs the risk of not meeting the sprint commitment which places additional pressure in subsequent sprints because of additional work backlog, tighter deadlines and a negative reputation for delivery.

Another form of hostage work is a manager or senior engineer approaching individuals on sprint to ‘quickly just implement a fix’ or ‘provide an estimate’. The engineer can’t decline because of the perceived seniority of the asker, so they do it. This does not just take away the time spent on the effort from the sprint, but also bears the additional cost of introducing context switch thrashing, loss of knowledge sharing while the engineer is working rogue and implied prioritisation of asked task over prioritised sprint work.

A last form of hostage work is an engineer who go rogue on their own and defend it with ‘I know this is not on sprint, but this is a learning opportunity for me’ or ‘I have this pet project or agenda I want to push, so I am rather going to work on that than the priority established during sprint planning’. In effect you are leaving the (now compounded) responsibility of meeting sprint commitments to your colleagues. You lose the trust of your colleagues who now have to work harder to meet sprint commitments – effort eating into their capacity for learning and personal investments.

SCRUM only works when everyone on a team actually protects the sprint and commit to the process.

Setting up multiple versions of Java JDK on a Mac

A quickie but a goodie – setting up multiple versions of Java JDK on a Mac. 🙂

Install Homebrew and Cask

  • Install cask if necessary
    • ➜ ~ brew tap caskroom/cask
  • Ensure brew caskroom is up to date
    • ➜ ~ brew upgrade brew-cask

Install jenv

  • Install jenv
    • ➜ ~ echo 'eval "$(jenv init -)"' >> ~/.bash_profile
  • Always run jenv (choose one :-))
    • ➜ ~ echo 'eval "$(jenv init -)"' >> ~/.zshrc
    • ➜ ~ echo 'eval "$(jenv init -)"' >> ~/.bash_profile

Install Java JDK’s

  • Java JDK’s are installed on iOS in /Library/Java/JavaVirtualMachines/
    • ➜  ~  ls /Library/Java/JavaVirtualMachines/
  • If you are missing any, use brew to install JDK
    • ➜ ~ brew cask install caskroom/versions/java7

Add JDK’s to jenv

  • for each jdk:
    • ➜ ~ jenv add /Library/Java/JavaVirtualMachines/[…JDK Version..]/Contents/Home
  • Look for all known binaries and rebuild shims
    • ➜ ~ jenv rehash
  • ➜ ~ jenv versions