melreams.com

Nerrrrd

Be a better programmer while still having a life: part 3

Unrelated image from pexels.com to make this post look nicer in social media shares.

More stuff you can do to be a better programmer while still having a life!

The core of programming is really problem solving, but we’re kind of expected to pick it up as we go while we’re learning specific skills like programming in java. I have a strong suspicion that’s why so many new developers feel totally lost when they try to build something on their own: we’ve collectively done a bad job of teaching them how to break down problems and solve them.

Problem solving is a gigantic topic so I’m not pretending this blog post is going to be comprehensive, I’m just aiming to share a few tips to get you started.

First of all, don’t just start coding. It really helps to have some sort of plan for what you’re going to do. If you dive in and just start coding without any sort of plan you’ll often end up lost in the weeds because figuring out how to solve a problem and how to code that solution at the same time is so much harder than doing those things one at a time.

Ironically, it’s also hard not to do those things at the same time. It’s really common to feel like you’re wasting time planning and making lists when you should be writing code, or that planning is boring and no plan is ever perfect so why bother? It’s also not at all unusual for programmers to start coding without a plan because they’re worried about whether they can solve the problem, so they just start writing code and hope the complete solution will come to them.

Having a plan actually speeds things up because it cuts down on the feeling your way around in the dark that you end up doing when you don’t know where you’re going or how to get there. If you really can’t stand the planning part, programming may just not be for you – solving problems is the real job, code is just the tool we use to solve them. Making a plan may force you to admit that you just don’t know how to solve a certain problem which sucks, I’m not going to lie, but isn’t it better to figure that out right away instead of potentially spending days or weeks coding only to find out that your partial solution is never going to work? Trust me, that sucks way more.

So that’s all great, but how exactly do you break down a problem and make a plan to solve it?

One example is laid out in 5 Steps to Solving Programming Problems by Adrian Prieto. The step I want to concentrate on is “2. Solve the problem manually.” Seriously, write it down exactly the way you would do it if you had to do it manually. If part of the problem involves looking things up in the database, just pretend you have a gigantic binder or that you can call another department for the data you need. The imaginary manual procedure might sound really awful and tedious but that’s fine, computers are great at boring and tedious.

Example time! A common programming challenge question is to write a palindrome checker – you give it a string, it tells you whether or not it’s the same backwards and forwards. It’s really easy to look at a short palindrome like racecar and see that it’s obviously the same backwards and forwards, so let’s imagine we have a much longer string. Now how do we tell whether or not it’s a palindrome? One way is to look at the first character and see if it’s the same as the last character, then the second character and the second last one, and keep doing that until we get to the middle of the string (let’s assume for now that we don’t have to worry about spaces or punctuation). If we make it to the middle of the string it must be a palindrome, so we can return true. If any of the pairs of characters don’t match then it’s definitely not a palindrome, so we can stop checking right there and return false.

Now that we have a manual process, we can start adapting it for a computer to run. The thing you have to remember is that computers are really dumb. If you tell a person “stop when you get to the middle of the string” they’ll know what you mean and what to do if the string has an odd number of characters so there’s only one in the middle. Computers, on the other hand, don’t know what a “middle” is unless you tell them and don’t know what to do with a string with an odd number of characters either. For that matter, they don’t know how to tell they’ve gotten to the middle of the string.

In the interests of not making this post 5000 words long I’ll skip the specifics of telling a computer how to find the middle of a string, the important thing to know is that once you have an overall process you can dive into subproblems like “how can the computer tell when it has checked enough characters?” without losing sight of why that problem even matters and how it fits into the rest of your solution.

It really doesn’t matter how bad your first try at a process is. Writing down how you would do it manually is always good enough for a first try, and once you have a basic process you can start improving it or even trying totally different algorithms. The great thing about a simple set of point form instructions or even pseudocode is that it’s much quicker and easier to change than actual code, so you can mess with it to your heart’s content.

That works great for straightforward problems, but what do you do with an overwhelmingly large problem where it’s not obvious where to start? Let’s say you want to build a todo list app. Should you start by designing the UI? Or by figuring out what your data model should look like? How do you decide which features your app should have?

