Katkat

Review Code for Memory Risks

OktaFrontend Engineer · Technical Screen

Last updated

This question tests your ability to identify memory-intensive patterns and performance bottlenecks in JavaScript array manipulation, specifically regarding garbage collection and object reference stability.

Scenario

You are performing a code review for a frontend utility module designed to handle large arrays of user session objects. The module is intended to deduplicate the list based on a sessionId field. The current implementation is causing the browser tab to freeze when processing arrays with over 50,000 items.

Review the provided implementation and identify at least three performance or memory-related issues. Propose a more efficient approach.

/**
 * Deduplicates an array of session objects based on sessionId.
 * @param {Array} sessions - Array of objects { sessionId: string, timestamp: number, data: any }
 * @returns {Array} - Deduplicated array
 */
function deduplicateSessions(sessions) {
  let result = [];
  for (let i = 0; i < sessions.length; i++) {
    let isDuplicate = false;
    for (let j = 0; j < result.length; j++) {
      if (result[j].sessionId === sessions[i].sessionId) {
        isDuplicate = true;
        break;
      }
    }
    if (!isDuplicate) {
      result.push(sessions[i]);
    }
  }
  return result;
}

Constraints

  • The input array can contain up to 100,000 objects.
  • Each session object contains a nested data property that may hold large strings or metadata.
  • Memory usage should be minimized to avoid triggering frequent garbage collection cycles.

Tasks

  1. Analyze the Big O complexity of the current implementation.
  2. Identify why this implementation is problematic for large datasets.
  3. Rewrite the function to achieve linear time complexity O(n).

Hints

Hint 1

Observe the nested loops; consider how the number of comparisons grows relative to the input size.

Hint 2

Using a hash-based data structure can provide constant-time lookups to replace the inner loop.

Hint 3

Think about the memory overhead of creating new array references versus using a Set or Map to track unique identifiers.

Follow-up questions

  • How would your approach change if we needed to keep the 'last' occurrence of a duplicate instead of the first?
  • If the 'data' field is extremely large, how can we avoid unnecessary memory pressure when filtering?
  • How does the garbage collector handle objects that are no longer referenced in your optimized version compared to the original?