PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates understanding of string data structures, memory layout, ownership and move semantics in Rust, and algorithmic complexity related to copying and performance.

  • Medium
  • xAI
  • Coding & Algorithms
  • Software Engineer

Explain and Implement Strings

Company: xAI

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: Medium

Interview Round: Technical Screen

##### Question What is a string in programming languages? Inside a struct string{} in Rust, what fields are stored and how would you design and implement one yourself? If you copy a string, what is the time complexity of the operation? How can move semantics be made more efficient? In Rust, is a move simply a reference update?

Quick Answer: This question evaluates understanding of string data structures, memory layout, ownership and move semantics in Rust, and algorithmic complexity related to copying and performance.

Simulate a simplified dynamically-allocated string type and compute the total number of bytes copied by the system. Each string has a length L and a capacity C. Capacity is always at least 1. You are given a list of operations on named variables. Operations: - make name len: Create a new string variable with length len and capacity equal to the smallest power of two >= max(1, len). - copy src dst: Deep copy src into a new variable dst. This copies exactly src.length bytes. The new dst has length src.length and capacity max(1, src.length). src remains valid. - move src dst: Move src into a new variable dst (shallow, ownership transfer). No bytes are copied. dst takes src's length and capacity. src becomes invalid and cannot be used until re-created. - append name k: Increase the string's length by k. If length + k exceeds capacity, reallocate by repeatedly doubling capacity until it is >= new length; this reallocation copies exactly the old length bytes once. Then set length to length + k. No operation will reference a variable that does not exist or is invalid, and destinations for make/copy/move do not already exist. Return the total number of bytes copied across all operations (deep copies and reallocations only).

Constraints

  • 1 <= len(ops) <= 200000
  • 0 <= len, k <= 10^9
  • All operations are valid as per the rules (e.g., src exists, dst does not yet exist; moved-from variables are not used until re-created).
  • Capacity doubling is by repeated multiplication by 2 until capacity >= required length.
  • Bytes counted are only from deep copies (copy) and internal reallocations during append; appending new external data itself does not count.

Solution

from typing import List

def total_copied_bytes(ops: List[str]) -> int:
    state = {}  # name -> [length, capacity]
    total = 0

    def next_pow2_at_least_one(x: int) -> int:
        if x <= 1:
            return 1
        p = 1
        while p < x:
            p <<= 1
        return p

    for op in ops:
        parts = op.strip().split()
        if not parts:
            continue
        cmd = parts[0]

        if cmd == 'make':
            name = parts[1]
            L = int(parts[2])
            C = next_pow2_at_least_one(L)
            state[name] = [L, C]

        elif cmd == 'copy':
            src, dst = parts[1], parts[2]
            L, C = state[src]
            total += L  # deep copy bytes
            state[dst] = [L, max(1, L)]

        elif cmd == 'move':
            src, dst = parts[1], parts[2]
            L, C = state[src]
            state[dst] = [L, C]
            del state[src]

        elif cmd == 'append':
            name = parts[1]
            k = int(parts[2])
            L, C = state[name]
            target = L + k
            if target > C:
                total += L  # copy old bytes during reallocation
                newC = max(1, C)
                while newC < target:
                    newC *= 2
                C = newC
            L = target
            state[name] = [L, C]

        else:
            # Inputs are guaranteed valid; no other commands.
            pass

    return total
Explanation
Maintain a map from variable name to (length, capacity). make initializes length and a power-of-two capacity. copy adds the source length to the total and creates a new variable with capacity equal to its length (at least 1). move transfers the pair (length, capacity) and deletes the source, costing 0 bytes. append either fits within capacity or triggers a single reallocation: double capacity repeatedly until it can hold the new length; this reallocation copies exactly the old length once and then increases the stored length. The total is the sum of bytes copied by copy and by reallocations during append.

Time complexity: O(n) where n = number of operations (amortized, due to capacity doubling).. Space complexity: O(k) where k = number of live variables..

Hints

  1. Track for each variable its (length, capacity) and whether it is alive.
  2. For append that exceeds capacity, add the old length once to the total and then double capacity until sufficient.
  3. copy adds exactly src.length to the total; move adds 0 and invalidates the source.
Last updated: Mar 29, 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
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL 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

  • Flatten and unflatten nested Python structures - xAI (nan)
  • Compute dasher pay from order events - xAI (nan)
  • Compute total active time per Twitter Space - xAI (medium)
  • Design a Recoverable Iterator - xAI (medium)
  • Implement Distributed Matrix Multiplication - xAI (hard)