Coding continues to gain popularity in the professional world. As it does, people who didn't major in programming are using coding bootcamps as a way to enter the field. As my friends consider a transition, i am often asked, "What is the hardest thing to learn about coding?" This has got me thinking.
Now, asking what the hardest thing to learn about coding is a lot like asking an artist what is that hardest thing to learn about art. The answer is going to be heavily influenced by what kind of art the person makes. A sculptor, painter and photographer will all point to different specific difficulties. Coding is much the same.
I've spent their career working on the web. My answers will differ from a game dev or an enterprise java dev (God save your brave souls). With that disclaimer presented, these are the hardest things to learn about coding.
Where to put your code
Learning where to put your code is arguably the hardest thing on this list. I guess that's because it is the easiest to dismiss. We all assume we know how to do this. Learning how to break your code up, how granular to make your functions, where to put those functions and what to name them takes a minute to learn and a lifetime to master.
So if we all think we are good this this, how do we get better? To offer some advice, i would suggest being ruthlessly critical over your code when you have to change it. Every time you revisit code you wrote 6 months ago that requires you to split up one of your functions, remember it as evidence you didn't organize your code optimally and try to change that next time. Conversely, every time you notice 2 of your functions being called only in unison, you have gone too granular. Remember that as well.
I focus on this topic a lot and have since i started coding. I regularly catch things i did poorly. Maybe chasing perfection in this is a fools errand. Maybe not. But even when you are 90% of the way there, your codebase and team members will thank you for it.
Reducing complexity over time
The codebase of any actively developed system is going to grow over time. This growth leads to increasing complexity. That is not good. Every time a codebase grows in complexity, three things happen: bug inject rates go up, velocity goes down and employees take longer to onboard.
To avoid this, you need to be aware of places the code's architecture and code organization is sub-optimal. Raise your teams aware of this when you identify them. Come up with the optimal structure and start to incrementally move toward those goals.
To perform this well is difficult. It takes a shrewd and unbiased perspective. As business needs change and the codebase grows to reflects that, previously ideal models or controllers might change. It is very possible you will be the author of the code that needs changing. Admitting they are now wrong and need to changed isn't always an easy thing to do.
When to not code
Every "what separates senior SE's from junior SE's" post includes the frustratingly ambiguous statement: "senior engineers brag about the code they didn't write". A note to juniors: this does not mean they are proud of the "clever" solution that saved 10 lines of code. Instead, it means they brag about the features they quite literally said "no" or "not yet" to.
When we are presented with problems, our nature is to solve them. This is sometimes hasty. Major features should be proven manually before being codified.
What does "major" mean? How do we prove some features manually? Where do you draw the line of proving vs just doing? Whose time should be spent proving the features manually? It depends. That is why this practice is so difficult. Implementing it correctly is dependent on your organization, headcount and process. Reflect on which features should have been proven manually. They are often cases of developing something no one uses, or one that works in a way user's don't want or expect. Apply those learnings moving forward to prevent the same mistakes being made int he future.
Keeping up with code
Software, process and frameworks move fast. It takes effort to keep up with the rate that they appear. This is made worse by our individual stubbornness. The longer we code, the more we rely on the techs we are most familiar with. Over time, this can close us off to the emerging techs and leave our skills stale compared to the shifting developer market. This is a constant struggle for developers.
As software engineers, we need to think of ourselves as technologists. A non-trivial part of our job is providing the best technology choices for the companies who employ us. We cannot fulfill that responsibility if our expertise includes a blind spot over the past few years of advancements.
Rely on what you know, but stay open to suggestion. Our primary job is to deliver value and our proven techs are often our best bet. But we also have a duty to make sure we can hire people moving forward. Being able to keep a codebase modern, without masturbatory efforts to learn a swanky new tech, is a delicate balance. The fact that you are reading a software blog post is an indication you are doing something right.
None of the things listed above are a perfect science. That is what makes them tricky: you have to find how they work best in your practices. Each are done differently by different people on different teams. But remember that the lack of a perfect answer does not reduce the importance of these ventures. It means consistently achieving success on these fronts takes regular focus and review.
The hard truth is that we are all varying degrees of bad at these things. Not a problem, as long as we stay diligent about our improvement. These are the hard parts, after all.
tl;dr: Coding the solution to a problem is the easy part of coding. The basics. These are the hardest things to learn about being a software engineer.