This past week I finished the last few assignments for Stanford's free introductory course to computer science and software engineering, CS106A, which is offered for free here. My solutions to each of the assignments can also be found on GitHub here.
All in all, the courses are quite different in the content of their teachings. CS106A uses Java to introduce principles of software engineering and object-oriented design, and really drills into your head principles like information hiding, abstraction, top-down design, and stepwise refinement. Harvard's course, on the other hand, uses C, a low-level procedural language that is arguably much harder to grasp due to needing to understand the inner workings of pointers, memory management and the like. CS50X delves into low-level computer science concepts in much greater depth, including data structures such as hashmaps, binary trees, linked lists, and tries. It also goes into in-depth discussions of searching and sorting algorithms such as linear search, binary search, merge sort, selection sort, etc. and how to determine the algorithmic complexity of each of these techniques. It also delves into cryptography, the inner workings of compiling from source code, and web development, among many other topics.
After taking both, I have to say that Harvard's was considerably harder (only 0.9% of all registrants ended up finishing the course, which is 1,300 out of 150,000+), although maybe that perception is due to it being my first computer science course. In any case, CS106A certainly has a different overarching theme and offers its own benefits, especially if you are looking for a solid grounding in object-oriented design.
I hope what I learned will be useful when I start taking Berkeley's CS169.1X Software as a Service, which teaches software engineering in the context of Ruby, Rails, TDD and BDD. I'll probably start that this weekend.