What if I have to make a technical decision and I don’t know the right answer?

Dear new developer,

Sometimes you are confronted with decisions for which you simply don’t know the correct answer. This has happened to me many times over the years. A recent example is that the client wanted to build an online quiz. They wanted to be able to edit quiz questions and answers. They wanted it to feel like an application (rather than a website). I had never built something like this before, but I was the person best situated to make the architectural decision which would underpin this application.

You may not have time or money to do all the research you feel you need. You may be doing something that has simply never been done before. You may be in an arena where you are being pressed for a decision (like a meeting).

If you are in a situation where you have to make a choice about a fundamental architectural decision (like a platform/library/framework), you probably are in a small team moving fast, or at a company where you are one of a very few number of technical folks. In this case you may feel over your head and incapable of making the correct decision.

And yet, the decision still needs to be made, and you are the one who has to do it. (The unfortunate fact is that the too late perfect decision is worse than the pretty good timely decision.)

Techniques that won’t work out well for large important decisions:

  • avoiding making the decision
  • googling for an answer and take the first option provided
  • deferring to someone else
  • doing a thorough full examination of all the possible solutions, draw up an excel spreadsheet and a powerpoint to make sure you haven’t missed anything
  • avoiding discussion among team members

Here’s how to proceed.

First make sure that you do need to make the decision, and that you have the proper business context. The number of choices that you should consider and amount of research you should do depend on the impact of the decision. Things to think about:

  • how much of the business does this touch? If it is contained or constrained, you can spend less time thinking about this. If you are implementing a small micro service, or if you are choosing a service that is only used by a portion of the organization (like github for your code), then a choice that needs to be unwound will be easier to do. If you are picking the development language that will be used for the core product, rewrites are almost guaranteed to be far in the future.
  • how irreversible is the decision? Most decisions aren’t irreversible given enough time and money, but some are easier than others. Swapping out one memecached provider for another is pretty trivial, but changing from mysql to postgresql is more complex. Changing from GCP to AWS can, depending on the amount of data you have, be person-years.
  • does your company have internal solutions that you might be able to leverage? The bigger the company, the more likely the problem has been solved before, and finding that solution will be quicker and better than rebuilding it.
  • can you defer the decision until later? Is there a manual process or a service you can buy that will avoid a technology investment, even for a few months?

If you can’t defer the decision, then make the best one you can with the information you have. Research based on the impact on the business. I want to acknowledge the uncomfortable tension between knowledge and action that are at the root of any decision made with incomplete knowledge (aka, all of them!). There’s a spectrum based on risk and commitment, and unfortunately, I’m not aware of any great heuristics for determining risk or commitment other than experience and reading.

My approach towards such a decision is:

  • learn what you can. This includes finding out as much as you can about the problem, including current solutions
  • bounce ideas off of others in the company, but make them specific (both in form and in who you ask). This will help avoid analysis paralysis
  • ask for recommendations. Start at your current company. Even if you can’t find someone who has direct experience with the problem, there may be people who have related experience. You can also google to see what other folks have said about the various solutions (make sure to limit the results to “the past year” or you’ll end up reading about old versions). It can also include searching for experts on twitter and linkedin to ask questions (or to look at their blogs/sites to see if they’ve answered it already). And finally, don’t forget to look for communities (slack, old fashioned forums, open source project email lists) and see what they say. It’s far better to read what you can rather than pop into these communities and ask–those kinds of requests can happen often enough to annoy folks. But if you don’t see any answers, do ask.
  • realize that no decision is perfect. In 20 years of development, I can tell you that I’ve never made a perfect decision, they all involved tradeoffs and lack of perfect knowledge.
  • communicate the risks with the business. This includes the risks of you feeling like you are over your head, as well as any other risks that your research has found.
  • come up with a recommendation and implement it.

Again, hopefully you won’t be confronted with a far reaching architectural decision for a number of years, but it happens. Hopefully this framework gives you a bit of guidance toward making that decision.

Oh, and if you wanted to know my quiz conundrum ended, some of the choices I made were implemented, and others got swapped out as the team changed. The app was a success.

Sincerely,

Dan

Things learned the hard way

Dear new developer,

Sometimes you only learn through experience. This post catalogs 30 years of experience. As I read this, I nodded my head often.

Good points include:

Be ready to throw your code away

A lot of people, when they start with TDD, get annoyed when you say that you may have to rewrite a lot of stuff, including whatever your already wrote.

TDD was designed to throw code away: The more you learn about your problem, the more you understand that, whatever you wrote, won’t solve the problem in the long run.

You shouldn’t worry about this. Your code is not a wall: if you have to throw it always, it is not wasted material. Surely it means your time writing code was lost, but you got a better understanding about the problem now.

and

A language is much more than a language

A programming language is that thing that you write and make things “go”. But it has much more beyond special words: It has a build system, it has a dependency control system, it has a way of making tools/libraries/frameworks interact, it has a community, it has a way of dealing with people.

Don’t pick languages just ’cause they easier to use. Always remember that you may approve the syntax of a language for being that easy, but you’re also enabling the way maintainers deal with the community by choosing that language.

and

Don’t mess with things outside your project

Sometimes people are tempted to, instead of using the proper extension tools, change external libraries/frameworks — for example, making changes directly into WordPress or Django.

