I'm a cargo cult programmer, help me

202 points by jrookie ↗ HN
Hello HN I come to you for help.

I went to college and got an Information systems degree, it was a crappy college so the most programming we had was dabbling with arrays and pointers in C, not much Algorithsms & Data Structures, no unix, no Operating Systems and no compilers, and most importantly no problem solving. Half way through college my father died so I had to find a job to make ends meet, somehow i got sucked into the java "enterprise" world where I've been for the past 5 years, glueing API's and frameworks together, with some Javascript and SQL on the side, however on the verge of my 30's, I now have found that I lack the fundamentals of Computer Science, the things every programmer should know: Algo's, Data Structures, Operating Systems an understanding of compilers and being profficient with linux. Eventually I plan on going back to a real University and getting a CS degree, but I'm unable to do so at the moment, this is why I have come to ask for help.

OTOH I have given thought about if programming is really for me, I have found that I'm really, really bad at problem solving and "thinking outside of the box" I have come to accept that I'm really not smart. I'm slow, forgetfull, concepts never seem to stick, I have to force myself to not take things for granted, it seems no matter how hard i try I can't look at problems from different perspectives and understand the implications of a particular solution, I'm starting to think I may have a learning dissability, or that is because I lack the basic toolkit for problem solving, but I really think I'm just not very smart.

Of course the realization of my lack of skills, as you may have guessed, is because I want a better job, and there seems to be no place in the world for dumb programmers, and to be honest this is something I understand given my limitations and looking at my other peers, seeing how long it takes for me when programming something or understanding a problem, seeing how fast other people can grasp concepts that I struggle with, I understand that I'm just not valuable that all my experience means nothing, So I'm back to 0.

I have started going through the basic Algo's and Data structures again with a basic Java book about algorithms (I tried cormen but no way I could wrap my head around that stuff, I forgot all the calculus/math from college and i just lack the mathematical maturity for that book).

I'm also trying to study discrete maths, Operating Systems and compilers, of course one step at a time. I imagine this will take me years just to get a basic understanding of all these concepts.

And finally trying to memorise all those linux commands I ALWAYS forget.

Lastly I'm trying to learn technologies and languages that will help me get a better job, I'm still not decided whether I should learn Ruby on rails or python or Lisp or just stick to Java and learn Android and do my own thing and forget about joining a "cool" startup or working at the big guys like google(10 years from now after I become a real programmer of course...) Or quitting programming altogether.

Hackers, I understand this is a long and boring post, filled with grammar & spelling errors (English is not my primary language), but I only ask of you to guide me whether I should continue this path in which I have invested all my adult life on or just start again from zero, I just don't want to be a cargo cult programmer anymore.

Thank you

158 comments

[ 5.1 ms ] story [ 229 ms ] thread
Kudos for discovering something important about yourself.

Your path forward probably should be determined by the kind of work you want to do, but I think you know this.

Certainly don't be sucked into the new technologies because they're cool. Nor should you necessarily get a CS degree, depending on the work you want to do. You sound like you want to learn everything ever about computing, but that's a recipe for frustration and won't necessarily help you.

But anyway, good luck.

Thanks for your answer.

I would really like to learn more about machine learning and NLP, after reading a bit about them I found them to be incredibly interesting subjects, however my Math/Algorithms skills are a barrier into understanding most of the concepts, that is why I plan on eventually getting a CS degree.

And yes I agree, it might seem like I'm trying to learn too much at the same time, I'm just incredibly overwhelmed about all of the stuff I've been blatantly ignorant about whilst calling myself a "programmer".

"Programmer" I think is a little like "scientist". It used to be possible to be an expert in all things, but it's not really any more. So don't be so hard on yourself. You're like a biologist retraining as a chemist.

But since you've found something that fascinates you, go for it!

I worked as a programmer for many years. I hit 30, felt bored, and am now in graduate school studying NLP.

A lot of people in NLP are awful programmers. We have a group of ML researchers down the corridor and they build all their models in Matlab. You do not need to write great code to do research. It is more important to come up with a well thought out model and then throw together a horrible implementation to show it works.

Math is a very wide and varied subject. A lot of things you'll learn in a CS degree are useless for ML/NLP. Many people argue that ML is just applied statistics, with a sexy name to get more funding.

Finally I think the reason you're feeling stupid is that you're starting to challenge yourself. I spend most of time feeling really dumb in graduate school. Your brain is a muscle and needs constant training. You'll hit plateaus where everything seems like gibberish. Keep it at and you'll be surprised what you can learn.

Good luck.

For what it's worth, the only way I've ever learnt anything significant relating to programming was getting a job that demanded it. Want to learn Linux? Install it on your primary laptop and get a job that uses it. Same for Python or Ruby and Rails or whatever.

So, I think your feeling of incompetence may be just a feeling of being totally bored by doing the same thing for five years. If you got a job that, say, demanded you immediately learn how to make feature changes on a PHP site, I expect you could do it fine.

This doesn't cover everything in your post, though -- you're right, it does take years to become a kernel or compiler hacker. There's plenty of work to be done with fewer prerequisites than those two.

I agree. Specialize in working on one aspect, starting from the most rudimentary "get sh*t running" and working your way up. Rails has been great for me as I've learned to poke around along the entire LAMP stack.

At most you'll need 3-4 books on computing math, sorts, data storage, etc for reference only. Slowly, one will need to start understanding more and more complicated aspects of CS, just to make stuff work. With the introduction of Github & other open source examples of coding, learning by example and trial is easy. During this time, I'd also grab a good book on database design & architecture.

Thank you for your answer.

I have already installed linux as my primary OS at home, I still have to stick to windows in my job though.

If you have the ability and the desire, install Cygwin on your work computer, and do as much work through that as you can. It may help.
Thanks, I will give it a shot.
Take a crack at Python and Ruby (or another language if you prefer) just to widen your experience, even if you stick to Java it will be good for you as a developer. I did the migration from Java to Python a few years back and I'm still learning and unlearning, so don't get discouraged.

One bit of advice: Try to learn a bit about proper testing as you are learning your new language, it will be easier than trying to do it after you've learned and testing will help you build confidence in your abilities in the new language.

Two good books:

"Learn Python the Hard Way" by Zed Shaw http://learnpythonthehardway.org/static/LearnPythonTheHardWa...

and/or

"Why’s (Poignant) Guide to Ruby" by _why http://mislav.uniqpath.com/poignant-guide/

Most non-rockstars forget Unix commands, it's not a big deal and you can help yourself by writing up a cheatsheet or googling for one. Practice and muscle memory helps.

I haven't had a chance to check it out but there is a PacktPub book on Python algorithms which looks interesting: "Python Algorithms: Mastering Basic Algorithms in the Python Language" by Magnus Lie Hetland

Good luck!

Thank you for the links I will check them out!
Oops .. Apress Book not PacktPub.
I'd just like to second what huxley said about not getting down on yourself for forgetting unix commands. If unix hacking isn't mission critical to your job you tend to not get the reps in these commands to make them automatic. Make google your best friend and if you have to look through a chmod or crontab tutorial every few months, it's not the worst thing in the world.
People are not born with the ability of a Djikstra or whomever you idolize. It takes decades of diligent practice to get to that point.

