| Scale | Number of Boards | Number of Pieces | Memory Usage | Operations per Second | Complexity |
|---|---|---|---|---|---|
| 100 Boards | 100 | 1,600 (16 per board) | Low (MBs) | Low (few hundred ops) | Simple object management |
| 10,000 Boards | 10,000 | 160,000 | Moderate (GBs) | Moderate (thousands ops) | Need efficient data structures |
| 1,000,000 Boards | 1,000,000 | 16,000,000 | High (hundreds GBs) | High (hundreds of thousands ops) | Requires sharding and caching |
| 100,000,000 Boards | 100,000,000 | 1,600,000,000 | Very High (TBs) | Very High (millions ops) | Distributed system with partitioning |
Board and piece hierarchy in LLD - Scalability & System Analysis
Start learning this pattern below
Jump into concepts and practice - no test required
The first bottleneck is memory and CPU on the application server managing the board and piece objects. As the number of boards and pieces grows, keeping all objects in memory and processing moves or state changes becomes expensive. The object hierarchy and frequent updates cause CPU load and memory pressure before storage or network limits.
- Horizontal scaling: Add more application servers to distribute board and piece management load.
- Caching: Cache frequently accessed board states or piece positions to reduce recomputation.
- Sharding: Partition boards across servers by ID ranges or user groups to limit per-server load.
- Efficient data structures: Use lightweight representations for pieces and boards to reduce memory footprint.
- Event-driven updates: Process piece moves asynchronously to smooth CPU spikes.
- Assuming 16 pieces per board, 1 million boards = 16 million pieces.
- Each piece object ~200 bytes -> 3.2 GB memory for pieces alone.
- Boards with metadata ~1 KB each -> 1 GB memory for boards.
- Operations: 10 moves per second per board -> 10 million ops/sec at 1 million boards.
- Network bandwidth depends on update size; small updates (~100 bytes) -> ~1 GB/s bandwidth.
Start by explaining the system components: boards and pieces as objects. Discuss how load grows with number of boards and pieces. Identify bottlenecks in memory and CPU. Propose scaling solutions like sharding and caching. Use real numbers to justify your approach. Keep answers structured: growth, bottleneck, solution, cost.
Your application server handles 1,000 piece updates per second. Traffic grows 10x to 10,000 updates per second. What do you do first?
Answer: Add horizontal scaling by deploying more application servers behind a load balancer to distribute the update processing load and avoid CPU bottlenecks.
Practice
Piece class in a board game design?Solution
Step 1: Understand the role of a base class
A base class provides shared properties and methods for all derived classes, avoiding repetition.Step 2: Apply to board game pieces
All pieces share common traits like position and type, so the basePiececlass holds these.Final Answer:
To define common properties like position and type for all pieces -> Option BQuick Check:
Base class = common properties [OK]
- Confusing board layout storage with piece properties
- Thinking base class handles user input
- Assuming base class manages network tasks
King that extends a base Piece class in a typical object-oriented design?Solution
Step 1: Identify correct subclass syntax
In modern OOP, a subclass usesextendskeyword and callssuper()in constructor.Step 2: Check each option
class King extends Piece { constructor(position) { super(position); } } uses correct syntax:class King extends Piece { constructor(position) { super(position); } }.Final Answer:
class King extends Piece { constructor(position) { super(position); } } -> Option AQuick Check:
Subclass syntax = extends + super() [OK]
- Using incorrect keywords like inherits
- Placing extends after function declaration
- Trying to add properties with '+' operator
console.log(board.pieces[0].type);?
class Piece {
constructor(type, position) {
this.type = type;
this.position = position;
}
}
class Board {
constructor() {
this.pieces = [];
}
addPiece(piece) {
this.pieces.push(piece);
}
}
const board = new Board();
board.addPiece(new Piece('Knight', 'B1'));
Solution
Step 1: Understand object creation and storage
A newPiecewith type 'Knight' and position 'B1' is created and added toboard.pieces.Step 2: Access the first piece's type
board.pieces[0]refers to the first piece, soboard.pieces[0].typeis 'Knight'.Final Answer:
"Knight" -> Option DQuick Check:
First piece type = 'Knight' [OK]
- Confusing position with type
- Assuming pieces array is empty
- Expecting an error due to missing pieces
class Piece {
constructor(type, position) {
this.type = type;
this.position = position;
}
}
class Queen extends Piece {
constructor(position) {
this.type = 'Queen';
this.position = position;
}
}Solution
Step 1: Review subclass constructor rules
In subclasses, the constructor must callsuper()before usingthis.Step 2: Check Queen constructor
Queen constructor assignsthis.typeandthis.positionwithout callingsuper(), causing an error.Final Answer:
Missing call to super() in Queen constructor -> Option CQuick Check:
Subclass constructor must call super() first [OK]
- Forgetting super() call in subclass constructor
- Trying to assign this before super()
- Assuming constructor is optional in subclass
Solution
Step 1: Understand scalability and extensibility
Good design allows adding new piece types without modifying existing code, following open-closed principle.Step 2: Evaluate design options
SubclassingPiecelets each piece implement its own move logic, enabling easy extension.Final Answer:
Use a base Piece class and create subclasses for each piece type implementing their own move logic -> Option AQuick Check:
Subclassing = scalable and extensible design [OK]
- Using large switch-case blocks that are hard to maintain
- Handling moves globally with if-else reduces flexibility
- Hardcoding moves in board class limits scalability
