
When Plaid’s recruiter emailed me and said, “The next step is a CodeSignal assessment,” I knew exactly what that meant: a four-question, 70-minute sprint that feels like a compressed LeetCode session with real stakes.
Plaid has used online coding assessments (HackerRank / CodeSignal) as the first technical filter for new-grad SWE roles for several years. Recent guides describe a pipeline of recruiter screen → online assessment or technical screen → onsite / virtual onsite.
On the CodeSignal side, their General Coding Assessment (GCA) is very standardised:
4 questions of varying difficulty
70 minutes total, with flexible time allocation
All questions available from the start; you can move between them freely
Multiple submissions allowed; your highest-scoring submission per question is kept
Add CodeSignal’s proctoring and Suspicion Score integrity system on top – webcam, screen recording, activity telemetry – and you get a pretty serious exam environment.
My 2025 new-grad SWE pipeline looked like this:
Online application
Recruiter call – background, timeline, basic questions like “Why Plaid?”
CodeSignal online assessment (the focus of this article)
Technical screen – live coding
Virtual onsite – several rounds: more coding, design, and behavioural
That lines up with most recent interview guides for Plaid: initial recruiter chat, one or more technical assessments, then a multi-round onsite or virtual onsite.
The CodeSignal OA was the first real technical gate. My recruiter was explicit: “Passing this is required to move forward.”
Official CodeSignal docs say the GCA has four questions in 70 minutes, and you can distribute your time however you like. Community posts also point out a pretty consistent difficulty pattern:
Q1: Tiny, implementation-only, almost no algorithm
Q2: Slightly larger implementation problem
Q3: Long simulation / implementation with non-trivial edge cases
Q4: The most algorithmic one (arrays / graphs / DP), worth the most points
My Plaid assessment followed this almost perfectly:
Q1 – format words based on length parity (string manipulation)
Q2 – simulate cd commands and return the final path (stack / path normalisation)
Q3 – simulate a molecular reactor queue with capacity constraints (time-based queue)
Q4 – find the largest square that fits in a skyline of skyscraper heights (array + brute-force optimisation)
Below I’ll walk through each of these four questions the way I understood and solved them during the assessment.
⚠️ Note: These are my own recollections and paraphrases of what I saw. CodeSignal regularly rotates and reuses questions, so your test may be different.
These problems are genuine problems I encountered during the assessment, which I am sharing along with the solutions I provided.
(Warm-up: strings, O(n·L))

The first question was a gift – basically a sanity check to make sure you can manipulate strings without panicking.
You’re given an array wordsList of strings.
If a word’s length is odd, convert it to uppercase.
If its length is even, reverse the characters (case preserved).
Return a new array with each word transformed. If the input is empty, return an empty array.
Example
wordsList = ["HeLLo", "Data", "science"]
# Output: ["HELLO", "ataD", "SCIENCE"]
"HeLLo" → length 5 (odd) → "HELLO"
"Data" → length 4 (even) → "ataD"
"science" → length 7 (odd) → "SCIENCE"
I told myself: Don’t over-engineer Q1. This is the trap where people start worrying about optimisation when the problem is literally:
res = []
for word in wordsList:
if len(word) % 2 == 1:
res.append(word.upper())
else:
res.append(word[::-1])
return res
I spent maybe 3–4 minutes on this:
One pass over the list
A couple of custom test cases
Submit once and move on
Let n = len(wordsList) and L = max word length:
Time: touch every character once → O(n·L)
Space: new list with transformed words → O(n·L)
The real skill here is resisting the urge to “get clever” and instead banking a quick, correct question.
This question is indeed a bit difficult. So I utilised the linkjob.ai tool, which remains invisible on screen and thus evades detection by interview platforms.

cd Commands(Stacks / path reconstruction)

