Skip to content

Instantly share code, notes, and snippets.

@bertoort
Created April 30, 2020 17:26
Show Gist options
  • Save bertoort/1434a69fc9fae4210a626e13952f7a16 to your computer and use it in GitHub Desktop.
Save bertoort/1434a69fc9fae4210a626e13952f7a16 to your computer and use it in GitHub Desktop.
What makes a senior software engineer?
Standard Junior Mid Senior
Contributions Makes consistent small or minor contributions. Or makes bigger contributions less frequently. Makes solid contributions on a regular basis. Is a major contributor to the team.
Known Tech Stacks Has basic understanding of at least one stack. Has in depth understanding of at least one stack. Can build common features in the stack using the conventions, opinions, and patterns common to that stack. Can crank out code and deliver features at a consistent and good pace. Has in depth understanding of multiple stacks that have different conventions and patterns baked into their frameworks. Can easily build common features using each stack. Can evaluate and has opinions about the best framework for a given application/problem. -- OR -- Has in depth understanding of a single stack. Has an understanding of many design patterns and how to implement them. Can design and implement an architecture for a large codebase that is scalable, maintainable, and testable.
Production Apps May have worked on 1 or more production-deployed applications. Not expected to be able to handle DevOps issues. Has worked on at least 1 application that is/was live in production with real users. Capable of handling most DevOps issues. Has a good understanding of at least 1 application's infrastructure. Has worked on multiple applications with different teams of people that have been deployed to production with real users. Able to handle any DevOps issues. Capable of recommending infrastructure that will meet the needs of the application.
Ability to Learn Has learned the basics of at least one language/stack. Consistently is able to learn how to use new libraries and frameworks in the languages they are comfortable in. Is able to learn new languages and frameworks effectively. Can move between coding paradigms without major slowdown. Solves problems at a higher/more abstract level and just needs to learn new syntax when switching to a new stack.
Knowledge Gaps Is aggressively learning everything about what they are currently working on. Not expected to be aware of their knowledge gaps, for the most part. Confident with knowledge, but is often unaware of where knowledge gaps are and when assistance to should be sought. Is aware of where knowledge gaps exist for themselves as well as the team. Will often recommend immediately seeking outside help rather than attempting to solve problem that falls in a knowledge gap for the team.
Frequency of Help May require help on a frequent basis. Occasionally will need guidance on a story/feature or epic level. Rarely needs help but values and often seeks out collaboration to validate ideas or brainstorm best solutions to hard problems. Understands that constructive criticism and peer reviews result in better design decisions. Is always asking: "What could I be missing?" and "How will this not work?"
Code Smell Understands the concept of what a code smell is, but rarely is able to identify them. Often identifies code smells that go against the existing patterns in the codebase. Occasionally identifies new code smells. Rarely is able to provide best solution to new code smells. Consistently is able to identify all types of code smells and implement solutions to fix them.
Process Smell Can follow whatever process is currently in place. Consistently attends meetings (standups, sprint planning, etc) and contributes within the current process. Able to follow current process, understand the "why" of the process (why is there a pre-planning meeting, what is the point of retros, etc), and often suggests small tweaks to fix inefficiencies. Able to identify major inefficiencies in process and recommend a variety of solutions to help fix the problems. Fully able to redefine and refactor entire process to meet the needs of the team. Able to identify problems that would be solved by additional processes and also when the process is too heavy for the given team/problem. Able to convince team to adopt changes to the process.
Best Practices Follows best practices if there are patterns for those practices in the existing codebase. Can often identify best practices or when they are being broken. Follows best practices that are existing patterns. Occasionally will recommend a new best practice. Believes in best practices based on faith. Occasionally will fight for adoption of a non-critical best practice longer than they should. Can consistently follow best practices whether there are similar patterns in the codebase or not. Can identify where best practices are not being followed and formulate a plan to refactor to best practices. Is able to identify and refactor existing patterns which have outlived their usefulness. Often will follow best practices based on experience of being burned by not following best practices in the past. Knows when to diverge from best practices, because they're not always applicable given the nuance of the situation.
Giving Feedback and Mentoring Not expected to mentor other team members or provide feedback without a process or system that is funneled through a manager. Readily accepts all feedback from peers and mentors. Occasionally will provide feedback to team members when prompted. Mentors other developers through pairing. Consistently helping to level up the skills of everyone else on the team. Will often provide feedback to team members (developers, PMs, designers, managers) to help effectiveness and efficiency of the team. Mentors other team members through pairing and providing direction on skills to learn/practice outside of the pairing environment. Consistently provides constructive critical feedback that is directed at the work and not the individual. Consistently will "teach people to fish" rather than doing it themselves. Will not only provide critical feedback, but also solutions and paths forward to better the team.
Receiving Feedback May have difficulty separating feedback on delivered work verses feedback about themselves. Often feels strong sense of ownership and pride in the work they have delivered. May have difficulty accepting constructive critical feedback of that work or may take that feedback too personally. Rarely takes constructive critical feedback of work personally. Consistently seeks out constructive criticisms in order to deliver better work. Accepts feedback regardless of delivery.
Attachment and Change Often not attached to any existing code, processes, etc. Rarely resistant to change. Consistently able to execute/follow changes as defined by more senior members of the team. Often feels an attachment to code, features, design patterns, solutions, etc. Occasionally resistant to change. Often will defend non-critical decisions/changes longer than they should. Rarely attached to any existing code, process, design, etc. Understands that requirements change, pivots happen, teams reorganize, etc. Has opinions, but doesn't feel the need to win all arguments. Understands the overall importance of each decision being made. Consistently able to create a plan to roll out large sweeping changes without drastically affecting velocity.
Awareness Often fully understands the current feature/bug they are working on. Consistently fully understands the current feature/bug they are working on. Often understands how it affects the rest of the codebase/system. Understands the business value the feature will provide as described by a PM/PO. Fully understands the current feature they are working on. Fully understands how it affects the rest of the codebase/system. Is able to explain the business value the new code will provide. Has the foresight to evaluate how the code written today might change in the future and what would cause it to change.
Foresight Not expected to be aware of how a coding decision now will affect the codebase in the future Occasionally will identify future issues that could arise from a decision made to the code today Consistently will identify any future issues that could arise from a choice made in the code today. Consistently is able to voice product/feature concerns about how features that are built today will affect the cost to change or growth in the future. Consistently able to retrospectively look at code and have empathy for/understand the reasoning behind past choices (good or bad).
Estimates Understands velocity and volatility. Consistently provides estimates that are consistent with the rest of the team. When estimating alone, will occasionally underestimate. Rarely voices concern early when estimates are off. Consistently able to provide rough estimates for new workflows or small new applications. Able to convert non-technical, high level requirements or wireframes into individual stories with estimates. Has a clear understanding of the difference between features, bugs, and chores and how they are (or are not) estimated. Consistently able to estimate the time and complexity it would take to deliver anything from a new set of features to a completely new application. Able to provide estimates quickly and efficiently based on previous experience. Is also able to identify risks that could impact those estimates and provide possible solutions to minimize those risks. Rarely under estimates work. Consistently voices concern to the team early when work is not matching up with its original estimate.
Debugging Often requires help. Rarely follows code paths outside of classes/files they have worked in and know well. Can fully debug and fix the majority of common issues. Will follow code paths throughout the codebase. Will rarely debug into external libraries and dependencies. Can find the root cause of all issues. Will debug inside of codebase and will regularly debug into external libraries and dependencies to find root cause of issue even if it is not caused by the code owned by the team. Fully capable of finding best solution to bug, even if it is submitting a PR to an external library.
Testing Consistently writes tests which follow established patterns in the codebase. Consistently writes tests that follow existing established patterns. Occasionally will introduce a new way of testing which follows established patterns for the testing framework in use. As needed, will define new paradigms for testing whenever existing testing patterns don't work effectively. Fully understands many testing patterns and tools that can be used to solve common cases. Is capable of building a testing framework to best meet the needs of the codebase. In a pinch, can perform the duties of QA/QE for the project.
Multiple Solutions Will often only come up with a single solution. Occasionally will be aware of multiple solutions for a given problem. Capable of doing a rough evaluation between solutions. Consistently able to identify, evaluate, estimate, and execute on a variety of solutions. Evaluations are often broken down to a granular level: what is quickest to ship? what is easiest to maintain? what is best aligned with the team's skills? which will perform the best? Able to explain solutions with pros and cons to PM/PO or other non-technical decision makers. Often will provide potential solutions which are not purely technical/code based, i.e. a completely different feature that solves the underlying business problem.
Breaking Down Problems Often will attempt to tackle the entire problem at once. Rarely considers how to break down a large task into smaller problems. Often is able to identify how to break down problems within the current framework or patterns in the codebase. Consistently is able to break down a single high level story into multiple actionable development tasks. Consistently solves each of these tasks individually and makes sure they come together to solve the original problem. These development tasks can span across multiple levels of the application, or across multiple services or systems. Often will drive the breaking down of stories/features into smaller chunks of work that is easier for the development team to tackle.
Focus Tradeoffs Often unaware of what the trade-offs are. Often will have an opinion on what the focus should be. Not expected to be able to convincingly argue for one trade-off vs another. Consistently is able to explain the trade-offs of focusing on pushing in one direction vs another in the codebase. Should bugs be fixed or new features built? Should performance be improved or a new UI implemented? Scheduling and balancing velocity vs refactorings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment