Spheres of Alignment

This is a post in my alignment series. See the introductory post Finding Alignment for more context.

I think, in practice, most of what managers do--and indeed all leadership--is about building alignment. The core concept, of alignment, having a shared understanding of the problem space and its context combined with relevant goals and objectives, and grasp of how the context contexts to these objectives. Alignment isn't just "agreement" or "understanding the solution," and really centers on this connection between context and goals. Alignment shows up in many different situations and interactions:

  • a small working group (2-4 people) who are working on building or developing something. The thing can be any kind of work product: a piece of software, documentation, a business process, a marketing campaign, a sales deal. When you have more than one person working on something, if they're not aligned, each person may be able to work on a piece of work as delegated or assigned, but lacks the ability to (reliably) continue to work on the next piece of work after finishing a narrow task, or be able to assess if a line of work is still germane to the goals as things develop. If we view people's roles in projects as machines, and they perform assigned tasks well, then alignment isn't super critical, but if you need people to make decisions and act upon them, then they have to be aligned, as a group otherwise the project runs a huge risk of stalling out as each contributor pulls in an opposite direction.
  • one person aligning with the rest of their team to understand how their background and personal goals contribute to and interact with the team's context and goals. Individuals all bring unique skills and interests and (hopefully) useful to teams, and teams (e.g. their leaders) need to be able to understand how to effectively use those skills and interests to support the team's goals. This happens over conversation and in the context of someones participation in a team over time, and doesn't need to take a lot of time on a regular basis, but cannot be entirely abandoned.
  • managers need to align their teams with the company's objectives. This takes the form of making sure that the projects that the team is working on (and will work on in the future,) support the organization and company's larger goals.
  • across all level each team needs to align with its peer teams and the organization that it belongs in. This is true in organizations with 30 people and 3-4 teams, and in organizations of 2000 people and dozens of teams.

Alignment is hierarchical, and largely the responsibility of leaders to monitor alignment above and below them, and understand if their teams or specific contributors are falling out of alignment. This doesn't necessarily mean that it's not participatory and discursive: individuals can impact the direction, goals, or alignment of their teams, but there must be well formed goals of the organization (that they can understand!) and they must be supported by their team in order to actualize in this dimension. Despite being hierarchical, and individuals and teams must align up building and maintaining alignment in all directions is actually the responsibility of leadership at all levels.

It's easy to frame this as "you must align with the goals sent from above," this couldn't be further from the truth. Some organizations function like this, but it's probably not healthy for anyone, because the kinds of alignment that it builds are fleeting and tactical. Teams and contributors do need to align with broader goals (up), but their job is not building alignment, it's building whatever their specialty is: attending to the organizational health and alignment is the concern of leadership whose work must center on building alignment. At almost every level, the alignment goes both ways: you work with leaders above you to align your own work and team, and work with the people you collaborate and mentor to build alignment.

When it works, and even though it takes a while, it helps teams and organizations work really well.

Easy Mode, Hard Mode

I've been thinking more recently about that the way that we organize software development projects, and have been using this model of "hard mode" vs "easy mode" a bit recently, and thought it might be useful to expound upon it.

Often users or business interests come to software developers and make a feature request. "I want it to be possible to do thing faster or in combination with another operation, or avoid this class of errors." Sometimes (often!) these are reasonable requests, and sometimes they're even easy to do, but sometimes a seemingly innocuous feature or improvement are really hard sometimes, engineering work requires hard work. This isn't really a problem, and hard work can be quite interesting. It is perhaps, an indication of an architectural flaw when many or most easy requests require disproportionately hard work.

It's also the case that it's possible to frame the problem in ways that make the work of developing software easier or harder. Breaking problems into smaller constituent problems make them easier to deal with. Improving the quality of the abstractions and testing infrastructure around a problematic area of code makes it easier to make changes later to an area of the code.

I've definitely been on projects where the only way to develop features and make improvement is to have a large amount of experience with the problem domain and the codebase, and those engineers have to spend a lot of consentrated time building features and fighting against the state of the code and its context. This is writing software in "hard mode," and not only is the work harder than it needs to be, features take longer to develop than users would like. This mode of development makes it very hard to find and retain engineers because of the large ramping period and consistently frustrating nature of the work. Frustration that's often compounded by the expectation or assumption that easy requests are easy to produce.

