What do the top 1% of software engineers do that the other 99% do not?

October 20, 2014 – 3:12 pm

This interesting question was recently posed on Quora: What do the top engineers do, that the rest do not? And how do you get the habits to become one?

Anyone can tell you something like “oh you should use source control!”, or “you should comment your code!” or other obvious things like that.

But there is a limit to how much code and how good code you can crank out daily, so how do you actually become better?

Being an engineer is more than just being a good programmer. You may be able to come up with fast algorithms to solve problems, but what about building the architecture for a large scale application, that is both easy to understand but also testable? Or what if you’re showing your web app to the users and they are confused, and keep asking you how to use it?

If the only thing you do is just write code, your job can be outsourced to some cheap programmer in some cheap country, and you don’t want that right? That’s why to be a top engineer that stands way above the cheap mediocre people, you need to look outside the immediately obvious realm of writing code. Top engineers have a much wider range of skills, which they use to understand their client better, provide higher quality solutions, and deliver a lot more value (and as a bonus for them, all this justifies the boss giving them a higher salary).

1. Constant learning

This is the basis of everything. By learning new things, even if you don’t end up using it daily, you will increase your knowledge about what is out there.

Even if something you learn doesn’t have any obvious practical uses, you gain new insights and ideas through it. The wider your range of skills, the better solutions you will be able to provide, and as a result, the more value you can deliver.

Learning adds up: You learn something, and as a result, learning something else is easier. Learning becomes easier the more you learn, and also helps with all other aspects of software engineering.

The trick is to not only learn about programming, but also about other things.

  • Learn a new tool – testing tool, automation tool, etc.
  • Read a book. It doesn’t have to be about programming, you could for example read about user interface design which is very useful to know
  • Talk to other developers – Others know about things you don’t, you’ll get new ideas, or maybe even solutions to problems you’re having
  • Write about software engineering. It may sound strange, but writing will help improve many of your skills. To learn more about that, read my article about how you will become a better developer by teaching
  • Learn a new language – TypeScript, Haskell, Prolog, C… pick the one that looks most difficult.

I can hear someone say “But I’m busy and don’t have time to do this”. You can take just one hour a week to do this, as long as you do it. If you can’t find a single hour a week to improve yourself, maybe this is not for you.

2. Understand, Solve, Implement

Have you ever started working on something, only to find out you don’t have any idea what to do? Or maybe you got stuck, and had to start from scratch?

This is a typical issue especially with beginners, where they lack the understanding necessary for the task. Experienced engineers often have an understanding, but might lack the solution.

The best engineers will get an understanding of the problem, come up with a solution, and only then implement it.

There are many ways to understand the problem: You can talk to people, use Google, look at other projects which do similar things…

Next step, the solution, is usually more difficult. It doesn’t have to be a concrete solution, a general idea is good enough. Maybe find a library you can use, the documentation you need for an API, or perhaps some necessary hardware…

The last step is usually the fun one: Implementation.

In the end, sometimes things won’t work out. You may have to go back or start again, but by following the understand, solve, implement pattern you have much higher chances of succeeding and not getting stuck in the middle and wasting a lot of time.

3. Have a plan

The best engineers will have a plan. There’s several components to this:

  • A high level overview of the project – An overview of the components, modules, and how they interact with each other.
  • Understanding and solution for what needs to be done – As explained earlier, get an understanding of the problem and a concept of a solution
  • A high level implementation – What components you should add for the feature/fix/whatever, their purposes, and how they integrate with the rest of the project

These combine to allow you to build a solution that doesn’t suck.


The A-Team always had a plan

The high level overview shows you the base: Existing components, any needs for refactoring if you implement a new component, etc.

The understanding and solution help you design a better implementation, as you won’t have to guess.

Finally, the high level implementation idea is so you won’t get stuck. It’s possible the idea will change as you start working on it, but having a guide is helpful.

Without a plan, you are more likely to duplicate existing functionality or add components which integrate poorly. That will lead to a maintenance nightmare if not corrected.

4. Stay objective

Top engineers stay objective. They try to understand the true reasoning behind something, going deeper than just the initial impressions.

