General Motors Of Canada · Software Engineer
Updated · 2026-09-24

General Motors Of Canada Software Engineer
Interview Guide

THE 60-SECOND BRIEF

At General Motors Of Canada, a Software Engineer plays a critical role in redefining the future of personal mobility. As the automotive industry shifts toward electric vehicles (EVs), software-defined architectures, and autonomous driving (ADAS), General Motors Of Canada's engineering teams are building the systems that make these innovations possible. From the Markham Software Technology Centre to the company's historical manufacturing hubs, software development supports vehicle safety, infotainment (such as the Ultifi platform), cloud telemetry, and manufacturing automation.

The behavioural round is a technical round in narrative form. Prepare it by collecting specifics you actually owned, such as a design you argued against, an incident you diagnosed, or a decision you later reversed, rather than by rehearsing phrasing.

General Motors Of Canada candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.

Make every external side effect safe to retryModel units, lots and state machines preciselyKeep a site operating during a network partition

38 min read

Practice 15 Software Engineer prompts
15Practice promptsAcross five skill areas
3With worked solutionsIncluded in the practice prompts

At General Motors Of Canada, a Software Engineer plays a critical role in redefining the future of personal mobility. As the automotive industry shifts toward electric vehicles (EVs), software-defined architectures, and autonomous driving (ADAS), General Motors Of Canada's engineering teams are building the systems that make these innovations possible. From the Markham Software Technology Centre to the company's historical manufacturing hubs, software development supports vehicle safety, infotainment (such as the Ultifi platform), cloud telemetry, and manufacturing automation.

You will contribute to large-scale, safety-critical software that interacts directly with vehicle hardware, cloud-based data pipelines, and customer-facing interfaces. This requires a unique blend of robust systems programming, modern software design patterns, and an uncompromising focus on reliability. Whether you are optimizing embedded C++ code for real-time controllers, building scalable Java microservices, or developing Android-based infotainment applications, your work directly impacts millions of drivers globally.

This position demands both technical rigor and exceptional collaboration. As a, you will work closely with cross-functional teams of product managers, hardware engineers, and systems designers. The problems you will solve are complex, highly regulated, and deeply rewarding. Success in this role means writing clean, testable code while maintaining a holistic view of how your software integrates into the physical vehicle and the broader digital ecosystem of.

01

Recruiter Phone Screen

reported

The title covers product work, platform work, infrastructure, mobile and frontend, and those are different jobs with different loops behind them. A screening call is the cheapest place to find out which one the seat is, and asking reads as experienced rather than fussy. The questions that separate them: what the team is on call for, what the last three projects were, and whether any round happens inside an existing repository instead of a blank file. Then say which of that you have done and which you have not. Claiming the whole posting is the fastest way to be found out one round later.

What to demonstrate

  • Whether you can locate your experience inside one flavour of the role honestly instead of claiming the entire requirements list
  • Whether you name what you have not done, which an experienced screener reads as a level signal and can plan the loop around
  • Whether what you want next matches what the seat is: someone who wants greenfield work landing on a team that mostly operates an existing system is a hire that leaves within the year

How to prepare

  • Mark every line of the posting as done, adjacent or new, and write one sentence for each adjacent line naming the closest thing you actually built
  • Split your last two years into rough percentages across feature work, operating and debugging live systems, and design or review, so a question about scope gets numbers rather than adjectives
  • Bring three questions that discriminate between seats: what the team is paged for, how much of the work is changing existing code versus standing up something new, and what shipped in the last quarter
PracHub interview research ↗
02

Online Technical Assessment

reported

What this round decides is narrow: whether you can produce code that runs and is correct on inputs nobody showed you. An elegant solution that does not compile scores below a plain one that does, so write a correct brute force first, say out loud that you know its cost, and improve it with the working version still on screen. What separates strong answers is who finds the broken case. Trace your own code against an empty input, a single element, and duplicate keys before you say you are finished, because being told is far more expensive than noticing.

What to demonstrate

  • Whether degenerate inputs get checked without being asked for: an empty collection, one element, every element equal, and the extreme value the input type allows
  • Whether the complexity you state matches the code you actually wrote, including a sort or a copy sitting inside a loop
  • Whether the finished answer is verified against the worked examples before you call it done, rather than assumed correct because the code reads correctly

