Programming: What separates the men from the boys?

I have come up with the following list of topics:

  • Pointer arithmetic
  • Unicode vs ASCII strings
  • Memory management
  • Calling conventions
  • Basic mathematics, such as linear algebra (eg 2d rotations, translations and scaling, things you’ll regularly find in basic GUI stuff).
  • Multithreading/concurrency

Over time I have found that some programmers master such concepts at an early stage in their career, while others continue to struggle with these things for the rest of their lives.

Thoughts? Some more topics we can add to the list?

Update 25 Nov 2017: I have recently read Joel Spolsky’s Guerrilla Guide to Interviewing. He touches on various subjects as well, such as unicode, recursion and pointers. One thing he says is this (emphasis mine):

But like I said, the good programmers stand up, write the answer on the board, sometimes adding a clever fillip (Ooh! Unicode compliant! Nice!), and it takes thirty seconds, and now I have to decide if they’re really good, so I bring out the big guns: recursion and pointers.

15 years of experience interviewing programmers has convinced me that the best programmers all have an easy aptitude for dealing with multiple levels of abstraction simultaneously. In programming, that means specifically that they have no problem with recursion (which involves holding in your head multiple levels of the call stack at the same time) or complex pointer-based algorithms (where the address of an object is sort of like an abstract representation of the object itself).

I’ve come to realize that understanding pointers in C is not a skill, it’s an aptitude. In first year computer science classes, there are always about 200 kids at the beginning of the semester, all of whom wrote complex adventure games in BASIC for their PCs when they were 4 years old. They are having a good ol’ time learning C or Pascal in college, until one day the professor introduces pointers, and suddenly, they don’t get it. They just don’t understand anything any more. 90% of the class goes off and becomes Political Science majors, then they tell their friends that there weren’t enough good looking members of the appropriate sex in their CompSci classes, that’s why they switched. For some reason most people seem to be born without the part of the brain that understands pointers. Pointers require a complex form of doubly-indirected thinking that some people just can’t do, and it’s pretty crucial to good programming. A lot of the “script jocks” who started programming by copying JavaScript snippets into their web pages and went on to learn Perl never learned about pointers, and they can never quite produce code of the quality you need.

That’s the source of all these famous interview questions you hear about, like “reversing a linked list” or “detect loops in a tree structure.”

Sadly, despite the fact that I think that all good programmers should be able to handle recursion and pointers, and that this is an excellent way to tell if someone is a good programmer, the truth is that these days, programming languages have almost completely made that specific art unnecessary. Whereas ten years ago it was rare for a computer science student to get through college without learning recursion and functional programming in one class and C or Pascal with data structures in another class, today it’s possible in many otherwise reputable schools to coast by on Java alone.

A lot of programmers that you might interview these days are apt to consider recursion, pointers, and even data structures to be a silly implementation detail which has been abstracted away by today’s many happy programming languages. “When was the last time you had to write a sorting algorithm?” they snicker.
Still, I don’t really care. I want my ER doctor to understand anatomy, even if all she has to do is put the computerized defibrillator nodes on my chest and push the big red button, and I want programmers to know programming down to the CPU level, even if Ruby on Rails does read your mind and build a complete Web 2.0 social collaborative networking site for you with three clicks of the mouse.

I think this relates very closely to my point: the things in my list are not so much ‘skills’ as they are ‘aptitudes’. Being able to master the concepts shows that your brain is wired in a certain way, which is beneficial for developing great software.

And we’ve also seen people here ‘snickering’ in the comments as he points out: they think you don’t need to know, because modern languages and tools hide the details from you anyway. I agree with Joel that you want your programmers to know these details, regardless.

This entry was posted in Oldskool/retro programming, Software development and tagged , , . Bookmark the permalink.

