On The Value Of Fundamentals In Software Development

Martial ArtsI believe in the value of the fundamentals, but it sometimes seems like I am the only one. I am firmly of the opinion that the key to true mastery and expertise in software development (and in everything else) lies in having a solid grip on the fundamentals, so solid that you don't really need to think when you apply them. Whenever I trot this opinion out, however, I inevitably find myself in the minority. You see, we – software developers – view ourselves as problem solvers. We don't really need to have deep knowledge and understanding of anything (and with the amount of tech we're exposed to on a daily basis it is pretty much impossible anyway). As long as we know that something exists, we can always infer, look-up and work-out everything we need to be able to use it. This attitude is fine, but I believe it is wrong to apply it when it comes to fundamental knowledge, and this is where many people seem to disagree with me – to my constant amazement. Before looking at this further, let us define what fundamental knowledge actually is.

What Are Fundamentals

A couple of years ago I was asked the following question in an interview. Explain how optimistic locking works, in the context of Hibernate. At the time I had done a bit of work with Hibernate, but I was by no means an expert, so I drew a complete blank. What a total FAIL on my part that was, because optimistic locking is not really a Hibernate-centric idea, it is a fundamental concurrency control concept. I should have been able to fire-off an explanation of optimistic locking in general and I would have been 90% of the way there (regarding how it works within Hibernate).

Here is how I like to look at it. There are fundamentals at the macro level and at the micro level. At the macro level (i.e. looking at software development as a whole) there are concepts, algorithms and knowledge that will be applicable no matter the type of work you're doing or the domain you're working in. We're talking things like arrays, hashes, trees, sorting, searching, some graph algorithms, caching, certain object oriented concepts and yes, even things like lazy loading and optimistic locking. There are a few others, but surprisingly not that many. You need to know these things backwards. The implications of using them on small and large data sets, common problems they apply to, limitations and how to overcome them etc. You will be playing with these every day, for the rest of your career; surely you owe it to yourself to understand them as deeply as you possibly can. Yet, most people have at best a working knowledge, which has remained at approximately the same level since university. 

At the micro level (i.e. looking at a specific technology, language or library), there will be API details, tools and quirks that you have to internalise fully in order to be truly effective. When I started learning Ruby, I read all sorts of books and blog posts. I found out about various techniques, tools, gems etc. Did any of it make a significant impact on the quality of my code or how fast I was able to write it? Not really, at least not that you would notice, beyond the natural improvements that you would expect from continued usage. Then, at one point, I spent a couple of hours closely looking at the API of the Array class, I don't remember what my reasons were, but all of a sudden, I noticed myself coding faster and able to maintain a state of flow for longer. You see, I didn't need to look-up much to do with the Array class any more, I was really surprised at how much of a difference that made (but if you think about how often we use/manipulate arrays, it is not actually that surprising). You know what my advice would be to someone just starting to learn Ruby? Arrays, Hashes, Strings and Files – learn their API's off by heart as soon as you can, you will find yourself head and shoulders above most other Ruby programmers straight away. That is micro level fundamentals.

A Solid Understanding

Castle

What does it mean to internalise something completely? Let's take martial arts as an example. You can pick up some books and read all of them. You can have someone show you all the moves and can even try some of them out a couple of times. Does that make you an expert martial artist? Not by a long shot, for that you need to practice, and keep practicing until muscle memory kicks in and the moves become second nature to you. You've internalised them. More than that, you don't spend hours practicing complex combinations (not initially anyway), you spend your time working on basic movements, complex moves are made up of basic ones and if you have those down solid, it is a short step to be able to combine the simple moves to perform the more complex (my apologies to any real martial artists if I've oversimplified anything).

Yet, in software, most of us are just like that fan-boy amateur martial artist. We bite off a little bit of Ruby, then some Javascript, moving on to C# and coming back for a taste of Rails, then, back in Java land we take-in just enough Spring to get by and only as much Hibernate as we need to list it as a skill on the resume. We jump from technology to technology, wanting to know and be aware of everything (so we don't fall behind), but all the while, we would probably have been better off practicing our "basic moves". It doesn't matter how many object oriented languages you know, if you're not precisely sure what coupling, cohesion or abstraction means, your code is likely to be equally crappy in all of them. It doesn't matter how many inversion of control containers you have used, if you don't know what problem dependency injection is trying to solve, then you're just another sheep ready to follow the leader off a cliff (it's true, sheep will actually do that).

