Trading Firm Interview Prep

Operating Systems

Virtualization

Limited Direct Execution (How System Calls work)

Process

Scheduling

Memory API

Concurrency

Threads

Mutex

Condition Variable

From https://stackoverflow.com/a/4742791/6327671 :

A common implementation approach for a mutex is to use a flag and a queue. The flag indicates whether the mutex is held by anyone (a single-count semaphore would work too), and the queue tracks which threads are in line waiting to acquire the mutex exclusively.

A condition variable is then implemented as another queue bolted onto that mutex. Threads that got in line to wait to acquire the mutex can—usually once they have acquired it—volunteer to get out of the front of the line and get into the condition queue instead. At this point, you have two separate sets of waiters:

  • Those waiting to acquire the mutex exclusively
  • Those waiting for the condition variable to be signaled

When a thread holding the mutex exclusively signals the condition variable, for which we’ll assume for now that it’s a singular signal (unleashing no more than one waiting thread) and not a broadcast (unleashing all the waiting threads), the first thread in the condition variable queue gets shunted back over into the front (usually) of the mutex queue. Once the thread currently holding the mutex—usually the thread that signaled the condition variable—relinquishes the mutex, the next thread in the mutex queue can acquire it. That next thread in line will have been the one that was at the head of the condition variable queue.

There are many complicated details that come into play, but this sketch should give you a feel for the structures and operations in play.

Semaphores

struct semaphore {
    int value;
    mutex m;
    condition_variable cv;
};

void init(semaphore *s, int value) {
    s->value = value;
    init mutex s->m;
    init condition variable s->cv;
}

// only decrement when positive
void wait(semaphore *s) {
    acquire mutex
    while value <= 0:
        cv wait
    decrement value
    release mutex
}

void post(semaphore *s) {
    acquire mutex
    increment value
    signal cv
    release mutex
}

Single Buffer Producer/Consumer Problem

condition_variable empty, fill;
mutex m;
size = 0

void consume() {
    lock mutex
    while size == 0:
        wait(fill)
    get element from buffer
    size -= 1
    signal(empty)
    unlock mutex
}

void produce() {
    lock mutex
    while size == FULL:
        wait(empty)
    put element in buffer
    size += 1
    signal(fill)
    unlock mutex
}

Common Concurrency Problems

Deadlock

Persistence

Files

Important Linux System Calls (how are each implemented)

Inter-process Communication

Pipe

####

C++

Compilation Process

constexpr/consteval

Memory Layout

stl data structures

hashmap/hashset

struct hashtable {
    list<payload> list;
    array<payload> table;
}

map/set

deque

string

span