University Learning

When you tell people that you went to university and studied some Computer Science related degree, people think you are a genius.

They also assume you must be a better programmer than self-taught developers, but that isn’t the case.

I heard someone rant on a podcast that some people in the industry try to “gatekeep” by saying that “Software Engineers” are university taught, whereas self-taught people are merely “Software Developers”. So a “developer” is a  pejorative term. I’m not sure if that is an American thing, because I have never heard of that before, and it’s not something I have witnessed in England. Personally, I use the terms as synonyms, and if I did hear someone trying to differentiate between them, I would certainly argue against it.

I was taught programming at College and didn’t learn much. I went to University and the standard of teaching (when it came to programming) was actually very low. 

Part of the problem is that you do some coursework based on something you are studying on the course, and by the time your code is starting to look complex – then you have completed the task. Your attention moves onto the next set of coursework and the pattern repeats. So essentially you are writing code using basic constructs like “If statements” and “For loops”, then moving onto another basic task using the same constructs.

Another problem is that when the coursework is graded, they mainly care about the written report. Often you had to simply demonstrate your program running to prove you didn’t just pretend.

The other problem is that it didn’t matter if your code was efficient or clear. As long as you could explain the theory, then it is fine. You were encouraged to litter your code with code-comments, explaining every line. When you actually learn how to write good code, you read about the idea of “clean code”, which means writing code in a logical and easy-to-read manner. This is the opposite of how universities teach it.

Your code at uni is a mess. There’s no automated tests, there’s no design patterns, the methods and classes aren’t split into small logical groups. It’s loads of messy code crammed into a few files (or maybe just 1 file); it’s not readable or very maintainable, and then the file is double the size because you have spammed it with code comments.

At that point in my life, I found that I learnt the most in my first job, simply by making mistakes and thinking about what I could have done instead. After I left that job, I spent time reading and working on the most ambitious idea I had. It was at this point, I felt that I finally understood how to be a developer.

The Invoice

I was working on fixing an important bug and one of the managers called me to ask how I was getting on. I gave him an update, and he said that he had been informed that a customer had complained about this particular bug – and even had sent an invoice to try to bill us for time lost  because of this bug. With their calculations, they wanted £6k in compensation.

I often think about the impact of software bugs. Ideally, the software should always work and help the user do their jobs. A bug will cause frustration and slow the user down. If a company has loads of users that are all impacted by the same bug, then the impact is multiplied. If we end up taking a month to fix it, then the impact is multiplied over that time.

We had no intention of giving into the user’s demands though. We were just fixing the bug as urgently as we could.

The Weeklong Bug

This one is more of a diary blog, rather than criticising anyone in particular. It’s an example of the tricky and infuriating side of being a software developer.

There was a bug logged a few months back that we didn’t pay attention to, but it’s progressively got more complaints and there are a bunch of users complaining about it on a Facebook group, so I think it got attention from the CEO.

Like usual, the bug comes to me to fix, and it seemed the expectation was that I’d have it done in a few days.

Users basically have an Inbox with a list of tasks in there. Like an email application they can see the tasks on the main-view but can also double-click to open them. On this open-view, they can click buttons to deal with the task, but they can also scroll to new tasks rather than closing.

On the open-view, users were clicking Approve but nothing happened. If they clicked it again, then it was successfully approved. If you looked in the audit, it did show two approvals. This bug didn’t occur if you opened the task directly from the main-view, then Approved. It was only when you switched to another task on the open-view.

I could easily recreate it, but when I was debugging, I couldn’t make sense of what was going on. It seemed to have the correct data, it updated the correct property, then all of a sudden, it seemed wrong again. The code in that area was massively confusing and it was hard to work out how things should work.

After days of looking at it, I managed to persuade one of my work friends (and maybe one of the smartest developers) to come help me out. He couldn’t understand the problem, but came up with theories of caching problems. I didn’t see anything obvious in the code I saw, but I was out of ideas, so we changed the config to disable all the caches. Didn’t make a difference.

The next day, I told my manager that there’s no progress, and we probably need to get more nerds involved. So I managed to get a couple of hours with the smartest developer at the company.

He couldn’t understand it either. He was convinced that after the data is saved to the database, something on another Thread was changing the data in the cache, so that the object on the client doesn’t match the server cache. 

The next day, we were losing hope. I could only get a couple of hours with the smartest developers but even they were confused, and now I was on my own again.

I looked at some recent changes to the files in question, and I saw someone had reduced the amount of “refreshes” on these tasks. It was previously trying to reload the data a few times every time you selected a task. I reverted the changes to see if it made a difference…and it fixed the issue.

The thing is, I wasn’t going to just revert the changes, because the performance issues would be back. So then I was trying to work out why that had a bearing on the cache. I persuaded a Senior developer on my team to also look at it because I was convinced I was close, but by this point, it was hard to think because I had spent 5 days on this same bug. I had been doing more than my 9-5, I was basically doing 8-6, then sometimes 10pm-12am. There must be something I am overlooking.

