Interview Questions

What Salesforce Interviewers Actually Test (and Why the Obvious Answers Aren’t Enough)

By Shekhar June 3, 2026
What Salesforce Interviewers Actually Test (and Why the Obvious Answers Aren’t Enough)

Salesforce developer interview questions have a deceptive quality. The surface questions look easy. “Explain governor limits.” “What’s the difference between List, Set, and Map?” Any Trailhead-certified candidate can recite those answers. The real screen is what comes after the first answer, when the interviewer asks: “And why does the platform enforce it that way?”

The platform’s multitenant architecture drives everything. Apex runs in a shared environment, so the runtime enforces per-transaction limits to prevent one org’s code from consuming resources that belong to other tenants. Understanding that one sentence reframes how you answer almost every governor-limits question.

Below are 31 questions – split across Apex, Lightning Web Components, SOQL, triggers, and integrations – with answers that explain the “why,” not just the “what.” I’ve also flagged 7 of them as the ones that tend to actually decide the outcome of the interview.

One data point worth having before you start: the BLS projects software developer employment to grow 15% from 2024 to 2034 – roughly five times faster than the average occupation. Bureau of Labor Statistics, Occupational Outlook Handbook. That growth doesn’t remove competition for Salesforce roles; it sharpens it, because more people are qualifying to apply.

Apex Programming (Questions 1-11)

Apex is not Java. That’s the most useful framing I can offer. It looks like Java, it feels like Java in many places, but the execution model is completely different – and interviewers are checking whether you know the difference or whether you’re just mapping from a prior language.

Core concepts

1. What’s the difference between List, Set, and Map in Apex?

List is ordered and allows duplicates. Set holds unique values only. Map is key-value pairs, typically used for fast lookups by Id or by a field value when you’re processing collections inside a trigger handler. The “which one do you reach for first” answer is Map, 90% of the time, because you’re almost always querying records and then matching them to Trigger.new by Id.

2. How does == behave differently for objects vs. primitives?

For primitives, == compares values. For objects, it compares references – so two separate String instances with identical content can return false with ==. Use .equals() for string comparisons in Apex to avoid that trap.

3. What are governor limits and why do they exist? [High-signal question]

The Salesforce platform is multitenant – your org’s code runs on the same infrastructure as thousands of other orgs. Governor limits are the runtime constraints that prevent any one transaction from monopolizing shared compute and database resources. Per the Apex Developer Guide, synchronous transactions are capped at 100 SOQL queries, 150 DML statements, and a 10,000ms CPU timeout. Async contexts (Batch, Queueable) get more headroom – 200 SOQL queries, 60,000ms CPU – but the principle is the same. Candidates who answer “they exist to prevent runaway code” are telling the interviewer they read a blog post. The better answer explains multitenancy.

4. How do you handle exceptions in Apex?

try-catch-finally blocks. The built-in types you’re expected to know: DmlException, QueryException, NullPointerException, LimitException. LimitException is the one that bites you – it can’t be caught. Once you hit a governor limit, the transaction fails and the exception is unhandleable. That’s the architectural reason to bulkify code upfront rather than try to catch your way out.

5. Static methods vs. instance methods.

Static belongs to the class, no instantiation required, one copy in memory per transaction. Instance methods operate on a specific object and can access instance variables. Trigger handlers are usually static because you’re calling utility methods without needing to carry object state across calls.

Advanced Apex

6. Apex sharing – with sharing, without sharing, inherited sharing. [High-signal question]

“with sharing” enforces the running user’s record visibility. “without sharing” ignores it – the code sees everything. “inherited sharing” uses the calling context’s sharing setting, which is useful when you have an inner service class called from both a controller (user context) and a batch job (system context) and you want consistent behavior in each. The runAs() method in tests lets you verify behavior under a specific user’s permissions without deploying to production.

7. Future methods – what are they and when do you use them?

Annotate a static void method with @future and it runs asynchronously in a separate transaction. Primary use cases: HTTP callouts (can’t happen in the same transaction as DML that hasn’t committed yet), mixed DML (you can’t do DML on a setup object and a non-setup object in the same transaction), and offloading work to avoid hitting CPU limits in a trigger. The downside is you can’t chain them or monitor them easily – for anything more complex, Queueable is the better choice.

8. Batch Apex. [High-signal question]

