Ask HN: What are the ways you go about getting comfortable with a new codebase?
Tools like Eclipse's Java Browsing Perspective(https://querix.com/go/beginner/Content/05_workbench/01_ls/02_interface/01_perspectives/java_browsing.htm), Visual Studio's Object Browser make it easier to browse the codebase by components.
What are the ways you do it? Is there anything similar available for functional programming?
68 comments
[ 2.5 ms ] story [ 150 ms ] threadHopefully there's an overview of the code base in an `ARCHITECTURE.md` file[1], and then read through it, and the respective documentation and tests for the main modules mentioned in it.
If you assume their tests cover the important business logic / stuff "they want to keep" (ref. "Beyonce Rule"[2]), they should inform you about the most important stuff.
> [1] https://matklad.github.io/2021/02/06/ARCHITECTURE.md.html
> [2] https://www.oreilly.com/library/view/software-engineering-at...
I suggest:
1. Find a senior dev, ask then for exisiting pointers to good documentation to self learn.
2. give that a go, make note of all the questions you have
3. then have a session with that dev for platform walk through. Take lots of notes and ask your questions.
4. offer to update docs where you found errata or missing steps or even complete topics not mentioned
5. suggest to the team anything about onboarding that can be improved.
And that's why the first thing I ask during a technical interview is "Do you have internal documentation?".
Someone can explain a code path, what it should do, what the bug is and with that you can get familiar with a path through the application.
Ask around about the big things everyone would like to change and where the scary code is that nobody wants to touch, and with those things in mind, fix some bugs.
The initial questions will tell you what to avoid initially. Longer term, if you can fix them you'll look like a rock star.
Honestly, learning to read code and execute it in your head is a super power
I've recently did it on huge, very very specific codebase and after 2-3 months I understood it (what to add where, not just what's happening where) relatively OK
[1] https://en.wikipedia.org/wiki/COMEFROM
I use "go to definition"/"find references" to go all around the code base and at the same time try to figure out how each files interact with each others.
Pharo(Smalltalk) IDE is one of the best IDE I've ever used. It even has a feature where you give input object and output object and it tells you what messages you need to send to get from input to output.
Projects, especially messy ones, often behave like lava flows where there is an active and ever expanding edge where changes are currently being made. Beneath this are layer upon layer of nearly impenetrable and often implicitly deprecated code from former developers.
This practice came from a time when I was brought in midway through a rewrite to get rid of unmaintainable code from some offshore contractors. I saw a repository where half the code lacked any organizing principles and had massive security issues. The second half was textbook (pedantic even) OOP, the kind taught in Java textbooks. It was beautifully executed except for using a few outdated tricks to do OOP in early versions of PHP (no longer needed in the version used for this project).
Because I didn't look at the dates, I assumed the neat OOP code was the result of the rewrite. I was wrong.
Try actually using the program as an end user would.
Read error messages, read code, make predictions about what the code does, find out if your predictions are true.
Sort of unrelated, but I've got a story about a project I was looking through that confused the hell out of me. It was a C# library that would allow you to render an element from a shockwave flash file (it was either .swf or .fla).
I spent ages digging through the code. The example worked really well, but I couldn't get it to work with one of my files.
Eventually I contacted the author and he told me the library used reflection to get the name of your variable and would look for that variable name in the flash document.
Another strategy I like is picking parts of the codebase and trying to refactor them. You don't even need to commit anything if you're not supposed to go around changing things: just by spending some time moving things around, seeing what breaks and so on will give you a better understanding of the code and what it does.
Reading the codebase does surprisingly little for me, you essentially have to change it and see what happens.
1. I go straight to the entry point, the main(), and then follow how the initial configuration, flow of data, sanitisation, and routing is done.
2. I look for bugs. Fixing bugs reveals the complexity as you need to look for side effects of the fixes when you don't yet know the system. Writing tests for those fixes also helps understand the system.
3. I look for the least changed part. I find these are usually the oldest and most core part of how the program works, whereas more recent changes are business logic and feature addition.
But of these, the first yield the greatest initial understanding and allows me to change things with less fear.
A 4th way I would add is: If you need to make a minor change or understand how one specific function is expected to work, search for its unit tests and start there.
I guess the landing page or authentication page could be considered the equivalent, but I’m not sure those would hit your goals to understand flow of data, etc. ?
Android introduced navigation graphs [1], which were meant to solve this problem. But what happened in reality were instead of arrows point to each screens, there would be multiple islands that were teleported in from random places.
[1] https://developer.android.com/guide/navigation/navigation-ge...
Second - I learn how different components are wired together.
This reminds me of Pharo which does all of the above, indexes classes, messages and has a rich documentation support.
I find the only way for me is to actually run the code locally, play around with it until I understand the data flow.
Get a good flame graph up, and you'll have a really solid visual representation of what's going on.
Bonus: on almost any project, nobody has done a profiling pass in at least a few months, so you'll probably discover some extremely easy performance improvements and you'll look like a goddamn hero when you speed up e.g. the test suite by a factor of 3 in your first week on the job.
Also, attempting to draw a sequence diagram and fixing it as you go trains the brain to handle a mental model of a large process.
1. Fix a couple of bugs
2. Add a small feature
3. Refactor a small piece of it
Always start with few small things and keep increasing the complexity of the things you do. Working on a codebase is the best way to understand it.
Also try to read tests, because they can show a lot about how the components are used and their properties.
Usually at least one of them stands out, so I at least read this through (usually diagonally).
I might also pick different things based on my goals.
Once I think I have a grasp of the high level aspects, I start pairing or validate with tiny feedback loops.
Update: I also create my own (naive) helicopter view diagram of the context and validate it with people on different levels.
Instead, I get myself a couple specific tiny bugfixes/features to do first. Just finding out where those are, one by one, tells you a lot and may not be as simple as it sounds.
I was once hired to help with polishing a code base for imminent shipping. I fixed one bug. The fix was one line, but not trivial at all. Took me a whole week of reading code. The customer was extatic. There were like 12-15 years worth of layers of code to read.