3 things that helped me become productive on new codebase faster
1. Start with a goal to fix a tiny issue. It will help you not go too deep, too early and yet give you an overview of the codebase.
2. Document the steps to setup dev environment in your own words and highlight the issues that you run into
3. Take time to learn the new Library or the tooling you encounter. Learn with the goal of familiarise yourself with the keywords/concepts of that library or the tools. It's okay even if you don't understand exactly how they work. When you really need to understand to solve a problem or a piece of code, you can use the keywords to quickly go to exact documentation references to learn more. A thumb of rule for me is to not invest more than a day to learn these new concept continuously(I can always come back to it if I see the need for that)
I just joined a new team as a lead and #2 is killing me, to the point where I have felt like giving up. The documentation my team was given was a hastily thrown-together hack that was full of missing and incorrect steps. It should not take more than a few days to set up a
local development environment, but I’ve had to fight for admin rights, ask a million questions, and have other leads work with me for days on end (who themselves struggled with their own dev env). These are not very hard problems to solve, but they do take time and dedication. I’ve been on many other teams where I was either given a pre-configured VM image or I had comprehensive, clear set up instructions, allowing me to be up and running in hours instead of weeks.
This is also a project management issue. Too many times, PMs or tech leads are not at all technical and have little to no comprehension of the complex environments they oversee nor “technical empathy” for the engineers. It matters not to them what can empower a developer or make them more productive, and too often devs are told “you’re a developer, you should be able to figure it out” or “just use the tools we gave you”. Some of this
does come from heightened and constantly changing security requirements that everyone is expected to blindly implement, but there is also an inherent laziness where leadership doesn’t consider what those kinds of changes mean for everyone involved.
Many, many projects needlessly waste ridiculous amounts of time and money on these issues.
Yeah, it's crazy to me how common it is to just let basic dev environment polish languish.
In a small enough place, I usually will just fix whatever is slowest and most annoying about it myself.
At bigger places... good luck. Sometimes you can get away with hacking together some scripts that do things for your personal setup, but if there isn't buy in to fix the problem you're often out of luck.
2. Document the steps to setup dev environment in your own words and highlight the issues that you run into
This is the most significant thing for me getting up to speed on a new or old project. I absolutely hate reading some whacky custom dependency, jboss, hell like project setups. They just kill morale. And I feel really bad when I see new starters wade into the tall grass on this stuff. I can almost see the moment they go to lunch and start thinking about quitting tech.
My personal reaction to being given really bad 'quick start' doco so many times, is to try and leave every project I work on in a state where "mvn clean install" will do everything needed to get things running.
You may join a team, but your team is also getting a new member. They should be working HARD to make you productive asap, and crazy dev setup is like a code smell.
There was no 'getting started', no docs. I was left on my own. So I muddled through. And documented everything in Makefiles. Not readme, but working code. Now `make clean` `make install` etc, all run, deploy, install, clean etc the project.
A great way to learn. But unfortunately worthless to others in the team, as they all were entrenched in their own ways and setups. I just added a sixth' way of 'working with the codebase'. I'm no to sure if it is the team, me, or Make, but I certainly won't spend such time a next new codebase arrives.
(I do add makefiles on each of my private and opensource projects though, and will keep doing that)
Indeed, crazy dev setup is definitely like a code smell. I remember at one place, it took me 3 weeks to get to the point where I could merge my first PR. Another place I was at, they handed me a laptop that was already set up to run the code, and all I had to do was set up my own editor. Guess which place I was more productive.
Usually a team with a good lead will have a bug that’s not too hard, and will help the newcomer learn the codebase.
It’s easier to learn something when there’s a purpose than in the abstract. And a quick win is motivating.
For more senior developers, assigning a simple feature addition is another option. Eg, having a front end developer add a filter option to some search panel in an application. It may require some UI work, which has the added benefit of getting one involved with people on the UX side — helping to onboard in a team sense. It also may involve some server communication components. Either way, like Muir said — tug on one tiny leaf and you’ll find it is connected to all of nature. (Or something like that.) Similarly, investigate a bug or new feature and you’ll find it brings you through a large portion of the app’s infrastructure.
Document the steps to setup dev environment in your own words and highlight the issues that you run into
Lots of people are commenting saying they have problems with this.
The first thing I do when working on an unfamiliar project is to write a SHELL SCRIPT that records everything I did. I keep that at the root of the git repo, usually as "run.sh".
For example here is what I did when hacking on Kernighan's awk 5 years ago:
So now 5 years later I can see exactly where I downloaded the source from. I count how much source code there is in a repo to get a feel for it, and I have that exact command recorded.
And I was trying to figure out how much test coverage there is, so I ran a bunch of gcov stuff, which involve Python.
The shell script may have some problems now, but the point is that I can tell within 10 seconds what I did 5 years ago. And I can fix it in a few minutes.
It costs so little to write down these commands that it's worth it. If you try to make it really rigorous then you're not going to do it. Th
In summary, I suggest becoming SHELL LITERATE and checking in shell script with comments. The point is that shell is ALREADY what you're typing, so you can save it exactly like it is in a file, and run it later. (You can also use a Makefile, but then you lose that property, and that matters. Make has all the gotchas of shell plus some more.)
Another meme I use is "never remember a port number".
I have had the experience of pair programming with people and they are trying to remember port numbers. Sometimes the server doesn't print it out to the console.
Sometimes they go digging through their notes, or they go digging through Python source code to find the port number.
I always know the port number because I put it in a shell script at the root of the repo.
If you automate stuff like this you can get to the meat of the problem a lot faster.
I would recommend that when someone is new in a large project with an older code base, to pay attention and learn from others.
A mistake I often see is too many “suggestions for improvement” too early. This behavior, when excessive as it often is, is perceived to be invalidating tough choices that were made before your time and chances are that the people who made the choices had good reasons for it and are more experienced than you are. Learn from your seniors - it may be hard when you’ve just read about this new “paradigm X which solves all problems” and you believe you are smarter than others - but please try.
A good senior would explain the "good reasons". A bad senior would be annoyed that the choices are questioned. As a leader I tell my "apprentices" to always question me what the reason is for doing something. Being in a leadership position is not just about your pupils progress, it's just as much about your own learning. You learn a lot when you have to explain stuff. It can be very humbling when you try to explain in-front of your team, being questioned, and then discover that you where wrong.
Often the reasons are not clear because they are not documented it, often only the dev who did it would really know.
Also, it's probably worth taking note of 'fresh eyes' because they have the advantage of hindsight which is often good. That said, there usually complex elements of incumbencies so I do think it should be some time before people have too much lean in.
This is a pretty one-sided take. I think it’s quite possible to lose perspective when working on a large codebase. It’s also possible to have small bits of technical debt accumulate without anyone feeling the total weight of it all. Old code can use whatever fad was most popular when it was written or it can carry the cruft of old dependencies or api changes. Just because something is old it doesn’t mean that it’s good
Of course. But as a newcomer, you cannot know which one it is, and as the OP said this behaviour has a lot of chances to be perceived as invalidating. I've been on both sides of this situation, and in both cases I felt that it was almost disrespectful, it's sending the message that you don't think the team is competent enough to have considered them and carefully picked trade-offs.
When I was on the receiving side (there was a newcomer to the team doing a lot of "suggestions for improvement"), I made a lot of effort to explain the context that led to a different decision, but it was very draining and rarely the good time for it (it distracts from the conversation), it was really hurting collaboration. Eventually we had a one-to-one in which I explained exactly that, and we found that it would be much better to raise these as "can you tell me why is this one like this" (rather than "improvement suggestion" that can be invalidating), and do it in one-to-one so that it's not distracting. Collaboration was much better after that
For sure, it's great to have a new pair of eyes and you certainly don't want to tell somebody to keep their challenges and suggestion for improvement for themselves. But it doesn't mean that there's no good way or bad way to do it
Yeah, I find this a huge problem especially with junior devs (by which I mean those within the first five or so years of their career. When you have people calling themselves senior devs after six months the job title has become meaningless). Until you've been around long enough to understand how large code bases (in general, not the one you're working on!) evolve over time and why common trade offs are made you're not going to be able to grok the weaknesses of an existing code base quickly.
Start off by being humble and asking why certain things have been implemented in the way they have, there is usually a reason. Sometimes it's even a good one!
All of this is true. To me this article mostly reads like 'water is wet'. What one often sees, though, is that younger developers often have the idea that they need to read through portions of the code as a step of getting into it. I am not really sure that it is a helpful step for all but the smallest code bases. It is often more helpful to start with a user story and then try to find out what portions of the code apply to that.
it is true but as we all know checklists can help to make sure stuff isn't missed, even for very experienced people, and it is an unmitigatedly good thing for newer developers.
What helped me in a rather huge Java/Spring codebase with little documentation and little knowledge was running the code locally and using async-profiler to generate flamegraphs for requests to our rest-endpoints - then setting breakpoints in the ide and spending a few hours just following the requests to the code. It's not a good idea to rely on this for a complete understanding but I've remember attempting to read the code class by class before and was unable to get a mental model of it - after doing the flamegraph/stepping in the debugger dance a few days I've started to feel right at home - it also helped me quite a lot to pinpoint further issues.
I think I found the pony: do lots of little experiments to test your understanding of the code. The value of software is not in the bytes of the library/executable or even the source code. It is in having people working for your company who have a mental model of it in their head.
Interesting reading the comments how everyone has their own best way of joining a new team.
For me, the best way to join a codebase without a doubt is to actually just use the product first. What good is looking at the code if you have no idea what the product is even supposed to do?
This doesn't have to be in-depth knowledge, but just go through the setup of your product, do a few happy path use cases, feel what it's like to actually use the thing you're about to develop.
Go and talk with the people who wrote it. Often times there are a just a handful of people that wrote a lot of the core functionality, they often aren't the most social. Talk to them when you are in the planning phase of implementing something.
Lots of great advice here that I agree with. IMHO though I see a lot of engineers miss on the team and social aspects of coding. Just as important as your tech stack is your team. Have an idea for improving something? That's great, but remember to listen first and learn to love what is great about the way it is. For you it could be X% better for the original authors it is a miracle that they made it work at all and it is important enough to need a bigger team.
That, try to understand all the things that are not documented. Sure some projects may have written extensive documentation and all the options they considered and why the did what they did, but most of the decisions usually are not documented. Try to get into the mindset of those people and get into the conversation.
> The rule of thumb I use is to understand something just enough to express what it does without necessarily knowing exactly how it does that. This process is called "chunking," and it relies on the fact that once you have a basic understanding of a unit of code, "you don't need to remember all the little underlying details" (Oakley).
Isn't this how a lot of non-math majors learn math at uni? You learn how to use it, but you don't learn the proofs behind it? When I dove into a first codebase, I took the above said approach because that's how I learned (most) math.
A younger me would've find the Tools section valuable.
Oakley emphasises that understanding is an important part of chunking. Chunking is not the same as root learning without understanding. More that when you familiar enough with a concept you don’t have to think of all the details of it, but can treat it as a unit.
1. Start with a goal to fix a tiny issue. It will help you not go too deep, too early and yet give you an overview of the codebase.
2. Document the steps to setup dev environment in your own words and highlight the issues that you run into
3. Take time to learn the new Library or the tooling you encounter. Learn with the goal of familiarise yourself with the keywords/concepts of that library or the tools. It's okay even if you don't understand exactly how they work. When you really need to understand to solve a problem or a piece of code, you can use the keywords to quickly go to exact documentation references to learn more. A thumb of rule for me is to not invest more than a day to learn these new concept continuously(I can always come back to it if I see the need for that)
This is also a project management issue. Too many times, PMs or tech leads are not at all technical and have little to no comprehension of the complex environments they oversee nor “technical empathy” for the engineers. It matters not to them what can empower a developer or make them more productive, and too often devs are told “you’re a developer, you should be able to figure it out” or “just use the tools we gave you”. Some of this does come from heightened and constantly changing security requirements that everyone is expected to blindly implement, but there is also an inherent laziness where leadership doesn’t consider what those kinds of changes mean for everyone involved.
Many, many projects needlessly waste ridiculous amounts of time and money on these issues.
In a small enough place, I usually will just fix whatever is slowest and most annoying about it myself.
At bigger places... good luck. Sometimes you can get away with hacking together some scripts that do things for your personal setup, but if there isn't buy in to fix the problem you're often out of luck.
This is the most significant thing for me getting up to speed on a new or old project. I absolutely hate reading some whacky custom dependency, jboss, hell like project setups. They just kill morale. And I feel really bad when I see new starters wade into the tall grass on this stuff. I can almost see the moment they go to lunch and start thinking about quitting tech.
My personal reaction to being given really bad 'quick start' doco so many times, is to try and leave every project I work on in a state where "mvn clean install" will do everything needed to get things running.
You may join a team, but your team is also getting a new member. They should be working HARD to make you productive asap, and crazy dev setup is like a code smell.
There was no 'getting started', no docs. I was left on my own. So I muddled through. And documented everything in Makefiles. Not readme, but working code. Now `make clean` `make install` etc, all run, deploy, install, clean etc the project.
A great way to learn. But unfortunately worthless to others in the team, as they all were entrenched in their own ways and setups. I just added a sixth' way of 'working with the codebase'. I'm no to sure if it is the team, me, or Make, but I certainly won't spend such time a next new codebase arrives.
(I do add makefiles on each of my private and opensource projects though, and will keep doing that)
Usually a team with a good lead will have a bug that’s not too hard, and will help the newcomer learn the codebase.
It’s easier to learn something when there’s a purpose than in the abstract. And a quick win is motivating.
For more senior developers, assigning a simple feature addition is another option. Eg, having a front end developer add a filter option to some search panel in an application. It may require some UI work, which has the added benefit of getting one involved with people on the UX side — helping to onboard in a team sense. It also may involve some server communication components. Either way, like Muir said — tug on one tiny leaf and you’ll find it is connected to all of nature. (Or something like that.) Similarly, investigate a bug or new feature and you’ll find it brings you through a large portion of the app’s infrastructure.
Lots of people are commenting saying they have problems with this.
The first thing I do when working on an unfamiliar project is to write a SHELL SCRIPT that records everything I did. I keep that at the root of the git repo, usually as "run.sh".
For example here is what I did when hacking on Kernighan's awk 5 years ago:
https://github.com/andychu/bwk/blob/master/run.sh
So now 5 years later I can see exactly where I downloaded the source from. I count how much source code there is in a repo to get a feel for it, and I have that exact command recorded.
And I was trying to figure out how much test coverage there is, so I ran a bunch of gcov stuff, which involve Python.
The shell script may have some problems now, but the point is that I can tell within 10 seconds what I did 5 years ago. And I can fix it in a few minutes.
It costs so little to write down these commands that it's worth it. If you try to make it really rigorous then you're not going to do it. Th
In summary, I suggest becoming SHELL LITERATE and checking in shell script with comments. The point is that shell is ALREADY what you're typing, so you can save it exactly like it is in a file, and run it later. (You can also use a Makefile, but then you lose that property, and that matters. Make has all the gotchas of shell plus some more.)
https://news.ycombinator.com/item?id=25400278
(I have a couple upcoming blog posts that mention this. Another view on this, regarding releases: http://www.oilshell.org/blog/2020/02/good-parts-sketch.html#...)
----
Another meme I use is "never remember a port number".
I have had the experience of pair programming with people and they are trying to remember port numbers. Sometimes the server doesn't print it out to the console.
Sometimes they go digging through their notes, or they go digging through Python source code to find the port number.
I always know the port number because I put it in a shell script at the root of the repo.
If you automate stuff like this you can get to the meat of the problem a lot faster.
A mistake I often see is too many “suggestions for improvement” too early. This behavior, when excessive as it often is, is perceived to be invalidating tough choices that were made before your time and chances are that the people who made the choices had good reasons for it and are more experienced than you are. Learn from your seniors - it may be hard when you’ve just read about this new “paradigm X which solves all problems” and you believe you are smarter than others - but please try.
Also, it's probably worth taking note of 'fresh eyes' because they have the advantage of hindsight which is often good. That said, there usually complex elements of incumbencies so I do think it should be some time before people have too much lean in.
When I was on the receiving side (there was a newcomer to the team doing a lot of "suggestions for improvement"), I made a lot of effort to explain the context that led to a different decision, but it was very draining and rarely the good time for it (it distracts from the conversation), it was really hurting collaboration. Eventually we had a one-to-one in which I explained exactly that, and we found that it would be much better to raise these as "can you tell me why is this one like this" (rather than "improvement suggestion" that can be invalidating), and do it in one-to-one so that it's not distracting. Collaboration was much better after that
For sure, it's great to have a new pair of eyes and you certainly don't want to tell somebody to keep their challenges and suggestion for improvement for themselves. But it doesn't mean that there's no good way or bad way to do it
Dead Comment
i gave a go at making a cheatsheet of the steps: https://twitter.com/Coding_Career/status/1350445944395821056...
think it's a good guide to follow even if I instinctively do most of it already.
For me, the best way to join a codebase without a doubt is to actually just use the product first. What good is looking at the code if you have no idea what the product is even supposed to do?
This doesn't have to be in-depth knowledge, but just go through the setup of your product, do a few happy path use cases, feel what it's like to actually use the thing you're about to develop.
Lots of great advice here that I agree with. IMHO though I see a lot of engineers miss on the team and social aspects of coding. Just as important as your tech stack is your team. Have an idea for improving something? That's great, but remember to listen first and learn to love what is great about the way it is. For you it could be X% better for the original authors it is a miracle that they made it work at all and it is important enough to need a bigger team.
Isn't this how a lot of non-math majors learn math at uni? You learn how to use it, but you don't learn the proofs behind it? When I dove into a first codebase, I took the above said approach because that's how I learned (most) math.
A younger me would've find the Tools section valuable.
Which makes sense, at least firstly, considering that understanding a proof is a lot easier when its conclusion is already familiar.