Are deadlocks always a symptom of design flaws or are they an unavoidable occurrence even in well designed systems with high data writes/reads?
I am of the opinion that deadlocks are always the symptom of design flaws


With READ COMMITTED SNAPSHOT set, and foreign keys supported by indexes, deadlocks should be treated as application bugs.  

That's not to say you'll never see a deadlock, or that you won't have to introduce locking hints to serialize access to objects.  

But with RCSI, deadlocks should be rare enough that they can be individually diagnosed and remediated, as opposed to using a retry loop or resorting to dirty reads.