Implement Database.Batchable with three methods: start() returns the record set (usually a QueryLocator), execute() runs on each chunk of up to 2,000 records, finish() runs once at the end. Each execute() call is a fresh transaction with its own governor limits. That’s the whole point – you can process millions of records because you’re chunking them into governor-limit-safe batches. Default chunk size is 200. Interviewers often follow up with “can you chain batches?” – yes, call Database.executeBatch() inside finish().

9. Database.insert() vs. insert DML statement.

The DML statement (insert myList) fails the whole transaction if any record errors. Database.insert(myList, false) – allOrNone set to false – allows partial success and returns a SaveResult array so you can inspect which records failed and why. Use the method when you’re processing batches with mixed-quality data and you want to log failures rather than roll back everything.

10. Queueable vs. future methods.

Queueable is the upgrade. You can chain jobs (call System.enqueueJob() from within a Queueable execute()), pass complex types (not just primitives), and monitor job status via AsyncApexJob. Use future for simple fire-and-forget callouts, Queueable for anything that needs sequencing or richer state.

11. What’s a Schedulable class and what are the limits?

Implement Schedulable, define execute(SchedulableContext), schedule it with System.schedule() or through Setup. You can have 100 scheduled Apex jobs active at once. Common pattern: the scheduled class just calls Database.executeBatch() so the heavy work runs in Batch Apex, not in the scheduler itself.

Lightning Web Components (Questions 12-16)

LWC replaced Aura as the preferred component framework around 2019, and most new development is LWC. That said, plenty of orgs still run Aura components – interviewers will test whether you know both or only LWC. Saying “Aura is legacy” without being able to explain the difference in rendering model is a red flag.

12. LWC lifecycle hooks – what fires and in what order?

constructor() fires first, before the element is added to the DOM. connectedCallback() fires when the component is inserted into the DOM – this is where you initiate data loading. renderedCallback() fires after every render, including re-renders, so be careful putting fetch logic here or you’ll call Apex on every property change. disconnectedCallback() fires on removal. errorCallback() catches errors thrown by child components. Most candidates know the first three; errorCallback() distinguishes people who’ve actually handled production errors.

13. Parent-to-child and child-to-parent communication.

Parent passes data down via @api properties on the child. Child sends data up via custom events – new CustomEvent(‘myevent’, { detail: data }) dispatched with this.dispatchEvent(). The parent listens with onmyevent. This is the standard web events model, which is intentional – LWC follows web standards much more closely than Aura did.

14. @track, @api, and @wire – current state. [High-signal question]

@api exposes a property as publicly settable by the parent. @wire connects to a Salesforce data source or Apex method reactively – when the parameters change, the wire adapter refetches. @track is the one that trips people up: in the original LWC release, you needed @track for reactive object/array mutations. Since Spring ’20, all class properties are reactive by default for primitive changes, so @track is only needed when you mutate a property that’s an object or array without reassigning the reference. Most modern code you’ll see doesn’t use @track at all, and interviewers notice if you don’t know that.

15. Calling Apex from LWC – wire vs. imperative.

Wire: reactive, automatic, good for data that should refresh when parameters change. Imperative: you call the imported function in connectedCallback or an event handler, handle the promise, good for mutations or conditional fetching. Both require @AuraEnabled on the Apex method, and cacheable=true on read-only methods allows the client-side cache to serve repeat calls without going to the server.

16. What’s the difference between LWC and Aura components?

LWC uses native Web Components standards – shadow DOM, ES modules, the browser’s own custom elements API. Aura has its own proprietary rendering and event model. LWC is faster, smaller bundle size, better tooling support. Aura is still needed for certain Salesforce-specific contexts (some AppExchange packaging scenarios, components that host Aura children), but new development should default to LWC unless you hit a specific platform constraint.

SOQL and SOSL (Questions 17-21)

SOQL optimization questions are where Salesforce interviews get genuinely hard. The syntax is simple; query performance is not. Interviewers will often give you a slow query and ask you to improve it, and they’re watching whether you think about indexes.

17. SOQL vs. SOSL – when do you use each?

SOQL queries a known object or relationship. SOSL is a text search across multiple objects and fields simultaneously – think of it as a full-text search that returns multiple sObject types in one call. Use SOQL when you know what you’re looking for and where. Use SOSL when you’re implementing a search bar that should return Contacts, Leads, and Accounts all at once.

18. How do you optimize SOQL for performance? [High-signal question]

