I'm a cargo cult programmer, help me
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 ] threadYour 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.
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".
But since you've found something that fascinates you, go for it!
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.
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.
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.
I have already installed linux as my primary OS at home, I still have to stick to windows in my job though.
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!
Do not feel down about feeling stupid or inadequate, just keep working in a reasoned manner towards your goal.
You will get there.
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:
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.
Of course the skills you learn are more sys admin / OS concepts than fundamental CS concepts though.
I'm currently using Ubuntu as my primary OS at home but I will give Gentoo a shot.
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 :)
He could even do it from his current Ubuntu install.
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
They both can deliver you to about the same point on install (Gentoo stage3 install).
Probably something like "Linux From Scratch" http://www.linuxfromscratch.org/ would also be a good way to learn the important details.
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.
http://norvig.com/21-days.html
"Structure and Interpretation of Computer Programs"
http://mitpress.mit.edu/sicp/full-text/book/book.html
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.
After working through some of SICP, would you recommend then using Scheme for practical projects?
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.
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.
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.
Thanks.
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
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.
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!
And yes I really think I need a mentor, just haven't found one yet, or haven't looked hard enough.
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).
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.
I agree with you that formal education is valuable when you lack direction on "how" and "what" to learn as you stated.
http://www.youtube.com/user/UNSWelearning#p/p
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.
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.
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.
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
I tried reading that Godel book and I couldn't wrap my head around it, I will give it a second shot though.
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.
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...
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.
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.
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.
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
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.
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.
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.
Sadly I have really bad social skills.
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.
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.
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.
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".
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.
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.
> 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...
>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:
>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.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.
(Not a beginner's book, but it has anything you ever wanted to know about P and NP.)
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.
This site is probably has a more extensive list, but it seems to be down right now: http://www.itl.nist.gov/div897/sqg/dads/
Google's cache of it is only 2 days old, so it's probably temporary.
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.
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.
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.
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 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.
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 just died a little...
Look around a bit, you'll die some more. No, a lot more.
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.
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?
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.
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.
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.
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.
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.
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.
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.
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.
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.
"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)