HireHireInterview Quizzes › Salesforce Developer

Salesforce Developer Interview Questions

Think you're ready? These are the questions that actually decide Salesforce Developer interviews. Warm up on Easy — then face the Hard round, where 95% of candidates crumble. 30 questions across 3 levels, instant score, completely free.

30Questions
3Difficulty levels
95%Fail the hard round
FreeInstant score
Easy
Warm-up · 10 Qs
Medium
Practical · 10 Qs
Hard
Brutal · 10 Qs
⚡ Take the Salesforce Developer quiz — get your score →

The Salesforce Developer interview questions

Below are the real questions, grouped by difficulty. Expand any one to reveal the correct answer and why — or take the timed quiz for a score you can share. Can you clear the Hard round?

Easy round 10 questions

In Apex, what is the maximum number of records that a single SOQL query can return per transaction by default (governor limit for total records retrieved via SOQL)?
  • A. 10,000 records
  • B. 50,000 records ✓
  • C. 100 records
  • D. 500 records
Correct answer: B. The Apex governor limit caps the total number of records retrieved by SOQL queries in a single transaction at 50,000.
Which Apex trigger context should you use to prevent a record from being saved by adding a validation error with addError()?
  • A. after insert
  • B. before insert ✓
  • C. after update only
  • D. after delete
Correct answer: B. before insert/before update runs prior to the database commit, so addError() there stops the DML and prevents the record from saving.
What does the 'with sharing' keyword on an Apex class enforce?
  • A. Field-level security on all fields
  • B. The sharing rules of the current user ✓
  • C. Ownership of all records to the running user
  • D. Automatic record locking
Correct answer: B. 'with sharing' makes the class respect the organization-wide defaults and sharing rules that apply to the current running user.
A developer needs to make a callout to an external REST API from an Apex trigger. What is the correct approach?
  • A. Call the HTTP request synchronously inside the trigger
  • B. Use an @future(callout=true) method or Queueable to make the callout asynchronously ✓
  • C. Use a Batch Apex start method
  • D. Callouts from triggers are never possible in any way
Correct answer: B. Synchronous callouts are not allowed directly in triggers, so you must invoke them asynchronously via @future(callout=true) or a Queueable.
In a Lightning Web Component, which decorator is used to expose a public property that a parent component can set?
  • A. @track
  • B. @wire
  • C. @api ✓
  • D. @public
Correct answer: C. The @api decorator marks a property or method as public so it can be set or called by a parent component.
What is the primary purpose of a Junction Object in Salesforce?
  • A. To store formula fields only
  • B. To implement a many-to-many relationship between two objects ✓
  • C. To create a rollup summary on a lookup
  • D. To enforce field-level security
Correct answer: B. A junction object uses two master-detail relationships to model a many-to-many relationship between two objects.
Which SOQL feature lets you query child records related to a parent in a single query (parent-to-child relationship query)?
  • A. A subquery using the child relationship name in the SELECT clause ✓
  • B. The GROUP BY ROLLUP clause
  • C. A semi-join using IN
  • D. The FOR UPDATE clause
Correct answer: A. Parent-to-child queries use an inner subquery referencing the child relationship name, e.g. SELECT Name, (SELECT LastName FROM Contacts) FROM Account.
To avoid hitting governor limits, why should DML statements never be placed inside a for loop iterating over records?
  • A. DML inside loops causes syntax errors
  • B. Each loop iteration issues a separate DML statement, quickly exceeding the 150 DML statements per transaction limit ✓
  • C. Loops disable sharing rules
  • D. DML in loops always rolls back automatically
Correct answer: B. DML inside a loop issues one statement per iteration and can exceed the 150-DML-statements-per-transaction limit; bulkifying by collecting records and doing one DML avoids this.
What minimum Apex code coverage does Salesforce require to deploy Apex to a production org?
  • A. 50%
  • B. 75% ✓
  • C. 90%
  • D. 100%
Correct answer: B. Salesforce requires at least 75% overall Apex code coverage to deploy code to production.
Which interface must an Apex class implement to be run as a Batch Apex job?
  • A. Schedulable
  • B. Database.Batchable ✓
  • C. Queueable
  • D. Database.AllowsCallouts
Correct answer: B. Batch Apex classes must implement the Database.Batchable interface, which defines the start, execute, and finish methods.

Medium round 10 questions

