I have recently been involved in the overhaul of an established business with poor output into a functioning early/mid stage startup (long story). We are back on track but, honestly, my lessons learned fly in the face of a lot of currently accepted wisdom:
1) Choose languages that developers are familiar with, not the best tool for the job
2) Avoid microservices where possible, the operational cost considering devops is just immense
3) Advanced reliability / redundancy even in critical systems ironically seems to causes more downtime than it prevents due to the introduction of complexity to dev & devops.
4) Continuous integration seems to be a plaster on the problem of complex devops introduced by microservices.
5) Agile "methodology" when used as anything but a tool to solve specific, discrete, communications issues is really problematic
I think overall we seem to be over-complicating software development. We look to architecture and process for flexibility when in reality its acting as a crutch for lack of communication and proper analysis of how we should be architecting the actual software.
Is it just me?
Switching from Hadoop to Spark was clearly a good idea for our team, even though it required learning a new stack, but there isn't a strong reason to switch to Flink or start using Haskell.
Agile makes sense when your main risk is fine-grained details of user requirements, but not when you have other substantial risks, such as making sure a statistical algorithm is accurate enough.
Microservices probably reduces the asymptotic cost of scaling but add a huge constant factor.
Relational databases are the right choice 95% of the time, non-relational stores require a really specific use case.
TDD is good for fast feedback in some domains, but for others, manually investigating the output or putting your logic into types is better. E.g. a lot of my time comes from scaling jobs that work on 10gb of data but crash on 1tb, TDD is not that helpful here.
Continuous integration mostly makes sense when you're making a lot of small changes and can reliably expect a test suite to catch issues.
In short, ask the question "when is practice X useful?" instead of "is practice X a good idea?"