The second question was basically a mini shell: simulate cd and output the final absolute path.
You start at the root directory /. You’re given an array commands, where each element is a string of one of these forms:
"cd /" – go to root
"cd ." – stay in the current directory
"cd .." – go up one level (no effect if you’re already at /)
"cd <subdir>" – go into the child directory <subdir> (a lowercase string)
All specified directories are valid. After executing all commands in order, return the absolute path to the final directory. Use / as the separator; root by itself is /.
Example
commands = [
"cd users",
"cd codesignal",
"cd ..",
"cd admin"
]
# Output: "/users/admin"
This is almost identical to the classic “simplify Unix path” problem.
I kept a stack of directory names representing the current path under root:
Initialise stack = [].
For each string in commands:
Split it: cmd, arg = line.split()
If arg == "/": stack = []
Else if arg == ".": do nothing
Else if arg == ".." and stack not empty: stack.pop()
Else: stack.append(arg)
After processing everything:
If stack is empty → return "/"
Else → return "/" + "/".join(stack)
I made sure to test a couple of edge cases:
Multiple cd .. from root in a row
Commands that end at root again
Let m = len(commands), L = max command length:
Time: split + a couple of operations per command → O(m·L)
Space: at most one directory segment per command in the stack → O(m·L)
After Q2 I was around the 20-minute mark and feeling good.
(Simulation + queue + event timing)

This was the classic CodeSignal “story question” that is 95% simulation and 5% algorithm.
You’re a senior chemist running a molecular reactor:
The reactor processes one sample at a time.
Each synthesis takes exactly 5 minutes = 300 seconds.
Samples arrive over the day at times given by array times (seconds from day start), in non-decreasing order.
While waiting for the reactor, samples sit in a cooling chamber.
The cooling chamber can hold at most 10 waiting samples (not counting the one currently in the reactor).
If a new sample arrives when there are already more than 10 samples waiting, the new one is rejected.
If a sample arrives exactly when another finishes, you process the waiting queue first:
The finished sample leaves the reactor
Immediately take the next waiting sample into the reactor
Then put the newly arrived sample into the chamber (if there is space)
You must compute the time in seconds when all accepted samples will have finished processing.
The prompt explicitly said any solution with time complexity not worse than O(times.length²) would pass, so a straightforward simulation was fine.
I treated it as a single-server queue with capacity.
State:
currentTime – time when the reactor will be free
waiting – number of samples in the cooling chamber
duration = 300 seconds
Algorithm sketch:
currentTime = 0
waiting = 0
duration = 300
for t in times:
# First, process as many completions as possible up to time t
while waiting > 0 and currentTime <= t:
# One sample finishes at currentTime
waiting -= 1 # one leaves the queue and enters reactor
currentTime += duration
# Now handle the arriving sample at time t
if currentTime <= t and waiting == 0:
# Reactor idle; start immediately
currentTime = t + duration
else:
# Reactor busy or waiting queue non-empty
if waiting < 10:
waiting += 1 # sample accepted into cooling chamber
else:
# rejected; do nothing
pass
# After all arrivals, process remaining waiting samples
while waiting > 0:
waiting -= 1
currentTime += duration
return currentTime
The tricky part is correctly handling the “arrival exactly when something finishes” rule. Processing completions before considering the new arrival naturally matches:
Finished samples leave
The next waiting sample goes into the reactor
The fresh arrival joins the queue afterward
Let n = len(times):
Each accepted sample enters and leaves the waiting queue once; each synthesis adds one duration.
The loops are effectively linear in the number of accepted samples.
Even if I’m slightly pessimistic, this easily falls under the allowed O(n²) time, with O(1) extra space.
I spent ~20 minutes here, mostly double-checking edge cases like:
Many arrivals bunched together
A long idle gap after everything is processed
(Array + brute-force optimisation, O(n²))

