

Ask HN: How should I go about learning CS? - oltmans

Hello hackers,<p>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.<p>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)
======
silentbicycle
Speaking as another history undergrad, here's what I've found helpful:

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.)

~~~
deathbob
I also have a history (and now CS) degree. If you want to get into
programming, do some programming. Don't worry about what language or what
project, just grab something and do something.

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!

~~~
silentbicycle
> ...and a lot of the analytic skills you developed in history actually will
> translate pretty well to CS.

You're the first CS person I've _ever_ spoken with who understands that!

------
jsmcgd
What do you want to ultimately achieve? Do you want to become a hacker or do
you want to know about computer science for intellectual gratification? While
these options certainly aren't mutually exclusive, they can however be very
distinct.

If 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 :)

~~~
simplegeek
Thanks, I just want to have a firm grasp of theory and algorithms because I
want to prove I'm not _just_ a tester :) Also, I think I want to improve my
chances of getting hired into a good software company. Because I guess if I
apply to Google then I think they expect me to know decent theory and
algorithms. So two aims a) internal gratification and thirst b) improving my
odds.

Thanks again for writing in.

~~~
tphyahoo
you're probably not going to get hired at google without some kind of degree
in computer science.

maybe you should do a long-distance course in CS.

fern uni hagen has one that I considered.

~~~
atarashi
I don't think thats true. Nostrademons, for example, was just hired there, and
he has a degree in physics. If you can somehow demonstrate competence, even if
its just from self-study, you should be fine.

~~~
tphyahoo
I shoulda said, if you have a B.A. and not a B.S.. (IE, a degree in some kind
of science, rather than a humanity.

The OP was a history major if I recall correctly.

------
gcv
I'm impressed that you chose to approach learning from a theoretical point of
view. It will serve you well; you will understand algorithmic approaches which
stump a lot of people who lack a theoretical background. (Please, no "I never
got a CS degree, but I know what I'm doing" replies --- the HN audience is
more competent than the average in the working world. I'm sick and tired of
working with people with trade-school degrees in programming or "computer
engineering" who do not understand binary search.)

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...](http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-
lectures/)). 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).

~~~
mechanical_fish
A question: Cormen, then Knuth? Or the other way around? Or does it not
matter?

~~~
gcv
I must sheepishly admit that I have not fully read Knuth. I've skimmed parts
of Vol. 1-3 and looked up specific things, but I have not gone through every
proof with a fine-tooth comb. (Far from it.) The book is enormously deep, very
valuable if you follow all the math, insightful. At the same time, it doesn't
cover a whole lot of topics, and with good reason: it isn't complete yet.
Volume 4 has been in production for decades now, and being released piecemeal.
CLRS (Cormen et al.) has less depth, but more breadth. The book covers
introductory graph algorithms in reasonable detail, for example.

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.

------
markessien
I'm a hardware guy, so I've got a different approach. I'd say, drop the
algorithms book. Start with a book called "Structured Computer Organization"
by Andrew Tanenbaum. After you read that book, you'll feel like you actually
KNOW a lot more.

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.

~~~
donw
I second this. Growing up in a family with a continuous lack of money, I was
always having to work with computers that bordered on ancient -- the manual
for my first computer was actually written in Sumerian on a clay tablet.

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.

------
nostrademons
I'm going to repost my e-mail response to you here, in case others are
interested:

    
    
        As a first step, I've bought Discrete Mathematics book and reading it for last two months. 
    
    

Good.

    
    
        What should I move on to once I understand Discrete Maths? Straight to algorithms? How do I approach algorithms? 
    
    

I'd actually start with data structures, but this can be tricky as I don't
know of a really good standard datastructure textbook. We learned mostly from
professor's handouts. We did have a textbook - Data Structures and Algorithms
in Java by Goodrich and Tamassia (<http://ww0.java4.datastructures.net/>) -
but its quality was spotty.

I also learned some from "C++ Components and Algorithms" by Scott Robert Ladd
([http://www.amazon.com/Components-Algorithms-Scott-Robert-
Lad...](http://www.amazon.com/Components-Algorithms-Scott-Robert-
Ladd/dp/1558514082)). 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>

    
    
        I mean should I understand every proof written in Cormen's book? I'm confused as to how should I approach this.
    
    

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.

    
    
        What other math books should I be reading? 
    
    

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.

~~~
simplegeek
Thanks, Jonathan. I really appreciate your reply.

~~~
azanar
Being a mathematics major as well as CS, can offer a recommendation of a book
for each of set theory and mathematical logic. Each were the basis for the
course I took on the topic, and recieved pretty good reviews on Amazon:

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. :-)

~~~
nostrademons
The Enderton book was what we used for my Mathematical Logic course, and it
was pretty good. Thin, but a pretty clear and (apparently) comprehensive
presentation.

------
yan
CS is a gigantic field and if you start midnlessly wandering around, you're
surely to be overwhelmed with how much stuff exists. I have a MS in CS and I
still feel like a majority of topics are way over my head. I find that I have
to spend a bulk of my time for some period on very specific things to feel
like I got a grasp on them.

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.

~~~
simplegeek
Good comment. Basically, my aim is to learn as much math and theory as
possible. Also, to eventually become a rock star web programmer and a compiler
writer(I want to write fun little computer languages one day).

~~~
tphyahoo
If you want to be a web programmer, start building web apps.

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.

------
gills
My opinion might stray a little bit from some of the answers here. I don't
think a CS education is complete without an understanding of how the whole
stack works.

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.

------
speek
Learn Scheme -> Read/watch SICP. Work your way up to algorithms. Build stuff.

~~~
apgwoz
I think the key here is "build stuff." Do all the excercises in SICP, and see
about doing the projects that are listed in the Open CourseWare for the
course. (I think one of them is a web-spider.)

------
bprater
Who do companies want to hire?

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.

------
nihilocrat
Write some code. It sounds like you are reading a little too much about math.
Not all CS is math, otherwise we would all just be math majors.

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.

------
sireat
www.catonmat.com is a CS themed blog that gets posted here from time to time
and is quite educational. The writer is a physics BS who self taught enough CS
to get through all the interviews at Google(but was not hired at the end).

------
axod
Pick a goal first:

"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.

------
ig1
New Turing Omnibus - it's pretty much the best overview of CS theory for non-
CS people.

------
jwesley
Keep posting threads here asking for tips.

~~~
nostrademons
I think this is actually a bad idea, because tips themselves will never give
you the fundamentals you need to be a good programmer. It's like asking for a
steady stream of fish instead of going out, buying a fishing rod, and getting
some fishing lessons.

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.

------
Rod
IMHO, you don't need to know much theory to do testing. Programming is not a
science, it's more of an art. Artisans don't need PhD's in Discrete Math to
get their job done. Instead, they need passion, perseverance and tenacity.
It's good that you want to learn about theory, but reading books is not
enough... you have to code too.

~~~
newsycaccount
He didn't ask to learn programming, he asked to learn CS. He isn't getting a
PhD in discrete math, he is reading a discrete math book, which is a bare
minimum for learning CS.

~~~
Rod
You are right and I stand corrected. I was somewhat puzzled that someone who
has no technical background actually wanted to learn CS. That is unusual.
Often people want to learn how to program and call it "CS", though CS has
little to do with writing code. Thanks for correcting me.

