What Knowledge Gaps Do Self-Taught Programmers Generally Have?
BeardedChimp writes "I, like many others here, have learned to program by myself. Starting at a young age and learning through fiddling I have taught myself C++, Java, python, PHP, etc., but what I want to know is what I haven't learned that is important when taught in a traditional computer science curriculum. I have a degree in physics, so I'm not averse to math. What books, websites, or resources would you recommend to fill in the gaps?"
Although in practice most of the time advanced data structures and algorithms are not used, it is useful to study them and implement them yourself at least once. Dijkstra's algorithm, Prim's, Kruskal's, maximum flow, and other basic graph-operating algorithms are a good example.
Some people might consider that a good thing ...
Experience helps, but the real killer deal is experience backed by a CS/Eng. degree.
Need an ISP in South Africa?
I've found that self-taught programmers can actually be quite productive. However I've noticed (in general) the following deficiencies which I think are both rooted in the fact that the need to memorize seemingly arbitrary facts about a system is inversely proportional to deepness of understanding of that system (see graph):
-Design Patterns (noted earlier by others): There is a tendency of self-taught programmers to follow a design pattern more doggedly than others. This can be tied back to the fact that for the self-taught a particular design pattern represents what programming is to them. They memorize a series of facts that support the design pattern they use rather than understand the nature of a design pattern itself. They tend to have steeper learning curves when presented with new structures and design patterns because using a new design pattern requires the abandonment of the facts they've memorized and starting anew with memorizing a new set of facts.
-Adaptability: Self-taught programmers tend to reach a certain level of comfortableness with technology (ie: languages/libraries/etc.) and attach themselves to it. The thought of using a different language, library, or system is daunting (or even aggressively resisted) since, again, changing requires a new memorization of facts around the technologies (see graph).
Much of what you should learn formally from a CS degree is WHAT a programming language is or WHAT a design pattern is, not merely HOW to program or HOW to use a particular design pattern.
That said, there's nothing stopping a self-taught individual from learning these things on their own. It's just that when you're teaching yourself a trade you, naturally, immediately (and sometimes exclusively) focus on things that allow you to compete on a particular level or with a particular technology. Learning design patterns or what programming is in the abstract doesn't seem to have an immediate payoff (clients aren't going to ask you about those things). But they are skills which allow you to be competitive across technologies or design patterns which is especially important in the rapidly changing world of computers.
Faith is a willingness to accept something w/o complete proof and to act on it. Reason allows you to correct that faith.
To be fair, I got BS degrees in Computer and Software Engineering, but if we consider only the required courses from both these curriculums, I gained:
- NO education on design patterns
- A very limited understanding of how to apply big O analysis to an algorithm (although I do understand what it represents)
- Almost NO attention to "proper" OO analysis and design. Any knowledge of this I have is from personal experience during school and professionally
- only a cursory look at threading.
- A good understanding of state machines
- Exposure to language construction (via a required course on compilers)
- A good understanding of computer architecture
What one learns in an academic environment is very much dependent on the core curriculum the school has and thus a self-taught programmer may not be at much of a disadvantage at all.
I'd say you need to learn enough mathematics to get an appreciation for what goes into the discovery of an O(nlog[n]) algorithm -vs- its [naive] O(n^2) counterpart.
This is a gap I've seen with self-taught programmers: they didn't take algorithms classes where you analyze algorithms for efficiency and write complicated algorithms for (mostly) academic problems. Even amongst university-taught programmers, most people see this class as a waste of time. I've taken it twice (undergrad and graduate level) and find it helps me in my job.
You could teach people all they need to know about big O and common algorithms in an afternoon.
Sorry, but I gotta call B.S. on that one.
You need YEARS of mathematical training to grok this stuff.
Have you ever tried teaching college level programming to recent American high school graduates?
I have had young adults [some already with bachelor's degrees who were coming back to school to brush up] who couldn't reliably compute anything in Base-16 [hexadecimal].
They need the better part of a decade's worth of intensive mathematics training to get to the point that they could really grok the difference between what goes into a "slow" O(n^2) algorithm and its "fast" O(nlog[n]) counterpart.
And let's face it, lots of people doing basic HTML or VBA [Visual Basic for Applications] probably don't have sufficiently high IQs to make that transition.
And even if they do have sufficiently high IQs, then summoning the self-discipline [not to mention just the spare time] to tackle this stuff is going to require a really formidable application of the will.
Which is not to say that it can't be done, but the odds are definitely stacked against them.