Do not feel down about feeling stupid or inadequate, just keep working in a reasoned manner towards your goal.

You will get there.

Thanks for your words of encouragement.
Also, don't get discouraged by all the amazing projects you see on the internet. I used to feel that I would never be any good because I would spend all day looking at the latest thing on Hacker News and know that I couldn't build those things. But remember that those same people spent years developing their specific set of skills. It didn't just happen overnight.
I've gotten some flak for saying this other places, but the most helpful thing that I've ever done to learn linux was installing gentoo. Especially doing it without the official install CD (by using something like knoppix).

Start here: http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=...

The thing that is different about installing gentoo vs centos or ubuntu is that instead of something that looks like this:

     Would you like to format the disk (click yes or no)?
You get a walkthrough of what fdisk is, then how to use it, then you use it to partition your disks. Instead of selecting a filesystem from a dropdown, you make one with mke2fs.

I don't recall if Ubuntu even tells you what lilo or grub is.

The reason I like this is that it forces you to understand what is going on. What is the /boot partition? Why is that important?

Installing gentoo is going to force you to use tar, and wget. It's going to force you to get comfortable on the command line.

It's also going to force you to understand what a kernel module is. It's going to force you to understand things like: what chipset does my wireless card use?

It's hard. And it takes forever. And it probably won't work the first time.

To me, it's kindof a rite of passage, like telling a carpenter that he has to build his workbench before he is allowed to start working on anything else. The workbench he makes might suck...hopefully this causes him to want to keep building new workbenches until he has one that is perfect.

Oh god I remember trying to install Gentoo on a PowerBook once about 5 years ago on the advice of a friend. Spent a couple days trying, never did get it working but I did learn a bit about Linux...

Of course the skills you learn are more sys admin / OS concepts than fundamental CS concepts though.

Tried to get Gentoo running on my Compaq T1000 Transmeta tablet quite a few years ago, to no avail. However Ubuntu jumped on that like Sheen on a, um, well suffice to say the architecture was well supported.
I'll second this. It's long and laborious, but it's also not as hard as you might think - the handbook is great at holding your hand through the process.
Thanks for this.

I'm currently using Ubuntu as my primary OS at home but I will give Gentoo a shot.

Perhaps try it inside a VM. Installing gentoo from scratch is a brilliant way to learn linux, but it's not so much "trial and error" as "trial by error" (message.)

If you do it in a VM or on a spare machine then you will have convenient access to web resources, which you will need :)

This is why I suggested doing it from something like knoppix.

He could even do it from his current Ubuntu install.

You might also consider trying out Arch Linux. (www.archlinux.org)

I moved to Arch after a few years with Ubuntu and I love it. It's a little higher-level than Gentoo in that you don't have to make your own file system or compile your own kernel, but it is an educational experience in that you have to install anything you'd like to use. When the 15 minute install is complete, all you have is a bash prompt. Getting a GUI, the ability to print, wireless, etc is all up to you.

They give you a great package manager and they maintain an excellent Wiki that can walk you through almost any task. Arch taught me loads about configuration.

Then again, I did Gentoo back in the day too. It might take 4 days to complete the installation, but you sure will learn some things! :D

The main difference between Arch and Gentoo is that Arch is binary (IA-32(e)) package based and Gentoo is source based.

They both can deliver you to about the same point on install (Gentoo stage3 install).

My experience might be out of date at this point, but I remember getting similar experiences out of installing Slackware and FreeBSD years ago. Nowadays, the Ubuntu installer takes care of so many details for me, that I don't really have to think about the install process.

Probably something like "Linux From Scratch" http://www.linuxfromscratch.org/ would also be a good way to learn the important details.

Another great way to learn Linux is to setup a VPS. Last year I setup a VPS from scratch with no previous experience (Ubuntu, PHP, Ruby on Rails, DNS, email server, iptables and more) using just web tutorials. It was a slow process (it took me about a week full time) but it taught me a lot.
Agree totally.

Setting up a VPS from scratch taught me a great deal, it's nice to be able to flip a switch and make all your mistakes disappear, and then have a new fresh canvas available.

"Teach Yourself Programming in Ten Years"

http://norvig.com/21-days.html

"Structure and Interpretation of Computer Programs"

http://mitpress.mit.edu/sicp/full-text/book/book.html

1) Ctrl-F Structure and Interpretation of Computer Programs

2) Upvote

3) Post reply. SICP is not only the best textbook on computer programming, but one of the best textbooks I've read on any subject. The first three chapters will teach you more than most programmers ever learn, in such a way that you can apply it to any language.

> in such a way that you can apply it to any language

After working through some of SICP, would you recommend then using Scheme for practical projects?

If you want to learn fundamentals, you need to master C. The language itself is very simple and readable, but what it will teach you is how memory works.

Every algorithm & data structure worth implementing has been implemented in C and is probably available in an open source project. You can download Redis, which is fantastic code and covers all the basics. Take one of these projects and start trying to mold it to your will.

Write specialized string parsers in C for doing simple things you'd normally do with a script. If you do it right, it'll be several orders of magnitude faster.

Learn to use the GNU debugger.

Take blocks of algorithmic code you've written, learn pthreads, make them concurrent, and actually able to achieve linear increases in speed as you add cores.

Your greatest ally will be well-written open source code.

"Write specialized string parsers in C for doing simple things you'd normally do with a script. If you do it right, it'll be several orders of magnitude faster."

Note that this ONLY makes sense in the context of a learning exercise. If it's simple and you'd normally do it with a script, the performance you'd gain from a C rewrite isn't worthwhile. The knowledge you'll gain from making C do something it doesn't make easy, though, is.

In most situations, I definitely concur. There are a few cases where I've had to process >10g flat files and I whipped up a specialized tool in C that could run through it nearly as fast as the disk could feed it.
Sure, but I doubt you'd seriously try to handle that with pipes and Unix anyway. 10g warrants someone who knows what they're doing and knows, like you, when the overhead of writing in C pays for itself in faster processing.
Unless you're in scientific community, where it's common to have to convert GBs of data from one weird format to another, or possibly analyzing them, nevertheless knowing only e.g. R and Matlab.
You might find "The Elements of Computing Systems: Building a Modern Computer from First Principles" interesting. It is broad, it covers pretty much everything you mention wishing to know, but somewhat shallow (It is only 350 pages after all.) So far it has hit on the somewhat less rigorous side, so it would probably be a good fit for someone who thinks they lack mathematical maturity.

I just don't want to be a cargo cult programmer anymore Then don't be. The main thing to do is Practice (note: work isn't practice.) Basically build something, but at every step of the way try different approaches and measure the results of what happened. Every step of the way look for ways to improve what you do.

Yes! thanks for mentioning that book I forgot about it but I plan on getting to it eventually, there's just so many things to learn, so many books...sometimes I feel overwhelmed.

Thanks.

The problem is, if you "try to think outside of the box", of if you "try to remember things", you will not be able to... And if you stop and think about when you tried to do those things, well you will probably notice that you passed almost all the time worrying, or doing something else as useless as that.

The point is that you shouldn't try to do something, you should do it, i.e., you "span" a desire in your soul and you go along the feeling, the "thinking" is just for control, not substance... at first you will litteraly be bugged by thoughts like "i'm not good enogh for this" etc... aknowledge the existence of those thoughts, and then throw them away.

Yours is a post about bad self-fulfilling prophecies.

It's not really a matter of intelligence for the most part, it's only a matter of experience.

PS.: oh, and AFTER you got rid of the bad self-fulfilling prophecies, you could try to create some good ones :)

