The Road from Junior to Intermediate Developer
My current job title is “Software Engineer II”, a rank above entry-level but below senior. My promotion to level II surprised me when I first heard about it, mainly because I still viewed myself as a new programmer.
However, looking back, I can tell that I’m a much better engineer now than I was a year ago. There hadn’t been any moments when something “clicked” inside me and I suddenly started performing at a higher level. Instead, my habits and my unconscious thought processes incrementally evolved over time as I gained experience and learned from past frustrations. I am no longer the newest programmer on my team and I have also had the chance to watch other new developers experience a similar growth trajectory.
So what does it mean to be a mid-tier developer? Based on my observations of my personal growth and the growth of developers around me, here are the main differences between junior and intermediate developers.
Junior developers… | Intermediate developers… |
---|---|
Consider “writing code” to be their primary job duty. | View themselves as stewards of their codebase and products. Writing code is merely one skill in a much bigger toolchest. |
Write code first, then consider testing and rollout later. | Start thinking about testability and rollout early in the coding process. |
Are disdainful of the design and planning stages and are eager to quickly start coding. | Understand that time spent on a robust design will pay for itself later on. |
Believe that bug-free code is possible if enough diligence is applied. | Understand that software bugs and programmer errors are inevitable; consider how to add speedy problem detection and mitigation to their major feature items. |
Believe that technical debt arises in codebases because past programmers were stupid. | Understand that technical debt is an inevitable result of changing requirements, increased complexity, increased scalability needs, staff turnover, and simple entropy. |
View old codebases as irredeemable and have fantasies about rewriting them from scratch. | Understand that codebases contain lots of implicit crystallized knowledge and that giant refactorings are risky |
Significantly underestimate the time necessary to complete almost all programming tasks. | Still make lots of underestimates, but understand that estimates should be adjusted upward when projects have lots of ambiguity or require lots of collaboration. |
View code reviews as an obstacle in their way; they “win” if their changes get quickly approved and “lose” if they get heavily criticized. | View code reviews as a critical quality assurance step and as the easiest point in the software lifecycle to catch defects. |
Knowingly submit unfinished code with a reassurance that it can always be fixed later. | Know that most code, once submitted, is left alone untouched for a very long time; aim to minimize future regrets. |
Take pleasure in adding their own new code to already-big codebases. | Groan when there’s a need to add lots of new code and smile when there’s an opportunity to delete lots of old code. |
Measure their productivity through line counts and the number of pull requests. | Have an appreciation for planning, requirement clarification, debugging of production problems, and other non-coding tasks. |
Speeding Up the Process
Have you ever had to do any of these difficult and frustrating tasks?
- Debug a production issue in a module that has insufficient logging
- Try to avoid introducing new bugs to a spaghettified codebase that has diverged far from its original design
- Change core low-level code in a codebase with poor test coverage
- Add duct-taping and error-handling around libraries that don’t work as advertised
- Measure the scope and extent of a production problem in a service that lacks good metrics and monitoring
- Make sense of incomplete or incomprehensively-written specifications and bug reports
- Fix your code or design document after it has gotten a barrage of negative review feedback and your spirits are crushed
Anyone with a “Software Engineer II” or equivalent job title has likely done all of these things. Intermediate developers have had many chances to see for themselves what happens when coding (often their own) is done rashly and impulsively. Frustration acts as an empathy-building exercise.
Intermediate developers ultimately develop a holistic view of software engineering that is much broader than code. Intermediate developers are mindful of things that junior developers often neglect, such as requirement determination, planning, architecture, testing at multiple levels of granularity, rollout management, documentation, debugging tools, metric collection, production problem detection, and production problem mitigation. Developers always learn first about coding; this means junior developers start off preoccupied with the coding aspect of the full engineering workflow. Developers don’t take interest in supplementary engineering work until they discover and appreciate the need for it - this takes time and experience.
Is it possible to rapidly become an intermediate developer without spending a lot of time at the junior level? Is it possible to bypass having to make lots of mistakes and experience lots of frustration along the way? Maybe there are cases out there of young coders who quickly develop a complete engineering intuition and rapidly start performing at a “Software Engineer II” level, but I have personally never seen this happen.
From Intermediate to Senior
What does the progression from intermediate to senior developer look like? I can’t fully answer yet because I’m not there yet. However, here are some skills I’ve noticed that senior developers can do much better than me.
- Identify and prioritize high-impact work ahead of low-impact work
- Tell apart between technical debt that will bring future pain and technical debt that is ugly but harmless
- Write code that is flexible to change and can easily be scaled up in the future
- Quickly attain proficiency with new and unfamiliar codebases
- Quickly find the information they are looking for inside of dense documentation and log files
- Avoid unproductive distractions in favor of high-quality focus time
- Make decisive decisions without getting trapped into analysis paralysis
Am I right in thinking that these are the most important skills for an intermediate developer like me to be learning? Only experience will tell.