Ask HN: Can you be a good programmer if you are not details oriented?
I am not naturally detail oriented. Some of my colleagues can easily find differences between nearly similarly looking pieces of code. I waste a bit of time trying to fix the errors caused by my detail blindness. Does this improve with more experience?
26 comments
[ 3.9 ms ] story [ 57.2 ms ] threadWhen you're first starting out, you are spending mental energy all over the place. Over time, especially with conscious exercise, you become honed in on the places where important details often lie.
My detail-orientation varies widely. At work/in code, I have incredibly deep focus and can spot small details that are amiss. At home, my wife can ask me to clean up the kitchen counter, and I can't find what she's objecting to. :)
In the meantime you should pick up a few organizational practices. For example before starting a tricky piece of code I like to list out as many edge cases as I can think of (this is like TDD, but you don't get tests at the end). Or when you're trying to debug something make a list of every scenario you can think of that will lead to that bug. In time this will sink in and you'll automatically know where to look when something unexpected happens.
Some of the details oriented work is actually just habit, I can spot tiny issues in Ruby, but I need a diff to figure out Go code. Tools help a lot too.
I think when I say "I am not X" I unconsciously blame it on my nature and see it as something that I cannot correct and have to live with. A subtle change in attitude about yourself can go a long way.
An entire system can go down because a single bit which should have the value 0 has the value 1, or vice-versa.
However, everyone has problems with details to some extent. Otherwise, we wouldn't have software defects. A reasonable software development process does not rely on hiring perfect people who take care of every detail and never make a mistake. (By saying which I don't intend to blur the distinction between missing a detail, or getting a details wrong.)
Alan Perlis once wrote the following epigram, #32 out of many:
"Programmers are not to be measured by their ingenuity and their logic but by the completeness of their case analysis."
That's the important thing: getting all the cases right and not missing any.
I'm reminded of a recent article about grandmaster chess players - when briefly shown a chess board with pieces that were laid out in a reasonable way, they were later able to recall them exactly with ease. Non-chess players were generally unable to recall them at all. When shown chessboards that made no sense (strange configurations, etc), the grandmasters were not any better than non-players.
I think that if you're relatively new, this sort of thing can be difficult, but the more you work with code, the easier it will become. Common patterns become "more of the same" and you can start to notice minor details relatively easily.
Another point is that teams are ideally made of people with complimentary skills and mindsets. Try to be the best "you" instead of trying to be as good a "Jim" as your coworker Jim. Bring something to the table that Jim isn't so good at. Even if Jim is awesome, there's probably something that you can do better. Even if it's a "soft" skill like ferreting out hidden requirements or something.
So, you might get better, or you might just find that other people seem to enjoy working with details more than you do, and that's often okay too.
Ultimately you will develop a sense of "code smell". A quick glance at some code will give you an impression of it likely being right or having problems. (For example lots of variables and control flow is more likely to have bugs. Seeing lots of zeroes and ones points to off by one issues.)
For example I've been programming for 20 years, and with my favored languages I don't see "details" of the code at all; I mainly think in indentation shape and huge code block pattern recognition, with the internals of the patterns abstracted away and irrelevant. "Oh, this is just a request handler that reads a file."
By sheer weight of experience I'd classify myself as a pretty "good" programmer, but I don't consider my programming style to be "details oriented" at all.
Summarily I would suggest that a programmer worrying about being "details oriented" is a lot like a fresh lawyer agonizing about the fit of their suit. Stop worrying about it.
So practice, practice, practice!
My second piece of advice is to just slow down. I don't know if you're a fast coder or not, but in my experience, any problem can ALWAYS take another hour or two (or day or two!) to ensure that it's done perfectly. It takes far less time to do it right the first time than it does to "hack it in and fix it later." Slowing down also means that you spend more time on the details -- and your detail spotting gets better!
Good luck.
If a reference can possibly be null, check it before you use it.
When comparing things like URLs and URIs that are supposed to be functionally equivalent regardless of case, use a case-insensitive comparison like string.equals("a", "A", StringComparison.InvariantCultureIgnoreCase) or even "a".ToUpper()=="A".ToUpper(), rather than the default "a"=="A".
The Javascript === vs == shitshow.
Floating point equality without an epsilon value.
Remembering to put in the # or . prefix when trying to select an element by id or class in css/jQuery selectors.
Understanding when database calls are actually triggered using your ORM of choice.
Using thread-safe containers when collections can be modified on one thread while they are being iterated over on another.
Treating rm -rf with extreme care.
After you run into an embarrassing bug that makes you look incompetent because you failed to account properly for these things, you develop a certain amount of OCD about it and internalize the checks. At least you should, or else you just end up making the same mistakes over and over. Of course, things can always fail in new and unexpected ways, so you are always adding to your corpus of fail.
As a last note, an incredibly help for me has been using static analysis tools that are built into tools like Resharper, Webstorm, IntelliJ, (basically anything made by JetBrains), Javascript linters, etc. You can offload a lot of the burden of correctness checking for the more trivial errors and gotchas to the machine, and focus on higher-level issues.
Many writers have a miserable time proofreading their own work--and it's this way because they already have a strong mental model of what they wrote. When our brain already has a strong model, it can hide a lot of detail from us. It's really just trying to help free our attention for _new_ detail, but in cases like this it causes problems. I suspect you're having trouble finding these minor issues in your own code, and I also suspect you'd find them more readily in code you aren't familiar with (if you're proficient at reading code you didn't write--itself a muscle that must be developed.)
My perception is that the biggest component of developing the ability to proofread my own writing was learning to edit other people's writing in a very exacting manner. Other people write differently than you do; when you edit them in an exacting manner, you're strengthening processes for applying arbitrary rules, deciding which arbitrary rules are worth enforcing, and building your own sense of style. When you just do this to yourself, it can take longer for you to develop strong opinions, because you aren't forced to encounter all of the mistakes and tics other writers make. Getting pissed off at all of the annoying shit other writers do will provide both the eye and motivation to attack your own writing with a scalpel. Learning to admire perfect pacing, metaphors, structure and word-choice will slowly prepare you to realize when you fall short. From there, it can help to apply what you've learned to older writing that you're less familiar with; the gap you need to read yourself clearly will shrink.
In programming, I think the most succinct analog to this process is refactoring other people's code (note: I didn't say rewrite. Avoid that temptation.) Likewise, it's also really useful to refactor your own code once it has become unfamiliar; you'll both realize how you've grown, and identify some of your own annoying tendencies. When you invest time in activities like this, you're building strong models of where things should be, and how they should be done. You'll cope with common problems, and develop a sense of how code can be written to make those mistakes harder to make in the first place, and easier to spot when you do.
I realize I haven't said a word about finding stray semicolons or an errant bracket, yet, but my point is: there are classes of mistake that are much easier to find when you're reading like an editor than when you're reading like a programmer.
Probably the best thing you can do is seek out code reviewers, as they find problems (and they will) try to become aware of patterns in your mistakes and then focus on eliminating those.
[1] http://www.osnews.com/story/19266/WTFs_m
I've been programming for over 20 years and I've come to think the two most important factors contributing to a "good" programmer are communication skill and attention to detail (both of which can be learned, though some seem innately good at both at the outset).
For example: let's say you are reviewing someone's code. You notice they've missed some null checks, haven't properly handled exceptions or ignore some failure cases, aren't doing object comparisons properly, etc. They insist the code works fine (if you're putting up untested code for review, you should be beaten), but those little things now consume the reviewer's valuable time and head-space when they should have been sorted out before the review was ever posted. As the reviewer, you get caught up in an endless stream of niggling little details and nitpicking, rather than focussing on the logic and design and structure of the code. Meanwhile, the programmer feels very productive ("hey, I've just churned out a whole new module") and moved on to the next task, essentially relying on everyone else to finish his job.
Missing some things like this now and then doesn't make one a bad programmer, but consistently neglecting/forgetting them implies a lack of attention to detail and makes me wonder what else they're missing that I'm just not seeing (slog through several hundred lines in a code review and you will inevitably start missing things (http://www.ibm.com/developerworks/rational/library/11-proven... )). It also creates a lot of busy-work churn for the whole team that has to deal with that code. They may seem to be very productive, but they're actually dragging down the overall productivity of the team because everyone else has to point out the little things that were missed, as well as most likely re-review the code once all the small-detail changes have been made.
EDIT: fixed link
So based on personal style, it's possible to get better by walking a middle path of not too crappy and not over-crafted.
(The real work is the stuff that needs doing or somehow seems "most important.")