You have to know several hundred things in order to be a good programmer, and a good chunk of these aren't even on CS program.
I interviewed a guy once whose list of data structures was "bit, nybble, byte, float, char, int". As I recall, he didn't have a CS degree, and had over a decade of experience in the field. He did not get the job.
There is something to be said about using a common nomenclature, and I understand why you might be hesitant to hire someone who isn't speaking the same language as the rest of your team, but underneath he could still be an algorithms genius.
I end up using some kind of state machine just about every time I build a web app. If you're just tossing PHP together to make something work, you might never happen upon a pattern like that, but as a professional developer these things definitely shouldn't be a mystery, even if you "just" build web apps.
Like all things, state machines can be overused and over abused, even during times when they are not ideal.
For HTTP to work best, you should try and keep it as stateless as possible. Keeping state consistent between multiple servers is very much non-trivial. If your web app takes off and needs to be scaled to more than 1 server, design choices such as state machines can really cause you very nasty issues down the line. You either have to keep state across a memcache system, which can get wonky with multiple requests hitting multiple servers, or you have to keep the state encoded inside a cookie which opens up security issues.
Sticking to stateless webapps is nearly always a better choice. Check out some guides to RESTful services to get started.
"new", "approved-by-other-user", "verified-by-admin", "hidden", "promoted".
I agree that at the HTTP level you shouldn't be using FSMs.
They also work great for transactional resources like a shopping cart order.
Some people just solve the same problems over and over again without realizing it.
Much of the theoretical underpinnings behind some of the stuff I use, I might not have ventured to look into it were it not for my college degree (nor could I have figured it out by myself). The more basic stuff you know, the easier it is to pick up the harder stuff. Trick is to know which stuff is the basic stuff first. In college you get a shortcut to the basic foundation stuff. If you have a nose for that sort of thing, then good, but it's very hard to do so in the beginning.
CS courses aren't designed to give you practical programming knowledge. It's designed to teach you theoretical underpinnings that you can carry throughout your career, regardless of what the technology du jour is in vogue.
Sometimes, it's just good to have had a brush with something, so you can pattern match and say...I remember seeing something similar before. Or even to know what something's called, so you can look it up later. Hard to search for things when you don't know what they're called.
I tend to disagree. You don't need to search for things by name, you only need to recognize some common cases for the pattern and then look for people talking about those cases, which is pretty easy to do. From there you'll find the pointers to what you need to know.
Most problems in CS (or at least things you'll be solving without moving into postgraduate research) are solved by existing algorithms and patterns that have been used elsewhere for a long time, so there is tons of data to look back on.
Metacomment: incoming list of people saying cs education is for "sheeple" and any real hacker can get a job/learn it on his own.
And this is the metareply,
That's not the point of an education. Mistaking college for that is thinking college is trade school training. It generally hasn't been, it usually isn't, and it shouldn't be.
Loosely, the purpose of education ( as opposed to training ) is to provide (i) a broad base of understanding across a wide variety of areas nearly inaccessible without portals created by experts, (ii) a theoretical grasp of the field, providing a framework and sense of theoretical possibilities present, past, and future, (iii) a structured and systematic mechanism to go through these subject areas in ways that are (a) thought-through, (b) approximately complete, and (c) pedagogically competent, and finally, (iv) a standard way to attain a certain competence in the area that is generally agreed upon to provide a base understanding.
It would be disingenuous to suggest, imply, or to ignore the fact that many educational institutions do not fully live up to their promise. It would also be disingenuous to ignore the fact that a vast number of incoming students really just want to be trained for a job and go make a decent wage, which is an entirely morally acceptable desire. These facts are connected by the economics of supply and demand.
My university went into a semi-deep understanding of complexity theory, graph theory, logic and a few areas relating to bioinformatics. I also got a shallow introduction to logic gates, assembler languages, java, etc etc.
Most university degrees are similar with the emphasis changing around a bit. I feel a university degree is still very important as it gives you something far greater than a few pieces of theory: an understanding of how to learn more.
Most self taught programmers will have gotten their knowledge from experimentation, books, Google searches, and sites like this one. In general, they aren't going to be able to grab academic research from the 60s in optimizing graphs and apply that to their code when needed as the type of language and math involved is going to push them away. Meanwhile, a CS grad has probably had to go through these types of papers for their degree and will understand how to approach them. The confidence of doing it before in their degree is also incredibly important when reading something that looks like Greek.
EDIT: And don't knock the knowledge you can gain from a paper written by some professor back in the 60s - the concepts, algorithms and recommendations are nearly always just as valid today.
The average person with a CS degree isn't familiar with the research literature either. That's the kind of background you usually get from doing a PhD.
With the hindsight of plenty of time in the field, I find it remarkable how many fundamental concepts you still need to learn that they do not teach in current CS programs. In my area of work, massively parallel algorithms and distributed systems, the core theory, never mind practice, still has to be learned outside of school and the initial barriers are not trivial. (Small-scale parallelism and distribution is based on functional programming concepts and mutability. Large-scale parallelism and distribution is based on topology and Nash flows. Very different conceptual models.)
Totally OT, but I don't suppose you have a reference to some introductory material on that (seminal paper, textbook, etc would be fine)? I've been getting massively more interested in distributed systems & reliability thereof.
Also first sentence is really awkward. Better:
I will be the first to admit that I absolutely despise the state of higher education. The concept is fundamentally flawed, and I am not thrilled to have spent 3 years (and only 3, thankfully) working towards a piece of paper that “proves my skills”. In my opinion, it does not do that in most cases.
Automata theory may seem arcane, but if you want to truly understand concurrent programming, protocol design, robust systems, etc, you need good cognitive models. Heck, Erlang (one of my favorite languages for massively distributed computing) has some nice OTP stuff (http://www.erlang.org/documentation/doc-4.8.2/doc/design_pri...) built in for using FSMs to make your code sane and robust.
FSM's are one of the theoretical CS concepts that it is easiest to see the practical use for, but other TCS tends to be just as useful if you look at it right. Eg, space complexity right? For the most part that doesn't matter, does it? Nope. A bunch of modern internet-sized problems end up being streaming problems (http://geomblog.blogspot.com/2005/05/streaming-algorithms.ht...), and you need to understand basic space complexity, linear algebra, and probability, all of which a good CS degree will get into your head. I think the role of a good CS degree is to get some theory into people's heads, so that they have the right cognitive models for tackling difficult problems that come up in the real world.
I'm not saying that a CS degree is necessary to be a good programmer, or that you can't pick up those mental tools without a CS degree if you need them. But, it is easiest for most people to learn that kind of stuff in a university environment. I for one didn't know that I needed theory to work on the sorts of massive-data problems I was interested in, before going to university. A good CS degree knows about your unknown unknowns.
I consider a degree to be proof that a) you can be trained, b) you can start and complete a program of study (i.e., project), and c) you have a good idea of what you're talking about.
It doesn't mean you are any good at it (or even above average, really). It doesn't mean that you're a programmer or a scientist. It just means that you're trainable.
And in that regard, the major you choose doesn't really matter one bit. You can get a degree in biology or theater or business, and you'd still be trainable. You might not have the fundamentals, but those are easily taught. If you can learn bio-chemistry, then you can learn FSMs and pick up the fundamentals of programming.
So as others have pointed out, it's not a computer science degree that matters. It's trainability and the capacity and desire to learn that matter. I'd hire a hard-working, self-directed, knowledge-hungry theatre major over an entitled, I-don't-want-to-do-anything-but-program CS major any day of the week.
It's actually the reason for really disliking papers that prove something. You forget stuff after you got that paper, but keep your degree.
Also one simply has to say that there are HUGE differences between what you need to get that sheet of paper, even if you went to the same school and often if you attended it at the same time.
After my second year at uni I felt that I should just quit and get a job. Everything I needed for landing a job in the industry, I was getting from my own side projects. I wasn't learning about things like scalability, or robust system architectures, or code deployment, yet half of the interviews I went through expected me to know about them, even if it was for a graduate position.
I still haven't used the vast majority of the theory I was taught at uni, but sometimes, when you come up with an elegant solution and trace it back to that 'Computer Vision' course you've done at uni, it feels like it's all worth it. As others said, coding skill is very important but when you know the theory you know where to look for solutions.
The biggest value of a CS degree to me is to be exposed to the cool work of others.
What I mean is, we have people from all over coming here and giving talks on the kind of things they're working on. Sure, many of these things are more 'academic' in nature (in the sense of not being immediately deployable e.g. a new internet protocol), but I think their work is exploring the boundaries of the current state of knowledge.
To get a feel for what kind of crazy stuff intelligent people are up to. That's the reason I love being a graduate student.
In my humble opinion anyone can learn to program in any language and most people can produce quite a few examples, but good programers know how to apply theory which helps them produce faster and more reliable code.
For example, the tendency to religiously follow patterns, over-complicate things.
IMO these concepts come up all the time. A CS degree might help you to know what they are, but not when and how of applying them.
Also plenty of self-taught developers are aware of these patterns. I can't imagine a "good developer" who wouldn't know about FSM, or someone who would use redis without considering time complexity.
For those who _did_ get a CS degree, what things you learned from it do you use in your current programming work? and how?
Edit: or rather, what is the single most important thing you would want self-taught programmers to know about, that you find most don't?