The question about what features you should have is one of the simpler ones: build the tiniest thing that could possibly work. You can always add more features later. In the case of a todo list app, I would start with being able to add new todos and being able to cross off existing ones. Don’t worry about subtasks, don’t worry about due dates or recurring tasks or anything else, just start with the simplest thing that could possibly be considered a todo list.

As for where to start, if I knew the right way to approach every problem I’d be a millionaire :) I personally like to start with the UI so that once I get down to the data model I already have a list of all the visible information that I definitely need to store. On the other hand, if you’re especially comfortable with data modelling it can be easier to start there. That can also save you from building a database that’s perfect for one screen and kind of terrible for everything else. It really doesn’t matter where you start as long as you remember to look at your overall design from different angles and see if it still makes sense.

At the “boxes and lines” diagram stage just like the point form description of a manual process stage you lose hardly any time at all if you sketch out a solution, figure out it doesn’t handle something well, then throw it out and start over. The important thing is to learn more about the problem, not to come up with a perfect design on the first try.

Like communication, practising problem solving doesn’t have to take up a single hour of your time outside of work. You can get all the practice you need on work problems while you’re at work and still have a life outside of work :)

Be a better programmer while still having a life: part 2

Unrelated image from pexels.com to make this post look nicer in social media shares.

In my last post about becoming a better programmer while still having a life, I talked about communication. Specifically, making sure you understand why you’re doing a task and what the eventual user of that feature wants to accomplish. That’s far from the only thing communication is good for, though. It’s not just about clarifying tasks, it’s also important to communicate status. Strictly speaking, this may not make you a better programmer in terms of getting things done. It does, however, make you easier to work with and that’s a big part of being a professional. And in the interests of full disclosure, I’m not always great at this, especially when I’m busy, but I try.

If you use slack, a good solution for my team and maybe yours is to post little updates about what you’re working on and how it’s going in your dev channel. When you share what you’re working on, people will have something useful to tell you surprisingly often. I’ve had coworkers tell me about existing code I hadn’t seen before that applies to my problem, ways they had already tried to do something and failed (super helpful because it narrows down what I have to try), or bring up potential issues I hadn’t thought of.

Team leads also really seem to like having a running list of what you’ve been doing and if you’ve hit any snags lately. In my office it’s common for people to work from home, which means my team lead can’t always rely on chatting with people in the lunchroom or on the way to get coffee to figure out whether our tasks are going well or not. My last set of updates were a series of complaints about how badly I was getting along with play 2.5’s requirejs plugin, don’t feel like you have to have positive or even particularly well thought out updates.

Nobody particularly likes to post a bunch of updates about how badly things are going, but that’s actually really useful for your team lead and the rest of your team to know. They can’t make plans about next week if they have no idea how much stuff is going to get done this week. Your team lead doesn’t just know what you’re doing or if you need help, you’ve got to tell them directly. If your updates are always about how badly things are going that’s a useful sign that something is wrong. It could be that you and/or your team lead need to find another solution because the current one isn’t working, it could be that your assignment isn’t at the right level for you and you need some help, it could just be that it’s an especially hard task and you’re not going to be available to do anything else for a while.

If something is going poorly, it’s always better to talk about that sooner rather than later. Seriously, waiting too long to raise the alarm kills projects. Now, it is true that in dysfunctional workplaces you may be blamed or punished for bringing up perfectly reasonable concerns. I’m not going to pretend that every boss you’ll ever have will be the perfect manager, but if you bring up a concern and get ignored or punished for “being negative” I want to reassure you that you are not the problem and didn’t do anything wrong.

If things are going well, you should talk about that too. Just like your team lead needs to know if they can’t give you another task, they need to know if they do need to get another feature specced out and ready for you to work on next.

Whether or not you ever show anyone else your list of things you got done (and it’s not a bad idea to have that handy for when annual review time comes around), just looking back at your list can help motivate you. When I feel like I haven’t been accomplishing anything, it can be really helpful to scroll back through the updates I’ve given and remember that while I maybe didn’t end up with a lot to show for my fight with requirejs, I did learn a lot about play 2.5 plugins and build processes and that will definitely be useful later.

If ongoing updates throughout the day are too much information you can do daily or weekly updates, the only essential part is giving updates on a regular basis. Definitely don’t feel like you need to write a novel for every update, status updates are meant to let people know what you’re up to, not to eat up time you could be using for your actual work.

