Machine Coding Problem

Health Tracker

macoAllmanagementtime-series-data-aggregation
Commonly Asked By:AppleFitbitGoogle

Requirements & System Scope

Functional Scope (In-Scope)

  • Time-Series Storage Engine: Structuring in-memory measurements sorted dynamically by timestamps for fast sliding-window analytics.
  • Wearable Duplication Filtering: Deduplicates identical sensor records by combining deviceId + timestamp values to prevent sync retry overhead.
  • Dynamic Alerting Rules Evaluator: Inspects incoming user measurements dynamically to immediately trigger notifications on rule breaks.
  • Sliding Statistics Aggregation: Computes min, max, sum, count, and average vitals across custom query ranges.

Explicit Boundaries (Out-of-Scope)

  • Continuous Raw Network Sync Protocols: Omits real-time HTTP transport sockets and cellular connections.
  • Physical Data Privacy Encryption Layers: Skips hardware-level AES-256 block encryption processes and tokenization algorithms.

Class Diagram & Entity Relationships

Structural layout mapping vital measurements, rules, and aggregator dependencies:

Loading...
  • Measurement Class: Models the primary vital payload, keeping type, device identifier, and raw value context.
  • AlertRule Strategy: Evaluates operator comparisons in real-time, executing lightweight validation immediately on ingestion.

Design Patterns & SOLID Principles

  • Observer Pattern: Uses AlertCallback structures to decouple vitals state ingestion from downstream notification and paging subsystems.
  • Strategy Pattern: Enables swappable comparator algorithms for threshold calculations within AlertRule.
  • Single Responsibility Principle (SRP): Decouples vital records collection (HealthTrackerService) from report generation (AggregatedStats).

Core Execution Workflows

Vitals Collection & Aggregation Pipelines

  1. Sensor Ingestion:
    1. Identify target vital types (e.g. Heart Rate, steps, blood pressure) and append to storage array.
    2. Compare deviceId + timestamp to avoid storing duplicated records.
    3. Find the sorted placement index using binary-search (to keep time sequence sorted at O(log N)).
  2. Alerting Hook:
    1. Acquire the active rules list registered for the specific user.
    2. Verify if the new vital value crosses the defined threshold operator.
    3. Dispatch non-blocking callback warning the downstream client instantly.

Concurrency & Thread Safety Strategy

Ensuring high-frequency, thread-safe ingestion under continuous wearable sync:

  • Coarse-Grained Synchronization: Utilizes synchronizing mutex locks during sensor writes to prevent dirty read states while evaluating range queries.
  • Deduplication Invariant: Filters duplicates under simultaneous uploads by verifying compound keys before doing array writes.

Complete Clean Code Blueprint

Production-ready reference designs illustrating in-memory time-series tracking and alert evaluation in Java and Python:

// โ”€โ”€โ”€ JAVA BLUEPRINT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;

enum VitalType {
    HEART_RATE, STEPS, SLEEP, BLOOD_PRESSURE
}

class Measurement {
    private final String measurementId;
    private final String userId;
    private final VitalType type;
    private final double value;
    private final long timestamp;
    private final String deviceId;

    public Measurement(String measurementId, String userId, VitalType type, double value, long timestamp, String deviceId) {
        this.measurementId = measurementId;
        this.userId = userId;
        this.type = type;
        this.value = value;
        this.timestamp = timestamp;
        this.deviceId = deviceId;
    }

    public String getMeasurementId() { return measurementId; }
    public String getUserId() { return userId; }
    public VitalType getType() { return type; }
    public double getValue() { return value; }
    public long getTimestamp() { return timestamp; }
    public String getDeviceId() { return deviceId; }

    @Override
    public String toString() {
        return "Measurement{" + type + ", value=" + value + ", time=" + timestamp + ", device=" + deviceId + "}";
    }
}

class AlertRule {
    private final String ruleId;
    private final String userId;
    private final VitalType type;
    private final double threshold;
    private final String operator; // "GREATER_THAN" or "LESS_THAN"
    private final String alertMessage;

    public AlertRule(String ruleId, String userId, VitalType type, double threshold, String operator, String alertMessage) {
        this.ruleId = ruleId;
        this.userId = userId;
        this.type = type;
        this.threshold = threshold;
        this.operator = operator;
        this.alertMessage = alertMessage;
    }

    public boolean evaluate(double value) {
        if ("GREATER_THAN".equals(operator)) {
            return value > threshold;
        } else if ("LESS_THAN".equals(operator)) {
            return value < threshold;
        }
        return false;
    }

    public String getRuleId() { return ruleId; }
    public String getUserId() { return userId; }
    public VitalType getType() { return type; }
    public String getAlertMessage() { return alertMessage; }
}

class AggregatedStats {
    private final double min;
    private final double max;
    private final double average;
    private final double sum;
    private final int count;

    public AggregatedStats(double min, double max, double average, double sum, int count) {
        this.min = min;
        this.max = max;
        this.average = average;
        this.sum = sum;
        this.count = count;
    }

    public double getMin() { return min; }
    public double getMax() { return max; }
    public double getAverage() { return average; }
    public double getSum() { return sum; }
    public int getCount() { return count; }

    @Override
    public String toString() {
        return String.format("Stats{min=%.1f, max=%.1f, avg=%.1f, count=%d}", min, max, average, count);
    }
}

interface AlertCallback {
    void onThresholdBreached(AlertRule rule, Measurement measurement);
}

class UserTracker {
    private final String userId;
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final Map<VitalType, List<Measurement>> timeSeries = new ConcurrentHashMap<>();
    private final List<AlertRule> alertRules = new CopyOnWriteArrayList<>();

    public UserTracker(String userId) {
        this.userId = userId;
    }

