Reflecting on my first pair programming interview

For those who don’t know what is pair programming, it is basically a software development technique where two developers/software engineers work together on the same machine. At any one time, one would be doing the actual programming and the other would be reviewing the written code. In both cases, communication between the two developers/engineers is very important.

Pair programming is usually done at some companies who want shipped codes or software that has fewer defects. After all, defects on shipped code could mean higher cost in terms of quality checks and troubleshooting.

And for some companies pair programming is also done as one of the interview stages. One of the purpose is the interviewer to figure out if you are suitable for the position. Interviewees are judged on their soft skills such as communication, ability to problem solve, plan and think critically, and technical capabilities. Another purpose would be to determine if the interviewee is able to work with other developers in the company.

Pair programming interviews are also there for the interviewees to understand who they are working with and how they may have to work in the company. It’s a good chance to find out if he or she is suitable for the applied role.

For me, despite working as a software engineer for five years now, I have never done pair programming. Most of the time, I work alone or in a team. And when it comes to interviews, the toughest kind I get are those where you have to do technical quizzes, solve programming challenges or do whiteboard problem solving.

So having to do a pair programming interview for the first time is both exciting and scary. And sad to say, I didn’t pass the interview.

Towards the end of the interview, the interviewer gave some really honest and constructive feedbacks that are helpful for my personal growth. I thank him for that and for the time he spent on me.

At the same time, I feel really shitty about the interview failure, which is expected. But my mood is now about to fall off the cliff. For some context, I have been struggling with burnout for months, depression and forms of anxiety for the last four. My mood was only just stabilising after three weeks of anti-depressants.

Don’t get me wrong, I’m not looking for any sympathy nor trying to guilt trip anyone. I’m just sharing what I am feeling and have been through.

So what went wrong and could be better?

Low to average technical skills

My JavaScript fundamentals are weak. I was having issues with lambda and anonymous functions as well as some other fundamentals like passing of data. It prevented me from figuring out the solutions to some of the problems I encountered. The last time I did any decent amount of JavaScript was two years ago and even then, I only used the surface of what the language is capable of.

Making matters worse, I had to work with ReactJS, which is a JavaScript framework for developing UI. I also have to work with Redux, which is another JavaScript framework for state management. And it was no fault of the interviewer. I indicated that I want to do frontend development with ReactJS during the previous interview with one of the company’s employee.

At the end, a couple of hours spent every night for the past four days to learn ReactJS and Redux simply isn’t going to cut it.

But it doesn’t change anything. If I still want to be a frontend developer and be good with ReactJS/Redux, I have to keep learning and practice. And develop some apps using those frameworks along the way.

Failure to comprehend actual requirements

This is really on me. I was given the chance to read about the requirements and end goal of the exercise. The key focus areas were listed down in the document. But for some reason, I didn’t realise that I hadn’t really read and understand the whole thing before jumping in to come up with a solution. I could only attribute it to stress and anxiety.

Due to that, the solution I came up with was half-baked and caused major problems further down the development process.

Therefore, I really have to work on improving my resilience to stress and directing the brain to focus better. This is the only way for me to be able to understand future situations more clearly and come up with a better solution.

Overengineering

In software development, there are three principles that all developers should follow for higher productivity. They are:

  1. DRY => “Don’t repeat yourself”
  2. YAGNI => “You aren’t going to need it”
  3. KISS => “Keep it stupid simple or “keep it simple, stupid”

And because of my failure to comprehend the actual problem, my half-baked solutions caused me to violate principle 2 and 3. There were additional React components that I created that weren’t necessary and made the codebase more complex.

I’ll admit that I violated those two principles a lot of time during my five years of software development experience. It is because I like to provision for future uses. Breaking those principles served me well so far because I have experienced scope creep that requires components or functionalities that I thought of in advance and had implemented. That means, I didn’t need to spend extra effort to develop and refactor my code later.

Going forward, I really need to train myself on going for the simplest and fastest solution to any problem.

Took too long and prevented successful gauge of my skills

Because of overengineering, it took me more than twenty minutes to develop the application foundation. After which, I had to redo some of my codes in order to support certain functionalities that I have overlooked because of my failure to read and comprehend the requirements. More time was wasted.

Therefore, I was unable to implement the other features of the application that would have allowed the interviewer to determine my understanding of ReactJS and Redux.

