Node / React


Section A: General Coding (Algorithms)

A1. Given an array of integers, return the two indices whose values sum to a target. Assume exactly one solution exists.

// Input: nums = [3, 2, 4], target = 6
// Output: [1, 2]

function twoSum(nums: number[], target: number): number[] {
  const seen = new Map<number, number>();
  
  for (let i = 0; i < nums.length; i++) {
    const complement = target - nums[i];
    
    if (seen.has(complement)) {
      return [seen.get(complement)!, i];
    }
    
    seen.set(nums[i], i);
  }
  
  throw new Error('No solution found');
}

A2. Given a string, return the first non-repeating character, or an empty string if none exists.

// Input: "swiss"
// Output: "w"

function firstNonRepeatingChar(s: string): string {
  const counts = new Map<string, number>();
  
  for (const c of s) {
    counts.set(c, (counts.get(c) ?? 0) + 1);
  }
  
  for (const c of s) {
    if (counts.get(c) === 1) return c;
  }
  
  return '';
}

A3. Given two strings, determine if one is an anagram of the other.

// Input: s = "listen", t = "silent"
// Output: true

function isAnagram(s: string, t: string): boolean {
  
  if (s.length !== t.length) return false;
  
  const counts = new Map<string, number>();
  
  for (const c of s) counts.set(c, (counts.get(c) ?? 0) + 1);
  
  for (const c of t) {
    const count = counts.get(c);
    if (!count) return false;
    counts.set(c, count - 1);
  }
  
  return true;
}

A4. Given an array of intervals, merge all overlapping intervals.

// Input: [[1,3],[2,6],[8,10],[15,18]]
// Output: [[1,6],[8,10],[15,18]]

function mergeIntervals(intervals: number[][]): number[][] {
  
  if (intervals.length === 0) return [];
  
  const sorted = [...intervals].sort((a, b) => a[0] - b[0]);
  const result: number[][] = [sorted[0]];

  for (let i = 1; i < sorted.length; i++) {
    const last = result[result.length - 1];
    const current = sorted[i];
    
    if (current[0] <= last[1]) {
      last[1] = Math.max(last[1], current[1]);
    } else {
      result.push(current);
    }
    
  }
  return result;
}

A5. Given a nested object/array structure, write a function to flatten it one level deep (common in both Node backend data-shaping and React prop transforms).

// Input: [1, [2, 3], [4, [5, 6]]]
// Output: [1, 2, 3, 4, [5, 6]]

function flattenOneLevel(arr: unknown[]): unknown[] {
  const result: unknown[] = [];
  
  for (const item of arr) {
    if (Array.isArray(item)) {
      result.push(...item);
    } else {
      result.push(item);
    }
  }
  
  return result;
}

Section B: Node.js

B1. What's the difference between require() and import? Can they be mixed in the same project, and what config controls that?

require() is CommonJS — synchronous, resolved at runtime, works with dynamic paths (require(variable)). import is ES Modules — statically analyzed at parse time, must be top-level (no conditionals), but supports dynamic import() returning a Promise. They can be mixed in the same project, but Node needs to know which module system a file uses: set "type": "module" in package.json for ESM by default (use .cjs for CommonJS files), or leave it unset/"commonjs" and use .mjs for ESM files.

// package.json: { "type": "module" }

// ESM (default with "type": "module")
import express from 'express';

// CommonJS still works via .cjs extension or dynamic import()
async function loadLegacyModule() {
  const legacy = await import('./legacy.cjs');
  return legacy.default;
}

B2. Write a simple Express route handler that accepts a POST request, validates a required email field in the body, and returns a 400 with an error message if it's missing.

import { Router, Request, Response } from 'express';

const router = Router();

router.post('/signup', (req: Request, res: Response) => {
  const { email } = req.body;

  if (!email) {
    return res.status(400).json({ error: 'email is required' });
  }

  // proceed with valid request
  res.status(201).json({ message: 'User created', email });
});

export default router;