Giving status updates regularly probably sounds like a really small thing, but it’s been incredibly useful for me.

Be a better programmer while still having a life: part 1

Unrelated image from pexels.com to make this post look nicer in social media shares.

In my last post I said that being a better programmer wasn’t worth sacrificing your entire life outside of work, but that doesn’t mean being a better programmer isn’t worth some work. Also, sacrificing all of your free time is simply not necessary. There are lots of things you can do to be better that don’t involve never seeing your friends again and/or being a bad partner. Lots of them!

Here’s tip #1 for being a better dev without killing yourself over it:

Communication!

Specifically, when you get a task, ask some questions to make sure you understand it. Some of the most important questions are the ones you’re scared to ask because you don’t want to look stupid. Like “What is feature x for?” Just because the JIRA ticket says to build an x doesn’t mean the business really needs an x. They might actually need outcome y and think that building an x is the way to get it.

Once you understand why the business needs an x you might be able to suggest a simpler solution – sometimes you don’t need a week of dev time, sometimes all you need is a cron job. Sometimes there’s a library that can do what you need quickly and easily. Sometimes there’s a product or service that does what you need for less than the cost of the dev time, plus if it breaks you may be able to make it their customer support’s problem instead of yours :)

Even if you don’t have a better solution, it’s really helpful to understand why you’re doing something and what you’re really supposed to accomplish. No spec is ever perfect, you’re practically always going to have to make some decisions on your own – knowing the reason behind what you’re doing lets you make way better decisions than if you’re just trying to guess what might make sense. That’s how things nobody wants get built (well, one of many ways they get built, let’s not pretend there’s only one cause) – somebody gets a vague spec, takes their best guess, maybe runs into some problems and has to cut part of it, maybe some of the parts that get cut are actually really important but the dev didn’t know that and now we’ve got a feature nobody wants.

Another good reason to ask questions is to clarify the spec. If you run into anything that needs more details or contradicts some other part of the spec, it’s better to know that before you start building. Nobody likes having to go to their boss after days of development and tell them that they just realised that to build the feature properly they need to build z too and that means they have to throw out the code they already wrote that only supports x and y. Nobody likes hearing that either, so think of the time you spend asking questions as an investment in not disappointing your boss/missing your deadline later.

You might find a whole extra set of problems that need to be figured out before you can build the thing you were originally supposed to. On a large project at work I found out partway through that I hadn’t put nearly enough thought into how new settings for an extension of an existing feature were going to work with the original settings. I could have saved myself a lot of time building and rebuilding handling for that if I had asked more questions in the beginning (and done a better job of planning everything out before I started building it, but that’s a separate blog post).

Not only are complications like that really useful to know about for the sake of building something only once, but the feature might get scoped down or cut entirely if it’s too much of a hassle to do it properly. That might sound disappointing but how much more would it suck to waste days or weeks of time on something that’s never going to work correctly?

And the bet part? Asking questions about work while you’re at work doesn’t touch your free time at all!

Not all problems need to be solved with code

Unrelated image from pexels.com to make this post look nicer in social media shares.
Unrelated image from pexels.com to make this post look nicer in social media shares.

If you’re a programmer and someone asks you to solve a problem, that means the problem needs to be solved by writing code, doesn’t it? That’s what programmers do, right? Not necessarily!

Knowing how to write good code is a huge part of being a good developer, but so is knowing when not to write more code. Take this question from reddit for example. If the problem is that you need an online store, writing one from scratch is the last thing you should consider. Needing to be able to sell stuff online is not a unique problem. It’s not even a slightly unusual problem. The more common the problem you’re trying to solve, the better chance somebody out there has already solved it and will sell you the solution for a reasonable price. In the case of an online store, that’s probably WordPress and one of about a zillion ecommerce plugins, or one of many (so many) ecommerce platforms.

To keep beating on the online store example, let’s talk about why it’s such a bad idea to write one from scratch. First of all, writing a whole store from nothing would take ages. If your goal is to sell things, spending weeks if not months building your store and getting everything working just right would be a huge waste of time. And don’t think you’re done just because the store works – if nothing else, you’re going to need to apply security updates to whatever it runs on, and let’s be honest, there will be bugs and you will need to fix them :) Sadly, the more lines of code you have the more potential bugs you have. The more code you write, the more code you have to maintain.

