Erlang / Erlang Basics Interview questions
1. What is Erlang?
Erlang is a functional, concurrent programming language built by Ericsson in the late 1980s to run telecom switches that had to stay up for years without a reboot. It compiles to bytecode that runs on its own virtual machine, the BEAM, rather than the OS running Erlang code natively. The language...
2. What is the BEAM virtual machine?
The BEAM ( B jorn's E rlang A bstract M achine) is the runtime that executes compiled Erlang bytecode. It is not a general JIT like the JVM's HotSpot; instead it is tuned specifically for running huge numbers of tiny, isolated processes. Key jobs the BEAM handles for you: Scheduling millions of l...
3. What are processes in Erlang?
An Erlang process is the basic unit of concurrency — not an OS process, but a lightweight, BEAM-managed unit with its own stack, heap, and mailbox. Spawning one costs only a few hundred bytes and microseconds, so it's normal for a running system to have tens of thousands of them at once. Pr...
4. What is the actor model in Erlang?
The actor model treats every concurrent unit as an actor : an isolated entity that has its own state, receives messages one at a time from a mailbox, and reacts by updating its own state, sending messages to other actors, or spawning new ones. Erlang's process model is a direct, production-grade ...
5. What are atoms in Erlang?
An atom is a constant whose only value is its own name — think of it as a symbolic label rather than a variable. Atoms are written lowercase ( ok , error , undefined ) or quoted if they contain spaces or start with a capital ( 'My Atom' ). They're used everywhere as tags: function results l...
6. What are tuples in Erlang?
A tuple is a fixed-size, ordered container written with curly braces, like {ok, 42} or {point, 3, 5} . Once created, its size and the position of each element never change — you build a new tuple rather than mutate an existing one. Tuples are the standard way to bundle a small, known number...
7. What are lists in Erlang?
A list is a variable-length, ordered sequence written in square brackets, such as [1, 2, 3] or [apple, banana] . Internally it's a singly linked chain of cons cells — each cell holds a head element and a pointer to the rest of the list, ending in the empty list [] . That linked structure is...
8. What is pattern matching in Erlang?
Pattern matching is Erlang's core mechanism for both destructuring data and controlling program flow. The = operator isn't assignment in the usual sense — it asserts that the left-hand pattern must match the right-hand value, binding any unbound variables in the process. { ok , Value } = { ...
9. Define immutability in Erlang?
In Erlang, once a variable is bound to a value it can never be reassigned within that scope — there is no mutation, only rebinding through a new variable name or a new function call. This applies to every data structure: lists, tuples, and maps are all persistent; "changing" one actually bu...
10. What is a PID?
A PID (process identifier) is the opaque reference every Erlang process gets when it's spawned. You can't inspect or construct one by hand — you receive it from spawn/1 (or a related function) and use it as the destination for messages. Pid = spawn(fun loop/0), Pid ! {greet, "hi there"}. PI...
11. What is a module in Erlang?
A module is Erlang's unit of code organization — a single .erl file compiling to one unit that groups related functions under a shared name. The file starts with a -module(Name). declaration matching the filename, and an -export([...]). attribute listing which functions outside code may cal...
12. What are guards used for in Erlang?
A guard is an extra boolean condition attached to a function clause or case branch with the when keyword. It runs after the pattern matches structurally, letting you filter on values rather than just shape. classify(N) when N < 0 -> negative; classify(0) -> zero; classify(N) when N > 0 -> positiv...
13. What is OTP?
OTP (Open Telecom Platform) is the standard library and set of design principles bundled with Erlang for building reliable systems. It's not a separate product — it ships with the language and supplies battle-tested behaviors (reusable process templates) so teams stop reinventing server loo...
14. What is a gen_server?
gen_server is the OTP behavior for the common client/server pattern: a process that holds state and responds to requests. Instead of writing your own receive loop, you implement a small set of callbacks and the behavior handles the process mechanics. init(Args) -> {ok, State}. handle_call(Request...
15. What is a supervisor?
A supervisor is an OTP process whose only job is to start, monitor, and restart a set of child processes according to a restart strategy. It doesn't do business logic itself — it exists purely to keep its children alive. i n i t ( [] ) - > { ok , {{ o ne _ f or_o ne , 5 , 10 }, [{ worker 1 ...
16. Describe the "let it crash" philosophy?
"Let it crash" means Erlang code generally doesn't try to defensively handle every possible failure inline. Instead, when a process hits an unexpected state, it's allowed to terminate, and a supervisor detects that exit and restarts it fresh. The reasoning: trying to anticipate and recover from e...
17. What are records in Erlang?
A record is a compile-time convenience for naming the fields of a tuple, so you write Person#person.name instead of remembering that the name sits at tuple position 2. Under the hood a record is still a plain tuple with the record name as its first element. -record(person, {name, age = 0}). P = #...
18. What is message passing?
Message passing is how Erlang processes exchange information, since they share no memory. The ! operator sends a message asynchronously into the target process's mailbox, and receive pulls a matching message out of the caller's own mailbox. Pid ! {self(), {add, 2, 3}}, receive {ok, Result} -> Res...
19. What is hot code loading?
Hot code loading (or hot code swapping) is the BEAM's ability to load a new version of a module into a running system without stopping it. The runtime can keep two versions of a module in memory at once: the old version, still running for processes mid-execution, and the new version for anything ...
20. What are binaries/bitstrings in Erlang?
A bitstring is a sequence of raw bits; a binary is the common special case whose length is a multiple of 8 bits (whole bytes). They're the go-to type for network data, files, and any bulk binary payload, written between double angle brackets. Bin = <<1, 2, 3>>, <
21. What is ETS?
ETS (Erlang Term Storage) is an in-memory table built into the BEAM for storing large amounts of data that any process can read or write directly, bypassing normal message passing. It's how Erlang handles shared state that would be awkward to keep inside a single process's mailbox loop. Tab = ets...
22. What is Mnesia?
Mnesia is Erlang's built-in distributed database, layered on top of ETS/DETS storage. Unlike ETS, Mnesia adds transactions, replication across nodes, and optional disk persistence, so multiple nodes in a cluster can share and safely update the same tables. mnesia:create_table(person, [{attributes...
23. What are list comprehensions?
A list comprehension builds a new list by describing it declaratively: a result expression, a generator that walks a source list, and optional filters, all in one line, instead of writing an explicit recursive function. Squares = [X * X || X <- [1, 2, 3, 4], X rem 2 =:= 0]. %% Squares = [4, 16] R...
24. What is a behavior in Erlang?
A behavior is a formalized process pattern: OTP defines the generic, reusable parts (the message loop, error handling, standard API), and you supply a callback module that fills in the domain-specific parts. It's conceptually close to an interface plus a template method pattern from OOP. -module(...
25. What are ports in Erlang?
A port is Erlang's built-in mechanism for talking to an external OS process or native code, treated from the Erlang side just like another process you can send messages to and receive messages from. It's the standard, safe way to shell out to a C program, a script, or any external executable. Por...
26. What is a NIF (Native Implemented Function)?
A NIF is a function implemented in C (or another native language) and loaded directly into the BEAM, callable from Erlang exactly like an ordinary function. It's used when pure Erlang is too slow for a specific hot path, such as heavy numeric or cryptographic work. -module(math_nif). -export([fas...
27. How do you spawn a process in Erlang?
The base function is spawn/1 (or spawn/3 for a module/function/args form), which starts a new process running the given function and immediately returns its PID to the caller — there's no waiting for it to finish. Pid1 = spawn(fun() -> loop(0) end), Pid2 = spawn(counter, loop, [0]). In prac...
28. How does Erlang achieve concurrency without shared memory?
Instead of multiple threads reading and writing the same memory region, each Erlang process owns its own private heap and stack, and the only channel between processes is copying messages into a mailbox. There's nothing to lock because there's nothing shared to race over. Concretely, the BEAM's s...
29. What is the difference between spawn and spawn_link?
Both start a new process and return its PID, but they differ in what happens when that new process terminates abnormally. spawn spawn_link Caller and new process are independent; if the child crashes, the caller is unaffected. Caller and new process are linked ; if either crashes, the other recei...
30. What is the difference between a list and a tuple?
Both are ordered Erlang data structures, but they're built and used very differently. List Tuple Variable length; a linked chain of head/tail cons cells. Fixed length, decided at creation; contiguous positions. Cheap to prepend to ( [X|List] ); processed recursively. Cheap to access any known pos...
31. Why is Erlang considered fault-tolerant?
Fault tolerance in Erlang comes from combining process isolation with supervision, not from trying to prevent every possible bug. Because each process has its own heap and crashes independently, a failure in one part of the system doesn't corrupt shared state or take down unrelated processes. On ...
32. How does pattern matching differ from equality comparison?
Equality comparison ( == or =:= ) asks a yes/no question: are these two already-known values the same? Pattern matching ( = , function clauses, case ) does more — it can also bind unbound variables as a side effect of a successful match, and it can check structural shape rather than a singl...
33. When should you use ETS instead of process state?
Keeping data inside a single process's state works fine when only that process needs it, or when access is naturally serialized through that process's mailbox. ETS becomes the better fit once many processes need concurrent read/write access to the same data, because going through one process's ma...
34. How do you handle errors in Erlang without try/catch?
Erlang's idiomatic style leans on tagged return values for expected, recoverable failure conditions, reserving exceptions (and try/catch ) for genuinely unexpected situations. A function that can fail in an "ordinary" way typically returns {ok, Value} or {error, Reason} , and the caller pattern-m...
35. Why doesn't Erlang have mutable variables?
Erlang was designed around concurrent, isolated processes from day one, and mutable shared variables are exactly what makes concurrent programming dangerous in most other languages — race conditions, torn reads, and the need for locks all stem from two threads touching the same mutable cell...
36. What is the difference between gen_server and gen_statem?
Both are OTP behaviors for a stateful process, but they model that state differently. gen_server gen_statem State is an arbitrary term you pass between callbacks; behavior is the same regardless of what that term holds. State is explicitly modeled as one of a set of named states, with transitions...
37. How do you implement a simple supervision tree?
A supervision tree starts with a top-level supervisor whose init/1 callback declares a restart strategy and a child specification list; each child can itself be a worker or another supervisor, nesting arbitrarily deep. init([]) -> SupFlags = #{strategy => one_for_one, intensity => 5, period => 10...
38. What happens when a linked process crashes?
When a linked process terminates abnormally, the BEAM sends an exit signal carrying the exit reason to every process it's linked to. What happens next depends on whether the receiving process is trapping exits. process_flag(trap_exit, true), Pid = spawn_link(fun() -> exit(boom) end), receive {'EX...
39. When would you choose Mnesia over ETS?
Reach for Mnesia when data needs to survive beyond a single node, or beyond a single BEAM restart, or must be updated as part of a transaction spanning multiple tables. Reach for plain ETS when the data is node-local, disposable if the node restarts, and speed matters more than durability or cros...
40. How do you use the observer tool to inspect a running system?
observer is OTP's built-in GUI for peering into a live BEAM node: process list with memory and message queue length per process, supervision tree visualization, ETS table browser, and application overview, all without adding any extra code to the system being inspected. 1> observer:start(). Runni...
41. Explain the execution flow of a gen_server call?
gen_server:call/2 looks like a normal function call, but underneath it's a request/reply protocol built out of plain message passing plus a monitor for safety. sequenceDiagram participant Caller participant GenServer as gen_server process Caller->>GenServer: {'$gen_call', {Caller,Ref}, Request} N...
42. Explain the internal working of the BEAM scheduler?
The BEAM typically runs one scheduler thread per CPU core, and each scheduler maintains its own run queue of processes ready to execute. Rather than relying on OS-level time slicing, the BEAM preempts processes based on a reduction count — roughly one reduction per function call/operation &...
43. How can you optimize message passing between heavy processes?
The main cost in Erlang message passing is copying the message into the receiver's mailbox, so optimization mostly means reducing what gets copied and how often. Use off-heap binaries for large payloads — binaries over 64 bytes are reference-counted, so passing one only copies a small refer...
44. Explain the lifecycle of a supervised process?
A supervised worker follows a well-defined path from start to eventual restart or shutdown, orchestrated entirely by its supervisor. stateDiagram-v2 [*] --> Starting: supervisor calls start_link Starting --> Running: init/1 returns {ok, State} Running --> Crashed: unhandled error / exit Running -...
45. How do you troubleshoot process mailbox overflow?
A growing mailbox means a process is receiving messages faster than it processes them, which if left unchecked can exhaust memory and eventually crash the node. The first step is confirming which process(es) are affected. Pid = whereis(my_worker), {message_queue_len, Len} = process_info(Pid, mess...
46. What is the difference between synchronous and asynchronous message passing in OTP?
Both ultimately use the same underlying ! primitive, but OTP's gen_server:call and gen_server:cast wrap it with very different guarantees about waiting for a result. call (synchronous) cast (asynchronous) Caller blocks until a reply arrives or it times out. Caller sends and continues immediately;...
47. Which is better for state management, ETS or process dictionaries, and why?
A process dictionary ( put/2 , get/1 ) is per-process mutable key-value storage that bypasses Erlang's usual immutability, private to that one process only. ETS is a separate in-memory table that can be shared and accessed concurrently across many processes. ETS is generally the better choice whe...
48. How does distributed Erlang handle node failures?
Distributed Erlang connects multiple BEAM nodes into a cluster where PIDs, links, and monitors all work transparently across node boundaries — sending to a remote PID looks identical to sending locally. Node health is tracked through a mesh of TCP connections, each node maintaining a heartb...