Avoid being an expert beginner

Dear new developer,

This post by Erik Dietrich covers the situation where a developer becomes an “expert beginner”. This is something to avoid as you build your career–don’t work in a place where you are isolated or unable to progress. He breaks progress in any area down into a number of components–Beginner, Advanced Beginner, Competent, etc.

As such, Advanced Beginners can break one of two ways: they can move to Competent and start to grasp the big picture and their place in it, or they can ‘graduate’ to Expert Beginner by assuming that they’ve graduated to Expert. This actually isn’t as immediately ridiculous as it sounds. Let’s go back to my erstwhile bowling career and consider what might have happened had I been the only or best bowler in the alley. I would have started out doing poorly and then quickly picked the low hanging fruit of skill acquisition to rapidly advance. Dunning-Kruger notwithstanding, I might have rationally concluded that I had a pretty good aptitude for bowling as my skill level grew quickly. And I might also have concluded somewhat rationally (if rather arrogantly) that me leveling off indicated that I had reached the pinnacle of bowling skill. After all, I don’t see anyone around me that’s better than me, and there must be some point of mastery, so I guess I’m there.

This post is worth reading in whole. It resonates with me because I’ve spent most of my career in small companies. I do that because it fits best with my desires and my life goals. But I’m acutely aware that as I become more experienced, I am typically one of the most experienced technical folks in the room. This is a problem, because I could believe that I had most or all of the answers based on my experience (what the Expert Beginner believes).

I strenuously combat that by engaging with my peers in person and online, and I think this is a great way to do so. It’s not as deep an engagement as working with them, of course, but affords me the ability to work at small companies.

Ways to engage with the larger software community include:

The work environment you are in is a great place to level up, but depending on your situation, you may end up with few people you can learn from. In that case, it is imperative that you improve yourself through engaging with the larger software community.

Sincerely,

Dan

Read the documentation

Dear new developer,

Reading the docs is so important. It is so easy, when you are confronted with a task, to just jump in and start doing. It feels right. It feels natural. It feels like progress.

The problem is that it may be motion, but it probably is not be progress. You may be spinning in circles rather than moving towards your goals.

So, the solution is to read the docs. Documents are key ways of transmitting knowledge and will let you reduce effort or reuse solutions. There are a couple of different kinds of documents that are worth reading:

Requirements/high level project docs: These are typically written specifically for the project, and will help give you a sense of direction. It will help you find how the work you are doing fits in. Depending on the size and maturity of your organization, you may find these documents in various levels of detail and completion.

If you don’t find any at all, take the time to write one, even if it is just a one page overview that answers “what are we trying to accomplish”. Send this to a senior member of your team (or of the business, if there aren’t senior technical team members) and ask “hey, did I document what we are trying to accomplish here?” If not, revise until everyone is on the same page.

Writing down these requirements can save tons of time, as they can bring new members of the team up to speed as well as bring the team into alignment. If you are working on a project with human interaction, clickable prototypes can also be useful in determining the functioning of what the team is building.

Try to keep these documents up to date, though that is always a struggle. Whenever I start a new project, these type of docs are the first thing I look for, and if I don’t exist, I start writing them. They can take many forms and can include things such as overarching goals and terms (especially if they are not common vernacular).

Even a paragraph in slack that is pinned to the channel is better than nothing, but I typically like to put them in a google doc (if the keeper of the doc is non technical) or a readme in git (if the keeper of the doc is technical). Having these kind of docs available will keep you from heading down errant pathways that aren’t moving toward the end goal. It reduces your effort.

Platform and library documents: These are the user manuals for the tools you are going to use. Oftentimes they’ll be provided by an outside source (an open source project or a company) and are general in nature. As a new developer, hopefully you’ll have some internal guidance on these tools (even if it is just a conversation on why language X was chosen). But no matter how you arrive at the platform/library/framework, it’s a good idea to learn as much as you can about the tools you are going to be using. I tend to bounce back and forth between experimentation and documentation, but find the learning style that works for you.

A thorough read of the docs will save you time. Recently I was using a snap in CMS for Ruby on Rails, a web framework. I wanted to customize the back end system and jumped immediately into prototyping code. Later I was reading through the docs and saw that there was official support for my customization. I burned a few hours of time figuring out the wrong way to do what I accomplished, then had to spend time doing it the right way.

One of the difficulties of reading these docs is sometimes you don’t know what you need to know, nor how to look for it. I can think of a few times where I was working in AWS. I scanned the documentation and proceeded to work. Later, running into an issue, I went back and re-read the documentation and lo and behold the solution to my issue was in the documentation, I just didn’t know enough to know that I needed that piece of knowledge. There’s no way to avoid such situations. But having scanned the documentation for the tools you are using to solve your problem will let you be aware of any prebuilt snap in solutions, and also may point out extension points that you’ll want to be aware of as you build out your solution. Reusing code and concepts will save you time or money.

