Habits of efficient developers - WeAreDevelopers 2018
Video from my presentation on WeAreDevelopers 2018 on habits of efficient developers
The video of my WeAreDevelopers talk on “Habits of efficient developers” is online. This is what you can expect:
Slides are here and the full video:
Feedback and questions welcomed!
Hello everybody, my name is Daniel I work for a company called Akvo and we are here today to talk about efficient developers.
So the first thing that I want to do is define what we mean by efficient.
To be efficient means achieving maximum productivity without wasting resources, and in our case as developers that resource is usually time, which means to be efficient is to do things fast.
But this definition is missing one key element for us that we can see in this quote by Peter Drucker:
So to be efficient is not that we have to be very very fast, it’s that the things we do, we have to do them in a proper way, so the decisions that we take today don’t slow us down in the future.
Now that we have this quote here you maybe wonder: well what is more important to be efficient or to be effective?
Obviously doesn’t make any sense to go really really fast if you end up in the wrong place, but equally if we know where we want to go but we never reach that place it doesn’t make sense either.
In fact there is some synergy between the two: if you are efficient it means that you spend less, time takes you less time to do things, which means that you have more time in your hands to stop, look around and make sure that you’re going in the right direction.
So to be efficient allows you to be more effective.
Now, in this talk we are just going to focus on what it takes, what it makes us efficient.
And we’re going to start talking about focus.
There are plenty of studies that try to quantify what is the cost of an interruption for us developers, and it seems that the cost is around ten or fifteen minutes. So every time that somebody comes and interrupts you it take us between ten and fifteen minutes to reload the context of the tasks that we were doing to be able to be productive.
So it paramount to be efficient to minimize the number of interruptions that we get, so we have long periods of time where we can focus on the task at hand.
There are basically two types of interruptions: the ones that you control and the ones that other people control the ones that you control.
This one, email notifications, is probably the worst offender.
If you think that that little pop-up doesn’t nothing for your concentration, the truth is that for your brain it looks more something like this:
You cannot just stop looking at it. Millions of years of evolution have made our brains really sensible to any unexpected movement, mostly because the fear of being eaten.
So when that little pop-up shows up on your screen you have to focus on it. You don’t have an option.
1a. Disable ALL notifications
So efficient developers the first thing that they do they disable all notifications.
Not just email notifications, but absolutely all notifications. In fact you don’t even want to see that little number with the number of unread notifications on your screen, because as soon as that little number changes, your brain is going to pick up the change and you’re going to start thinking about who could send my an email or what do I need to read.
So you can always deal with emails whenever you want, whenever you have the time. Nobody should expect that you’d reply immediately to their emails. There are other means of of communication that are more appropriate if something is really really urgent.
Emails are asynchronous and it’s more efficient to deal with them in batches.
The only notification that you want to say is the one that tells you that you broke the build.
And please never be one of these guys:
That they type an email and they want to tell you just to make sure that you received an email this is really really annoying.
And this brings us to the other types of interruptions: the ones that you don’t control.
What can you do with somebody comes to your desk and interrupt your flow? I know three possible options.
The first one is to wear some headphones. Really, really big, so when somebody comes you pretend that you didn’t see him and you hope that he will just walk away.
The second option is that you have a very good team, somebody like this guy:
Somebody that is able to tackle any interruption before it reaches the team.
1b. Pair Programming
The third option is to do Pair Programming.
If you are doing pair programming, when somebody comes to interrupt you, what should happen is that one of the two developers in the pair stands up, walk away a couple of meters and deal with the interruption, and when he’s done he goes back to the other pair, and that other guy, that was able to keep focus, works like a really fast cache to get him into a productive state a lot faster.
The additional benefit of pair programming is that, because you have another developer looking at what you are doing all the time, you are not going to check the news or your phone or your email as often, so that peer pressure is just going to cause you to be more efficient.
I don’t think I need to explain this, right? We all know it, and I don’t like to sound like your mom when she tells you to eat your greens.
So let’s move to the next one.
1d. One thing at a time
Efficient developers just do one thing at a time and the reason is exactly the same why we hate interruptions: because of the context switches.
Image attribution: https://www.targetprocess.com/articles/speed-in-software-development/.
Here we see that doing the blue task after finishing the green task, it just takes less time.
In fact it is not just that it takes less time, when you try to do multiple things at the same time, the quality of your work usually suffers.
We all know that the definition of multitasking is:
Just screwing several things at the same time, so you should always focus on one thing, finish it and then you move to the next task.
2. Master IDE
You, me, we are all going to spend thousands upon thousands of hours in front of your IDE. It’s one of our main tools, so you really need to know it inside out because any efficiency that you gain in your IDE is going to be multiplied but those are thousands of hours that you are going to spend front of it.
2a and 2b. Functionality and shorcuts
Basically need to know two things: its functionality and its shortcuts.
Now just because you are sitting already in front of it for six hours a day it doesn’t mean that you are going to master it.
To master your IDE you have to make a conscious and deliberate effort to learn it, to find what functionality you don’t know about it.
You can read the release notes, you can follow blogs or YouTube channels of people using it or you can just do pair programming.
2c. Pair Programming
When you do pair programming, each of your partners is going to show you how they use the IDE and it’s going to show you functionality that you didn’t know about, or it’s going to show you more efficients ways of doing some tasks. Also you can teach him your tips and tricks, so you make the whole team more efficient.
3. No menial work
I’m always surprised about the amount of manual work that we, developers, can put up with. And I found it very paradoxical, given that we are paid to automate others people’s job.
Manual work is not just slower to do, but it’s dull, boring and error prone. So I’ll always wonder well why we keep doing it.
I think one of the main reason is that we sometimes forget that:
And as developers, we have this very rare and powerful skill that allow us to create an army of minions that will do as we say, they will not complain about it, they never get tired and they do it really really fast.
And I think we don’t use this skill often enough.
Sometimes, it maybe because we just end up with this kind of minions:
But that’s a different talk.
Just to make sure that this sinks I’m going to repeat it again:
You don’t do things that a computer, that your computer, can do for you.
3a. Write programs (for yourself)
So efficient developers before starting any task they always think: well, can I write a program to do the task? or at least to help me to do the task?
And I’m not just talking about automating some work that can take you hours, I’m also talking about automating tasks that can take you five seconds, but you do several times a day.
And I am so talking about writing programs for one of tasks that you’re never going to do again. First, because maybe is more efficient, you can do it faster, but second because, I hope that, writing programs is fun. At least it is fun for me, more fun at least than doing things manually.
To write simple programs there is nothing like old good Bash Shell.
I have been a developer for eighteen years and during those 18 years I have changed operating systems, I have changed programming languages, I have changed IDEs, I have changed my mind up about all kinds of ideas and practices.
The only thing that has been constant during those 18 years has been Bash so I want to show a little demo about what bash can do for you
(Failed Demo from min 10:00 to 14:00)
It doesn’t matter!
So I’m going to then move to the next thing that is, whenever you are writing a program you should always time limit the amount of time that you are expected to use on it, this is a good example, right? because if I keep going I will spend the next 25 minutes just trying to get it working.
So whenever you are trying to write a program or automate a task, the first thing that you should do it’s time limit it. And if after that time limit you are not able to finish it, just move on and do things manually.
Now, even if you think that that’s a waste of time, I tried to for five minutes to get this thing working and I didn’t get it, well, the truth is that you have learned a little bit. That’s not wasted time. That’s invested time on you, learning and getting better.
Image attribution: https://xkcd.com/1205/.
This is a nice table from a XKCD that tells you how much time you can expend to automate some tasks. So have a look at that.
3b. Avoid GUIs
And if we are talking about writing programs, what you should always do it’s avoid graphical user interfaces. Why? Because you cannot put a UI inside a for loop. UIs don’t compose. They just live in their little world.
Now, I’m not saying that you should never use them, because they are extremely useful when you are getting started, when you are learning something new, but once you are past that phase of beginner you will actually want to do more complex stuff and UIs just constrain what you can do.
3c. Automated testing
And if we’re talking about avoiding UIs, the first UI that you want to avoid is your own applications’ UI.
There is nothing less efficient than starting application, clicking things around, and filling up forms to know if your feature, the new feature, is working or if you broke anything.
A part of making this more efficient, automated test also the give us the confidence to refactor and change code because it’s going to catch bugs.
And bugs are the worst time waste of all. First, you need to write that the bug, then somebody has to review the bug then you need to put the bug into production, and then by the time some user notice the bug, you have gone through this massive context which, because you probably wrote the bug several weeks ago and so, even if you wrote the code that has debug, that code is already alien for you, and you have to dig into it, and then you need to fix it, you need to go review it, you need to explain it to your boss, you need to fill some JIRA issues, and then you need to go again through all the release process.
So bugs are just a big waste of time.
But worse than a bug it’s having the same bug twice, right? so whenever you go and fix a bug, the first thing that you should do is write a test to prove that you are able to reproduce the bug, you see it fail and then you fix it.
3d. Repeatable Development Environment
And the last thing that you want to avoid to do manually is setting up the development environment, right? This is not going to make you just more efficient but the whole team more efficient.
This is how the instructions for any project that I joined look like from my point of view.
Image attribution: https://www.flickr.com/photos/jackbetty/4427395256.
And the only thing clear about them is that they’re not going to work. Maybe they are missing some step, or they’re not precise enough, or maybe I will make some silly mistake when I try to follow them, and the result is always the same, two, three, four days of wasted time.
What you want to achieve its instructions as close as possible to this:
Just one command. And that one command should bring all the tools, and configure them, to be able to build, run and test your application.
If you need a database, it should install the database and configure it, and seed it with some data.
If you need any build tool, maven, NPM, whatever, it will download the correct version of maven and install it, and configure any SDK that you need.
As you can see my tool of choice right now to do this it’s Docker Compose, which is part of the Docker suite.
If you are not familiar with it, this an example:
Here we are see that our development environment needs three containers: a Postgres DB, a Redis DB and our own application.
This has multiple benefits.
First thing it takes use minutes for somebody new to get started, but also if something stops working on your development environment you can just easily just wipe the whole thing and start again. If there any change on the development environment, you know, its share immediately with the whole team. And the instructions never get out of date.
Also because Docker is running things in isolated environments, it means that if two projects that you’re working on they use completely different versions of a database or a JDK, well they’re going to be completely isolated, so it doesn’t bother one and the other.
And also because it’s so easy to make changes, it allows you, it encourage you, to experiment. If you want to try a new JDK or SDK or a new version of the database, just make the changes, started it and if you don’t like it, you just completely wipe the whole environment.
4. Fast Feedback
And the last section that we are going to talk about is feedback.
It doesn’t matter what you are working on, you should always try to find the shortest and tightest feedback loop possible.
Feedback is what its telling us if we are going in the right direction.
Feedback make us at the same time more efficient and more effective.
You want feedback often and early, to make sure that you don’t wander on the wrong path for too long, with the consequent waste of time and energy.
4a. Test-Driven Development
If we talked about the benefits of automated test, yeah, we save time, it catches bugs, allow us to the factor, when is the best moment to write tests?
Well my opinion is before you start doing any coding.
If you’re not familiar with the TDD workflow it’s basically this:
I’m going to go really fast through it.
You first write one test, and only one test, you run it you see it fail, you see it fail and then just write enough code to make that test pass, and then you refactor, you clean up, your code, running the test just to make sure that you didn’t break anything.
There are least four reasons why you want to use the this workflow:
The first one is the fast feedback that gives you. As you are building the new feature to know that your code is doing what you expected it to do.
The second reason is that, if you truly believe that automated test saves you time, you want that benefit as soon as possible, as you are developing the new feature.
The third reason is organizational. I have hears too many times the phrase “I don’t have time to write tests” or “I’m not given the time to write tests”, and for me just actually means that, well, “I always write my code, I finish my feature, and once I finish my feature, is when I do try my test, and if there is any time pressure, well, you know, I’m not going to, I don’t get time to write those tests”.
And because you don’t write tests, it means that you don’t refactor your code, because to refactor code you need a very good automated test suite, and because you don’t refactor code, it means that your code starts to accumulate garbage, and because your code starts to accumulate garbage, it takes you more time to actually build new features, and because it takes you more time to build features, you get more time pressure, and you have more time pressure so you have less time to write test, closing a vicious circle cycle that always end up with the same: with us, developers, crying for our rewrite.
And the four reason why you want to write your test first it’s a mechanical reason:
Seeing a test fail is the test that test if the test tests what is supposed to test
Or in simple words, how do you know that your test doesn’t have any bug?
If you write a test and you see it red, there is a strong indication that there is some piece of production code, some logic, that is not there.
If you write the test and you never see it red you don’t know if it is because you’ve ready implemented a feature, or because you forgot on an assert in your test, or the setup code is not correct.
Now when you present this idea to a lot of people they always come up with this phrase:
I can’t write a test first because I don’t know what I’m going to build.
And this can mean different things.
It can mean that you don’t understand what business is asking you to do. And in this case it’s true you cannot write any test, but you cannot write any production code either. What you have to do is go back to business and ask for clarification. What do you want to do?
The other case is that you actually understand business, and you’re too actually understand the logic that you need to build, but you don’t know if you are going to write one class, or ten classes, or if you are going to put an if statement or a switch or a factory factory factory.
You don’t know what you’re going to do, but you know, understand, the logic, and you know, understand, the mechanics of the side effects. So you know which database you are going to use, you have use it ten thousand times already, you know the table, you know everything.
In all these cases you can actually run a test first.
But it’s true that sometimes we actually don’t know how to do the side effects that we are asked for. We, for example, may know that logic for your new application, functionality it needs to call some restful endpoint, to get some forex exchange, and you have never used it, and you don’t know the end point, and you don’t know what you need to give to it, and you don’t know what it’s going to give you back. Or maybe you need to consume some messages from a message queue, and you have never done that, so you don’t know which libraries to use, you don’t know how they work.
In all those cases you don’t really know what you don’t really know what are going to do.
There is always this face of exploration that we have in our job that we used to fill up those gaps, to convert unknown side-effects into known side-effects
And that’s something that TDD doesn’t help you with.
What you want to do it is, first, read the documentation to see if you are able to fill those gaps, and the second thing you want is to write a lot of little programs, to test, to play around with that technology.
For this the best tool that I know it’s a REPL.
REPL stands for read eval print loop and it’s just basically a fancy way of saying that you have like a command line interface inside your application.
Instead of trying to explain it, let’s see it in action, if it works this time.
(Demo from 25:00 to 29:30)
4c. Code reviews
The last thing that we are going to talk about it’s code reviews.
Code reviews tell us if the design of the code that we are doing, if it fits the application.
It allows one of your your teammates to tell you if you have any bugs, and it also we can use it to share knowledge, right? It’s a way of sharing knowledge.
So efficient developers want their code to be code review.
Now there is something very true behind code reviews.
When we are presented with this huge massive changes, I don’t know what your reaction but my reaction is something like “oh my god”.
But when we get small changes, we are able to give useful feedback to the author of the change, because we are able to understand the change.
Also, even if you are very disciplined developer and you go through that really painful review process, in my experience what does it happen when you go and tell the author like, well you know, I think your design is just shit, no, no, no, your sorry you could improve your design, or we could use a different library that will save us some time, or some resources, or whatever.
What usually happens its the author say like, yeah, I think you are right, but you know, I have already spent like several days or weeks working on this, and the end of the sprint is tomorrow, so even if I think you’re right, I don’t think I’m going to have time to do your change, what you’re suggesting, because it’s going to take me several more days to do it. Also, you know, it’s already working. So let’s do something different, let’s just commit the change as it is, and we are going to ask the product owner to create a refactoring story. I’m sure he will be delighted to put it on top of the priority queue.
And we all know that those things never happen, so you end up again with worse code that, leads to this lower implemented feature, with blah blah blah…
So efficient developers, they don’t want just code reviews they want small and early code reviews
4c. Continuous code reviews
So what they actually want is continuous code reviews.
This practice consists on getting one of your teammates to sit just beside you, and as you are implementing the feature, this developer sitting beside you, is going to suggest improvements on your code, it’s going to be catching bugs that you are doing, and for the reviewer the changes are really, really, small. Ss you type them, he see those those changes, and for you, as the author, you can get feedback even before you start writing any code.
Additionally if for whatever reason you are not able to finish the feature, this other developer it’s able to pick that feature without any effort, because he has been behind each of your decisions, so you avoid those knowledge silos within the team.
Also, this this other developer can work as your personal StackOverflow, because maybe he has already found that similar issue and he already knows how to fix it. And sometimes you don’t even need to ask the question because he sees what you are doing.
Some people call also this Pair programming.
So that’s all that I have, very briefly:
Focus master, your IDE, your tools, avoid manual work, and find yourself the fastest feedback loop possible.
And last words:
you should always find time to stop,
reflect on how you are working, and
never ever stop learning
Thank you very much.
More about efficiency:
- Disable notifications
- Master your IDE
- Write programs for yourself
- Why to Docker Compose a calm environment
- Did you read my email?
- Go and have a rest
- The conference talk (you are here)
- Other reasons for TDD: Baby steps, ROI, Evil Manager Syndrome and Watching the watchmen
- Where TDD falls short, find yourself a good REPL