Select your current position
Pick a role and level — we'll show the growth path, skills and gap analysis.
Development path
Junior
0-2 years
Responsibility: Completing tasks under the guidance of senior colleagues. Learning the codebase, standards, and team processes. Writing code to spec, fixing simple bugs, writing tests.
Key skills:
Middle
2-5 years
Responsibility: Independently developing features from decomposition to deployment. Participating in code review. Optimizing performance. Mentoring junior developers. Taking part in architecture discussions.
Key skills:
Senior
5-8 years
Responsibility: Designing the architecture of components and services. Solving complex technical problems. Managing technical debt. Code review as a quality gatekeeper. Mentoring middle developers. Choosing technologies for new tasks.
Key skills:
Lead / Staff
7-12 years
Responsibility: Technical leadership of a team or area. Designing system architecture. Coordinating with other teams. Establishing standards and best practices. Participating in hiring. Planning the technical roadmap.
Key skills:
Principal
10+ years
Responsibility: Technical strategy at the company or domain level. Cross-organizational influence. Solving systemic business problems through technology. Mentoring lead engineers. Publicly representing the company.
Key skills:
Gap analysis: skills to develop
To reach the next level you'll need to develop:
Implements complex AST transformations: constant folding, dead code elimination, inlining. Uses babel/typescript compiler API for code transformation. Writes plugins for ESLint and TSC.
Implements code generation for stack-based or register-based bytecode. Uses LLVM or QBE for native code generation. Generates optimized code for function call patterns.
Confidently applies code review skills for compiler engineering in non-standard tasks. Independently selects optimal approach and tools. Analyzes trade-offs and suggests improvements to existing solutions.
Implements optimization passes: function inlining, loop unrolling, vectorization hints. Uses dominators, loop analysis and alias analysis. Measures impact of passes on code size and performance.
Implements bytecode compiler + VM interpreter for a simple language. Understands dispatch techniques: switch dispatch, threaded code. Optimizes the main interpreter loop.
Implements a baseline JIT compiler for a simple bytecode format. Understands tracing JIT vs method JIT architectures. Implements basic inline caches for dynamic method calls.
Implements LL(k) and LR parsers, builds AST for programming languages. Uses parser generators (ANTLR, yacc/bison). Handles syntax errors with error recovery strategies.
Writes LLVM Analysis and Transform passes using C++ API. Generates LLVM IR programmatically for simple constructs. Uses opt and llvm-dis for pipeline analysis and debugging.
Implements bidirectional type checking for languages with type annotations. Understands constraint-based type inference. Writes a type checker for a language with generics and simple subtyping.
Confidently applies algorithms and complexity analysis for compiler engineering in non-standard tasks. Independently selects optimal approach and tools. Analyzes trade-offs and suggests improvements to existing solutions.
Confidently applies code quality practices for compiler engineering in non-standard tasks. Independently selects optimal approach and tools. Analyzes trade-offs and suggests improvements to existing solutions.
Confidently applies data structures for compiler engineering in non-standard tasks. Independently selects optimal approach and tools. Analyzes trade-offs and suggests improvements to existing solutions.