When I was a younger, I participated in many piano competitions and festivals where each of the competitors would take turns playing a repertoire of songs in front of an adjudicator who would provide us written constructive feedback on how we played our pieces and awarded prizes to the top three. For the first couple of years, the negative feedback got to me. I'd practice my pieces for months and months; playing every note perfectly, comparing artistic interpretations, committing them to memory so deeply I could play them blindfolded. Feedback was always very objective but the objectivity didn't stop me from sometimes taking it personally. I had the time. I put in the effort. Perhaps I would have done better if I were a better pianist.
I stopped competing in high school because I wanted to start playing songs from this decade or more accurately, the ones that impressed the girls at school. Somewhere near the end of highschool, I did pretty well – I made enough scholarships to feel “rich” as a young teenager.
It's actually not so different from what I do now. Picture this: You've got a new feature to build. It's an empty slate and that's beautiful – you can steer the ship in whatever direction you'd like.
What can this look like? How does data flow? Can we batch it? Maybe we have stream it instead? Should we use Redis? Would Kafka work better? You speak to product and design to make sure you've completely dialled on the right thing to build. You have no idea what they mean by alignment but you're glad it means that you can build what you want to build. You sit down putting pen to paper (keyboard to IDE?) and craft something great, bringing your ideas to life. You consider trade-offs, you follow good engineering practices, you implement caches where you need them, you make proper abstractions.
git commit -m “hey everyone i've built this wonderful thing with my own two hands and i want you all to see it”. CI is green, and you request reviews. You come back from a well deserved coffee break to look at your pull request and what was once a flawless creation now looks like the result of a school assigment you did not even remotely understand.
…What is the rationale behind using this data structure here? …This variable doesn't ever change, why did you not make it immutable? …What is this function doing here? It breaks the design pattern you've set for the rest of the project. …This is not easily readable, I suggest breaking the lambda out into a function so it's obvious what's happening here. …This isn't PEP8. …Be more consistent with your class naming. …What does this do? …Why is this written this way?
You don't need to read the rest– your brain reflexively summarizes them for you: why am I not a better engineer?
There's a fallacy that doing things perfectly the first time is the right way to do things. This can stem from years of school where tests, assignments, and exams gave you one opportunity to get things right and all of your subsequent attempts don't matter. Even if we may know this to be untrue outside of school, it unconsciously sneaks into our minds and tells us that we need to be perfect. Luckily(?), I've failed a lot in my life. The one skill that has been extremely helpful in my growth as a software engineer is how to take criticism of my work objectively, not personally. Writing code and creating software can be a creative process, potentially making it very personal. Having a tight coupling with your work hinders your growth as a software engineer. Code review is one of the best ways to learn how to become a better programmer because it allows you to take advice from those who have likely done what you have done before or have seen things you might have missed. I remember exactly when I started getting drastically better, just like in highschool with piano, it was when I became less concerned about how my performance reflected on my skills and more concerned how I could make the thing i'm making better.
if you want to go far, go together.
Code that gets reviewed is a collaborative effort. A merged PR that breaks the codebase is the shared responsibility of all those that wrote or reviewed the code. When code is being written on my computer, I own it. The second I put up a pull request, I decouple my ownership over it because we collectively own it now – you have a responsibility to tell me what's wrong and I have the responsibility to make changes. If we get it wrong, we'll revert, learn from it together, and try again.