[quote user="CDarklock"]My understanding of GC is only as deep as this: "if the language is garbage collected, I don't have to worry about releasing memory". I have a vague awareness that sometimes your GC blows and you should jump through a couple hoops to make the GC work better, but I really don't care about the specifics. I just want to know where I can find an expert who can point out the hoops. But if your project happens to be a new garbage-collected language, you'd better find someone who's an expert on garbage collection, and that will almost certainly not be me.[/quote]But the fact that, say, Java and C# are garbage-collected and C++ is not has direct bearing on writing correct code when you're dealing with resources and when to close them. In C++, you must ensure that the destructor properly releases your resources, and that you properly scope all your object instances, otherwise you'll get leaks. In Java, there are no destructors and you don't necessarily need to explicitly scope objects, but you can't assume that everything will get collected in a timely manner or you'll get short-term resource leaks. So you don't need to know the details of the GC itself, but the implications of what the GC does have important implications on the code that runs under it.
I find it's the ones who know just enough about something to be dangerous that are often the source of some of the more frustrating bugs. Off-by-one errors are common enough with junior developers, but it's the more-seasoned ones that are less experienced in a given environment that cause deeper errors. The following were done by supposedly-seasoned developers:
* Code in Java that used JDBC objects without explicitly closing connections, statements, or result sets. This bears directly on the "short-term leak" thing above, as these automatically get closed when they're finalized by the GC. However, if you don't close them when you're done with them, those resources on the database server continue to be allocated until you happen to run out of memory in the **JVM**, rather than running out of cursors in Oracle.
* Code in C++ that stored references to stack-scoped objects. Most of the time, these would get consumed before the stack-based objects got trashed, but once in a while not. This would result in low-frequency, unpredictable, hard-to-reproduce errors.
* Code in C++ that had template parameters on a base class for the sole purpose of adding unnecessary parameters on some of its methods. Some of this was to emulate covariant overrides, but other times it was to avoid extrapolating a base class for other method parameter types. All this really did was increase the code size dramatically, as all of the methods in the base class needed to be instantiated again for each derived class. This isn't arguably a bug, but it produced bloated code that was harder to maintain and sucked up page memory like a sponge.
Yes, one can program with a broad understanding, but I think one needs deeper subject knowledge more frequently than your comment suggests. It doesn't necessarily need to reside in each developer, but you should then have an expert doing code reviews to make sure esoteric language-specific details don't bite.