In the previous post on How to answer algorithmic programming interview questions, we discussed a templated approach on how to solve algorithmic questions. In this post, we will explore similar steps that will help you think in the correct direction while solving design questions.
To set some context, design questions differ from their algorithmic counterparts in how you approach them. Design questions, as the name implies, focus more on how to architect a larger system than just writing an algorithm to solve a specific aspect of the problem. Some examples of design questions may include:
1. Design a transaction ID/conversation ID for an API system
2. Design a cloud based employee performance management system that can support over 100,000 employers.
Here the approach you would take would focus more on component/system design with performance, throughput, stability, scale and redundancy in mind. Let's review some of these buckets that you should keep in mind when designing large scale software systems.
Design principles and philosophy: Before you even start your broader system design, talk about your design philosophy. That is, what are your guiding principles for a good design. For example, simple, robust, scalable, resilient to failures, etc.
Product requirements: To design a good system, you need to understand what the requirements are; UI, interactions, Middle tier, backend, etc. What are the different entry/exit points, metrics that matter, etc.
System requirements: Once you have articulated the different product requirements, it is important to think and list down system requirements such as availability, scale, perf, geo-redundancy, etc. This and the product requirements will help you design a system that meets both functional and system requirements.
Which features would be Pri-0 versus Pri-1 and why: This is an optional part and you might give this more attention if the interview is more focused on product design than a system design.
Architecture: This is the meat of the interview. Here you would define various components of the system, how they interact and the data flows. You would also talk about data redundancy, database backups, load balancing, etc.
Measurement and logging: All good designs should talk about how you would measure performance, key metrics and do your logging and analysis.
Performance characteristics: You should also spend some time discussing the performance characteristics of your proposed architecture. Pay special attention to key operations and high traffic sections.
Geo-redundancy: Designing systems that serve traffic all across the globe and allow failures and fall-backs are strong characteristics of a good design.
Define how the solution would scale: Scale is something that every company, product design looks for. How would you handle increased traffic across the globe while keeping your performance relatively constant should be thought through from the very start.
Security: Most non-trivial products today have security from start. User info, financial information need to be properly secured and steps defined on how to mitigate breaches.
Talk about stability/health checks: A highly performant system that is unstable does not help. Focus on aspects that help build a stable system. Local redundancy, failovers, uptime are important factors.
Deployments/Zero downtime: Think and define how zero downtime and rolling deployments will happen.
Proposed enhancements/improvements: Since this is a first pass on design, talk about alternate design and different technologies.For example, RabbitMQ versus QPID, PostgresSQL versus Cassandra. etc.
Of course, a good system design has a strong architectural component. Focus on building a strong foundation and rest everything should be a guiding factor towards that goal.