Good luck, you are going to need it

Thanks for your answer.

The last thing I want is to give up again, sadly the more I try the more these thoughts come in to my head and the harder it is to throw them away.

A couple of thoughts. One, there's a ton of work that doesn't need databases, or operating system knowledge. It helps, but its not essential. Android developers are hot hot hot right now, and its not a huge system to learn (I'm a mobile dev manager).

As mentioned before me, you can learn a lot on the job. One of the best dev's I know never finished college either.

I am always looking up the proper syntax of commands (find -exec anyone?) It just takes repetition and the constant thought that "maybe there's a command that does this better".

Finally, put down the math books. Put down the compiler books. Data structures and algorithms, sure, but those others. Bah! Now, if you want a supplementary book that helps a ton, pick up a patterns book, preferably the "Gang of Four" book (http://en.wikipedia.org/wiki/Design_Patterns). It helped me to look at problems in a bit more of a formal sense, and it allows me to say "Oh this is such and such a pattern" and other devs get it immediately.

Don't get discouraged. You may just need a new job where you are mentored if you feel like your skills and experience is meaningless. Your desire to learn and your passion for your chosen career make you a fertile ground for training.

Good Luck!

Thanks!

And yes I really think I need a mentor, just haven't found one yet, or haven't looked hard enough.

"Finally, put down the math books. Put down the compiler books. Data structures and algorithms, sure, but those others. Bah!"

This is seriously bad advice. The converse is not necessarily good advice but when the OP explicitly wants to be good at CS, "put down the compiler books and read the GOF Design Patterns book" is terrible advice. The GOF DP book is barely one step above Cargo Cult sw,something the OP is trying to flee. There is a wide range of advice on this thread but this must be the worst(imo, ymmv etc).

plinkplonk - I respect your opinion, so asking this question in earnest. Mind pointing to the best advice in the thread? I could look at the most up-voted answer, but group think is not always right.
OTOH I have given thought about if programming is really for me, I have found that I'm really, really bad at problem solving and "thinking outside of the box" I have come to accept that I'm really not smart. I'm slow, forgetfull, concepts never seem to stick, I have to force myself to not take things for granted, it seems no matter how hard i try I can't look at problems from different perspectives and understand the implications of a particular solution, I'm starting to think I may have a learning dissability, or that is because I lack the basic toolkit for problem solving, but I really think I'm just not very smart.

I doubt this is true. Rather, I think your currently ad-hoc way of trying to learn things is not effective. In other words, it has been your method, not you. One of the benefits of a formal education is knowing what is out there, even if you don't know it yet. (Knowing what you don't know.) That means you can go and learn it as you need to.

I suspect your difficulty with "thinking out of the box" is that you just haven't been exposed to alternate ways of doing things.

My point: you're not stupid. Learning all of this stuff even when someone says "this is what you should learn" is hard. Learning it when you have to figure out what to learn is even harder. Many people here will disagree with me, but I think a formal education is valuable for the reasons I stated. But, you said that's not an option for you now. So I recommend doing basically what you're doing: use existing textbooks to find out what you should learn, and learn it. Treat going through those books like a course. Many university courses also have the course syllabus online - looking through those for topics you should research yourself is also valuable. And, of course, MIT's Open Course Ware (http://ocw.mit.edu/index.htm) was designed with students like you in mind.

Thanks for your words.

I agree with you that formal education is valuable when you lack direction on "how" and "what" to learn as you stated.

I apologize for not addressing the main question, but I'd just like to express that I disagree that you're not very smart.

It might be a knee-jerk reaction on my end when it comes to to the whole "maybe I'm not smart enough", but you're showing awareness of your own (current) limits, which isn't something to speak lightly of.

What are your experiences with problem solving? It's something you learn, like most things. You might not be able to 'think' in that fashion now, but I know quite a few people who swear their brains and perspectives have been reprogrammed through forcing themselves to study math despite lack of talent, and in my own experience you can learn to flex and twist your mind much like you can your body, even if just like with your body it might be easier or harder in some directions.

You might however lack the aptitude which make it more fun to engage in or otherwise lead many more savvy to programming and CS, and only you can decide wheter this is something that slows you down or stops you dead.

When I did martial arts, I had some students who were dismissive towards their less sports-savvy comrade since they took longer or had a harder time to learn the basics; but what they forgot were that they'd already learned all the periphery skills of using their body from other sports, for them it was a simple matter of learning one more skill atop their experience and skill at already using their bodies, the ones who were having troubles were learning several more skillsets at once since they hadn't up to that point.

The same could apply to you, people have the opportunity to learn or understand different things at different points in their lives; some lessons some of my friends learned when they were 12 which other friends learned when they were 60, partially since they hadn't had the opportunity to truly learn or understand them until then.

I guess what I'm trying to say is, try not to be discouraged because it's hard; it can sometimes mean you're not aware of all the things on your plate at the moment, and even if it feels you're failing you're probably learning something else that's also beneficial while you do.

Sorry for semi-rant, but that's the part I felt remotely competent to comment on.

I do however agree that projects are the way to go if you wish to learn or remember. I and my friends learn more from our personal pet projects than we've ever done at our University.

Thanks for your words, no need to apologize :).
It sounds like you may not be "dumb", but maybe just a beginner who is struggling to get to the next level. Here are a few questions I'd ask first before you decide programming is not for you.

1. Do you work with other experienced and passionate programmers who can mentor you?(http://chadfowler.com/2011/02/24/be-careful-of-who-you-work-...)

2. Do you know how to learn? A lot of people assume it just comes down to reading the material, I found this book explains the process quite well and it is put in the context of a software developer looking to attain mastery http://www.pragprog.com/titles/ahptl/pragmatic-thinking-and-...

3. Have you "cultivated your gurus" so to speak? Putting up a post on HN is a great start, but continually involving yourself in discussions in the greater community will help you to tap into a source of experienced mentors even if you don't work with them. Find groups for topics you are interested in and then involve yourself, ask questions, learn, then contribute to the discussion yourself.

4. Have you considered getting involved in some open source projects? These are a great place to learn from others as well.

In the end learning isn't generally as simple as just reading a few books for most people. I would consider starting with a few books on how to get your career development and your learning process on the right track and then go from there. Even if you do decide you're not cut out for programming, what you learn from those books will be valuable no matter what path you choose.

The books I'd recommend:

http://www.pragprog.com/titles/ahptl/pragmatic-thinking-and-...

http://www.pragprog.com/titles/tpp/the-pragmatic-programmer

http://www.pragprog.com/titles/cfcar2/the-passionate-program... (will admit to not reading this one but I hear very good things)

Yes I realize these are all PragPro books, what can I say, they are that good.

Thanks for you answer, you tackle some of the other things I've been struggling with for the last few years.

1. I work with other experience programmers but they are not really into "mentoring", I have been looking for someone online who can lead me on the path of the hacker.

2.Good point, sometimes I do feel like I don't know how to learn. Thanks for the link I will check it out.

3.This is one of my flaws...I'm not very confident in my abilities, and frankly I never feel like I have something good enough to contribute, this is also why I've never felt comfortable starting a blog or participating in open source projects.

>This is one of my flaws...I'm not very confident in my abilities

Realise that lack of confidence is just another way of saying "knows his limitations." This is an asset that most people at your level don't have.

If you want to learn some CS, here's a concept for you: Fail Fast

https://secure.wikimedia.org/wikipedia/en/wiki/Fail_Fast

This concept, like many CS concepts is often generalised by hackers to life in general. Practice makes perfect. What does practice mean? Doing things badly over and over again until you get better. Viewed in this light, failure is an asset. As long as you learn from it, you can see each failure as another step on the road to success.

As I say, hackers generally take this attitude that failure is good. Strolling into an IRC channel or message board for a particular technology and professing your utter ignorance and incompetence concerning the matter will likely not be met with the derision you might fear. Most people are more eager to help the humble than the bullish.

EDIT: Also read this book before you read any actual programming books. Don't worry when you don't understand parts of it.

http://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach

Thanks,

I tried reading that Godel book and I couldn't wrap my head around it, I will give it a second shot though.

I think the best thing to do when you get to the really dense sections is just to plough through. It reaches a critical mass of crazy notation and mindbending logic in the middle, but once you get past that it drops back to being relatively graspable again as he addresses different areas. At least for a while :)

As I said, don't expect yourself to really understand all of it the first time you read it. Read it for the bits you do understand, not the bits you don't. Even if that turns out to only include the Carrol-esque dialogue, it's worth it.

#2 is your key problem. You do not know how to learn.

As a developer, "I am but an egg". Much of the advice offered seems good, but I fear it may reinforce a key problem. It seems to me that you are trying to model the external attributes of great programmers. For example, you judge yourself based on your inability to remember command line commands. But while remembering this stuff is surely a trait of many great programmers, it is by no means essential. And those that have it, got it by accident, through their hours at the command line, not by trying to memorize all the commands.

Dude, you could learn C or Python or assembler or whatever, and I'm sure it will help, but it won't get at the core problem. The key internal attribute of a great programmer is the ability to think, and to learn. These are what you must seek. Learn algorithms or data structures or whatever, but always be learning how to learn and think.

You have had a lousy education and probably never had great teachers. This is not necessarily your fault. You must learn how to think. And this is a very hard thing, many people never do. I'm not sure of the best way to go about it.

One important thing is to trust yourself, even knowing that in your limitations, you will screw up. This is okay, if your choices are based on some clear thinking, and you can later assess that thinking for its mistakes. Because that is how you will learn.

Another is that you can learn to learn in all sorts of places. You needn't do it only at programming. Do you have hobbies doing things that come more naturally to you, or that seem simpler? Spend some time working to become great at those. You will learn problem-solving and gain confidence, and relief from the stress and exhaustion of work. Be curious about everything.

Another is to focus on principles. I suspect that Java and Windows aren't so good for this, but as an egg, I can't say for sure. I suspect open source tools are better places to learn principles. But don't try to sound like a great programmer, learn to think clearly and elegantly about programming.

Another is to start simply. Don't try to be a great programmer, don't try to do things beyond b/c that's what the great programmers do. Become able to do simple things, elegantly and properly, and then become able to do more things.

Be willing to take a step back. Maybe these Java jobs pay more? But if you aren't learning, they aren't paying anything near enough. Find a job where you can grow, and never mind the wage, that will come in time.

Understand that confusion and frustration are natural and necessary to learning. Learn to distinguish good confusion, which can lead to progress, from bad confusion, which leads nowhere. But confusion does not mean that you are stupid. If you'd had a proper education, you would understand that smart people are confused all the time. They just aren't panicked by it, because they know it signifies little about themselves, and that they will, in time, pass through it.

Take heart. Humility is a door to learning; despair is a door to nowhere. You can get there. We are all learning, many of us are still trying to recover the time we lost to mistakes and accidents. My God, if you knew what I'd give to get back the time I have wasted . . . . Find ways to enjoy today, even as you aspire to be more tomorrow. Put little bits of beauty and color in your life, always find ways and times to laugh, eat well occasionally, watch some good movies, read some good books. Frodo saw the flowers growing in the vandalized statue, Sam saw the stars above the murk of Mordor, and they knew that there was some lovely and grand above their misery, against which the misery could not forever prevail. Now maybe that's a little melodramatic, but you have to see the glimmers of hope, and know that you're hoping for something so much better that it must be possible.

This is crucial. Even if you start to learn, you are going to be in confusion and frustration for a long time. If you don't find a way to fin...

You probably don't have a learning disability. You have simply come to grips with the fact computing is inherently difficult in a lot of aspects. When you go out and teach yourself, don't be discouraged by failure. You shouldn't read technical books like a novel, no one does, and those who claim they do are just lying. For more on that you can read this: http://web.stonehill.edu/compsci/History_Math/math-read.htm

Which describes how math books (and other technical books by nature) should be read and studied. Don't think after reading a paragraph, you should understand everything. Take it slow, and take the time to work out things on your own, the more this happens the easier it gets.

Also, whether you are good or not at problem solving, just remember that you should be enjoying the process of solving problems, not necessarily just the answer. It took Steven Hawking 29 years to make a big step of progress with Black Holes. Experimenting is just as important as the thought process is. Read something, test it, break it, try to fix it.

You also stated you had difficulty looking from new perspectives. This is tricky, but first get your creativity flowing, then ask all of these question. Why? How? Why Not (INSERT SOMETHING ELSE)? Will it work with this? What is the fundamental idea? Is there a way to change the implementation of how this is done, while still maintaining the proper outcome? Scribble down your ideas, and play with them.

For example, I remember when I was trying to fix my indoor toy flying helicopter after the plastic broke on one of the propellers. Instead of taping it I asked myself, what it was exactly I was trying to do, which was reconnect a broken plastic propeller. Then I asked myself what ways this could be done. After fooling a bit, I decided that since it was plastic I could simply melt it back together. You just have to learn to break things down, and chunk them together, and play with the elements of a problem.

Keep reading, learning, most importantly have some fun.

Thanks for your answer,

The difficult part for me is that I have to force myself to ask the questions that you talk about, it's definitely not intuitive for me and my first reaction is not to think about the different solutions a problem could have, like you said I can't break a problem into chunks, and this I think is essential to be a programmer.

These are things you can't do yet. The yet is the important part- never forget that.

I read somewhere above that you spend a lot of time fixing bugs. Congratulations! You're already a programmer!

To move onward and upward, the biggest thing you can do is change your mindset from "how do I make this problem go away?" to "what is causing this problem to happen?" At the end of the day, you'll still get those bugs fixed, but you'll have a deeper understanding of the things that led to them in the first place.

Once you know that, breaking things down and shuffling ideas becomes second nature.

I think maybe your model of how a person becomes a good programmer and reality might be far apart.

When I wanted to learn C, I bought six or seven books, some of which came with a compiler. I read each book.

Now that probably sounds like I am a genius, sucking down information directly from the text. But what really happened wasn't so flattering at all: I flailed. It wasn't until the third book or so that I finally got anything to compile, and I think it was book 4 where I figured out how the hell to read pointers.

I really sucked at learning programming.

When I picked up C++, we were on a family vacation. The kids all played in the pool and did fun stuff. I sat by the pool and read C++ books. If I thought C was tough, C++ was a killer.

I finally got it, though.

Last year, when I wanted to finally learn Functional Programming (I'm 45) I did the same thing. And this time, guess what? Even after the books I sucked.

So I started writing little projects, which also sucked. I went back and read the books again. I wrote some more code. I still suck at it, but I suck a little less. Perhaps in another year or two I'll consider myself proficient.

Yes, it is terribly awesome to sit down in front of a client with a tough problem and do some wizardry on the screen and feel like the hero. I spent my 20s and part of my 30s being the super-hero star guy. I had a blast.

But that's just hot-dogging: showboating. (People do it for fun and to make their job more like a theater performance) In reality for every one of those times I was showboating there were hundreds of hours spent trying to figure out what the hell was going on with something.

I think it might be easy to look at other coders who are like I was and get the wrong impression. Yes, some folks are smarter or have a better recall than others, but guys with huge recall ability many times get wrapped up in some kind of minutia that's not important to the team. Everybody has flaws. This will sound very strange to hear, but it's true: you can be the worst programmer on a programming team and be the most valuable and critical person there. I've seen it happen dozens of times.

The question is: are you working at making yourself better? Not how smart you are, how you feel about programming, or any of that. Just a simple question about what kinds of habits you have in place to continue to improve. If you have those habits, you'll either become a better coder or eventually work out what you're meant to do. But you have to have those habits first.

So my advice is a little less angst and a little more work. Both to you and me :)

EDIT: By some kind of weird twist of fate I have been thinking about this a lot recently, because I was writing a review of the best book I've ever read that improved my coding, Code Complete. http://news.ycombinator.com/item?id=2263127

What you said about guys with huge recall ability getting wrapped up in some kind of minutia really rang true with me.

When I first started at the place where I work now, I encountered a couple of guys who are excruciatingly smart, and seemed to know every little detail about a thousand random topics. They wrote excellent code, and I was really glad they were on the team since they were part of a very small group of guys who seemed to be the only ones who knew what was going on in terms of our code and the direction it was going in.

But they were extremely intimidating to be around. Don't get me wrong, they were very nice guys, but their seemingly immense intellect was scary and humiliating. I regularly felt like a dumbass -- and I was the only one there with a PhD (in astrophysics, no less).

Over time, I saw that these two guys regularly got caught up in the minutia of some abstract aspect of a problem, so much so that they became annoying to have around, and were somewhat of a hindrance in the decision-making process. I was surprised to discover that I wasn't the only one to have noticed this. I also noticed that neither of these guys never really seemed to produce anything huge out of their massive intellects, and most of the big jobs were tackled over a long period of time, with a lot of comparatively "dumb" guys doing most of the work.

Everybody does have their flaws.

I suppose what could be taken away from this observation is that you shouldn't waste time comparing yourself to the "genius" types. Don't put yourself down because you're not as quick or as all-knowing as someone else. What matters more is that you get stuff done, and that you always desire to improve yourself AND work towards that end. You may not become "all-knowing" or develop a huge recall ability, but the other skills that you do possess will get better and better, and you'll be worth more than the motor mouth "geniuses" whose ability to talk outshadows their ability to get stuff done.

Yep. I think we easily confuse "programming" as being the technical details of mastering and remembering thousands of little details. We find comfort in that. When in fact "programming" is making computers solve problems for people. The computer part and the people part of that equation are equally important. And if you talk about "being part of a programming team" then you're adding in all the social issues of working with other people to solve technical problems.

We love looking at the minutia, but that's simply because we've been indoctrinated to think of the technical part as being the "important" part. These are all equally important. If anything, the technical part is less important than the other parts (ducks). Been a lot of teams full of below-average coders that have done some incredible things. Intellect does not equal impact. Not even close.

Firstly I'd say don't get down about it, my guess is that over a certain level (which you are no doubt at) IQ correlates poorly with success.

What are your soft skills (social, sales etc) like? There is a real sweet spot for people that can span both worlds. That role is a lot of fun too.

Thanks for your words.

Sadly I have really bad social skills.

> I now have found that I lack the fundamentals of Computer Science, the things every programmer should know: Algo's, Data Structures, Operating Systems an understanding of compilers and being profficient with linux.

Sorry, but I'm not proficient at everything of this (especially Linux, maths and algorithms), and still I consider myself a talented coder. I'm very skilled at gluing code together (gluing with skill, not throwing things together). At the end of the day, what matters is whether you can make things work, and nothing else.

> OTOH I have given thought about if programming is really for me, I have found that I'm really, really bad at problem solving and "thinking outside of the box" I have come to accept that I'm really not smart. I'm slow, forgetfull, concepts never seem to stick, I have to force myself to not take things for granted, it seems no matter how hard i try I can't look at problems from different perspectives and understand the implications of a particular solution, I'm starting to think I may have a learning dissability, or that is because I lack the basic toolkit for problem solving, but I really think I'm just not very smart.

I think that before learning to think out of the box, you should start to live out of the box. Join an acting class, especially one where improvisation is stressed (I recommend you find an acting school which teaches Lecoq's method). Challenge yourself to do things you are bad at (in the beginning, I was very very bad at acting).

Try finding similarities between things in different subjects. Read "Neruda's Postman" by Skarmeta to learn what a metaphors are and how to find them. The more different the areas of human activity you'll know, the better you will be at spotting similarities and challenging your ways of doing things.

I lack the fundamentals of Computer Science, the things every programmer should know: Algo's, Data Structures, Operating Systems an understanding of compilers and being profficient with linux.

Relax. That's true for 99% of all programmers.

Eventually I plan on going back to a real University and getting a CS degree

Absolutely not necessary. You will probably learn more building anything than learning it in school.

I'm starting to think I may have a learning dissability

Maybe you do, maybe you don't. Just because the rest of the world is quick to diagnose everything doesn't mean you have to.

I have come to accept that I'm really not smart. I'm slow, forgetfull, concepts never seem to stick

Your performance shortcomings could be for many reasons. Being "really not smart" is the least likely of any of them. They are much more likely caused by other things like uninteresting work, poor environment, personal issues, nasty people, or even health issues. Whether you're "smart" or not, thinking that your aren't is pretty much a guarantee for failure. Please don't do that.

I have started going through the basic Algo's and Data structures again with a basic Java book about algorithms

Sorry to say, but you're just doing it the hardest way you can. You don't need a book; you need a project. I (like many others here, I'm sure) have achieved much, but have always had difficulty learning from books and theory. It's hard! You need to find work where the things you need to learn will be required. Funny how quickly and easily you'll find a way to learn them when you actually need them. I'm not sure how you should go about finding such work, but I imagine many responses in this thread do.

I just don't want to be a cargo cult programmer anymore.

Good. That makes your normal.

And finally trying to memorise all those linux commands I ALWAYS forget.

Then use less commands. I have never used more that 10% of what was available in any technology and I always got the job done.

I have to force myself

This is the most important thing you have said.

Have you ever actually enjoyed building stuff? Have you ever gotten really "jazzed" about the project you were working on? Have you ever leapt up out of your seat and danced when you got something working?

If you answered "yes" to any of these questions, then you really do have the passion to be a programmer. Stop selling yourself short and listen to the great advice you're sure to get here from fellow Hacker News'ers.

If you answered "yes" to none of these questions, then there's no sense for you to continue wasting your time searching for the passion. If you haven't experienced any by now, then you probably never will. No one should have to "force themself" to love what they're doing. Find something else.

P.S. Sorry about your father. Loss affects each of us differently. And don't worry about your English. It's fine. Please give yourself your best chance to succeed and keep us posted. Best wishes.

While I agree with virtually of what you said, the following statement I do disagree with: You don't need a book; you need a project. (in reference to laerning algo and data structures).

There are too many non-trivial algorithms that you are just likely to not rediscover. Many are the result of some of the best minds in various fields over decades. Dynamic programming isn't something that will likely just show up in your code w/o knowing about it (it may, but probably among the more skilled). Balanced trees almost certainly won't. Heck, even standard binary trees probably aren't obvious to someone who hasn't thought about the problem.

And definitely not things like the Fast Fourier Transform or stability of Gaussian elimination, etc...

I'd at least recommend spending a weekend reading a pragmatic algorithms book like Sedgewick, http://algs4.cs.princeton.edu/home/Algs4Flyer.pdf.

Have a project that you're working on too, but don't do it without also learning algorithms and data structures more formally. Otherwise you'll end up finding a lot of poor solutions for problems that have known good solutions.

There are too many non-trivial algorithms that you are just likely to not rediscover.

I agree, but would also (respectfully) ask, "So what?"

OP needs to learn to crawl, then walk, then run. And he seems like a great candidate to do all 3.

Even so, even if he works 30 years having a ball delivering great product to satisfied customers, he may never encounter "Fast Fourier Transform" or "stability of Gaussian elimination".

I think of "advanced" subjects like dynamic programming, functional programming, and even algorithms and low-level code like mountaineers think about Mount Fuji: A coward never climbs it. A fool climbs it more than once.

I haven't written a b-tree traversal in 10 years and hope I never do again. I'd rather stand on the shoulders of new giants and get other cool stuff done.

OP's not there yet. Give him time.

Also, he needs a reason to learn this stuff. "Because I need it for this project" is a better reason then "Because everybody else is doing it and I think I need to, too".

"Because I need it for this thing I'm doing" is the only motivation that ever works for me. That said, taking that weekend to read the book to know what might actually be available for that thing you're doing is also a good thing to do periodically.
Let me echo VivTech. You dont need to memorize all the algorithms and variants, but you do need to know what is there, so that sometime later when you need a solution, you know where to look. Also you need to dive deeply into some aspect such as sort or lists so that you get a good feel for big O notation and analysis. You may never implement a sort or tree algorithm, but is good to know which one to pick when you need it.

I've never had to use FFT, but sorts, trees, and graph traversal are pretty common.

My introduction to algorithms oh so many moons ago was Sedgewick when it was a single volume in C(?). I found it easy to read and use.

The problem is that there are a lot of projects you can go into as a cargo cult programmer, do an OK job, and come out more or less still a cargo cult programmer - you can build a pretty good web site by iterating on tutorials and copy-and-pasted snippets.

If you follow the guidance of, say, SICP, there're "projects" geared to expand your abilities.

So, I agree, but look for the right project - don't learn a framework, learn to do something.

>> There are too many non-trivial algorithms that you are just likely to not rediscover.

> I agree, but would also (respectfully) ask, "So what?"

Well, if you're trying to sort big arrays with bubblesort, you may have to wait a long time...

http://warp.povusers.org/grrr/bubblesort_eng.html

>Teaching bubble sort as some kind of "basic sorting algorithm" has real-life negative consequences. This is a real-life example: this is a piece of code in the gnu flex program:

    /* We sort the states in sns so we
     * can compare it to oldsns quickly.
     * We use bubble because there probably
     * aren't very many states.
     */
    bubble (sns, numstates);
>There's absolutely no rational reason why bubble sort was used here instead of insertion sort. Bubble sort can only be slower, and it's not in any way easier to implement.
Actually for small values of n, an n^2 sort can be quicker than an nlogn sort, depending on how it is implemented.
Yeah, hence insertion sort (the best n^2 sorter) is used to speed up quick-sort. It's insane to think of using bubble sort for the same task. (And for n=2, you don't need a sorting algorithm.)
Yes I agree that there are algorithms that I would have never known about without hitting the books, I came across this recently. I was trying to solve one of ITA software hiring puzzles(Just for fun somebody mentioned it in SO) the "instant search" puzzle, I could never find a solution to the problem I spent days playing with it until I decided to give up, a few months later I found out about "Suffix trees" from wikipedia and found an implementation in Java, I'm still trying to understand about how it works but I used it in the ITA puzzle and the thing actually works and its freaking FAST!.
Was "not knowing" that algorithm preventing you from doing anything before you actually found it? If your goal is to learn for learning sake, then fine go buy some books and learn. If on the other hand, you are trying to build stuff, then by all means start building stuff and learn what you need along the way.
What if the goal is getting hired at ITA Software?
Any suggestions on a book describing algorithms useful for the ITA-style problems? I looked at those problems a while back (just out of curiosity, not to get a job) and realized that I didn't really know how to solve those optimization / approximate-solution-to-NP-complete problems. Is there an AI text, maybe, that would fill this gap in my knowledge?
I'll second the recommendation for Sedgewick's book. The pictures in there are so good that you hardly even need the words, and I successfully learned algorithms from it.

The other algorithms book I would recommend is Steven Skiena's "Algorithm Design Manual", which has less depth than Sedgewick or Cormen et al., but is very well written and has a chapter that's a field guide to most algorithmic problems you commonly run into, and how to solve them. Looking through this algorithmic bestiary is well worth the time. The rest of the book is also good.

I have a smart co-worker who also likes Skiena's Algorithm Design Manual. I found that book to fluffy, though. But then I enjoy books like "Combinatorial Optimization - Polyhedra and Efficiency" by Alexander Schrijver.

(Not a beginner's book, but it has anything you ever wanted to know about P and NP.)

I don't know about the OP or anyone else, but I've always found it easier to learn about a fundamental algorithm when I've got a real problem to use it on, in a real project that's in front of me. The problem isn't one of rediscovery, it's knowing that a solution exists in the first place.
That particular book is listed as being released on March 21 2011. Is there something I'm missing or are you recommending his earlier books on Algorithms in C?
Any of his algorithms books. I believe he has C, Java, and Pascal. But unless you need the book right now, I'd be inclined to wait a few weeks to get this latest edition.
I would argue, both. Pick up a project you find interesting to drive the directions of your learning, and supplement it with book-learning as you go.

For instance, if you wanted to do some game programming for iOS/Android, pick up books that focus on algorithms appropriate to that context, not just a general book of algorithms.

Thanks for your words.

Most of the stuff I've been doing for the last year or so is bug fixing as I have found that I'm better at finding and fixing bugs and even adding stuff to code that is already written and I really get excited when I get something working, It just takes a very long time for me to develop something from scratch mostly because I'm never comfortable with my code and I end up re writing everything and thus never getting anywhere.

Thanks for your words.

Your welcome. Posts like yours often help other people as well, so thank you too.

I'm never comfortable with my code

Neither am I. I don't think that feeling ever goes away. Whenever I look at something I wrote last year, I think 2 things: "I can't believe I wrote this," and "I hope no one else ever sees it with my name on it."

It just takes a very long time for me to develop something from scratch

Then don't write anything from scratch. I have about 2 dozen "base programs". Whenever I need to develop something new, I grab the closest one, "save as" something else and get to work. I'm always tweaking, improving, and adding to those base programs, kinda like automating my own continuous improvement. I'm too busy focusing on my user's dilemma and the task at hand to waste valuable brain space memorizing syntax. Every little boost helps. We all do it.

I have about 2 dozen "base programs". Whenever I need to develop something new, I grab the closest one, "save as" something else and get to work.

That's an interesting method. Could you give an example of those 'base programs'—what are they, how long, how much do they do, etc.

   1. basic form
   2. form with multi-valued lines
   3. form with data set (multi-valued parent/children)
   4. form with grid
   5. tabbed form
   6. form with skins
   7. batch (loop thru something)
   8. batch update selected records in a table
   9. batch dump table records --> .txt or .xml file
  10. batch .txt or .xml file --> update table records
  11. batch file --> create & populate database table
  12. cut an email
  13. traverse internal tree function
  14. traverse file index(es)
  15. build html from parameters
  16. build javascript from parameters
  17. build .pdf from parameters
  18. build hp esc sequences from parameters
  19. benchmark a process
  20. how does that syntax work?
  21. which way is faster?
  22. batch string parser
  23. batch source code search
  24. batch source code changer
I have more, but I don't have time to find them right now. OK, I think I'll add:

  25. batch parse source code, identify routine for reuse
a lot of these sound like they should be libraries.
> I'm never comfortable with my code

I've been doing this professionally for around 12 years (and for the record, no CS degree -- my degree was technical communication with a CS emphasis) and to be honest, I'm still not very comfortable with a lot of my code either.

I generally think that if you don't look at code you wrote six months ago and think "Dear god, what is this crap?" it's a sign you're not learning enough as a programmer, so I wouldn't say that being uncomfortable with your code is a bad thing by any means. The key thing in my mind is if you're always looking to improve.

I'm never happy with my code either. I seem to write parts of it over and over because it just doesn't look or feel right.

I believe that's extremely common and from my experience, most of the really good programmers that I've known do it.

My personal take is that it means you have some semblance of taste, which I think is essential. Otherwise you end up like the people who think "temp1", "temp2", and "temp3" are perfectly fine variable names and who don't think whitespace is an important concern when programming.

There's a video of Ira Glass floating around that I was sending to all of my friends a few years ago, on the nature of creativity and self-criticism.

One of the great points he made was that if you ever finish a project of any kind and think it's really great -- just perfect, and just what you wanted to achieve -- it's time to hang up your hat and go home, because you're done. You aren't going to improve from there, and you won't learn anything new (though there's always more to learn, in any field).

The harsh self-critique just means that your skills still don't measure up to your taste, and if you find yourself doing great without much trouble, that just means you have really poor taste.

I've got a project for you:

In terms of algorithms and data structures, this is about the best that you can get: Given a list of 10k unordered sets of 5 letters (let's say a .txt file, 5 letters per line), print what set occurs most often.

It's much more challenging than you'd expect, and my suggestion would be to implement any sorting that you wish to do, yourself. (not use Arrays.sort, or any library like that).

It's a problem that I was given in highschool, and was pretty exciting.

For an example data set, my suggestion would be to get a random character generator printing 5 characters per link, 10k times.

Would this work as a solution:

i) convert the array of arrays of chars into an array of arrays of integers (the letters ASCII values).

ii) create a new integer array containing the sum of the cubes of each ASCII value for each entry

iii) create an empty hash table and fill it with (key|value) pairs containing (integer|number of occurrences) by looping through the previous array