There is a difference between really understanding something and learning just enough to get by (i.e. having a working knowledge). It is usually ok to only have a working knowledge of most of the tech you use day-to-day; there is simply no need to have a deep understanding of the hundreds of libraries and technologies you deal with. The reason it is ok though, is because it's assumed that you will have a solid understanding of the fundamental principles that all this tech is built upon. You don't need to know the specifics of the Hibernate or ActiveRecord implementation if you understand how lazy loading, or optimistic locking works. If you have MVC down, then whether you're using Struts or Rails makes no difference, it's just an implementation detail. Basically, a good rule of thumb is, the more fundamental the concept the more solid your knowledge of it should be. It's the whole, solid house – solid foundation thing.

I sometimes think that a generalist with really solid fundamentals could pass for an expert almost every time. Have you ever seen someone walk up to a keyboard, start coding and not stop for 10, 15, 20 minutes, no need to refer to anything? Impressive isn't it? They seem to produce an amazing amount of useful code in a very short period time and when they leave people whisper the word genius. But there is nothing genius about it, just someone who took the time to learn the micro level fundamentals in that particular area – the rest was just practice. You can do the same, get your macro and micro level fundamentals down solid, after that it's all about strategic practice, but that is a story for another post. To me, all this just makes a whole lot of sense. I would have thought it would make just as much sense to everyone else and yet I constantly find people to disagree with me on this point – it's really quite puzzling :).

