How can I reduce my error rate when using my skills?
When using skills in which you can make mistakes, it is important to monitor what you do and where you make your mistakes. Like any performance optimization problem, you want to figure out where you make the most mistakes and where you'll benefit the most from fixing those mistakes. If you make the same mistakes 100 times at the cost of a minute each time, that may be preferable to making 1 mistake that cost 100 minutes to fix, given that once the mistake happens, the cost stays the same.
Document your skills. Write down what you do, when you do it (triggers) and what kind errors you make during those steps. Evaluate how many times you make that mistake and how long it costs to fix. Then when you use your skills, track when you make mistakes and how long it takes you to fix the mistake.
As an example, think of a software engineer doing code reviews. Reviewing code requires going through a variety of checks: is the build passing? is the functionality properly implemented? are there tests? are the new files in the proper location? Without a list, the engineer is left looking at the code without any clear checklist. If he is methodical he will have a list he goes through in his head. If not, then he will most likely only look at the code and give it a summary opinion, that is, whether he likes what he sees, or not.
In both cases, given a non-explicit methodology, is it hard to assess where the mistakes are made and which mistakes cost the most to fix. If you don't check that tests were written for the new functionality or changes, what impact will it have in the future? Depending on how likely the code is to change, the likelihood that something gets broken may be significant. While adding a test may require a few minutes, one has to judge how much time would be wasted if a bug were introduced in the piece of code. As code complexity increases, so does the cost of fixing issues in that code.
With an explicit checklist you will be able to track the things that you want to verify before code is merged. As your checklist covers more and more case, this list will reduce the likelihood that the person who wrote code made a mistake that gets into production. By the same token it will increase your effectiveness as a software engineer to produce quality code.
There are no tests on the project I joined. How do I get started?
When joining a new project without tests, here is the value you need to provide through the addition of tests:
- the application works and doesn't crash
- the application works and supports a few input cases
- the application works and supports a variety of input cases
- the application works and is robust to most input cases
Start by finding the main entrypoint of the program and call it in a test. Your test doesn't have to do much, other than ensuring you can start the program and possibly exit. Your goal should not be to assert anything yet, but to exert the code. Create a few tests that do very few things other than starting and terminating the program. Once you've covered a few use cases, you can use those tests to ensure that the application can start, do a few things, then terminate without crashing.
Start unit testing the various parts of the code that are critical. To determine what is critical, you'll have to dig into the code. With the tests you initially wrote you will get a sense of the "critical" pieces, simply due to the fact that they are executed whenever the program starts and stops, which are two things you always want to work.
When writing unit tests, always aim to write a test case that covers the happy path first. You want to demonstrate that the functionality a class or function is supposed to provide is there first and foremost. Then you want to test its robustness and its ability to handle a variety of input cases. Given a large codebase, start by covering most of the code with the happy paths before you start to dig into the special cases.
How can you tell between noisy and useful code refactoring?
The classical adage in software development is that "if it ain't broke, don't fix it". Code may not be in an ideal state, but you should not focus on refactoring it if you aren't working to change it to do something else or so that it can be used in other parts of the code. It is fine to do code refactoring from time to time, especially if you have free cycles and know about a few pieces of code that have been bothersome. However, spending time refactoring systems that are already working but a bit clunky may not be the best use of time, especially if you or your team don't have free cycles to spare.
In a business environment, a refactor also means implicating other developers to review your changes. As such, this introduces distractions in those developers that could be more focused.
In this case, whether a refactor or other changes to the code is noisy is a matter of timing.
How do you estimate the size of a project roughly?
When I am asked to provide a rough estimate of the required effort on a project with a lot of requirements or user stories, I first want to make sure that my estimate is in the right order of magnitude. That means that I want to estimate a project that takes 1-10 weeks to be in that range, but not estimate less than a week or more than 10 weeks. Similarly, a project that takes one or more years should not estimated as a job of a few weeks.
My orders of magnitude are as follows:
- 1 day
- 1 week (5 days)
- 1 month (20 days)
- 1 quarter (60 days)
- 1 half-year (120/125 days)
- 1 year (250 days)
As such, when estimating a task, I will say that the task will either take 1 day, 1 week or 1 month. In general, any task that is estimated at 1 month long (or above) needs to be broken down into sub-tasks as it indicates that the task is hiding a lot of complexity.
With this kind of approach, one can estimate that a developer can do approximately 250 small tasks (1 day), 50 medium tasks (5 days) or 13 large tasks (20 days) per year.
Start by creating an estimate of the overall project without thinking about any of the underlying tasks. This is done to have a quick idea of the scale of the project.
Then list and estimate the tasks that will need to be accomplished to complete the project. You might be forgetting a few, but it is fine at that moment. Think mostly of the most important tasks and also the riskiest.
If the sum of the efforts you estimated is in the same order of your original project estimate, then you are done. If not, then you need to investigate and explain what led you to either over or under estimate. Did you forget to estimate some tasks? Did you ignore some tasks when you did your initial estimate? What were the assumptions you made that were right/wrong? Once you are satisfied with your explanation, you are done with estimating.
How can you tell if you are a low performer?
I always prefer to compare myself against my prior self and not against others. Thus, I would consider myself a low performer if my throughput is lower than what it has been on average in the past. This may happen for many reasons, amongst them it would be because I'm learning something new, so I'm spending a good chunk of my time on learning and less on executing. It might be because I'm trying different ideas to find the best one because I'm working on something I've never worked before.
It's generally easy for a programmer to tell whether he's been more or less productive than the prior week. It is mostly based on feelings, where you feel good when you are productive and less good when you're not making any progress or facing issues.
If you think and feel that you are performing poorly, start recording more thoroughly what you are working on. Identify when you start and finish working on a task, and when you get blocked, write down why. After a few weeks, look at what you wrote and assess what might cause you to feel that you are a low performer. Is it because you're working on a task you are not good at? Is it because of a lack of motivation on the task you've been assigned to?
With more information in hand to determine why you feel that you are a low performer, you will be able to devise a plan so that you can once again feel like a high performer.