iv) sort the hash table by 'number of occurrences' and store the biggest (key|value) pair

v) look for the first match in the original array to find which chars it represents

Efficient/correct or not?

First of all, do not ever call yourself "slow" or "not very smart". This is just not true. I haven't realized that English is your primary language until you mentioned it Granted, English is not my native language either, but the point is: if you could get this far with the natural language you're definitely have anything but the learning disability. And having a stable job after dropping out of college is no small feat either.

Algorithms and Data structures. I have CS and Applied Math degrees, but honestly - very rarely I have to recall the inner workings of specific algorithms and data structures. It is useful to know how it all works, but not as important as you may think. You can certainly follow "fake it till you make it" approach: you need to remember memory and time complexities of the data structures and some implications, e.g. "hash tables have asymptotically O(1) search time but may consume more memory than red-black trees that provide O(log(n)) search time but have guaranteed memory and search time constraints". And so on and so forth. So go ahead and read Cormen with that in mind.

Also, my guess is that you need only as much CS as you need to become a better software developer. I don't think you want to be a theoretical computer scientist, do you?

In your situation I would also recommend reading following books:

"Structure and Interpretation of Computer Programs". Honestly, to CS graduate it reads like a book for preschoolers but it is very beautifully written and is almost zen-like. And it will definitely help you understand what programming is about if you did not get proper formal training.

