How to seem good at everything: Stop doing stupid shit
jinfiesto.posterous.com
jinfiesto.posterous.com
I think the most profound thing about the post was that it showed a striking difference between determined practice and directed practice. Just being determined and putting in the hours will _not_ be sufficient to pass a plateau of learning. Sometimes you need _directed_ learning to push you past that plateau.
Applying that to code, I think this is the difference between just programming a lot and thinking you'll get better, and actually reading texts, reading code and talking to other programmers to see how other people do things better.
For example, you can start using more anonymous functions in your code because all the cool kids are doing it, but unless you really understand how to deal with high-order functions and what a map and fold are, you are just going to be doing stupid shit that doesn't really help your code at all.
That and practice. My chess improved noticeable with timed play. Putting a time limit on a game forces you to do 'something', if only to stop losing. In my case, this forced me to eventually develop a strategy and focus my game on actually attacking particular areas of the board. This really improved my game.
A lot of what that particular paper talks about is applicable to other languages that have lambda expressions in them.
Some of the examples in it does rely on lazy evaluation though. Laziness is usually encodable in most languages with lambdas. But most aren't lazy by default. Keep that in mind.
In more practical terms, you need lambdas to have closures, currying and higher-order functions in general. Without that you don't have Lisp, ML, Haskell, etc.
I don't think this follows from the article. "Not doing stupid shit" in the article's term is getting better at the basics. When you're describing is directed study but I can't see how it is directed at "the basics of programming", which would have to be something not off-by-one, not using objects before their initialized or whatever is "really simple".
The problem of overcoming bad habits is a really tough one.
In a performance-based skill like Chess or music, you can drill simple stuff to make them perfect. It's hard to see a simple equivalent in programming.
I'm also not sure if there is an equivalent to perfection in programming. All the things that slow me down do look "stupid" on some level but they're stupidity of different levels, from design to variable name to the creation of functions to understanding and avoiding syntax errors.
If there is an awareness drill to educate oneself against bad programming habits, I'd love to find it.
Not that I've done this. I should.
They couldn't say what the difference between functional and object-oriented programing is. They couldn't tell you what a good name for a variable is (maybe they have somewhat good variable names, but they don't really know why they are good or bad). They couldn't properly define an architecture for a new project.
There are basics in programing that should be known before all the programing languages, frameworks and what not. And I think from time to time everyone should try to learn more about the basics instead of a new language. From time to time think really hard why this variable should be called that. Why we need a new package for that. Why is a method built the way it is.
I don't have a copy of "Code Complete", but from what I've heard it's a similar deal. XP arguably eliminates a lot of stupid shit, but arguably introduces a lot of stupid shit at the same time (as do many dogmatic processes).
While "best practice" lists are always going to be controversial (in both programming and music, but not chess), they do have a lot of value if you don't overuse them, and take them with a grain of salt.
It's very interesting to get ahold of a "best practice" book or an organization's SOP manual just to see what battle-tested advice is given for various situations... you may disagree but they embody wisdom. At the very least you can find out where they're coming from.
Not all "bad stuff" is "stupid shit" in this approach. The "joel test" really doesn't relate.
Just about all Chess players know to avoid hanging pieces - the article described going from there to making that understanding habitual. Essentially, the article, if it was consistent, would be looking for some equivalent to musical scales that a software engineer could do practice before actually programming. It is not a matter of knowing best practices but a way of systematically developing the habits to put them into practice.
It is the difference someone telling you not to make a mistake and going over and over doing things to actually get in the habit of not making mistakes... A person can learn theoretically how to play music in a week and if producing keystrokes at the proper time didn't matter, people wouldn't spend more than a week learning the skill. As it is, a lot more practice is required.
But really, I'm pretty sure there isn't a software equivalent of musical scale because software isn't as specific a skill as reading or performing music. Software involves a large variety of logical skills which most adults already have to some degree. It is so complicated on some levels that mistakes are sort-of inevitable on other levels.
This is exactly right. Ericsson and the related expertise psychology literature calls your directed learning 'deliberate practice'. Have you read the _Cambridge Handbook_ or his 1993 paper http://www.gwern.net/docs/1993-ericsson-deliberatepractice.p... ?
The real benefit comes from when you understand the concepts behind map and fold. If you realize that fold is nothing but replacing each n-ary constructor of an algebraic data type with an n-ary function, then you recognize that you can do the same thing for data structures besides sequences, like binary trees, graphs, and ASTs. There you're getting some benefit, because there's no built-in language syntax for iterating over those.
data List a = a : [a] | []
[1, 2, 3, 4] = (1 : (2 : (3 : (4 : []))))
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr (+) 0 [1, 2, 3, 4] = (1 + (2 + (3 + (4 + 0))))
foldr (*) 1 [1, 2, 3, 4] = (1 * (2 * (3 * (4 * 1))))
...by extension ...
data Tree a = Leaf a | Branch (Tree a) (Tree a)
foldTree :: (a -> b) -> (b -> b -> b) -> Tree a -> b
foldTree f g (Leaf x) = f x
foldTree f g (Branch x y) = g (foldTree f g x) (foldTree (f g y)
Then you recognize that the GoF calls this the Visitor pattern, because certain stupid languages don't have higher-order functions or algebraic data types, and so you need to make the equivalencies between concrete subclass => ADT constructor, Visitor => function, and object state => return value. Suddenly a lot of modularized compiler libraries (eg. LLVM) make a lot more sense.Then you realize that a map is nothing but a list-fold where the binary operation is constrained to be the composition of some arbitrary function of the element together with a cons operator:
map :: (a -> b) -> [a] -> [b]
map f = foldr ((:) . f) []
The cool thing about this formalism is that it makes it explicit that f depends only upon the single element of the sequence, and that the ordering of the resulting list is independent of the actions of f. In other words, map can be parallelized. And that lays the groundwork for MapReduce, which lays the groundwork for massive-scale parallel data processing.Pretty much the opposite of the (true but trivial) concept that ordering of the result is independent of the map function.
TL;DR What you wrote at the end sounded a bit analogous to saying startups succeed because of their idea, while they succeed for a number of things -- mostly the execution and how much other people like the idea in the real world.
The general point is that you aren't going to succeed unless you understand those building blocks in enough detail that you can take them apart and put them back together again in new ways. Map & reduce are concepts from functional programming, usually explained in Scheme or Haskell. MapReduce is a C++ framework. To go from one to another, you not only need to understand the nitty-gritty engineering details, but you also need to understand the fundamental computing concepts well enough to translate them into languages and use-cases that they weren't originally intended for.
(Side note: the MapReduce framework actually bears less resemblance to map & reduce than most people think. The "map" phase is a combination map & unfold, because you're not only iterating over the input, but you can output multiple times for a given input element. Think of running a word count over web pages: you have to parse the page and output multiple words per page. And the "reduce" phase is only a reduce within keys: it's really a map between keys, because the output is required to have the same keys as the input to the phase. I've often wished for a separate "re-key" phase, where the values output from the reduce phase could be reshuffled under a different key.)
To avoid misunderstanding, I'm a fan of functional programming too. But the intersection of the MapReduce framework and map&reduce of Scheme and Haskell is mostly in the name and in some core math concepts that are ageless (predate programming and lambda calculus).
I think that the mechanics behind this consist of what is basically, to borrow a term from comp sci, an impedance mismatch between our internal maps of the world and the shared maps we call physics or math or piano technique. We tend to organise things in a particular way so that we can communicate about them with each other but this shared set of symbols is never the same as an individuals' internal representation. I think that the reason all internal maps are different is because the subject (the human) is an integral part of them. In other words, one's understanding of gravity will have shared symbolism with completely subjective experiences that have nothing to do with gravity. The process of learning is essentially a mapping of one set of symbols to another. More accurately, there seem to be three levels, the experience itself, the internal symbols relating to the experience and the external shared symbols we use to communicate with each other. Based on this, I think that the categorisations in the shared map rarely make sense internally and that, as a layman, following the lines drawn by the categorisations doesn't make sense, hence the roadblocks that people encounter.
To put it another way, the categorisations we have in our shared knowledge are primarily for communication purposes and are, objectively speaking, irrational. Separating math from physics from music does not make sense in real terms since they are different perspectives on the same system. Or, to put it yet another way, the map is not the territory and those who understand that are much more adept at navigating with maps.
All you have to do is not disqualify yourself by being stupid or obnoxious.
The idea that you have to be the most dazzling job cantidate or the most amazing romantic partner to succeed in these areas probably holds people back a lot. In my experience if you don't do anything overtly stupid, the other party will subconsciously fill in the blanks so that you match "what they were looking for".
Regardless, it's still like a sport - if you don't make unforced errors, you will be more likely to succeed.
Consequently practice does help. You're better at dating if you go on more dates. You're better at interviewing if you get more interviews. Practice allows you to "not make silly mistakes" unconsciously, which frees up your more creative side to show the best you.
and btw, first dates are great!
Quite the contrary actually: leaning back, having fun and "being yourself" is sustainable because you don't put on an act.
I'd say 90% of the stupid things I do are because I wanted to do something new or risky and as such I have a neophytes mind. Sure, when I start to hit an intermediate level I can then self-analyze and make that jump from average to 'sometimes good' but I can't do it all the time and I sure as hell can't do it in the beginning.
So lets look at interviews. I've been on a few. I've played the ultra-conservative role of being super-careful and treating them like I'm on trial. That approach doesn't seem to work. I've recently played the role of someone who is very socialable and even tells a joke or two and other "stupid" behaviors
Hey, you know what? It turns out most humans are far, far from these rational logical creatures. They aren't thinking "Lets fill this position" they're thinking "Lets hire someone I can work with who doesn't seem like an overserious ass or a nut and has at least the basic competency to understand the job and learn more." Geeks of the world need to understand the great importance in social skills, risk taking, socialization, understanding social culture, etc. The idea that we can just solve everything by being super careful and super critical of ourselves is not a smart strategy.
I dunno, man. I graduated last month. 9 interviews in the last 2 months. Finally landed a job, so I guess I can talk about how the other 8 went. Honestly its not so simple as you describe. There is definitely a supply-demand dynamic at work. Too much supply. Literally too many sailors and too few ships. Every university of repute ( Courant, UCB, MIT, Princeton, Stanford, UChicago, CMU, Columbia, Cornell ) and the 2nd-tiers ( UMich, Rutgers, UToronto, Baruch, Boston ) together graduate some 1500+ solid quants each year. That's 1500 people with a Financial Mathematics Masters, in addition to C++ programming, whether via BSCS, MSCS, or PhD ( several PhDs in my pgm ), with typically another 1-2 graduate degrees thrown into the cocktail! I used to think with 3 Masters I was in a good spot, but I realized I was actually in the middle/bottom tranche. There are many people ( some 25% of class ) seeking a Masters in Financial Math who already have either a Physics PhDs or Statistics PhDs or ofcourse pure Math PhDs ( aka God ). So they get this science/math PhD, realize academia sucks, then head for a financial math degree, then get a C++ certificate ( there's a mini industry minting money off of "C++ certification for quant") and then show up at the interview. A first-timer ( ie. one with just Financial Math & C++ ) has zero chance. These are not the only ones you are competing with. You also have insiders ( people with MBAs and CFAs and 5 years at an IB/PE ) who may not do very well on the C++ or the math, but their experience at a trading desk gives them a huge edge. IBs surely cannot absorb 1500 bodies year after year. So the interviews are super-technical and nobody wants you to succeed. I wouldn't say I was stupid/obnoxious at 8 of the 9. 2 of them said I was "clearly overqualified and would quit in 3 months out of boredom" ! Some others were "not a right fit" type ( too much programming not enough math or vice-versa) , but there were a few hedge funds where I felt Boy this is my dream job but they were technically off-the-charts. The questions were goddamn hard. And the math was hard. Write C++ code for pricing a barrier option on an instrument with some specified parameters where the volatility is stochastic ( ie. use Heston's volatility model to price a barrier call. ) Now that's not the sort of stuff you look forward to without a stiff one. A classmate was asked to walk through a SABR and a GARCH and asked to explain in detail which one would be a better fit for a certain class of fx bonds and why. While the programs give you a good overview of everything, that is also their flaw - they give you detailed knowledge of nothing. So you have to have mandatory side projects to succeed. I had written a few thousand lines of java to price condors & written an optimizer over the holidays, so that was what got me my job. But even that wasn't sufficient. Walk me through your code. Did your model actually make you money ? How much money ? Did you make money because of your model or because of the view of the instrument ? I mean that stupid side project suddenly took a life of its own and became like a real production system which should jump through all sorts of hoops and make money from day 1! There was much more relief than happiness when it was all over and I got the job.
Bottomline, right now there are simply too many good candidates and too few positions. You have to be really really smart and lucky. Stupidity and obnoxiousness is a very trivial filter - most will get past that pretty soon. What happens after that is what counts.
It's a pretty common idea among traders as well. One of the fundamental teaching examples is why it's better to avoid a loss than make a gain:
Say you start with $100 and take a 50% loss down to $50. Now, what percentage gain will it take to get you back to $100? Many people new to the game will unthinkingly answer a symmetrical 50% gain, but of course that's wrong. To get from $50 back to $100, you need a 100% gain.
For every loss, getting back to even requires asymmetrically more % gain. I imagine poker players are very aware of this harsh fact as well.
There's even an old misquoted Japanese/Chinese proverb that hints at it - If you sit by the river long enough, you'll see the body of your enemy float by. Implying the power of doing nothing and letting your adversary shoot themselves in the foot. (http://news.ycombinator.com/item?id=1225153)
Of course, it's very frustrating to make a "simple" error in a game of chess that might have already taken up a couple of hours of time and which may lose the match for your team, which represents a large geographic region.
But after a lot of reflection it became apparent to me that this kind of frustration is very much an inherent property of the game of chess.
It turns out (once you play enough games and get pretty damn good at it) that it's actually quite a limited and simple game. Once you're down half a pawn or so there aren't many possibilities to generate a counterattack on another part of the board to make it possible to win without relying on your opponent making a subsequent simple mistake.
I did play quite a bit of Go at university and for a while I was confident that I could get good. If I'd stuck at it I would certainly be a low-ranking amateur dan by now but I decided to spend the majority of my spare time learning more about IT.
One reason for my early enthusiasm in the game of Go was because it's such a complex game it's not really clear when a "simple" strategic error has been made. Perhaps more importantly, because both players experience much more difficulty choosing moves than in chess, there's usually a reason to play on when you've made a mistake even when playing a highly competent player.
This has been a long reply. I'm trying to illustrate that the secret to seeming good at everything is to participate in activities which are intrinsically difficult and where your intelligence will have the chance to shine through rather than to participate in activities where one foolish blunder can allow a person of much lesser ability to beat you.
On another note, I've never really grokked Go. The rules seem so simple I'm never really sure if I'm playing right. Additionally, It's really difficult for me to evaluate a Go board and see who's winning. On the other hand, I've never invested much effort in understanding Go.
I do not find this to be the case. Even with games involving the top few players in the world (rated 2700+ FIDE) you will often find that players come back from a computer evaluation significantly below -0.50.
Also, you can be at a significant disadvantage and still be able to draw the game. It is really rare that one mistake can decide the game. -0.50 is well within the drawing range.
"One reason for my early enthusiasm in the game of Go was because it's such a complex game it's not really clear when a "simple" strategic error has been made. Perhaps more importantly, because both players experience much more difficulty choosing moves than in chess, there's usually a reason to play on when you've made a mistake even when playing a highly competent player."
On the other hand, chess endgames can often stay up in the air for a really long time, with two or even three results possible. Go endgames (almost by definition) consist of both players grubbing out a point or two here and a point or two there, with all group life and death already decided, so it is rare that the game is decided late.
(If it helps ground any of my assertions, my USCF chess rating is 1870 and my AGA Go rating is 4 kyu. I don't know whether I would certainly be a low-ranking amateur dan by now if I had stuck with it.)
By the way, I note that Josh Infiesto does not appear in the USCF rating list, so either he did all his playing before 1991 when they started keeping computerized records, or his games in which he wiped the floor with 1500-level players were informal non-tournament games.
edit For the record, I haven't engaged in any serious study of chess end games. I'm not really qualified to comment on how end games might evolve.
This is the point of TFA... if you want to get really good, stop blundering. Until then you're making excuses. You've chosen other pursuits "rather than to participate in activities where one foolish blunder can allow a person of much lesser ability to beat you."
You've selectively defined ability to not include things you don't think are important-- but they do matter objectively.
Hope this doesn't sound harsh. We all do that.
In the chess example, I reconfigured the 'don't do stupid shit', to something like, a) Open with an intent, b) Don't lose pieces without purpose, and c) Do everything for a purpose. I wanted to add this information to the thread, because I think the 'don't F up your shot' croquet analog includes a more explicit sense of limiting your actions based on your ability. In croquet, all the theory and mental prowess in the world is sacrificed if you can't execute the ideal shot under the circumstances. This is acknowledgement of your current ability is what I think applies to much of programming (and life).
Note that I am NOT suggesting that you avoid moving your abilities forward. However, focus a lot of effort on knowing what you know, and learn how to use it well. The more you use it, the more you learn and expand on that skill set. The more carefully you use what is within the realms of that skill set, the fewer mistakes (and the more successes) you will have.
I use similar rules when investing, playing poker, and in competitive video games. I'd phrase them as:
- begin with a goal in mind
- take deliberate actions (that you are capable of) that advance you toward your goal
- don't give up resources (money, chips, pieces, hitpoints, etc.) unless that advances you toward your goal
Also, your definition of 'stupid' is going to change throughout the years. You shouldn't be afraid of trying something new now because you might realize in a couple years that what you were trying to do was stupid; doing it is what helped you become a smarter and more experienced person.
I know this wasn't actually the point of the article, but it seems like the 'don't do stupid shit' motto could easily be taken too literally into this interpretation.
Still better, in my opinion, is: "work on your weakness".
My hobby is Olympic weightlifting. In Oly lifting brute strength can take you only so far, to succeed and progress you need to constantly work on technique.
And the only way to improve technique is to identify something you're doing wrong at the moment and to break that habit. It takes time, effort and buckets of hard, horrible work; but at the end your performance has been consistently improved for good.
If on the other hand you stick only to what you're good at, you will inevitably peak. I am very good at back squats. If I'm not consciously trying to work my weaknesses, I will do buckets of back squats and get strong at them.
But what I ought to do instead is work on getting under the bar faster, or work on my second pull, or work on foot placement during the jerk, and so on. If I put the bulk of my effort into these, I will progress much faster and further overall than any amount of squatting will grant me.
Having an excellent teacher to see and explain those things puts you at such an advantage over someone stuck with a less experienced or educated teacher. I like to think that theses lessons can help carry over into the startup world. That is (in sum), technical execution and winning are the only things that matter.
It's unfortunate (or perhaps a blessing in disguise) that there's no real "Teacher/Student" analogue for CS. On the other hand, the Programming/CS community is far more open about sharing information than some of the other communities I've been in. The piano community for instance is in general somewhat secretive. Ideas about piano playing seem to be passed down from generation to generation. Near the top, the techniques for obtaining "excellent playing" seem to be well agreed upon. As we get closer to the bottom, lots of misconceptions and disagreements seem to surface.
In the programming community, while there are obvious camps, since information is available so much more freely it's vastly easier to make informed decisions about what's stupid and what's not.
Of course this sounds easy but it's not.
Making the decision is the hardest thing anyone can do. It comes with consequences, both good and bad. Consequences in potentially eliminating the fulfillment of needs you may have or possible coping mechanisms you have grown into. When you make a true decision you cut off possibilities.
Raising your standards necessitates making a 'real" decision and cutting off options. Sometimes doing stupid shit is the only way some people know how to wrap their head around the f*cked up things they have come to understand.
I know negative comments are frowned upon but I just wish these knock-off quasi-zen bullshit articles didn't bubble up to the HN twitter bot so often. I'm irritated because I took the time to read this assuming that the author was going to deliver something useful and that wasn't the case, it was just a bunch of hot air. "Succeed by not failing." Very good.
I'd like to give the author full marks for marketing. Provocative title, slick design, little substance... he ought to get a job at Wired!
The article is a bit dated today, but I think he's still got a point:
http://www.joelonsoftware.com/articles/Stupidity.html
For every other software company that once had market leadership and saw it go down the drain, you can point to one or two giant blunders that steered the boat into an iceberg. Micropro fiddled around rewriting the printer architecture instead of upgrading their flagship product, WordStar. Lotus wasted a year and a half shoehorning 123 to run on 640KB machines; by the time they were done Excel was shipping and 640KB machines were a dim memory.
Poker is unusual in being so strongly a game of incomplete information. A top professional may only have a few percent advantage over a complete novice, so skill is rarely evident in the short term. Identifying leaks is painstaking in poker because even in hindsight you are rarely sure of the right way to play a hand. Even over a long session at the tables, a player can do everything right but lose, or play terribly but walk away with bulging pockets.
I think that poker theory has a great deal of relevance to entrepreneurs. The mental fortitude required to invest money in an uncertain outcome based on partial knowledge is an overwhelmingly important skill in both.
Two skill types:
A. Doing something fairly simple perfectly, plugging even the smallest mistakes.
B. Doing something that is very, very difficult as well as you can - ie, doing it at all. Doing your best to simplify situations that have a potential to become even more complex while still managing great complexity and accepting that you will make mistakes (and guarding against and finding those mistakes).
Notice, the difference between a very good programmer and very bad programmer is absolutely not a few percentage points. Poke and music are each more like skill A whereas programming is more like skill B (though these classifications are of course quite rough).
It seems like if we aren't distinguishing the skill type here, we will wind-up just tossing out vague cliches. "Don't mistakes, dude".
There's an analogy here for both authors and software developers.
That's what your piano teacher beat into you (not out of you). That's what those chess drills taught you.
Fundamentals.
Fundamentals are never taught properly for anything.
I say this a programmer, a former music student (university level) and someone who's learned alot of shit.
If you keep practicing the wrong way, you'll never improve.
I can't count the number of times that I've seen developers (or classmates) try really complex things without understanding what's going on underneath, and then not be able to understand why it doesn't work.
You have to know what you're doing wrong, so you can stop doing it.
The post speaks to me as 9 out of 10 amateurs are out there doing stupid shit almost every swing - trying to hit the crap out of the ball at the expense of basic fundamentals (primarily balance), attempting miraculous shots when in trouble only to put themselves in more trouble etc. I was one of those dudes not too long ago (and still am sometimes), but recently tried to 'stop doing stupid shit'. It is unbelievable how quickly your scores can drop (that's a good thing for those who don't play) by accepting the predicament you have put yourself in and playing the next shot with intent, focus, and generally being smart about it.
I never thought of consciously applying this thinking to startups/programming but it's completely doable and probably effective.
If you don't try to hit the ball too hard, just get it back in-play -- you'll beat everyone who's worse than you, everyone who's as good as you, and half the guys that are better than you.
However this is not exactly what the OP is about - I think author's point is to cut off things that doesn't work, and stick to those who do; it's about optimizing your learning methodology.
Also you can do really stupid shit, like browsing reddit all day long (which was my first thought when I looked at the title), but that's different thing, and it's quite obvious that it won't lead you to success.
It is very interesting in how he is focusing on "reaching goals" instead of "looking good" or "looking stupid" etc...
I think a must read for everyone
I think about how much this applies to middle management sometimes. Are you doing to do stupid shit that others ask you to do even when it is wrong, or are you going to demand the right approach and build a reputation for at least trying to always do the right thing.
E.g. saying yes to a ridiculous deadline that you know your development team can't possibly hit is stupid shit. Say no.
Though it is mentioned in the article, I think it doesn't get as much attention, the most important part to this little piece of advice for someone learning something new: Learn what you should not be doing as well as what you should. (People usually focus on the later and not the former) ... A great tip for educators too.
don't do stupid shit means nothing. why would anyone want to do stupid shit? This kind of the same meaningless wording that everyone thinks applies to them in horoscopes how many times have you read "doesn't suffer fools gladly"?
It's stupid to be absent, either physically or mentally, from your own life. Whether this be not being "awake" or late during a meeting/class/work/date or not preparing places to show up to.
The recent presidential election comes to mind.
Another mistake is to put on a position and then watch it drop without limit, insisting that you're "right" all along and the market just hasn't seen it yet. Better to have a stop-loss and bug out of the position the minute the market judges you wrong. You can always put on the trade again later.
I really didn't even have to mention that second point, since it's already implied by the Kelley criterion. If you're trading without a stop loss, then quite simply you're risking the entire amount of that position and you can calculate Kelley accordingly.
"Stop losing money" is rule number one. Remember, if you lose 50% of your capital, you have to double your money just to break even again. Better to lose only a percent here and a percent there, and occasionally hit a 10% gain.
You can also consider trailing stop losses, which also fit under the Kelly criterion if you count unrealized gains as part of your overall capital.
People will give tons of various anecdotes on this, but they apply to them, not you. The stories they tell are just the scorched remains of a unique learning experience that can rarely be communicated verbally.
Keep doing things that seem interesting and hard. Don't be afraid to do stupid things. Everyone has to do a stupid thing at least once to learn from it. Identifying and eliminating your own stupidity afterwards is what will make you good.
Whether you identify the stupidity yourself, or has it pointed out by some helpful master is up to you. Both work.
TL;DR: http://ed-thelen.org/comp-hist/samp-IBM-think-sign.jpg
> "If it's not broken don't fix it."
Definition of stupid shit is relative though, what's stupid in the codebase today may not have been so stupid 3 years ago. What might look stupid upon first visit might actually be the only reasonable way to solve the problem.But then there's other stupid shit, hacks for quickly solving a certain edge case. For example abusing Java type erasure and collections.
Other stupid shit from experience is avoiding risk of "new" technologies, (Still on CVS).
In short, being lazy when you know better.
There's a reason StackOverflow is so popular - it makes it easier to find the 'well trodden paths' ("correct way") along with someone pointing out caveats.
I recommend video taping yourself during skill execution and then asking an expert to review it for you. You will be amazed at how many mistakes you are making and also how easy and straightforward they are to correct once you are aware of them.
This is helpful for everything from sports to dating to programming.
And because I'm always scheming, many savvy internet marketers are allowing people to upload videos of themselves practicing niche skill X and then hiring a coach to review them. Some cool HTML5/Flex software on a CRUD database could be a big hit here.