Lessons I've Learned From My First Year of Being a Software Engineer
Here are some valuable fundamental principles that I picked up and carried with me along the way
After almost 5 years of being exposed to programming and almost 2 years of being a full-time software engineer, as someone who's had his fair share of hair pulling activity (no, not that one), I'd like to think that I've already gained a bit of wisdom in me as to how to avoid that unfavorable activity brought about by erronous application behavior that doesn't make sense when it should given that it's literally and technically just combinations of 1's and 0's. I'm technically a professional but I'm not really claiming to be an expert given that I'm aware of the vastness of the software development field. I am however confident in my stance that the time it takes for me to build working features and solve problems has been significantly reduced thanks to that thing called experience; ergo, without further ado, here are the top 5 lessons I've learned from my first year of being a software engineer.
Don't trust yourself
I've reached a point that after several times of "doing the same thing", I made assumptions where I did x, so y must happen. The tricky part is sometimes, it's not the same thing. It can be literally the same thing on the code block level but it may not be such under the context where it runs from. I once encountered an issue where I was logging the value of a certain valuable in line 1 and line 3 and it was changing despite the fact that there's no code in line 2 that's visibly defining a new value for that variable. This thought me about bearing in mind mutability - the quality of a variable's value to change. There can also be a typographical error that is hard to spot sometimes. Sometimes I wanted to gamble and test if my ego was correct and proceed to submitting a pull request (PR) and testing in production - but soon enough, I realized that my ego was not supposed to be the thing I was testing - my code was.
It can save you from the embarrassment of a senior developer asking if you tested your code upon seeking approval for your pull request. It can also save you some time from PR resubmission and/or redeployment if you could have just verified if your code was working in the first place. The smartest developers I know are aware of the mind's tendency to make some mistaken assumptions - so test. It's generally good practice to verify the truth.
Writing things in stone
Logging was one of the things I didn't really expect to be important. My past more-ignorant self thought it was solely activated for development and debugging, respectively, when you're seeing things for the first time and when shit hits the fan and you're searching for patient zero. It's generally more important, however, to be more proactive than reactive. Maybe it's comparable to holding an umbrella waiting for it to rain, but I'd like to think of it more as informational ammunition so we're able to know what's happening when we want to know it and we can swiftly drill down and exterminate the bugs that come our way. Plus, we don't really have to store the logs since the beginning of time.
The soft in software
It's not enough that your code is working, it also has to be maintainable. What this means is that it ought to be easy to plug in new features and fix issues when they arise. Now, I actually consider this as an umbrella term because there's a lot of aspects that contribute to a system being maintainable. One of which is simplicity that can also be intertwined with code readability. What you write should not only be understood by computers, but also humans. When working on big systems, more often than not, you're going to be working in a team and it's important that more than one person can modify your code given that business demands can't really be met by a system whose modules rely on only one person. A small technical example of this is putting complicated conditions in a descriptive boolean variable so that it's easier to understand the business rules that the program is trying to execute.
Applying programming principles such as SRP (Single Responsibility Principle) and DRY (Don't Repeat Yourself) in the architecture of your code base would also be of great support in making your system maintainable. Documentation is, as well, one of the aspects that I was pertaining to given that it's easier to maneuver around a system when you know the context with which the system runs. Again, this will allow you to 1) spend less time building new features and 2) avoid making big hotfixes - averting you from having to spend a lot of time finding a workaround around an unsustainable architecture.
Thinking BIG
It's not enough that your code is working, it also has to be performant. It's okay when you're just trying to achieve the desired results on your local machine for the first time. It's not okay when production is serving thousands of request per minute and your algorithm is taking twice as long given that it's making 2 database fetches per run when it can already be done with one. An avoidable 2 second difference in processing time doesn't really look like an issue at first when the request count is minimal but at a thousand request scale, that's around 30 minutes of computing time wasted and if you don't really have the luxury of burning cash putting up additional server instances, you might as well take the time to optimize your code and do some sort of benchmarking to keep costs to a minimum before you get that next round of funding.
The futility of panic
My past few points was a bit technical. For this last one, I ought to switch to the other / softer side of the spectrum. I've only gotten familiar with this lately and it's probably one of the most impactful principles I picked up that made my day-to-day a bit lighter and happier. Initially, in my first few weeks as a more-ignorant being, I thought that if I'm not literally coding where my keyboard is clacking and the editor cursor is moving, I wasn't working - I wasn't making any progress since how could there be progress if literally nothing is happening with the contents of the application repository. To compensate for my "lack of work", I naturally felt a bit of stress considering I wanted to make up for "lost time". Eventually, after several severely exhausting fuck ups, I got to take the time to think about things and that's when I realized that I could take problems in a chill manner and still get things done.
Apparently, you don’t pay the plumber for banging on the pipe. You pay him for knowing where to bang (no, not that one). On my first few weeks working, our CTO even said that "80% of development is reading code". I now have this notion that coding is literally an activity of telling the computer what to do after we've figured out what to do ourselves and sometimes that "figuring it out" part can be spent away from the code editor. It can be sketching a diagram on a whiteboard to help grasp the situation, it can be asking the users of the system about the problems they're facing, or it can simply be drinking coffee whilst staring blankly into the abyss of a plain wall or a colleague's face - thinking about a solution to the problem; ergo, when the stakes are high, 1) take a breather, 2) plan out your actions, and 3) execute. If shit hits the fan, all you have to do is clean it up. We don't really have to spend as much time worrying than we do programming. A calm mind is less likely to make some rash decisions.
To wrap it up, that's:
1) Test - ensure your code is working.
2) Log - allow yourself to easily know what's happening if needed.
3) Promote Maintainability - allow yourself to ship new features faster.
4) Build Performant Code - save yourself some moolah and some trouble of having to address feedback from an angry mob of users.
5) Keep Calm - the result is gonna be the same, if not better - without the extra emotional input.
I'm looking forward to finding more breakthrough knowledge in the years to come.