My first exposure to programming was in Grade 8 after hearing classmates brag about creating a computer virus. I soon began copying Batch scripts from YouTube videos like “How to make a virus” and although I never got to building a virus, I did manage to put together a quiz shown on the Console. I was excited but knew I failed my original goal to create a virus and realized it would be too difficult. I quit YouTubing about Batch and soon forgot everything about Batch scripting except that it had goto statements and the “echo” keyword.
I tried to pick up HTML but after reading an entire book dedicated to the subject, I was still lost creating a basic layout. I tried but seriously failed to achieve my goal to make a website. Soon enough, I forgot almost everything about HTML except that there were <h#> and <p> tags.
I tried to make games with GameMaker, which contained a “visual language” as well as a programming language (or maybe it was a DSL? Can’t remember). My goal was to build a tower defence game similar to Bloons Tower Defence but a week into my endeavours, I quit because it was too confusing. Another failure, third strike and I was out. Except that I wasn’t.
In 2011, I tried to learn Java. Three weeks later, I quit out of confusion and failed to learn it.
In 2012, I tried to learn Java. Soon, I quit again out of confusion, and failed to learn it.
In 2013, I tried to learn Java. You guessed it. Failed again. I wasn’t really surprised at this point.
With these failures behind me, I think it’s accurate to say that for all practical purposes, I began learning programming in May 2014 while I was in Grade 12 studying for the International Baccalaureate exams(HL Math, Physics, Chemistry, English, and SL History, French). I had already accepted my offer to study Computer Engineering at the University of Waterloo and knew that I needed to learn programming to complete my degree. I also knew from my experience self-studying math and winning national math competition awards that to genuinely become skilled at a subject, one must do more than attend class on the subject and study for the tests; one must take personal initiative to pursue it.
As a result, I was resolved to learn programming before university started. Given my past failures trying to learn programming, I was anxious whether I would fail again. After reading two textbooks about C#, I felt completely overwhelmed and lost good morale. How do you make a function? So what exactly is an object? And what’s a const? Despite low morale, I didn’t quit this time. I purchased one more C# book (The C# Player’s Guide) and luckily, this one I could actually understand.
When I went to China in August, I took the book with me and studied an hour a day, becoming introduced to polymorphism, LINQ (yes, this beginner book provided excellent overview of C#), delegates, and even a blurb about the CLR and CIL. I challenged myself to do something with my programming skills – something more meaningful than calling Console.WriteLine(…).
After much thinking, I came upon a good challenge: build a Windows Store App before the year ends. For me, this was a huge deal. I had just started programming and was still very shaky in the fundamental syntaxes (how do you instantiate an object again?). Essentially I felt I barely new programming but had set a task to launch a legitimate piece of software to a platform used by millions of users. It was my moon goal.
I read many online tutorials and watched several Youtube videos, but it was hopeless. Integrating C# with XAML was too hard, reading the documentation was too confusing, and the most basic buttons to do something took forever. I was lost. Finally, near the end of September, I made the decision to pay $50 for Windows 8.1 Apps with XAML and C# Unleashed, which was the most money I had ever spent on a book that wasn’t required for school. But it was money well spent.
By the end of October, I had a decent understanding of C# and XAML.
By the end of November, I had already completed 10% of my app and remembered proudly animating images as they came into existence.
By the time first semester was over, I had finished about 20% of my app. Nevertheless, the time I put to build my app instead of studying was manifested in my grades: a 15% drop from high school, barely making the mark to retain a scholarship.
There were still two weeks and a half weeks before the start of 2015 and I still had 80% of the app left to do. But I was motivated because the possibility of actually completing the app was real. A week later and I was 50% complete.
That’s when I made the decision to add a “Games” mode with 15 levels. Looking back, it was a poor time management decision because many a night was I up working around the clock to implement the games. My goal was to get the app working; coding best practices, design, and readability were not my concern and as such, I programmed with astonishing inefficiency. Hours were spent literally copying code from one file and pasting it in another, and by copy-paste, I mean Ctrl-C and Ctrl–V: I clicking the mouse, copy, click to another file, paste. Repeat. 10 repeats later and I realized I made a mistake! Delete everything and restart over. Hours of doing this. My pinkie began to ache after the 3rd hour. Did I consider using inheritance? Yes, but how do you inherit a class? No time to find out; gotta finish project first. What about a global variable? But how do you make a variable global over several files? No time to time find out; gotta finish project first. Why do I need to copy this piece of code? I don’t know, it just feels right. Just keep copying until it eventually compiles. On and on, for several hours! That was a tough day. Instead of blindly copying, I should have sharpened the saw and took some time to look for improvements.
On the evening of December 31st, I completed building my app but it wasn’t until 2am January 1st, 2015 that I submitted it to the Windows App Store. Although it was 2 hours after my deadline, I still felt a lot of pride and satisfaction (and also some anxiety in case there was still some undiscovered bug) having successfully written my first piece of legit software. Sure, the code was awful and broke so many OOP principles and used so many bad practices that it was just sinful, but the app – the end product – still worked! I was hesitant to share my source code on GitHub in case an employer decided to look at it and, much to my detriment, use it to judge my coding standards. But eventually, I picked up the courage to upload the source code – all 30 000 lines of it. Every flaw, every bad logic, every poor design choice was up for show. Looking back, I realize now that this project, in terms of lines of source code, was my largest one – it had more than my next 5 largest ones combined! Today when I look at it, I see more than just bad code, I see the dedication I put into making this app work despite poor code. Despite knowing nothing about best practices, design, or even coding conventions, I managed, by sheer tenacity, to overcome all odds and make a viable app. When I look at the code now, I am inspired, marvel at what could be achieved despite not really knowing what was going on. Where there is a will, there is a way.
Memory Ultrapack was the key reason I was offered to work as a Software Developer at a local Sass startup: Fusebill. During our interview, it was very clear that I was very much a beginner but I think the reason my interviewer, who also became my boss and mentor, hired me was because he saw potential and perseverance. I distinctively remember one conversation that sparked my interest to learn additional software in my free time. We were talking about what type of engineering I was interested in and then he told me that if you really enjoy software and want to become a prolific developer, then there would be times when you programmed past midnight. I was amazed but I had no plans to program past midnight. I wanted to sleep! But something must have been triggered in me because a week later, I programmed past midnight for the first time! That was the spark because it led to many more occasions when I programmed past midnight during my internship.
After work, I would learn design patterns. In July, I tried to build a tower defence game with Qt and V-Play Engine but after two weeks of struggling, I put the project to a stop. Then in August, I learned to use Unreal Engine 4 and built a brick-breaker game. It was an interesting experience developing a game and was the first time I tried visual programming.
The goal of my coop was to develop a RESTful API in my fourth month. I tried my best to learn as much as possible but unfortunately, I still lacked the skills to build the API. Nevertheless, I still contributed to the company and in the process and learned a lot. Although it was tough for me to learn new technologies and actually program on an enterprise software, it was also extremely educational, especially for a beginner like me, and made me a better developer. I knew I was still a beginner, a journeyman, and was appreciative of the opportunity to coop in the industry. I was quite surprised (but not as surprised as I was semi-drunk, but that’s a story for another time) when during our parting lunch, my manager told me ‘When you later coop at Microsoft, let me know’! Wow, thanks for the belief! It’s good to have someone cheer you on even before you knew what you were doing.
School started in September and I was now in my second year of university applying for a second co-op position. With 4 months of coop experience working with C# web development, I decided to apply for more web or C# jobs to gain more experience working with the technology .The only problem was that JobMine (our co-op portal) couldn’t filter jobs based on keywords in their job summaries so to check whether a job used C# or web technology, I manually clicked on over 300 links. Click, wait for tab to open, read. Close tab. Repeat 300x. The process wasn’t as bad as my copy-pasting adventures when building Memory Ultrapack, but it was still incredibly frustrating and annoying.
As a joke, I applied to Microsoft and Google, which received more than 500 applications, and since applications to IBM didn’t affect our quota of applications, I applied to there as well. I didn’t get an interview with Microsoft and Google, but much to my delightful surprise, I received an interview with IBM! I didn’t expect that out of 200 applicants, I would be among the five selected for an interview and although I thought I wasn’t qualified for the position, I wasn’t going to let go of this opportunity.
I remember arriving at the interview feeling scared. We talked a bit about my past experiences and then, much to my surprise, proceeded to algorithmic and design questions! To keep a long story short, I did poorly and didn’t receive an offer. But at least I became aware that it was important to prepare for algorithmic and design questions. Two days before interviews closed, I received a phone interview with BlackBerry Security and oh boy was I nervous! Like IBM, this was a company I really wanted to work at. Before the interview, I booked a computer room with my co-op office (CECA) and was promised by staff that I could use it, which included the computer in the room. Except that promise was never honoured. Two minutes after I logged on to the computer to solve a programming challenge issued by the interviewers, the very same CECA staff one who booked the room for me and promised I could use its computer unceremoniously kicked me out of the room by pointing at the door saying “You’re not allowed to be here”. I mouthed why?. After all, she did promise me less than 15 minutes ago permission to use the computer. The reply, a cold “You have to leave”. I find it amazing that just when I needed the computer the most, I was sabotaged and betrayed by none other than my own coop office – the very people whom we students pay $600 a term to help students get jobs, not fail jobs.
I was hurt and in that instant, I realized my trust had been gravely misplaced. Imagine my frustration as I tried to write an online interview questions without a computer. Luckily, I had a laptop (20% battery and no charger. My laptop also had a tendency to be reallllly slow to boot). I managed to log back in to the programming challenge 5 minutes later, but those 5 minutes ruined any chance I had of receiving an offer. Adding insult to injury, when that same CECA staff saw me finish my interview, she smiled and seemed to mockingly said “See, that didn’t go so badly”. With great restraint, I stayed calm and didn’t say any expletives unsuitable for this blog. It was challenging. I wonder how much of the $600 I pay to CECA every term went to this particular staff member because I wasn’t aware I had paid money in order to sabotage myself. I sure hope she doesn’t get the chance to sabotage any other students.
I received and accepted an offer to work at CIBC. As exam time rolled around, I felt the need to learn C++ so I picked up Qt and QML to develop a speed-test game. I didn’t know until later that this small game would be very helpful to securing my next coop. Exams came and left. Soon, 2015 was over.
At CIBC, I had the opportunity to be mentored by a mid-age man with 25 years of software experience, who has been a CTO, wrote a DSL and a database, read Knuth and every other book his teachers had recommended, worked with low-level systems, and loves backpacking. He was wise and provided many insights about the corporate world. At some point, I realized that when spoke with me about software or corporate life, it would be in everyone’s best interest if I keep my trap shut, thereby not exposing my own ignorance and sprouting nonsense, and take notes on what he says – yes, I took notes because my mentor inspired better than any professor I’ve had. One month later, my mentor left on a backpacking trip but in that one month, he shared with me the important messages that software was more than languages, it was an ecosystem with architectures, best practices, readability, etc., and that blind loyalty to an organization (like my blind trust in CECA) is dangerous for oneself.
It’s likely my mentor triggered some sort of subconscious need because I soon found myself working on my hobby projects with greater fervour than before, programming until sinful hours, and became genuinely interested in increasing my software skills.
As a hobby project, I decided to tackle my problem using JobMine to filter for jobs by developing a web scraper that downloaded jobs from JobMine and built my own filtering system so that other students and I can more easily find jobs we want. As of present, this remains my most influential hobby project (then again, almost all my other hobby projects were not built with the intentions to be used by real users but rather a playground to practice specific software skills while still building something nice). This project saved 10+ hours in my job search and more than one classmate told me that because of it, they found their coop job! I had initially thought building this project would take 2 months but it turned out to take only 1 month!
In the next 3 months, I bought and read a dozen software books and became more conscious about how I structured programs. Inspired by the projects my mentor had built throughout his career, I pushed myself to dedicate more time into learning software in order to develop more sophisticated projects. A typical weekday would be 8 hours of programming at work followed by several hours of programming after work. A typical weekend would either be hanging out with my girlfriend or programming the entire day. I took programming and developing projects very seriously and at the end of my coop term, I had not only build the web scraper, but also a multiplayer chess game, two Android apps, a TI calculator program and published four programming articles. Nevertheless, I also felt burned out. I needed to take a break and knew that it was in my best interest to relax, temporarily pause from programming, and just chill. Unfortunately, school was due to start and I wouldn’t get the break I needed.
If you followed my blog, you might have read my thoughts about 2B, the school term from May-August. To summarize my thoughts about school: I was not impressed with what I was learning in class. To that end, I emersed myself with learning software. Throughout May, I was practicing algorithm and design questions, learning from my interview with IBM that they would likely show up again. After much studying, I finally came to develop an intuitive feeling for recursion and fundamental algorithms. Interestingly, few companies asked questions as difficult, actually asked these questions but I still learned a lot. I received an interview with Intentional Software, who had 4 stages of interviews. They grilled me on CS fundamentals and I grilled back. However, I stumbled on an actual programming question but unfortunately wasn’t invited to the next round. Nonetheless, it was a good experience. I also interviewed with SMART Technologies, the creator of the SMART Board. I was flattered that the interviewers had taken the time to look at my GitHub profile and talked about specific items from my cover letter. They also noted my speed game built with Qt from six months before. Overall, the interview was a fun experience and the interviewers and I exchanged a couple funny one-liners. Interviewer: “Have you ever been to Calgary” Me: “I once flew over it on the way to Vancouver”. The reason I applied to SMART was because I wanted to work on C++ and there was one posted position covering C++ and the others were with web technologies. I didn’t think I would get the C++ position because my previous work experiences were with web technologies but applied anyways. Lo and behold, there was actually another C++ position available that wasn’t on the job posting: Driver’s and Diagnostics. I didn’t really know what that was about but it sounded really really cool and different from most co-op jobs.
I had previously told an interviewer that for me, the salary isn’t a big deal since if a salary is within +/- $5/hour, I wouldn’t base my decision on salary but more on the learning experience. If the salary is more than $5 difference, then the workload and learning oppurtunities would likely be more advanced. As it turns out, SMART not only offered a C++ position working on a cool team, but also the highest salary. It also was located in Calgary and had provided travel expenses. I was nervous during the interview upon realizing that this would be a great company to work at. Due to a glitch in my coop center’s paging system and my rapid speaking speed prompted from nervousness, we finished the interview 15mins ahead of schedule. Darn.
Later that day, as I was prepping for an interview with BlackBerry Security (a different team than before), I received an offer from SMART. The next day, I interviewed with BlackBerry and this time, received an offer (I guess karma decided to give me a second chance. This time, my coop office didn’t sabotage me but a minute before the phone interview, my phone decided to restart itself…and I missed the interviewer’s call. After restarting, I called back and luckily, things went smoothly from there. My phone, at that time, was a BlackBerry phone. I now use an iPhone). I decided to accept SMART’s offer.
Throughout June, I had been studying Python and planned on making that Tower Defence game I had wanted to make so many years ago. Having diligently studied software for six months, sacrificing hundreds of hours of my own time that could have been spent on other things in order to pursue software, I felt pretty good about my software abilities. I have an upcoming coop at SMART Technologies, intuitively understand fundamental algorithms, have already built several hobby projects, and worked cumulatively 8 months in the industry. I felt good and thought I had a strong grasp of software. I think you can guess where this is going.
On a fateful day in early July, I logged into my class’ Slack channel and saw that a friend had shared his resume. Out of curiosity, I took a look at his resume. I knew it would be impressive but I should have mentally braced myself more. It wasn’t just impressive, it was intimidatingly amazing! I took pride in my software accomplishments and what I’ve learned so far but my projects, with exception to one, felt like “Hello world” compared to his. But quickly, my disappointment subsided and in its place, I felt inspired. Here was living proof of how much a person could learn if they put the dedication and time into learning. It’s possible to learn at a faster rate than I had been learning. I felt motivated and wanted to accelerate my software growth and absorb more. At the time, I didn’t know how much I could absorb but I was determined to try my best. I knew it would be a tough battle but as they say, where there is a will, there is a way.
With renewed energy, I redoubled my efforts to learn Python and build a tower defence game. Learning software went from Top Priority to Supreme Top Priority. I wanted to learn more, and more quickly, and I was going to push myself to the limits.
I had been developing my tower defence game and learning theory behind some concepts for over a month now. But to learn more, I, for two weeks, stopped doing assignments, homework, review, and skipped Monday and Friday classes in order to program. Hours and nights flew by. Coffee was consumed. Day melted into night and night turned to day. I gave my tower defence game my utmost and absolute attention. Coursework had to be put on a temporary stop. At the end of the two weeks, with my prior Python research and development, I built Tower Pop, a multiplayer tower defence game that uses machine learning to help players make moves. It wasn’t finished; the UI was lacking, there were some bugs, and the machine learning algorithms could certainly need more work. But I was pleased. I learned and absorbed and had successfully pushed myself as much as possible. I had quite a bit to catch up in coursework but it was worth it.
It was soon August and exam time. I tried to keep myself busy by studying for exams but felt empty and wanting instead. I realized I wanted to do more programming but not just a simple program; I wanted to build something more complicated; something tough. I thought about encryption but didn’t want to delve into the finer details of number theory so I decided to learn compression algorithms instead. Looking back, I’m not sure what caused me to want to challenge myself to learn compression algorithms in the middle of studying for hectic exams, which I was already having trouble with. Perhaps the knowledge of what somebody my age who also started programming at the same time as me can accomplish embolded me to become more aware of the possibility. Of what is possible. And by knowing what was possible, my apetite to learn automatically sought to consume and learn everything that was possible.
And so, I began learning compression algorithms during the middle of exams. For every course except Operating System, I would grumpily study. When I took a break to learn compression, I felt relieved and happy! As expected, learning and implementing the algorithms took some time. By the time exams ended, I could successfully compress .txt files with Huffman. Soon afterwards I added two more algorithms and after about a month of sustained effort, I built a cross-platform text compressor.
Afterwards, I wanted to try my hand at building a DSL. I picked up Boo and built a very primitive DSL, more as to understand what a DSL is rather than a legit language. It was an interesting experience.
August ended and September came. I lived in Calgary and worked at SMART Technologies. My mentor was a self-taught chef with two engineering degrees, one in Software Engineering and another in Electrical Engineering. He was very knowledgeable about embedded software and guided me through the hoops of cross-platform development, coached me in using more tools, and made sure that there were tasks for me to do as he worked 10+ hours a day developing the kernel and daemon services of the next generation of the SMART Board.
Transitioning from web development to the workflow of large scale C++ development and working close to the hardware was a large challenge for me. My biggest mistake at SMART was not clearifying at the start of my internship the expectations for me. As a result, throughout almost the whole 4 months, I was stressed that I was merely working on driver diagnostic tools while my coworkers worked on kernel and Android development, hard-core stuff, because I had assumed that I was underperforming since I wasn’t also working on kernel development. I pushed myself to work harder and I learned a lot but compared to kernel development, I thought my work wasn’t significant. It wasn’t until about a week before I was due to leave that I asked my mentor what previous coops worked on. He told me they did tasks similar to what I had been doing and that he was happy with my work! I huge boulder was lifted from my shoulders. All this time, I had thought I was underperforming when actually, I was on the right track! All that stress for 4 months for…well…for nothing! Lesson learned!
Throughout September, I set a goal to build a new programming language and began studying compiler theory. It was tough and boggled my mind. At the same time, I began to have doubts about whether to continue learning software or try a different career path, such as sales or business. By the end of September, I decided to take a break from studying compilers because it, plus the concentration I put into learning at work, was starting to overwhelm me. I switched my hobby project towards something more familiar: web development. I picked up Node.js and feeling the un-finality of not having the skills a year and a half ago to build a RESTful API and curiosity to try one out, I built a story-sharing app that contained a RESTful API. I finished building it in early December and deployed it with Heroku. Then, I switched gears to once again, double my effort on building a programming language. After much studying, I finally did build one. It’s called Swoosh. It was very simple and had traces of Pascal but overall, it was a programming language I built.
Over the past year, I put in over 1000 hours of my own time outside of work or school assignments to study software development. That might seem like a tall order. But most of my free time was invested in learning software, 54/64 books I read were software-related (I normally don’t read the whole book from cover to cover, usually half the book or specific chapters), and most of my major hobby projects took 150-200 hours to build. There were many sacrifices made to pursue learning software, from missing out of social events to feeling lots of stress to developing bad posture and some unhealthy habits, not all of them were good sacrifices but I think, overall, they were worth it.
Since first semester, I progressed from knowing very little about software development to gaining meaningful work experience, understanding the software development life cycle, having the confidence to take on personal programming projects, and overall, learning a lot about software development. There’s still a lot to learn and I’ve only barely scratched the surface but nevertheless, despite many failures and setbacks, I am happy that in two and a half years, I progressed from a Windows app to an interpreter.