Another trait is the belief that they either never need to touch their code after they write it, or worse, only they will ever touch their code. It fires me up to see code that was written with the complete intention of never coming back to it again, despite the fact that it has to be maintained to keep the business running - reports have to use the data it generates, other applications have to use it's services because we can't afford to keep re-implementing everything. I also really hate seeing code that seems like the dev locked themselves up in their basement for a decade to write it. All sorts of custom switches, hardcoded configuration values, experimental tech embedded so deep the only graceful way to relieve that debt is to nuke it.
When I started programming seriously I had a mentor who gave me a long list of my shortcomings. It's taken years of hard, dedicated work to rectify most of those problems and I still have a huge distance to cover to be as good as I want to be.
Being a good programmer is a skillet acquired with hard, concentrated effort over time; not just a good attitude with some self-awareness.
Being aware of what you are lacking allows you to improve on those things, work around those issues and accept when collegue is actually good at stuff you are not good at.
All of these examples make sense in the context of your business, but in some environments these might be best practice ;)
What are those environments? Can you be more specific?
High-risk systems where a software bug could result in loss of life - aviation, submarine tech, defense, medical etc. Edit: This is for throwing exceptions on undefined behavior.
For unlimited threads I imagine scenarios exist particularly when scalable computing is so popular. Large high traffic web stores such as Amazon/Ebay, financial institutions, etc. Either way, the problem shouldn't be solved by an individual developer on a project making things up as they go - its a problem that probably needs to be defined at a framework layer, and discussed within the team of developers and requirements definers.
Poor programmers do things like allowing an incoming request to spin up unlimited concurrent threads. Poor programmers erroneously throw exceptions on any operational deviation - even it if can be handled without error.
Most importantly - poor programmers do not learn from their mistakes and are unable to see that they are poor programmers.