Filter on indexed fields – Id, Name, CreatedDate, LastModifiedDate, and any external ID or custom indexed field. Avoid non-selective filters (WHERE IsActive = true on a table with 95% active records returns too many rows and won’t use an index). Avoid wildcard LIKE clauses at the start of a string. Use LIMIT. For large datasets, use SOQL for loops (for (sObject s : [SELECT…]) { … }) instead of putting all results in a List to avoid heap limits. Query fields you actually need – SELECT * doesn’t exist but wide SELECT clauses increase heap usage.

19. Parent-to-child and child-to-parent relationship queries.

Child-to-parent: SELECT Name, Account.Name FROM Contact – dot notation traversing up the relationship. Parent-to-child: SELECT Name, (SELECT LastName FROM Contacts) FROM Account – subquery using the plural relationship name. You can go up five levels in a parent-to-child subquery; there are tighter limits on nested subqueries. Interviewers test whether you know the relationship name convention (Contacts plural for the child set, Account.Name singular for the parent field).

20. Dynamic SOQL and injection prevention.

Database.query(queryString) runs a SOQL string assembled at runtime. The injection risk is user-supplied input concatenated into the string. Two defenses: use bind variables where possible (Database.query(‘SELECT Id FROM Account WHERE Name = :accountName’) – the colon binds a local variable, preventing injection), and escape user input with String.escapeSingleQuotes() when bind variables aren’t an option.

21. What is a SOQL aggregate query and when does it break?

SELECT COUNT(Id), SUM(Amount), AccountId FROM Opportunity GROUP BY AccountId. The result is a List of AggregateResult, not a typed sObject List. This trips up developers who try to cast the result. The common failure: aggregate queries that return more than 2,000 rows in a non-Batch context hit a governor limit. If you’re aggregating across millions of records, run it in Batch Apex.

Triggers and Automation (Questions 22-26)

Trigger questions separate people who’ve worked on production orgs from people who’ve only worked on sandboxes. Production orgs have years of accumulated automation – triggers, flows, workflow rules, process builders – that all interact, and the order-of-execution question is usually how interviewers probe for that experience.

22. Trigger contexts – what fires before vs. after?

Before triggers fire before the record is saved to the database – use them for validation and field manipulation (no DML needed, you’re modifying Trigger.new directly). After triggers fire after the record is committed – use them when you need the record Id (which isn’t available before insert) or when you’re updating related records. The contexts: before/after insert, before/after update, before/after delete, after undelete.

23. Bulkification. Why does it matter and what does it look like? [High-signal question]

When Salesforce runs a data load or an import, triggers fire in batches of up to 200 records at a time. A trigger that does a SOQL query or DML inside a for loop will hit governor limits immediately at any scale. Bulkified code collects all the Ids from Trigger.new into a Set, runs one query to fetch related data into a Map, then iterates through Trigger.new using the Map for lookups. One query, one DML statement, handles 200 records. A non-bulkified version would run 200 queries and fail at limit 101.

24. Order of execution for automation tools.

The simplified order: System validation, before-save flows (record-triggered), before triggers, Salesforce internal validations, custom validation rules, duplicate rules, after-save flows (record-triggered), after triggers, assignment rules, auto-response rules, workflow field updates (which can re-trigger validation and triggers – this is where recursion happens). Process Builder is deprecated as of Spring ’23 but still runs in existing orgs. New automation should use Flow or Apex.

25. Preventing recursive trigger execution.

A trigger updates a related record, which fires another trigger, which updates back – infinite loop. The standard pattern: a static Boolean in a handler class, set to true on first execution and checked at the start of each execution. Because static variables persist for the duration of a transaction, the second execution sees the flag and exits. Be careful with workflow field updates though – they re-fire triggers with a fresh execution context in some scenarios, so the static flag doesn’t always protect you.

26. Flow vs. Apex triggers – how do you choose?

If the logic is declarative and doesn’t need complex data structures, use Flow – it’s easier for admins to maintain and doesn’t require code reviews. If you need collections processing at bulk scale, complex conditional logic across multiple objects, HTTP callouts, or behavior that Flow genuinely can’t express, use Apex. The platform’s recommendation since Spring ’23 is Flow-first. One practical note: record-triggered flows run before after-save triggers in the execution order, which creates interaction risks in complex orgs with both.

Integration Patterns (Questions 27-31)

Integration questions come up most heavily in senior and architect-level interviews. For junior roles, knowing REST vs. SOAP and callout basics is usually enough. For senior roles, they want to hear about Platform Events, the Enterprise Messaging Platform, and how you’d design a fault-tolerant outbound callout at scale.

