Now that I’ve been at my job for over a year and a half, I’ve gotten many opportunities to make code changes, review others’ code changes, write documentation, and triage issues. Throughout this process, I have learned many things that should be done, and things that should be avoided. My intent for this post is share some of these things. Many of these things are coding related, but I think they can easily be translated to other work environments.
This post is pretty much all text, so without further ado, let’s jump into it, I guess. 🙂
Below are some references that I’ve used to help me. By no means have I fully mastered everything in said references; it is something I continue to work towards.
There is a lot of domain-specific knowledge when you join a new team. For me, learning how to use company-specific tools or new source control tools (Perforce) took some time. In order to bring myself up to speed, I took notes on various things. At first, it was the small, trivial commands that I wasn’t familiar with. When I started to work on projects, I took notes on the problems I encountered, and their potential solutions. All these things helped get me up and running quicker. I like to say quicker rather than quickly because there are a lot of moving pieces that I end up touching here in comparison to small side projects I’ve worked on before.
The notes you take here help in a few ways. First, they help you nail down the basics: whether it be the daily commands you use, or some sort of process you have to follow to get a particular task done. Second, they serve as a fallback point when you forget something. Sometimes the solution to a particular problem is scattered across multiple documents that were hard to find from the start. Writing down the problem and solution in one place (perhaps along with referencing said documents) can help jog your memory should the same or similar problem arise in the future.
Once you’ve nailed down documenting things for the sole purpose of helping yourself, you can also focus on documents that help others. This can come in many forms. In one case, I had design documents that I’ve merged with my problem/solution documentation because they were found when I was working on the project. In another example, on one of my teams, I found that figuring out if a particular product supported my feature was cumbersome: it required either checking on the product itself or checking the code. For one product it might be straightforward, but for more than one, it becomes a headache. I saw that we had one spreadsheet that tracked support for a different purpose, so I mimicked the same thing for my particular feature. Whenever I had to go look up the support for it, I would update that spreadsheet so I wouldn’t have to go digging again. This saved me some time, and we also received feedback from other stakeholders that use our feature that said it helped them find things quickly without having to always bug us about it.
When you’re working on a particular bug or issue, there are times where you’ll encounter more things to fix. Being the person that wants to “do the right thing” and fix things, you might consider doing it within the same set of changes for the issue you’re working on. What happens when you encounter this scenario more than once? Do you just keep tacking on code changes?
The answer I found was no. When you take a step back, at the end of the day, someone is going to have to review this set of changes. If the changes you’re making have nothing to do with the issue at hand, don’t include it: it just makes your life and the reviewer’s life harder. Instead, file a new bug to track the new problem, and come back to it in a separate review. I’ve found that in several occasions, I’ve ended up doing this and my changes became more convoluted and confusing.
Porting fixes from one branch to another
Many software companies will have “release branches”. It is here that the code that goes out to customers will reside. In many scenarios, companies will flush out high impacting bugs in said branches, ensuring that the branch is stable before it goes out to clients. For example, at the company I work for, we have a feature release that goes out (e.g 4.24.1), and then eventually we’ll have a maintenance train that will only accept bug fixes and no new features.
There are times where you may discover an issue in the mainline development branch that is also present in a release branch. We’ll fix the issue in mainline, and then port the fix into a maintenance train. By keeping things simple and avoiding other unnecessary changes (re: scope creep from above), we make this backporting (or cherry-picking) task much more easier, and reduce the chances of hitting a developer’s favourite problem: merge conflicts.
Knowing when to ask
I might have touched upon this before, but I’ll state it again: ask for help. This doesn’t mean that when you get stuck, you ask for help immediately. It means to dig for potential solutions to your problem for “some time” before going up to someone for help.
There are a few reasons for this. First, by “getting your hands dirty”, you end up getting yourself through the process of problem solving, which is a critical portion of any job in my humble opinion. Second, after having gone through this process, you can explain to the person you’re asking for help that you’ve tried X, Y and Z, but are unsure of the next steps. This shows that you’ve actually tried something and aren’t waiting for someone to “feed you the answer”. It’s a good skill to have when starting out in a new area.
Personally, I’ve found that knowing when to ask for help can be hard to judge. What is “after some time”? I think that it depends on how much experience you have in the given area. If you’re new or an intern, you’re expected to ask questions. write down the answers, and continue moving along. Even if you’re familiar with a given area, if you ask someone for help with what you’ve tried, you’ll probably get some good answers. Also another point is that you’re sort of expected to help others; it’s sort of a give and take scenario. It’s also in the best interest of everyone to help each other, as others can help get you unblocked on what you’re stuck on, and vice versa.
DRY and KISS are two acronyms we love. DRY refers to “don’t repeat yourself”, and KISS refers to “keep it simple, stupid!”. I find that both are sort of inter-related. DRY, in simple terms, means to not write repeated code, and KISS refers to not having 4 lines of code when you could have a single line that would do the same thing.
I find that this sort of thing comes with experience. Code reviews help to aid with this, because someone with typically more experience in the area can help you identify if things seemed to be duplicated or is complicated. As you dive deeper into the codebase, you’ll be able to identify places where this concept is being used correctly, and where it might need some improvement. Experience with the programming language is also helpful. For example, in Python, I thought of using a C/C++ style for-loop to construct a list that meets a certain criteria, but later realized that a single line list comprehension can accomplish the same thing.
Writing good change descriptions
I think this heading sums up what needs to be done in itself: write good change descriptions. In order to appreciate this, we have to think about this in the future. Imagine yourself debugging an issue, and you’re going through the change history. If your commit messages are simple like “Fix bug”, it provides you (and anyone else going through it) no context on what the “bug” is. This causes you to look into the actual diff to “figure out” the bug, which means time. The amount of time spent just increases with more descriptions like that. A good description should describe the background of the issue itself, how it happens, why we’re fixing it, and how we’re fixing it.
The impact of good descriptions is felt at various places in time. Immediately, code reviewers will thank you for a good description to help them understand why tghe change was proposed. In personal projects, its impact might not be as big if you know it inside and out, but if you sideline a project and look at it again three or four years down the line, good descriptions are super helpful if you’re trying to get back into it. At work, issues we find in released software will get fixed, and people come and go. If the person that made the change is no longer at the company, a good change description should be enough to understand it without having to spend a few hours or days to re-establish that context.
In closing, I think that company culture played a role in helping me realize the above points. At my current workplace, we focus on quality. That means we work on ensuring that new code changes we introduce are coupled with their relevant tests, and ensuring that we support our teams in the field that help our customers out.
That being said, above all else, make sure to take care of yourself and your family first. At the end of the day, work is work, and it will never leave unless you do. I touched upon it in my previous post, but having work rule your life is definitely not healthy, and is something I’m continuing to improve upon.
Anyways, that’s all the rambling I have to go on this time around. Until next time!