Mentoring #4

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 haven’t written about my Apprentice in detail for a while. After spending a bit of time with him, he then got involved in more form-filling and exams for his Bootcamp company. It seems weird that we probably paid a premium for the Bootcamp company to train him, but yet he has been working with us for about a year now (I think) and we have barely managed to do anything with him. I really hope we don’t hire from those Bootcamp companies again. You may as well just hire someone and train them up yourself.

The good news is that my Apprentice has now “passed his apprenticeship” which means he has no more dealings with the Bootcamp company and now can work with me full-time.

At the moment, I’ve given him some Junior developer tests that employers normally give before an interview, so he is working his way through those. Ideally, he should have done them in an hour, so I guess he is a long way off from a Junior standard since he has had them a few days. But hopefully, I can train him well, so I’m quite excited for that.

Another complication is that my team has been assigned another Apprentice and my manager asked me if I could also train him. I made a great point that we have loads of Seniors in the team, so why aren’t they being asked? He said it was a good point and would look at promoting me. We will see how that goes.

Here’s a small summary of aspects I have gone through with my Apprentice. These are C# or Visual Studio topics:

  • Use some shortcuts like F12 to navigate methods
  • Ctrl+t “Go to type” shortcut that seems way better than Ctrl+f to find code
  • Use the “Rename” feature to easily rename variables/methods/classes setc
  • Break large methods into smaller ones – use Visual Studios “Extract method”.
  • Using breakpoints, the watch window, immediate window, “tracepoints” to debug. This is very important, you can never be a good developer without being good at debugging.
  • What the “Call Stack” is, and how to navigate through the method calls using Call Stack window.
  • How to create a branch in Git, push it to the server and create a Pull Request.
  • Class inheritance and polymorphism. 
  • When to use Abstract classes and methods.
  • The difference between “hard” casts and “as” casts.
  • Using some basic Linq (Select, Where, OfType).
  • Creating basic Winforms, and how to use Dock and Anchor to automatically resize controls as the form resizes.

The Dialog

I logged into our application and was greeted by a new dialog. When I see something new, I normally scrutinise it, and check out its functionality. I guess I’m quite inquisitive.

The thing is, the dialog also caught my attention because it looked really odd

My eyes were instantly drawn to the link which was in a strange position, and the font looked very large. I loaded up the code to see what was going on. Usually, we use Tahoma 9, but this dialog was using a combination of “Arial” and “Microsoft Sans Serif”, then the link text is 10.5 rather matching the other 9.5 (which is wrong anyway because it should be 9).

The buttons look a bit dark: they are using “Light grey” rather than the standard “Control Light”.

I also thought the Email label was a bit far away from the text box. The buttons are quite far away too.

So I quickly made a few minor tweaks to illustrate how I thought it should look like.

I probably should have left the text in bold, but I had already deleted my changes after taking the screenshot

It’s not perfect, but closer to what I expect to see. It’s easier for me to judge because I’m used to our application. Moving from the original dialog to another looks jarring since the fonts were clearly different sizes, whereas you readers have no comparison.

How does an entire team of developers and testers not notice these differences? I quickly checked the other dialogs they added and saw similar problems there. Sometimes spelling mistakes, grammar mistakes, randomly double spaces between words, and some uncentered text:

why not centre the text vertically?

It’s a complete lack of attention to detail by the entire team really.

I contacted the team, which was led by Colin who is infamous for his lack of attention to detail. His response was that he “was just following what the User Experience team gave him”. I checked the documentation he shared, and the mock-ups looked like how I imagined them to be – and not how his team had implemented them.

One of the Testers said something along the lines of “well, we debated these issues within the team, but ultimately – the Product Owner said it was fine”. 

When they did “fix” it, the developer didn’t send the review to me, but I noticed it and jumped in. It had already been approved by a member of their team, but was it actually good? Would it meet my standards? 

No. He had barely changed anything. 


The fonts were still the wrong style and size, the buttons were still the wrong colour, they were positioned incorrectly. He had even changed a few things no one actually told him to change – so made it worse.

Software Development Interviews

I think a big challenge during the Software Development hiring process is how to determine who is good or not. 

Sometimes companies give large projects as a do-at-home test, but this puts people off when they currently have a job and have other commitments that take up their free time.

You could be given a smaller task, but then it may still not give a good representation of how someone codes, and you could easily get someone else to write it for you.