The last question was the “algorithmic” one. Once I stripped away the city story, it was a largest-square-in-histogram problem.
You’re given an array cityLine of positive integers. Each value is the height of a skyscraper in a row; each skyscraper has width 1.
You want to place the largest possible square such that:
Its base spans a contiguous block of skyscrapers.
Let h be the minimum height among those skyscrapers, and w the number of skyscrapers in the block. Then the side length k of any square on that block must satisfyk ≤ h and k ≤ w.
Return the area k² of the largest possible square.
Example
cityLine = [1, 2, 3, 2, 1]
# Best square has side length 2 → area 4
Visually you can see several 2×2 squares; trying a 3×3 fails because there’s no stretch of width ≥3 where all skyscrapers are height ≥3.
The statement again said an O(n²) solution is fine.
Let n = len(cityLine).
I did a controlled brute force over all segments:
Initialise best = 0.
For each starting index i from 0 to n-1:
Set minHeight = cityLine[i].
For each ending index j from i to n-1:
Update minHeight = min(minHeight, cityLine[j]).
The segment length is width = j - i + 1.
The largest possible square side is side = min(minHeight, width).
Update best = max(best, side * side).
Return best.
The key trick is maintaining minHeight incrementally as j expands, so we don’t recompute minimums from scratch for each (i, j) pair.
Nested loops over i and j → O(n²)
All operations inside are O(1)
Space is O(1) extra
There is a more advanced monotonic stack solution in O(n) or O(n log n), but the problem literally told me O(n²) is enough. Under time pressure, I preferred “simple and obviously correct” over “fancy and buggy.”
I finished Q4 with a few minutes left to re-run tests on all questions and clean up stray debug prints.
Looking back, what actually moved the needle for me wasn’t grinding 1,000 random LeetCode problems – it was targeted practice aligned with the CodeSignal format.
I read CodeSignal’s own docs and several external guides:
4 questions, 70 minutes, varying difficulty
You can move between questions freely; best submission per question is kept
GCA is used as a “coding score” style benchmark for early-career roles
Just knowing that Q1 is supposed to be trivial and Q4 is supposed to be the hard one made time-management decisions much easier.
Because CodeSignal reuses question templates across companies, practising by pattern is more effective than hunting for “Plaid-only questions.”
I focused on:
Strings / arrays: implementations like Q1 (formatting, case conversion, reversing).
Stacks: path simplification, bracket matching, undo/redo (for Q2).
Queues & simulations: rate limiters, printers, processing queues (for Q3).
Histogram-style array problems: largest rectangle / square, prefix minima, monotone stacks (for Q4).
I simulated the real 70-minute experience:
5 minutes to read all four questions
≤10 minutes for Q1
15–18 minutes for Q2
~20 minutes for Q3
Whatever remains for Q4 + final review
Reddit threads and blog posts confirm that this pacing mirrors how GCAs are designed to feel.
By the time I took Plaid’s OA, the format felt familiar rather than scary.
CodeSignal employs certain detection methods, such as 'suspicious score' detection. Because of this, I needed to find an application that truly provides AI support but is not easily detected. After searching extensively, I saw that the reviews for the LinkJob AI app were quite good. After trying it out, I found that its screenshot analysis feature was genuinely helpful for solving CodeSignal problems. I did use this feature in my formal test and successfully passed it, which is why I'm willing to share my interview experience here.

If you’re aiming to ace the Plaid CodeSignal assessment:
Know the format. 4 questions, 70 minutes, difficulty ramp, best score kept.
Bank Q1 and Q2 quickly. They’re mostly implementation – don’t overthink them.
Get systematic about simulation. Questions like the molecular reactor reward careful modelling more than clever tricks.
Accept O(n²) when the statement allows it. For skyline-style questions, a clean quadratic solution is better than a half-baked O(n log n) attempt.
Practise under realistic conditions and treat AI as a prep partner, not a live crutch.
I pause and reread the question. I break the problem into smaller parts. Sometimes, I write a quick plan in the editor. If I still feel stuck, I move on and come back later.
I practice with a timer. I set mini-deadlines for each question. I review my solutions after each session and look for ways to solve problems faster next time.
I choose the language I know best. I stick with it during practice. This helps me avoid mistakes and lets me focus on solving problems, not syntax.
I always check my connection before starting. I keep my phone nearby as a backup. If I lose connection, I reconnect quickly and contact support if needed.
My Journey To Success In The BCG X Assessment
Strategies And Tips For Succeeding In TikTok's Assessment
Lessons Learned From My Ramp CodeSignal Assessment Success
Transforming Anthropic Practice Into A Successful Routine
Reflecting On My xAI CodeSignal Assessment Interview Journey