When someone talks about “best practices”, do you just take their word for it? Have you ever tried to understand why something is considered a best practice? Or is it actually a bad idea?

Many engineers take things at face value. “This is the best practice!” – OK, I’ll do this then. “Here, these are some good design patterns!” – OK, I’ll just use these everywhere.

Top engineers try to understand the reasoning behind this. What makes this a best practice? What makes these design patterns good? You might not be able to see the reasons easily. This is another reason why you need to learn new and different things constantly, as that will give you a better perspective on analyzing new things. However there is a simple way you can speed this process up: Ask the person who tells you this, or find an expert and ask them. Ask them the difficult questions, like “what makes this a best practice in your opinion?”

Another example of this is PHP: Many engineers have an immediate response of “PHP sucks!” when they hear the name. This is of course not true, there are very, very few things in the development world which are truly bad and should never be used. If you hear someone throw around a lot of nonsense like “language X is crap”, and if they’re serious and not joking, it’s often not a good sign.

  • Try to understand why people like or dislike some things – Some tools (like Haskell) are indeed amazing, but it’s useful to know why people feel this way. Using or not using something because of how you feel about it is usually not a good thing, as you might be overlooking something that would be more suitable for the task.
  • Don’t get personal – It’s sometimes fun to debate things like favorite editors or languages, which will provide endless heated arguments on the internet. Many will blindly defend their favorite, devolving into personal attacks when they run out of things to say. Try to avoid this, and instead try to understand the other side’s point of view.
  • Don’t follow blindly – Best practices, design patterns, all have their uses, but you should try to understand why. You might discover that they’re actually not that good afterall.

5. Understand requirements vs desires

All engineers desire to use their favorite tools with all projects.

Top engineers realize that the project’s requirements dictate what tools you should use, not what you personally desire to use.

A good example of this is blogging software. In such a case, WordPress is a solid choice, but developers don’t like it. I would rather take a nice framework in some nice language and write a custom blogging solution. It would be much more fun to work with, because let’s face it, WordPress’ codebase is pretty bad.

However, if you were to create your own solution, you could be shooting yourself in the foot.

This is why you need to understand when the reason you want to use something is your personal preferences or desires, instead of the requirements for the project.

6. Understand the importance of user interfaces, user experience and usability

I like using the iPhone, but many people don’t understand why. Often especially developers will ask me “but Jani, why would you want to use an iPhone when you could use this amazing Android phone instead?”

The simple reason for this is user experience and usability.

Why do you like using your favorite editor over others? You find it easier to use, you work faster in it, you like the way it looks more than the others… In other words, it has a better user experience for you.

Many engineers work with user interfaces at least to some degree. Great engineers often have to discuss features and implementation with designers or the clients. It pays off to have at least an elementary understanding of UI, UX and usability, as it helps in brainstorming better solutions to problems you need to solve.

7. Understand project management and the business value of your project

Idealistic people will tell you that if you’re a great engineer, you will deliver projects on schedule. While this is a sign of being good, in real life things sometimes go wrong.

This is where understanding of project management and business value comes into play. As the best engineers are often involved project management, at least in a role of advisor to the team lead / boss / client / whoever, understanding which tasks are the most important for the business goals becomes useful.

Deadlines slip sometimes. That’s when you need to be able to find the highest priority parts to deliver. In other words, what are the most useful and important features or fixes for the customer.

Understanding projects and value is also useful for planning schedules, so you can continuously keep delivering new releases. Faster releases means your customer sees progress more often, and you will get feedback on it faster. Many big companies and startups rely on being able to release code into production rapidly, for example Facebook.

  • Be more involved in project planning – You get better by practicing. If you can’t do it at work, use something like Trello to do so with your personal projects
  • Pay attention to what the customer really wants – For example, if you’re building a web app, what do they gain from it? Will it make some task take less time? Will it help them acquire more customers? Try to understand where the value is

You don’t have to become a project manager or anything. Just having an understanding about these things is useful, as when you understand value, you can focus on where it matters, and give better proposals on features. This again goes back to you delivering more value yourself, by giving the customer a better result.

Conclusion