This is an easy way to make the project unmaintainable really really fast. As soon as a new version is released, you’ll have to keep up your changes in sync with the main project and, pretty soon, you’ll find that the changes don’t apply anymore and you’ll leave the external project in an old version, full of security bugs.

and

Companies look for specialists but keep generalists longer

If you know a lot about one single language, it may make it easier to get a job, but in the long run, language usage dies and you’ll need to find something else. Knowing a bit about a lot of other languages helps in the long run, not to mention that may help you think of better solutions.

The whole thing, though long, is worth a read.

Sincerely,

Dan

There is no perfect system, it’s all about the tradeoffs

Dear new developer,

I want to build perfect systems. There’s something so beautiful about a perfect bit of code that solves a problem elegantly and succinctly. Especially if it comes with a set of unit tests and great documentation.

But, every time I start to work on any real world problems, tradeoffs come into play. Let’s take the example of a simple website that is going to display some information about a business and will occasionally be updated. Some tech tradeoffs to consider when thinking about what to build:

  • how prominent is the business?
  • what is the brand of the business?
  • how often will updates occur?
  • how large does the website need to be?
  • what is the business trying to achieve (a simple online presence? leads/future customers? lowering customer service request frequency? some other business goals?)
  • who is going to be doing the updates? how savvy are they?
  • what is the budget?
  • what is the timeline?
  • who is available to do the work?

Every one of these has an effect on the kind of system that you build. A website for a local jeweler that just wants to have a web presence, show store hours and highlight occasional sales is going to be built one way. A website for a newspaper that needs to be updated regularly and stand up to occasional large spikes of traffic should be built in another fashion. They both might be pretty simple sites, however. You need to find out what the goals are and that will inform the tradeoffs that you have to make.

The point is not that one site or technology is better than the other, it is to acknowledge and make sure everyone is on the same page regarding the choices. (These choices can evolve over time. I have worked on several sites recently that were implemented in perfectly good technologies for their time, but now are aged.)

This letter was inspired by this twitter post (thanks Samuel).

Sincerely,

Dan

Assume Positive Intent

Dear new developer,

I enjoyed this post from Rick Manelius (who also did a guest post a few months ago) about assuming positive intent. From the post:

Chris [a client] could have crushed me, and yet he didn’t. In fact, he did the exact opposite and taught me an incredibly valuable lesson. Amidst the bickering on one phone call, he asked his colleagues to stop this behavior and to assume positive intent instead. He went on to describe how this is a philosophy he’s adopted in his personal and professional life as a means of being more efficient, effective, and solution focused. After all, approaching any situation with the opposite mindset results in wasted time and energy. Assuming negative intent means you’re spending lots of time second guessing everyone’s motivations, being combative instead of collaborative, and slowing everything down by having to update contracts meticulously instead of going off of a handshake.

In general, assuming positive intent makes your life better at little to no cost. There are places where it isn’t appropriate (and Rick covers some of them). But having an operating assumption that everyone is trying to do the best they can is a good way to view the world. It’s a lot more fun. It leads you to partnership (rather than strife).

Sometimes I struggle with this. As developers, we spend a lot of time thinking about how things can go wrong. Sometimes I’m not as trusting as I should be. But when I’ve assumed positive intent, I am rarely wrong.

Sincerely,

Dan

Someday, You Won’t Want To Code For A Living

Dear new developer,

I remember the first full time coding job I had. I was able to  work on a great team, on interesting problems. I was able to get into the “flow” that is such a magical state. I was paid well. I had free snacks.

I remember going into my manager’s office and chatting with him. He seemed a bit stressed. He was constantly interrupted. He had lots of meetings. He seemed to want to code, but didn’t have time for it.

Me being the naive young optimist, I asked him once why he wasn’t coding. Why would he leave a really fun job for management?

He looked at me with a knowing smile and said something like “one day, you’ll understand”.

I don’t code for a living now. Oh, sure, I write some code. And it still gets me into flow. And I still enjoy it.

But the honest truth is that when I am coding, I have the leverage of one person. As I grow older, I grow more impatient to effect change in the world. The best way to effect change is to have more leverage. Some options for higher leverage:

  • writing
  • project management
  • product management
  • speaking
  • mentoring
  • leading a team
  • managing
  • teaching
  • architecting
  • consulting

Most of these involve communicating about coding (or other technical systems), but coding is not the primary work output. Instead, the emphasis is on knowledge or alignment of a team.

Now there are also code specific ways to get more leverage. Two that I can think of.

  • work on really big systems that have a lot of users (FAANG companies, or something similar).
  • work on open source libraries or projects that have a lot of users

If either of those floats your boat, then pursue that. I don’t like the first because I don’t really enjoy the bureaucracy and politics of big companies. I am not a fan of the second because I don’t really enjoy working for free.

By the way, no one says you have to have leverage. I’ve just seen that happen again and again across many companies and many individuals. Part of that might be the crowd I run with, but part of it might be that more leverage typically means more pay.

Your career is long. My guess is that one day you won’t want to code for a living. Enjoy it now, but keep your head up and think about what other areas, focusing on communication or team alignment, might eventually be of interest to you. Learn about those areas. Meet people who are currently doing them, and ask questions.

Sincerely,

Dan