How to prepare

  • Take five problems you have already solved and, without running anything, write down what each returns for empty input, a single element, and all-duplicates. Then run them and count how many you predicted wrong.
  • Drill the brute force as its own skill: on ten problems, write only the obviously-correct slow version and time how long it takes to get it passing. If that is more than a few minutes, that is what to practise, not the optimal version.
  • Add a fixed last step before you submit anything, reading only the loop bounds and the initial value of each accumulator, which is where most off-by-one errors live
PracHub interview research ↗
03

Panel Interviews

reported

A day like this is several different games in a row, and the expensive mistake is carrying the previous one into the next room. Coding rewards narrow precision and finishing inside a timer. Design rewards breadth, stated assumptions and naming what you are deliberately not building. Behavioural rewards specificity about people and decisions. Candidates who over-engineer a coding problem they were supposed to finish, or who start sketching class hierarchies before anyone has agreed what the system has to do, are usually still playing the last round. Between rooms, name out loud which game the next one is.

What to demonstrate

  • Whether the coding round ends with something that runs and has been traced against a degenerate input, rather than an extensible design that was never finished
  • Whether a design discussion opens by agreeing on traffic shape, read-to-write ratio and what is allowed to be stale, instead of proceeding from an architecture you arrived with
  • Whether a behavioural answer names a person, a disagreement and what you did about it, rather than describing the system the story happened inside
  • Whether the opening habits still appear late in the day: restating the problem, asking for constraints, saying the plan before typing

How to prepare

  • Book three mocks of different types back to back on one afternoon and ask each interviewer afterwards which round you answered in the wrong mode
  • Write a three-line opening script per round type — coding: restate, name the approach and its cost, then type; design: ask for scale, read-write mix and what must not break; behavioural: name the person, the stakes and the decision — and run it off a card so the switch is mechanical rather than remembered
  • Practise coding with a timer you do not extend, stopping when it stops, so the trained reflex is to finish a correct solution rather than to keep improving one
PracHub interview research ↗

PracHub editorial advice for the preparation topics above.

01

Treating the database as the truth about physical stock

Every system in this domain drifts from reality, through miscounts, unrecorded damage, mis-scans and theft, so a design with no adjustment path forces the drift somewhere worse. The usual shape is a CHECK constraint or application guard that clamps a position at zero: the negative that would have exposed a missing receipt is silently swallowed, and the first visible symptom is a picker standing at an empty location for an order the system promised. The correct posture is to let the invariant fail loudly - record the cycle-count adjustment as a first-class movement with its own reason code, surface the variance, and let planning see that this location is unreliable - because an adjustment that is indistinguishable from a normal pick destroys the only signal that would have found the root cause. A related version of the same mistake is deleting or updating a movement row to fix a mistake, which leaves the position correct and the history a lie.

02

Judging delivery windows and cut-offs in UTC

A delivery appointment, a receiving cut-off and a same-day promise are all statements about local wall-clock time at a specific stop, so evaluating them in UTC misclassifies on-time performance for any leg that crosses a zone, and misses cut-offs by an hour on the two days a year a region changes offset. The subtlety that catches experienced engineers is that converting a future local time to a UTC instant at write time bakes in the offset rules as they were known then: when a jurisdiction changes its rules, an appointment stored that way silently moves, which is why a future window is better stored as local wall time plus an IANA zone identifier and resolved at read time, while a past event is correctly stored as an instant. Duration arithmetic needs the same care, because a transit that spans a DST boundary is genuinely 23 or 25 hours long in local terms even though the elapsed instant count is unchanged. Storing only a date with no zone - common on partner feeds - is the version of this that cannot be fixed downstream, so the zone has to be captured at ingestion.

03

Assuming the bug is in the framework

Suspect your own code first: read the stack trace top to bottom, check which versions are actually installed rather than which ones you believe are, and reproduce in isolation before blaming a library that thousands of people run daily. When the fault really is upstream, you need that minimal reproduction to say so credibly anyway.

04

Arguing past a hint

