Hacker News new | ask | show | jobs
by alerighi 1762 days ago
To me competitive programming doesn't make you a good software engineer.

It will teach you bad practices, like abusing of dangerous programming constructs or data structures to optimized the code or just save some typing while writing the code (like one letter variable names, macros, etc), global variables and state in the program, not using common design patterns, not using OOP, not documenting the code and in general writing code that is difficult to maintain because it's not well engineered. You would say that a person would do that only in competition, but in my experience I saw that is not true, because if you learn to program a particular way, you would do the same also in other contexts.

Also, the competences that you will acquire by doing competitive programming are next than useless: in the real life I've yet to encounter a situation in which I have to use an algorithm used in a competitive programming competition (yes, I did them with even good results). And if you need them, you don't implement them yourself, but you use a library that manages all the work. The Dijkstra implementation that most competitive programmers use is a toy implementation, not something that you would never use in any sort of enterprise software.

The fundamental skill that competitive programming doesn't teach you, that to me is the most important thing for a good software engineer, is using Google to find documentation online. Most of the errors I see by young software engineers could easily been prevented if they did a simple Google search and read the official documentation (not a random blog post)! And yet in competitive programming you are forbid to use the internet, to me it's stupid, it's like requiring to write code with a typewriter just because in the past keyboards and monitors didn't exist.

6 comments

> It will teach you bad practices, like abusing of dangerous programming constructs or data structures to optimized the code

If someone can't weigh up the pros and cons before using a particular technique, they're going to be a bad software engineer anyway. The field is all about making the right tradeoffs in particular situations, and blindly following current generalised "best" practices without really understanding what they're meant to be better than is going to get you into trouble too.

Breadth of knowledge and experience is a great thing. If you follow from the start that OOP is the right and only way to do things for example, you're not going to have a feel for when it gets in the way. Actually knowing what it's like and what happens when you do something the "bad" way is very valuable experience too e.g. you're going to be a better coder if you'd had to battle with buffer overflows and memory leaks in C in the past even if now you only use Java and Python.

This kind of logic really bugged me after moving from academia into industry. In academia for example, it's usually the right choice to make quick and dirty prototypes to get the results you need for a paper and not burn time over-engineering it. This doesn't mean I don't how to clean up code. I would also say it gives me more experience on avoiding over-engineering compared to someone that tries to copy best practices all the time.

> It will teach you bad practices, like abusing of dangerous programming constructs or data structures to optimized the code or just save some typing while writing the code (like one letter variable names, macros, etc), global variables and state in the program, not using common design patterns, not using OOP, not documenting the code and in general writing code that is difficult to maintain because it's not well engineered.

These are not “bad practices”. Many of them are bad in certain common contexts, but literally none of them are bad in throw-away code used in the course of root-cause-analysis of problems in other code basis, and most are useful in many parts of proof of concept code. In working on production systems, most of the volume of code I produce isn’t production code, and has a very different set of constraints than production code.

And given history on HN, whether “not using OOP” is ever a “bad practice” is probably a whole discussion of its own.

And if the proof of concept does work, you take all the code that you written, throw it away and rewrite it? Probably not. I've seen too much "proof of concepts" go into production because they worked. Except when someone else had to actually maintain the thing and the person that wrote it leaved the company 1 year before.

There is not proof of concept code to me. Every line of code that I write professionally I write it to the higher standards. That doesn't mean over engineering it, but it means writing it in a way that is maintainable and understandable by others. I can compromise on functionality, of course in a proof of concept I implement only the things that I need, but not on code quality.

Even if I have to write a script that I know it will have to be used once and never again I will write it in a good way, you never know if you need it again, if a coworker does need to do a similar thing and you can just give to him as reference, or if you can take pieces to do other things.

Competitive programming doesn't teach you only algorithms and data structures, it teaches you to think very clearly about program flow, edge cases, debugging etc., points which you seem to just gloss over from the comment you're replying to, just to justify a conclusion you had already reached.
definitely, alot of the "algorithms" in leetcode practice look deceptively simple on the surface, but deep down, there are lots of edge cases and are good practice to think deeply about them

on the otherhand, they can also encourage messy and hard to maintain code, or super efficient implementation can be brittle which you dont want in production unless there is a really really good reason...

if "competitive coding" also judge on other criteria such as clarity, readability and maintainability, in addition to efficiency and "correctness" that would be great imo

Not using design patterns seems like pure upside.

I don't think it's reasonable to use a library for most things one implements in competitive programming, because the work of getting your problem instance in and out of the library is probably greater than the work of writing the solution yourself, in code length and in runtime. As an example, the only time I ever needed to use A* was on a state space that was larger than the main memory of any computer on Earth. I don't expect that I can download a library that does A* on abstract state spaces not fully present in RAM for me, but I can just bash out my own A* that's fused with the definition of the state space. Maybe this is so easy to do partially because I did a bunch of programming contests in which I wrote BFSes that were fused with the definitions of graphs.

> I don't expect that I can download a library that does A* on abstract state spaces not fully present in RAM for me

I'm sure this does exist! A functional library where you pass in, not a pointer to the set of all nodes, but some functions to get the node with the current lowest distance and to update the distance of a node.

Not saying it was the right thing for your use case, but don't rule it out. Even in languages that aren't strongly FP - eg it happens a lot in Go due to the lack of generics, and if you squint, the C++ STL is kind of like this.

It's not. Because then someone else has to maintain the code you written, and if he cannot see any common pattern in your code he will make 10x the effort to understand the code, that means wasting time and thus loosing money for the company.
Is this about the design patterns or the A*? Design patterns are a mix of techniques to pay complexity make code extensible that usually will not ever be extended and workarounds for the deficiencies of a specific family of languages. An example I posted about previously is that you could spend hundreds of lines across a dozen files implementing double dispatch, or you could use dramatically less if you aren't implementing it in terms of a language-provided dynamic-dispatch-on-the-first-argument-only primitive.

It is nice to write code that can be understood by the next reader. To explain what our invariants are and what we are up to, we have comments.

Not using OOP is a bad practice? That's a hard sell.
> It will teach you bad practices

Agreed, everything that makes good contest code is a bad thing for production code. In a contest you just want to hack together something as quickly as possible, it only needs to work once, will never be maintained or documented.

It's all good fun as a sport, but nobody should consider it relevant to working on production code.