Elixir & Erlang/OTP Module 3
Pattern matching and control flow interview questions
Interview questions on pattern matching and control flow: warm-ups, then what each harder question tests and how a good answer starts.
Warm-up questions
Short questions with short answers, each answered in full.
-
Fresher
Is = assignment in Elixir? What does it do, and what is the pin operator for?
Answered in the lesson Pattern matching, the match operator and the pin
-
Fresher
When do you use case, when cond and when if in Elixir?
-
Fresher
What is a guard in Elixir, and what may it contain?
Questions with model answers
What each question tests, the first step of a good answer and the follow-ups to expect.
-
Fresher to mid
A service starts with {:ok, text} = File.read("settings.json"). On a new server it stops at boot with a MatchError showing {:error, :eacces}. A teammate proposes rescuing the error and starting with built-in defaults. What do you recommend, and how should start-up treat a settings file that is missing or wrong?
- What it tests
- Reading what a MatchError reports, telling a broken setup from an expected failure, and choosing between a crash, a clearer error and handling with case.
- First step
- Read the value in the error: :eacces means the file is there but the service may not read it, a deployment mistake that no code can repair. Starting with defaults would hide it and run the service with settings nobody chose, so start-up should stop, with a message that names the file and the reason.
- Follow-ups
-
- Would File.read!/1 be better than the match here?
- The file is optional on developers' machines. What changes?
- The file exists, but its JSON is invalid. What should start-up do?
From the lesson Pattern matching, the match operator and the pin
Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.Opening the model answers with your pass…
Model answers open with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so the model answers can’t be opened at the moment. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Fresher to mid
A webhook handler starts with %{"event" => event, "amount" => amount} = payload, the decoded JSON from a payment partner. After the partner adds a refund event without an amount, requests fail with 500, the partner retries, and the crash logs fill with whole payloads, customer emails included. Explain each effect and redesign the handler.
- What it tests
- Seeing that let it crash is for the unexpected, not for outside input, that a MatchError prints the whole value, and checking untrusted data with case and explicit errors.
- First step
- Separate the two kinds of failure. A partner's payload is outside input, so a shape the code does not know is an expected event, not a bug. The match turns it into a crash, the crash into a 500 that invites a retry, and the MatchError message prints the whole payload into the log.
- Follow-ups
-
- What status should the handler return for a payload it cannot use?
- How do you keep personal data out of the logs when a request fails?
- How do you test the handler against the partner's next new event?
From the lesson Pattern matching, the match operator and the pin
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
An order router has the clauses {:ok, order} when length(order.items) > 0 -> ship(order) and {:ok, _order} -> :empty_order. Orders from an old import, whose items field is nil, have been reported as empty for weeks, and nothing ever raised. Explain why, and rewrite the clauses.
- What it tests
- Knowing that an error inside a guard makes the clause fail silently, matching on the shape of a list instead of its length, and deciding what data of the wrong kind should do.
- First step
- Run the guard by hand on an order from the import: length(nil) raises ArgumentError, but inside a guard an error only makes the clause fail, so the order falls through to the :empty_order clause. The compiler had already warned about length(order.items) > 0 and suggested a pattern instead.
- Follow-ups
-
- Should an order with items set to nil raise, or be routed somewhere?
- Why does the compiler prefer [_ | _] to length/1 here?
- Which tests would have caught it on the first day?
From the lesson case, cond, if and unless
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
An HTTP client returns {:ok, %{status: status}} or {:error, reason}. Write the case that decides whether to retry: which statuses and errors are worth another try, in what order the clauses go, and what happens to a status or a reason you did not expect.
- What it tests
- Writing case clauses with patterns and guards for a real policy, ordering them from specific to general, and choosing between a catch-all and a crash on purpose.
- First step
- Sort the outcomes first: 2xx is done; 408, 429, 502, 503 and 504 may succeed later; other 4xx and 5xx will fail the same way again; a timeout may succeed later. Then write one clause per group, the specific ones on top, with guards such as status in 400..599 for the general ones.
- Follow-ups
-
- A 429 comes with a Retry-After header. Where does that go?
- Is it safe to retry a POST that timed out?
- How do you keep the clauses in the right order as the policy grows?
From the lesson case, cond, if and unless
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
All Elixir & Erlang/OTP interview questions · The Elixir & Erlang/OTP track