Software. (Reflections 2/4)

Hi everyone ! Welcome to part two of my 'Reflection' series- a collection of blog posts sharing some memorable stories from my university life, with a few key lessons I've learnt intertwined between. Once again, I've listed all these lessons below for your convenience (with the ones relevant to this post bolded), but stick around if you want to hear the full story.

You might have heard a lot of these phrases before because some are very cliché. However, I'm a firm believer that things are cliché because they are true, it just sometimes takes a specific event or two to make you realise how real they are.

  1. You are the average of the five people you spend the most time with
  2. Theory gets the grade, practice gets the job
  3. You're responsible for creating your own opportunities
  4. Your habits are a reflection of your identity
  5. 80% of the output comes from 20% of the causes

    Second year

At the end of my first year, I spent a lot of gruelling hours trying to decide what specialisation I wanted to go into. Due to my piss poor spatial recognition skills and inability to visualise an orthographic drawing, I crossed out all the specs that would inevitably melt my temporal lobe. Bye, Civil, Mechanical, Mechatronics, Biomedical. Next, my failure to drill a simple line of holes into a metal sheet at the compulsory general engineering skills workshop made me reconsider anything too practical- adios Computer Systems, Electrical, Chemical Materials. Yeah, I didn't really have many options left ... So, I spent the majority of my time weighing up between Engineering Science and Software Engineering.

What initially put me off Software Engineering was how different the skill ceiling of students joining the cohort would be. For every other specialisation, everyone starts their second year more or less the same. I mean, no student comes into Civil saying "Yeah, I've built a couple of bridges in my spare time for a personal project". Software kids are a different breed though. On one hand, you have people like me coming in with nothing except the ability to write a for loop and the mindset that MatLab is the best programming language in the world because 'you don't need to compile anything'. Then, on the other hand, you have people who have already self-taught themselves everything the degree has to offer since high school and are only here to collect a degree and their 150k/year job upon gradation. Hell, they could probably write a 'Hello World' program before I eve knew what those worlds meant.

These people were just built different, I thought. How was I supposed to keep up and compete with these freak genius coders in the same assignments, tests and exams? But, even with these doubts, I still ended up picking software. Deep down, I knew I would have to spend a lot of time and effort catching up to everyone else, but I felt really motivated for some reason. Maybe it was because I saw my other friends overseas pushing themselves to achieve great things. I'm not sure, but I was up for the challenge. I wanted to become a 'good' software engineer. Whatever that meant. So I spent the first semester putting all my efforts into my studies, giving up everything else along the way. So when I got my results back at the end of the semester, and I found that I had achieved 4 A+'s and 2 first-in-course awards I must've felt pretty good right? "Surely being at the top of my class means I'm a good software engineer".

Well no, it was quite the opposite. My physical and mental health was at an all-time low, and I still didn't feel I was anywhere near competent as a software engineer. I mean, I could explain to you the importance of encapsulation, or show you how to design a file system using the composite design pattern... but I couldn't actually build anything? If you asked me to make you a weather app and deploy it, I would have no idea where to even start. So I guess the question was why? Why was there such a big disconnect between what I was learning in software engineering and my ability to be a good software engineer? What I found even more interesting was that the same peers in my cohort that I looked up too found these courses just as tricky as I did! Yet struggling with understanding Liskov's substitution principle didn't stop them from knowing everything when it came to building a start-up hybrid mobile application with a serverless backend.

Now a few years later, everything is much more clearer to me. Most programming courses only give you a baseline understanding that cannot be directly applied to building real things without additional work of your own. Unfortunately, that's the reason why there are so many grads that come out of university with coding related degrees that have told me they 'never felt like university taught them how to code'. However, on the flip side, I've seen incredible programmers who can build full functioning web applications without ever stepping foot into a computer science lecture or knowing what 'object oriented programming' is. Yes, of course, they may become a better programmer if they learnt about good design practices, but the matter of fact is that they can still build things, and that's something I couldn't say for myself back in 2018.

We become great software engineers by repeating the process of doing, failing and learning- not by reading coding resources. What I've realised about books and coding tutorials over the years is that they only really become helpful when you already have real life experience to draw parallels too. Yes, Clean Code is a great book, but if you haven't written enough code on your own to understand why its principles are important, then what's the point? You're trying to learn how clean up your code without even knowing what 'dirty code' looks like or the mistakes that lead to it being created. Instead, imagine if you built a personal project that grew so big that it became difficult to maintain. If you then read Clean Code, I promise you will have many more aha moments, to the point where it feels like you are reading an entirely different book. You would also be able to directly apply the books principles into your own code, and significantly increase the chance of this knowledge being committed to your long term memory. This is the learning part of the do, fail, learn cycle.

Another mistake I always see is people blindly follow tutorials for 'building an X app from start to finish'. I genuinely believe this is the worst way to learn. By just copying someone's code, you don't understand why they did what they did. Instead, just pick an idea you're passionate about and attempt to build it- even if you have no idea how. Let's take the example of creating a weather app. You choose to use React because you've used it once before, so you go ahead and set up a starter project. Nice. You've also heard of a website called OpenWeatherMap that has weather forecast data. Hmm but I don't know how to retrieve this data from my application. Now, this is where you should use a tutorial. Find an article or resource teaching you how to make an API request using JavaScript- no more, no less. Continue this process and tackle each hurdle as they appear. Don't know how to centre a div? Google it. Not sure how to manage state? Google it. Wondering how to deploy your application? Google it. The difference between doing this and just searching "How to build and deploy a weather application in React" is that you follow the do, fail, learn cycle which teaches you the most critical skill in software engineering- problem solving.

Coming back to my personal experience, the moment where everything clicked for me was when I embarked on a start-up project with a few of my friends at the end of semester one. Within a year of working on this project, I had learnt more about software development from this project and my team members than I had in all my courses combined at university. Most importantly, these were skills that you don't just empty from your brain after an exam but keep for the rest of your career. During my final year, I realised the experience from this single project gave me a massive advantage over my other peers as I could deliver real-world applications in my practical courses. Even though I still might not immediately know how to build a piece of software if you asked me, I now understand the process and have the confidence to figure out how. That's a magical feeling. Remember, university courses are important, but they'll only get you 50% of the way on your journey to becoming a great engineer. The last mile is up to you.

"Theory gets the grade. Practice gets the job. "

© 2020 Andrew Hu