When the interviewer asks what happens for a particular input or floats a different data structure, stop and take it seriously; it is almost always a correction rather than idle curiosity. Talking over it converts a recoverable wrong turn into a data point about how you handle review.

Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.

12 technical prompts3 include a worked solution

Given a list of strings, write a program to capitalize the first lette…

medium
data structures and algorithms

Given a list of strings, write a program to capitalize the first letter of each string while handling edge cases like empty inputs.

Approach
  1. Restate the input: its shape, its size, and what is guaranteed about it.
  2. State the target complexity and say which constraint rules the naive version out.
  3. Choose the data structure from the access pattern, not from familiarity.
Follow-up
  • How does this change if the input no longer fits in memory?
  • Which test case would catch an off-by-one here?

Write a function to reverse a string or manipulate an array of element…

medium
data structures and algorithms

Write a function to reverse a string or manipulate an array of elements efficiently.

Approach
  1. Restate the input: its shape, its size, and what is guaranteed about it.
  2. Choose the data structure from the access pattern, not from familiarity.
  3. Walk one small example through your approach before writing the whole thing.
Follow-up
  • Which test case would catch an off-by-one here?
  • How does this change if the input no longer fits in memory?

Write a program to process a simulated stream of sensor data (such as …

medium
data structures and algorithms

Write a program to process a simulated stream of sensor data (such as a CSV file) and filter out anomalies based on specific thresholds.

Approach
  1. Choose the data structure from the access pattern, not from familiarity.
  2. Name the brute-force solution and its complexity before improving on it.
  3. Restate the input: its shape, its size, and what is guaranteed about it.
Follow-up
  • What is the worst case, and how likely is it on real data?
  • How does this change if the input no longer fits in memory?

Solve a classic array-sorting or searching problem, explaining the tim…

medium
data structures and algorithms

Solve a classic array-sorting or searching problem, explaining the time and space complexity of your approach.

Approach
  1. Name the brute-force solution and its complexity before improving on it.
  2. Restate the input: its shape, its size, and what is guaranteed about it.
  3. State the target complexity and say which constraint rules the naive version out.
Follow-up
  • How does this change if the input no longer fits in memory?
  • Which test case would catch an off-by-one here?

Re-sum a movement ledger and report positions that disagree

easyWorked solution
aggregationreconciliationappend-only ledger

inventory_movement holds 3 billion immutable rows: item_id, node_id, lot_id (NULL when the item is lot-untracked), state, delta_qty (signed int64 in the item's smallest transacting unit), uom_code, and reversed_by. inventory_position holds one row per (item_id, node_id, lot_id, state) with qty, version and last_movement_id, using lot_id = 0 as the sentinel for untracked. Up to 80 million distinct keys. Report every key whose summed movements disagree with the stored qty, while writes continue. State your time and space bounds and how you bound the comparison.

Approach
  1. Fix the key first. inventory_movement.lot_id is NULL for untracked items and inventory_position.lot_id is 0, so the group key is (item_id, node_id, COALESCE(lot_id, 0), state). Getting this wrong does not error — it silently produces two groups that each look like a variance, and the report becomes noise nobody reads.
  2. Cut the ledger at a watermark, but do not take W = max(movement_id) at the start of the scan. A sequence hands out an id before the inserting transaction commits, so at the instant you read that maximum there are ids below it still in flight and invisible to your snapshot. Summing movement_id <= W misses them on this run, and advancing reconciled_through_movement_id to W makes the miss permanent: every later incremental run starts above those ids and they are never summed again. That is a hole in the ledger's own re-derivation, not a transient skew.
  3. Take a watermark that is provably settled instead. Bound write transactions with a statement or transaction timeout so 'the longest write' is a number T, record (observed_at, max_movement_id) samples periodically, and use as W_safe the largest sampled id whose observed_at is older than T — every id at or below it has committed or rolled back. Sum rows with movement_id <= W_safe, compare only against position rows with last_movement_id <= W_safe, treat anything newer as a write that raced you rather than a variance, and advance reconciled_through_movement_id only to W_safe so the next run starts there instead of re-reading 3 billion rows. If the ledger carries a commit timestamp, cutting on that is the same guarantee without the sampling table.
  4. Sum delta_qty as int64, and include reversal rows. reversed_by is a back-pointer for audit, not an exclusion filter: an original of +10 and its reversal of -10 must both be summed to reach 0. Excluding the original while keeping the reversal produces -10 and a false variance on every corrected key.
  5. Guard the denomination rather than trusting it. uom_code is stored per row because pack factors change over time, so reject — do not sum — any row whose uom_code is not the item's smallest transacting unit, and report those keys separately. A mixed-denomination sum is arithmetically meaningless and looks exactly like a real variance.
  6. Hash aggregation is O(n) time and O(distinct keys) space: 80 million entries at roughly 40-56 bytes each in a typical runtime is 3-5 GB, so quote the number. The bounded-memory alternative is an external sort-merge on the group key — O(n log n) comparisons, resident memory bounded by the merge fan-in rather than by key count, and it streams — or hash-partition by hash(item_id) % P and run P independent passes for 1/P of the peak.
Worked solution 25 min
  1. Write the group key expression down explicitly, including the NULL-to-0 mapping, before any aggregation code.
  2. Derive W_safe from a sample older than the transaction-duration bound T, and state in one sentence which rows on each side are in scope — this is the part that makes the report trustworthy under live writes, and the part that decides whether an in-flight row is re-read next run or lost forever.
  3. Implement the hash aggregation with an int64 accumulator and a uom_code assertion per row, emitting rejected rows to a second output rather than into the sum.
  4. Build a fixture with four keys: one clean, one with a movement missing from the position, one with an original plus its reversal, one with a row in cases where the item transacts in eaches.
  5. Run it, then re-run with the fixture rows shuffled, with a concurrent writer appending past the watermark, and with a writer that reserved an id below max(movement_id) and commits only after the scan finishes — then run the incremental pass and confirm that row is summed there.
EXPECTED RESULTExactly one key is reported as a quantity variance; the reversed key reconciles to zero difference; the mixed-unit key appears in the rejected-rows output rather than the variance list; rows appended past the watermark change nothing; the row whose id was reserved below `max(movement_id)` but committed late still sits above `W_safe`, so the next incremental run sums it instead of skipping it permanently.
Follow-up
  • A key shows a variance of exactly one pick, repeatedly, at one node. What do you look at first, and what would distinguish a duplicate movement from a missed one?
  • The job takes six hours and the variance report is stale by the time anyone reads it. How would you make it incremental without losing the guarantee that it re-derives from the ledger?
  • Who writes the correcting movement, and what reason code does it carry?

Four days sample coding, design, fundamentals and the practical rounds at deliberately shallow depth, which is enough to surface the topics you did not know were in scope. That map, rather than a guess made on day one, decides where the last three days go.

Small steps. Visible outcomes.0 / 7 completed
ONE WEEK · YOUR PACE

Prepare, practise & reflect

One practical outcome each day. Spend longer where you need it.

0 / 7 done
01Coding, one pass at shallow depth
  • Solve one problem from each of six families, an array with two pointers, hash counting, binary search, a tree traversal, a graph traversal and one dynamic program, under a hard twenty-minute cap with no extensions, marking each finished, late, or stalled.
  • For every stall, write the exact move you could not make rather than the subject, so the note reads could not turn the recurrence into a loop rather than bad at dynamic programming.
  • Fix nothing today. The value of the pass is the unfixed record.

Deliverable: Six timed attempts marked finished, late or stalled, each stall carrying a named blocking move.

Practice prompt ↗Practice prompt ↗Practice prompt ↗Worked solution ↗
02Design, one pass at shallow depth
  • Spend twenty minutes each on three different shapes, a read-heavy feed, a write-heavy ingest path, and something needing a transaction across two entities, stopping each at requirements, interface and data model.
  • After each, write the first question you could not answer, which is usually a number you could not estimate or a failure mode you had no vocabulary for.
  • Mark which of the three you would be most relieved not to be asked, and treat that as data rather than as a preference.

Deliverable: Three shallow designs, each with the first unanswerable question written at the bottom.

Practice prompt ↗Practice prompt ↗
03Fundamentals and the practical rounds
  • Answer eight short questions in writing at four minutes each, covering the material that fills the gaps between the big rounds: what happens between a URL and a rendered page, what an index costs on write, when a process is preferable to a thread, and what conditions a deadlock requires.
  • Do one thirty-minute practical task of the kind a take-home compresses: read an unfamiliar two-hundred-line file and write what it does, what you would change, and the one thing you remain unsure of.
  • Score every answer fluent, correct but slow, or absent, and keep the absent ones visible.

Deliverable: Eight scored short answers and one written reading of unfamiliar code.

Practice prompt ↗Practice prompt ↗
04The rounds that are about you, and the map
  • Deliver three behavioural answers aloud against a timer, a conflict, a failure you owned, and a decision made without enough information, marking any that ran past three minutes or contained no number.
  • Assemble the map: every marked item from days one to three on a single page, sorted by how likely it is to appear in your loop rather than by how uncomfortable it felt.
  • Choose exactly two areas for the remaining three days and write down what you are deliberately abandoning.

Deliverable: A one-page scored map of the whole surface area with two areas chosen and the rest explicitly abandoned.

Practice prompt ↗Practice prompt ↗Worked solution ↗
05First chosen area, to the depth you skipped
  • Work the higher-ranked area in four focused blocks, choosing items one level above where you stalled rather than repeating what already works.
  • After each block write the rule you extracted in one sentence with its precondition attached, since a rule carrying no precondition is exactly what fails under a variation.
  • Re-attempt the day-one or day-two item that exposed this area and compare against the original timing.

Deliverable: Four worked blocks, a timed re-attempt against the original, and three one-sentence rules with preconditions.

Practice prompt ↗Practice prompt ↗
06Second chosen area, where the gap is coverage rather than speed
  • Treat the second area differently from the first. Day five drilled something you could already half-do; this one is usually a topic you had simply never met, so build one worked reference example end to end and keep it, rather than attempting six problems badly.
  • Write down the vocabulary you were missing on day two or three, five terms at most, each with the one sentence that makes it usable in an answer rather than the textbook definition.
  • Redo the shallow attempt that exposed this area and note whether you now fail later in the problem, because moving the failure point is the realistic gain from a single day and is worth more than a score that did not change.

Deliverable: One worked reference example for the newly covered area, a five-term vocabulary list, and a note on where the failure point moved.

Practice prompt ↗Practice prompt ↗
07Reassemble the loop
  • Sit two rounds back to back with no gap, ordering them so the area you chose second comes last, because the map was built from rested, isolated attempts and the loop will reach your weaker area when you are already spent.
  • Write where the second round suffered from the first, which is normally the point at which structure collapses into narration.
  • Reduce the week to one page holding only the rules you can state without reading them.

Deliverable: Mock notes on cross-round carryover plus a one-page card of rules you can recite from memory.

Practice prompt ↗Practice prompt ↗Worked solution ↗

Expand any day for tasks and deliverables. Your progress is saved on this device.

Conflict answers where you were right and everyone came round are the weakest ones. Stronger: the evidence you went and collected, what would have changed your mind, and what you did in the weeks after the call went against you. Implementing a design you argued against, properly, is a specific and checkable behaviour.

Tell me about a time when you had to deal with a difficult coworker or…

medium
behavioural and engineering judgement

Tell me about a time when you had to deal with a difficult coworker or team dynamic. How did you resolve the conflict?

Approach
  1. Give the blast radius: what could have broken, and what you measured.
  2. Close with what you would do differently, concretely.
  3. Pick a story where you made the decision, not one where you watched it.
Follow-up
  • How did you know your change caused the improvement?
  • What would you do differently if you ran that again?

Describe a challenging project you worked on. What was the obstacle, a…

medium
behavioural and engineering judgement

Describe a challenging project you worked on. What was the obstacle, and how did you overcome it?

Approach
  1. Close with what you would do differently, concretely.
  2. Name the disagreement and how you resolved it with evidence.
  3. Give the blast radius: what could have broken, and what you measured.
Follow-up
  • What would you do differently if you ran that again?
  • How did you know your change caused the improvement?

Unblock an engineer whose replayed feed double-counts

easy
mentoringevent timededuplicationidempotency

An engineer on your team consumes a partner status feed that resends a rolling 24-hour window every night. Their consumer folds each message into shipment_leg.status by last write wins, keyed by partner message id. Deliveries are flipping back to in transit each morning, and some receipts are counted twice. They have been on it two days and ask for help. Describe a time you unblocked someone: how you diagnosed it together, which of the two independent defects you pointed at, what you deliberately let them find, and how you checked the fix held.

Approach
  1. Start by getting the two defects named separately, because they are independent and fixing one hides the other: duplicates are a deduplication problem, and statuses regressing is an ordering problem. A consumer can be perfectly deduplicated and still flap.
  2. Fix the dedupe key first, since it is the cheaper of the two and it is wrong for a stated reason: a partner message id changes on resend, so it identifies the transmission rather than the observation. The stable key is the source plus the device or partner event sequence, enforced as a unique constraint on observation_event.dedupe_key so a replayed window becomes a no-op at the database rather than a judgement in application code.
  3. Then fix the fold: order by occurred_at, compare status_rank on the progress lattice and take the maximum, so a picked_up event arriving after delivered is recorded but cannot lower the leg. Keep the superseded observation rather than dropping it, because it is usually the row that explains a later dispute.
  4. Teach the diagnostic rather than the answer. Ask them to replay one leg's observations in shuffled order and assert the same final status, which is the property that makes the fold order-insensitive and is a test they can write in twenty minutes. Let them discover from their own data that occurred_at is sometimes wrong, which is why clock_offset_ms is stored beside it and why the lattice, not the timestamp, is what guarantees monotonicity.
  5. Check it held with data rather than with a green build: count legs whose status_rank decreased in the last day, expect zero, and keep it as a standing assertion. Say what you did with the rows the old consumer had already corrupted, because leaving them is a decision too.
  6. Be honest about the handoff. Say how long you spent, what you did not do for them, and whether they could explain the fix back to you afterwards, which is the only durable test that the unblocking worked.
Follow-up
  • They ask whether broker ordering guarantees solve this for them. What do you say?
  • An event arrives a week late and its status is below the current one. What should the pipeline do with it, and what should it tell anyone reading the leg?
  • How do you repair the legs already corrupted, given the observations are all still stored?
  • 01

    Tell me about a time when you had to deal with a difficult coworker or team dynamic. How did you resolve the conflict?

  • 02

    Describe a challenging project you worked on. What was the obstacle, and how did you overcome it?

  • 03

    An engineer on your team consumes a partner status feed that resends a rolling 24-hour window every night. Their consumer folds each message into shipment_leg.status by last write wins, keyed by partner message id. Deliveries are flipping back to in transit each morning, and some receipts are counted twice. They have been on it two days and ask for help. Describe a time you unblocked someone: how you diagnosed it together, which of the two independent defects you pointed at, what you deliberately let them find, and how you checked the fix held.

PracHub interview preparation framework ↗
Is this an official General Motors Of Canada interview guide?

No. It is PracHub's own research and practice material for the Software Engineer role at General Motors Of Canada. Rounds and questions reflect what candidates have reported, not a process General Motors Of Canada has published, and they change over time. Confirm the current format and scope with your recruiter.

PracHub interview research ↗
How technical are the final round interviews for Software Engineers?

This depends heavily on the specific team. Some teams focus almost entirely on behavioral questions and past project discussions using the STAR format, while others include rigorous live coding, debugging exercises, and system design panels. Always clarify the format with your recruiter beforehand.

PracHub interview research ↗
What is the TRACK program at General Motors?

The TRACK program is General Motors Of Canada's rotational program for recent graduates and early-career engineers. It allows you to rotate through different departments (such as infotainment, active safety, and manufacturing) over two years, helping you find a long-term fit within the company's engineering organization.

PracHub interview research ↗
How heavily are GM's core values evaluated during the interview?

Very heavily. Interviewers are looking for candidates who demonstrate safety, integrity, inclusion, and a team-first mindset. Bringing up these values naturally during your behavioral responses is highly recommended.

PracHub interview research ↗
What is the typical timeline from application to offer?

The process generally takes between three to six weeks. However, candidates occasionally report longer timelines depending on the volume of applicants and internal scheduling constraints.

PracHub interview research ↗
Sources & methodology 3 sources ↗

Official role evidence, timestamped platform data and clearly labeled preparation advice.