← Chicagotrading Interview Insights

Chicagotrading·Software Engineer·Technical Phone Screen·Intermediate

Intermediate
Jul 2026

Summary

First technical round at Chicago Trading, 60 minutes, focused entirely on implementing standard C++ constructs. Pretty much exactly what people on the forums said to expect, so no real surprises if you did your homework.

Questions Asked (3)

Q1

Implement a unique_ptr from scratch.

Technical Trade-offsAlgorithms & Data Structures
Author's notes

This is a known ask for this company so I'd practiced it.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the scope: a minimal unique_ptr that supports construction, destruction, move semantics, and basic access. Then implement the core members (pointer, destructor, move constructor/assignment, release, reset, get, operator*, operator->) while explaining design decisions and trade-offs. Finally, discuss extensions like custom deleters, array support, and comparison with std::unique_ptr.

Pro tip: Emphasize exception safety and the Rule of Five: explicitly delete copy operations and provide noexcept move operations. Mention that a unique_ptr should be as cheap as a raw pointer (zero overhead) and that the destructor must be noexcept.

1. Clarify requirements and scope

Ask whether to implement a minimal version or full-featured (custom deleters, arrays). Confirm that move semantics and exclusive ownership are required.

2. Define the class skeleton

Declare the template class with a pointer member. Delete copy constructor and copy assignment. Declare move constructor and move assignment as noexcept.

3. Implement core operations

Write constructor (default and from raw pointer), destructor (delete pointer), move constructor (steal pointer, null out source), move assignment (release current, steal, null out source), and release/reset/get.

4. Add access operators and utility functions

Implement operator* and operator->, bool conversion, and swap. Optionally add make_unique helper.

5. Discuss extensions and trade-offs

Talk about custom deleters (template parameter), array specialization (delete[]), and how std::unique_ptr handles these. Mention performance and exception safety.

Key Points to Mention

  • Exclusive ownership and move-only semantics (deleted copy operations)
  • Rule of Five: destructor, move constructor, move assignment, and deleted copy operations
  • noexcept on move operations and destructor for exception safety and performance
  • Zero-overhead abstraction: size and performance comparable to raw pointer
  • Custom deleters and array support as advanced features
  • Comparison with std::unique_ptr and when to use it over shared_ptr

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

Implement a vector from scratch.

Algorithms & Data StructuresSystem Design
Author's notes

Paired with the unique_ptr question in the same session.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements (e.g., dynamic array, template/generic, exception safety) and then design the class with core operations: push_back, pop_back, operator[], size, capacity, and reserve. Implement with manual memory management, ensuring correct copy/move semantics and exception safety, and analyze time/space complexity.

Pro tip: Demonstrate production-quality thinking by discussing exception safety guarantees (e.g., strong guarantee for push_back) and move semantics to avoid unnecessary copies, which is crucial for performance-critical trading systems.

1. Clarify Requirements

Ask about expected operations, type support (generic vs specific), memory constraints, and exception safety requirements. Confirm whether to mimic std::vector or a simplified version.

2. Design Interface and Data Members

Define the public API (push_back, pop_back, operator[], size, capacity, reserve, etc.) and private members: pointer to data, size, capacity. Decide on growth strategy (e.g., doubling).

3. Implement Core Operations

Write code for constructor, destructor, copy/move constructors and assignment operators, push_back, pop_back, reserve, and operator[]. Ensure proper memory allocation/deallocation and element construction/destruction.

4. Handle Edge Cases and Exception Safety

Address self-assignment, empty vector operations, and exception safety (e.g., strong guarantee for push_back using copy-and-swap or careful ordering). Discuss move semantics for efficiency.

5. Analyze Complexity and Test

State time complexity for each operation (amortized O(1) for push_back, O(1) for pop_back and access) and space complexity. Mention testing strategies (unit tests, edge cases).

Key Points to Mention

  • Dynamic memory allocation and deallocation (new/delete or malloc/free)
  • Amortized O(1) push_back with capacity doubling
  • Copy and move semantics (Rule of Five)
  • Exception safety guarantees (basic, strong, nothrow)
  • Iterator invalidation and const-correctness
  • Template/generic implementation for type flexibility

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

What is the difference between move semantics and copy semantics in C++?

Technical Trade-offs
Author's notes

Follow-up to the implementation questions.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by defining copy and move semantics in terms of resource ownership and performance. Explain how move semantics enables transfer of resources from temporary objects, avoiding deep copies, and highlight the impact on efficiency. Use a simple example to illustrate the difference and mention when each is used.

Pro tip: Emphasize that move semantics is not just about performance but also about correct resource management, especially in types that own resources like smart pointers or containers. Mention that understanding move semantics is crucial for writing exception-safe and efficient code in modern C++.

1. Define copy semantics

Explain that copy semantics creates a new object as a copy of an existing one, duplicating resources. This involves deep copies for resource-owning types, which can be expensive.

2. Define move semantics

Explain that move semantics transfers resources from a source object (usually a temporary) to a new object, leaving the source in a valid but unspecified state. This avoids deep copies and improves performance.

3. Contrast performance and resource management

Highlight that copy semantics duplicates resources (e.g., dynamic memory), while move semantics steals them. Moves are typically O(1) for resource handles, whereas copies are O(n).

4. Provide a concrete example

Use a simple class like a dynamic array or string to show how copy constructor and copy assignment duplicate data, while move constructor and move assignment transfer ownership.

5. Discuss when each is used

Mention that move semantics is automatically used for rvalues (temporaries) and when explicitly using std::move. Copy semantics is used for lvalues or when no move is available.

Key Points to Mention

  • Copy semantics duplicates resources, leading to potential performance overhead.
  • Move semantics transfers resources, leaving the source in a valid but unspecified state.
  • Move operations are typically noexcept to support strong exception guarantees.
  • Move semantics is enabled via rvalue references (T&&) and std::move.
  • The Rule of Five: if you define a destructor, copy/move constructors, and copy/move assignment operators, you should define all.
  • Move semantics is crucial for efficient use of standard library containers like std::vector during reallocation.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.