Images by thivierr and antonychammond

  • Amber Shah

    The problem with saying that every decent developer NEEDS a solid understanding of the fundamentals is there’s just too many things that some people might consider a fundamental. For example, like yourself in the interview, I didn’t know what optimistic locking meant. As a good developer, “should” I know? Well, maybe it’d be nice if I knew every “fundamental” but that’s not realistic.

    And for the plenty of truly great developers out there who do know much more about concurrency than myself, perhaps they don’t know about some things that I consider “fundamental” about the things that I care about, things like object oriented design, TDD, agile, core Java, algorithms, web services, etc. My husband has strong opinions about what every developer “should” know about database design, networking, security, etc.

    So the idea of knowing the fundamentals soudns good in theory, in practice I think almost every developer will have a different idea of what would be a fundamental.

    • http://www.skorks.com Alan Skorkin

      Hi Amber,

      I hear what you’re saying, and if we get down to the level of the micro fundamentals this is certainly true. But when it comes to macro fundamentals it is not that hard to cut it down to what you should know. When it comes to pure programming, crack open a good algorithm book and a good operating systems book (seriously crack one open you will find half the problems you’ve dealt with in your career right there, I know I did), read and learn what is in there and you’re 90% of the way there.

      If we bring the web into the equation, then undoubtedly it would help to know really well how the http protocol worked, maybe have a good idea about tcp/ip.

      Basic OO, TDD and Agile can be counted as fundamentals, but compared to the time invested needed to learn the stuff I talked about above, this is small fry. It’s still important but reasonably simple to learn and not that time consuming.

      And even if you do have a different idea of what the fundamentals are, well go with that, become intimately familiar with what you think is important. The problem is that most people are not willing to invest the time to do even that.

      • Amber Shah

        Practically speaking, I think we’re actually on the same page. We should all be learning more about the our craft, specifically, more concepts and “how it works” than just plugging libraries in together. So I think to a certain extent this debate is semantics and also reacting to the people we have dealth with specifically.

        The thing that gets me is when someone dismisses a developer because they don’t know theory X, Y or Z (when of course, that developer doesn’t know everything either). I tend to run into this pretty often, I think, where I am not seen as “good” because I will state honestly that I don’t know something, when I could easily stump the other person on several technical topics that are very important.

        I also agree that learning something like TDD or agile probably takes less effort than learning something like encryption or compression, but at the same time, SO many developers I run into know -nothing- about it (but somehow think they do). We’re in the business of writing software, it would be good if we knew how to do that, right? No seriously… right?

        My husband has always done a decent amount of networking and knows about it, much more than my (almost nonexistent) knowledge on the topic. In college we both took a “Networking” class together. Guess who aced it and who got a C? Yep, I got the A. I can -still- spout some of the things I learned in that class but I am -useless- and he is still light years ahead of where I am. Practically speaking – which person would you rather have working on your network?

        • http://www.skorks.com Alan Skorkin

          Dismissing people for not knowing something is another matter all together and is silly considering the breadth of our industry. What is bad is when someone is ignorant of something but still try to act like they are not. Personally I respect people a lot more for admitting they don’t know than for trying to pull the wool over my eyes. This is another post I’ve had on my agenda for a while.

          • http://www.WhiteCranePhotography.com Rakesh Malik

            I agree. When I interview candidates I try to make sure that I ask them questions that they don’t know the answer to, and if they can’t honestly tell me that they don’t know, then I immediately gives them the thumbs down.

            I do respect people who tell me that they don’t know the answer, but are willing to try to reason their way through an attempt to find a solution, especially if they can work with feedback and commentary as I offer it in response. I’ve found that the better interviewers share that attitude; they don’t care as much that you didn’t know, but rather that you didn’t lie and that you can think and collaborate.

      • http://www.mbahacks.com Ed Castano

        Any specific recommendations for a good algorithm book and a good operating systems book?

        By the way, I’ve been reading a bunch of your posts and I find them all great. I found your site while researching the Ruby case method.

        Thanks,
        Ed

  • Richard Hanley

    If each software discipline has separate fundamentals then they aren’t really fundamentals. To explain what I mean, I am going to take Alan’s martial arts example and expand it. Lets consider for a moment the sheer number of martial arts styles. Karate tends to focus on punches, while Tae Kwan Doe focuses on kicks. Ju-jitsu focuses on joint manipulation, but Aikido looks more at movement and momentum. However, each and every style focuses on you stance and how to use your entire body in a technique.

    In the same sense there are software fundamentals. So in this sense what is considered truly fundamental in each and every software discipline. Nearly every discipline will have people working together. This means that understanding other people’s code, and more importantly the interfaces to that code is fundamental. The same goes for APIs. Another fundamental is the idea of abstraction.

    My view on this subject is that there is a group of fundamental conceptual principles that are more or less universal. This is similar to Alan’s macro view, but a bit broader. Knowing an algorithm isn’t as important as knowing how to study a random algorithm and using it properly.

    These universal fundamentals can then be applied to a certain discipline. In this sense each of the varying fundamentals that Amber mentions are just different instantiations of the same fundamentals. These are also akin to Alan’s micro view.

    To sum up, in my opinion there are universal fundamentals that are important to all software. However, in these fundamentals are realized in very task specific ways. With this, a developer needs to know the fundamentals, and how they apply to their discipline.

    (and sadly I have written far more than I had planned)

    • http://www.skorks.com Alan Skorkin

      Hi Richard,

      That is almost exactly how I view macro fundamentals and it is often hard to define, (although I gave it a go in the article) and even harder to figure out if a particular concept fits in. But as I said in response to the comment above, you don’t really need a definitive list, work out your own one and invest serious time in it.

  • Keith Hanson

    On top of everything Amber has said (and I agree with all of it), I had these issues with your post…

    ‘We bite off a little bit of Ruby, then some Javascript, moving on to C# and coming back for a taste of Rails, then, back in Java land we take-in just enough Spring to get by and only as much Hibernate as we need to list it as a skill on the resume.’

    We’re fan-boy amateurs? We hop around from technology to technology? Umm…. I know that I do not. I’ve specialized in ruby for the past three years (professionally). I’ve had real, mission-critical applications written in Rails, Merb, Sinatra, and now Harbor. I’ve used MySQL (and felt the pain), PostgreSQL, CouchDB, and Redis. Every one of these technologies is something I’ve done, in the past, for a project because it fit the need. I also don’t list a skill on a resume I’m not intimately familiar with, and feel that doing so would be intellectually dishonest. Please, let’s not setup straw men to prove our points.

    Had you said, “I bite off… ” and “I take-in just enough”… and “I need to list it as a skill…”, I would have felt entirely different about this post. Instead, I’m offended you think I pad my resume and never obtain a deep knowledge of my career. Even more, I’m annoyed you generalized so much.

    ‘It doesn’t matter how many inversion of control containers you have used, if you don’t know what problem dependency injection is trying to solve, then you’re just another sheep ready to follow the leader off a cliff (it’s true, sheep will actually do that).’

    I feel like this was about the only really useful thing you’ve said here, and largely the entire point of the article. In short, you’ll be a better developer in general if you understand the problem a library is trying to solve. Even shorter, experience.

    Because let’s be honest… do you have the time it takes to even do what you’re suggesting? When a job needs something done, do you honestly go and research every “fundamental” that a library uses? I’m willing to bet that your boss (or clients if you are a consultant), wouldn’t look favorably on that sort of research. Unless you’re creating everything from scratch. And I hope you are not.

    On the other hand, when you run into a problem BECAUSE of root issues like that, the research is to solve the problem, and thus, you learn about the “fundamental”. In other words, experience.

    So yes, being proactive about your research would ultimately be of great help to you as a developer on the job. But, as Amber pointed out, there’s an upper limit to what sort of time investment you can make, and even in what you decide to ultimately research.

    Perhaps a more useful post might be the fundamental things you’ve learned on the job that helped you in the long run (like learning about Arrays or Hashes), instead of these vague generalizations that neatly box every developer up.

    • http://www.skorks.com Alan Skorkin

      Hi Keith,

      I appreciate your point of view. You said yourself that I used generalisation in my post and yet you seem to be personally offended by them. Rest assured, I wasn’t targeting you specifically. I was observing a general trend – hence generalisation. There are plenty of developers who are conscientious about what and how they learn, know their fundamentals well etc. But let me ask you this, is every other developer you’ve ever worked with exactly like you? If the answer is yes, then you’ve been very lucky.

      I hear a lot of people site the lack of time thing, but I did break things up into macro level and micro level did I not. OF course you can’t learn every micro level thing, but at the macro level you’re doing yourself and everyone else a great disservice if you don’t know. And I am not saying I know every fundamental even at the macro level, by any stretch of the imagination, but I try to correct this because I do see it as a problem.

      There is a difference in learning ABOUT something and knowing it really well. If you know you’ll be using Rails for 10 projects in the next few years, it really behooves you to take the time and learn it really well outside of those projects and well as within them. If you learn everything as you go … I seriously find it puzzling that so many people think this is ok. Once or twice – sure, but the third time you use something, isn’t it worth the investment to take a step back and try to understand it at a fundamental level? Not even everything but at least some things?

      • http://rubyengineer.com Keith Hanson

        Probably not every other developer, but damn close :) I’ve tried to stay away from the jobs where I’m a small cog surrounded by other cogs that simply do their jobs for the paycheck. But I do admit that for the most part, developers that go out and post blogs about their experiences, learn lessons in a public way (posts/comments), and generally strive to better their understanding is rare; perhaps not with the (m)any of the people I work(ed) with, but yes, generally I’d agree :P

        I simply want to say that you shouldn’t use generalizations to prove your point, because I’d wager that those people who you are generalizing aren’t going to read this and won’t change even if they did, haha!

        I agree, and apologize for not drawing the distinction from macro/micro. Still… I think that experience should be the best guide in determining what macro level fundamentals to sink your teeth into, and that’s a post I’d love to see!

        Hmm… I see your point about learning it really well, it’s just something that in general, I find impossible to do on the job. I suppose I’m far more a “learn by doing” sort of developer. I really like to find something applicable to work on that a fundamental idea will solve. For instance, right now I’m toying around with a game. I’m using Madeleine for Object Prevalence (http://www.prevayler.org/old_wiki/PrevalenceSkepticalFAQ.html), I’m using Inversion of Control, I’m using State Machines… it’s all really fascinating.

        But I can’t say that I’d truly, deeply grok any of these topics without really *doing* something I’m actually *interested* in. Test/toy projects *aren’t* the same. Theory is *not* enough to deeply understand something (for me, at the very least). And I suppose in some misplaced way, that’s what I was getting at.

        To *truly* know/grok a fundamental, you have to actually do something with it, and I just don’t think that’s feasible for someone who sits down and wants to decide on fundamentals up front. It takes experience and feeling pain before you can really deeply learn these things :)

        • http://www.skorks.com Alan Skorkin

          Hey Keith,

          Learning by doing is a very valid technique, you’d be surprised how many people are in the same boat (the vast majority). Learning the theory is valuable but ultimately only takes you so far. You need to apply what you learn in order to truly retain it. You’re lucky if you can do this through work (very lucky). I think it is about being creative with your ‘toy’ project, they don’t really have to be toys, but you need to plan them to achieve the goals you’re trying to reach as opposed to generally doing them for the sake of it. I really should do a few posts about this, but it is not an exact science :).

          And there is nothing wrong with going through a painful experience before you work out what you have to know, many people seem to need this as well :).

  • Daniel

    Yes, I also agree that there are some things, some “fundamentals”, that every developer should know. Also, those “fundamentals” might vary according to the developer’s field. For example, someone who is solely a web developer that works with PHP might not need to know a lot about multithreading, locks, etc. Then again, if you have two PHP developers, one that knows how multithreading works, all the concepts and that might have worked with multithreaded programs before in another language, and another one who doesn’t have a clue about anything low-level, the first one would be considered a better choice.

    I agree that any developer, doesn’t matter the language and architecture, should strive to know as much as he can about the platform he works with – he should know how processors work, should know how his OS works or at least have some clue, know how memory management, process management, everything works, so he can also understand how things tie together with each other. Then moving up to higher levels, a developer should also know his language’s internals – for example, a PHP developer should know how apache works (MPM, prefork, etc), should read the relevant RFCs (http, etc), should know about PHP’s internals (so he can know the cost of doing things, would know whether a foreach is quicker or slower than a for to traverse an array, etc). It’s those little things that draws a line between a great developer who knows what he’s doing and someone who just stitches functions together hoping they will work as he wants…

    • http://www.skorks.com Alan Skorkin

      Hi Daniel,

      Exactly, and more than that, if you switch languages at some point, this process starts over again. You become a ruby programmer and you will once again need to know how your new language handles all those things. Which is why I always laugh when people tell me they learned a programming language in 2 weeks. The interesting thing is, if you learned the macro fundamentals while working with you first language, they remain the same, OS concepts, algorithms, concurrency handling etc. It is just the implementation quirks you need to get across which becomes a lot easier.

  • Roger Roelofs

    I totally agree on the macro fundamentals. These data structures and patterns we use every day are language independent. Understanding the basics and how to apply them help us to write better code efficiently. They also help us understand new languages and frameworks with greater speed and accuracy. I’m less inclined to agree on the micro fundamentals. We often have to work in multiple languages simultaneously which makes it difficult to avoid using reference material. You may know both languages well, but get a function call wrong because you are still mentally partly in the other language. As long as you can create an environment where lookups are quick and painless, double checking that you are calling the correct function with parameters in the correct order doesn’t break the flow. Knowing the language apis is good, and worthy of some time and effort, but knowing the macro fundamentals will repay you over and over no matter what language or framework your current job requires.

    • http://www.skorks.com Alan Skorkin

      Hi Roger,

      You’re of course right about the fact that you will always need reference material. I am not suggesting that you should know all the language api’s of by heart that would never scale. What I am saying is, it would be really helpful to know the basic and most commonly used api’s. It’s fine to look up socket api details when you need to use it, since you probably won’t do it all the time. But when you constantly need to look up array api details that gets annoying and slows you down significantly since you use it so much.

  • Ahmed

    Excellent post as usual.
    I totally agree with you.
    I think you will be the next Jeff Atwood, if your posts a little bit shorter.
    I’m waiting for (strategic practice) post.
    Thanks,
    Ahmed.

    • http://www.skorks.com Alan Skorkin

      Thanks mate,

      I hope I can get to writing that post soon, I’ve been planning to do it for a while, unfortunately the list of things I want to write about keeps growing longer, my free time on the other hand does not :).

  • Korny

    I agree with the fact that you need to know a bunch of fundamentals – but I disagree with:
    “We’re talking things like arrays, hashes, trees, sorting, searching, some graph algorithms, caching, certain object oriented concepts and yes, even things like lazy loading and optimistic locking. There are a few others, but surprisingly not that many”

    Sorry – but there are many; huge numbers of things are fundamentals to different domains and sub-domains of IT, and I strongly doubt you can, or should, know them all.

    A quick off-the-top-of-my-head list of some example fundamentals that I’d expect you to know well if you were in a particular domain; at least as well as optimistic locking:
    Web development: what progressive enhancement / graceful degradation are.
    Javascript: How closures work (in js, as well as in general). When to use global variables.
    Ruby: How to write an internal DSL. How to use ‘class << self'
    Java: How classloaders work. How and where generics are broken. How to use anonymous inner classes effectively.
    (skipping Python – funny, I used to be a big fan, but Ruby has driven all Python from my memory)
    C++: how a vector is actually implemented in memory. How the RAII pattern works. How and when to use virtual destructors. (why does my brain still remember this stuff?!)
    C: How function calls and parameters are stored on the stack. How to use function pointers.
    Assembler: How to do loop unrolling. Which ASM instructions are optimised differently on 80386, 80486, and Pentium processors. How to do fixed-point arithmetic.
    Gui development: the difference between classic MVC and web MVC
    Databases: How to handle inheritance. Query profiling and optimisation. Stored procedures, their use and abuse.
    CSS: How to hide elements without breaking screen readers. How the box model is broken in Internet Explorer. How to clear floats.
    And this is just familiar domains – I’m sure there are some significant fundamentals in the .NET world, and in the real-time-computing world, and in the seriously-concurrent-programming world, and in the wonderful world of mainframes. I’ve missed some stuff from Functional Programming, and of course there are the SOLID principles. And a pile of things you should know about TDD, and BDD, and testing in general.

    Ok, I’ve gone a bit overboard. My point is – I think there are tonnes and tonnes of fundamentals, and you should know lots of things – but I seriously doubt you can know “all” the fundamentals. You need to be a T shaped individual – know a few things really well, know lots of things well enough, and demonstrate your ability and willingness to learn things in depth when you need them.

    • http://www.skorks.com Alan Skorkin

      Hey Korny,

      Ahh, but we’re once again getting into the macro vs micro fundamentals question. It is impossible to know all micro fundamentals in every domain, but there are macro fundamentals that cross all domains.

      There are many algorithms that are applicable in any language and domain. You will be using and interacting with OS’s no matter what you do, so knowing basic operating system concepts is always useful. If you’re working with OO then basic OO principles will cross languages with you etc. For example, SOLID principles are built on top of more basic OO concepts which I mentioned in the post, coupling, cohesion, encapsulation, abstraction. Dependency injection is a direct result of one of the SOLID principles etc. The point is there are fundamentals and then there are FUNDAMENTALS :).

      I completely agree that you should be T shaped, but this is the domain of micro fundamentals, you pick an area or three and attempt to know these in depth. The universal fundamentals will be just as applicable here as everywhere else.

  • Pingback: Dew Drop – April 4, 2010 | Alvin Ashcraft's Morning Dew

  • Korny

    But if you want cross-domain macro fundamentals, then your example of optimistic locking sucks totally. It’s highly specific to the database domain – and even then, only to people who care about simultaneous editing of data. It’s important to big business – but not to games developers, nor to (most) website developers, nor to most fat-client app developers, nor to mobile app developers…
    Dependency injection? Functional programmers don’t need it, at least not in it’s normal form, and Ruby programmers rarely need it (see the great article at http://weblog.jamisbuck.org/2008/11/9/legos-play-doh-and-programming for more on misplaced idioms in ruby)
    MVC? There are 2 quite different patterns going by the name MVC in different domains, and a large world of skilled programmers who get by happily without either.

    Possibly the SOLID principles are geniunely cross-domain, at least for the object-oriented subset of IT (it’s a big subset, but it’s still a subset – it misses kernel developers, mainframe coders, FP lovers, and a lot of web-ui development).

    You tell me what the genuine macro fundamentals are, and I’ll probably agree that everyone should know them in depth. But I’m struggling to know what fundamentals apply to all of:
    - someone writing mainframe cobol for a bank
    - someone writing embedded controller code for a dynamometer
    - someone writing an AI in lisp
    - someone writing weather simulations on grid systems at the BOM
    - someone writing an iPhone game
    - someone modifying the linux kernel for the next Android release
    - someone writing VBA applications to automate a range of Office documents

    If you want to limit your definition of IT to “people who write OO code for webapps”, then there are lots of common fundamentals, *to them*. (Though still not Dependency Injection!)

    • http://www.skorks.com Alan Skorkin

      You make a good point, it is very difficult to find fundamental concepts which will always be applicable everywhere. Although I do maintain that algorithmic knowledge and OS concepts comes close.

      I guess the best thing to do is to turn it around, if you are working in web programming does it mean you don’t need to know how HTTP works, or MVC or a range of other core concepts in web programming? And if you know this stuff really well, if you do decide to transition to say mobile development on a new device, do you throw these concepts out?

      I don’t think so, let’s say the socket communication libraries are a little raw on your new platform, but that’s alright cause you have deep knowledge of the subject. MVC not applicable in it’s old form, but you can easily shift your mental models since you know it backwards. That’s the way I prefer to look at things when it comes to the fundamentals.

  • http://barebonescoder.com Jeff

    There’s no question that having the “fundamentals” mastered on a subconscious level will elevate one’s performance across the board. As other commenters have said, the challenge is identifying the “fundamentals” in your given environment, and also those areas that are “fundamentals” across most other environments. That is worthy of a blog post in and of itself.

    • http://www.skorks.com Alan Skorkin

      You’re right but I believe that people can often easily identify at least some fundamental concepts in their domain, but they end up paralyzed with indecision in case they’re wrong. An investment into learning anything more or less fundamental is better than no investment at all.

  • http://coolest.com Alex

    I’m not an ESR fan, but I do like his list of Unix Philosophy “rules” and find they mostly cross all Software Development domains (@Korny).

    Probably need a “Rule of Cohesion: group by related function” in there too though.

    http://www.faqs.org/docs/artu/ch01s06.html
    1. Rule of Modularity: Write simple parts connected by clean interfaces.
    2. Rule of Clarity: Clarity is better than cleverness.
    3. Rule of Composition: Design programs to be connected to other programs.
    4. Rule of Separation: Separate policy from mechanism; separate interfaces from engines.
    5. Rule of Simplicity: Design for simplicity; add complexity only where you must.
    6. Rule of Parsimony: Write a big program only when it is clear by demonstration that nothing else will do.
    7. Rule of Transparency: Design for visibility to make inspection and debugging easier.
    8. Rule of Robustness: Robustness is the child of transparency and simplicity.
    9. Rule of Representation: Fold knowledge into data so program logic can be stupid and robust.
    10. Rule of Least Surprise: In interface design, always do the least surprising thing.
    11. Rule of Silence: When a program has nothing surprising to say, it should say nothing.
    12. Rule of Repair: When you must fail, fail noisily and as soon as possible.
    13. Rule of Economy: Programmer time is expensive; conserve it in preference to machine time.
    14. Rule of Generation: Avoid hand-hacking; write programs to write programs when you can.
    15. Rule of Optimization: Prototype before polishing. Get it working before you optimize it.
    16. Rule of Diversity: Distrust all claims for “one true way”.
    17. Rule of Extensibility: Design for the future, because it will be here sooner than you think.

    • http://www.skorks.com Alan Skorkin

      Mate, it’s like you read my mind. I’ve been planning to do a post on the Unix Philosophy for a while now, and you’ve just given a perfect lead-in :).

  • http://waytogole.blogspot.com/ shailesh

    hi,
    I agree that language and technology comes last before that you should have solid knowledge of fundamental.

    Basically all languages have their own syntax but the fundamental is always same all languages share same logic. Say for example sorting of number follows same patter we do either in pen and paper or in any language with use of any of the basic sorting technique.

    please do post this type.

  • http://www.EdmundKirwan.com Ed K

    Maybe the most fundamental software fundamental: sometimes a fundamental is a fundamental, sometimes it’s not.

    Ed

    PS I see you only mention encapsulation in one of your response posts. Tut, tut:
    http://www.edmundkirwan.com/encap/fundamentals/paper1.html

  • http://jchyip.blogspot.com Jason Yip

    Re: “so solid that you don’t really need to think when you apply them”

    Have you read Talent is Overrated by Geoff Colvin?

    One of the key distinctions with people who become world-class experts is that they tend to deliberately avoid shifting into the no longer think about it mode even with things that they can do very well. The reason is that they need to maintain attention in order to keep improving. In other words, unconscious competence does not allow for improvement.

    • http://www.skorks.com Alan Skorkin

      Hey Jason,

      I actually have read it :) – great book and I will be talking about some of the stuff I took away from it in later posts. You’re right though, I didn’t word it well. Just because you don’t NEED to think about something doesn’t mean you shouldn’t. Infact it is often advantageous to have a close look at stuff you think you know extremely well.

      For example, I’ve started having a look at OS concepts recently and I must say that the weight of experience gives you a whole new level of insight (not that I was an expert in the first place :)).

  • http://dhondtsayitsagile.blogspot.com André Dhondt

    What should be on the list of fundamentals? A bunch of us have been building a list at the http://www.AgileSkillsProject.org/

    • http://www.skorks.com Alan Skorkin

      Hey Andre

      I really like that, good resource.

  • patrick

    Interesting article. Thank you. A quick note about your martial arts comparison. I think it is a very good comparison but I would like to add a few clarifications:

    1. You have to train moves until muscle memory kicks in because otherwise you would not be able to concentrate on complex moves/combinations (bigger picture).
    2. Unlike programming, in a fight, there is often little to no time to think about your movements so you have to rely on your reflexes (~ < 0.3 seconds), which you train by doing Point 1.
    3. Comparing martial arts with other sports, it is one that demands overall training of the body (fundamentals) instead of focusing/specializing on certain muscle groups

    thanks again for this great article

  • Pingback: Interessante Links im Netz V « DaRaFF's Blog

  • Pingback: Links « Beautiful Discovery

  • Muhammad U

    Wow! This is just a great post.

    It made me think through what I’m currently learning. Recently I’ve been skimming around with languages and this really pushes me to go read all the details of everything I’m picking up for further development of my own programming skills.

  • Pingback: links for 2010-05-05 | Michael Ong | On9 Systems

  • Pingback: phunculist

  • googya

    you are not the only one who believes in value of the fundamentals,me too!

    in china,there is a quote ,”基础不牢,地动山摇”

    • http://www.skorks.com Alan Skorkin

      Unfortunately I can’t read that, but I am sure it’s profound :).

      • rajanrajan

        It means without a solid foundation mountains shake :)

  • http://gakshay.wordpress.com Akshay

    Hi Alan,
    I like your post, especially the simple way to explain any point with real time example. Even I used to say about Martial arts example to explain it to fellow friends.

    To share little more, We say say programmer has three phases in his/her life Jackie Chan, Bruce Willis and James Bond (generalized way) :
    1. In starting they are naive, have little knowledge, ask lot of questions (similar to sounds produced by Jackie Chain..hoo haaa hiii) and then fails a lot many times then expected :)
    2. Then they learn, practice and gets better. Now when a problem comes, they get bruises, blooded just like Mr BW but keep trying hard and hard until they solve it themselves (learning more basics, practicing and using them wherever needed). Just like we see in Bruce Willis (Die Hard series).
    3. Then they get expertize and they no more need to look into books or API again and again. If some new technology or API comes in, it just takes minimal time for them to implement it as if they know whats into it. We call them Genius or James Bond level who even fires a bullet in any direction but it will only hit the Villain :) .

    They are the strongest amongst all and we adore them and want to be like them.

    Thanks,
    Akshay

  • http://gabrielrodriguez.net Gabriel Rodriguez

    I friggin’ love your blog posts dude and style of writing. Really keep it up.

    • http://www.skorks.com Alan Skorkin

      Thanks Gabriel, much appreciated.

  • Pingback: 高兴的一天 « Flyer's Blog

  • Pingback: 程序员的谎谬之言还是至理名言? @ Hello! MY LOVE!

  • Pingback: 人小力大 » Blog Archive » crawler engine思考

  • Laura Montemayor

    Loved this post. I am a week away from starting a Ruby on Rails bootcamp and this has completely changed the way I will continue my prep work.

    Thanks :)

  • Aniruddha

    One of the best article I’ve ever read.
    I’m starting learning Ruby and will surely keep these in mind. And also time for me to go back and brush up on my fundamentals…