Another reason you shouldn’t write a store from scratch is if you’re taking people’s money, you have to be absolutely sure that you keep their payment details and personal information safe. Protip: security is hard and if at all possible, you should make it someone else’s problem. If you use a reputable plugin or platform, you can be reasonably sure all the security stuff has been done correctly. Aside from security, there’s also uptime to worry about. If your store goes down, you don’t make any money and you get to freak out about what brought it down and how to bring it back up. Again, if what you want to do is sell things, trying to figure out why your store went down is a terrible use of your time. Also, if you use existing software that thousands of other people have already beaten on, you’re a lot less likely to have surprise downtime.

And don’t forget requests for new features! If you build your own store, it’s going to be pretty basic at first. Sooner or later, you’re going to want fancy stuff like sales, limited time offers, discount codes, etc, etc. Yay, more stuff to worry about finding bugs in! Those aren’t even the really scary examples, either. If you decide you want to internationalize your store with descriptions in the local language and prices in the local currency, you may need to rewrite huge parts of it. And then worry about finding bugs in those parts, because there are so many fiddly little details you can get wrong with internationalization.

Developing your own [fill in the blank] can enormously expensive, too. Sometimes it is worth it to develop exactly the thing you need in-house, but sometimes it’s really not. The great thing about commercial off-the-shelf software is that the vendor can sell it for a tiny fraction of what it cost to build it because they can sell it over and over. Even the very newest junior dev’s time still has a value – is a week of their time still cheaper than buying the solution? Is having precisely the feature you want going to make more money than having that junior dev work on something more directly related to your business?

As developers, our first instinct is to start writing code when we want to get something done. That’s totally normal and you shouldn’t feel bad about it. It took me ages to learn to ask whether we actually need more code to solve a problem or whether there’s a simpler workaround. What I wish more developers were taught in school is that our job is to solve problems, not to write code. Yes, sometimes writing custom code is the best solution to the problem, but sometimes a simple wordpress plugin or a cron job is all you need :)

Talk of the day: Be Awesome By Being Boring

Because I’m a Katrina Owen fan, I’ve watched a bunch of her talks. Recently I was watching her talk on Therapeutic Refactoring (it’s great and you should watch that one too), saw that it was from Cascadia Ruby Conf, and decided to see what other talks from that conference were recorded anywhere. One that grabbed my eye right away was called Be Awesome By Being Boring by John Hyland.

The gist of his talk is that “boring” (stable, commonly used, not shiny and new) technology is awesome because you can trust it, you can get help when you need it, and you can focus on building something useful instead of fighting with your tools.

Even if you’re a beginner programmer and nowhere near ready to worry about whether your production database is going to crash, it’s still good advice. Well known, commonly used tools are way easier to learn because they’ve been around long enough to have docs written for them and to have the majority of the bugs worked out of them, they’ve been used enough that somebody else has probably run into the same problem and asked about it on stackoverflow already, and because so many people use it, even if your exact question hasn’t been asked already somebody out there can answer it.

For example, take a look at the number of questions tagged Java on stackoverflow versus the number of Kotlin questions. When I wrote this post, Kotlin was closing in on 4k, where Java had 1.1 million. I’ve heard good things about Kotlin and I’m not saying it’s a bad language to learn, just that you’re going to find answers a lot more easily with the language that has over 200 times more presence on stackoverflow. Not that stackoverflow is the be all, end all of programming language popularity, but I think it’s a decent measure of how many people are using a language.

Be awesome by being boring, it’ll make your life easier!

Talk of the day

If you share my obsession with software design (and maybe even if you don’t) you’ll enjoy this talk by Katrina Owen called Overkill. The basic idea of the talk is the use of a simple toy problem as an excuse for focused practice. I really like the idea of going back to basics as a path to mastery, that’s actually why I’ve been on my own back to basics kick on this blog.

If you like that talk, Katrina Owen co-authored an object oriented design book with Sandi Metz (who is also fantastic) called 99 Bottles of OOP. I haven’t read all of it myself yet, but I have watched (well, listened to) a few of Katrina’s and Sandi’s talks and really enjoyed them.

Link of the day: Queues Don’t Fix Overload