27. REST vs. SOAP APIs in Salesforce context.

Salesforce exposes both. REST is JSON-based, stateless, simpler for most integrations – the Salesforce REST API uses standard HTTP verbs against /services/data/v{version}/sobjects/. SOAP is XML with a WSDL-defined contract, more appropriate for legacy enterprise systems that already speak SOAP or when you need transactional guarantees. For new integrations in 2026, the default is REST unless you have a specific reason to use SOAP.

28. Callout limits and how to work around them.

100 callouts per transaction, 120 seconds total callout time. Callouts can’t happen in the same synchronous transaction as DML (the database commit and the HTTP request would be in an ambiguous state if either fails). The solution: use @future(callout=true) or Queueable with AllowsCallouts to move the callout to an async context after the DML commits. For high-volume scenarios, Platform Events or outbound messaging decouple the calling code from the HTTP execution entirely.

29. Authentication methods for Salesforce APIs.

OAuth 2.0 with the appropriate flow for the context: Web Server flow for server-to-server with user consent, JWT Bearer Token flow for server-to-server without user interaction (the standard for integrations), Device flow for devices without browsers. Username-password OAuth flow works but is deprecated in newer API versions because it doesn’t support MFA. Named Credentials in Salesforce Setup store the credentials so they don’t live in Apex code.

30. Platform Events for real-time integration.

Platform Events are Salesforce’s publish-subscribe messaging model. You define an Event object, publish with EventBus.publish(), and subscribe with a trigger, a flow, or an external system using CometD. The key architectural benefit: decoupling. The publisher doesn’t need to know about or wait for the subscriber. Events are durable and replayable. For high-volume scenarios they’re substantially more reliable than callout chains. One constraint: Platform Event triggers don’t run in the same transaction as the publishing code.

31. Security considerations when exposing Salesforce data via APIs. [High-signal question]

Field-level security doesn’t automatically apply to Apex REST endpoints – you have to explicitly check it with Schema.SObjectField.getDescribe().isAccessible() or use WITH SECURITY_ENFORCED in your SOQL queries. Sharing rules apply based on the running user’s context, so make sure your REST class declares “with sharing.” IP whitelisting at the Connected App level reduces the attack surface. Audit trails (via EventMonitoring) log API activity. API versioning matters for clients that can’t update immediately when you change the response schema.

What we see in live Salesforce interviews

At LastRound AI, our copilot runs alongside live interviews. Across the Salesforce developer sessions we’ve supported, the questions that most often determine the outcome are #3 (governor limits – specifically the “why multitenancy” follow-up), #8 (Batch Apex chunking), #14 (@track deprecation in Spring ’20), and #23 (bulkification with a live code example). These four come up regardless of the level or company. The integration and security questions (#28-31) are consistently stronger differentiators at senior level.

Candidates who stumble on those four tend to be people who’ve used Salesforce but haven’t had to debug a governor-limit failure in production or clean up someone else’s non-bulkified trigger. That experience gap is hard to fake.

One opinion worth having going in

I think the Salesforce Certified Platform Developer I is underrated as interview prep. Most candidates use it as a resume checkbox. But the exam guide actually maps almost exactly to what senior interviewers test – governor limits, SOQL, Apex patterns, testing best practices. The official Trailhead certification page has the exam outline. The “Apex Testing” domain alone is worth studying even if you’re not pursuing the cert, because code coverage and test isolation questions show up in almost every technical screen at a serious Salesforce shop.

One thing I’d push back on: the common advice to “know the order of execution cold.” My experience watching actual interviews is that almost nobody asks you to recite it verbatim. They ask you to describe a specific scenario – “a trigger updates a record and something unexpected happens downstream” – and work through the reasoning with you. The candidates who’ve actually dealt with that scenario in production handle those questions well. The candidates who memorized a list struggle.

The platform is genuinely deep. If you’d asked me in 2022, I’d have said 3 months of hands-on work plus the PD1 cert puts you in solid shape for developer interviews. The bar has moved since then. Orgs are now asking about DevOps Center, Salesforce Functions (where it’s available), and headless Salesforce patterns. You don’t need to be an expert in all of it. But knowing it exists – and being honest about what you’ve actually shipped vs. what you’ve read about – goes a long way.

Shekhar

Written by

Shekhar

LastRound AI.

View Shekhar's LinkedIn profile →

Leave a Reply

Your email address will not be published. Required fields are marked *