"Design Patterns". It is not a CS, but Software Engineering book. It provides a framework for your software design skills. You can be a great programmer without reading that book, but then you have to be exposed to a lot of beautifully designed code, and that book will save you a lot of time.

Find a popular and stable open source project that is closest to what you are doing now or what you want to do and read the code, look at the build infrastructure, documentation, try to get involved and maybe even fix some bugs, starting from simplest ones and moving up to features. You'll get a lot of brutally honest peer reviews, just don't abuse it.

Hope that helps.

>Eventually I plan on going back to a real University and getting a CS degree, but I'm unable to do so at the moment

Come up with your own curriculum then. Invent homework assignments like the following:

1. Install a linux distribution: http://www.ubuntu.com/desktop/get-ubuntu/download

2. Install the languages you mentioned: sudo apt-get install sbcl ruby

3. Type 'irb', 'python','sbcl' to open interpreters for Ruby, Python, or Lisp

4. List the names of all the data structures and algorithms you've heard of and their operations. Be sure to include hashtables and b+ trees.

5. List the worst\best\average case runtimes for each operation.

6. Describe a practical use case for each.

7. Implement each by typing directly into one of the above interpreters.

You'll learn much faster, always get A's, and not have to spend any money.

OP, if you make it down here: the overwhelming majority of my programming ability comes from doing variations of what the above post says.

