10 mistakes every programmer makes
-->
Consider the systems that will be running your code toward avoid performance issues further down the line.When you start programming, you get disillusioned quickly. No longer is the computer the allinfallible perfect machine – "do as I mean, not as I say" becomes a frequent cry. At night, when the blasted hobgoblins finally go toward bed, you lie there furthermore ruminate at the errors you made that day, furthermore they're worse than any horror movie. So when the editor ofPC Plus asked me toward write this article, I reacted with both fear furthermore knowing obedience. I was confident that I could dash this off in a couple regarding hours furthermore nip down toward the pub without the usual resultant night terrors. The problem with such a request is, well, which language are we talking about?I can't just trot out the top 10 mistakes you could make in C#, Delphi, JavaScript or whatever – somehow my top ten list has toward encompass every language. Suddenly, the task seemed more difficult. The hobgoblins started cackling in my head. Nevertheless, here goes…
1. Writing beneficial to the compiler, not beneficial to people
When they use a compiler toward create their applications, people tend toward forget that the verbose grammar furthermore syntax required toward make programming easier is tossed aside in the process regarding converting prose toward machine code. A compiler doesn't care if you use a single-letter identifier or a more human-readable one. The compiler doesn't care if you write optimised expressions or whether you envelop sub-expressions with parentheses. It takes your human-readable code, parses it into abstract syntax trees furthermore converts those trees into machine code, or some kind regarding intermediate language. Your names are by then history. So why not use more readable or semantically significant identifiers than just i, j or x? These days, the extra time you would spend waiting beneficial to the compiler toward complete translating longer identifiers is minuscule. However, the much-reduced time it takes you or another programmer toward read your source code when the code is expressly written toward be self-explanatory, toward be more easily understandable, is quite remarkable. Another similar point: you may have memorised the operator precedence toward such a level that you can omit needless parentheses in your expressions, but consider the next programmer toward look at your code. Does he? Will he know the precedence regarding operators in some other language better than this one furthermore thereby misread your code furthermore make invalid assumptions about how it works? Personally, I assume that everyone knows that multiplication (or division) is done before addition furthermore subtraction, but that's about it. Anything else in an expression furthermore I throw in parentheses toward make sure that I'm writing what I intend toward write, furthermore that other people will read what I intended toward say. The compiler just doesn't care. Studies have shown that the proportion regarding some code's lifecycle spent being maintained is easily five times more than was spent initially writing it. It makes sense toward write your code beneficial to someone else toward read furthermore understand.
2. Writing big routines
Back when I was starting out, there was a rule regarding thumb where I worked that routines should never be longer than one printed page regarding fan-fold paper – furthermore that included the comment box at the top that was fashionable back then. Since then, furthermore especially in the past few years, methods tend toward be much smaller – merely a few lines regarding code. In essence, just enough code that you can grasp its significance furthermore understand it in a short time. Long methods are frowned upon furthermore tend toward be broken up. The reason is extremely simple: long methods are hard toward understand furthermore therefore hard toward maintain. They're also hard toward test properly. If you consider that testing is a function regarding the number regarding possible paths through a method, the longer the method, the more tests you'll have toward write furthermore the more involved those tests will have toward be. There's actually a pretty good measurement you can make regarding your code that indicates how complex it is, furthermore therefore how probable it is toward have bugs – the cyclomatic complexity. Developed by Thomas J. McCabe Sr in 1976, cyclomatic complexity has a big equation linked toward it if you're going toward run through it properly, but there's an easy, basic method you can use at the fly. Just count the number regarding 'if' statements furthermore loops in your code. Add 1 furthermore this is the CC value regarding the method. It's a rough count regarding the number regarding execution paths through the code. If your method has a value greater than 10, I'd recommend you rewrite it.
3. Premature optimisation
This one's simple. When we write code, sometimes we have a niggling devil at our shoulder pointing out that this clever code would be a bit faster than the code you just wrote. Ignore the fact that the clever code is harder toward read or harder toward comprehend; you're shaving off milliseconds from this loop. This is known as premature optimisation. The famous computer scientist Donald Knuth said, "We should forget about small efficiencies, say about 97 per cent regarding the time: premature optimisation is the root regarding all evil." In other words: write your code clearly furthermore cleanly, then profile toward find out where the real bottlenecks are furthermore optimise them. Don't try toward guess beforehand.
4. Using global variables
Back when I started, lots regarding languages had no concept regarding local variables at all furthermore so I was forced toward use global variables. Subroutines were available furthermore encouraged but you couldn't declare a variable just beneficial to use within that routine – you had toward use one that was visible from all your code. Still, they're so enticing, you almost feel as if you're being green furthermore environmentally conscious by using them. You only declare them once, furthermore use them all over the place, so it seems you're saving all that precious memory. But it's that "using all over the place" that trips you up. The great thing about global variables is that they're visible everywhere. This is also the worst thing about global variables: you have no way regarding controlling who changes it or when the variable is accessed. Assume a global has a particular value before a call toward a routine furthermore it may be different after you get control back furthermore you don't notice.
Of course, once people had worked out that globals were bad, something came along with a different name that was really a global variable in a different guise. This was the singleton, an object that's supposed toward represent something regarding which there can only be one in a given program. A classic example, perhaps, is an object that contains information about your program's window, its position at the screen, its size, its caption furthermore the like. The main problem with the singleton object is testability. since they are global objects, they're created when first used, furthermore destroyed only when the program itself terminates. This persistence makes them extremely difficult toward test. Later tests will be written implicitly assuming that previous tests have been run, which set up the internal state regarding the singleton. Another problem is that a singleton is a complex global object, a reference toward which is passed around your program's code. Your code is now dependent at some other class. Worse than that, it's coupled toward that singleton. In testing, you would have toward use that singleton. Your tests would then become dependent at its state, much as the problem you had in testing the singleton in the first place. So, don't use globals furthermore avoid singletons.
5. Not making estimates
You're just about toward write an application. You're so excited about it that you just go ahead furthermore start designing furthermore writing it. You release furthermore suddenly you're beset with performance issues, or out-of-memory problems. Further investigations show that, although your design works well with small number regarding users, or records, or items, it does not scale – think regarding the early days regarding Twitter beneficial to a good example. Or it works great at your super-duper developer 3GHz PC with 8GB regarding RAM furthermore an SSD, but at a run-of-the-mill PC, it's slower than a Greenland glacier in January. Part regarding your design process should have been some estimates, some back-back-of- the-envelope calculations. How many simultaneous users are you going toward cater for? How many records? What response time are you targeting? Try toward provide estimates toward these types regarding questions furthermore you'll be able toward make further decisions about techniques you can build into your application, such as different algorithms or caching. Don't run pell-mell into development – take some time toward estimate your goals.
6. Off by one
This mistake is made by everyone, regularly, all the time. It's writing a loop with an index in such a way that the index incremented once too often or once too little. Consequently, the loop is traversed an incorrect number regarding times.
If the code in the loop is visiting elements regarding an array one by one, a non-existent element regarding the array may be accessed – or, worse, written toward – or an element may be missed altogether. One reason why you might get an off-by one error is forgetting whether indexes beneficial to array elements are zero-based or one-based. Some languages even have cases where some object is zero-based furthermore others where the assumption is one-based. There are so many variants regarding this kind regarding error that modern languages or their runtimes have features such as 'foreach loops' toward avoid the need toward count through elements regarding an array or list. Others use functional programming techniques called map, reduce furthermore filter toward avoid the need toward iterate over collections. Use modern 'functional' loops rather than iterative loops.
7. Suppressing exceptions
Modern languages use an exception system as an error-reporting technique, rather than the old traditional passing furthermore checking regarding error numbers. The language incorporates new keywords toward dispatch furthermore trap exceptions, using names such as throw, try, finally furthermore catch. The remarkable thing about exceptions is their ability toward unwind the stack, automatically returning from nested routines until the exception is trapped furthermore dealt with. No longer do you have toward check beneficial to error conditions, making your code into a morass regarding error tests. All in all, exceptions make beneficial to more robust software, providing that they're used properly. Catch is the interesting one: it allows you toward trap an exception that was thrown furthermore perform some kind regarding action based upon the type regarding the exception. The biggest mistakes programmers make with exceptions are twofold. The first is that the programmer is not specific enough in the type regarding exception they catch. Catching too general an exception type means that they may be inadvertently dealing with particular exceptions that would be best left toward other code, higher up the call chain. Those exceptions would, in effect, be suppressed furthermore possibly lost. The second mistake is more pernicious: the programmer doesn't want any exceptions leaving their code furthermore so catches them all furthermore ignores them. This is known as the empty catch block. They may think, beneficial to example, that only certain types regarding exceptions might be thrown in his code; ones that they could justifiably ignore. In reality, other deadly runtime exceptions could happen – things such as out-of-memory exceptions, invalid code exceptions furthermore the like, beneficial to which the program shouldn't continue running at all. Tune your exception catch blocks toward be as specific as possible.
8. Storing secrets in plain text
A long time ago, I worked in a bank. We purchased a new computer system beneficial to the back office toward manage some kind regarding workflow dealing with bond settlements. Part regarding my job was toward check this system toward see whether it worked as described furthermore whether it was foolproof. After all, it dealt with millions regarding pounds daily furthermore then, as now, a company is more likely toward be defrauded by an employee than an outsider. After 15 minutes with a rudimentary hex editor, I'd found the administrator's password stored in plain text. Data security is one regarding those topics that deserves more coverage than I can justifiably provide here, but you should never, ever store passwords in plain text. The standard beneficial to passwords is toward store the salted hash regarding the original password, furthermore then do the same salting furthermore hashing regarding an entered password toward see if they match.
Here's a handy hint: if a website promises toward email you your original password should you forget it, walk away from the site. This is a huge security issue. One day that site will be hacked. You'll read about how many logins were compromised, furthermore you'll swallow hard furthermore feel the panic rising. Don't be one regarding the people whose information has been compromised and, equally, don't store passwords or other 'secrets' in plain text in your apps.
9. Not validating user input
In the good old days, our programs were run by individuals, one at a time. We grew complacent about user input: after all, if the program crashed, only one person would be inconvenienced – the one user regarding the program at that time. Our input validation was limited toward number validation, or date checking, or other kinds regarding verification regarding input. Text input tended not toward be validated particularly. Then came the web. Suddenly your program is being used all over the world furthermore you've lost that connection with the user. Malicious users could be entering data into your program with the express intent regarding trying toward take over your application or your servers. A whole crop regarding devious new attacks were devised that took advantage regarding the lack regarding checking regarding user input. The most famous one is SQL injection, although unsanitised user input could precipitate an XSS attack (crosssite scripting) through markup injection.
Both types rely at the user providing, as part regarding normal form input, some text that contains either SQL or HTML fragments. If the application does not validate the user input, it may just use it as is furthermore either cause some hacked SQl toward execute, or some hacked HTML/JavaScript toward be produced. This in turn could crash the app or allow it toward be taken over by the hacker. So, always assume the user is a hacker trying toward crash or take over your application furthermore validate or sanitise user input.
10. Not being up toward date
All regarding the previous mistakes have been covered in depth online furthermore in various books. I haven't discovered anything new – they furthermore others have been known beneficial to years. These days you have toward work pretty hard toward avoid coming into contact with various modern design furthermore programming techniques. I'd say that not spending enough time becoming knowledgeable about programming – furthermore maintaining that expertise – is in fact the biggest mistake that programmers make. They should be learning about techniques such as TDD or BDD, about what SLAP or SOLID means, about various agile techniques. These skills are regarding equal or greater importance than understanding how a loop is written in your language regarding choice. So don't be like them: read McConnell furthermore Beck furthermore Martin furthermore Jeffries furthermore the Gang regarding Four furthermore Fowler furthermore Hunt & Thomas furthermore so on. Make sure you stay up toward date with the art furthermore practice regarding programming.
And that concludes my top 10 list regarding mistakes programmers make, no matter what their language stripe. There are others, toward be sure, perhaps more disastrous than mine, but I would say that their degree regarding dread is proportional toward the consequences regarding making them. All regarding the above were pretty dire beneficial to me the last time I made them. If you have further suggestions or calamities regarding your own, don't hesitate toward contact me furthermore let me know.