How to be a successful junior engineer

Dear new developer,

I enjoyed this post from Hanah Yendler on how to succeed as a new developer. Note that she is working at Eventbrite, a larger company (1100 employees according to wikipedia), so some of the advice may be a better fit for new developers at bigger companies.

A few of the pieces of advice really resonated with me:

Take responsibility for something that seems slightly out of your reach. One of my previous managers at Eventbrite told me that he wants me to be sitting just on the edge [of] fear because that’s where intense learning happens. I have a huge fear of failing, but taking responsibility means pushing yourself and growing as an engineer.

and

It can be tough to get a subject matter expert (aka an engineer more senior than you) to explain things on a level that you can understand –especially when they have very intimate and in-depth knowledge of a system or complex subject. This is where asking questions becomes essential. You can use questions to help guide them to the answer you are searching for.

Both of these pieces of advice are true when you are new to the industry and true when you have decades of experience. (Pushing yourself to the edge of your comfort zone is how you grow, and asking questions is one of the fundamental ways to learn.)

The whole post is worth reading.

Sincerely,

Dan

Don’t Shit on Someone Else’s Work

Dear new developer,

There will come a time when you are looking at a system and trying to understand the choices behind it. You may be looking at a particular class, a subsystem, or a more fundamental choice, like the language or the system architecture.

And you’ll wonder what the hell the initial implementer was thinking. You’ll wonder why this system is still in production. You’ll wonder why someone didn’t fix this.

You will be tempted to trash talk this piece of work to your colleagues.

Don’t do this.

Why?

It’s not helpful. Now, it’s perfectly acceptable to point out issues and ask questions about why choices were made. It’s a good idea to suggest improvements, whether those be code changes, removal or replacement of portions of the system or something else. But complaining about the existing system doesn’t do any of that. It’s just complaining.

It displays a lack of empathy. Chance are you don’t know the constraints and pressures that the original implementer and past maintainers faced. Making judgements based on code without knowing the constraints is like hiring someone based on the color of their shirt–you just don’t have all the information needed.

Trust me, in the future you’ll face constraints, like lack of knowledge, time or labor or money, that will cause you to make choices that are suboptimal. At least once in my career I’ve come across a boneheaded piece of code. Cursing under my breath, I wondered “who wrote this crap?”. As I pulled up the commit log, my face fell as I realized that I had. Doh!

(What should you do if the code or system doesn’t work at all? In that case, the questions about constraints and understanding how a failed system was built are even more important. But again, complaining doesn’t help anyone at all.)

In short, when you are working in a codebase and trash talk it, you are the critic, not the man in the arena.

Sincerely,

Dan

Three Tips for New Developers

Dear new developer,

I ran across this post with three tips for new developers.

The tips were:

  • Develop broad expertise
  • Work in application support
  • Hone your interpersonal skills

This especially resonated with me. Note that the javascript frameworks indicate this article is a bit dated; I’d substitute React, Vue and Angular for jQuery, MooTools and Prototype, but the premise is the same. You can’t make an intelligent choice between alternatives if you only understand one of them.

To sum it up, I advise new developers to work with multiple platforms. For instance, C# developers should get familiar with truly open source alternatives like PHP or Ruby, and web developers should get to know more than just one JavaScript framework like jQuery — they should get to know MooTools, Prototype, and more. Another consideration is that doing consultant work often means working within the client’s environment and technologies, so the ability to dive into new (or new to you) technologies is a must.

I can’t argue with any of these. From a high level view, when you are beginning your career, you want to learn as much as possible from a variety of perspectives. This will inform your career in the future and let you make decisions from a position of knowledge, rather than assumption. So spread your wings. When I was a new developer, I worked all up and down the software stack, from server management to database administration to front end development. And I learned what I was both good at and enjoyed.

The other thing to be aware of is that you are more likely to be hired for potential rather than knowledge early in your career. That means that if you step into, say, an application support role and then want to move out of it, you can focus on what you learned or how you improved the company, rather than what you did. A senior application support developer who’d been working in that field for ten years would have a harder time making that pitch than a newer developer.

Finally, improving your “soft” skills of communication and team work will pay dividends in the future. Rare are the developer jobs that are 100% (or even 80%) focused on coding. Defining the problem is often the hardest part of the development process, and it certainly has the most value. (Which would you rather have, the perfect solution to the wrong problem, or the 80% solution for the right problem?)

The entire post is worth a read.

Sincerely,

Dan

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