The first key thing to understand is being a great engineer is not only about programming. There’s a wide variety of other useful skills that contribute to how well you can do your job. Being a great programmer is important, but so are other aspects of software development and the related processes. Learning about them should be high on your to-do list.

The second key thing is understanding yourself. I highlighted some examples of thinking, like understand, solve, implement and remaining objective here, but there is more. Try to identify problems in your thought process and in how you approach problems, as having a better understanding of yourself will allow you to adjust your thinking and become even better.

If you take these two things and try to keep them in mind, you’re well on your way to become one of the best engineers out there.

Ever feel like you're stagnating, and not sure what to do next to keep improving? Sign up for my newsletter!

Join now and learn the things that make a good developer become great

  • How top software engineers write and structure their code?
  • How to stay productive, even when you have a large-scale project or a complex problem
  • What to do when you want to make your code more reliable or easier to maintain

We will never sell your information or spam you, ever.

Using techniques from statically typed languages in JavaScript

September 2, 2014 – 8:48 pm

I wrote an article discussing some techniques from statically typed languages. Head over to SitePoint to check it out!

Here’s what you can expect:

  • JavaScript type system, and how it tries to bite you
  • Expanding more about the rule of consistent types with more details on using it to reduce bugs
  • Dealing with type-checking and type-conversion in a way that doesn’t result in spaghetti and extra checks all over the code

Head over to SitePoint to read the article

In order to become a better developer, you must first become a teacher

August 18, 2014 – 1:20 pm

The headline might sound pretentious, but what is the most important skill for a developer besides actually writing code? Communication.

What do you typically do when you communicate as a developer with someone else?

You explain problems, you describe solutions, you talk to non-programmers about what you’re doing. You could also say that you’re teaching others about what you’re doing. Heck, when you’re writing code, you need to comment it and that is also a form of teaching – teaching someone what your thought process was when writing this code.

Being a good communicator is often completely overlooked. Sure, you might see a job placement ad wants someone who has “good communication skills”, but what does that even mean?

Let’s take a step back and think about why it’s really important for a developer to be a good communicator, and then we can come back to how you can become a better developer by teaching – but don’t worry, this process will only require a small amount of effort, although if you enjoy it, you can absolutely spend more time on it too, and reap bigger rewards!

First, let’s figure out what it means to communicate well with other developers. Of course, this includes things such as discussing problems and solutions, explaining your reasoning behind the choices you made when building out some systems, and things like that.

But what is the core skill that you need to be able to do all of the above things? The ability to truly understand all the moving parts in your code – to be able to have a mental image of how it’s structured and how all the pieces fit together to form the whole of the application.

Without this understanding, you can’t explain it to someone else. Sure, you could show them your code, but that’s not really explaining it – you’re just letting them figure it out on their own, maybe pointing at a few functions to push them in the direction you want.

This is why understanding the code and being able to communicate well go hand in hand. Beginning developers will often think about algorithms in a much lower level… “I need a for loop here, and if clause there”… but experienced developers think on a higher level “When a condition is true I need to iterate through these”. Notice how there is no mention of the actual programming language level constructs. When you gain this sort of understanding, you immediately become better at communicating how the systems you’re creating work.

The good thing is that when talking to other developers, you can show them the code even if you’re having difficulties explaining all the things. However, what if you have to explain it to someone less technical? If you’re working in a team, you could probably let someone else deal with it, but if we actually want to become better developers, then this is something we would need to try to do.

People who aren’t developers will not understand all the technical details. You need to be able to take the nitty gritty details of your code and move it into a more abstract level of thinking. Perhaps you can use analogies with something the other person is familiar with to explain things, but again in order to be able to do this well, we need to have deep understanding of the code first.

You might think how does this relate to me? I just like to write code and do cool stuff. I sometimes felt like that as well, but wouldn’t it be really nice to be able to write code and do cool stuff AND get paid for it? The stereotypical case that you might be thinking of here is of course some big corporation because everyone knows they’re full of people who don’t understand anything and blah blah. That is the wrong assumption however.