However, you do want to be careful not to spend too much time reading docs and thinking about the problems. I’m often confronted with a problem that is newish, whether in a domain that I’m unfamiliar with or combining two or more existing pieces of software in a novel way. Sometimes there’s no way forward but to just start thinking and coding, and documentation is no guide.

But knowing the bounds of the problem and information about the tools you have to solve it will help you determine when you are at such a place, and when and where you’re on well trodden ground.

Sincerely,

Dan Moore

Job hunting tips for new developers

Dear new developer,

Joe Marshall has some interesting tips for new developers (he calls them “junior developers to be” but developer nomenclature is so broken that I prefer the term “new”). They are focused around finding a job (and Joe has a newsletter to help 🙂 ).

They range from the simple: “Read coding interview books.” to the arduous: “Github helps, but take it beyond toys. Real projects have stakeholders.” to the practical: “Take notes during interviews.”

I purposely focus on all that you need to know to succeed as a new developer apart from getting a job (though I have written a few things about interviews). I do this for two reasons:

  1. I’m no expert at getting a job as a junior developer. It’s been a long time since I did that, and the world has changed. I’m not sure I’m a good resource to help anyone get a development job, since I’ve only gotten hired for full time employment four times in my career.
  2. There are a lot of other great resources out there, and it’s a topic that many write about (because it matters a lot)

But this choice doesn’t mean I can’t point to helpful posts elsewhere. Suggest you read the whole thing.

Sincerely,

Dan

Learn to use a debugger

Dear new developer,

When you are fixing a bug in a program you are working on, a key thing to do is to get an understanding of the state of the system. This can include user input, stored values from a persistent data store, and non recurring information like the current time. But the most important piece of state is that of the program in memory. What function or procedure the

Reproducing a problem with a test or sequence of steps is crucial for being able to solve it. You should take every step you can to make sure that your debugging environment is the same as the environment that the problem is appearing in. I remember one program I was debugging that worked fine in development, but failed miserably in production. It used Google Web Toolkit, which compiled java down to javascript. In development, even when I compiled it, the obfuscated variable names were different. That ended up being the issue–there was a variable name collision between the compiled javascript and another javascript that wasn’t namespaced correctly. I tore my hair out and was reduced to putting in console.log statements on production.

And that’s how a lot of debugging happens–printing out log statements to a file. You can solve many problems that way, it’s extremely portable and customizable, and it gives you some insight into program state.

However, a far better solution is to use a real debugger. They’ve been around since the 80s, at least, and give you far more insight into a program’s state than log statements. You can see the state of any variable. You can run commands interactively. You can stop anywhere, and restart the program. If you pair an interactive debugger with an automated test, you can have an extremely tight feedback loop that will help you zero in on the issue at hand.

Most of the major languages have such interactive debuggers (in fact, that’s one way to decide to avoid a language; a development language without a real debugger is likely to have other language level issues, like a poor dependency management story). Some languages even have standard protocols where you can connect to remote servers with a debugger. If you ever have to debug a production issue and can enable that, it’s going to be super helpful.

Debuggers are often integrated with an IDE, but some are runnable on the command line. Whatever your language, just google for “<language> debugger” and find out more about this valuable resource.

Sincerely,

Dan

How to read code

Dear new developer,

Reading code is much more common than writing code. Some might even say, “don’t trust any documentation, read the code,” though I consider that to be a pretty radical position.

But how can you effectively read the code. This post from selftaughtcoders.com gives a good explanation:

Find one thing you know the code does, and trace those actions backward, starting at the end.

Rinse and repeat.

It’s a wonderfully self-perpetuating cycle: you read more code; you gain the ability to understand it quicker and more effectively; so you are able to consume even more code; and so on.

And it doesn’t stop there: you’ll also see huge positive gains in your own coding.

I know nothing about his courses, but his insight into reading code to build intuition about programming and development in general is spot on. I tend to do this through code reviews, reading blog posts and going to meetups rather than tracing code paths, but reading code can be a good way to level up. Github is your friend.

Sincerely,

Dan

The best code is no code

Dear new developer,

It’s paradoxical, but sometimes the best thing you can do is not write code. Remember, the value you provide is to solve the problem you are faced with (the outcome), not to write code. Custom code has value, but comes with costs. It needs to be deployed, maintained and upgraded. It has bugs. It requires a developer to change. It also has opportunity cost. Writing custom code to accomplish task A means that you won’t have time to accomplish task B, which may be either more urgent, more important or both.

