Ask HN: How should I go about learning CS?
My undergraduate is in History, however, I've been working as a Tester(also some technical writing) for last 4 months in a startup based in Europe. I've to admit that I don't have very strong CS fundamentals i.e. theory. How do you recommend I go about it? As a first step, I've bought Discrete Mathematics book and reading it for last two months. What should I move on to next once I understand little bit of Discrete Maths? Straight to algorithms? How do I approach algorithms? I mean should I understand every proof written in Cormen's book? I'm confused as to how should I approach this.
What other math books should I be reading? Any help will be appreciated. I know there are some very good self-taught hackers in here. Also, some very good and highly educated CS hackers lurk here. So any help is highly appreciated as right now my condition is like a fish without water. (note that, going to school isn't an option right now)
40 comments
[ 31.1 ms ] story [ 404 ms ] threadIf you want to be a productive programmer there is no substitution for programming experience. In the same way knowing a lot of music theory won't make you a great concert pianist without years of practice.
Computer science theory will allow you to attempt some problems beyond the reach of intuition. However a great deal has been achieved by people just having a go.
I don't think there is any one answer. There is no definitive example of a computer scientist or hacker. I'd recommend just getting stuck in. Try many different things. Find out what interests you and then read the relevant books. You'll go farthest if you're doing something you enjoy not by adhering to some consensus from a disparate bunch of usually jaded hackers :)
Thanks again for writing in.
maybe you should do a long-distance course in CS.
fern uni hagen has one that I considered.
The OP was a history major if I recall correctly.
You can tick-talk all day long, but I want guys that have the guts to get serious and the guts to get it done. Theory doesn't pay the bills, shipping code does.
You shouldn't wait to find a company to start your education on churning out great code, you need to start now, today -- go find an open-source project and dive in.
Every hacker here will tell you the same thing: You can read about having sex all day long, but when the lights are out and you are in the sack with a pretty lady -- experience is what counts.
http://mitpress.mit.edu/sicp/
I think you have to first figure out what you're goals from this are. Do you want to write a web app? Do you want to write an operating system? Some people approach the problem from the latter goal and are very quickly dismayed by its depth. If you want to write something more simple, you can start at tutorials of just languages, and then work up from there. HN is usually a good barometer of interesting CS topics.
In terms of just pure CS fundamentals, I think looking at the freshman curriculum of a reputable school should be a good start. The danger with diving into CS from the theoretical side though, is being dismayed at the little perceived relevance of CS theory to actually writing code. A good plan to prevent losing interest is learn with micro-projects that can be completed in a short amount of time. Having small rewards regularly can help you stay on track.
The obvious thing is to get good at ruby.
But I would say, have a look at haskell, and happstutorial.com.
hanging out in haskell cafe, a certain amount of CS is likely to just rub off on you.
To start, you should read SICP (http://mitpress.mit.edu/sicp/) and watch the lectures (http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussma...). You should probably do this before diving deeper into discrete math, algorithms, or theory of computation. SICP is almost completely unique in that it touches on all these topics, and puts them in the context of actual programming. It also happens to include solving fun problems along the way.
After that, you'll be well-prepared to have a ball in all aspects of CS. You can get more into pure hacking by learning languages (after Scheme, I recommend C, Python, Common Lisp, Haskell, and Prolog before jumping into more unexplored directions like Scala and Clojure), and following up by studying compilers and operating systems. You can get into a more job-oriented path by learning Java and C#. You can get into more algorithms by reading Cormen et al. and, of course, Knuth. You can get into pure theory by reading Sipser (wonderful, wonderful book).
As a side note, Knuth presents examples using a synthetic machine language. Don't get me wrong: this is actually extremely cool, but you end up jumping between thinking about registers and then thinking about very high-level math. This shouldn't throw you off very much, but it makes me think that it shouldn't be the first or only algorithms text. CLRS, on the other hand, uses pretty dense pseudocode, lots of mutable state, and bad variable names. The longer algorithms can be hard to follow. I know that a 3rd edition will come out in a couple of years, maybe it'll fix that. Not sure.
Speaking for myself, I'm not sure I could plough through either Knuth or CLRS, from first to last page. I read books like that by reading introductions and then skipping around. By the time you get that far, you'll know what interests you and where you need to pick up knowledge. Certainly once you have dynamic programming techniques under your belt, you'll know enough to guide your own explorations.
And after you read that book, you'll probably know a lot more than half the people here about how computers really work.
To compare the approaches:
- After you read Cormens book, you may be able to prove that quicksort is faster than bubblesort.
- After you read Tanenbaums book, you will know where the arguments are stored in memory when you call a function with multiple arguments.
Everybody has to decide which is more important for him to know, I know which was more interesting for me.
Having to actually learn to work with the system at a base level will be incredibly useful once you start to pick up more advanced concepts, and I imagine that the history of computing might be a topic in which you can find interest as well.
People keep mentioning the Wizard book (SICP). It sounds like it would be perfect for you. I think it veers too much on the side of theory for most people, but it sounds like you have no trouble with that.
So work through the Scheme lessons in SICP or HTDP, it's a fun and playful language! You can easily build interesting algorithms and watch them in action to get a better feel for how computation behaves. You will also be introduced to FP which will help you in the long run as a dev.
From there I like to think of two directions you could explore.
Down => compilers, OS design, processor/memory/machine architecture, networks, circuits, physics.
Up => automatons, language theory, complexity, ways to mitigate complexity (approximation, optimization, AI).
Sideways => the wide world of application programming.
It depends on what tickles you...but in my opinion a basic understanding across the spectrum will provide you with the framework to explore more specific areas without feeling lost.
Read HTDP (http://htdp.org/), SICP (http://mitpress.mit.edu/sicp/), and/or CTM (http://www.info.ucl.ac.be/~pvr/book.html), and do most of the exercises. They're all huge books, but getting even halfway into any of them will cover a tremendous amount of material. Also, they focus on largely complementary material, and each may help clarify concepts you find puzzling in the others. Also, HTDP is probably the most approachable of the three. (The first two are available online, the third has a draft PDF floating around. There's something to be said for a hardcover on your desk, though.)
Also, find something you're seriously interested in and program for it. With an undergrad in history, you have quite a few niches to draw upon that most CS grads don't. (Python is one reasonable language for this. People will debate this endlessly, though; picking something and actually doing it is more important than getting bogged down in worrying about language differences, for your purposes. Having libraries relevant to your niche is also important.)
You will almost certainly need to learn C somewhere along the line; it's a good candidate for the lingua franca of algorithms. _The C Programming Language, 2nd ed._ by Kernighan & Ritchie is the book, and for good reason. Learning C will also get you intimately acquainted with many mistakes people frequently make, which will help hone your testing / debugging. (This is the upside of C making it easy to shoot yourself in the foot, I suppose.)
For math and algorithms, take your language(s) and dive in at Project Euler ( http://projecteuler.net/ ), a series of math puzzles. Have fun with it, and dig deeper into any questions you don't understand or can't code a reasonably efficient solution for. The algorithmic insights will come when you read other peoples' solutions that solve the problem 1000x faster. :) Also, comparing both idiomatically similar and fundamentally different solutions to the same problem across several languages can teach you quite a bit.
For data structures (which you didn't explicitly mention, but will need along with algorithms), I found learning OCaml (via http://caml.inria.fr/pub/docs/oreilly-book/ ) most helpful. ML is an excellent language family for expressing complex data structures, and a little experience with it will probably make thinking about them clearer, regardless of what language you're working in. (Other people will probably have better book recommendations, though.)
That said, I found http://www.processing.org/ to be very useful in my transition. Nothing like a little visual feedback to keep the motivation high :) Clean syntax, great documentation, active community. Fantastic starter language, a great way to dip your toe in the pool and see if you really want to do programming before you buy a bunch of expensive books. Attempting to use one of the more masochistic languages (c/c++/java) can break your spirit before you even get going.
I expect you'll pick up discrete math pretty easy, and a lot of the analytic skills you developed in history actually will translate pretty well to CS.
I wish I had more time to reply but I have to run, final 2 tips, install linux and write a compiler. Have fun and good luck!
You're the first CS person I've ever spoken with who understands that!
"I want to write an operating system"
"I want to write a video game"
"I want to write a raytracer"
"I want to write new firmware for my TV"
Then do it, learning what you need along the way. Forget "CS", just do it.
In general, I think one should try to understand basic principles first, instead of solving specific problems they have. Nobody here can tell you what you ought to be asking, but intro textbook authors have put a lot of thought into what you need to know and base their books around that.
I also learned some from "C++ Components and Algorithms" by Scott Robert Ladd (http://www.amazon.com/Components-Algorithms-Scott-Robert-Lad...). This is old - it's what I first picked up when I was 15 and playing with MUDs - and a little basic, but it got me started.
Cormen also has a lot on data structures, but the level of presentation is pretty high. It may be easier to combine it with another source.
Also, the C2 Wiki has some great pages on data structures and algorithms: http://c2.com/cgi/wiki?DataStructures
This will take you a long time - I don't understand every proof in Cormen's book, I just go back to them as necessary. I'd start by understanding what's going on under-the-hood when you use standard library datastructures - linked lists, vectors, heaps, trees, hashtables. Once you've got that, go on to understand the variations of these, eg. the half a dozen or so different collision-resolution strategies used in hashing.When you've got that, take a look at some of the more advanced data structures in there, like binomial and fibonacci heaps, skip-lists, B-trees, etc. And somehow make time for graph algorithms, they come in handy.
You should make time for Structure and Interpretation of Computer Programs (http://mitpress.mit.edu/sicp/). Other good theory books: Concepts, Techniques, and Models of Computer Programming by Peter van Roy, and Types and Programming Languages by Benjamin Pierce. As for math - it's good to know some set theory and mathematical logic, but I wasn't a math major so I don't have good recs in that area.Karel Hrbacek and Thomas Jech, Introduction to Set Theory. ISBN-13: 978-0824779153.
Herbert Enderton, A Mathematical Introduction to Logic. ISBN-13: 978-0122384523.
Hope this helps. :-)
They want to hire someone that is amazingly good at something.
Someone that is truly passionate.
Someone that really gets what they are doing.
Many of us are generalists, because we've been doing this gig so long. We've soaked up a myriad of technologies.
But it takes a lifetime of experience, something you don't have time for.
Learning about lots of algorithms may be fun (heck, it is to me!), but it may not be the best use of your time.
Right now, you need maximum leverage, especially in a waning economy.
If you pick a technology that you are having a blast with, you are going to push yourself and your skillset.
Does John Carmack do OS-hacking or web-app-hacking? Nope, he builds great game engines. (Well, that, and something about rockets.) And he's compensated accordingly.
It might seem silly to ditch the books in favor of building your own ray-casting engine (or whatever makes your bells jingle), but
1) you're going to find out if you are truly passionate about going in deep, and
2) you're going to have real-world experience and will be able to have a serious conversation with other engine designers. Quite important in job interviews.
You don't need 100,000 jobs. You only need 1. Decide now what you job you want and start your course in that direction.
Good luck -- exciting times for you friend!
BTW: Math isn't necessary for great hacking. In my line of work, I rarely need that skillset. And when I do, there are libraries.