What are the three common mistakes made by beginner programmers?

Comments (12)

Ben Buchanan (200ok)'s photo
  1. Not asking for help when they need it. You're a junior, you will need help.
  2. Asking for help without making a genuine attempt first. Seniors do know when you're taking the piss ;)
  3. Trying to do too many things at once. Learn one thing properly, not ten things badly. Bugfix one thing in isolation, don't change ten things at once then commit the lot when something works.

Balancing (1) and (2) is tricky. A really good strategy is time boxing. You are having a problem with something. Consider how long you think is reasonable to try on your own before you seek help (and go short - 1 hour? 1 morning? 1 day at most). By planning ahead a bit you essentially put a time limit on your own stress; plus you can plan to ask for help at an appropriate time.

Some totally hypothetical examples follow, I have not in fact been all four of these people at different times, not at all, you can't prove anything:

Bad: coming to your senior on the last day of the sprint, incoherent with frustration, having spent days trying to fix a low-story-point bug. You've changed everything, tried everything, nothing works. You've got fourteen git branches named things like fix5 and a nice collection of red builds; and you're starting to wonder why the hell you thought coding was a good idea. Meanwhile your senior just mentally scrubbed the chances of finishing what they were working on; and are starting to wonder why the hell they thought taking on some leadership duties was a good idea.

Good: you spend an afternoon having a solid go at solving a problem. You've tried A, B and C; but three tests are still failing and you don't know what to try next. At standup the next morning you ask a senior to give you a hand with it, because you're not sure what to try next. They say yes, they'll help you after they grab a coffee.

Realistically the second dynamic persists well beyond junior/senior, it's really how things always go when you need help from someone who knows a topic better than you do. So you might as well get used to it as soon as possible ;)

Show all replies
Ben Buchanan (200ok)'s photo

I make some bits of the web.

Mark the amount of time does depend on the size of the task, but I should probably have said "a couple of hours" rather than "an afternoon" :) Still, I tend to be pretty generous with time for junior devs. They need the space to be able to look up some information, try a few different things, break stuff, fix it again, learn those incidental things that haven't come up before, etc.

Ivan Bacher's photo

1) Missing semicolons

2) Copy/paste from Stackoverflow without understanding the code and expecting everything to work.

3) Writing code with no indentation


Show all replies
Steven Ventimiglia's photo

Creative Technologist & Sr. Front-End Developer

Because that person would be mistaking precision with effort. ;) They may not even realize that it's indentation, which is properly managed by tabs. You either indent or space.

All I need to do is force them all to work within a Python environment so they can find where code was broken by using spaces instead of tabs. Most of the time, they will call this a "whitespace issue", however, I feel the issue is more about wanting to do things "our way"... even if it's not the correct way. It's one of the reasons I love Golang; either your syntax will be consistent and useable, or it ain't building squat.

Then, once you get past the debate of Spaces vs Tabs; it becomes about two (2) tabs, "...nesting statements too close to each other", and four (4) tabs ,"...wasting too much space."

I use tabs, and I even go a step further. Two tabs for HTML/CSS/SCSS. Four tabs for JavaScript. The reason is that I feel less of a need to have my static code spaced as much, but like to have blocks of functionality to be a bit more "aired out" - also, doing the same with PHP, Python, Go, etc.

Mark's photo

This is probably not really for first-few-months beginners...

  • I did not yet realize how different 1-month personal projects are from large-scale projects made by big teams. Suddenly you don't know all of the code anymore, you have to make assumptions about what other code does, have to follow conventions, the percentage time spend finding bugs goes way up and all timescales in general increase by an order of magnitude.
  • I thought type systems are useless, or are only useful for performance. In reality, they help rule out a lot of bugs at compile time, which is absolutely where you want your bugs ruled out, and they are documentation that doesn't get outdated.
  • I didn't try to fail as fast as possible. It would seem kind of convenient if the program kept running if I'd forget to pass an argument, or would get null for a a non-existent hashmap key, or when dividing by zero. At least the program was still running, right? Well, it shouldn't be. A clear error is much better than a wrong/undefined result in most cases. If you're unsure about something, make it fail loudly until you are sure. In development, you'll want to move all your errors in this direction: continue with wrong result -> fail with stacktrace -> unit test failure -> compile time error.
  • I almost always underestimated the time needed for anything (I kind of still do). I don't know if that's specific for programming. But it takes a lot of experience to be able to make any kind of reliable time estimate.

One day, you will wish your problem were as immediately apparent and easy to find as a missing semicolon...

As an example of the third point:

  • "Continue with wrong result": e.g. Javascript uses toString as its hash function for maps, and does not do equality checking, and returns undefined for missing values, so if you use the wrong key by accident, you'll later find out the result is undefined if you're lucky. If you're not lucky, you get the wrong object back and pay 10.000€ to the wrong person. You could move this to "fail with stacktrace" by using something like Python (of course, in the browser, you probably can't...).
  • "Fail with stacktrace" might happen in many cases where you're solving a bug and don't want it to come back. Lets say your method constructs an SQL query, but when using it with some combination of patameters, you find that you forgot a space and your database rejects it. You then write a unit test for various parameter combinations, which causes this and any future SQL syntax errors: "unit test failure" reached. (Which should in turn prevent you from merging the feature into the main code).
  • "Unit test failure" could be the above case, which might become a compile-time error by using a type-safe query builder. Or you might be getting a null-pointer, so you switch to a non-nullable type (in e.g. Kotlin, Swift, variables can be nullable or non-nullable), or you use Java's crappy approximation Optional (or primitives).
  • As an example of going straight from "continue with wrong result" to "compile time error", and to illustrate my second point, lets say you might make the mistake of comparing Person.id with Customer.id, which does not make sense because they're different tables. Well, if they're not compatible, they're not really the same type of thing, are they? But chances are that the are both integers in the code. So instead you convert them to Id<Person> and Id<Customer> respectively. This won't be possible in a dynamic language, and it will only help a little in e.g. Java that implements .equals(Object) by default. But in e.g. Rust, you just don't make Id<Person> and Id<Customer> comparable, and it will simply fail to compile if you ever make the mistake. More info.