I didn't get much education from university, except for the occasional nagging feeling of "I think I covered this in a class once". That usually turns into a Google spree, where I re-teach myself whatever concept I almost-remembered.

I have a sneaking suspicion that this opinion will be unpopular... but it is mine, it's humble, and I'm entitled to it :)

You are stuck being a cargo-cult architecture-astronaut because you are stuck in a language that exemplifies and encourages it. ROR and python, while perfectly good in themselves, will allow you to stay there. My advice would be to take something 'horrible' but useful - PHP springs to mind - and play with it. Do fun stuff just for the hell of it. Do things quickly, not correctly. Correct things one by one and see which things actually make a difference, and which things were a complete waste of your time.

Memorising linux commands? What? Slap! Write yourself a cheat-sheet and remove that excuse from your head immediately. It'll take you 5 minutes. If it takes you longer, you're doing it again. Stop making the perfect cheat-sheet that covers every example of everything you may ever need, and write the 5-minuter that covers 95% of it.

Set a line between the front of what you're doing and the back. In front of the line, everything must be neat, useful and functional. Behind the line you can do whatever you please. The line is the part of the 'achieving things' model that cargo-cults miss - the difference between practice and theory. You might even surprise yourself about your coding ability once you start evaluating things that way.

  You are stuck being a cargo-cult architecture-astronaut because you are stuck in a
  language that exemplifies and encourages it. ROR and python, while perfectly
  good in themselves, will allow you to stay there.