It took him a couple of days but he did point me in the right direction. It seemed we were basically caching a data object in a variable, retrieving the data again on the server which changed the object references in the server cache. Then when you click Approve, it updates a different object reference, and now they are out of sync.

So I basically removed the cached variable, and only used the data once the server cache had been updated.

A simple fix in the end, but it took all week.

Missing Update

I received a review from Colin which was modifying an internal tool. I have never made any changes for this tool, but I have had a nosey at other changes to have a vague idea of the approach to modifying this.

I point out that his SQL patch was missing an “update” statement. (Ideally, maybe someone should add a database trigger, because manually adding this extra “update” statement to every patch is a bit silly; but hey, that’s the current process).

He replies back asking why he needs the update. Before I had even responded, he had made the change anyway. So he has no idea, but is happy to do what I say! 

He also said “I have never made a change for this tool before”. I knew that was a lie. I could look at the ‘Completed Pull Requests’ and find 1 change that he did a few months back. I really haven’t made a change to this before, and I know that this statement needs adding in, it’s not really an excuse.

I explain that if you look at all the other patches, they all have it in. I also linked a recent review which was done by the “Module Expert” where he flagged this as a problem, and has provided a basic explanation of what it was for. This Module Expert was on holiday for the week, so we couldn’t ask him, or get him to review it; so Colin has to make do with me reviewing it.

3 hours later, I get another Pull Request from Colin. It’s a separate change, but it’s another patch for the same tool. It doesn’t have the “update” statement in.

Instead of shaming him on the Pull Request. I send him a message on Slack asking how he managed to forget. He then tells me it isn’t needed because “it is a different area”. 

No idea what he is on about. If he really thinks it isn’t needed, then why did he change it as requested in the last review? If I am wrong, then he shouldn’t have made the change, and he should have responded telling me that. Of course, if he sends a review without this expected change in, then I’m going to question it again, aren’t I?

I Want To Do Some Enhancements

Many years ago, the development team was set-up in a way that “proper” developers worked on enhancements, whereas Juniors worked on fixing bugs. To be honest, in many situations, fixing bugs is the hardest scenario.

I always like a variety, because doing a particular thing becomes tedious and isn’t giving you a good range of skills.

Julian started moaning about how he wanted to “do some enhancements”. He was itching to prove himself and craved variety.

The managers finally caved in and gave him a set of 4 enhancements to do as a mini-project over the course of a couple of months. When the deadline approached, he had left the company.

When we looked at his changes, only 2 looked even close to finished. They were riddled with bugs. One of them looked like an absolute botched implementation, and when I looked at the code and pasted it into Google, I found the Stack Overflow posts it was taken from.

Julian had just copied and pasted code, tried to change a few things here and there, but couldn’t improve it. I imagine he realised he has made a fool out of himself, so handed in his notice before we uncovered what a mess it was.

In the end, we just scrapped his code completely because it was a waste of time looking at it any further. 

The Name

I was peeking at Code Reviews and I saw this code.

retrievalUser.Surname = Formatters.ToTitleCase(usersName.Item as string);
retrievalUser.GivenName = Formatters.ToTitleCase(usersName.Item as string);

Notice how the code for both Surname and GivenName is exactly the same.

How can that possibly work? If “usersName.Item” is the full name like Alan Taylor, then surely if the UI shows GivenName and Surname, then it will be displayed as “Alan Taylor Alan Taylor” which is obviously not their name.

If this is some temporary code, then why haven’t they added a code comment next to the code to highlight that this needs replacing? Something like “Currently, the API only returns the full name so we cannot determine the users Surname and GivenName until version 2.1”.

Also, is it even correct to Title Case someone’s name? If you have a name like McDonald, wouldn’t this become Mcdonald? There’s probably loads of other examples too. I think the Dutch “van” is lowercase like “Robin van Persie”.

So there’s not much right with these 2 lines of code.

Crap C# Set property

I haven’t wrote a nerdy blog with code for a while. So let’s discuss C# Properties. A basic example could look like this:

private int _amount = 0;

public int Amount
{
   get { return _amount; }
   set { _amount = value; }
}

Here we have a property called Amount and the value is a number (int = Integer). You can get the value to see what it is, and you can set a new value. You could test it out with code like this:

Amount = 50;
MessageBox.Show($"Amount: {Amount}");

We set the Amount to 50. Then display the value in a message box. So this will display “Amount: 50”.

I saw a poor implementation of this basic C# feature. When I have come across crap code, I’ve sent it to my Apprentice to see if he understands why it is bad. This one caught him out.

This example looks similar, but notice the set method. It has a hardcoded value of 0 rather than the C# keyword “value”.

private int _amount = 0;
public int Amount
{
   get { return _amount; }
   set { _amount = 0; }
}

So what happens when you do this?