You have a trigger on the Account object that needs to update related Contact records. To follow best practices and avoid hitting governor limits when 200 records are processed in a batch, how should you perform the DML on the Contacts?
  • A. Call an update statement inside the for loop that iterates over each Account
  • B. Collect the Contacts into a List and perform a single update DML statement after the loop ✓
  • C. Use a @future method for every Contact update individually
  • D. Perform a separate SOQL and update inside the loop for each Account
Correct answer: B. Bulkification requires collecting records into a collection and performing a single DML operation outside the loop to stay within governor limits.
A validation rule should fire only when a record is being created, not when it is edited. Which formula condition correctly restricts the rule to new records?
  • A. ISNEW() ✓
  • B. ISCHANGED(Id)
  • C. ISNULL(Id)
  • D. PRIORVALUE(Id) = null
Correct answer: A. The ISNEW() function returns true only when a record is being created, making it the correct way to limit a validation rule to inserts.
In Apex, you need to query Contacts and their parent Account's name in a single SOQL query. Which query correctly retrieves the Account name?
  • A. SELECT Id, Account.Name FROM Contact ✓
  • B. SELECT Id, (SELECT Name FROM Account) FROM Contact
  • C. SELECT Id, Account__r.Name FROM Contact
  • D. SELECT Id, Accounts.Name FROM Contact
Correct answer: A. For a child-to-parent relationship on a standard lookup, you traverse using dot notation with the relationship name (Account.Name).
Which statement about the difference between a Workflow Rule and Process Builder / Flow is most accurate for a developer choosing an automation tool today?
  • A. Workflow Rules can create related records, but Flows cannot
  • B. Flows can perform more complex logic like creating/updating unrelated records and calling Apex, which Workflow Rules cannot ✓
  • C. Workflow Rules run after Flows in the order of execution and can override them
  • D. Flows cannot send email alerts, so Workflow Rules are required for email
Correct answer: B. Flows are far more capable, able to create/update any records and invoke Apex, whereas Workflow Rules are limited to field updates, email alerts, tasks, and outbound messages.
You wrote a test method and need to verify that an exception is thrown when invalid data is inserted. What is the recommended pattern to assert that behavior?
  • A. Insert the record inside System.runAs() and check debug logs
  • B. Wrap the DML in a try-catch, and if no exception is caught call System.assert(false) to fail the test ✓
  • C. Use Test.isRunningTest() to skip the insert
  • D. Set the record to null and check that it equals null
Correct answer: B. The standard pattern is a try-catch where the catch verifies the expected exception, and reaching the line after the DML (via System.assert(false)) fails the test because no exception occurred.
A Lightning Web Component needs to call an Apex method and get data when the component loads, with the result automatically refreshed if the underlying data changes. Which approach is most appropriate?
  • A. Call the Apex method imperatively inside the constructor
  • B. Use the @wire decorator on the Apex method ✓
  • C. Use setInterval to poll the Apex method every second
  • D. Use a Visualforce remoting call
Correct answer: B. The @wire decorator reactively provisions data from an Apex method and integrates with Lightning Data Service caching, refreshing when tracked reactive values change.
In the Salesforce order of execution, when do 'before' triggers run relative to validation rules on a standard save?
  • A. Before triggers run after all validation rules complete
  • B. Before triggers run before system validation but the record's own validation rules run after before triggers ✓
  • C. Before triggers never run when validation rules exist
  • D. Validation rules and before triggers run simultaneously in random order
Correct answer: B. In the order of execution, before triggers execute, and then the record's custom validation rules run after them (after system validations for required fields).
You need to grant a group of users edit access to certain Opportunity records they do not own, based on a criteria like Region. Which sharing mechanism is the standard declarative tool for this?
  • A. Profiles
  • B. Permission Sets
  • C. Criteria-based sharing rules ✓
  • D. Field-level security
Correct answer: C. Sharing rules (owner- or criteria-based) open up record-level access beyond the org-wide default, which profiles and permission sets do not control.
A SOQL query in Apex might return zero rows. Which of the following will throw an exception if no rows are returned?
  • A. List<Account> accs = [SELECT Id FROM Account WHERE Name = 'X'];
  • B. Account acc = [SELECT Id FROM Account WHERE Name = 'X']; ✓
  • C. Integer c = [SELECT COUNT() FROM Account WHERE Name = 'X'];
  • D. for (Account a : [SELECT Id FROM Account WHERE Name = 'X']) {}