Other companies leave it until the interview and make developers write code in a manner that is completely out of their comfort zone; e.g. using pen and paper, or a whiteboard. Apparently, Google makes you write code in a shared Google Doc.

I’ve sometimes been given a timed test to complete at home. So you are emailed a list of varied questions and have to quickly code them then send them back via email within an hour.

The challenges they make you do can be varied. Sometimes they can be really basic, using fundamental concepts you will use on day 1 like simple loops. Sometimes they opt for the computer science route, and ask you to implement classic algorithms, maybe a sorting algorithm like bubble sort. Sometimes I have been asked to create a structure like a linked list, or a Directed Acyclic Graph.

You could specifically study these typical questions and then get past the code part of the interview process – even though in a real job you would struggle when posed with various real-world problems. There are plenty of websites that sell training courses that target these algorithms because they are so widely used in the hiring process.

So in the worst case, you will be writing code with a pen, with no resources to help you, under pressure from people watching and judging you.

Yet, when you are employed, you are using an IDE like Visual Studio on a PC, have more time to come up with a good implementation, and can use many internet resources to help you. You will need a good knowledge of the existing codebase, and be utilising 3rd party libraries.

You need to be able to communicate effectively with team members, use Google/Stack Overflow to find solutions/answers. I think it’s important to be able to do code reviews, and show debugging skills, but this is never tested as far as I’ve seen.

In a high-pressure interview, you don’t get a representation of how the person is day to day. I tend to panic in an interview, but am completely relaxed in my job. Even when there is a tight deadline, it still doesn’t faze me as much as an interview situation. So I’d say you can’t even reliably test “ability to handle pressure”.

There was one time we have used this typical interview approach for internal candidates. What’s the point giving a programming test to a software engineer that’s currently employed at your company? It makes sense to give this test to someone moving from another department. I got denied a Senior promotion using this method, yet most of my team members would have vouched that I was among the best in the team. Yet, underperforming Developers got promoted using this process. I’ve written many stories about them here (Colin, and Derek).

I’m not sure what the best way of judging developers, but I would probably go for a programming test using a laptop while allowing use of the internet (or just the interviewer’s knowledge). The test would involve writing some new code, but building upon some existing code which has a bug or two that the candidate is required to debug and fix. The final part of my test would be to review a selection of code changes to see how they handle Code Reviews. This could take a few hours, so I’d only include a few standard questions.

Currently, it’s a failed system if someone can be an excellent programmer, demonstrated by a comprehensive Github profile, yet fail an interview because they couldn’t come up with an optimal solution for some problem while being surrounded by a panel of intimidating interviewers.

Haven’t done a weeks work

I’m currently finishing off a project where we have been assigned a new Project Manager. She hasn’t made a great impression so far.

The Testers haven’t been available over the week, but personally, I did complete the development on 3 items that I’d estimated to be 8 days work, so really that’s 1.5 working weeks of work. So in my mind I was ahead of schedule by half a week.

The Testing hadn’t been done, so we hadn’t fully completed the items, so technically, we get 0 points there. However, I was ahead from my side.

Then in our project meeting (which the Testers also couldn’t attend), the Project Manager stated that she was very disappointed because “we haven’t done a week’s worth of work”.

I told the Testers what she said and they were outraged because they felt “it wasn’t her place to comment”.

A few days later, she sends me a message like:

“could you please quickly pop intot eh knban BOARD AND MAKE SURE YOU HAV PU SEOM NUMBER OF DAYS AGAINST EACH OF YOUT ITEM SO I CAN SEE HOW LONG SOMETHING TOOK ETC”

Project Manager

Did she type that without looking at the screen? So bizarre.

Winforms Dispose Controls Quirk

Here is an interesting quirk with Winforms in C#. Calling Dispose on a Control has a side-effect of removing it from the container it has been added to.

So you can have code like this:

for (int c = 0; c < MainPanel.Controls.Count; c++)
   MainPanel.Controls[0].Dispose();

which correctly removes and disposes every control, even though you have a fixed index of 0. Since the control at index 0 is removed (as well as being marked as Disposed), the next control then becomes index 0. Therefore, it does call Dispose on every control.

So when you look at this code:

foreach (Control item in MainPanel.Controls)
{
   item.Dispose();
}