I really enjoyed this post about how Queues Don’t Fix Overload, it does a great job of explaining why bolting something onto your application without digging into the root cause of your problems will just make things worse in the long run.

Bonus link: I found that post in the Programming Beyond Practices newsletter by Gregory Brown, which I also recommend. Have a look at the archives, there’s some good stuff in there.

Development is communication

Unrelated image from pexels.com to make this post look nicer in social media shares.
Unrelated image from pexels.com to make this post look nicer in social media shares.

Much like development is maintenance and a creative field, development is also communication. One of the hardest problems I’ve run into with programming isn’t the programming itself, it’s making sure I’m actually building the right thing and fully understand the requirements.

Just because it’s obvious to you that a feature should work a certain way doesn’t mean it isn’t equally obvious to someone else that it should work a different way. Not that I’ve ever gotten burned by that or anything ;) As overly simple as it sounds, it can be really helpful to talk your plan for building a feature over with the person who came up with the requirements and your team lead. Something as simple as having a quick chat about how you’re going to build a feature can uncover assumptions you’ve made that aren’t right or things you missed or even existing code you didn’t know about that could really help.

If you’re working directly with other developers on the same project, it’s possibly even more important to communicate with them. At the very least you need to figure out who does which piece and how your code will work together. If you can divide a project into nicely separated pieces with an interface or API between them that definitely makes things easier, but you still need to keep in touch. Interfaces can change as you build and discover what you actually need, parts of the project can be delayed, there are all kinds of things other people on your project might want to know about.

Even if you’re not on the same project, it’s still useful to communicate with your team. If nothing else, your team lead needs to know how your task is going so they can get ready to assign you more work or re-assign a task they were going to give you if you hit a snag.

Stubbornness is more important than intelligence or talent when you’re learning to code, but that doesn’t mean it’s useful all the time. Listening to other people’s ideas is just as important as refusing to give up. It’s tempting to stubbornly insist on doing things your way, but that’s only going to hurt your project and piss off your team. An idea being yours doesn’t mean it’s the best way to do it. Of course, another dev, even a more senior one, having an idea doesn’t magically make that one perfect either, that’s why it’s so important to talk things out. It’s nice when you get to implement your own ideas, but it’s best for your project if you implement the best ideas you have available, whether those came from you or from someone else on your team.

Whether or not you actually take their suggestions, it’s really important to listen to your team. Despite what you may have heard, software development involves surprisingly little coding in a basement far away from all human contact. Professional software development is fundamentally a team sport, very little of it is so small that a single person can build and maintain an application by themselves. Working with a team means you need to get along with them and listening to them is a big part of that. If you bother asking for anyone else’s opinion, you need to give it a fair shot and seriously consider implementing it. If your mind is already made up, do the polite thing and don’t waste people’s time by asking for opinions you’re not actually going to listen to.

The preceding rant is brought to you by the many horror stories I’ve read online about people who label their listening problems someone else’s communication problem. Listening is communication. Without it, no information gets shared.

Communication skills are at least as important as hard development skills if you want to make a living as a developer. If I had to choose just one, I’d say communication is more important. Someone who will listen to me and explain what they’re doing can learn to code or code better. There’s nothing you can do with someone who can’t communicate. That doesn’t mean you have to be perfect at it – I’m certainly not – just that you’ve got to try.

What is good code anyway?

Unrelated goblin kitty image from pexels.com to make this post look nicer in social media shares.
Unrelated goblin kitty image from pexels.com to make this post look nicer in social media shares.

One of the many things that it took me a while to get a really solid handle on after college is what good code actually is. As a beginner, my idea of good versus bad code was solely based on whether it worked or not, it didn’t make sense to me that working code could be ‘bad.’ I was reading this blog post about writing good code (it’s really good, you should read it) the other day and thought I should talk about what good code actually is and why it matters.

First of all, a piece of code that works is always better than one that doesn’t. Credit where it’s due, I believe it was Deryk Barker who told us that back in college. Having an elegant, clear design for your application is great and all, but an application that actually does things is better than a perfectly designed application that doesn’t exist yet. Your design is never going to be perfect anyway, and if you want to accomplish anything eventually you need to write some code.