I know this is not really beginner level, but it took me long to realize, so I want to save you a year or two!

Jason Knight's photo

The less code you use, the less there is to break

In reality, they help rule out a lot of bugs at compile time

Hence the joke about shooting yourself in the foot in programming languages. Pascal won't let you shoot yourself in the foot. Any decent compiler shouldn't be letting bugs compile and run in the first place -- and really interpreted languages that have a pre-parsing stage should be implemented with the same mentality.

... which is why it's so annoying that so many languages do not take this approach and just blindly plod on as if nothing is wrong past stuff that flat out shouldn't even compile.

But then I spent a decade working in ADA. You want a language that doesn't let you compile mistakes?

I almost always underestimated the time needed for anything (I kind of still do). I don't know if that's specific for programming. But it takes a lot of experience to be able to make any kind of reliable time estimate.

"Ach laddy, ya didnae tell 'im how long it would REALLY take, did ya?!?"

Call me Scotty

One of the earliest lessons I learned in programming was to "Mr. Scott" all my time estimates. You figure out how long it should REALLY take to the best of your ability.... then you double it when talking to the client.

A good Engineer is always a wee bit conservative, at least on paper.

It is always better to deliver ahead of schedule than to be late. It is very easy to give a time estimate for if everything goes right -- rarely does everything go right even from the very start, so you HAVE to give yourself that wiggle room... doubling the estimate is typically overkill, but it's a responsible approach to the problem.

... one that is a constant battle what with the "we want everything yesterday" mentality of clients with utterly unrealistic expectations.

Just don't let such doubling make you lazy because "we've got the time" -- what you tell the boss/client/what-have-you and the schedule you plan for yourself should be two separate things!

Mike Chilson's photo
  1. Trying to memorize syntax.
  2. Not asking for help.
  3. Preoptimizing their code before it's even working.
Jason Knight's photo

1) "Wah wah, eye dunz wanna types" -- it is terrifying how many beginners flat out refuse to use verbose meaningful variable and function names, or try to skip "optional" bits of languages costing clarity, or fail to maintain good indentation habits, or become over-reliant on the automation of IDE's and fancy editors to try and do their typing for them. It all boils down to lame excuses for not wanting to type... and really if you don't want to type you really aren't serious about programming.

2) "Blind Copypasta" -- Diving straight for frameworks and off the shelf components they don't even understand the workings of, as opposed to learning how/why things work, how/why things would/should be done, and in general leaving them hobbled in terms of recognizing if said code is any good, worth using, or just an outright scam. See such mind-numbing asshattery bootcrap or any other front-end HTML/CSS "framework" as proof of that; the folks using and promoting such systems clearly not knowing the first damned thing about HTML or CSS... but thanks to that lack of knowledge they get suckered into thinking such garbage is worthwhile, using terms like "easier" or "simpler' or "makes me more productive" when it in fact has the exact opposite effect!

I mean, you will be copying code from time to time, but if you're going to use it take the time to understand what it does, why it does it, why it chose to do it that way, and to double-check if it violates good practices or not. If it flies in the face of how the underlying languages were even meant to be used in the first place, it's probably not a great choice.

3) "Wah wah, sumbuddies usededed teh h4rsh wurds!!!" -- You're a beginner, you're going to write trash code. You're going to get duped and suckered by nube predating scam-bait BS like W3Schools. You're going to use bad practices... so when someone starts belting out a laundry list of what you did wrong, attacking whatever source you learned them from that's NOT an attack on YOU personally. Suck it up and LEARN, if you don't recognize what's being said RESEARCH the terms being used instead of going all crybaby over it.

It's often shocking how a simple post reviewing a website's code such as:

On the surface you have illegible colour contrasts, uselessly undersized fixed metric (pixel measurement) font sizes, non-elastic layout, and broken responsiveness. There's no scripting off graceful degradation or at least warning messages telling a large swath of potential users to sod off. It appears to be wasting 100k of markup on 5k of plaintext and half a dozen images -- something there's no legitiamte excuse to be wasting more than 10-12k of markup on. Popping the bonnet to look at the code you have a complete lack of semantics, gibberish use of numbered headings resulting in a broken document structure, endless pointless DIV for nothing, endless pointless classes for nothing, static style in the markup, static scripting in the markup, and a host of other "how not to build a website" failings so common to the scam bait that is bootcrap.

Will result in beginners -- and even some alleged experts -- getting their soft little panties in a knot. Instead of going "wah wah" maybe one should bother trying to understand what they're being told? You're a beginner, you know jack at this point, so don't be surprised or get offended when someone DARES to tell you what you're doing wrong!

Steven Ventimiglia's photo
  1. Thinking they can become a true front-end developer without producing HTML, CSS, and Vanilla JavaScript on an optimal level, by hand.
  2. Using a framework before fully understanding the language and tools that it's based on.
  3. Assuming that 2-4 years of college has prepared them for the real world.