Correct answer: B. Assigning a SOQL query directly to a single sObject throws a QueryException (List has no rows) when zero rows are returned; assigning to a List safely returns an empty list.
Which governor limit is most directly relevant when you accidentally place a SOQL query inside a for loop iterating over 200 records?
  • A. The 100 SOQL queries per synchronous transaction limit ✓
  • B. The 10,000 DML rows per transaction limit
  • C. The 6 MB heap size limit
  • D. The 50,000 records returned by SOQL limit
Correct answer: A. A query inside a loop over many records quickly exceeds the 100 SOQL queries per synchronous transaction limit, which is the classic reason to move queries outside loops.

Hard round 10 questions

You must update 10,000 User records (setup) and 10,000 related Account records (non-setup) in response to a single button click, and both updates are genuinely required together. Doing both DMLs in one synchronous transaction throws a MixedDML exception. Which approach correctly resolves this while keeping both updates?
  • A. Wrap the User DML in Database.update with allOrNone=false so partial success suppresses the MixedDML error
  • B. Perform the Account DML synchronously and move the User DML into a @future method (or Queueable) so it runs in a separate transaction ✓
  • C. Add 'without sharing' to the class so setup and non-setup objects share the same DML context
  • D. Reorder the statements so the setup-object DML always executes before the non-setup DML in the same transaction
Correct answer: B. MixedDML is resolved by separating setup and non-setup DML into different transactions, typically by deferring one to an async @future or Queueable method.
Consider this Batch class: ``` global class Recalc implements Database.Batchable<sObject>, Database.Stateful { global Integer total = 0; global void execute(Database.BatchableContext bc, List<Account> scope){ total += scope.size(); // ... work ... } } ``` A batch of 1,000,000 records runs with scope size 200. Midway, execute() throws an unhandled exception in one chunk. What happens?
  • A. The entire batch rolls back and total resets to 0 across all chunks
  • B. Only the failing chunk's DML is rolled back; other chunks already committed remain committed, and total retains its accumulated value from successful chunks ✓
  • C. The batch pauses and can be resumed from the exact failed record via Database.resume()
  • D. All subsequent chunks are skipped and the batch is marked Completed with partial data
Correct answer: B. Each Batch execute() chunk is its own transaction, so a failure rolls back only that chunk while committed chunks persist and Database.Stateful preserves accumulated instance state.
In the Salesforce Order of Execution, a before-insert trigger sets Field_A, a Validation Rule references Field_A, a Flow (record-triggered, after-save) updates Field_B, and a Workflow field update sets Field_C. Which sequence is correct for a single record insert?
  • A. Validation Rule -> before trigger -> after trigger -> Workflow -> Flow
  • B. before trigger -> Validation Rules -> after trigger -> after-save Flow -> Workflow field update -> (re-fire triggers if workflow updated a field) ✓
  • C. Flow -> before trigger -> Validation Rule -> Workflow -> after trigger
  • D. before trigger -> after trigger -> Validation Rule -> Workflow -> Flow (Flow always runs last, after commit)
Correct answer: B. Before triggers run first, then system+custom validation, then after triggers, then after-save flows, then workflow rules whose field updates can re-fire before/after triggers a second time.
A recursion-prevention pattern uses a static Boolean flag set to true on first trigger entry and never reset. Within a single transaction, a legitimate later update to those same records needs the trigger logic to run again. What is the risk of this exact static-flag design?
  • A. Static flags reset between batch execute() chunks, so recursion is never actually prevented at scale
  • B. A never-reset static flag can over-suppress legitimate re-entry, silently skipping trigger logic for records that genuinely need reprocessing within the same transaction ✓
  • C. Static variables are shared across concurrent user sessions, causing one user's flag to block another's trigger
  • D. The trigger depth limit of 16 makes static flags redundant, so the flag has no effect at all
Correct answer: B. A static flag that is set once and never reset blocks all subsequent legitimate re-entry in the same transaction, over-suppressing valid reprocessing rather than just breaking the recursive loop.
You have a SOQL query `SELECT Id FROM Contact WHERE Custom_Status__c = 'Active'` running against 8 million Contacts. It throws a non-selective query error in a trigger. Custom_Status__c has only two possible values ('Active'/'Inactive') split roughly 50/50. Which action will make this query selective?
  • A. Add a custom index on Custom_Status__c; the index makes any filtered field selective regardless of value distribution
  • B. Nothing on that field alone will help because the low-cardinality filter matches ~4M rows, exceeding the selectivity threshold; add a selective, indexed, high-cardinality filter (e.g., a bounded date/Id range) ✓
  • C. Wrap the query with WITH SECURITY_ENFORCED, which forces the optimizer to use a selective path
  • D. Convert it to a skinny table query, which removes all selectivity thresholds
