I've had the pleasure as a developer of working with some amazing teams on some beautiful projects. Their onboarding process was good, the documentation was complete, there was a full suite of automated tests, continuous integration and code reviews.
Those kinds of projects are a joy.
But that's not what this post is about.
I've worked on some difficult projects that were the complete opposite. No testing, no automation, documentation that hadn't been updated in 6 months, and nobody knew what changes were being made because there were no pull requests or code reviews.
There's usually a combination of typical reasons for this state of affairs. Often it was pressure from management or unrealistic changes in scope happening at the last minute. Some teams tried to use a Scrum process and succeeded in doing sprints and daily standup meetings but it didn't make things better.
The root problem wasn't just the lack of a process, it was typically the lack of resources combined with an over-reliance on technical debt.
I don't have the best memories of those terrible projects, but at the same time I realize that I learned a lot of important lessons.
I learned things that I didn't even realize were important when I was working on well-organized projects.
When we're thinking theoretically of "best practices", it's easy to think in a vacuum where real-world pressures and restrictions don't apply. But in reality, every project is a collection of trade-offs and compromises between different pressures being applied to it. There's never unlimited time or resources. You have to make a lot of difficult choices.
Most technical debt out there doesn't happen because of ignorance or incompetence. It happens because of choices where sacrifices have to be made because of outside limitations and pressures.
Startups are a good place to find a lot of lessons to learn. I've worked for a few startups and a good number of them are now dead. I consider that a lucky outcome for me, because it has given me a glimpse into what not to do as an entrepreneur.
I've seen all kind of reasons for startup implosion: mis-management of resources, founder disputes and drama, lack of understanding of the target market, waiting too long to ship something.
Interestingly, software development itself seems to be the least likely cause for failure in the cases that I've seen. The customer almost never cares about the code. They care about the problem that you're solving for them.
Meanwhile, in the startups where I worked which did succeed, while I gained a lot of insight about entrepreneurship, I didn't learn as many deep, hard lessons.
Maybe it's because there is really just one way to succeed in entrepreneurship. Make something that solves a real problem for real customers. But there are many ways to fail. There's a ton of ways to do it wrong, and so there's a ton of potential lessons there.
I like to think of this as the sponge principle for learning.
What's the best way to learn on the job? Absorb everything you can. Like a sponge.
Where is a sponge going to absorb the most? In places where it's wet and messy. Where there's stuff to absorb.
In contrast, imagine trying to absorb anything by running your sponge over a clean, dry counter top. You're not going to get much out of it.
Be a sponge and learn from what's happening around you. Not just from your own work: learn from your peers, from your managers. Learn from what the company founders are doing. Learn from what's going on in marketing and in customer support.
One last thing. All this has to come with a reminder. Don't stay at a shitty workplace for long. Leave when you can. Definitely leave if you're no longer learning anything.
Watch out for people who talk about company loyalty or tell you that you should wait X amount of time before switching jobs. You don't owe your employer anything beyond the work/salary transaction. If it's bad, get out of there. Burnout is never worth it.