There are a couple of ways in which you might solve a business problem with out writing a lick of code.

  • Use a library or framework. For instance, I worked at a place where they had written their own database connection pool. Why? I never got a great answer, but it wasn’t clear to me that one of the open source solutions wouldn’t have worked. You need to have an awareness of such libraries to be able to propose this.
  • Use a third party SaaS tool. I’ve seen people run their own in house git repositories. There may be good reasons to do this (including security or privacy concerns). But Github is going to give you a far better experience and unless you have a big team, probably better security and privacy. You need to know what the problem, the solution and the cost are to make an effective suggestion.
  • De prioritize the work. I was at a meeting with a CEO and we were talking about continuing an effort to integrate a set of outside data sources. I asked why, and we discussed it a bit further. It became clear that the reason we were thinking about doing it was because of inertia. It became clear that there was no real business reason to do it, and we prioritized other work instead. A clear roadmap and the willingness to question requirements are helpful with this path.
  • Do it manually. I was working on a startup and we had the need to occasionally refund customers. I could have integrated with the payment provider and had this case be handled automatically, but it was much much easier to document the process and handle it manually. Refunds happened rarely enough that there was no value in automating them. Here it is helpful to know how often the problem arises, how long it takes to fix manually, and how often it will arise in the foreseeable future.

Now, sometimes you may not understand the larger context of your work. You may propose a solution that isn’t the right fit, and there’s certainly nothing wrong with writing custom code to solve a problem.

In cases where I’m not sure I have full understanding, I always preface my questions with “I am not sure I have the full picture, but I think we could solve the business problem using solution A or project B, rather than writing custom code.” If you are working directly with the client, they likely won’t care, as long as the problem is solved. If you are on a team, the engineer or project manager running your project should have a good understanding of alternatives and why custom code might be the right solution. Most folks will be happy to share that reasoning with you.

In short, it’s better to keep your eyes on solving the business problem and be aware that custom code isn’t always the right answer.

Dan

PS No, this isn’t an April Fools Day post 🙂

Learn to use Google, and use it well

Dear new developer,

Searching is is important to writing and understanding software. Less so for giving you a base of knowledge. For that, I’d seek out books, video classes or side projects, depending on how you learn. Googling well is tough if you don’t know what terms to use. (I’ll use google as a synonym for a generic search. I’ll address issues of other search engines below.) Once you have a firm base of knowledge and understand software jargon, you can stand on the shoulders of giants.

Tips for searching:

  • Google the exact error message (almost). When you get an error message like nginx_1 | 2019/01/06 20:42:22 [crit] 11#11: *1 connect() to unix:/var/run/php5-fpm.sock failed (13: Permission denied), don’t just cut and paste it into the search box. Look at the error message, and see what is unique to your situation. For the error message above, text like the nginx instance name, nginx_1, and the date and time, 2019/01/06 20:42:22, are unique to my installation. Searching on them won’t be useful. But the message text starting with connect() looks like it will be far more common and will likely yield good results.
  • Read the results, whether forum post or documentation, carefully. I’ve been bitten by this more times than I care to remember. But it’s very easy, when you find a stack overflow, forum or other result that seems to apply, to just cut and paste the top answer as quickly as possible and get back to what you were doing before you started searching. This is the quick path, but the better choice is to read the entire page and make sure that they are addressing the same issue that you are trying to address. You also want to pick the best solution (which may not be the first one, especially if the page is old). Sometimes newer libraries or releases have different paths forward, and so you should try to map the software you are working in to the one that the page refers to. The other reason to scan the entire page is that it will give you a sense of the different solutions. The underlying goal of doing the search is to incorporate the knowledge into your understanding so that you won’t have to do this Google search in the future (you may have to search in your project or commit log, but that’s quicker than redoing a google search, especially months from now). Trying to understand all the solutions and what they are doing is a way to be a just in time learner. Mindlessly copying the solution isn’t.
  • Add links to what you find in your commits and your comments. Do this especially if the solution is complicated or esoteric. You should of course write a commit message that explains your intent, but adding in the link can give additional context.
  • Think about the terms you use in the query. This is where foundational knowledge comes in. For example, if you know that active record is an object relational mapping tool, or that ruby is a dynamic language where every class can change another (which is called “monkey patching”) then you can know how to google for things related to these concepts. If you want to change a specific active recrod behavior, you might google “how to monkypatch active record” which will get you far more focused results than “how do change the rails database system”. This ca be iterative. Pay attention to the terms used in posts you find, and use them in new queries.
  • Consider using an alternate search platform. I use duckduckgo.com as my default search engine. Frankly, it’s not as good as Google, but it gives answers I need in about 75% of the searches, and I can easily run the same search on Google if I need it. I am supporting an alternative search ecosystem that will be better for the internet in the long run.

A last point is important enough that I’m going to break it out. Google, and search engines in general, work well because there’s content out there produced by people. You can take part in producing that content, either by adding to stackoverflow (which can be as simple as just voting an answer up or down–after you’ve tried the solution out), writing a blog post or responding to that forum post. If you encounter an issue no one has ever seen before, write it up, like I did here. This participation in the wider internet is crucial for the continuing useful functioning of the internet. So, participate in some way and give back.

 

Using Google to solve problems lets you leverage the hive mind for your development work. Don’t just use it. Use it well.

Sincerely,

Dan