Last updated May 2014


My life has changed substantially since I started university, and most of the change is due to the Software Engineering co-op program at the University of Waterloo.  This page is intended to document these changes and the experiences I've had getting my degree.

My parents have always had to work hard for a living.  Manual labour in frigid -30C (-22F) conditions is something my father is very familiar with.  I consider myself very fortunate that it's unlikely I'll ever have to do manual labour to make a living again.

When I was a kid, my parents started a business selling railroad ties.  Railroads would periodically replace older railroad ties as part of their regular maintenance, and contractors would bid to clean up the old railroad ties.  Many were busted and worthless, but some were ideal for re-purposing in retaining walls.  We would always win the small contracts because other contractors would simply pick out all the good ties and leave a huge mess, while we would bring rakes and shovels and pick up every last particulate until the ground was clean.  This would typically entail a full work day after a 4 hour drive (in both directions) to the middle of nowhere.  At the end of the day, we'd all be dirty and climb into a ton truck that didn't have any leg room for the middle passenger.  Whenever my father needed to shift gears, I would have to lift my legs up, otherwise the stick shift would hit them.

The work I do has changed since then.  I just got my software engineering degree, and I finished my last work term at Amazon Inc. working on Amazon Redshift.

This was what I did just before coming to university, and I would probably still be doing it if I didn't get accepted.

This is a skidder, and I used it to pull trees out of the forest.

I grew up in New Brunswick, Canada.  The exact place I'm from has no population statistic associated with it.  If you Google for it, you will find a different place in New Brunswick that just happens to have the same name.  The nearest town is a 15 minute drive away and has a population of about 4000.  The nearest city is about an hour away.

This is the same ice storm that took out the power in Toronto in winter 2013.

When I first applied to Waterloo, I was overly confident that I would get in since I already had a web site and a lot of coding experience.  It didn't feel good when I got a letter saying that my application was rejected.  My father insisted on calling the university to ask why I was rejected, but I told him not to.  He did it anyway, and that was probably the most important call of my life because I was put on a waiting list, and a couple months later, I got an email saying that I was offered admission contingent on good performance in some correspondence courses I was taking.  This is a picture of the 18 hour drive from my house to Waterloo.

Work-Term #1 ProductWiki

For my first work term I worked with Omar Ismail (co-founder of ProductWiki), who went on to also co-found Streak (YC S11).  I think I was really lucky to get a job at ProductWiki, because I actually got to write code there.  For a first co-op, many students didn't get jobs that involved coding, and a few didn't get jobs.  The ProductWiki team were also UW alumni, so they understood the significance of work term evaluations that students receive.  A bad evaluation will show up for every job that students applies for during their next 5 co-op rounds.  They gave me the highest evaluation of 'Outstanding', which set a precedent for me.  In the end, I got an outstanding from all of the 5 companies I worked for.  I don't have any work related pictures, but here are some photos I took around this period.

This was taken in the laurel creek conservation area, near where I lived at the time.

Velocity Residence

I spent 6 terms living in Velocity Residence, an entrepreneurial themed residence at UW.  I didn't create any million dollar startups while I was there, but I gained a much more mature perspective on business over the years.  I think everyone has an idea for a new social network, or a to-do app, and Velocity allows you to get that out of your system as a short term project, instead of being unfortunate enough to convince a VC to give you money for your terrible idea.  The pitch practice and networking opportunities are also very valuable.

Starting about half-way through the first term, I started taking pictures of the blackboard notes instead of writing them down.  I never took notes in high school because my handwriting was so messy and slow.  I also found it difficult to listen to what the lecturer was saying while writing things down at the same time, so this was perfect for me.

I posted these notes on, a site I created to share the notes with members of my class.  This graph shows the number of page views per day to the Class of 2014 Software Engineering course notes site during the 2A term. Each number indicates the day a major exam took place.  Note the spike in page views the day before most exams.  There are 5731 pictures on

Most Popular Browser by Visitor

The sample consists almost exclusively of people in the SE 2014 class who visited the site in the 2A term. This data is based on individual visit, so it biased in 2 ways: First, toward the people who actually visit the site since not everyone uses it. Secondly, toward people who visit the site more.

Most Popular Operating System by Visitor

Visitor Repeats

Work-Term #2 Xtreme Labs

My second work term was in Toronto at Xtreme labs.  This was exciting because it was the first time I had ever visited a big city.  Xtreme labs has since been acquired by Pivotal Labs.

Work-Term #3 OANDA

On my third work term I lived closer to downtown Toronto.  I worked for OANDA, which was cool because I had opened a trading account with them almost as soon as I turned 19.  When I first opened the account and started learning about the FOREX markets, I never expected that one day I would actually work for a market maker.

On one cold fall morning, there were a bunch of tiny frozen mosquitoes on the steps to my apartment.

Dundas Square

6:00AM view of Toronto from Trinity Bellwoods Park.

One term I became so overloaded with school work that I stopped going to any of my classes and just did assignments in my room all day, every day.  On this particular day, I finished my combinatorics assignment at 5:30AM just as the sun was coming up, so I celebrated by going for a walk and taking some pictures of the sun rise.

Work-Term #4 NVIDIA

I did my fourth work term at NVIDIA.  It was my first big-name company, and it was a nice feeling to actually accomplish the pilgrimage of so many other software engineers who ultimately end up in silicon valley.

At NVIDIA, I re-wrote an internal web site that showed the results of the many thousands of unit tests for CUDA from a number of static pages, into one fully dynamic search tool.  This saved hours of time for the QA team and developers.  They are now able to bookmark a URL that shows only the test results that are relevant to them.  I also made it possible to re-run unit tests directly from the test result page.

I had a lot of trouble finding a place to live, and I ended up renting a bedroom in a family's house for $1000 a month (which was a very good price).  The catch was that I now had a 10km bike ride to work every day from San Jose to Santa Clara.  I ended up moving to two more places in search of a place that was closer to work.  Taking the bus would have required a 2 hour commute and one transfer.  This place is not friendly to people who don't have cars.

I eventually moved closer to work, but I still had to cross this road on my bicycle every day.

I found a glitch in the matrix.  This is located here.

The first week end after I arrived in California, I biked up Sierra Road.  These pictures don't really do justice for the feeling you get looking out over the rolling green hills that seem to stretch on forever.

One day in Subway, a man in a tie dye shirt who looked kind of like a wizard started a conversation with me.  He told me about how he never used to be religious, but after he had chickenpox around the age of 40, he starting seeing signs from god.  He saw visions of angels and now spreads the message to everyone that the most important thing in the world is love by creating artwork that represents the angels he sees.  He gave me this picture.

This is a picture of me with Jen-Hsun Huang, the CEO of NVIDIA in his back yard.  If I could have this photo taken again I would have shaved and got a haircut but I guess I'll have to live with this one.

The CEO invited all the interns over to his house for the evening.  I won't post the pictures here out of respect for his privacy, but I can say that he's doing well and his car can go very fast.

The time during which I visited Jen-Hsun's house crystallized my impression of the valley.  After we were done enjoying the hospitality of someone who's net worth was hundreds of millions of dollars the bus took us back to NVIDIA.  I then got on my bicycle and biked home in the dark to the place I was staying.  I slept on a bunk bed in a room with 5 other people, in a house that had more people than I could count.  The owner of the property also lived there, and he slept on the couch so the extra bed could be rented out for increased cash flow.  One of the individuals who lived there was an entrepreneur from Spain.  He usually wasn't there because he worked 14 hour days.  He didn't even come home a couple times.  He talked about the deals he was making worth hundreds of thousands of dollars, and he still slept on the bunk bed across from me.  There was also a Japanese girl who was doing immigration research for the Japanese Government, and a variety of similarly ambitious people.  I was invited to a Chinese food outing once, and by chance found out that the person sitting next to me had founded  This was a truly inspiring place full of people willing to invest all their energy into making it big, and many of them actually do.

San Francisco

It doesn't seem like a good idea to build houses like this in a major earthquake zone.

I would be afraid my car would flip over.


Of course.

I didn't realize it at the time, but this guy is legit.

Caltrain station.

The free market at work.

Moffett Federal Airfield

Hangar One

Alcatraz Federal Penitentiary

Work-Term #5 Amazon Inc.

At Amazon I worked on an AWS product called Redshift during the period when it first launched.  Amazon was the first company I worked for that, I felt, had scalable software development practices.  It was my first experience working with such a large and complex distributed system.

During this term, I worked on internal tools that were used by the ops team to perform maintenance more quickly and safely.  I actually coded up some solutions that were from interview questions I had received in the past.

The view from my apartment in downtown Seattle.  I was very happy that I didn't have to bike to work this time.

Taken from Victor Steinbrueck Park

View of work from the apartment.

View of the apartment from work.

CS452 - Real Time Programming

CS452 - Real Time Programming, is a course unlike any other.   Attending lectures is completely optional.  There is absolutely no content to study for, and the final exam is 26.5 hours long.  It is also my favourite course.  During the first lecture, the professor declared: "You're all here because you're a little bit weird, and I'm a little bit weird too."  After one week, half of the class had dropped the course.

In the words of some people, CS452 has a reputation of being the 'hardest course at Waterloo'.  It belongs to a group of advanced technical electives known informally as 'the big three' that are infamous for being so time consuming.  The QNX operating system traces its roots back to this course.

The entire course centers around a project where each group of two students build a real-time OS kernel from scratch with no debugger, and no starter code other than a busy-wait printf function and a boot loader.  It is standard to not use memory protection because it takes too much time to configure.  The kernel runs a set of user tasks that operate a model train set in response to real-time information derived from sensors on the track.  The communication with the train set runs at 2400 baud so it takes about 61 milliseconds to ask all of the sensors for data about the train's possible location.  This makes it particularly challenging because a train can move about 3 centimeters in that time.  A successful project needs to be able to ask where a train is and successfully flip track switches before the train moves over them or collides with another train.

The first thing I did was write an assert function.  When I was a kid, I used to watch Shining Time Station, so I made the assertion failures as obvious as possible by printing and ASCII-art representation of Thomas the Tank Engine.

The trains tend to speed up and slow down depending on how warm they are, and how polished the track is.

Communication with the train controller must be reverse-engineered from old BASIC code.

Each sensor on the track remembers whether it has been pushed forward or backward since the last time it was polled, but only if it's not broken.

The switches on the track must be separately activated and de-activated in two different commands.  If you turn it off in less than 150 milliseconds you won't actually move the switch because the solenoid needs power for some time before it actually moves (I believe this is due to power factor). If you turn it off after 500 milliseconds you risk physically damaging the hardware by burning out the solenoid.  It is routine for many of the switches and sensors to be broken, and your project is expected to handle this smoothly.

I found it difficult to attend all of my classes.

In this photo I was trying to get preemptive context switching to work when an assertion failure fired in one of the tasks.  At this time I wasn't disabling interrupts on the assertion failure condition so the kernel would context switch out periodically while it was printing the message for the assertion failure.  I had put a debug message of "iii" in the interrupt handler, and the result was some very esoteric humor.

Our UI which showed the state of all sensors and switches.  Many of the sensors would stick on, which would cause the model to think the train was in a completely different place on the track.  This would typically cause the trains to crash.

The cross-compiled code is downloaded to a TS-7200 board attached to a peripheral on the main computers in the lab.  Every student in the course becomes very familiar with this button.

Work-Term #6 Amazon Inc. (2nd)

I returned to Amazon to work on Redshift again.  I had originally decided to intern at a different company for each term, but the product was interesting enough to come back to.

This term I took over a partially-complete project and drove it to production for customers to use.  The project was event notifications for Redshift.

My new apartment.  No direct view of work, but still pretty close.

The view from my huge living room windows overlooked a community center that homeless people slept behind sometimes.  It was a strange juxtaposition given the fact that my corporate housing provided more than what I needed, and gave me a comfortable 7th floor view of people who had nothing.

Sunrise from my apartment.

Sunset from the office.

I was able to get a blurry photo of Jeff Bezos.

Deionized electrolyte water.

Veni Vidi Vici

Final Grades

I never failed a class, but I came close a few times.  I also ended up doing an extra course in my last term due to some graduation requirements that, I would argue, were not clear enough.

Grades Ordered by Mark

96SE 490Design Project 1
90SE 390Design Project Planning
90SE 491Design Project 2
88SE 101Introduction to Methods of Software Engineering
88SE 464Software Design and Architectures
84ECE 455Embedded Software
83MATH 119Calculus 2 for Engineering
83SE 350Operating Systems
83STV 205Cybernetics and Society
82CS 137Programming Principles
81MATH 115Linear Algebra for Engineering
81CS 348Introduction to Database Management
80CS 458Computer Security and Privacy
78CS 138Functional Programming and Data Abstraction
77PHIL 145Critical Thinking
77SOC 101Introduction to Sociology
76MATH 117Calculus 1 for Engineering
76PSYCH 101Introductory Psychology
76ENGL 210FGenres of Business Communication
76CS 445Software Requirements
76CS 454Distributed Systems
75MSCI 261Engineering Economics: Financial Management for Engineers
75CS 246Object-Oriented Software Development
75CS 240Data Structures and Data Management
75SE 465Software Testing and Quality Assurance
74MATH 135Algebra for Honours Mathematics
73ECE 358Computer Networks
73CS 452Real-time Programming
72CHE 102Chemistry for Engineers
71ECE 126Introduction to Electrostatics, Magnetism and Electronics
69SE 380Introduction to Feedback Control
65ECE 222Digital Computers
65BIOL 130Introductory Cell Biology
65CS 349User Interfaces
61CS 241Foundations of Sequential Programs
60MATH 213Advanced Mathematics for Software Engineers
60CS 343Concurrent and Parallel Programming
60CS 341Algorithms
59BIOL 140Fundamentals of Microbiology
58SE 141Digital Circuits and Systems
56BIOL 273Principles of Human Physiology 1
55PHYS 115Mechanics
53STAT 206Statistics for Software Engineering
53MATH 239Introduction to Combinatorics
52SE 212Logic and Computation

To be completely honest, some of the marks seemed completely random.  I would often expect a mark that was +/- 20% in the wrong direction.  For example, in ECE 455 I got my 6th highest mark of university.  I thought I was going to fail the course because I skipped most of the classes to get eye surgery or to attend one of my other courses that was scheduled at the same time.  In CS 343, my 8th lowest mark, we worked with a language called micro C++.  I found a bug with the compiler that resulted in a segmentation fault on a certain rare race condition.  I was even able to create a test case that would trigger the fault in under a couple seconds (I think it wasn't synchronizing the exit of threads correctly).  I showed the prof and he confirmed that it was definitely a bug in micro C++, and that he wasn't going to fix it.

Distribution of Marks


I don't know how many job interviews I've done, but I put it around 50-80.  I did Jobmine 5 times, and I had 24 interviews one term.  Doing all these interviews was stressful, especially since they happen during midterm week, but it really boosted my confidence at interviewing for jobs.  It also made me good at interview questions, since the same ones generally start appearing over and over.

It also gave me an opinion on how to interview a job candidate well, and what kind of questions you should or should not ask.  This is an endlessly debated topic, but I really feel one place where interviewers get it wrong is on asking people to write code.  It is extremely rare for a software developer to write code that gets contributed toward the end product.  If all software developers did was write code, then modern windows could be written by 1,000 developers in about about four months[1]. Instead, Microsoft has 43,629 engineers[2] and no shortage of work for them.  What software developers spend most of their time doing is typically 1) communicating and 2) re-writing code that doesn't work.  This re-writing typically occurs because of inadequate or improper communication related to the requirements, but can also be caused by errors introduced due to lack of CS fundamentals or simple mistakes.

I will start by discussing how the interview process seems to focus on the errors introduced by a lack of CS fundamentals and make some claims:

Claim 1:  If you want sustainable software you shouldn't hire people who can write code, you should hire people who can debug code.

There are several reasons why I feel this claim is justified:

Claim 2:  If you only want throw-away software fast, then you can just hire people who write code.

There is another side of the argument that is more sympathetic to the business needs of programming, instead of the more academic desire for perfection:

Claim 3:  If you want the best of both worlds, then create teams where some members write almost perfect code the first time, and some members can debug code fast regardless of how perfect their first solution is.

I believe the best approach, especially if you run a large organization, would be a hybrid one:  Hire some people who are really good at quickly writing code that is mostly correct, and some people who are really good at quickly debugging code.  If you put these people on the same team, you get the best of both worlds.  By virtue of their differing views on how to best solve problems, it may be difficult for these individuals to see the perspective of the other, so good inter-personal skills will be especially important.

In the extreme case if there is no cross-pollination between these two intellectual types, you'll either end up with software that is unnecessarily late and higher quality than necessary, or software that looks perfect now but causes a slow accumulation of technical debt.  The latter case is a less obvious and more severe problem since the effect is disconnected temporally from the cause.  I believe this is why there is traditionally so much emphasis on being able to write code fast in interviews.

 When I was in California, I met an engineer who described a dichotomy that has stuck with me.  He said that the way a stereotypical mathematician learns to program is take a book on programming, read the entire thing, then write their program without looking back at the book.  The way an engineer learns to program is by taking the book, throwing it in the garbage, then taking something they know already works and slowly tinkering with it until it becomes the program they want.  Although the label engineering/mathematician isn't really relevant here, I do feel that this idea is relevant for defining two ends of a spectrum for describing how people solve problems.  Some people algebraically arrive at a solution that is almost perfect, but if they're wrong they find it difficult to orient themselves in the direction of improvement.  Other people use something closer to fixed-point iteration, continually using feedback to clumsily get closer to the right answer.  If you'll stick with me on these extremely lose associations, you might enjoy reading about the idea of how analysts and algebraists eat their corn.  You'll probably notice that of the two algorithms for solving problems I just described, one is from analysis, and one is from algebra.


Finally, one of the attributes of a potential employee that I think is the most overlooked is their ability to communicate and interact with others.  For at least a few of my interviews, I would walk in, and the interviewer would say "OK, let's get right to it. So we've got a binary search tree...".  No "Hi, how are you?" or any kind of small talk at all.  I don't think it makes sense to spend a lot of time asking someone how their day was, but if you hire this person they're probably going to be giving presentations, conducting meetings or talking to customers etc.  Two or three minutes of well-targeted small talk questions also give you a great idea of the kind of habits this person has.  Do you have any side projects you're working on?  Do you enjoy what you're studying?

Some people have personalities that are particularly poisonous to your organization.  People who consistently talk down to co-workers, or try to call out the inferiority of work that other people have done to assert themselves on higher ground are among these types. An email stating "Hey, can you stop breaking the build?  You're putting us way behind. Thanks." is sure to contribute less to group productivity than "Hi, I noticed the build <link to build> is red, and the last commit is related to XYZ you worked on.  Can you help me fix it? Thanks,Firstname Lastname".  If you match one of these poisonous people with a reasonable person, work will still get done, but you're going to damage employee loyalty.  If you put two poisonous people together, you might even end up getting negative work done as they will continually battle it out for the higher ground by purposely not communicating so the other person will screw up.  And they will, and it will always be the fault of the other person so nobody will improve.

In an interview, there is a clear social hierarchy.  The interviewer is at the top, and the interviewee is at the bottom.  If you want to give the person a chance to show that they might be poisonous for your organization, you could think about disrupting that hierarchy.  Instead of sitting across a table from, side beside them and work with them.  After all, this is the way its going to be when they come work for you, isn't it?  They'll spend a huge amount of time communicating with team members to solve problems, not solving problems by themselves while others watch.  If you're working with an interviewee to solve a problem, and you say something stupid, does the interviewee try to make you feel bad about it?  If they do that to an interviewer, they'll probably be even worse to people on their team.


On the day of my last exam I had $5,039.22 in the bank.  I have no debt and I'm waiting on an income tax refund from the government.  In the early days I borrowed a few thousand dollars from my parents, but I was able to pay for almost all of my tuition with my own money from co-ops.  This is a huge deal because my understanding is that people at other universities end up with $100,000 in debt after they graduate.  Before I started university I didn't really realize how big of a difference the co-op program would make.  Having no debt is really awesome!

I've spoken highly of my experiences in many aspects, but it's not all fun and games.  The social experience at UW isn't exactly the greatest.  Partially, this is my own fault since many people are able to manage the high work load and having a social life at the same time, but I'm not able to do this.  Ever since second year I started focusing more on school because I didn't want to fail a term and set myself back.  Since the work load is high enough that its never possible to 'finish' your assignments, I ended up working on school pretty much all the time.  I was never able to determine exactly how much effort was necessary to 'just get by', and with the threat of the guillotine over my head all the time, I spent more and more time on school, until the last term when I ended up with 7 courses.

The fact that it's necessary to move every 4 months is a mixed blessing.  It's great to have so much diversity, but finding a place to live every 4 months can be a pain.  It's also difficult to put roots anywhere and get a good stable social circle going.

Elon Musk commented that he didn't go to Waterloo because there weren't many girls on campus.  I can say that there are girls on campus, but very few of them go to my classes.  In my graduating class there were 5 girls and 78 guys.  In some of my electives there were no girls.  In the work force there were generally less girls than in my classes.  I believe this trend is changing because I've been told that the lower year software engineering classes have a ratio that is closer to 50/50.

The last 5 years have been the most significant of my life.  The experiences I've had due to the co-op program have probably been the most impactful on me.  I've been able to realize that the world is so much bigger than I thought before.  I have also had the opportunity to be influenced by so many successful entrepreneurs, and great thinkers.  For the first time in my life I was able to meet other people who shared a passion for knowledge as great as mine.  Most of my friends have gone off to work at Google, Amazon, Facebook and all the other big companies.  I really look forward to seeing where they end up.

To be continued...

Sign up for when I write part 2, if you're interested:


Part 2 is now available here.


[1]  The point of the argument is to consider how long it takes to write software if it were just a matter of typing the characters.  I have made the assumption that modern windows is about 100,000,000 lines of code.  If it takes about 20 seconds to write out one line of code (this should be more than enough time for the average line), then with 7 hour work days it's going to take (100,000,000 * 20) / (60*60*7) = 79365 person days to finish.  Thus, with 1,000 developers it would take about 79 days.  The assumption that time taken for work scales linearly with the number of workers is justified since the thesis of this argument states that all developers do is write code, which is a solitary act that is independent of the total number of workers.  With 20 work days per month, that's about 4 months.

[2] Accessed May 12, 2014

[3] If all 100,000 components need to work at the same time, and each of them works 99.99% of the time, then 0.9999^100000 = 0.00004537723 = 0.0045%

[4] Master boot records still use CHS addressing, which doesn't make much sense for SSDs and flash devices.  There is also lots of fancy magic you need to do in order to support large disks or have more than 4 partitions.