According to the Dreyfus model of skill acquisition, as you progress from novice to expert in a particular skill, you learn when to "break the rules" and rely more on using judgment and intuition based on the context of the particular problem being solved.

This type of expert behavior comes up in Stack Overflow podcast #53, when Will Shipley describes how he has developed an intuition about which types of changes are more likely to break the code. (as an example, he mentions how he fixed a memory leak, and knew that this change would break something, but he didn't know what, and he discovered a resulting bug about a month later). Based on his intuition about which changes are likely to just work and which ones are likely to result in bugs, Shipley feels that he does not need to rely on a rules-based approach such as achieving a certain level of coverage with automated unit tests.

What is an intuitive programming skill that you have developed over the years, where you are able achieve better results by knowing when to "break the rules"?

+6  A: 

Seeing code as a whole has helped significantly.

The more you look at code, the better you can read it as a language in itself, without having to translate it into English (ala The Matrix, "I don't see the code anymore... just blonde, brunette, redhead..").

When you can achieve that, you can think about your application as a single entity, rather than individual lines of code, and can 'feel' which threads of the story you're telling link up to other threads in other places.

I agree. This visuality is in my opinion understated nowadays. Most people I deal with seem to be pleased in fixing this-and-that and having about the scope of what they can see on the screen at once, instead of seeing the whole code at once.Personally, I need to do print-outs of the code, and read them on paper, to get the big picture.
I wish I could get you more up-votes. Being able to understand code at a level like one understands language is a fantastic (and incredibly rare) skill.
Adam Sills
+4  A: 

In selecting items for Unit Testing.

I think that most people would agree that striving for 100% Unit Test coverage is counter-productive. Where experience pays is in thinking through a new feature or architecture and knowing where I have to really bite the bullet and create a full suite of tests. That is, knowing intuitively that a particular function or module is particularly dangerous or subject to change in ways that incur substantial risk.

Mark Brittingham
100% coverage of what? If you mean code lines, or the state of the program, I agree. But it's not too hard to make close 100% coverage of public methods with a couple of different combinations of parameters. Using TDD, that's kinda a necessity even.

I've only learned so far that breaking rules results in regret later. For a while I can think that I managed to be smart and create something workable in less time I should have but later it'll be back to bite me.

+3  A: 

As a seasoned Perl programmer, I learned that the rules were made to be broken. :) Despite Perl's many criticisms, I think the experience did help me to look at problems in different ways and see more than one solution (Perl's motto is "there's more than one way to do it" - among others), which has been helpful in other languages and overall helpful in being able to easily acquire new skills and languages on the whole.

Breaking the "rules" is what allows for beautiful syntactic sugar and clever programming techniques including reflection and AI. If we never "broke the rules" we'd still be using punch cards, no?

+4  A: 

Things I've learned:

  • How to break down large problems into small, atomic steps.
  • How to plan things rather than jump right off the bat, forcing me to refactor several times in the process.
  • How to avoid trying to build the "perfect" system right off the bat, knowing that a well documented working version is better than a version that never leaves the development stage.
+7  A: 

Never trust data.

Au contraire. Trust, but verify.
Will Hartung
I have to agree with Will.
But if you have to verify it then are you really trusting it? ;)
+1  A: 

it is better to write new code, after you have tried fixing the old ones for 15 minutes. Have unit tests ready though.

+6  A: 

"I have a bad feeling about this" occurs more often nowadays. :)

Anders K.
+1  A: 

When a user asks for something to be done, turn the question back on WHAT they're trying to accomplish rather than HOW they're trying to accomplish it. You'll get a better view of the problem, and it could well be something that's already implemented in the system in a way the user has not yet discovered.

Will Hartung
+3  A: 

Understanding other people's code quickly, and being able to modify it to suit new requirements, bug fixing and so on has proved very valuable along the years. Seeing what the original programmer meant and what were the mistakes (or where was the beauty) is really nice.

It's something similar to increasing typing speed or reading speed, you can only do it with practice. No amount of theory will skip you the practice required.

Vinko Vrsalovic
+2  A: 

For me these habbits are very helpful

  • List item
  • Think clearly you code
  • Don't repeat yourself
  • You ain't gonna need it
+6  A: 
  • 99.99% of the time, someone else has already solved the problem, look it up first.
  • Patterns are there to help you think, not to help you code.
  • Internationalization and localization will bite you if you do not think of it early enough.

I always see places to use the Command Pattern. It's the best.

I also am quite good at figuring what objects need to be created for a system, and they always seem to fit together quite easily.


Minimize state and overall complexity. I find myself unconciously refactoring bits and pieces in my head to see if something can be done in less lines of code. Processors run at finite and fixed speeds. Your application or system can never run faster, it can only do less...

I'm not sure if it's an intuition, but it has become deeply ingrained in me to never settle with any level of knowledge or ability.

I think one of the key skills of becoming an effective programmer is learning to live a balanced life constantly spent climbing an endless waterfall of information.

Robert Venables
+2  A: 

If it an't broke don't fix it.

I disagree. This truism has lead to lots of lines unreadable code today and ultimately to never delivered sw. It you know how to refactor bad code without breaking it (cover it by unittests if you have to) do it.
+2  A: 

This might seem really an odd idea at first, but I've found that reading other people code really has helped me become a better programmer and develop a good intuition. It took me while to get efficient at reading code because it's so non linear, but the more time I spend looking at really well written code the better I am at emulating it, both in terms of style and structure and also in how to take advantage of quality third party libraries.

+1  A: 

Avoiding the debugger. Using TDD and writing simple and readable code, I spend less time debugging and have less breakable code.

If you have some tips for not using the debugger to test user interfaces and things with a lot of contextual state I'd love to hear them. And I've seen and used my fair share of dynamic mocks... Also, TDDing javascript in a meaningful way and TDDing interface-state such as coordinates of things on the screen in a meaningful way.

Simpler code structure which requires more actual typing is easier to read later, than complex and 'more intelligent' structures that save up keystrokes.

  1. Design based on what users do, not what they say.

  2. Trust the users, not the users' managers.

  3. Never say users will never do anything.

le dorfier
+1  A: 

When taking over code written by someone else, especially if the code is particularly spaghetti-ish, I've learned that, if unit tests don't already exist for it, that I need to write some against the existing implementation before I start refactoring it. Otherwise, something important will break.

+1  A: 

The simplest solution is normally the right solution. Don't try and over complicate things.


After you have been on the job for a while, I'd say everyone gets a feel for what algorithms, patterns, and data structures are going to be required to solve a particular problem.


  • when to use an array vs some sort of linked list,

  • which sorting algorithm applies to this aspect of the problem

  • which pattern to apply

  • how many layers of abstraction are needed to give extenstibility and performance

  • what makes a good index

Some are because you have used them on so many problems you start to recognize their applicabilit and others becuase you stubbed your toe and now you know better - such as quicksorting lists that are maintained in sorted or nearly sorted order.


Complexity is a smell

David Plumpton

How to create the architecture and overall design for any program.


I've become good at using the google. And I can usually get something to compile on the first try even after an hour of straight coding.

Josh Einstein

Think a design through before starting to type code.... and assumption is the mother of all screwups.

Jeroen Landheer
+1  A: 
  • See the big picture, but start with the ugly details.

  • How to avoid overengineering

  • Smell bad code

and most important...

  • How to judge if a coworker is a good developer or not

One thing I've found experience taught me (and has taught others) is to grok how something works. It's one thing to know how to use a language feature or concept (delegates, closures, garbage collection, memory models, etc), but it's another thing to understand how it works.

James Schek

related questions