Salesforce Software Engineer Interview Experience — Five Onsite Rounds, Every One Circles Back to Multi-Tenancy

Salesforce·Software Engineer·Apr 2026
Onsitemedium

Sharing my interview experience with Salesforce. My impression of this company is very different from consumer-product companies: the problems themselves aren't going for difficulty, but almost every round eventually circles back to "what if this system is shared by a lot of customers." Multi-tenancy, permissions, and configurability ran through the whole interview. There was also a whole round dedicated to values, and it counted for a lot.

The problem names were given to me in coded/homophone form (a common trick people use around here to dodge keyword filters), so I'll just describe each problem instead of typing out the coded name.

Round 1

The interviewer was patient, didn't talk fast.

The problem: find the lowest common ancestor, but each node carries a pointer to its parent, and you don't have access to the root.

Because of the parent pointers, this turns into finding the intersection point of two linked lists. I gave three solutions:

  1. Use a set. Walk up from p to the top, putting every node on the path into a set; then walk up from q, and the first node that's already in the set is the answer. Time O(h), space O(h).
  2. Compute depth. Walk both nodes up to the root, recording depth; the deeper one walks the difference in steps first, then both walk together — they meet at the answer. Time O(h), space O(1).
  3. Alternate two pointers. When p reaches the end, jump it to the start of q; when q reaches the end, jump it to the start of p. Both pointers travel the same total distance, so they're guaranteed to meet at the intersection. O(1) space, shortest code.

The interviewer had me write the third one, then asked: "What happens if the two nodes aren't even in the same tree?" The answer is both pointers become null at the same time, the loop ends, and it returns null — which is correct. I worked this out live, and after I finished he said, "Good, a lot of people get stuck in an infinite loop here."

Follow-up: what if instead of a binary tree, each node can have multiple parents — i.e. a DAG? Then it's not as simple as "lowest common ancestor" anymore — there could be multiple candidates, so you'd need to compute the full ancestor sets, intersect them, and filter by depth, and the complexity goes up too.

Round 2

The problem: decide whether an abbreviation is a valid abbreviation of a word. For example, "i18n" is a valid abbreviation of "internationalization", but "s10n" is not a valid abbreviation of "substitution".

The rule: a number in the abbreviation means skip that many characters; letters have to match one by one.

Two pointers scanning through: when you hit a digit, accumulate the full number and skip that many characters; when you hit a letter, compare it directly. A few traps to watch for while writing it:

  1. Leading zeros are invalid. "a01" should return false, because a number starting with 0 isn't valid.
  2. After skipping, you might go out of bounds — need to check for that.
  3. At the end, both pointers have to reach the end at the same time; only one of them getting there doesn't count as a match.

I listed these three traps before writing any code, and the interviewer said that was good, it saves back-and-forth fixes later.

The follow-up flipped it around: given a word, generate all valid abbreviations of it. I said this is a subset problem — each character either stays as-is or gets compressed, enumerate with backtracking, and remember that adjacent compressed characters need to be merged into a single number. I wrote out a skeleton for it.

Round 3

The problem: the kth smallest element in a binary search tree.

In-order traversal, return at the kth element. I wrote the iterative version, since it lets you exit early instead of walking the whole tree.

The real weight of the round was in the follow-ups, and they were very on-brand for this company:

"If this tree gets modified frequently, and kth-smallest gets queried frequently, how would you optimize it?" — maintain, at each node, the count of nodes in its left subtree; then a query can walk down like a binary search, O(h). The cost is that inserts and deletes have to update the counts along the path.

"What if this were a table in a database instead of a tree in memory?" — that's an indexing problem then; a B+ tree's nodes can maintain a similar count to support locating by rank.

"What if different customers see different data?" — the moment he said this I knew we were headed toward multi-tenancy. I said you either give each tenant its own independent tree (good isolation, wastes resources) or share the structure but tag every node with a tenant marker and filter at query time (saves resources but makes queries more complex — and the semantics of "kth smallest" now have to be computed over the filtered results, which breaks the counts you were maintaining before). The interviewer reacted well to me flagging on my own that the counts would become invalid.

By this round I basically had their pattern figured out: any problem can be steered toward multi-tenancy.

Round 4: System Design

The problem: design an internal enterprise messaging/collaboration system — something like channels plus DMs.

I worked through it in this order:

Requirements clarification. How many organizations, how many people per organization, 1:1 and group chat, does the message need to persist, do we need read receipts, do we need history search, does presence need to be precise. The interviewer specifically stressed one point: data between different organizations must be completely isolated.

Core flow. Clients connect to a gateway over a long-lived connection, messages go to a backend service, get written to storage, and get delivered to whoever's online; offline recipients get a push notification.

Data model. A conversation table, a message table, a member table. The message table is partitioned by conversation ID, and within a conversation, IDs are monotonically increasing by time, so pulling history is just a range scan.

Things that got dug into deeply:

  1. How to do multi-tenant isolation. I listed three options: a fully separate database (strongest isolation, highest cost, fits large customers), a shared database with separate schemas, and a shared table with a tenant column (cheapest, but every single query must filter by tenant — miss one and it's a data leak). I said in practice it's usually a mix — large customers get dedicated deployments, small and mid-size customers share. He pushed on "how do you guarantee the shared-table approach never misses the filter" — I said you can't rely on people remembering to do it; the tenant condition has to be forcibly injected at the data-access layer, with no way for the application layer to bypass it.
  2. Message ordering. Messages within the same conversation need a deterministic order. I said the server assigns a monotonically increasing sequence number within the conversation, not relying on client-side timestamps. The client shows an optimistic local update first, then replaces it once the server confirms.
  3. Write amplification from read receipts. A channel with a few hundred people — every person reading a message generates a write, and that's a lot of volume. I said you don't need to record "who read which message"; you only need to record "what sequence number has this person read up to, in this conversation" — one record per person per conversation, just update it.
  4. History search. You need an inverted index, but the index also has to be partitioned by tenant, and a search request has to be filtered by tenant plus the list of conversations that user has permission to see.
  5. Permissions. In an enterprise setting, channels can be public, private, or invite-only, and there are admin roles. I said permission checks have to happen server-side, not just hidden in the frontend.

This round went deep — I filled up three sections of whiteboard.

Round 5

This round was about values and collaboration, no coding.

The questions were roughly: tell me about a time you helped a coworker solve a problem; tell me about a time you took on extra responsibility on a project on your own initiative; how do you deal with a coworker whose style is very different from yours; has there been a time you gave up a short-term win for something you thought was right long-term; what does your ideal team culture look like.

None of the questions were hard, but it was clearly about checking whether you're "easy to work with." In the examples I gave, I deliberately talked more about other people's contributions rather than making it all about how capable I am — that felt like the right instinct.

At the end he asked if I had any questions, and I asked how they balance customer customization requests against platform generality — that's the classic tension for this kind of company. He talked about it for a while, and the mood was good.

That's it, wrapping up here. Wishing everyone a smooth landing.

Published

Curated and edited by PracHub

Practice the questions from this interview

Discussion

Sign in to join the discussion. The author is notified of every comment.

Loading comments…

Interview at a glance

Company
Salesforce
Role
Software Engineer
Rounds
Onsite
Difficulty
medium
Interview date
Apr 2026
Questions from this interview
10 questions

Real Salesforce interview experiences

First-hand reports from Salesforce candidates — the rounds, the questions they were asked, and how it went.

All 19 Salesforce interview experiences