Back to Palantir questions
System DesignSoftware Engineer

Network Object-Oriented Design

Role: Software Engineer


Design an object-oriented model for a computer network that supports nodes, connections, routing, and packet transmission.

Problem Statement

Model a computer network with the following capabilities:

  • Add nodes (computers/routers) to the network
  • Connect nodes with links that have a bandwidth and latency
  • Find the shortest path between two nodes
  • Simulate sending a packet from source to destination
  • Report network topology and link status

Class Design

python
from dataclasses import dataclass, field
from typing import Optional
import heapq

@dataclass
class Link:
    node_a: "Node"
    node_b: "Node"
    bandwidth_mbps: float
    latency_ms: float
    is_up: bool = True

    def other(self, node: "Node") -> "Node":
        return self.node_b if node is self.node_a else self.node_a

@dataclass
class Node:
    node_id: str
    ip_address: str
    links: list[Link] = field(default_factory=list)

    def connect(self, link: Link) -> None:
        self.links.append(link)

    def active_links(self) -> list[Link]:
        return [l for l in self.links if l.is_up]

@dataclass
class Packet:
    source_ip: str
    destination_ip: str
    payload: bytes
    ttl: int = 64


class Network:
    def __init__(self):
        self._nodes: dict[str, Node] = {}

    def add_node(self, node_id: str, ip_address: str) -> Node:
        node = Node(node_id=node_id, ip_address=ip_address)
        self._nodes[node_id] = node
        return node

    def add_link(self, id_a: str, id_b: str,
                 bandwidth_mbps: float, latency_ms: float) -> Link:
        node_a = self._nodes[id_a]
        node_b = self._nodes[id_b]
        link = Link(node_a, node_b, bandwidth_mbps, latency_ms)
        node_a.connect(link)
        node_b.connect(link)
        return link

    def shortest_path(self, src_id: str, dst_id: str) -> Optional[list[str]]:
        """Dijkstra by latency. Returns list of node IDs or None if unreachable."""
        dist = {nid: float("inf") for nid in self._nodes}
        prev: dict[str, Optional[str]] = {nid: None for nid in self._nodes}
        dist[src_id] = 0
        heap = [(0.0, src_id)]

        while heap:
            d, uid = heapq.heappop(heap)
            if d > dist[uid]:
                continue
            if uid == dst_id:
                break
            for link in self._nodes[uid].active_links():
                neighbor = link.other(self._nodes[uid]).node_id
                new_dist = d + link.latency_ms
                if new_dist < dist[neighbor]:
                    dist[neighbor] = new_dist
                    prev[neighbor] = uid
                    heapq.heappush(heap, (new_dist, neighbor))

        if dist[dst_id] == float("inf"):
            return None

        path, cur = [], dst_id
        while cur:
            path.append(cur)
            cur = prev[cur]
        return list(reversed(path))

    def send_packet(self, packet: Packet, src_id: str, dst_id: str) -> bool:
        """Returns True if packet reaches destination."""
        path = self.shortest_path(src_id, dst_id)
        if not path:
            return False
        print(f"Packet routed: {' → '.join(path)}")
        return True

Design Considerations

Why separate Node and Link? Links are first-class objects — they carry state (is_up, bandwidth) and belong to both endpoints. Modeling them as edges in an adjacency list loses that richness.

Routing metric: Shortest path by latency here; could also optimize by bandwidth (max-flow) or hop count depending on the use case.

Link failure: Setting link.is_up = False automatically excludes the link from routing on the next query — no graph rebuild needed.

Follow-ups

  • How would you support directed links (asymmetric bandwidth)?
  • How would you detect and handle network partitions?
  • How would you model subnets and IP routing tables?
  • How would you simulate packet loss and retransmission?
  • How would you extend this to support multicast (one source, multiple destinations)?