Here's another point of view: don't read, nor attempt to understand, and certainly don't change what is not immediately relevant to the first bug you are assigned. Use the bug to guide your learning. Write a test for your bug... no testing framework? Add the first unit test, for your bug. Each task you do will guide you into the relevant part of the code. If you never venture into e.g. utils/common/math/sin.cpp that either means it is correct code you should not change, or that it is unused. In either case, it is irrelevant to your job.
Unfortunately, the kind of environments that throw you into unknown code often change your project so fast that any attempt to understand the system more deeply will be soon lost as you change project again.
This might be a nihilist view, but lots of coding jobs are essentially exercises in futility anyway, so might as well be efficient about it...
If I need to debug someone's code, probably the first thing I ask is "are there test?" If you are lucky there might be some unit tests ... and they might even all pass too! :)
Sometimes it is easier to debug a test then it is to debug the whole thing (due to isolating the code you are interested in). Even if it is easier to debug the running application, having a semi-decent suite of tests is your lifebelt for making sure you are not inadvertently changing behavior directly or indirectly.
Other things I like to do:
- ask if you are the best person to be doing this? Did it land in your inbox/task-list because people thought of your name first? Is there someone else better qualified/with-context who might be better to do anything before you even start thinking about it?
- look at the change history of the code you are debugging - is it a "hot spot" that has had a lot of different hands fiddling around with it in the past (indicative of code that might have been troublesome and/or buggy in the past, with the risk of dirty hacks increasing as the number of changes per LOC increases...), or has it not been touched since check-in #1? If there have been lots of changes in that code go through the changes and look at the associated bug reports to make sure that any existing unit tests cover those scenarios (you may want to add them yourself if not, before you make any changes).
- when reading someone else's code I actually find it better not to try to equip myself with all of the domain knowledge and docs. Often if the original developers are long-gone then the docs will likely be way out of date anyway, and sometimes it is easier to just be laser-focused on the parts you care about rather than try and get a handle on the whole system. I guess it depends on what you are doing though - i.e. simple bug-fixes or doing something more far-reaching).
If it even can be tested. I’ve spent decades now dealing with beginning Java programmer’s preference for the relative simplicity of static initializers; that is, code that starts trying to connect to a live database as soon as you run it in a way that can’t be mocked out without making dangerous changes to the code in the first place.
If you are working on an old code base for a reasonable time I recommend to get to know the old developers. Check out the commit history, who wrote what, talk with them a bit if they are still around to get a feel for them. After a while you will probably see patterns, guy A usually wrote solid code, guy B a bit more sloppy. If you are investigating a bug in a specific area of the code use git blame and start investigating any additions by guy B first
Also, have the humility and the generosity to assume complex code is that way for some reason. The people who came before you are not likely to be such bigger idiots than you. If something looks wacko, slow down and ask yourself how it got to be that way.
If you were lucky enough to contact them that is! Attrition rate is such these days that many coders simply flee after a release or so, also depends on how old the code-base is. Git or other version control systems come quite handy, I agree.
Yes, exactly this. I worked support for many years, fixing bugs in other developer's code.
The most efficient way to find the problem and fix it is to find a string and start pulling it. Don't waste your time researching everything - you don't where that problem is yet.
You're either starting from "when I try A, B happens, but I want C" or you're looking at "the logs show this error (or just stop after last successful action)".
Use that as a starting place and follow it carefully until you get to the suspect behavior. Then start learning what's going and why it's wrong. Half the time, it's a red herring and you need to keep looking elsewhere.
It's take some effort to put on the blinders and ignore everything else, and you need to be OK with not knowing how some parts of the system work. If you need to know it to fix the problem, you'll learn about it in the course of your investigation.
True, it really depends on what kind of project manager you have in your team. Many are very particular about this, they ensure a thorough transition when an individual quits and make sure knowledge transfer happens properly. On the other hand, I've also met those who have no idea what all systems their project is owning!
#2 is a systemic problem in most environments. Especially in the engineering/enterprise space, many things exist only as "tribal knowledge". This is not just a cs problem, but a general problem that all managers should be aware of.
Don’t forget, once you reach “senior” level (about 5 years experience), you’re expected to be able to do this in a day or two, regardless of codebase size or complexity.
I wouldn’t say this is an expectation. Depending on the size and quality of code, you may be able to identify what’s going on in a code base within a day, or understanding it may require weeks. Then you probably want to document what you’ve found, so you can delegate whatever new features you need to implement or modify. And this can stretch longer if the nature of your tasks requires a deeper investigation of whatever dependencies (lets say other services or libraries) the code base depends on.
I’ve been at a couple of the large FAANGs. You don’t need to be able to do all of this on a day. If you do, your management fundamentally doesn’t understand what’s going on. If you’re at a senior level, it’s your job to communicate. If you have non technical stakeholders, you must be able to take complex topics and break them down and influence your stakeholders to agree to the right thing or at least explicitly accept the cost of what it is you lose by doing A over B or C.
Edit: I did work at a company before where something like this was an expectation, and not just from senior folks. The underlying issue was the manager chain upwards was all people managers who fundamentally don’t know the first thing about software development. The best you can do in that situation is break down the problem, size components, and communicate.
[+] [-] jeffrallen|6 years ago|reply
Unfortunately, the kind of environments that throw you into unknown code often change your project so fast that any attempt to understand the system more deeply will be soon lost as you change project again.
This might be a nihilist view, but lots of coding jobs are essentially exercises in futility anyway, so might as well be efficient about it...
[+] [-] mattlondon|6 years ago|reply
If I need to debug someone's code, probably the first thing I ask is "are there test?" If you are lucky there might be some unit tests ... and they might even all pass too! :)
Sometimes it is easier to debug a test then it is to debug the whole thing (due to isolating the code you are interested in). Even if it is easier to debug the running application, having a semi-decent suite of tests is your lifebelt for making sure you are not inadvertently changing behavior directly or indirectly.
Other things I like to do:
- ask if you are the best person to be doing this? Did it land in your inbox/task-list because people thought of your name first? Is there someone else better qualified/with-context who might be better to do anything before you even start thinking about it?
- look at the change history of the code you are debugging - is it a "hot spot" that has had a lot of different hands fiddling around with it in the past (indicative of code that might have been troublesome and/or buggy in the past, with the risk of dirty hacks increasing as the number of changes per LOC increases...), or has it not been touched since check-in #1? If there have been lots of changes in that code go through the changes and look at the associated bug reports to make sure that any existing unit tests cover those scenarios (you may want to add them yourself if not, before you make any changes).
- when reading someone else's code I actually find it better not to try to equip myself with all of the domain knowledge and docs. Often if the original developers are long-gone then the docs will likely be way out of date anyway, and sometimes it is easier to just be laser-focused on the parts you care about rather than try and get a handle on the whole system. I guess it depends on what you are doing though - i.e. simple bug-fixes or doing something more far-reaching).
[+] [-] commandlinefan|6 years ago|reply
[+] [-] el_programmador|6 years ago|reply
[+] [-] dranka|6 years ago|reply
[+] [-] jeffrallen|6 years ago|reply
[+] [-] el_programmador|6 years ago|reply
[+] [-] JustSomeNobody|6 years ago|reply
2. Find an entry point. If it’s a CL find main and then where params are parsed. If it is a GUI or web app find a form or menu.
3. Don’t debug, READ the code and trace with pencil and paper for notes. If you’re debugging you’re not reading.
Wash, rinse and repeat a few times. Note all questions you may have.
Now go find a domain expert to answer your questions.
[+] [-] jasonpeacock|6 years ago|reply
The most efficient way to find the problem and fix it is to find a string and start pulling it. Don't waste your time researching everything - you don't where that problem is yet.
You're either starting from "when I try A, B happens, but I want C" or you're looking at "the logs show this error (or just stop after last successful action)".
Use that as a starting place and follow it carefully until you get to the suspect behavior. Then start learning what's going and why it's wrong. Half the time, it's a red herring and you need to keep looking elsewhere.
It's take some effort to put on the blinders and ignore everything else, and you need to be OK with not knowing how some parts of the system work. If you need to know it to fix the problem, you'll learn about it in the course of your investigation.
[+] [-] chiefalchemist|6 years ago|reply
1) Never assume the person(s) writing the code will be available in the future.
2) Any given sprint should auto-add task/time for documenting and such. An hour or two now could save 5x, 10x or more later.
3) The more critical the feature/functionality, the more important #2 becomes.
[+] [-] el_programmador|6 years ago|reply
[+] [-] eyegor|6 years ago|reply
[+] [-] commandlinefan|6 years ago|reply
[+] [-] tracer4201|6 years ago|reply
I’ve been at a couple of the large FAANGs. You don’t need to be able to do all of this on a day. If you do, your management fundamentally doesn’t understand what’s going on. If you’re at a senior level, it’s your job to communicate. If you have non technical stakeholders, you must be able to take complex topics and break them down and influence your stakeholders to agree to the right thing or at least explicitly accept the cost of what it is you lose by doing A over B or C.
Edit: I did work at a company before where something like this was an expectation, and not just from senior folks. The underlying issue was the manager chain upwards was all people managers who fundamentally don’t know the first thing about software development. The best you can do in that situation is break down the problem, size components, and communicate.
[+] [-] RickJWagner|6 years ago|reply
As a group, we need to better understand how to read and debug code written by others.
[+] [-] medecau|6 years ago|reply
[+] [-] medecau|6 years ago|reply
1. Identify change points.
2. Find test points.
3. Break dependencies.
4. Write tests.
5. Make changes and refactor.
Working Effectively with Legacy Code, 2004, p. 18