Learn automated testing

Dear new developer,

If you want to build good software, learn automated testing. Depending on your platform of choice, you may have good defaults or you may need to investigate options. But I think of a test suite as a “fat suit” for your code. Sure, your code can still “fall down”. But it will hurt much less.

Automated test code is still code, and that means that it has a cost. You need to maintain it (both with infrastructure and developer time). I worked on a project once that had so many tests it felt like when you made a small change to the code, you spent most of the time updating tests. That is not optimal, and those tests could be refactored. You should count on spending some time working on your test suite, but I do feel that things that may be red flags in production code are OK with test code (just because that is supporting infrastructure).

On the project with the many tests, we knew when things broke because of all those tests. And we felt comfortable changing complicated logic knowing that edge cases were handled.

On another project I wrote a lot of tests and any time there was a bug that came in for a particularly complicated piece of code (it dealt with payments), I made sure to write a test for that bug. That’s the biggest win: tests can save you from regressions. It is not very much fun to fix a bug and have it pop back up six months down the line. Writing an automated test will keep that from happening.

Tests are also living documentation, as long as they are run regularly. (Please set up continuous integration!). They will help new developers get up to speed on a project, since the new dev can tweak something and get instant feedback (rather than having to try to find where in the user interface to go.)

It takes a while to understand the right way to test. There are books to read, and examples to follow. My experience is mostly from “on the ground”. I favor unit testing anything that is complicated to understand or may change. I favor integration testing important pieces of your application. I favor knowing what your platform provides and leveraging that. I favor using continuous integration on every branch. But I realize that every situation is different.

A special note about UX. Don’t test UX that isn’t important. And realize that UX is often a piece that breaks and is hard to test. I recommend starting with something easier, on the backend or in pure logic. Functions that do things like split up strings are a great place to start.

The most important thing is to start. If you have a project that doesn’t have any testing, make that investment and do the first test, even if it is trivial (“can I instantiate this object?”). And force yourself to write tests even when you’re slinging a lot of code. It will help future you, I promise.

Sincerely,

Dan

‘You get what you give’

This is a guest post from Rylan Bowers. Enjoy.

Dear New Developer,

‘You get what you give’ isn’t just a late ’90s catchy pop song set in a late ’90s mall that gives me late ’90s cringe (and nostalgia, but those go hand-in-hand, eh?). It’s also a great way to approach your career! This is something core to the tech scene I’ve adopted in Boulder, Colorado as codified by Techstars with their Give First rule in their Code of Conduct. Their other rules are great ones to build your career around, too.

I have found that giving provides many benefits to the giver:

  1. Offering to help engenders a greater sense of observation and consideration of others’ needs and feelings. This is something we all can work on, given our reputation as social introverts.
  2. It feels good to help others with no strings attached.
  3. If you want to attach (small) strings for your own motivation, you increase how others view you in a positive light.
  4. You may/likely will find rewarding hobbies, coding interests, or other intrinsic rewards without much effort.
  5. You become less arrogant.
  6. You help build your community in a positive way, no matter how small the give is.
  7. People are quicker to recommend you for a job or position if you ever fall on harder times.
  8. It improves your own sense of self-worth and confidence.
  9. You make more friends outside of work.
  10. Did I mention that it just feels good?

My one caveat: There are always people who will take advantage, do try to be open-minded and kind, but watch out for takers, they will burn you out! Thankfully, they are few and far between.

Another great example of this is Jason Cole’s “Year of Giving Dangerously”. I must add that this way of living is out of reach for you as a new developer, but something to keep in mind for over the course of your career. Give in small ways until you can give in bigger ways!

Also, be aware that being seen as only a taker is not a good thing. See my caveat above and think back on any time in your life that you’ve ran into one. Maybe someone who always wanted to copy your answers or homework, but never contributed? Or those group projects where you felt like you were doing all the work? Don’t be a taker.

Volunteer in your community. Be the good you want to see in the world.

– Rylan

Rylan Bowers is a developer, co-organizer of Boulder Startup Week and the Boulder Ruby Meetup, and all around good guy. Follow him on Twitter.

Know your runway

Dear new developer,

When you are considering a career move, whether to a startup, a sabbatical or further schooling (basically any time when your income will exceed your expenses) it pays to calculate your runway. There are various kinds of runway (social, emotional, financial) but the easiest one to calculate is financial. You do this by tracking your monthly net outflow (expenses minus any income) and knowing your savings. Dividing the savings by the outflow gives you the months of runway you have. At the end of your runway you will have no money, which makes living hard. That is something you want to avoid.

How can you avoid the “I have no money” outcome? First, calculate your runway regularly. Once a month is optimal. Second, be aware how long it would take to get a new job (this will probably be an estimate, but ask folks with similar experience who have found jobs how long it took them). Third, before you start, decide on a number of months of runway that will cause you to start seeking other sources of income. Fourth, get a job before you need to.

If you look like you are going to run out of money before you are done with whatever you are trying to do, then you have some hard choices. You can quit or pause your task, increase your income (drive for Lyft, etc), decrease your expenses (move to a cheaper home, etc). Decreasing expenses is the option you typically have the most control over, but it can be unpleasant. It’s the course I recommend, however, because it typically is the least distracting (though if you are cutting expenses to the point that you are hungry all the time, then that may not be the case).

The reason to get a job before you need to is that desperation makes interviews tougher (more pressure). Even if you find a job and get the offer, you will accept a job that isn’t the best fit just to bring in some income. If benefits aren’t important, you may want to consider contracting as a stopgap to allow a more relaxed interview process while stopping the bleeding.

Whew. Sounds stressful. Why would you ever put yourself in situation where you needed to think about runway?

Pulling from savings and not maximizing your current income is a form of investment. When I joined a startup as a co-founder I leveled up my skills around devops, customer empathy, community building, and product management. When I took a sabbatical I learned how much I truly loved building software (I remember reading an article about RDF in an internet cafe in another country).

It can absolutely make sense to invest savings and time into something that will drawdown your savings rather than increase it. Just keep in mind how long you can invest so you aren’t unpleasantly surprised.

Sincerely,

Dan

PS This post was inspired by a comment from a Meetup participant, but all thoughts and mistakes are mine.

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 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 current 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 they 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 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 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 please 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 more time doing it the right way.

One of the difficulties of reading these kind of 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 got to work. Later, running into an issue, I went back and re-read the documentation. Lo and behold the solution to my issue was in the documentation, I just didn’t know enough to know that I needed that knowledge. There’s no way to avoid this. But having scanned the documentation for the tools you are using to solve your problem make you aware of any pre-built 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 and/or money.

However, don’t spend too much time reading docs and thinking about the problem(s) you face. 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.

Knowing the bounds of the problem and information about the tools you have to solve it will help you determine when you are in a new space, 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 is executing when the bug appears, and what did all the variables look like at that moment?

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 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