Skip to main content

Pair Programming Interview Prep

· 3 min read

1. Define Functional Requirements:

What the users should be able to do. Clarify by asking: "what core features need to be implemented?"

  • Establish Core Entities
  • Is Extract, Transform, Load (ETL) necessary?

Define the contract between the system and its users

  • REST (Representational State Transfer): Uses HTTP verbs (GET, POST, PUT, DELETE) to perform CRUD operations on resources.
  • GraphQL: Allows clients to specify exactly what data they want to receive, avoiding over-fetching and under-fetching.
  • RPC (Remote Procedure Call): Faster than REST for service-to-service communication. Use for internal APIs when performance is critical.

Example:

POST /v1/tweets
body: {
"text": string
}

GET /v1/tweets/{tweetId} -> Tweet

POST /v1/users/{userId}/follows

GET /v1/feed -> Tweet[]
warning

Derive the current user from the auth token, not from user input.

2. Define Non-functional Requirements

What the system should be able to do. Clarify by asking "what part of the system?"

  1. Capacity is often unncessary to calculate. Skip upfront and calculate when it becomes relevant.
  • CAP Theorem: Prioritize consistency or availability?
  • Environment Constraints: Resource limitations
  • Scalability: What parts of the system needs to scale? Does it to prioritize reads or writes?
  • Latency
  • Durability: How is data loss handled?
  • Security: How secure does the system need to be? Consider data protection, access control, and compliance with regulations.
  • Fault Tolerance: How does the system handle failure?
  • Compliance: How will compliance be enforced?

Design the System

  • How does the data flow? Begin from the request and end with the response. How does the state of the data change within the service function chain?

::: info

Focus on the functional requirements (the core features that need to be implemented). Focusing on nonfunctional requirements can lead to scope creep and complexity; which in turn the solution will never be completed (or delivered).

:::

  • Fanout-on-write: when a user makes a post, it is written into 1,000 timelines

    • Use this when reads are more frequent than writes.
    • pay the cost when posting; fast reads, expensive writes.
  • Fanout-on-read is the pull method: when a user opens their feed, it pulls 1,000 post from the people they follow.

    • Use when writes are frequent
    • pay the cost when reading; cheap writes, expensive reads.
  • Most systems do a hybrid approach: fanout-on-write for less popular accounts, fanout-on-read for popular accounts.

Networking

  • HTTP over TCP
  • WebSockets: useful for real-time updates. Bidirectional communication (e.g. chat or streaming). Needed when data is pushed to the server regularly.
  • Server-Sent Events (SSE):useful for real-time updates. Server to client push. Simpler to implement.
  • WS and SSE are stateful
  • WS requires L4 Load Balancer to persist the connection
  • gRPC: service-to-service communication; high performance. Faster than JSON over HTTP.

API

  • REST examples: GET users/{id} or POST /events/{id}/bookings.
  • GraphQL: over-fetching and under-fetching.
    • query parsing + schema validation
  • Pagination for large results
  • JWT tokens for authentication

Data Modeling

Relational databases

  • e.g. Postgres
  • when data is structured with clear relationships
  • Normalization: data split across multiple tables to avoid duplication
  • denormalization: duplicate data and make reads faster. For read-heavy systems where data rarely changes (updates can be expensive).

NoSQL

  • e.g. DynamoDB
  • partition key and sort key based on access patterns
  • Most read value for partition key.
  • Have to know queries upfront.

Key Technologies

  • API Gateway route requests to the backend. Also logging, auth, and rate limiting.