How to become a better developer effectively

During these 10-11 years, when programming became my profession, I had diverse periods of success and failure. Routines, leaps – the same as with everyone 🙂

I wanted to gather some tips in this article. Would you add some in comments?

 

A Big Picture

V8 Engine

There are various ways to learn the same subject. One might require 5 years, whereas the second way gives the result in one. Programmers are practical people. We want to sit down, write and run the code soon. Probably this is why our most popular learning method looks like roller skating. We fall a lot and bruise a lot. In the end, we might curse its inventor and give up. Instead of this we could have prepared in advance. We could have watched/read how to lace the shoe, when not to raise a hand, how to fall, how to turn. All this is physics and is already known. We will fall a lot anyway, but with less trauma.

Let’s experiment: Think of a langauge, which you have been using for last 1-2 years. I guarantee, that if you read a good book (or documenation) about this language from cover to cover, large part or maybe even half of it will be new for you. I don’t mean that you should stop at every example and run the code, or get into all details and remember. I just say, that when we read the whole information in advance, we see the big picture. We can always google the details later, if we know that such thing exists at all. If we don’t have the base knowledge or maybe, for instance, how memory is managed, we will have memory leaks in our app and we won’t even notice.

After this we can add one more book about corresponding Best practices, which will spare us from even more ‘traumas’. So, we’ll have to rewrite the project for less times.

The book needs 2-3 days, but to get the same information with error and trial, we will need months.

 

Contests and algorithms

I think there is one stage, which every self-respecting programmer should pass. It requires much time, so, it is often passed during the school period, but better late, than never. If someone will feel lazy about it, they might be left behind by competitors.

I’m refering to programming contests and problem-solving. Based on this exercise process, your thinking style and speed will change drastically. Most of the popular mistakes will disappear from code, e.g. accessing wrong or nonexisting index of array, setting wrong limits in loops, allocating unnecessary memory and memory leaks, writing unoptimal code, using wrong data structure. You might even forget when was the last time you used a debugger. You will be able to run application not after writing each function but after writing lots of code and it will have small number of bugs. Unlike the real projects, these testing systems find all your bugs and consequently make you test better.

You may not need these learnt algorithms and you might not find them in real projects, but you will definitely need quick thinking and good skills of writing and testing code. It’s okay, if we don’t win, if we don’t reach into top hundred, even into top thousand best. This is a sport. Some people are born with this mind, some work very hard. Very few fights for an olympic medal, but we all exercise for good health, don’t we?

For me such phase was several years ago, when we created GeOlymp. For me such phase was several years ago, when we created GeOlymp. I didn’t invent the problems there, others did. I had different kind of tasks and also sometimes I was trying to solve them side by side with participants. Even today I feel when I fall out of shape, although I write some kind of code constantly. Then I get embarassed, when I make silly mistakes.

A good list where you can practice: The 10 Best Coding Challenge Websites for 2018

 

Teach

This is a popular method 🙂 When you explain something to other person, you notice completely different details. Generally I think that forming problem as a text is half work done. When you are looking for a bug or don’t know how to do something, try to describe and write the problem statement first. Rubber duck debugging is effective because of this. :))

 

Stress is destroying us

Gravity Glue | Stone Balance by Michael Grab

Programming is one of the very stressfull professions. I’ll tell you why: Every day programmer does what he hasn’t done before. If he does the same as earlier (or repeat what others did) and won’t use it instead, this counts as a big mistake. Also, he is asked to provide time estimation. Clearly, all estimations are approximate. He might come across various hard problems on the way which will cost him days or weeks. Programmers often work overtime to keep given promise.

Every one of them has their methods to cope with stress. It is much harder to recover
from mental tiredness, than from physical. Some practical tips:

  • Use automatizations. The most stressfull processes of our profession are good candidates for automating. This will save you lots of time and nerves.
  • When you are stuck on one problem, change the subject or have a rest. There is a saying – sleep on a problem. If you state the problem well before sleep, your brain will work at night and give you the answer in the morning. This really works.
  • Physical health, walk, meditation, sleep. You might think, that there is no time for exercies, but actually you can work more mentally, when you have physically active lifestyle. On the other hand, code of the sleepless person is full of bugs. Energetic drinks and huge amount of caffeine only make things worse.
  • Only you can take care of yourself. Stress is a nice motivator, but constant stress ruins the body and the brain.

 

Open-source projects

Like books, codes of other people is a good source for development. Nowadays, the most interesting projects are available on the internet and you can even become a contributor. Choose your favourite language, a project and you can participate without leaving home. By the way, this will also look good on your CV.

Dynamic Array

Dynamic array is a data structure with variable length. One can insert, retrieve or delete an element using random access – i.e. it needs a fixed time to reach any element and this does not depend on whole size of the array.

You might come across this structure by different names – dynamic array, growable array, resizable array, dynamic table, mutable array, array list.

To guarantee random access, it is necessary to allocate a continuous memory for the array, i.e. its elements should be stored next to each other.

In case of a static array, this is not a problem, as we define the length in advance. But sometimes we don’t yet know the length. So, how much continuous memory should we allocate?

Clearly, there is no point for allocating huge memory just in case. We should not reserve million bytes in advance just to store 20 elements.

This is where dynamic array comes in. In many programming languages this problem is solved this way:
The dynamic array is backed by a static array, which is created in small size. When this static array is filled and users will try to add more elements, a larger static array will be created behind the scenes. Existing elements will be copied into it and the old one will be deleted. Consequently, insertion of some elements in the dynamic array will take more time than the others.

With this solution in mind, we should answer to an important question: By what factor should we increase the static array length?

It should be noted, that again we are searching for a balance between performance and memory waste. If we increase the array length with only one element, rewriting whole array on each new element will take too much time. But if we increase by a large factor, we might end up with a large empty array.

Optimal number is 2. This number might be slightly altered corresponding to requirements.

You might find its different versions in various programming languages – e.g. Vector in C++ is increased 2 times. Vector from Java standard library also has a factor 2, however you can change it by passing arguments. A static array of ArrayList in Java is increased by 3/2 times. A static array of HashMap – by 2 times. In the C implementation of Python, the number is a bit odd – approximately 9/8. Here is the source.. And here is an explanation.

If the programmer knows approximate size of an array in advance, they can configure the dynamic array correspondingly. E.g. Vector in C++ has a function reserve, which will reserve memory of given size.

ArrayList and HashMap classes in Java have a constructor parameter initialCapacity. In case of HashMap, not only static array is rewritten in the background, but the hashes are also regenerated.

If performance is critical, this parameter can be used. I carried out several experiments and saw the difference, however, in ordinary tasks this difference is not noticeable. Even in case of factor 2 and million elements, the arrays are rewritten only for 20 times.

In the beginning, I mentioned that some element insertion might take time from O(1) to O(n), where n is a total number of elements. Despite of this and based on amortized analysis, insertion time in a dynamic array is defined as O(1).

The idea of amortized analysis is to consider both, slow and fast operations of the algorithm. They might balance each other. While estimating an algorithm performance, we generally reach for the worst case scenario, but sometimes it is possible to calculate the ratio of expensive operations.

Let’s calculate the time for filling a dynamic array of n elements:
If we increase the length of an array by 2 times, we can estimate the number of rewrite like this:

Let’s start from the end. In the end it will need to rewrite all elements. Before that, only half of elements. Before that, quarter of elements, etc.
n + n/2 + n/4 + n/8 + … = n (1 + 1/2 + 1/4 + 1/8 + …) = 2n

Also, let’s add an insertion time of a new element and we get 3n. If we take an average, we will get O(3) = O(1) time for inserting an element.