Amount = 50;
MessageBox.Show($"Amount: {Amount}");

Instead of showing “Amount: 50”, it actually shows “Amount: 0“. This can easily lead to bugs, or simply confuse a developer for a few minutes. The only way the value can actually be set in that implementation is via the “backing field”, the variable called _amount. This code will show “Amount: 50”

_amount = 50;
MessageBox.Show($"Amount: {Amount}");

Bonus SQL

I saw some bad SQL which I also sent to my Apprentice. I sent him this, hoping he’d maybe test it out, or maybe read up on bit fields, but he couldn’t tell me what was wrong with it.

declare @VerificationStatus bit
set @VerificationStatus = 2

A “bit” stores a value 0 or 1. So how can it be set to 2?

When you set it to 2, it doesn’t give you an error, it just sets it to 1. Any non-zero number is set to 1. This wasn’t the intention of the developer, he should have used an int. If he had tested his code, he would have seen it insert the wrong value into the table.

Product Names

Let’s say that the company I work for is “ACME” (classic fake company name). Our existing product is called “ACME Pro”, and our upcoming product is ACME-One. 

In the past, we have had inconsistent branding, with the company name written as ACME, Acme, and acme. We have tried to be more consistent and have discussed the importance that the new product is only ever gonna be “ACME-One” and the hyphen is very important.

Colin has been doing some work in ACME Pro, but it has some kind of integration with ACME-One. He had a database change and was populating the new table with values “Acme Pro” and “ACME One”.

I point out that the casing is wrong with the first product, and he has missed the important hyphen in the second product.

It would take him a few seconds to change it, whereas leaving it like that means it will probably be wrong for a long time and annoy pedantic/perfectionist people like me.

He replies “this isn’t user facing text, so it is not an issue”.

He really doesn’t care about quality. Also, one of the database columns is literally called DisplayName. Who is the text displayed to? If it isn’t an actual end user, it’s going to be an employee using some kind of configuration tool; and that is still a type of user. 

It’s also annoying for writing SQL queries, because you may type “where DisplayName = “ACME-One” but it won’t find it because the stored data is missing the hyphen. So you have to be aware of the misspelling in order for data to be returned.

Mentoring #3

I am mentoring an Apprentice who has never done C# before and this is his first programming job. So this is a diary of some-sort of his progression and my ability to mentor.

I found an example on the Code Review section of Stack Exchange by someone who was writing their very first C# program. I thought it was a good example to give to my Apprentice to test him out.

So I showed him the code, and asked him to explain to me what it was trying to do, if he could suggest improvements or spot any bugs. Basically doing a Code Review.

I thought he explained the code fairly well and struggled in places where the code wasn’t well-written. He did point out one bug and did hint at a few areas of improvement but didn’t seem sure on how exactly to improve it.

I then took him through some changes, and explained how the code could be improved. Most of the code was jammed inside one method so it was 300 lines long. I showed him how you can easily refactor the code into smaller methods using Visual Studio, and how to rename variables (with the advice of choosing descriptive names). The end result is code that is self-describing.

You can read the popular book Clean Code by Robert C Martin which discusses more ideas along these lines.

I told him it’s an important skill to read other developer’s code, since maybe you end up spending 90% of your coding time reading existing code (not sure of the exact statistic there, but it must be high). Also you will be doing it in the code review process.

He seemed to really enjoy it, and was grateful for my tips. I told him I will probably be testing him with more of these challenges, and I also expect to see him put my advice to use in his own code.

All Nighter

After my important bug fix was complete, it needed urgently testing, so a Tester worked overtime on Friday night and Saturday.

During testing, he found a bug, but it was completely unrelated to my fix. Still, he wasn’t to know that, and so when he raised it as an issue, my manager was panicking and trying to contact  some developers.

I didn’t see the message until Saturday 11am, but when I logged on and investigated it, I saw another message from my manager to liaise with Colin. Colin loves his overtime so had jumped at the chance to get involved.

When I managed to contact Colin at around 11:45am, he sounded like he was falling asleep. He then told me he was working 10pm to 4am to work out what was happening.

To be fair, he didn’t have the advantage of knowing what the original bug was or the impact of my fix, so I assume he spent a lot of time investigating that. The thing is, the only conclusion he had was that “it wasn’t caused by your change”. I worked that out within 30 mins; I didn’t need 6 hours.

The thing is, there’s no way you can work effectively that late at night; given that you have already done 9-5, and you have it in your mind that it’s now the weekend. To get back in “work-mode” and look at code through the early hours of the morning – it’s just madness.

The thing is, I worked on an important project with Colin a couple of years back. There were major problems with the code which were often caused by Colin. I fixed them during work hours. Colin was spending a few hours extra each night in overtime fixing other problems. He would then turn up late the next day, looking completely tired, and then wrote more crap code… then had to sort it out in overtime. Then it’s an endless cycle. If you want quality code, then overtime is not the answer.