PracHub
QuestionsLearningGuidesInterview Prep

Quick Overview

This question evaluates a candidate's skills in object-oriented design, implementing concrete classes from abstract interfaces, file I/O and streaming data transformations, error handling, and integration with a registry and CLI within a Python codebase.

  • medium
  • Bloomberg
  • Coding & Algorithms
  • Data Engineer

Implement classes within an abstract Python framework

Company: Bloomberg

Role: Data Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

You are given an existing Python codebase (~200 lines shown) that defines an abstract base class DataProcessor with abstract methods load(self), transform(self, record), and save(self, records); a registry/factory that instantiates processors by name; and a CLI that wires them together. Without editing the abstractions, implement a concrete CsvToJsonProcessor that: ( 1) reads CSV files in chunks; ( 2) transforms each row to a normalized JSON object; ( 3) writes line-delimited JSON to an output path; ( 4) handles bad rows with a retry/logging policy; and ( 5) integrates with the registry so the CLI can invoke it by the name 'csv_to_json'. Provide the class implementation outline and explain the control flow through the existing template methods.

Quick Answer: This question evaluates a candidate's skills in object-oriented design, implementing concrete classes from abstract interfaces, file I/O and streaming data transformations, error handling, and integration with a registry and CLI within a Python codebase.

You are working inside an existing Python framework that already defines an abstract base class `DataProcessor` with template methods `load`, `transform`, and `save`, plus a registry/factory and CLI wiring. Your task is to implement the core behavior of a concrete processor named `csv_to_json`. To keep the problem self-contained and testable, you will write a function that simulates what the concrete `CsvToJsonProcessor` would do: - `load`: read CSV records in contiguous chunks of size `chunk_size` - `transform`: normalize one row at a time into a JSON-ready object - `save`: emit line-delimited JSON records in the same order as successful rows - bad rows: retry transformation up to `max_retries` times after the first failure; if the row still fails, log it by recording its 0-based row index and skip it Normalization rules: 1. Normalize each header by trimming whitespace, lowercasing, and replacing runs of spaces with a single underscore. 2. The normalized header is guaranteed to contain `id`, `name`, and `age`, and normalized headers are unique. 3. A row is bad if its column count does not match the header length. 4. Required fields: `id`, `name`, `age`. - `id`: convert to integer - `name`: trim and collapse internal whitespace to a single space; it must not be empty - `age`: convert to integer and it must be non-negative 5. Optional fields: - empty string becomes `None` - `email`, if present and non-empty, is lowercased - all other optional fields are trimmed but otherwise unchanged 6. Output each successful record as a compact JSON string (one JSON object per line conceptually). Return a tuple `(output_lines, failed_rows)` where: - `output_lines` is a list of JSON strings for successfully processed rows - `failed_rows` is a list of 0-based row indices that still failed after all retries This captures the control flow of the framework's template methods without requiring actual file I/O.

Constraints

  • 0 <= len(rows) <= 100000
  • 1 <= len(header) <= 50
  • 1 <= chunk_size <= 10000
  • 0 <= max_retries <= 5
  • The normalized header contains the keys `id`, `name`, and `age`
  • Normalized header names are unique

Examples

Input: ([' ID ', ' Name ', 'Age', ' Email '], [['1', ' Alice ', '30', 'ALICE@EXAMPLE.COM'], ['x2', 'Bob', '22', 'bob@example.com'], ['3', ' Carol Danvers ', '41', ''], ['4', ' ', '28', 'dave@example.com'], ['5', 'Eve', '0', 'EVE@EXAMPLE.COM']], 2, 1)

Expected Output: (['{"id":1,"name":"Alice","age":30,"email":"alice@example.com"}', '{"id":3,"name":"Carol Danvers","age":41,"email":null}', '{"id":5,"name":"Eve","age":0,"email":"eve@example.com"}'], [1, 3])

Explanation: Rows 1 and 3 fail because `id` is not an integer and `name` becomes empty after trimming. The other rows are normalized and emitted as compact JSON.

Input: (['id', 'name', 'age'], [], 3, 2)

Expected Output: ([], [])

Explanation: No data rows means no output lines and no failures.

Hints

  1. Precompute the normalized column names once, then use a helper to validate and transform a single row.
  2. Process rows chunk by chunk, but keep the original row index so failed rows can be logged correctly.
Last updated: May 18, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Detect Recent Duplicate Records with Bounded Memory - Bloomberg (hard)
  • Minimize Travel Assignment Cost - Bloomberg (medium)
  • Determine Balloon Popping Time - Bloomberg (medium)
  • Solve meeting and tree problems - Bloomberg (easy)
  • Check connectivity between two subway stations - Bloomberg (easy)