It looks correct, and would be the code that I would write had I not known about this quirk. However, it doesn’t work as intended. It will only remove and dispose some of the controls since you are modifying the list as you are iterating through it

This is the danger of adding “side effects” to your code. It can cause weird behaviour that you wouldn’t expect, and can be overlooked if you are just reading the code.

Gibbon Testing

In my first programming job, I worked for a small company (under 10 employees in total). We had no Software Testers, and we definitely didn’t have any testing process. I don’t recall any automated tests either; I certainly didn’t know how to write them at the time (not even Unit tests).

When I finished my work, I informed the Senior developer, and I would upload the software to a touch-screen Terminal. He would casually play about with my new features. If he was happy, then the CEO would do similar tests; just casually explore and verify I had done what I claimed. Once he seemed happy, he did his final test: “The Gibbon Test”.

You could say this is some kind of performance testing, and also testing out multiple features in a short amount of time. What did the testing involve? Well, just frantically bashing on the screen.

I’m not sure how serious he took the testing. I mean, obviously it was a joke and we all laughed watching him do it. However, on reflection, I think it is actually a good idea – definitely a good one to do last after you perform all your serious tests.

With certain applications, the user could be frustrated and hit the screen randomly. Your program should be resilient to such abuse. I think a good example would be some kind of gambling game. When the user loses their money and hits the screen in frustration – the application shouldn’t crash, or take ages to respond. It should be ready for the next person to use.

Age

There’s been a few occasions now where I have seen developers write code to calculate someone’s age and it has been incorrect.

I was talking to a developer, Alan who was ranting about some incorrect code, so I looked at the review.

string ageInMonths = person.AgeInYears < 6 ? (person.AgeInYears * 12).ToString(): String.Empty,

So there’s an ageInMonths variable. If they are less than 6, then we populate it, otherwise we leave it blank. When we calculate the persons age in months, we simply take their age and multiply it by 12 since there’s 12 months in the year.

Alan begins by pointing out the problem, but Pierre doesn’t understand what he is referring to, so Alan backs it up with more examples…

Alan: Is this correct? If I am 2 months old, I am 2 months old, not 0 month old?

Pierre: yes, it is optional for people less than age of 6

Alan: I don’t think saying someone is 0 months old when they are 11 months is correct. Nor is saying 12 months old when they are 23 months old

Pierre: thanks, will correct it

This isn’t something that is a language barrier. It’s not even a lack of programming experience. It is simply just a lack of common sense. You just have to be human to realise this isn’t how ages work.

He clearly didn’t test it because it should be obvious the correct values weren’t showing. We could instantly see it was a problem just by looking at the code. We didn’t need to see it in action to realise that.

Tester of One

Penelope, a Software Tester was really disheartened. A bug had been discovered and she felt that she could have found it. Since she was on the project by herself, she holds herself to blame, rather than sharing blame in the team.

Penelope said that she had raised the concern that she was the only tester on a 6-month project but it was ignored by management.

I said that if she wanted to take annual leave during that time, then the team would be impacted. She said that actually happened and the release was delayed by 1 month. Management have to take part of the blame here.

I also said that even though she is the only tester, the Developers do need to share accountability too because they are all working towards the goal of quality and can’t just rely on the Tester.

I did question if anyone was actually blaming her anyway, or if it was the case of Penelope blaming herself which it did seem to be. I did understand how she could feel like she could have done more, but that negative outlook is bad for your mental health.

I stated that she should think of the bugs that she did find. If she found 50 bugs, then what’s the point being down over the 1 bug that was found by users? She has justified her job by finding the other bugs.

I was watching a video recently where former England and Arsenal football goalkeeper David Seaman was recalling the time he conceded a long-range Ronaldinho freekick against Brazil in the 2002 World Cup. He felt he had made a mistake (by being far off his line), and from that very moment was thinking about the backlash and criticism he would then receive from the media and fans – even during the game. He was putting his hopes on the team scoring a couple of goals to redeem him. As he was explaining this story, I wasn’t thinking “yeah that mistake cost us the World Cup”, I was actually thinking “he was such a great keeper, he probably was a major factor in England even getting that far”. A goalkeeper is such an important position, because a mistake often leads to a goal, whereas an outfield player makes a mistake and there’s a few teammates plus the goalkeeper to redeem him. 

