What qualifies a software developer as a “FSE” (Full Stack Engineer)? Having a definition is useful because it can help identify skill gaps, it provides context for specializations and provides a map of practices, technologies and tools used at a company and in a software system.
Below is a comprehensive definition of “FSE” that goes well beyond just listing the technologies that a FSE should be proficient in. It’s a generic list of skills, knowledge and practices that can be applied to different domains and technology stacks.
Generic definition of a FSE: A software developer who can do the following:
- Analyze requirements, formulate a system design and devise an implementation strategy.
- Provision and configure the systems necessary to support a solution.
- Develop all the components necessary to build a complete solution.
- Assure the quality of a software solution.
- Deploy a software solution into production.
- Monitor and manage the solution in production.
- Iteratively develop and deploy new features and improvements.
- Evaluate the usefulness of features and components based on usage patterns.
- Use observations to make inferences and predictions.
- Do all the above in collaboration with other stakeholders and engineers.
The list of skills is surprisingly long, yet incomplete; much more needs to happen to bring a software solution to customers. We omitted product ideation and product management, marketing, advertising, legal work, etc. It’s a rabbit hole, so we’ll stick to the 10 core skills listed above and elaborate on them.
The generic FSE definition can be applied to software solutions in various domains, like mobile applications, desktop applications, home automation, robotics, console games, etc. Let’s apply it to user facing internet applications.
Definition of a Full Stack Engineer in the Internet Domain: A software developer who can do the following:
- Analyze, design and plan.
- Identify system inputs, outputs and external interfaces.
- Identify user interactions that the system must support.
- Define the data that must be collected and stored.
- Define data transformations.
- Sketch out a user interface.
- Maintain a record of requirements and analysis.
- Determine an appropriate technology stack.
- Identify off-the-shelf systems that can be leveraged.
- Determine and design the components that must be built.
- Design component interfaces and APIs.
- Design data storage schemas.
- Design for security, reliability, resilience, scalability, usability, maintainability and configurability.
- Prioritize and track requirements.
- Break work into appropriate components and phases.
- Identify risks and ways to mitigate them.
- Provision and configure:
- Databases, application servers, compute clusters, LB’s, message queues, backup storage, etc.
- Environments for development, QA/staging and production.
- Networking between environments and between services within environments.
- Additional services required during development and deployment (build servers, source code repositories, etc.)
- The “front end” user interface
- Develop the online middle tier (controllers, REST APIs, business logic, etc.)
- Develop offline processes (data transformation and aggregation, asynchronous event processors, etc.)
- Implement security, logging, monitoring, test groups, feature flags, dynamic configuration and artifact updates, monetization, customer support, etc.
- Develop code that is secure, reliable, scalable, maintainable, testable, resilient and usable.
- Research technologies and solutions and integrate them into the system as needed.
- Devise, develop and execute manual tests.
- Develop and execute automated tests.
- Test for correctness, load, resilience, reliability, speed, consistency, and throughput.
- Log and track bugs and anomalies.
- Identify and implement process improvements.
- Deploy all software components to QA and production environments.
- Apply configuration changes to QA and production environments.
- Automate and validate deploys.
- Deploy updates.
- Monitor and manage:
- Monitor resource usage, transaction counts, throughput, response times, errors, and anomalies.
- Implement backup and recovery.
- Respond to software and system failures.
- Take corrective action to maintain availability.
- Perform root cause analyses and implement improvements.
- Identify, prioritize and track requirements for improvements.
- Modify existing code, configurations and tests to implement improvements.
- Evolve code structure, data schemas and architecture to mitigate and manage increased complexity.
- Identify events and attributes to log.
- Log events along with test groups.
- Consolidate, combine and aggregate event logs.
- Query and analyze raw and processed data.
- Calculate statistical significance of events.
- Select inputs and outputs for predictions and inferences.
- Select ML strategies (supervised-, unsupervised- or reinforcement learning) and algorithms (classification, regression or clustering)
- Perform offline model training.
- Implement online model evaluation and apply it.
- Iterate on the above.
- Communicate plans and status.
- Garner support, solicit input, adapt.
- Identify and motivate prospective stakeholders, build a team.
- Manage conflicting priorities.
While the list is still at a rather high level it can be used to:
- Identify skill gaps and strengths.
- Provide context for areas of specialization.
- Create a map of practices, technologies and tools used within a solution space.
Let’s call the map mentioned in bullet #3 a PTT-map: the Practices, Technologies and Tools used to build out a software solution. A PTT-map can be created for a company, a team or software system. Individuals can also map out their own personal technology stack and also their (best) practices for analysis, design, collaboration, etc.
Using the Full Stack Engineer in the Internet Domain as a starting point, I’d like to now create a PTT-map for a typical user facing web application deployed on AWS, augmented with resources to help learn the listed skills.
I’d appreciate any feedback you have. What’s missing from the generic definition, what’s superfluous?