Saturday, 4 April 2015

First year reflection

Thoughts on Software Engineering at Waterloo

It’s hard to believe that my first year of university is almost over. I would say that I survived first-year engineering, except that it’s never been about surviving—I loved every minute of it. It’s been an incredible experience, and from what I can see it’s only going to get better. In this article I’m going to compress the past decade of my life in a few paragraphs as well as talk about misconceptions, strategies, discoveries, and other experiences.

Programming hobby

Ever since I was ten or eleven years old, I knew I was going to write code for a living. I consider myself lucky in this respect, since few people discover their passion so easily, and fewer still are able to do it for a living. For me, it started when I discovered the basics of making webpages on the World Wide Web with the help of my uncle Mike and online tutorials. In hindsight, I had no clue what I was doing half the time. I remember being baffled by the official Java Tutorials, specifically by an example that used an interface called Relatable that seemed useless to me. On that occasion and others, I think of eleven-year-old me and wish I could address the confusion with a quick two-minute explanation. But nineteen-year-old me wasn’t there, so I continued learning on my own as best I could.

During my early teen years, I went through what I called “phases” of interest—drawing, programming, gaming, reading—focusing on one exclusively for a few weeks, getting bored, and moving on to another. At some point, writing code became my permanent phase, and I remember noticing the change. My early programming hobby consisted mostly of playing around with HTML/JavaScript and Java. In 2009, I discovered Python, and I liked it much better. I know the exact year because it’s documented in the first substantial project I wrote, a command-line version of the Cheat card game with AI players, written in Python. It’s about a thousand lines of code, and an OCD diagnosis could probably be made solely by looking at the documentation.

I continued my self-directed learning in high school. For a while I was very interested in making games using OpenGL. I didn’t produce very much because I spent the whole time learning about shaders and vertex buffer objects and the evils of the legacy fixed-function pipeline and trying to do things in the most efficient manner possible. During the Christmas break of 2011–2012, I learned about assembly languages and wrote a few programs by hand in assembly. A bit later, I did the first half of an online course called Nand2Tetris, where I learned how computers work from first principles. In 2012 I discovered Haskell, and in 2013 I met Lisp; but they deserve their own articles, so I’ll leave it at that.

Choosing Waterloo

By grade ten I was aware of the options I had for university, so I asked my computer science teacher whether I should study computer science or software engineering. He recommended the latter, and that was good enough for me. It was still a long way off, but in the back of my mind was the idea that I would eventually become a software engineer. In grade eleven, I decided that I wanted to go to the University of Waterloo. I knew about Waterloo because my dad went there for his Master of Accounting, and I decided on it mainly because of the reputation of its co-op program, and for its ability to churn out Silicon Valley material.

When the time came, I applied to Waterloo for Software Engineering as my first choice and Computer Science as my second. I also applied to Carleton University for Software Engineering with my third OUAC application. I was accepted early for CS at Waterloo and SE at Carleton, and I got my acceptance to SE at Waterloo in the spring. Even then, I was still debating between SE and CS because they seemed so similar. I ended up choosing SE mainly because it would be easy to transfer to CS but not so easy the other way around. It was the right choice, but again, it would have been useful to have my future self explain a few things. Ironically, the one difference I didn’t find in my research turned out to be the most significant.

Software engineering vs. computer science

There are five main differences between SE and CS at Waterloo. First, SE is unique in that it is jointly offered by the Math and Engineering faculties. I’d argue it gives you the best of both worlds. Second, engineering students have a much higher workload—this is the difference that I didn’t discover until I got there. In my first term, classes went from 8:30 a.m. to 5:50 p.m. There were a couple hour-long breaks in between, but still. Some of us have heard of a mythical thing called “free time,” but sightings are few and far between. Okay, I’m exaggerating a bit, but my point is this: there’s no way you can survive if you don’t enjoy what you’re learning. Third, SE has a secondary focus on hardware that CS lacks. This was perfect for me because I like hardware, but not enough to be a computer engineer. Fourth, SE has less flexibility in terms of course selection. We only get eleven electives: one per term starting second year, two in the second-to-last term, and five in the final term. This could be a drawback, but I like it because picking courses is stressful, and because it enables the fifth difference, the cohort system. Each year Waterloo admits a new cohort of about 130 SE students. We take all our required classes together, so it’s easy to get to know everyone. It gives you the feeling that, no matter how tough things get, we’re all in it together.

Some of these opinions may change as I reach upper years, but so far I love Software Engineering. I’m not saying it’s the superior program—all I’m saying is that, for me, it’s perfect. I’m sure there are CS students who prefer their program for an entirely different set of reasons. The flexibility to choose more courses and take a minor could be an important factor. In any case, the decision should not be made based on the perceived value of the degree. Students of SE and CS take many of the same courses, and there are few jobs that one can get but not the other.

Orientation week

My university experience began with O-week. Whatever it is, it certainly wasn’t designed for introverts. It wasn’t that bad, though—purpling your body was completely optional, for example. During this time I was also getting settled into the residence life at Village 1. My dad was right: the homesickness lasted about a week, and it was fine after that. I participated in the first few orientation activities, then holed up in my room with aloe vera for the rest of it because I was sunburnt so bad that my face was blistering. Even if I forget the sunburn (easier said than done), I don’t think I would have missed much if I had completely skipped O-week. The atmosphere was totally different from normal university life—no one actually has school spirit during the rest of the year. I met a few people in my program, but I would have met them later anyway.

The one interesting part of orientation was the session where they talked about engineering (and later, about software engineering in particular). They talked about the workload, how lectures, labs, and assignments add up to more hours than a full-time job. It was also said that seven hours of sleep is a common goal for engineering students. That was a lie! At least, the idea that you have to sacrifice sleep to be in engineering is a lie. I get a full eight hours of sleep from 9:30 p.m. to 5:30 a.m. nearly every night. There’s much more to time management than sleep deprivation.

First term

I had six courses in 1A. As I mentioned earlier, classes ran from 8:30 a.m. at the earliest to 5:50 p.m at the latest. To make up for that, we had hardly anything on Fridays—just one tutorial and a lab. I stopped going to tutorials pretty early on, except for the ones with quizzes, which counted towards final grades. We had all our midterms in a single week, as opposed to having them spread out in the evenings after classes. I liked that, but I’m not sure if it was worth it: to account for the missed lecture time, we had many 8:30 a.m. make-up lectures scheduled throughout the term.

My first university lecture was on linear algebra (Math 115). I really enjoyed that course, both for its own sake and because I knew how useful it would be. Linear algebra has many real-world applications for software engineers—it’s used extensively in 3D graphics and in facial recognition, for example. My other math course was calculus (Math 117), which taught me integration, an essential skill for future courses. Then there was linear circuits (ECE 140), which was interesting, but frustrating at times because it’s so easy to make mistakes in the calculations. I learned about complex numbers three times, since each of these three courses had something to say about them. The hardest course was definitely physics (ECE 105), where I learned about kinematics, linear and rotational dynamics, work and energy, oscillations, and waves. Although I probably won’t use those specific concepts very often, I’m glad we had to take it because it helped develop my problem-solving skills. In my computer science course (CS 137), we used C to learn about basic algorithms. I skipped most of the lectures because I already knew the content.

Finally, there was an engineering concepts class (SE 101). The weekly lectures touched on topics including methods of software development, project planning tools, engineering licenses, and Canadian law. What most people remember from the course, though, was the group project. We were in groups of seven, and we had to develop something using Python and a Scribbler Bot. In the first demo it had to drive around an obstacle, and in the final demo we could do whatever we wanted. The Scribbler Bot was a bit of a step down from my high school robotics class, where I got to use Arduino boards with accelerometers, ultrasonic sensors, radio transceivers, and servo motors. In particular, the Scribbler was annoying because the time for a 90º turn depended heavily on its battery life. Anyway, our end product was a web application where you draw shapes on screen, press a button, and watch the robot draw them on paper. I hosted it on GitHub; the commit log may give you an idea of who did most of the work.

Second term

The schedule for 1B was much better. Classes still started at 8:30 a.m., but they ended at 1:20 or 4:20 instead of 5:50 p.m. The total class time was similar because Fridays were just as busy as the rest of the week, and because we got one hour-long break instead of two. There were two labs this term, but we only had them every other week. We had SE 102 on our schedule, but it was just an occasional seminar, not a real course.

Just like in 1A, in 1B we had two math courses, one circuits course, one physics course, and one computer science course. Instead of linear algebra, I had algebra (Math 135), where I learned how to write proofs involving sets, integers, congruence classes, and polynomials. I really liked this course, which should come as no surprise since I read How to Prove It for fun in 1A. There are few things more satisfying than finally figuring out a proof on your own. I had another calculus course (Math 119), where I learned about Taylor series and multivariable calculus. I can’t decide if algebra or calculus was my favourite. In my digital circuits course (ECE 124), I learned about binary logic, combinational circuits, and sequential circuits (synchronous and asynchronous). I had an advantage here because about half of it was a review of my high school robotics class. The course on electromagnetism began with, “Welcome to ECE 106, your worst nightmare,” but it wasn’t all that bad. It was useful as an application of multivariable calculus, and it taught me how to reason about problems in three dimensions. Finally, there was CS 138, where we learned about data structures and OOP using C++. It was somewhat useful, but I learned far more just by working on a side project in C++.

Co-op interviews

The big difference between 1A and 1B is that in 1B we were all running around trying to get co-op jobs. In the end, I had ten interviews, and I managed to miss only one class because of them. Two were in person, one was on the phone, and the rest were on Skype. I was nervous for the first few, but after that it became fairly routine. I wore a suit at first, but the interviewers were never dressed very formally, so I stuck with a dress shirt and khakis after that. It was hard to know what to expect since each interview was different. I prepared for all the behavioural questions I could think of—“Tell me about a time when you …”—but I actually got very few of those. Some interviewers drilled me on the details of JavaScript, and others asked more general technical questions or none at all. The most open-ended question I got was, “What is the most important thing in software engineering?” I actually liked that question because I have an opinion on it, so I spent a little while talking about abstraction.

There was one thing common to all my interviews: they almost always wanted to know about my side projects, probably because I had listed them at the top of my résumé. By the end of February I had described each project several times, so the interviews became a bit more predictable. I believe those side projects were the main reason for my success. For example, I worked on a λ-calculus project called Lam purely for my own enjoyment during the Christmas break between terms. At the time I had no idea that potential employers would be so interested in it! I ended up getting three offers and five rankings, and I accepted the offer from Shopify. I’ll be working there in a month, and I’m very excited.

Striking a balance

Everyone has their own way of getting through the term. Some people just take it one day at a time, doing whatever’s due tomorrow, relaxing if possible, and staying up all night if necessary. Whatever works. I prefer to follow a strict and consistent schedule. I already mentioned that I usually get up at 5:30 a.m. After showering, I start my day with a cup of coffee and I make a list of things I need to get done. I’m rarely able to cross everything off, but I write them all down anyway. I always do the assignments as soon as they become available—not necessarily to get it over with, since I do enjoy most of them, but simply to avoid stress. Whenever it starts to feel overwhelming, which can happen when there are interviews and apartment contracts on top of midterms and homework, I ask myself if what I’m doing right now is making progress towards any of those big goals. If so, that’s all I can reasonably hope to do.

I try to study a little bit every day rather than cramming before exams. I also work on side projects when I get the chance. But, as much as I love software, I can’t do it all the time. By managing my time carefully, I’m able to give myself a reasonable amount of free time to do other things. On a good week, I’m able to finish everything by Friday to have a completely free weekend. It’s difficult to get a perfect balance between school and the rest of life, but I think I’ve done a decent job of it. Halfway through my first term, I started running. Two or three times a week, I go around Ring Road, which is just over three kilometres. The first time I went it took me 18 minutes and 30 seconds; now I often finish in 16 minutes. I once went when it was −30 ºC with the wind chill.

I’ve also made sure to set aside time for reading. I’ve finished seven books so far this year, and I have many more on my to-read list. I’m often trying to make the most efficient use of my time around classes, so it’s nice to forget everything for a little while and read. My other distraction is playing the piano. I’m not that good at it, but I’m able to learn songs by muscle memory if I practice for a very long time. When I have work to do, which is most of the time, I like listening to WCPE, a great classical radio station. At some point during first term I accidentally clicked on it in the list of radio stations on iTunes, and I’ve been a faithful listener ever since.

Intellectual buffet

In high school I was very focused on marks. They suffered a softer blow than I had expected here at Waterloo, and that probably helped a bit for the co-op process, but it seems that marks matter less and less in upper years. It’s easy to lose sight of the purpose of learning, to become fixed on the numbers on the assignments and exams. If it won’t make much of a difference, why care about it? We’re paying a lot to get an education at Waterloo, so presumably we should care if it’s working or not, and marks are a reflection of that to some degree. But that doesn’t seem to be what people really care about most of the time.

I’ve been trying to change my attitude towards courses at university. I’m not just plodding through here because I need a degree to get a job. I’m not just holding onto ideas long enough to regurgitate them on exams and then forget about them. It’s not just a game where the highest GPA wins. Thinking along these lines reminded me of some advice my computer science teacher R. Young gave me about a year ago:

There are so many interesting topics! University is like an intellectual buffet. The hard part is having to decide what to put on your plate. A plate is only so big, a human stomach is only so big, and the buffet closes at 10 p.m.

I think this is a great metaphor. Too many people go through university like they are being force-fed. When I step back and ask myself why I am in this program and why I am taking these courses, I realize that it is a once-in-a-lifetime opportunity to learn anything and everything that I want. And it would be a shame if I didn’t take full advantage of it.

Looking forward

As my first year at Waterloo draws to a close, I look forward to a great summer working at Shopify and all the new experiences that will bring. Exams haven’t even started yet, but it feels like I should be going home right about now! I’ll be back at school in the fall, but only for four months at a time, alternating with co-op for the rest of my undergraduate degree. By that I mean until 2019, so there’s still a long road ahead! And that reminds me of the Road, from my favourite poem by Tolkien:

The Road goes ever on and on
Down from the door where it began.
Now far ahead the Road has gone,
And I must follow, if I can,
Pursuing it with eager feet,
Until it joins some larger way
Where many paths and errands meet.
And whither then? I cannot say.