I've recently finished my first year as a technical team lead, my first role mentoring and supporting a technical team rather than being fully involved designing and coding on projects. This is some of the stuff I wish I had learnt faster.
I've been a "tech lead" on various projects over the years, but this has been my first role as a "team lead".
Largely this was a sink-or-swim experience, which probably isn't ideal, but overall I think I kept breathing and learned to paddle a little bit.
This post is mainly looking back at that first year and writing about the parts that stick in my mind as the major lessons.
A team/group expects their tech lead to help them. If they're expecting help, it's because something isn't working as well as they want. Your presence in the team changes it, altering how something works is a change and it's very likely other things will need to change to support that process. So that's your job - helping people change stuff (including themselves).
The trouble is, people HATE change. There is masses of information about this, from actual psychologists, pop-psych and pop-sci books & speakers, business gurus, even religions. Although I was already aware of this (Peopleware FTW!), it still took a long time to sink home sufficiently.
I'm probably still too likely to wave my "big stick o' change" at someone's sturdy mental foundations without enough care and I'm probably just as wary about others messing with my foundations too. But at least I recognise what's happening.
Don't Repeat Yourself is one of the mantras of good programming - it's a core part of refactoring, good encapsulation, abstraction, all the stuff we know we should be doing in our code. Find the right place to state something, state it there, reference it from anywhere else.
Not for people. People are not machines. They forget, they don't cross reference, they definitely don't remember what other people said or wrote and they are essentially large neural networks which need pathways reinforcing at well timed intervals. Preferrably with different views and contexts onto the same information.
So, DO repeat yourself. Get the facts straight, chop them into short and memorable pieces and repeat them in various forms and with various costumes. Sometimes things will stick straight away, and that's lovely, I happily took the easy wins and tried to feel good about that. Sometimes it takes a lot of repetition and that is frustrating - especially when the point seems obvious.
Sometimes it feels like fighting against willful ignorance and that's really hard. It probably means I'm blundering into the point above, about change, and I have far more to learn in this area.
While we're learning software, there's a lot of focus on what you should or shouldn't do - a lot of "right" and "wrong". That's understandable and pretty much unavoidable, since compilers and interpreters are basically formal engines for saying when statements are right and wrong (true-false; parseable-unparseable; 0-1).
However, there are many occasions when the computer doesn't really care - then the arbiters of right and wrong are our fellow coders, our team mates. Welcome to the grey areas. Over time we learn more about the grey areas, maybe choose preferred shades for certain things, learn to work with other people's preferences.
These can be worrying concepts when moving on from learning about coding with a "right" and "wrong" mindset. That took me a while to realise - I've spent too long looking at and wandering around in the grey that I didn't see the concern these areas could cause.
At the most simplistic level we can talk about things like: should you use tabs or spaces? 4 or 8? What about 3, is that bad? Would that make your code unreadable? What does that say about your indent style? Discussions about this have been going for decades. Have you seen that someone suggested Fibbonacci indentation? There are now IDE plugins to support this - how cool is that!? Oh and the compiler doesn't care about this at all - unless you're using a whitespace sensitive language (hello Python) - is that a good idea?
Over time I realised that showing comfort with inhabiting these grey areas, that all this stuff was up for discussion, that we're writing code for people to read, this was mental territory coding courses didn't really cover. So we started to discuss it more - to see where the weird and bad ideas could take us.
For example: if we're building both ends of an HTTP request-response system, we could add a new verb. Wouldn't be pure HTTP any more, but who would know? How bad would that be? Now look at what Microsoft did with IE and IIS - what do we think about that? Metaphorically speaking, the shades of grey we see depend largely on where we stand.
My point here is that I'm not trying to teach/tell/enforce what I think is "right" or "wrong" - I'm trying to show that whatever choice someone makes, they should understand why they are making it, understand that others can make different choices for other reasons, and those choices can work equally well as far as the overall system is concerned.
I saw early on that the other devs were interested in historical code horror stories (from way back in the nineteen hundred and nineties). Initially I thought maybe this was humouring the new grey-beard, but eventually realised they weren't just enjoying the stories, they were learning lessons they could apply. All those painful stories of times I'd either screwed up, helped fix screw ups, seen "can't happen" events happen, etc - all that stuff is useful experience they can use.
Learning that it is possible for a compiler to have a bug in it was a real eye opener for someone. Knowing that some software bugs can cause physical explosions suddenly means their current CSS alignment bug isn't as stressful. Although knowing that CSS alignment bugs can take months to solve, only to be broken again by a new browser bug, was also a scar they were eager to see ;-)
So I now talk more about the cock-ups, near-misses, bizarre constructs and designs in software that I've seen. If one of my stories jogs their memory when they see something similar, that may save them hours or days of frustration - they can build their own mental scars rather than having to collect the same ones as me.
Admittedly, once we'd agreed I wasn't just an old man shouting about "crazy endians", I was happy to share my war stories and show my mental scars, although maybe I've just helped them become more cynical, faster.
This feels like one of those "there is no 'I' in team'" comments. But, cynical as I am, that stuff does work, we're social creatures. In this case, I decided to try using "we" rather than "you" in code review comments where I felt a change was needed.
The basic idea is rather than statements like "you need to do X", "we need to do X" improves the conversation. We're replacing an instruction to an individual with a requirement for the group.
Admittedly the next bit of the conversation may be "So are you happy to do X for us?" or "Who is best placed to do X?" but I've been lucky, almost always there has been an immediate response along the lines of "yup, I can do that, thanks!"
Bonus Psych Tip: The next change I tried was phrasing some code review comments as questions.
The plan here is that rather than a comment like "You've missed an exception case here", a question "Are you sure that XyzException can't happen?" makes the reader think more about the question - and also gives them the opening to explain if they did mean what they wrote. It becomes an invitation to share info rather than a mechanistic instruction.
It also means you can hide the fact when you didn't understand the code ;-)
This follows on from the bonus psych tip above - a common piece of advice for mentoring is "Ask, don't tell". The idea is that a question opens up a conversation and encouraging engagement and learning, whereas giving instructions or advice is a closed conversation.
While that's clearly good advice (if a little self-contradictory), there are definitely cases where it doesn't help either the mentor or mentee.
If I'm called on to help with a debugging session, where someone in my team has spent the day trying to fix a nasty knot in their code, turned up all the logging, managed to attach a debugger to a synched codebase and recreated the failing scenario intermittently - I'm not about to ask any questions to stretch their mind further, it's already unravelling.
They're asking for help, from someone they know can help, who has seen this stuff before. They need to nail this bug down so it can be sorted before the progress meeting in an hour.
The last thing they need is some buddha sitting next to them prompting them to think about everything they haven't done.
It may not be good practice, but in these cases I'm happy to go for "tell, don't ask". More specifically I'll ask to drive (we're clearly pair programming now), then try to tell while driving.
My intent is that while I'm digging into the problem, I can also explain what I'm doing and why. Once we've got the bug nailed, or otherwise got some kind of answer agreed, then I'm happy to start with the more open questions. Maybe we'll also admire their new scar :-)
Maybe the argument here is that I've switched roles from "mentor" to "expert". Rather than being a teacher I'm playing the role of veteran in these situations.
Maybe I'm just trying to prevent their sanity leaking away any further.