Some people enjoy big corporates, but for many of us, the dream is to work at a cool startup, or maybe at Google. What is the common thing about these sorts of dream jobs? They get a lot of applicants for all their openings. There are many good coders who get interviewed, but which ones are the ones who stand out? The ones who can also communicate well. A job interview is one of the situations where you generally need to listen, ask good questions, and explain your decision process and choices well.

This exposes another facet of communication: Listening. It may sound really obvious, but listening can actually be difficult. For example, if you explain a program’s flow to some very experienced developer, they can probably picture it in their heads at least partially, even if you don’t explain it perfectly. Explain it to someone less experienced, and even if they listen, they may not really get the full picture.

And now, we can finally come back to the part about teaching. How does teaching relate to all of this?

Teaching requires all of the skills above. You need to listen well to understand the questions. You need to be able to formulate a clear solution, and then explain it in a way the other person can understand.

Now, I’m not saying you have to go to a school and teach programming there. Of course not. What I’m talking about is just helping other people with their questions, even if you’re not an expert. I’ve spent a large amount of time doing this, and it’s one of the reasons why I know about a very wide range of topics.

Helping people with their problems, even when you might not be an expert, will improve more aspects of your skillset than just communication. You might have to do a Google search to help with some topic you’re not completely familiar with, so you learn something new. Maybe the question just gives you a new way to think about some problem.

This is important especially if you aspire to become a team lead, CTO, software architect, or some other similar role. In roles like these, it’s very helpful to have a wide range of knowledge, even if you’re only passingly familiar with it. People in these roles will often need to mentor other developers, figure out solutions to new problems nobody else is familiar with, discuss business requirements, and all sorts of things where knowing that something exists and could help can be very important even if you’re not 100% familiar with its inner workings.

As with all aspects of programming, the best way to improve communication and your ability to reason about code on a higher level is practice. Thanks to the internet, all you have to do is go to Stack Overflow and answer a question. You can answer one question a week and get some practice like that, or you can answer one question a day if you like it… This is what makes teaching a very accessible method of getting practice for communication, and it only requires as much effort as you want to put into it.

So just go out there. Go to Stack Overflow, answer questions. Go to Reddit, answer questions. Talk to people on IRC or forums. Write a blog post. It’s interesting and fun, so why not?

Ever feel like you're stagnating, and not sure what to do next to keep improving? Sign up for my newsletter!

Join now and learn the things that make a good developer become great

  • How top software engineers write and structure their code?
  • How to stay productive, even when you have a large-scale project or a complex problem
  • What to do when you want to make your code more reliable or easier to maintain

We will never sell your information or spam you, ever.

How to reduce bugs in JavaScript code by following the rule of consistent types

August 11, 2014 – 6:22 pm Tags:

One of the most annoying type of bug in JavaScript code is when the code doesn’t have logical types. Oh hey, I’ll just sum these two numbers… NOPE! They’re actually strings! That just makes me so angry. To make matters worse, this is something I’ve had to deal with a lot with a codebase I’ve been working with recently.

JavaScript is dynamically typed, and it doesn’t care what you do with its variables. You can have a variable contain a boolean, then put an array into it… then put a number into it… but this does not mean you should.

Your values should have one type only

Sometimes you see code like this

function getNames(person) {
  if(person.firstName == '') {
    return false;
  }
 
  return [person.firstName, person.lastName];
}

At a glance, it doesn’t look like there’s anything wrong with it. However, it breaks a very important rule you should follow to keep typing-related bugs away from your code.

In a language with static typing, the above would not work. The problem is that the function has inconsistent return types. What this means is the function can return both a bool value, and an array value. That kind of thing would never fly in a statically typed language, and there’s a very good reason why you should never do this in a dynamically typed language either.

Inconsistent types will give you a headache

When a function returns different types, you can’t make any kind of assumptions about its output. As a result, it will cause a mess, both in code and possibly in bugs as well.

Let’s say you take the above function and want to combine the names…

var result = getNames(person);
var combined = result.join(' ');

Now what will happen when the function takes the first path and returns a bool? A “true” or “false” value does not have a function join in them, therefore it will cause the code to throw an error. In order to deal with the possibility of a bool instead of an array, we have to add all this useless fluff into the code