    public void addAlertRule(AlertRule rule) {
        alertRules.add(rule);
    }

    public void recordMeasurement(Measurement measurement, AlertCallback callback) {
        rwLock.writeLock().lock();
        try {
            VitalType type = measurement.getType();
            List<Measurement> list = timeSeries.computeIfAbsent(type, k -> new ArrayList<>());

            // Wearable deduplication check
            boolean isDuplicate = list.stream().anyMatch(m -> 
                m.getTimestamp() == measurement.getTimestamp() && 
                m.getDeviceId().equals(measurement.getDeviceId())
            );
            if (isDuplicate) {
                System.out.println("[DEDUPLICATOR] Ignored duplicate sync packet from " + measurement.getDeviceId() + " at " + measurement.getTimestamp());
                return;
            }

            // In-order time-series insertion
            int idx = 0;
            while (idx < list.size() && list.get(idx).getTimestamp() <= measurement.getTimestamp()) {
                idx++;
            }
            list.add(idx, measurement);

            // Evaluate Alert Rules
            for (AlertRule rule : alertRules) {
                if (rule.getType() == type && rule.evaluate(measurement.getValue())) {
                    callback.onThresholdBreached(rule, measurement);
                }
            }
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public AggregatedStats getStats(VitalType type, long startTime, long endTime) {
        rwLock.readLock().lock();
        try {
            List<Measurement> list = timeSeries.get(type);
            if (list == null || list.isEmpty()) {
                return new AggregatedStats(0, 0, 0, 0, 0);
            }

            List<Measurement> filtered = list.stream()
                .filter(m -> m.getTimestamp() >= startTime && m.getTimestamp() <= endTime)
                .collect(Collectors.toList());

            if (filtered.isEmpty()) {
                return new AggregatedStats(0, 0, 0, 0, 0);
            }

            double min = Double.MAX_VALUE;
            double max = -Double.MAX_VALUE;
            double sum = 0;

            for (Measurement m : filtered) {
                double val = m.getValue();
                if (val < min) min = val;
                if (val > max) max = val;
                sum += val;
            }

            return new AggregatedStats(min, max, sum / filtered.size(), sum, filtered.size());
        } finally {
            rwLock.readLock().unlock();
        }
    }
}

class HealthTrackerService {
    private final ConcurrentHashMap<String, UserTracker> userTrackers = new ConcurrentHashMap<>();
    private final AlertCallback alertCallback;

    public HealthTrackerService(AlertCallback alertCallback) {
        this.alertCallback = alertCallback;
    }

    private UserTracker getOrCreateUserTracker(String userId) {
        return userTrackers.computeIfAbsent(userId, UserTracker::new);
    }

    public void addAlertRule(AlertRule rule) {
        getOrCreateUserTracker(rule.getUserId()).addAlertRule(rule);
    }

    public void recordMeasurement(Measurement measurement) {
        getOrCreateUserTracker(measurement.getUserId()).recordMeasurement(measurement, alertCallback);
    }

    public AggregatedStats getStatsForRange(String userId, VitalType type, long startTime, long endTime) {
        UserTracker tracker = userTrackers.get(userId);
        if (tracker == null) {
            return new AggregatedStats(0, 0, 0, 0, 0);
        }
        return tracker.getStats(type, startTime, endTime);
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println("=== STARTING HEALTH TRACKER SIMULATION ===");
        
        // Setup service with alert dispatcher
        HealthTrackerService service = new HealthTrackerService(new AlertCallback() {
            @Override
            public void onThresholdBreached(AlertRule rule, Measurement measurement) {
                System.out.println("[ALERT DETECTED] Rule: " + rule.getAlertMessage() + " | Breached by: " + measurement);
            }
        });

        // Register HR alert for User-101 (Heart Rate > 120 BPM)
        service.addAlertRule(new AlertRule("rule-1", "user-101", VitalType.HEART_RATE, 120.0, "GREATER_THAN", "Abnormally high heart rate detected!"));

        long baseTime = System.currentTimeMillis();

        // 1. Record healthy HR measurements
        System.out.println("Ingesting healthy vital telemetry...");
        service.recordMeasurement(new Measurement("m1", "user-101", VitalType.HEART_RATE, 72.0, baseTime - 10000, "smartwatch-v1"));
        service.recordMeasurement(new Measurement("m2", "user-101", VitalType.HEART_RATE, 80.0, baseTime - 5000, "smartwatch-v1"));

        // 2. Trigger high heart rate breach
        System.out.println("Ingesting spike vital telemetry...");
        service.recordMeasurement(new Measurement("m3", "user-101", VitalType.HEART_RATE, 135.0, baseTime, "smartwatch-v1"));

        // 3. Test Wearable Duplicate Sync Guard
        System.out.println("\n--- Sync Guard Verification ---");
        // Record exact duplicate of m2
        service.recordMeasurement(new Measurement("m2-dup", "user-101", VitalType.HEART_RATE, 80.0, baseTime - 5000, "smartwatch-v1"));

        // 4. Query Range Stats Aggregator
        System.out.println("\n--- Aggregated Stats Report ---");
        AggregatedStats stats = service.getStatsForRange("user-101", VitalType.HEART_RATE, baseTime - 20000, baseTime + 1000);
        System.out.println("Aggregate HR statistics: " + stats); // Expecting count=3 (72, 80, 135) since duplicate was discarded.
        System.out.println("=== HEALTH TRACKER SIMULATION COMPLETE ===");
    }
}

๐Ÿ’ฌReview

Help Us Improve

How helpful was this walkthrough?

Click a star to rate. We actively use this feedback to refine and update our system design content.

Placeholder
Optional but highly appreciated!

Discussion

Share your thoughts, ask questions, or help others.

Loading comments...