I'd abstract one step up, and suggest it's the environment that's to blame instead of the tools.

At a previous company, I found that there was a not-insignificant number of my coworkers were seemingly-incapable. I originally blamed the people for their lack of skill; later, I moved on to faulting the tools (Java / Oracle / a less-than-stellar in-house "framework"), but eventually realized the problem was with the environment, and nothing else.

A couple of the biggest contributing factors:

* A near-constant state of panic ("is it done yet?")

* The implicit requirement that all decisions had to be routed through at least two stakeholders for confirmation

* Old guard programmers enforcing that things be done the One True Way, despite any evidence that alternate approaches would be better

Early-to-medium-ish into my time at that company, I stuck to my guns and did what I felt was right. I wound up writing toy apps in Rails and Node that changed how the company managed its production and release pipelines. Toward the end, I would constantly question my skills and abilities--despite the success of my toy apps--because I'd been conditioned to do so. I settled into a rut-of-despair very similar to the OP's for a few months.

I quit when I realized what my environment was doing to me.

> I have come to accept that I'm really not smart. I'm slow, forgetfull, concepts never seem to stick, I have to force myself to not take things for granted.

Congratulations! You have just discovered that you have an asset! Forgetfulness, an awareness of one's limitations and an understanding that learning can be challenging are all things that actual newbs are not aware of. You no longer suffer from hubris.