Final thoughts

Self-awareness is actually a very important skill to have. With it, you might be able to determine if you are suitable for a given role or job.

In my case, the combination of my highly-sensitive nature, under-developed stress resilience, highly self-critical and low self-esteem meant that I hadn’t really been able to function at the level required for a so-called experienced software engineer who’s been at this job for at least five years. I’m simply not ready yet to take on roles that require me to be a consultant or a quick thinker.

The other thing that I figured out was that the number of years of experience isn’t really a good gauge of your skills. The interviewer did point out that despite my years of experience, I still wasn’t able to grasp ReactJS even after 24 hours (spread over four days) of reading and practice. He implied that he was able to pick up the framework within two days instead of four.

With that, it could mean that either my fundamentals are very weak or that I’m simply not smart enough to pick up something fast. Or maybe both. For the former, I could work on it by going to read and study the fundamentals again. For the latter, well, I can only work harder than most to achieve the same skill level.

Either way, I’m just glad that I’ve been through it and knows what’s out there. There are valuable lessons to be learnt here, which is all that matters.

Image Downsizer

Let’s say you have images that you wish to load into your application. However, instead of having the user downscale or downsize those images first, your application could do it for them.

Below is a piece of code I wrote in C# that will do just that by brute forcing. Admittedly, it’s not the best solution. An AI probably could do it better but in many cases, the following works pretty well.

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace ImageTuner
{
    class Program
    {
        static void Main(string[] args)
        {
            string originalImageFile = "<image image file&gt;.jpg";
            string scaledImageFile = "<downsized image file&gt;.jpg";
            bool imageMatchCriterion = false;
            bool imageStillTooBig = false;

            float resolutionScaleFactor = 0.95f;
            long jpegQualityLevel = 100L;

            using (var originalImage = new Bitmap(originalImageFile))
            {
                while (!imageMatchCriterion)
                {
                    Console.WriteLine("Image doesn't match size criterion. Resizing.");
                    int scaledHeight = (int)(originalImage.Height * resolutionScaleFactor);
                    int scaledWidth = (int)(originalImage.Width * resolutionScaleFactor);

                    using (var toCompress = new Bitmap(originalImage, new Size(height: scaledHeight, width: scaledWidth)))
                    {
                        var jpgEncoder = GetEncoder(ImageFormat.Jpeg);
                        var myEncoder = Encoder.Quality;
                        var myEncoderParameters = new EncoderParameters(1);

                        var myEncoderParameter = new EncoderParameter(myEncoder, jpegQualityLevel);
                        myEncoderParameters.Param[0] = myEncoderParameter;

                        using (var tempStream = new MemoryStream())
                        {
                            //Save the image byte to memory first.
                            toCompress.Save(tempStream, jpgEncoder, myEncoderParameters);
                            byte[] imageSize = tempStream.ToArray();
                            //Check the image size in memory. If it's too big, continue to loop.
                            if (imageSize.Length <= 512000)
                            {
                                imageMatchCriterion = true;
                                using (var saveStream = new FileStream(scaledImageFile, FileMode.Create))
                                {
                                    toCompress.Save(saveStream, jpgEncoder, myEncoderParameters);
                                }
                            }
                            else
                            {
                                if (resolutionScaleFactor &gt; 0.60f)
                                {
                                    //Reduce the resolution of the image by 10 percent each time.
                                    resolutionScaleFactor -= 0.10f;
                                }
                                else
                                {
                                    //When the resolution scaling already reach 60%, time to look at reducing the quality level by 5 each time.
                                    if (jpegQualityLevel &gt; 50)
                                    {
                                        jpegQualityLevel -= 5L;
                                    }
                                    else
                                    {
                                        //Cannot drop the image quality below 50 percent. Once that happen, the image is almost unusable.
                                        imageStillTooBig = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (imageStillTooBig)
            {
                Console.WriteLine("Image resizing failed.");
            }
            else
            {
                Console.WriteLine("Image resizing completed.");
            }
            

        }

        private static ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }
    }
}


Focus and specialise

Conventional wisdom dictates that there are two main types of people in this world: Those who are specialists and those who are generalists.

But do you accept that wisdom is the truth?

For me, I don’t accept that wisdom.

It’s because, we also forget there’s the third type of person. The polymath. The Leonardo da Vinci of the world.

These are people who are really good at multiple fields or industry that to most people they are no different from specialists from specific field or industry.

Now, some people will just say that a polymath is really just someone who’s the best version of a generalists. However, the truth is polymaths are not generalists. They are specialists who figured out how to take what they are truly good at to apply at other fields or industry as described by Sean Norton in his article titled Polymaths aren’t generalists.

And the sad truth is that being either a specialist or a generalist isn’t good enough anymore for the global economy we have today. We all have to polymaths in order to participate in the economy in any truly meaningful way and earn our keep.

The reason why I said that is because of what I experienced during my job search.

Although I have at least five years of software development experience with a collection of other experiences I acquired over the years, they aren’t enough for me to get into the doors of certain companies like Grab, Lazada, PayPal or even Google. At the same time, I’m unable to go with a smaller and older companies, especially those SMEs in Singapore because they are unable to pay the kind of money that I believe I’m worth. If you are wondering, on average, a software engineer with my years of experience can command at least SG$4800 per month, excluding bonuses. Most SME can’t afford that. And so they will either hire someone who just need a job or more junior. Worse case, the role will be vacant for months because they just couldn’t find the right person.

So my conclusion is, to be a truly good software engineer who can command a high salary and respect from your peers, you have to really devote a large portion of your time to practice and play with technology. Because, you are to have a good grasp of algorithms, mathematics, software design patterns, software architecture, be fast, rational and logical, understand user needs and requirement, know about the different databases, and have working experience with a bunch of programming languages under your belt. A polygot, if you will. You also have to know how to write properly to prepare the necessary documentations. Furthermore, you have to know how to properly manage your time, communicate well with your colleagues and the various stakeholders. Finally, you have to know how to sell or market either your idea, yourself or both. Oh, don’t forget, you might also need to provide support to users…

What if you aren’t that good or don’t want to be that good due to a variety of personal reasons.

You are left with companies that are neither here or there. You still can get a decent pay writing code and managing projects but don’t expect yourself to be doing “change the world” type of projects. Before long you will be replaced by younger generation of software engineers who are probably smarter, faster, more nimble and flexible. I’ve seen first hand just how good the younger codes are. And who knows. Maybe replaced by an artificial intelligence (AI).

Don’t get me wrong. There’s nothing wrong with going to tech companies that are neither here or there. Maybe they can offer better working conditions. Maybe they are much slower in terms of pace. Less over time. The thing is, these companies are still around because they still can deliver a certain kind of value to their customers. In that context, for a person who’s married, have kids and a variety of commitments, your priority will be very different from someone and that might be a good fit. But for someone who’s single and still want to make an impact with what he or she does, those kind of companies might not be suitable.

But of course, don’t forget about self-awareness. You have to know who you are truly and whether you are a good fit in those startups or big tech like Amazon, Facebook, or Google. If you know you are not, then you better find alternatives that are more inline with what you look for and take actions to go that path.

For me, I know why I’m not there at the top. It’s nobody’s fault. I made the decision to split my time into doing a variety of other stuff that don’t really have any relationship to software development.

I devoted time and energy into writing that went relatively well for me for a time. Then the motivation just died and my writing enters into mediocre, barely any content state that you see now. You don’t even see me log in to Medium or WordPress that often these days. Neither do I even think much about writing. I let my writing projects sit and idle. I devote time and energy into video games and TV shows. Furthermore, in terms of the programming languages and technology stacks that I use to build software, I’m all over the place. Even my job role changed from developer to consultant-like and back to developer. I don’t even know how to market myself to job agents and hiring managers. Hell, I don’t even know what I like anymore.

So the lesson here is that one have to focus and be a specialist in whatever they do. Because ultimately, even polymaths are specialists. Don’t be a generalist because it will lead you to nowhere nice. After you have mastered all that you could possibly master in a given field, take the skillsets you’ve acquired to master the field and apply it into another field.

For example, as a programmer, I know I care deeply about formatting, style and highly readable yet expressive codes. So I have to keep practicising until I can do it without betting an eye just so that I can apply those techniques in writing with ease. Furthermore, if I focus on mastering a specific technology stack and framework, I could expand out into mentoring people using that specific stack. Now that will allow me to grow in a different way. Maybe, grow to become someone who can teach and communicate well. Even better, write highly detailed contents about the technology stack I use to help other people. And that could be the start of the journey to become a polymath.