Tuesday, September 13, 2016

Interviewing developers for legacy application codebase

Many of us are working on legacy codebase and cursing the previous developers for what they did? Especially on code quality. It may be very difficult to understand others code, if there are no comments or documents on why they did something in a particular way. Then we have to assume what was going on their head when they were writing that piece of code. Based on that we have to take new decisions. If our assumptions are wrong, our decision will also get wrong and it produce more damage to the system.

So to work on legacy code, developers needs special skills to read previous developers mind by looking at code. Its something like investigating a criminal case or researching on fossils to find what and why it happened in the past.

What is legacy codebase?

My simplest definition to the legacy code is as follows.

Any code which contains technical debt is legacy code.
Technical debt makes code resist to changes. Now we have to understand what is technical debt in software engineering. Its nothing but the damage caused to software because of bad decisions. One will not take bad decisions intentionally. They might be forced to take bad decisions because of many reasons. When we say taking bad decisions, it may be taken by higher managers as well as developers. Don't think that developers are not involved in producing technical debt. Below are some reasons for tech debt.

  • Deadlines because of budget, competition & time
  • Lack of analysis, planning & design.
  • Lack of awareness.
In one way tech debt is good and that is what gives job to most of us :-)

Coming back to legacy systems. If we google, we get different views on legacy code. Below are some of the factors people are saying what makes a codebase legacy

  1. The system or the target platform for code is out of common use or runs in compatibility mode
  2. The codebase contains code for handling old and outdated things such as reading floppy disk or serial port etc...
  3. The code which works in production but difficult to maintain because
    1. The original developers are not around
    2. No comments or docs.
    3. No code quality such as no inheritance & overriding, no patterns, not following SOLID etc...
    4. So many short cuts.
    5. There are many dependent systems which restrict changes
    6. The third party library versions are no longer supported by vendors
    7. No unit tests to validate new changes.
  4. Any production code is legacy
If we look closely, all these reasons points to technical debt. Ideally we should pay off tech debt at some point. But nobody does because of budget and release timeline constraints hence the code becomes legacy.
But it didn't mean we can just keep the legacy code as is and go forward. There should be somebody to maintain the legacy systems as there were good investments went to build such systems.

Also we cannot guarantee that the new systems we build will never became legacy.  

Tips to interview for legacy codebase

As we seen in the beginning engineers who are going to maintain the legacy codebase needs special skills. Below are some techniques to be tried to assess them during the interview.

Inform them

The first and important thing is to inform them that they are going to work on a legacy codebase. That gives them a chance to rethink and reject the offer. There are not many developers with the skill to work on legacy codebase. As mentioned above it requires special skill sets than just writing code. If their body language changes on hearing the word legacy systems, we need to be cautious. There are still programmers who don't know what is legacy code and of course they cannot take any action based on this information.

I was part of interviews to hire for legacy codebase and I asked about ADO.Net knowing that the person is not at all going to write any ADO.Net code.  Most of the legacy systems will be having a working data layer and developers will be getting required object(s) when they make a call to DL.Also asked about new language features knowing that its not going to be upgraded in recent years.

Puzzle to find out the logic

If the candidate is willing to work on legacy code, the next step is to evaluate them whether they are fit for the job. One of the important skill required for legacy code maintainers is the ability to understand the intention of previous coder by looking at / debugging the code. There is no guarantee that there will be enough comments, docs or best practices. So the best way to evaluate them is to show a piece of poorly written legacy code and ask to find out what is going on.

If we have legacy code, we don't have to think about what to ask. We can get it from our codebase itself. one sample is below.
int a=0;
private void Timer_Tick(object sender, EventArgs e)
{
    if ((a++ & 0x10!= 0)
    {
        Foo();
        a = 1;
    }
    DoWork();
}
 
private void Foo()
{
    Console.WriteLine("Foo");
}
 
private void DoWork()
{
    Console.WriteLine("Do Work");
}

What is happening in this timer tick event handler? Most of the graduates who just came out of college can say the output of this code. But they may not understand the thought process of the developer who wrote this code. The history goes as follows.

Developer X wrote the original code. At that time there was only DoWork(). For every timer hit, say 1 second the function was getting executed. Later developer Y came and he had to do something every 16 seconds. By that time, this code became legacy. X is not there in company or too busy to help Y. So instead of introducing new timer and all, Y simply added a counting mechanism using variable a so that only in every 16th second the Foo() gets executed. Y might have added simple comparison of variable a to 16 and reset the same.

Later Z came to fix performance with  hardcore bits and bytes computer science background and he changed the simple comparison to bitwise operation.

If somebody thinks like this, he is perfect fit for legacy systems.

Puzzle to fix something with minimal changes

Another important ability required for legacy developers is to do things with minimal changes. Better they should fix the defects by removing code than adding more. We can easily find out these type of scenarios in the legacy systems. If the candidate is able to fix by removing code, hire him immediately.

Refactoring with tools

Refactoring is important when working with legacy systems. It doesn't mean one person should sit for months and refactor entire code base. Instead whenever we do a change do a small refactor. Instead of doing it by hand, it should be done with tools such as refactor menu in Visual Studio. Testing a candidate for refactoring skill requires machine test where we can observe what is his/her approach towards refactoring. They should be refactoring only after making sure its not invoked from outside via reflection. Also look whether the names they are giving are meaningful or not. If someone don't know how to name things and refactoring, its same as creating legacy code in the first place.    

No comments: