The moment I realized I needed a CS Degree

A little more than two years ago, I was in London, UK and had just finished a 12-week hacker school. Rather than looking for a dev job during the course’s demo/graduation day (as is the norm at a hacker school), I was getting ready to move across the Atlantic to Vancouver, Canada to begin my Bachelor of Computer Science degree at the University of British Columbia. Here’s the story of when I realized a hacker school really wasn’t enough to get me where I wanted to go.

The story

It must have been something like Week 8 of the hacker school when I started thinking about applying for jobs and what my options would be at the end of it. I remember checking out a bunch of companies that used Rails in London and looking up sample interview questions on the careers section of their websites and Glassdoor. There were quite a few smaller independent firms that seemed open to hiring a hacker school grad, and their questions didn’t seem so bad.

At that point, I had just started to get comfortable with Sinatra and Rails and had probably built my first couple of web apps – a classifieds website for university students and a lowest unique auction site. And, as you do when you’ve just started to get the hang of a new field, I was thinking that I was getting pretty good – they call that the Dunning-Kruger Effect. I remember thinking that if things had worked out, I could have built a Facebook, I mean how hard could it be (building a scalable, secure and efficient system is hard as it turns out, and that’s ignoring the user acquisition and growth side of things).

But being the sensible person I am – I’m trying not to cringe as I write this post – I figured I should probably work there first. You know, get an idea of the finer points. Besides, I’d heard great things about the company from people who worked there. I’d even visited the office once before (the one at Page Mill Road I think) and it was pretty cool (free drinks, open plan office, Herman Miller chairs). So I checked out the careers section of their website and started trying to solve a sample engineering problem – back then Facebook had engineering challenges that you could solve to get contacted by a recruiter.

The sample challenge was to write a solution to the Tower of Hanoi.

Diagram of the Tower of Hanoi

Tower of Hanoi

As per Wikipedia, the objective of the puzzle is to move the entire stack of disks from one rod to another while obeying these rules

  1. Only one disk can be moved at a time.
  2. Each move consists of taking the upper disk from one of the stacks and placing it on top of another stack i.e. a disk can only be moved if it is the uppermost disk on a stack.
  3. No disk may be placed on top of a smaller disk.

If I remember correctly, the aim of the puzzle was to generate a sequence of moves which solved the problem.

Come again?

Yep, I had no idea where to even begin – and this was the sample challenge. The one that was meant to give you an idea of how to handle input and output, rather than being representative of the difficulty of challenges since the real ones are always a lot harder than the illustrative examples.

I remember doing some research on the Tower of Hanoi and discovering that it had to do with something called recursion – I only had a vague idea of what that was at the time. Most importantly though, I found out that this was a well-known problem taught in pretty much all CS degrees as part of their introduction to algorithms and data structures.

The more I read about the topic, the more I realized I didn’t know. My brief moment of (over)confidence in my abilities quickly evaporated and I figured out that knowing how to build a web application in something like Rails is not the same as being a Software Engineer – that building an MVP of a social network site is not the same as engineering one. The former can be done by following Michael Hartl’s famous Rails tutorial, while the latter requires knowledge of computer science and algorithms, hardware, growth, marketing, data science, etc, if the app is to stand any chance of success.

Doing the hacker school was great for figuring out that coding for 8, 9, 10, 11, 12 hours a day was something I really enjoyed, but most importantly, for learning how much more I still had to learn if I wanted to tackle really complex problems with code.

And so I looked around for CS degrees that took students with a previous degree. There were a couple of Master’s programs in the UK which seemed ok but a bit too short; most of them were only one year in duration and I didn’t think that was enough time to get a really thorough understanding of fundamental CS theories, plus they didn’t seem to have the top-tier tech companies recruiting from there.

The top CS schools in the US on the other hand, generally didn’t offer second degree programs. Some, like Stanford, didn’t admit students for second Bachelor’s degrees at all, while others like Waterloo required students to start from scratch and do a 4 year program.

And then I found out about the Bachelor of Computer Science (BCS) program at the University of British Columbia in Vancouver. It checked all the right boxes. It was shorter than a regular CS degree but not that short (advertised as 2 years, but 2.5-3 years in practice) and had good links to American tech companies (Facebook, Google, Amazon and Microsoft recruited its students) and had a decent reputation (something like 30 to 60 in World Rankings if you buy that sort of thing). And before I knew it, I was on a plane to Vancouver, Canada.

And that’s it. That’s how I ended up studying for a CS degree and how I kind of went full-circle this summer interning at Facebook – something I am certain I could not have done with just my experience at a hacker school, not by a long shot. It’s also been a while since I solved the Tower of Hanoi.

Here’s the code I wrote for it during my intro to algorithms class in my first year of my CS program – it’s probably a little rough around the edges but I remember thinking at the time I wrote it and solved the problem, wow, I’m really getting somewhere.

 

#include <iostream>
#include <string>

using namespace std;

void moveDisks(int, string, string, string);

int main(int argc, char* argv[])
{
  if( argc != 2 ) {
    cerr << "Usage: " << argv[0] << " n" << endl;
    return -1;
  }

  int n = atoi(argv[1]);
  moveDisks(n, "A", "B", "C");
  return 0;
}

void moveDisks(int n, string from, string transition, string to)
{
  if(n == 1)
    cout << "Move disk from peg " + from + " to peg " + to << endl;
  else {
    moveDisks(n-1, from, to, transition);
    cout << "Move disk from peg " + from + " to peg " + to << endl;
    moveDisks(n-1, transition, from, to);
  }
}

Ahhh summer school…

And by ahhh, I really mean AH! The first day of summer school started today and I’m already ready for the term to be over. It’s partly due to the insane amount of cover letters I’ve been writing in my applications for internships, but also because lectures during summer school are two and a half hours each. Trying to keep your concentration for such a long amount of time is difficult to say the least. Even so, I’m pretty excited about the two courses I’m taking this term.

 

CPSC 310 – Introduction to Software Engineering 

The prof in my Introduction to Software Engineering class is really charismatic and that’s definitely a help in keeping your attention when you’re trying to separate out your waterfalls from your spirals (these are two types of software processes). On the downside, I, and quite a lot of other people, failed to persuade the prof to let us code the class project in our language of choice. The project for the course involves parsing a publicly available dataset and plotting it in google maps (or equivalent), maintaining a database which users can add and edit records, and integrating social media authentication. Sound simple? I thought so.

Having done quite a bit with Rails, I thought the class project would be a perfect excuse to get better acquainted with some newer, and highly desirable, technologies. Specifically, Node.js. Everyone loves Node these days because it is asynchronous rather than strictly sequential in how to executes code, and this makes for more scalable applications. Node means the server doesn’t have to wait for a particular request to be completed or method to return, it can just go on doing what its doing and accommodate the request as and when it comes in.

Oh Node! (that’s really meant to be Oh no. Get it?)

Unfortunately, the summer term is so short that the prof wasn’t buying what I was selling – it’s a great way to learn new technologies! I’ve done a hacker school! I have a portfolio – at the end of the day, summer classes are a logistical nightmare. Trying to help a hundred or so students get their environments set up, teaching them software processes, and getting them to build a web app in a group without killing each other, is tough. I get that. And so, instead of using Node, we’re all going to have to use …. wait for it….. Java with the Google Web Toolkit.

I hold nothing at all against the professor – she agreed that something like Django or Rails would be infinitely more fun, and of course there’s the irony that Google Web Toolkit just converts Java to JavaScript anyway.. – but the rules are the rules. I’m just happy that we’ve got someone to teach the course this summer! Finding good professors, make that any professor, that can teach software construction is HARD.

Anyway, I still get to learn how Java works on the web – and of course, I can always find time.. somewhere.. to learn Node on my own – and that’s ok. If anything, this is good preparation for the real world where you have to use a specific technology, no matter how inefficient 🙂

 

CPSC 221 – Basic Data Structures and Algorithms

My first lecture in this class was pretty interesting. It was mostly a high level overview of why algorithms are important with a general intro to the concepts of arrays, lists (linked lists), and how a data structure might be good for one thing – e.g. arrays are good for binary searches compared to lists – but not for another – e.g. arrays do not handle insertion well since they are fixed size data structures. I didn’t learn anything brand new today but it was good to get an idea of where the course is heading.

One of the things I really liked was when the prof said that learning algorithms is the difference between you and some kid in high school who knows how to hack in python. To take it further, I guess knowing how to get an array sorted (my_array.sort) is not the same as being able to sort an array (i.e. understanding the algorithms behind Quicksort and Merge Sort).

Who cares? An example: ArrayList vs Lists

Choosing the wrong data structure can be catastrophic. The example we heard in class today was of an ArrayList and why you wouldn’t use it in a mission critical and time sensitive environment. An ArrayList may be a foreign concept to you if you’ve only ever coded in a language like Ruby. In Ruby, there is no need to declare a specific size for your arrays (although you can, and then those values can be set to a default), they just resize themselves automatically as things are inserted/deleted from them (the exact implementation of how this is done, in C which underpins Ruby, is pretty complicated so let’s leave it at that – I may need to come back and come up with a better example). This means that what are called arrays in Ruby are really ArrayLists in a language such as Java, i.e. self-resizing arrays. Don’t forget, arrays in the traditional sense are of fixed size.

Back to our example, we wouldn’t want to use an ArrayList in a mission critical system because resizing the underlying array of an ArrayList takes time. Time you don’t have. Can you imagine if you had a really badly implemented ArrayList, and it had 1 million elements in it and the underlying array (of size 1 million) was full, and you inserted a new element into it? Well, then you’d expect the array underlying your ArrayList to double, and now you’ve used up lots of time in copy elements from your old, smaller array, to your new bigger array, just so you can insert a single new element. Oh, and you’ve also used up lots of memory in the process. Guess what? Your mission critical system, let’s say a rocket ship, didn’t have that memory available for you to use. It crashed.

Or maybe the memory was available but in the time it took to resize the array, the rocket’s reverse thrusters were fired too slowly. Guess what? It crashed.

I am psyched for this class. Not least because it’s going to be needed to get through a lot of the interview questions that get thrown at undergrad CS students applying to internships. And who doesn’t like solving complex problems!

One other thing, we need to do the labs for this class in C++ and seeing as most of us don’t know C++ and neither are they going to teach it in class, I’d better go learn C++. This feels like the real world already.

Why algorithms matter

Look at any computer science program in the country (whatever country) and you’ll find an algorithms class or two making up part of the core curriculum. There’s a big difference between being able to write code which solves problems and being able to write code which solve problems efficiently, i.e. code which scales to solve large problems sets. And in a nutshell, that’s what the study of algorithms is about.

An example

Put these three numbers in ascending order:

3, 1, 2

Pretty easy right. Computers, schcomputers. Who needs them.

Now try putting these numbers in ascending order:

13, 3, 7, 31, 16, 2, 7, 3, 5, 6

A little harder, I’m sure, but still doable by hand with a bit of time.

What if instead of 10 numbers,  I give  you 100 or 1000 numbers, heck, while we’re at it, let try a billion numbers.And that’s exactly the sort of domain which the study of algorithms takes place in. The theory of being able to solve problems in a scalable fashion. Anyone can sort 3 numbers, but to solve a billion numbers take more than a little magic. But let’s back up for a second,

What is an algorithm anyway?

An algorithm is a series of steps or procedures which are applied to solve a problem, normally involving some degree of repetition.

The difference between an algorithm and a good/efficient algorithm

Just like with most things, there are algorithms and then there are algorithms. Studying algorithms is not just about figuring out an approach that will solve a problem eventually. After all, given enough money and time, most things are accomplishable

Going back to our number sorting example, an inefficient sorting algorithm (e.g. insertion sort) on a typical laptop might be able to sort a billion numbers in  300 years (give or take a few!). In the meantime, an efficient sorting algorithm like merge sort would take just 18 minutes. Pretty crazy right.

But enough with the numbers,

Why does this matter to you?

if you’re a web developer:

It means that you can understand what goes on behind the scenes of the built-in commands which come with languages like Python and Ruby (think .sort). Algorithms also help you understand why that solution you wrote to iterate and compare records in a database is completely time infeasible as soon as you have more than 100 records, and helps you figure out what to do about it.

if you’re looking for a job: 

The big tech companies LOVE asking algorithms questions during interviews. While knowing every command of a programming language is impressive, no doubt, being able to understand what’s going on is even more so. Having a good grasp of algorithms demonstrates your ability to think logically and sometimes creatively, and also fits in well with what bit tech companies are about – providing solutions/products to hundreds of millions, maybe billions of people.

if you’re just starting to get your feet wet in this little code world of ours:

Who doesn’t love a good sudoku? When you’re first learning to code, it’s about getting something, anything, that works – no matter how badly designed or inefficient. Your learning is mostly to do with remembering syntax and learning the fundamental constructs of programming languages like iteration and classes. Once you’ve gotten your feet wet and gotten to grips with these concepts, algorithms presents a way for you to apply what you’ve learned to solve some pretty crazy problems. Would it surprise you to learn that the efficient sorting algorithm I mentioned earlier, merge sort, is nothing more than a bit of recursion and for loops? Pretty crazy. It’s like learning the names and functions of every tool in a toolbox, and then being shown a car that someone just built with the exact same equipment.


For me, I’m about to start applying and interviewing for co-op jobs (similar to internships) as part of my computer science program at UBC, and I’m trying to learn as much as I can about algorithms. I only really get started learning about them formally  this summer when I take my first algorithms class, but what I’ve seen so far is pretty exciting. Being able to write programs which make non-hand-solvable problems solvable is what coding and computers are about. If you’re familiar with Python or are happy to start picking it up, the free ebook Problem Solving with Algorithms and Data Structures is a decent (albeit not the most academically rigorous) place to start.