But once you have a working application, whether your code is bad or good matters a whole lot. Development is maintenance. That is, if anyone ever uses your code, it will eventually need to change, and if your code is bad making those changes will be much harder than it has to be.

Understanding what makes code difficult to change is something that just comes with experience, none of my projects in college were long term enough for me to really understand what makes code hard to change. In other words, you shouldn’t feel bad if you don’t understand what makes code good or bad right away, it’s a tough concept. It’s also a matter of taste. There are certainly some things that are near universally loathed, but there are many more things that are matters of personal preference.

Let’s start simple and work up to the more complicated stuff.

One of the simplest parts of good code is just formatting it consistently. One of the reasons I think python is a great first language is because it forces you to indent your code properly. It sounds pointlessly picky, but indenting is really, really important. Especially in HTML, I can’t tell you how many times I’ve failed to close a div because I didn’t indent my code nicely and didn’t see the problem. Consistent formatting not only helps you spot errors, it makes your code a lot easier to read. You know how your English teacher hounded you about proof-reading your essays until your spelling and grammar were perfect? That’s because it’s jarring to be happily reading along and suddenly hit something that looks wrong. Code is very similar, the more different each piece is the more time you spend trying to figure out what’s going on. Every fiddly little detail takes up more space in your brain, the more of them you can take for granted the more room you have left for what the code is actually doing.

Another formatting issue is taking advantage of language quirks like not always requiring curly braces for if statements. Java, the language I’ve used most, allows you to leave out the braces if the body of your if is only one line. I hate that a whole lot because it’s a trap: if you add another line to that if but you forget to add braces, that other line won’t actually be part of the if block and your code won’t do what you meant. You should always code to make it as difficult as possible to screw up, and leaving out braces makes it easy to screw up later.

Another big deal is having good variable and method/function names. I’ve talked about this before, but it’s worth repeating – variable names matter! Sure, you know what you mean right now, but will you remember why you named that variable that way in six months? You will not, so give your variables nice clear names. If that means your variable name has to be a bit longer, that’s fine. You’re going to read that code many more times than you write it, it’s really not worth worrying about making variable names easy to type.

Besides being descriptive, names need to be consistent too. If you name three methods handleNewOrder, handleCompletedOrder, and handleShippedOrder, your cancel method needs to be named handleCancelOrder. If you have an extremely small application it doesn’t matter so much, but in my experience most professional programming is done on applications much too large for anyone to just remember all the method names. If your method names are consistent, you can pretty much guess what they’re called and use another piece of code without having to dig through it to figure out what on earth the order cancelling method you’re sure exists somewhere is actually called. That’s a big waste of time

Methods/functions also need to do one thing and only one thing. This is one of those things that will make much more sense once you’ve worked on a larger project. Methods that do too much are a pain to update because you have to sort out which part of it does which thing and where you can safely make changes to one part without breaking the other one. They’re also a hassle if new code only needs part of the functionality of the megamethod, now you’ve got to either refactor it into more methods that only do one thing each or duplicate part of the functionality. Both of those are risky, especially if you don’t have automated tests.

Speaking of tests, opinions vary but I think they’re a really important part of good code. It’s really helpful to be able to make a change, run the test suite, and be reasonably sure (no test suite is perfect) that you didn’t break anything that used to work. Sometimes parts of your application will interact in ways you just didn’t think of, comprehensive tests can catch that before you migrate something to production that will ruin your support team’s day.

At a level up from methods, your objects should just be in charge of one thing and have reasonable names too. For example, if you have a simple todo list application, you probably want a user object and a list object, and you really don’t want the user object to mess with your list or your list object to update your user. The easier it is to guess where a particular function actually happens in your code (updating a user, for example), the less time you waste digging around trying to figure out where on earth users get updated.

Application architecture is also an important part of good code, but this post is already quite long enough :) The TL;DR version of architecture is that your objects should be grouped in predictable ways just like your methods are grouped into objects in predictable ways. More on that later!

What should you ask in an interview?

In a few of my how does it work? posts I’ve mentioned that asking about a particular data structure or algorithm is a boring interview question that doesn’t tell you much of anything about whether your candidate can code.

