"One day Alice came to a fork in the road and saw a Cheshire cat in a tree. Which road do I take? she asked. Where do you want to go? was his response.
I don't know, Alice answered. Then, said the cat, it doesn't matter."
A good (non generic) answer to "What should I learn?" (asked by a self educated programmer here) depends on the answer to the question "What (kind of programmer) do you want to be?"
What you miss out on from an undergraduate CS degree is a survey of the field—the original poster already likely has specialized knowledge, but is missing the general knowledge breadth that you get through academic subjects that don't have immediate application to your own work projects. So your question isn't helpful, or rather its answer should be "the kind of programmer who would better be able to answer that question."
I just want to single out the ')' at the end of the post, a classic Cheshire Cat smile where you only see immediately his smile but not his face/eyes (i.e. compare with ":)").
If this is a coincidence and you done it by mistake (i.e. mistakenly have not put a ':') then this is one sweet coincidence. If not, then kudos to you :)
heh I did that deliberately(You can see there is no balancing '(' in the post), but I didn't expect anyone to catch it or even notice it. :-). I was just having some fun.
(For the perplexed) In "Alice In Wonderland" the Cheshire Cat fades away till nothing is left but its grin So I removed the ":-" from ":-)".
Note that the ":-" isn't strictly necessary: both Ambrose Bierce and Vladimir Nabokov, independently reflecting on their desires for the addition of a "typographic equivalent to a smile" before one ever existed in popular culture, proposed a simple "supine round bracket" or "\___/".
In addition, who are you? Do you see yourself as a mechanic (brilliant with tools), a mathematician (brilliant with symbols) or a philosopher (brilliant with ideas)? Give us a clue and those who are like-minded can jump in with what they find useful.
I would suggest learning algorithms and data structures. I know that is suggested a lot, but I did not realize how little I knew until I studied these things. And I think that is part of what makes good programmers stand out as these things apply to all languages.
I then looked at my primary programming language (C++) differently. I wasn't just always using vectors any longer. I knew when to use them and when to use a queue or stack or hash.
In short, studying algorithms and data structures and then applying what I studied in C++ made me a better programmer.
As someone with a CS background who has worked with several very talented self-taught programmers in the past I can echo this. Even if they knew a particular language or environment better than I did, I could usually write faster or more efficient code simply because of my deeper knowledge of data structures.
One in particular comes to mind, I was working a temp job during my 3rd year at college with a very talented friend who was self-taught. He had written a rather brilliant dynamic reporting system for a very large e-commerce site in Perl, allowing the management to interactively drill down into recent sales and inventory activity. It worked fine for a few years until the volume of data became very large. Try as he might he couldn't get the software to be performant any longer and had to resort to a 10-11 hour batch crunch every night with the output dumped out to static HTML files for the mgmt to review. Finally one night, the process failed -- out of memory. Throwing more hardware at it only bought another few days.
A dive into his code (most of which was really quite well done) turned up the following: he was using Perl hashes everywhere to operate on the data because they made the code easy to read and convenient to write and maintain. I rewrote many of the particularly inefficient parts to use arrays over a few weeks and suddenly, the entire batch took 10 minutes to run! A few more tweaks and we turned it off of batch mode and back into full interactive mode. Mgmt never had to wait more than a minute or two to return back a report of a huge amount of data.
The key of course was that he simply didn't understand how much overhead the associative arrays created because he didn't understand the data-structures involved. He had simply relied on the magic of the language to do that work for him. A few days spent with http://blob.perl.org/tpc/1998/Perl_Language_and_Modules/Perl... and he never made that mistake again.
First thing to do is realize that for many (most?) older programmers, this is the norm. Being self-taught in the days before Programming as a major or Comp-Sci for that matter isn't a new thing for the profession. That said, best thing to do is to continue the methods/procedures that got you to where you are. Learn more, read more. There are always other languages to learn and certainly more books to read. There are many lists of 'Best Computer Books for Language Foo' out there as well as 'Best Computer Books in General'--- find them and start at the top, bottom, middle, where ever you want. I tend to divide reading into what I think of as the classics and the practical; the classics are programming texts that apply to all languages, the practical are those that apply to a particular language. When it comes to reading in general, remember Sturgeon's Law--- '90% of everything is crap' this is particularly true for the 'practical' category, so spend time reading in the bookstore before plunking down cash...
Read recent phd theses. They always have a few chapters at the front giving an overview of the state of the art of their subject area, to prove that the candidate knows it. As for subject area, just sample widely - it's impossible to know what will be useful in advance, and in any case it's all exercise for the brain.
This is excellent advice. If you have a hard time following a thesis, look for introductory stuff in the bibliography.
CiteSeer (http://citeseerx.ist.psu.edu/) is an excellent place to find theses, research papers, etc., and it has local PDF / PS caches for many of them. Google Scholar (http://scholar.google.com/) also works, though many results will be behind academic paywalls (e.g. the ACM) - the "all X versions" link will often have alternative links, such as faculty pages, including PDFs / PSs.
Re paywalls: that's why I use also http://academic.research.microsoft.com/. For some papers it has a PDF link on the bottom of the page. As a personal preference, I like it more than Scholar (scholar is more full-text search driven, while academic is more filtered).
I'm surprised Donald Knuth's Art of Computer Programming only got 1 upvote. I've never considered the series a good fit for beginning programmers but for someone with 7 years under their belt who is looking for depth of knowledge I really can't think of a better choice of reading material (Plus there's a nifty box set coming out next year:http://www.amazon.com/Computer-Programming-Volumes-1-4A-Boxe...)
Most people that recommend TAOCP haven't read it; and IMHO it's highly overrated.
I've read parts of volumes 1 and 3. This book is awesome if you have the time to digest it, but you get faster results from other books that are easier to read, like Cormen's Algorithms.
It depends on the results you want to get-- TAOCP and CLRS are completely different creatures.
If you are expecting TAOCP to be an Algorithms textbook, you're going to be severely disappointed.
Personally, I find TAOCP to be highly underrated. I find Knuth to be an utter joy (and just yesterday, greatly enjoyed watching the video of the 16th Annual Christmas Tree lecture.)
CLRS is a great Algorithm textbook, but it's not the place to go to find why there is a Pi in the formula for the approximation of Catalan numbers.
I liken TAOCP to Proust. Fawned over by a small subset of people (rightfully so), a larger subset who talks about it but doesn't actually read it, and shunned by the majority as dense and intimidating.
I'd agree with you on Cormen's Algorithms but the original post already mentioned Algorithms (which could mean one of two texts that are considered standard in the field but both cover about the same territory).
But I'd be interested in knowing what books you refer to as far as giving faster results beyond that(TAOCP is dense which I'll agree makes it a difficult read). I've never found a book that covers the same information as TAOCP and while I hated every second of reading it when I was being forced to do so I have to admit the knowledge has served me well
TAOCP is a reference book. Almost no one reads it cover-to-cover. It's the thing you pull out when you need to do some red-black tree magic that you've long since forgotten.
Personally, I still think K&R is the best CS/programming book I've ever read.
I'd disagree with that only because I (and everyone I've ever spoken to about it who has a CS degree) was forced to read it cover to cover (and for the record I hated it at first). The problem with saying it's a reference book is it isn't really written like a reference book. If you don't understand the context of what he's saying I don't see how it would be usable (especially considering the environment it describes is essentially hypothetical). So while I think it could be used as reference I think you have to have read it to use it in that fashion.
My copy of Knuth is at home and I'm at work, so I can't check -- but does TAOCP actually cover red-black trees? My hazy memory says it doesn't, or if it does it gives them at most a passing mention.
(TAOCP is wonderful but I think the great majority of potential readers would be better served by Cormen/Leiserson/Rivest[/Stein]. But when you really need Knuth, nothing else will do.)
And here is the complete text of what Knuth says about red-black trees.
"Elaboration of these ideas [2-3 trees, and a way of representing them as binary trees -- gjm] has led to many additional flavors of balanced trees, most notably the red-black trees, also called symmetric binary B-trees or half-balanced trees" ... followed by a list of references to places where these other sorts of tree, including red-black trees, are discussed.
So, indeed, you wouldn't turn to Knuth for "red-black tree magic".
Knuth exemplifies the difference between programming and computer science. For programmers, the function it may have once performed (serving as a resource for what is the best algorithm to implement for some rare and complex task) has been surpassed by things like Google, and (ironically?) by Stackoverflow itself.
Maybe I'm just not seeing it but I don't see how anyone could have really used it as a reference for algorithms in the first place. There are much better books for that. Beyond that anyone in their late 30s or younger probably started learning in a managed environment which means a lot of what the books says was never useful in a practical sense (for example unless you already know the algorithms being referred to you aren't going to be able to make heads or tails out of assembly)
What it does do is give you depth of knowledge. It helps you to understand the part of the computer you've never even thought of if Java is the first language you ever learned.
I'm in the same boat (10 years of experience, a good 6 doing serious programming work) with no degree.
However, because I know I will always do web programming I have definitely not focused on issues like compiler design, low level memory management [1], etc because most of the languages I use are either interpreted or compiled to bytecode and thus those areas are irrelevant
I would therefore argue it very much depends on what kind of work you wish to do - sure read some more in depth stuff but if you are doing web programming spending some of that time on product development knowledge, server administration, etc might be more beneficial.
[1] clearly some memory management is important in languages like Java and Objective C but using the built-in alloc/dealloc functionality is not really "low level understanding"
Just to follow up and explain... I'm at the end of my programming career (10 years, I've worked on high profile stuff, I'm done), having migrated away from programming into product development and strategy.
Programming may be completely different in a decade's time but I won't be programming. My era is now and that was always the plan to concentrate on web.
I fully respect the "career programmer" may need to choose differently but for many of us working as an engineer/programmer is simply a step in the journey. To go back to the OP, that's probably why I didn't feel inclined to study CS at university.
Oh. So, er, "I will always do web programming" actually meant "I'm not really going to be doing much of any sort of programming from now on". Fair enough, and that may well be a very wise career decision, but I don't think I can really be faulted for misunderstanding you.
+The Practice of Programming - K&P are prolific authors and deliver the salient points of a BSCS and the transition into practicing programmer. Best bang for your buck.
+Code Complete - A no nonsense approach to Software Engineering and other tasks related to development. The SE texts used in most college courses are far too advanced and abstract for undergrad students that have never worked on very large projects. This one delivers excellent advice for single programmers up through medium size groups.
+Some algorithm and data structure book - there are a lot of bad ones. Use Amazon ratings to try and find a good one. Work through the design of as many algorithms as possible, no matter how mundane or the fact that most practical languages have libraries that deliver this functionality. Know what algorithmic complexity is and memorize the complexities of often used data structures to help quickly choose while coding.
+An operating system design book (e.g. Operating System Concepts or Modern Operating Systems) - know how the OS packages RAM, storage, CPU scheduling, network, concurrency for userland programming.
The thing that struck me about some of the recommended reading on the list was that I suspect some of the books in the highly voted answers are probably not recommended texts on a good CS course (as is the author of the posts wish). I mean it's been a while since I took an undergraduate course but there were very few books recommended that looked at the more practical side of computer programming - apart from maybe in the first year of your course, and I'm assuming the author was looking for more in depth reading. Senior years on many CS courses tend to focus on theory behind topics which is something that I think is probably a lot harder to get motivated to read than say Code Complete. I mean you really have to want/need to learn Edmonds' graph matching algorithm as things like that are not comfortable reading. It's the reason why I think doing a CS course has some benefits as it's not often you are forced to approach the subject in that manner. That said, the accepted answer has probably provided a decent list of books with a more academic slant.
I recommended The Elements of Computing Systems: Building a Modern Computer from First Principleshttp://www1.idc.ac.il/tecs/ It's a great book/course which takes you through all the abstraction layers from chip architecture to OO-programming.
After that, I recommend SICP.
When you are self-taught you easily end up with big holes in your knowledge, because you typically focus on what you need to know in your current project. These two books are great because they cover a lot of ground (different abstraction levels, different paradigms) while still remaining practical.
One thing I found useful as a self-taught programmer was getting outside of the dominant programming paradigms. Though I'd like to disassociate myself with the over-the-top PG fanboyism that sometimes goes on here, I must admit that his lisp books were a great help in breaking out of the imperative and OO worlds, and were a major influence on me at an early stage.
I'm not sure the SICP is for everyone, but that's exactly why I recommend it to self-taught programmers and the occasional "I'm a web jockey but I'd like to learn to be a real programmer" post. If you're excessively steeped in the practical side, it focuses like a laser beam on the bits of education you've missed out on, and in a shocking twist of fate, will teach you eminently practical skills as well. I'd rather hire web jockey + "I worked all the way through the SICP" than a guy with just a degree.
(I hate it when people say they learned nothing from schooling, computer science theory is dripping with practical usefulness. Unless you're just so damned brilliant you came up with compiler theory and basic AI and type theory and all kinds of other stuff all on your own. Which I don't believe.)
I had been programming for years before I got to college. I'm "self-taught", but until I got to college, I hadn't learned any of the academic aspects of programming. Learning how to analyze code, in addition to how to write it, was one way in which formal education really helped. Read about complexity analysis, for example.
Here's the slightly modified answer I just posted there (even though it's an old question):
Back when he was still doing podcasts Joel Spolsky answered the similar question, which was partly "Does a good programmer without a CS degree really have a chance to get a job at Fogcreek?[1]" (It's near the end of the page.)
He says that for a good self-taught programmer who began with a high-level language, say PHP or Java, who comes at programming from a practical perspective, there are a few important parts of the CS curriculum the person may have missed out on, and goes on to list some books that would help fill in those gaps.
Off the top of his head he named these books in about this order:
- Structure and Interpretation of Computer Programs[2] (also free online[3])
- C Programming Language[4]
- The Unix Programming Environment[5]
- Introduction to Algorithms[6]
He said that those books covered the aspects of the CS curriculum his company needs in a good programmer, e.g. being able to create algorithms for an uncommon data structure.
Those books all have the added advantage of having exercises, and all being a very pleasant read. SICP is an introduction to many of the big ideas in CS: data structures, streams, recursion, interpretation, compilation, register machines, etc., and their implementation in Scheme (a kind of Lisp). It's a great place to start. The next two focus on implementation details like pointers and memory allocation. They are compact, powerful books. The last, Introduction to Algorithms, seems misleadingly titled, as it is fairly comprehensive and used in both undergraduate and graduate courses. If you work your way through the entire book, chapeau!
For this, I recommend Dale Carnegie's poorly named How to Win Friends and Influence People, and attending your local Toastmasters group (you will improve your speaking substantially)
I don't know, Alice answered. Then, said the cat, it doesn't matter."
A good (non generic) answer to "What should I learn?" (asked by a self educated programmer here) depends on the answer to the question "What (kind of programmer) do you want to be?"
Step 1, answer the Cheshire cat! )