Your newfound recognition of your limitations is the foundation upon which you must build and shore up a structure for acquiring new knowledge, outlining plans which recognize your limitations and executing these plans in a predictable manner.

These problems are the same problems that most programmers (hell, most people) face. This is what the life-hacking movement is about. It is about understanding that we are all human, and that improvement in our lives requires recognition of our weaknesses.

If something is not working for you, what you should do is look for alternative methods to achieve your goal. If you do not absorb knowledge through reading books or theories, perhaps reading code would be better for you, or perhaps you are a social learner and need to talk to other programmers about what it is that they do.

Remember that every challenge is an opportunity. There are even people who have turned their quests for self improvement into niches and businesses in their own right. If you see something that doesn't make sense to you, it may not make sense to other people. If you find a way to make a task easier, others might find it useful too.

I hit the point you're at about 5 years ago. I'm beginning to feel competent and trust my ability to build things. There's a lot more that i want to learn and become better at. It's a long process, but many have tread the path before you, and many will follow in your steps.

G'luck.

This is one of those pieces of advice that hits my face so hard with its simplicity and non-obviousness, it makes me want to cry. This is made my Friday, thank you.
Honestly, this is what people mean when they talk about passion or tenacity or being "an animal" (cf http://www.paulgraham.com/start.html ).

What they mean is that you've got a drive to succeed in the face of adversity. That when you encounter difficulty, you won't become disheartened and lose focus on your goal and instead browse reddit for the next 12 hrs (There's some irony in Y-Combinator being responsible for one of the biggest time wasters on the internet). That when faced with a problem you'll take it head on, or if it's more sensible find a way to go around it.

This is a concept that's both maddeningly simple and insanely challenging.

Read this http://www.andrewmunn.com/2011/01/how-to-land-an-internship-...

about halfway through there is a list of common things even the toughest interviewers in the industry ask about. Read about all of those just to get a good overview. He just talks about interships but those skills will get you fulltime also. Trust me a bunch of people would love to have that guy full time.

Second you have to read yegge. http://steve-yegge.blogspot.com/2008/03/get-that-job-at-goog...

He'll help you fill out most of the rest of what you need to know but most importantly teach you about a subject that will make you feel alot better about what you feel like you don't know. The interview Anti-Loop. Basically two interviewers at a large enough company could interview each other and no-hire each other because of the questions they would ask in an interview but are only there because a third that has different interests interviewed both of them.

Now you've got the basics of what you need to learn more about which is largely data structures and algorithms.

Now you're ready to do some functional programming. learn some lisp. I happen to be reading the excellent Land of Lisp book myself now and recommend that also their is http://learnyouahaskell.com/starting-out. I'm sure there are other free online resources other guys here will point out also

Now you can get into Norvig and SICP and go even deeper.

"Teach Yourself Programming in Ten Years" http://norvig.com/21-days.html

"Structure and Interpretation of Computer Programs" http://mitpress.mit.edu/sicp/full-text/book/book.html

I didn't start with them because Norvig starts out discouraging you ,not that he isn't right about how it will take time to improve just that you will be amazed at how fast you can move when you really want it, and SICP can be really daunting if you start with it.

Also there is a great well of books and tutorials online about all the things you want to learn. Compliers to the cormen book you mentioned. The fact that you tried with that book means you are on the right track and you will get it.

Also I can't forget http://www.topcoder.com/ http://projecteuler.net/

and newcomer http://www.coderloop.com/

Those sites are places to hone your skills by working on coding problems. The biggest thing you have to do is pick some topics/ problems you are interested in and CODE.

You'll be surprise how far you get and how fast you can get there.

Good suggestions. One addition: You should learn Lisp eventually for the macros. But for your first introduction to functional programming (or computing in general, if you have a mathematical bent) choose something pure like Haskell or Clean. They won't muddy the waters with side-effects, or let you escape into assignments.
Agree 100% with topcoder.com algorithm competitions. They're a great way to measure your improvement and challenge yourself to get better.
so far in this thread, there isn't a single post belittling the OP; almost everyone has immediately stated "you're not stupid". i think that's probably the most encouraging thing i've seen all week.
You can't possibly be taking as long as I did; see "my evolution as a programmer": http://lists.canonical.org/pipermail/kragen-tol/2007-March/0...

I'm obviously not in a position to evaluate your IQ, but to me you sound pretty average. If you stick with your determination to get better, you'll be better than average in a few years, because most people don't.

Forget about IQ. To quote someone I agree with:

"Although high general intelligence is common among hackers, it is not the sine qua non one might expect. Another trait is probably even more important: the ability to mentally absorb, retain, and reference large amounts of ‘meaningless’ detail, trusting to later experience to give it context and meaning. A person of merely average analytical intelligence who has this trait can become an effective hacker, but a creative genius who lacks it will swiftly find himself outdistanced by people who routinely upload the contents of thick reference manuals into their brains." (http://www.catb.org/jargon/html/personality.html)