First of all, the reason I think asking someone to implement a data structure or an algorithm is boring is because all you learn by doing that is whether or not your candidate looked it up beforehand. Not even that, necessarily. Interviews are pretty stressful and plenty of people’s minds go blank when they’re stressed. I once choked on a question about the servlet lifecycle and it’s not like I don’t know how servlets work. If a question might tell you one thing and might tell you nothing, I don’t think it’s a good use of the limited amount of time you have in an interview.

Unrelated image from pexels.com to make this post look nicer in social media shares.
Unrelated image from pexels.com to make this post look nicer in social media shares.

I hate ridiculous brainteasers for the same reason – they’re just so binary.  Either your candidate gets the right answer or they don’t, which may or may not tell you anything because a stressful situation where you’re really scared of looking stupid is basically the worst possible environment to solve puzzles in.

Given all that, it seems fair to ask “Well what on earth should I ask in an interview?”

My take on it is that we’re overcomplicating the question. Which is kind of an occupational hazard, so don’t feel too bad about it :) Basically, if you want to know if someone can program, ask them about programming! Just straight up ask them how they would solve a problem.

One of my many pet peeves are wildly improbable scenarios questions like how many piano tuners are there in New York? Google, that’s how many. If you want to know how someone approaches a problem, just give them a programming problem. I really think it’s just weird to dance around the subject you really want to know about. You are allowed to straight up ask people about programming! It’s not as if programming problems are thin on the ground either (hey, what do you do all day again?), although it does take some work to find a problem that doesn’t require twenty minutes of backstory to explain why the problem is a problem. And if you’re asking improbable scenario questions because you want to see how a person thinks about a problem without them jumping directly into code, I think you’re depriving yourself of useful information. If somebody jumps directly into coding without thinking the problem through, I want to know that!

The kind of questions I think are interesting are realistic-ish (obviously you need something relatively simple if you want to ask more than two questions before you run out of time) scenarios like “given a system like x, how would you add feature y?” and “how does your solution change when you discover that the system is actually more like q than like x?” or “what would you do if production went down or was painfully slow?” or “given this description of a weird bug, what would you do to track it down and solve it?”

While every interviewing method has flaws, I like the idea of giving someone a take home project that either takes under two hours or that you pay them for, then talking about the choices they made in the interview. If you want to know if someone can code, just ask them to write some code! But for the love of god don’t ask them to do it on a whiteboard, that’s ridiculous. Coding on a whiteboard in no way resembles what a programmer does all day, even if your candidate is good at it it’s simply irrelevant to the job you’re trying to fill.

The downsides to take home projects are that they’re very biased in favour of people who have the free time outside of work to do them and that like everything else, it’s very very easy to do them badly. I’m willing to spend an hour or two on a take home project, but any more than that and I expect to get paid for my time.  That’s coming from someone who has no children, no pets, no elderly or sick relatives to look after, and practically no chores to do, too. For people who do have responsibilities, asking them to spend n hours of their scant free time on you is a big deal and you need to keep that in mind when you design your take home project.

Which is the other potential problem with take home projects: they need to actually take the amount of time you say they will. Yes, that means you need to have someone at the level you’re trying to hire for solve it first. I would say solve it yourself, but if you’ve been programming for ten years and you’re trying to fill a junior position, you need an actual junior to make sure what you’re asking for is reasonable.

That said, even the worst take home project is much more realistic than the ridiculous idea of asking people to take a short contract with you to see how they actually work with everyone in the office. There is basically zero chance anyone with any responsibilities is going to think “Sure, I’ll definitely quit my stable full-time permanent job to take a two week contract with some yahoo who might hire me if they decide they like me. What could go wrong?” That said, if you’re looking for people you can exploit, by all means keep hiring that way.

On a more cheerful note, a really good idea that came from a discussion on slack is having the candidate read some code and explain what it does. Most professional programming involves way more reading code and making sure you understand it, so much so that it seems like a really good idea to test people on that directly.

In general, ask stuff that directly relates to the job you’re asking someone to do. If you really do want them doing algorithm design then fine, ask them about algorithms. If you’re doing web apps, ask them about the frameworks you use or about general web concepts like concurrency, multi-threading, sessions, basic security, etc. If you do consulting, lean a little harder on scenarios where the candidate needs to ask questions to figure out what the client really needs, which is usually not what they asked for.

What do you think, readers? Do you have any favourite interview questions?