In some ways the theme of my engineering career has been work on taking "hard mode projects" reducing the barriers to entry in code bases and project so that they become more "easy mode projects": changing the organization of the code, adding abstractions that make it easier to develop meaningful features without rippling effects in other parts of the code, improving operational observability to facilitate debugging, restructuring project infrastructure to reduce development friction. In general, I think of the hallmarks of "easy mode" projects as:

  • abstractions and library functions exist for common tasks. For most pieces of "internet infrastructure" (network attached services,) developer's should be able to add behavior without needing to deal with the nitty gritty of thread pools or socket abstractions (say.) If you're adding a new REST request, you should be able to just write business logic and not need to think about the applications threading model (say). If something happens often (say, retrying failed requests against upstream API,) you should be able to rely on an existing tool to orchestrate retries.
  • APIs and tools are safe ergonomic. Developers writing code in your project should be able to call into existing APIs and trust that they behave reasonably and handle errors reasonably. This means, methods should do what they say, and exported/public interfaces should be difficult to use improperly, and (e.g. expected exception handling/safety, as well as thread safety and nil semantics ad appropriate.) While it's useful to interact with external APIs defensively, you can reduce the amount of effort by being less defensive for internal/proximal APIs.
  • Well supported code and operational infrastructure. It should be easy to deploy and test changes to the software, the tests should run quickly, and when there's a problem there should be a limited number of places that you could look to figure out what's happening. Making tests more reliable, improving error reporting and tracing, exposing more information to metrics systems, to make the behavior of the system easier to understand in the long term.
  • Changes are scoped to support incremental development. While there are lots of core technical and code infrastructure work that support making projects more "easy mode" a lot of this is about the way that development teams decide to structure projects. This isn't technical, ususally, but has more to do with planning cadences, release cadences, and scoping practices. There are easier and harder ways of making changes, and it's often worthwhile to ask yourself "could we make this easier." The answer, I've found, is often "yes".

Moving a project from hard to easy mode is often in large part about investing in managing technical debt, but it's also a choice: we can prioritize things to make our projects easier, we can make small changes to the way we approach specific projects that all move projects toward being easier. The first step is always that choice.

Signs of Alignment

This is a post in my alignment series. See the introductory post Finding Alignment for more context.

I really want to dig into some topics related to building alignment and figuring out when you're aligned as a contributor, or when the people you're working with are falling out of alignment with you and/or your team or organization, but I think it's worth it to start slow and chew on a big question: What it feels like when you and your team are well aligned, and why that's a good thing.

To my mind, when you have a foundation of alignment, and an understanding of what the business goals are for your organization, then it becomes really easy to work independently, because you know what's important, you know what needs to happen next and the people your working for/with can be confident that you'll be moving in the right direction, and don't need to do as much monitoring. Every so often, teams find this, and can really grind on it and deliver great features and products on the basis of this. It takes a long time (months!) for a team to gel like this, and sometimes teams don't quite get there.