var result = getNames(person);
var combined = '';
if(typeof result != 'boolean') {
  combined = result.join(' ');
}

Now, the example above is very simple. If you have ever worked on a large JavaScript codebase that broke this rule, you already know how bad it will get in a real application.

Always be mindful of your types

In order to fix this problem, we can simply rewrite the function like so

function getNames(person) {
  if(person.firstName == '') {
    return [];
  }
 
  return [person.firstName, person.lastName];
}

By keeping the return type consistent, we reduce the likelihood of bugs being caused by incorrect types. We also reduce the amount of code that you need to write, and less code is always better than more code.

Working in dynamic languages like JavaScript gives you great freedom, but with great freedom comes great responsibility. Save yourself the headaches, and keep your types consistent!

Are you tired of having to deal with bad JS code?
Sign up for my newsletter and learn how to fix that

  • What's the best way to architect large scale JavaScript apps?
  • Automate common development tasks and save hours of your time
  • Refactoring that horrible mess into something more manageable
  • Etc.  

We will never sell your information or spam you, ever.

Hello World Open 2014 thoughts

June 19, 2014 – 2:26 pm Tags:

I participated in the coding world championships, or Hello World Open, 2014. The challenge was to write an artificial intelligence for a slot-car racing game.

I wrote my bot in Haskell, and managed to rank 11 out of 856 competitors in the first qualification round, and 78 out of 203 in the second qualification round.

Read on for some general thoughts and a bit of analysis on the algorithms my bot used.

Read the rest of this entry »

Book review: Dependency Injection with AngularJS

February 16, 2014 – 11:29 am Tags: , , ,

Are you in the market for a book on AngularJS? Here’s my review of the book Dependency Injection with AngularJS, written by Alex Knol and published by Packt Publishing.

Disclaimer: I was sent a free copy of the book for review purposes.

Read the rest of this entry »

Tips for taking screenshots with PhantomJS + CasperJS

February 5, 2014 – 7:38 pm Tags: ,

It’s quite easy to use PhantomJS to muck around with pages, especially if you use CasperJS which provides you a bit nicer API.

It’s also pretty easy to take screenshots, but there’s a few things you need to take into account if you want the results to be accurate…

Read the rest of this entry »

AngularJS best practices: Refactoring existing code to Angular

December 27, 2013 – 8:12 pm Tags: , ,

I’ve been involved in several projects where I worked on moving an existing codebase into using AngularJS. Some involved refactoring a small codebase, which is relatively straightforward in most cases, but I’ve also refactored much larger projects where moving everything at once is not an option.

Here’s some best practice type stuff that I’ve learned along the way.

Read the rest of this entry »

Using AngularJS for fast prototyping

November 5, 2013 – 6:27 pm Tags: ,

One of the big pain points in web application development used to be quickly prototyping site layouts. Now we have things like Bootstrap and other CSS frameworks, which give you a quick grid and a bunch of other reusable components.

But that does not solve the whole issue: In today’s web applications, standard page load style actions just don’t cut it anymore. You need to have all kinds of UI features, from tooltips to dynamic form validations and who knows what else.

How do you quickly build a working UI prototype for a highly dynamic web based interface? Everyone knows building DOM in JavaScript for doing that stuff is kind of a pain, even with jQuery or Mustache.

Here’s how: With AngularJS. Not only is it great for building dynamic UIs, it’s actually amazingly fast for prototyping as well!

Read the rest of this entry »

Library author: Don’t provide an exploitable interface

August 31, 2013 – 10:17 pm Tags:

SQL injection is a pretty big deal. Its cousin shell injection is also a common issue, demonstrated quite well by a recent post to the PHP reddit. Although some suspect it was a troll, I heard echos from a variety of people who had seen pretty much exactly the same vulnerability in production.

This got me thinking: People writing libraries for doing things like shell commands, SQL, etc., don’t actually have to provide an interface that can be easily mis-used. An interface like this could just as easily be based on some other data type besides a plain string, completely side stepping issues caused by concatenation.

“What on earth are you talking about?” – Let me explain…

Read the rest of this entry »