Correct answer: B. A filter matching ~50% of 8M rows can never be selective even if indexed, because it exceeds the optimizer's row thresholds; you need an additional high-cardinality selective filter.
An LWC uses `@wire(getContacts, { accountId: '$recordId' }) contacts;` against a `cacheable=true` Apex method. A separate LWC in the same app inserts a new Contact via imperative Apex. The wired list does not show the new Contact even after the insert succeeds. What is the correct fix?
  • A. Set cacheable=false on getContacts so the wire always hits the server
  • B. Call refreshApex(this.contacts) after the insert completes, passing the wired provisioned value to invalidate the client cache and re-fetch ✓
  • C. Reassign this.recordId to itself to force the '$recordId' reactive parameter to re-trigger
  • D. Move the query into connectedCallback with an imperative call, since @wire cannot display server data
Correct answer: B. refreshApex on the stored wired reference invalidates the Lightning Data Service cache for that cacheable method and re-provisions fresh data, unlike changing an unrelated reactive variable.
You must call an external REST API from a trigger's after-insert context to enrich 200 newly created Leads, and the API allows only one record per request. You also need to respect the external API's rate limits with sequential ordering. Which async design is BEST?
  • A. Use a single @future(callout=true) method that loops 200 times issuing callouts, since @future runs asynchronously
  • B. Use a Queueable that processes a bounded batch of records and chains to the next Queueable (System.enqueueJob in execute) to enforce sequential ordering and stay within callout limits per transaction ✓
  • C. Call the API directly in the after-insert trigger; triggers permit callouts as long as they are wrapped in a try/catch
  • D. Use a Scheduled Apex job firing every minute to poll for new Leads and process them in bulk
Correct answer: B. Queueable chaining gives sequential ordering, per-transaction callout budgets, and controlled throughput, whereas @future can't chain and is limited to callouts with no ordering guarantee.
A class declared `public with sharing` calls a helper method in a second class declared `public without sharing`. The helper runs a SOQL query returning records the running user cannot see via sharing rules. What data does the query return?
  • A. Records are filtered by the calling class's 'with sharing', because sharing is inherited down the call stack
  • B. The query in the 'without sharing' helper runs in system mode for sharing and returns all matching records regardless of the user's sharing access ✓
  • C. A runtime exception is thrown because mixing with/without sharing in one call stack is disallowed
  • D. Sharing is enforced only if the helper is 'inherited sharing'; 'without sharing' always throws an FLS error
Correct answer: B. Sharing enforcement is determined by the sharing keyword of the class where the SOQL executes, so a 'without sharing' helper ignores the caller's 'with sharing' and returns all rows.
Which Apex test correctly verifies a callout without making a real HTTP request AND asserts bulk behavior?
  • A. Use Test.setMock(HttpCalloutMock.class, new MyMock()) before Test.startTest(), insert 200 records to trigger the callout logic, then assert results after Test.stopTest() ✓
  • B. Use SeeAllData=true so the test hits the real endpoint with production credentials for realism
  • C. Wrap the callout in Test.startTest()/stopTest() only; the platform auto-mocks any HTTP callout inside that block
  • D. Insert one record and assert a 200 status code, since bulk paths behave identically to single-record paths
Correct answer: A. HttpCalloutMock registered via Test.setMock stubs the HTTP response, and inserting 200 records inside start/stopTest exercises the bulk/async path and forces async completion before assertions.
A Platform Event subscriber (Apex trigger on the event) processes high-volume events. During a spike, some events appear to be processed twice. Which statement about the delivery semantics is correct here?
  • A. Platform Events guarantee exactly-once delivery, so duplicate processing indicates a code bug unrelated to the platform
  • B. Platform Event subscribers get at-least-once delivery and can be re-delivered (e.g., after an unhandled exception or EventBus.RetryableException), so subscribers must be idempotent ✓
  • C. Events are delivered in strict transactional lock-step with the publisher's commit, so a failed subscriber rolls back the publisher
  • D. Replay IDs guarantee no event is ever delivered more than once as long as you store the last replay ID
Correct answer: B. Platform Event delivery is at-least-once with possible retries/redelivery, so subscribers must be written idempotently to tolerate duplicate processing.

Prep for another role

Questions are original, written and independently verified for HireHire's role interview quizzes. They reflect the kind of knowledge Salesforce Developer interviews test, not any specific company's questions. HireHire maps live tech & IT jobs across India, updated regularly. Last updated: July 2026.