25 Responses to Programming: What separates the men from the boys?

  1. Erwin says:

    I honestly expected something like ‘dreams that do not involve mortgage payments’ or ‘room to be creative’… But this is a serious list, so good for you!

  2. GL1zdA says:

    It depends on the work that has to be done. In my area (Enterprise programming) understanding the high level concepts is much more important:
    * Being good at teamwork. This is the Number One. If you fail at it, you’re still a boy. Writing unreadable code, “owning the code you write” and many more fall in this category.
    * Understanding the language you are using. You don’t write in C like in Assembly, you don’t write in Java like in C++, you don’t write in JavaScript or Python like in Java. Basically, one should actively fight against “if all you have is a hammer, everything looks like a nail”.
    * Being able to look at the program from a higher level, knowing how to architect code. SOLID, KISS, DRY, YAGNI etc.
    * Knowing your tools. I still encounter people having problems working with version control. But knowing your editor, IDE, debugger, profiler etc. makes a difference between a good programmer and a mediocre one.
    * This one is small, but matters recently. Understanding functional programming and leveraging functional constructs the language of your choice provides. While there are few purely functional projects and given there are not enough programmers knowing such languages starting such projects is rarely viable, many general purpose languages provide some facilities to write functional code. Using them results most of the time in code that is easier to understand and statelessness is a friend of scalability.

    • Scali says:

      Thank you, these are good points. I suppose most of my points are in the category of “Understanding the language you are using”, or perhaps “Understanding the platform you are using”. At a higher level there are also various skills that programmers either have or they don’t.

  3. mh says:

    Add recursion to the list.

  4. Mārtiņš says:

    Regular Expressions

  5. snemarch says:

    Humm, “separates the boys from the men” sounds like “I can write an editor in pure assembly” machismo rather than “programming skills that are very useful but which junior devs might not have”. And there’s some entries in your list that are very specific and IMHO not that useful unless you’re doing very specific stuff (e.g. knowing about calling conventions if you’re doing low-level math libraries – hi vectorcall and intrinsics) and pointer arithmetics (people who think they’re clever with this are usually writing undefined/unspecified/implementation-defined buggy stuff).

    GL1zdA has some good points, and I’d like to add “know more than one language; know which constructs suits the language(s) you’re operating in”. Some influence can carry over nicely between languages, but you definitely wouldn’t write Java-style code in C++ 🙂

    Also, knowing not to go into uber-generalization to achieve YAGNI. It’s about balance, sometimes you get a better solution by accepting an amount of duplication (where the “better” metric can be performance, readability, maintainability).

    Resisting the urge to gold-plate production code – knowing when “enough is enough”.

    • Scali says:

      Humm, “separates the boys from the men” sounds like “I can write an editor in pure assembly” machismo

      I don’t think any of the points listed point anywhere in that direction. I have no idea where that came from. I think you should know better than that (*cough*hutch*cough*).
      I have you know this list was inspired because I encounter people who are in their 40s or 50s on a daily basis, who struggle with these issues. So I’m not talking about junior coders in the least. That’s the point, as I say: it seems many programmers struggle with these topics for their entire career, not just when they are a ‘junior’.

      And there’s some entries in your list that are very specific and IMHO not that useful unless you’re doing very specific stuff (e.g. knowing about calling conventions if you’re doing low-level math libraries – hi vectorcall and intrinsics) and pointer arithmetics (people who think they’re clever with this are usually writing undefined/unspecified/implementation-defined buggy stuff).

      I’m not talking about ‘magic tricks’ here, but rather the basic skills required to eg interface with native OS libraries or other third-party libraries that have a simple ‘flat’ C-like interface.
      To me those are basic skills that every programmer needs to master, because you’ll regularly need to interface with such libraries in daily life.
      Perhaps a bit of context is required here: I work at a company where a lot of Delphi is used, so interfacing with DLLs and such is a bit more difficult than if you would use C/C++, and could just use the supplied header as-is, taking care of calling convention for you. Delphi programmers need to translate the header files to Delphi functions. The same goes for other languages such as C# to a certain extent (with things like DllImport).

      Anyway, as I say, my list was about basic programming skills that I often find even ‘experienced’ programmers don’t master, not about software development in the broad sense. That’s a whole different can of worms.
      Having said all that, I do think there’s some truth in the fact that assembly programmers would generally master many if not all of the above topics.

    • iser says:

      > “separates the boys from the men” sounds like “I can write an editor in pure assembly” machismo rather than “programming skills that are very useful but which junior devs might not have”
      just wtf.

  6. Uuuuuuu says:

    “Pointer arithmetic” and “Memory management” are very specific, intertwined and closely related only to certain increasingly unessential languages and environments. You can easily (and could’ve already decades ago) go through an entire career without ever really being familiar with these concepts. I mean people have for decades recognized these were kinda bad ideas so I wouldn’t say mastering them is a good standard for measuring anything. Similarly “Calling conventions” is hardly today a good topic to use to measure someone’s competency as a programmer.

    Unicode and concurrency are by far the most relevant items on that list and I would stress their importance as these are issues that crop up pervasively in most fields are not easily going away. I might lump up “Basic mathematics” maybe too, but that’s such a nebulous point that will inevitably vary based on the subject matter, which will render any assessments or comparisons void.

    Other than those lists like this are pointless since they always end pigeonholing the concept of programming skill into some relatively narrow range topics that have been relevant to the author only. And oh boy does that show here.

    • Scali says:

      Well, feel free to disagree, but my experience has been that as our codebase gets migrated to 64-bit, certain legacy code pops up with pointer arithmetic, and I am one of only a handful of people in the company who know how to fix that. I shudder at some of the ‘fixes’ I’ve seen some people do (one particularly amusing one was that they cast everything to int64… yea, that works for 32-bit and 64-bit, but for 32-bit it is inefficient, and if we ever move from 64-bit to something else, it will break again).

      Aside from that, I think the argument that you can go without some skills for an entire career is not a very strong one. Pointer arithmetic is part of Computer Organization, and is taught in university, so apparently I’m not the only one who thinks it’s a good skill to master.

      Likewise, the argument that something may be a ‘bad idea’ from the past is irrelevant (the lists does not say nor imply that the topics are ‘best practice’). You can and will encounter such code in practice, and you need to be able to deal with it when the time comes.

      The personal dig at the end of your post is rather sad by the way. Not sure what that is showing…?
      I guess you could paraphrase my idea behind this list as follows:
      The ‘boys’ will get stumped when they encounter code relating to these topics, and need help from a ‘man’ (or will write horrible, buggy code in their ignorance).
      The ‘men’ know enough to never get stumped by anything. They have a solid basis, and can figure out anything, and just keep getting better and more versatile over time.

  7. rimina says:

    Good for me that I’m not a boy or man so I can just focus on coding and not be worried about how much a man I am…

    • Scali says:

      I have not worked with female coders, so I am not sure if this list is ‘gender-neutral’ or not 🙂
      It could be that girls vs women have entirely different topics 🙂

  8. Ron says:

    Integer arithmetics and numerical bases. You would be surprised how many experienced programmers:

    * think that x/256 is the same as x>>8 for all x
    * are not able to construct basic arithmetic operations (+ – * /) for arbitrary long numbers
    * only know “tricks” to work in base 2, 10, and 16, but have no idea how to f.ex. print a number in base 7, because they lack a solid understanding of numerical bases.
    * have no clue what two’s and one’s complement arithmetics are, and what their pros and cons are

    • Scali says:

      Thanks Ron, those are some points I can agree on.
      I guess we can also include floating point arithmetic, and using proper epsilon values, choosing the right order for operations etc, in order to get stable, reliable results.
      Too often I see pieces of code where they just threw extra precision at the problem, rather than rewriting the equation so that it is stable even with limited precision.

  9. Czesiu says:

    Scali, isn’t that list stronly related to C++ and C? I do believe some of that stuff may seem moot when applied to high level languages (say Java or C#/F#/other .NET languages).

    • Scali says:

      Not really. I already mentioned Delphi in one of the comments. And it certainly is not moot, because you never work in a vacuum. Both Windows and *NIX-based OSes have their roots in C/C++, so you can expect to encounter C/C++ regularly when working with these systems. It’s the interoperability with other languages where you require these skills, which may also include Java (JNI) or .NET (C# actually supports pointers in ‘unsafe’ blocks of code).

      Nevertheless, I always say that C/C++ is like the English of programming languages. Even if you work in a country/environment where the primary language is not English, you encounter English on a daily basis. Not knowing English means you can’t access a wealth of information that is only available in English.
      I feel that C/C++ is the same thing: in my opinion, every programmer (and I do mean programming, not scripting) should know at least enough C/C++ to be able to understand C/C++ headers included with libraries, and simple example code available only in C/C++, to the point where they can convert/adapt it for use with their own language and tools of choice.

      I think your response, like Uuuuuuu’s, shows that you seemed to completely miss the point of this article. Step out of the vacuum.

      • Czesiu says:

        As it happens, I’m a .NET dev working on Windows (UWP nowadays), and no, I can’t agree that you’ll meet C/C++ regularly – The one exception beeing high-performance graphics, where interoperability with C++ is necessary. In that case though, the recommended way is to go with C++/CX, a language that mixes with .NET quite nicely and without all the DllImport hassle (and as an added bonus, also works nicely as an abstraction layer between C# and pure C++ if you’ll ever need it). Majority of WPF/UWP apps will live happily without even touching WinAPI in any way, and the same goes with ASP .NET. Unsafe context in C# is such a rare occurance that I would’t call pointer arithmetics a thing that separates men from boys among .NET devs. If you decide you need high-performant code and write C# with lots of unsafe stuff, there’s a good chance you’ve picked the wrong tool for the job.
        Here’s the thing – I believe we’re both heavily biased by our work experience, and I wouldn’t call that a vacuum, just different stuff we work with on dialy basis. If I had to compile a similar list, I’d probably focus more on good OO practices, just like the stuff GL1zdA suggested, with extra focus on design and testing. Coming back to C#, it lets you use dynamic typing – and I think that understanding the differences between static and dynamic typing in 2017 is way more important than pointer arithmetics, even though using the “dynamic” keyword in C# should be treated like a potential code smell.

      • Scali says:

        a thing that separates men from boys among .NET devs.

        There you go again, that vacuum, see it? You are narrowing things down to ‘.NET devs’. A programmer is a programmer. You have certain skills or you don’t. .NET is just one of many frameworks available for programming. It is not programming.
        I never think in languages or frameworks. Programming in this context is a universal set of skills. I am talking about fundamentals. Bringing in languages, frameworks, or specific tasks/applications is missing the point.

        Also, do you really think high-performance graphics is the only exception? If so, why did you pick this one? (don’t tell me you based that on my blog’s contents, because I certainly did not have anything graphics-related in mind when I made this list).
        Have you never ever had to interface with any third-party tools, libraries, hardware or whatever, where the only SDK you could get was aimed at C/C++ programmers? Because I have, many times. Sure, sometimes there will be unoffical .NET wrappers out there, made by individuals. But that’s my point: you should *be* that individual that can build a wrapper. That’s the sort of thing that separates the men from the boys. The boys need a man to write a wrapper for them, the men write their own wrappers if the time comes (of course it should go without saying that you only write a wrapper if there are no good existing wrappers out there).

        Here’s the thing – I believe we’re both heavily biased by our work experience, and I wouldn’t call that a vacuum, just different stuff we work with on dialy basis. If

        Here’s the thing: I agree that *you* are biased. I however am aware of the vacuum that can exist if you never step out of your own world. So I always look around (heck I even did a blog on that sometime ago). Aside from that, I’ve been around for a long time now, and have worked various different jobs and various completely different areas of work within these jobs that you can hardly call me ‘biased’ anymore, based on the wide range of experience with programming languages, OSes, frameworks, libraries etc that I’ve racked up over the years.

        If I had to compile a similar list, I’d probably focus more on good OO practices, just like the stuff GL1zdA suggested, with extra focus on design and testing.

        Then why didn’t you? I clearly invited others to give more suggestions for the list.
        Instead, some people prefer to attack the items that I put on the list, rather than giving any suggestions themselves.
        Trying to get me to remove things from my list is futile. I put everything on there for a good reason, regardless of whether you agree with it or not (and as I already said before, the items on the list aren’t necessarily ‘best practice’ or even things I would encourage people to do. Just something that I think every programmer worth their salt should master, so they can handle the situation when they encounter it).
        All these attacks show me is that some people didn’t understand my point.

  10. veda says:

    Libraries what libraries?
    Not every project needs access to the Standard C library, some even can’t use the Standard C library, see kernel developers.

    • Scali says:

      Those aren’t skills I would expect every programmer to have, however.
      In an ideal world, I would think it’s nice that every programmer could write their own functions for string parsing, printing, sorting, linked lists, queues, hashtables and whatnot. But in practice I know that even though most university students had this in their first and/or second year, after graduation, they generally still won’t be able to do this.

      I think the big difference with the list I mentioned, is that programming environments generally take care of these problems for them, while the topics I put on the list are the ones you may run into because there is no workaround. You need to understand how memory management works, when you have to use some library that requires you to manually allocate/deallocate objects, for example.
      Just like you need to understand calling conventions when you have to import a third-party function from a library that doesn’t come with the proper header files for your particular development environment.
      Etc.

  11. Working in software localization, I think that those who still use ASCII in 2017 instead of Unicode should be hung by the balls.
    I’d also like to add the following two:
    – Hard-coding strings instead of storing them in an external file;
    – Still using old-style menus instead of the ribbon bar <3.
    The first one is acceptable in Python/Bash/Batch/What-have-you scripts for your eyes only, but running a disassembler just to extract text is an enormous PITA (and it's also more expensive to do).

  12. It’s a small big thing but I have encountered a lot of programmers who simply don’t TRY their code before putting it into production. Oh sure, “it compiles” and “I ran it once and it worked on my machine” but then it goes on a server or other peoples’ computers and they are caught with pants down as the thing falls apart. Hence I would say MEN think about and test their code from different angles whereas BOYS assume the magic of computing will save them the hassle (or maybe just don’t care). Unfortunately with the internet as a platform, this behavior has gotten even worse because it is so “easy” to patch things.

    A lot of programmers (of whom I would slap “junior” onto their title) are overly concerned with conventions and frameworks and not enough on logic skills, specific to their language or otherwise, that would make them strong at what they do. If a programmer would rather call a meeting than produce something, I’d call them a boy … and office work becomes daycare!

  13. Pingback: Experience and skill in software development | Scali's OpenBlog™

  14. Great list!

    I remember reading about a question regarding recursion in Abrash’ book first, where he did some job interviews for Redmond and none of the hopefuls was able to “convert” a recursive tree-traversal into an iterative approach. I immediately tried the “challenge” and was able to but it took a while… under tears, I mean sweat pearls, I realized how little I had understood the problem. Additionally as Michael pointed out in his book – the information is already there… which is such an important point and made me feel “double dumb”(TM)!

    I was rather disturbed when later in my “non-career” I attended a kind of “Fachhochschule”, which provided a CS like 3 year course, where that all penetrating “uuhhh… don’t touch the hardware” attitude was festering in “auto activate” mode. It especially depressing to have a programming teacher that wasn’t aware of the endianess of a machine, hostile to C and absolutely not interested in (reviewing) any code samples implementing “clever” things one might have come across when playing a game or using other software. He was talking about pointers like a radio show host about the Satanic Panic in the 80ies… why are such low quality people allowed to teach!?!
    Not all of the roster was like that, math, Linux and assembly dude being the notable exception but other than that it felt like a corporate bot academy. At university the attitude was more high quality but the “we’re so beyond the machine” attitude could be felt there too. Nonetheless, besides all “marxist” drivel, university provided some rough and tough base for surviving, or working with, more complex porblems.

    People in general are lazy and creatures of (bad) habit, so it’s understandable to go the easy route and just “skip over the details”… especially if you have the feeling that you’re to “slow” to get them. But such a low quality attitude may render one, in essence, a “fast food worker” instead of a “mini scientist”.

Leave a comment