This isn't to say that needing more guidance and wokring less independently means that you're unaligned just that you (or the people you're working with/for) are newer to the team, or there's been a change recently and everyone needs more touch points to build alignment. One of the risks of hiring people and growing teams that are really well aligned is that the change in team dynamic can throw off alignment, and I think this is one of the reasons that teams sometimes struggle to grow. In any case, while alignment is great and it doesn't happen for free, and it's fine for it to be a thing you're working on.

Alignment also reduces a lot of potentially contentious conversations and interactions: when you have alignment within a team or between teams you have a framework for prioritizing decisions: the most possible things that have the largest positive impact on the goals that you have are more important than... everything else. It all ends up being pretty simple. Sometimes you have to spend a bit of time on something that's locally lower priority if another team depends on it, or if you're helping someone learn something, but for the most part alignment helps you move toward the right direction.

When teams (and contributors) lack alignment, it's easy for low priority work to get done, or projects that don't end up supporting the business goals and so fail to find use (projects fail for other reasons, some of which are expected, so failed projects don't necessarily indicate miss-alignment). An unaligned team can end up competing with peer teams and internal collaborators. If some parts of a team or organization are well aligned and other's aren't, resentment and frustration can brew between teams. Basically, without alignment you can--if you're lucky--skate by with a little wasted effort, but often alignment deficits are a blight that can threaten a team's ability to be productive and make it really hard to retain great team members.

Not everything is an alignment problem: teams and projects fail for technical or logistical reasons. Sometimes conflicts emerge between collaborators who are well aligned but working on disconnected projects, or hold different concerns within a project. Alignment is a framework for understanding how organizations can move together and be productive particularly as they grow, and in this I hope that this has been helpful!

Finding Alignment

I keep making notes for writing a series of essays about alignment, the management concept, and it's somewhere in between a blog post and a book, so maybe I'll make it a series of blog posts. This is the introduction.

Alignment is this kind of abstract thing that happens when you have more than one entity (a person, working group, or team) working on a project (building or doing something). Leaving aside, for a moment, "entity" and "project," when efforts well aligned in that all of the effort is in persuit of the same goal and collaborators do work in support of each other. When efforts are out of alignment, collaborators can easily undermine eachother or persue work that doesn't support the larger goal.

Being well aligned sounds pretty great, you may think, "why wouldn't you always just want to be aligned?" And I think deep down people want to be aligned, but it's not obvious: as organizations grow and the problems that the organizations address become bigger (and are thus broken down into smaller parts,) it's easy for part of a team to fall out of alignment with the larger team. It's also the case that two parts of an organization may have needs or concerns that appear to be at odds with each other which can cause them to fall out of alignment.

Consider building a piece of software, as I often do: you often have a group of people who are building features and fixing bugs (engineers), and another group of people who support and interact with the people who are using the software (e.g. support, sale, or product management depending). The former group wants to build the product and make sure that it works, and the later group wants to get (potential) users using the software. While their goals are aligned in the broad sense, in practice there is often tension either between engineers who want things to be correct and complete before shipping them and product people who want to ship sooner or conversely between engineers who want to ship software early and product people who want to make sure the product actually works before it sees use. In short, while the two teams might be aligned on the larger goal, these teams often struggle to find alignment on narrower issues. The tension between stability and velocity is perennial and teams must work together to find alignment on this (and other issues.)

While teams and collaborators want to be in alignment, there are lots of reasons why a collaborator might fall out of alignment. The first and most common reason is that managers/leaders forget to build alignment: collaborators don't know what the larger goals are or don't know how the larger goals connect to the work that they're doing (or should be doing!) If there's redundancy in the organization that isn't addressed', collaborators might end up compeating against eachother or defending their spheres or fifedomes. This is exacerbated if two collaborators or groups have overlapping areas of responsibility. Also, when the businesses falter and leaders don't have a plan, collaborators can fall out of alignment to protect their own projects and jobs. It's also the case that collaborators interests change over time, and they may find themselves aligned in general, but not to the part of the project that they're working on. When identified, particularly, early, there are positive solutions to all these problems.

Alignment, when you have it feels great: the friction of collaboration often falls away because you can work independently while trusting that your collaborators are working toward the same goal. Strong alignment promotes prioritization, so you can be confident that you're always working on the parts of the problem that are the most important.

Saying "we should strive to be aligned," is not enough of a solution, and this series of posts that I'm cooking up addresses different angles of alignment: how to build it, how to tell when you're missing alignment, what alignment looks like between different kinds of collaborators (individuals, teams, groups, companies,) and how alignment interacts with other areas and concepts in organizational infrastructure (responsibility, delegation, trust, planning.)

Stay tuned!

Rescoping the Engineering Interview

It's not a super controversial to assert that the software engineering interview process is broken, but I think it's worthwhile to do that anyway. The software engineering interview is broken. There are lots of reasons for this:

  • interview processes are overoptimized for rejecting candidates that aren't good, that they often reject candidates that are good. This isn't a problem if it happens occasionally, but it's really routine.
  • it's difficult to design an interview process that's works consistently well across different levels and different kinds of roles, and companies/teams can easily get into a place where they really can only hire one type or level of engineer.
  • while many engineering teams know that the hiring process is biased, most of the attempts to mitigate this focus on the bias of the interviewer by making interview processes more consistent across candidate or easier to score objectively, while abdicating for the ways that the process can be biased toward certain kinds of candidates.

I've been part of lots of conversations over the years about "making interviews better," and many of the improvements to the process that come out of these conversations don't do much and sometimes exacerbate the biases and inefficiencies of the process. I think also, that the move toward remote work (and remote interviewing,) has presented an underrealized opportunity to revisit some of these questions and hopefully come up with better ways of interviewing and building teams.

To unwind a bit, the goals of an interview process should be:

  • have a conversation with a candidate to ensure that you can communicate well with them (and them with you!) and can imagine that they'll fit into your team or desired role.
  • identify skills and interests, based on practical exercises, review of their past work (e.g. portfolio or open source work,) that would complement your team's needs. Sometimes takes "figure out if the person can actually write code," but there are lots of ways to demonstrate and assess skills.
  • learn about the candidates interests and past projects to figure out if there's alignment between the candidate's career trajectory and the team you're building.

Most processes focus on the skills aspect and don't focus enough on the other aspects. Additionally, there are a bunch of common skills assessments that lots of companies use (and copy from eachother!) and most of them are actually really bad. For example:

  • live coding exercises often have to be really contrived in order to fit within an hour interview, and tend to favor algorithims problems that folks either have memorized because they recently took a class or crammed for interviews. As engineers we almost never write code like this, and the right answer to most of these problems is "use a library function", so while live coding is great for getting the opportunity to watch a candidate think/work on a problem, success or failure aren't necessarily indicative of capability or fit.
  • take home coding problems provide a good alternative to live coding exercises, but can be a big imposition timewise particularly people on people who have jobs while interviewing. Often take home exercises also require people to focus more on buildsystems and project-level polish rather than the kind of coding that they're likely to do more of. The impulse with take home problems is to make them "bigger," and while these problems can be a little "bigger" than an hour, a lot of what you end up looking at with these problems is also finishing touches so keeping it shorter is also a good plan.
  • portfolio-style reviews (e.g. of open source contributions or public projects,) can be great in many situations, particularly when paired with some kind of session where the candidate can provide context, but lots of great programmers don't have these kinds of portfolios because they don't program for fun (which is totally fine!) or because their previous jobs don't have much open source code. It can also be difficult to assess a candidate in situations where these work samples are old, or are in codebases with awkward conventions or requirements.

There isn't one solution to this, but:

  • your goal is to give candidates the opportunity to demonstrate their competencies and impress you. Have an interview menu [1] rather than an interview process, and let candidates select the kind of problem that they think will be best for them. This is particularly true for more senior candidates, but I think works across the experience spectrum.

  • if you want to do a programming or technical problem in real time, there are lots of different kinds of great exercises, so avoid having another candidate implement bubble sort, graph search, or reverse a linked list. Things like:

    • find a class (or collection of types/functions) in your codebase that you can share and have the candidate read it and try and understand/explain how it works, and then offer up suggestions for how to improve it in some way. I find this works best with 100/200 lines of code, and as long as you can explain idioms and syntax to them, it doesn't matter if they know the language. Reading code you don't know '
    • provide the candidate with a function that doesn't have side effects, but is of moderate length and have them write tests for all the edge cases. It's ok if the function has a bug that can be uncovered in the course of writing tests, but this isn't particularly important.
    • provide the candidate with a set of stubs and a complete test suite and have them implement the interface that matches the test cases. This works well for problems where the class in question should implement a fairly pedestrian kind of functionality like "a hash map with versioned values for keys," or "implement an collection/cache that expires items on an LRU basis."
    • have the candidate do a code review of a meaningful change. This is an opportunity to see what it's like to work with them, to give them a view into your process (and code!), and most importantly ask questions, which can provide a lot of insight into their mindset and method.

    I think that the menu approach also works well here: different people have different skills and different ways of framing them, and there's no real harm in giving people a choice here.

  • independent/take home/asynchronous exercises tend to be better (particularly for more senior candidates,) as it more accurately mirrors the way that we, as programmers work. At the same time, it's really easy to give people problems that are too big or too complex or just take too long to solve well. You can almost always get the same kind of signal by doing smaller problems anyway. I also believe that offering candidates some kind of honoraria for interview processes are generally a good practice.

  • one of the big goals of the interview processes is to introduce a candidate to the team and give them a sense for who's on the team and how they operate, which I think has given rise to increasingly long interview sequences. Consider pairing up interviewers for some or all of your interview panel to give candidates greater exposure to the team without taking a huge amount of their time. This is also a great way to help your team build skills at interviewing.

  • assessing candidates should also balance the candidates skills, alignment with the team, with the team's needs and capacity for ramping new members. Particularly for organizations that place candidates on teams late in the process, it's easy to effectively have two processes (which just takes a while,) and end up with "good" candidates that are just haphazardly allocated to teams that aren't a good fit.

These are hard problems, and I think its important both to be open to different ways of interviewing and reflecting on the process over time. One of the great risks is that a team will develop an interview process and then keep using it even if it turns out that the process becomes less effective as interviewers and needs change. Have (quick) retrospectives about your interview process to help make sure that stays fresh and effective.'

I think this is a follow up, in someways, to my earlier post on Staff Engineering. If you liked this, check that out!