Really, the mistakes are hopefully rectified before it gets to the last line of defence, i.e. before it reaches the Software Tester/Goalkeeper. If they save the day, then great. If not, then the team has failed. You can’t blame the last line of defence. 

As it goes, we could easily blame Paul Scholes, he made no attempt to get the ball and gave Brazil a cheap free-kick. 😁

Terrible Developers

Last week, I was reminiscing to myself about the developer that changed a random line of code which clearly wouldn’t have fixed the bug he was working on. It was also the same developer that repeatedly checked in “fixes” in an attempt to fix the build: Using the Build Server to test your code.

I said to my Apprentice, “how do you get into that mindset: where you write code, don’t even check it works then send it to your team to review?” but also “what happens if they did approve it and you are then embarassed when the Software Testers tell you it doesn’t work?“. Or even worse, “what happens if your bad code somehow went live?

I wasn’t sure if I’d see something like that again, but it seems like we have hired some terrible developers in recent times.

Today, I was having a nosey at Pull Requests (aka Code Reviews) and saw some changes that seemed like the developer hadn’t even built the changes, therefore didn’t run their own unit tests they wrote, or done any kind of manual testing.

When you create a Pull Request, it triggers off an integration build. Then you can only complete your request if you have a successful build, and your team members have approved the change.

First of all, the build was failing, and it was a simple syntax error which Visual Studio would have highlighted, and definitely would have been brought to their attention if they clicked the Build button.

Looking at the code though, the first thing that I thought was funny is that they had a Code Analysis error. When you get these errors, most of the time you have to fix the problem it is highlighting. In the case that Code Analysis is wrong and you are smarter than it, you can add a Suppression. To make it clear why it is suppressed, you can add a Justification parameter and add your own explanation to it. To force people to do this, we have added a Custom Rule “SuppressionsMustBeJustifiedRule“. But the sneaky developer went and suppressed that!

[System.Diagnostics.CodeAnalysis.SuppressMessage("Custom.Maintainability", "CM3000:SuppressionsMustBeJustifiedRule")]
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]

I then looked at their unit tests.

bool isValid = validator.IsValid(input);
Assert.AreEqual("True", isValid);

I was convinced that would give an error and it certainly does.

Assert.AreEqual failed. Expected:<True (System.String)>. Actual:<True (System.Boolean)>. 

Comparing the wrong datatypes. A Boolean is a true or false value but it cannot be compared to a String (text) representation of it (“True” or “False”). What they actually need is simply:

Assert.IsTrue(isValid);

If isValid is true, then the Assert passes. If isValid is set to false, then the test fails.

Then the next set of tests were like this:

string successMessage = string.Empty;
List<string> errors = validator.Validate();
if (errors.Count() != 0)
    successMessage = string.Empty;

Assert.AreEqual(string.Empty, successMessage);

So Validate returns 0 or more errors. If there are 0 errors then the test passes because successMessage was initialised to string.Empty and we are comparing it to string.Empty. If there are 1 or more errors, then we explicitly set successMessage to string.Empty (which hasn’t actually done anything because it was already initialised to string.Empty), then we compare it to string.Empty and the test passes. So no matter what Validate does, the test will always pass.

What an absolute waste of time.

I also said to my Apprentice that it is perfectly fine to have a go and writing some code but failing. Then you can say “here is what I have wrote, it doesn’t build but I don’t know why, can you help me?”. Then I can go through it, give him some advice, and together we come up with a good solution.

The worst thing you can do is give up, but then try and get the crap code checked into the codebase.

Star Wars: Knights Of The Old Republic II

Recently, I’ve been playing Knights Of The Old Republic II. On one of the missions, you board a spaceship with 2 party members with the aim of rescuing your main character. Whilst playing, the game crashed, and when I reloaded, I was controlling a character I didn’t recognise.

They had no equipment, average attributes, but what looked like fully maxed out skills. I was quite intrigued by the female portrait (my original character was male, and this newly generated character was also male).

When I went to the screen where it showed the party members, I saw the text:

“I am broken. So very, very broken”

It made me wonder how this came about. Was it some error the developers encountered but didn’t know how to fix? Or is it the case that they just put this code in just in case the game actually ever got into this state?

I didn’t bother carrying on to see what would happen. I did try reload a few times to see if it fixed the problem, but sometimes the loading screen would freeze. I loaded an earlier save and replayed the 20 mins I had lost.