0% found this document useful (0 votes)
4 views25 pages

SF Interview Guide

Uploaded by

heisnbergmorty
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views25 pages

SF Interview Guide

Uploaded by

heisnbergmorty
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Salesforce Senior Developer

Interview Preparation Guide


4.5 Years Experience | Comprehensive Q&A

1. Salesforce Security Model


Q: Explain the entire Salesforce security model.
Salesforce uses a layered security model with 4 levels:
• Organisation Level: Org-wide settings, trusted IPs, login hours, password policies, session settings.
• Object Level (OLS): Controlled via Profile and Permission Sets — CRUD access on objects.
• Field Level Security (FLS): Controls visibility and editability of individual fields via Profile/Permission Sets.
• Record Level: Determined by OWD → Role Hierarchy → Sharing Rules → Manual Sharing → Apex
Sharing.
Record level is always additive — you can only open access, never restrict below OWD once open (except
via restriction rules in newer releases).

Q: What is OWD (Organisation-Wide Default)?


OWD sets the baseline record access for all users. Options: Private, Public Read Only, Public Read/Write,
Controlled by Parent (for detail objects in MD). For external users: Private, Public Read Only. Default access
for a new custom object is Private if not configured.

Q: What is Role Hierarchy?


Roles define a tree structure. Users higher in the hierarchy automatically gain read/edit access to records
owned by users below them — if 'Grant Access Using Hierarchies' is enabled on the object. Roles do NOT
restrict access; they only open it upward. Note: Roles are not mandatory for every user.

Q: What are Sharing Rules?


Sharing Rules automatically extend record access beyond OWD to specific groups/roles/users. Two types: (1)
Criteria-based — shares records matching field criteria; (2) Owner-based — shares records owned by a
role/group. Access levels available: Read Only or Read/Write.

Q: 2 users, same profile and role, but one sees 100 records and another sees 10. Why?
Possible reasons: (1) Manual sharing — someone shared extra records with the 100-record user; (2) Apex
sharing — programmatic sharing added; (3) The user with 100 records is higher in role hierarchy or has a
different role; (4) Different teams in territory management; (5) The user has 'View All' on some record type; (6)
Sharing sets in Experience Cloud. OWD alone cannot explain this if profile/role are identical.

Q: OWD is private. I want User B (not the owner) to see the record. How?
Options: (1) Role Hierarchy — put User B above User A; (2) Sharing Rule — criteria or owner-based; (3)
Manual Sharing — owner clicks Share button; (4) Apex Sharing — insert into Account/Object share table; (5)
Public Group — add user to a group covered by a sharing rule.

Q: What is Apex Sharing? Write sample code.


Apex Sharing programmatically creates entries in the Share object (e.g., AccountShare, Case_Share__c for
custom objects). Used when sharing logic is too complex for sharing rules.
AccountShare share = new AccountShare();
[Link] = accountId;
[Link] = userId;
[Link] = 'Edit';
[Link] = 'Read';
[Link] = [Link];
insert share;
For custom objects, the RowCause should be a custom share reason defined in the object settings. Apex
sharing entries persist even if sharing rules change, unlike criteria-based shares which recalculate.

Q: What is 'with sharing', 'without sharing', and 'inherited sharing'?


with sharing: Enforces sharing rules — user only sees records they have access to (record-level). Does NOT
enforce OLS or FLS automatically.
without sharing: Runs in system context — all records visible regardless of user's sharing settings. Useful for
background/admin operations.
inherited sharing: Class inherits the sharing context of its caller. If called from a 'with sharing' class, it runs
with sharing. If called from 'without sharing', it runs without. Default for classes without declaration is also
inherited (effectively without sharing when called directly).
Key scenario: A 'without sharing' class called from a 'with sharing' class — the without sharing class ignores
the caller's sharing context and runs in system mode.

Q: With sharing — does it enforce FLS or OLS?


No. 'with sharing' only enforces record-level sharing rules. To enforce OLS, use
[Link](). To enforce FLS, use
[Link](). Or use WITH SECURITY_ENFORCED in SOQL,
or use [Link]() for both read and write operations.

Q: What are the settings available on Profile but NOT on Permission Set?
Profiles can set: Login Hours, Login IP Ranges, Page Layout Assignments, Record Type Defaults, App
visibility (default app). Permission Sets cannot configure these — they can only add/grant permissions, never
restrict. In Salesforce's roadmap, profiles will eventually be replaced by permission sets + permission set
groups.

Q: Difference between Permission Set and Permission Set Group?


Permission Set: A collection of permissions assigned to individual users in addition to their profile. Permission
Set Group: A bundle of multiple permission sets, assigned as a single unit to users. Muting Permission Sets
can be included in a group to suppress specific permissions within that group.

Q: 10 users, same profile with CRUD. Remove Edit and Create from 2 users only. How?
You cannot remove/restrict access through permission sets — they only grant. Solutions: (1) Create a new
profile with Read-only and assign to those 2 users; (2) Use a Restriction Rule (available from Summer '21) to
limit record access further; (3) For field-level restriction — use field-level security on a new profile. Note: From
Winter '23, you can enable 'User Permissions' on permission sets to potentially solve some restrictions.

Q: What is Manual Sharing? When is the Share button not visible?


Manual sharing lets the record owner (or admin) share an individual record with a user/group/role. The Share
button is not visible when: (1) OWD is Public Read/Write (no need to share); (2) The user doesn't own the
record and doesn't have 'Modify All' permission; (3) 'Manual User Record Sharing' is disabled in org settings.

Q: What are Restriction Rules in Salesforce?


Restriction Rules (introduced Summer '21) allow you to restrict which records a user can see — filtering
records from the user's view even if OWD allows access. Unlike sharing rules which open access, restriction
rules narrow it. They use filter criteria and can be applied per user criteria (profile, permission set, etc.).
Q: User has View All on Profile, OWD is Private — can they delete records owned by others?
View All allows reading all records. To delete, the user also needs 'Delete' on the object and 'Modify All' or
'Modify All Data' permission. 'View All' alone does not grant delete access. The user must own the record OR
have 'Modify All' on the object OR have 'Modify All Data' system permission to delete other users' records.

2. Apex Development
Q: What are Governor Limits in Salesforce? Give examples.
Governor Limits prevent any single tenant from monopolising shared resources in Salesforce's multi-tenant
environment.
• SOQL queries: 100 (sync) / 200 (async)
• SOQL rows returned: 50,000
• DML statements: 150
• DML rows: 10,000
• Heap size: 6 MB (sync) / 12 MB (async)
• CPU time: 10,000 ms (sync) / 60,000 ms (async)
• Callouts: 100 per transaction, 120 sec total wait
• Future methods per transaction: 50
• Batch apex jobs in queue: 5 (100 with Flex Queue)
Collections (Maps, Sets, Lists) help avoid limits — store data in memory and avoid repeated queries.
Bulkification avoids hitting DML/SOQL limits.

Q: Best practices for writing Apex code.


• One trigger per object — delegate to a handler class
• Bulkify all code — never put SOQL/DML inside loops
• Use Collections (Maps, Sets, Lists) to batch operations
• Use [Link]/update/delete with allOrNone=false for partial success handling
• Use with sharing to respect record-level security
• Avoid hardcoding IDs — use Custom Metadata or Custom Settings
• Write test classes with 75%+ coverage, use [Link]/stopTest for async
• Handle exceptions gracefully with try-catch-finally
• Use static variables to prevent trigger recursion
• Prefer SOQL for loops when processing large datasets to avoid heap issues
• Use @AuraEnabled(cacheable=true) only for read-only operations

Q: What is [Link] and [Link]?


[Link]: A List<SObject> of the new versions of records being inserted/updated. Available in: before
insert, before update, after insert, after update, after undelete. Values are read-only in after context.
[Link]: A Map<Id, SObject> of the same records, keyed by record Id. NOT available in before insert
(records have no Id yet). Available in: before update, after insert, after update, after undelete.

Q: What is [Link]?
[Link]: A Map<Id, SObject> of the old (previous) versions of records. Available in: before update,
after update, before delete, after delete. Used to detect changes: if ([Link](id).Status !=
[Link](id).Status) { ... }

Q: How do you handle trigger recursion?


Common approach: Static Boolean variable in a handler class. The static variable persists for the lifetime of
the transaction.
public class TriggerHelper {
public static Boolean isRunning = false;
}
In trigger: if(![Link]){ [Link] = true; ... }
Better approach for bulk scenarios: Use a Set<Id> of already-processed IDs instead of a simple Boolean, so
only unprocessed records are handled in recursive calls. This handles scenarios with 200+ records correctly
where Boolean might skip legitimate reprocessing.

Q: What is Mixed DML Exception? How to resolve?


Mixed DML occurs when you try to perform DML on setup objects (User, UserRole, Group, etc.) AND non-
setup objects (Account, Contact, etc.) in the same transaction.
Solutions: (1) Use @future method to perform one of the DML operations asynchronously; (2) Use
[Link]() in test classes; (3) Use a separate transaction via Queueable Apex.
// Solution using @future
@future
public static void updateUserAsync(Id userId, String email) {
User u = new User(Id = userId, Email = email);
update u;
}

Q: Difference between insert and [Link]?


insert (DML statement): All-or-nothing — if one record fails, the entire transaction rolls back. Throws an
exception on failure.
[Link](records, false): Partial success allowed — failed records are tracked in
[Link][]. Transaction does not roll back for individual failures. Best for bulk data processing
where partial success is acceptable.

Q: What is [Link] and rollback?


Savepoints allow partial rollback within a transaction. Use [Link]() to mark a point, then
[Link](sp) to revert all DML done after that point without rolling back the entire transaction.
Cannot rollback across async transactions.

Q: What is the use of @future annotation?


@future marks a static method to run asynchronously in a separate thread with its own governor limits. Used
for: (1) Making callouts from triggers (requires @future(callout=true)); (2) Avoiding Mixed DML errors; (3)
Offloading heavy processing. Limitations: Cannot accept sObject parameters (use Ids instead), cannot return
values, cannot be called from another future, limit of 50 per transaction.

Q: Can a future method call another future method?


No. Calling a future method from another future method throws a [Link]. The workaround is
to use Queueable Apex, which supports chaining.

Q: Can we call a future method from a Batch class?


Future methods cannot be called from the start() or execute() methods of Batch Apex. They CAN be called
from the finish() method. Alternatively, use Queueable Apex from execute() — one Queueable per execute()
call.

Q: What is Queueable Apex? Differences from Future?


Queueable Apex implements the Queueable interface. Advantages over @future: (1) Can accept sObject and
complex types as parameters; (2) Supports job chaining (call another Queueable from execute()); (3) Returns
a Job Id for monitoring; (4) Can run up to 50 chained jobs (1 from synchronous context, 50 from async). Use
Queueable when you need sObject params, chaining, or monitoring.

Q: How does Batch Apex process large datasets?


Batch Apex implements [Link]<sObject>. Has 3 methods:
• start(): Returns QueryLocator or Iterable — defines records to process. Called once.
• execute(): Called once per batch chunk (default 200 records). Each execute() is a separate transaction
with fresh governor limits.
• finish(): Called once after all batches complete. Used for post-processing (send email, chain another
batch).
[Link](new MyBatch(), 200) — 2nd param sets batch size (max 2000, min 1). For callouts,
implement [Link]. For state across batches, implement [Link].

Q: Can we call a batch from another batch?


You can call a new batch from the finish() method only. Calling [Link]() from start() or
execute() throws an AsyncException. Best practice: chain batches in finish() or use Queueable chaining.

Q: What is [Link]?
By default, Batch Apex does not persist instance variables between execute() calls — each chunk starts
fresh. Implementing [Link] preserves instance variable values across all execute() calls, allowing
you to aggregate counts, totals, error lists, etc. across batches.

Q: Can we make callouts from Batch Apex?


Yes — implement [Link] interface on your batch class. Callouts cannot be made from
start() or finish(), only from execute(). Each execute() can make up to 100 callouts. Note: You cannot have
both DML and callouts in the same execute() call if there are uncommitted DML statements (uncommitted
work pending error).

Q: How to schedule a Batch class every 30 minutes?


Salesforce's minimum cron schedule is hourly (you cannot set 30-min via cron directly). Workaround: Create
2 schedulable classes or schedule at :00 and :30 using 2 different scheduled jobs with cron expressions: '0 0
* * * ?' and '0 30 * * * ?'. In finish() method you can also reschedule the next run.

Q: What is CPU Time Limit? How to resolve?


CPU time limit is 10,000 ms (sync) / 60,000 ms (async). It only counts Apex execution time — NOT SOQL,
DML, or callout wait times. To fix:
• Move logic to async (Queueable/Batch/Future) for higher limit
• Remove unnecessary loops or nested loops
• Use Maps instead of nested iterations
• Move complex calculations to Flow or off-platform
• Use SOQL aggregate functions instead of Apex aggregation
• Profile using Salesforce Apex Profiling logs

Q: What is Heap Size error? How to resolve?


Heap size limit: 6 MB (sync) / 12 MB (async). Occurs when too much data is held in memory. Fix by:
• Using SOQL for loops: for(Account a : [SELECT Id FROM Account]) — processes one batch at a time
• Clearing collections after use: [Link]()
• Selecting only needed fields in SOQL
• Moving large data processing to Batch Apex (async has higher limit)

Q: SOQL 101 Error — what is it and how to fix?


'Too many SOQL queries: 101' occurs when you exceed 100 SOQL queries in a synchronous transaction.
Common cause: SOQL inside a loop. Fix:
• Move SOQL outside loops — collect Ids first, then query in bulk
• Use Map<Id, SObject> populated before the loop
• If 101 error in test class: ensure test data is set up in @testSetup and SOQL is not duplicated
• Check if managed package triggers are consuming some of the 100 limit

Q: What is the use of 'finally' keyword?


The finally block always executes regardless of whether an exception was thrown or caught. Used for cleanup
operations: closing connections, resetting state variables, logging. Syntax: try { ... } catch(Exception e) { ... }
finally { // always runs }

Q: What is dynamic SOQL? SOQL Injection and how to prevent?


Dynamic SOQL builds query strings at runtime using [Link](String). Risk: if user input is directly
concatenated, attackers can inject malicious SOQL. Prevention: Use [Link]() on all user-
supplied input before including in the query string, or use bind variables where possible.

Q: Difference between [Link] and Iterable in Batch?


[Link]: Returns up to 50 million records (bypasses the normal 50,000 SOQL row limit for
start()). Best for simple SOQL queries.
Iterable<SObject>: Allows complex processing logic in start() to build the list. Limited to 50,000 records. Used
when you need to pre-process or filter records programmatically before batching.

Q: What are best practices for Test Classes?


• Use @TestSetup for shared test data — runs once, rolled back after each test method
• Use [Link]() / [Link]() to reset governor limits and force async execution
• Never use SeeAllData=true unless absolutely necessary (e.g., standard price books)
• Assert expected outcomes — don't just run code without assertions
• Test bulk scenarios with 200 records to verify bulkification
• Test positive, negative, and edge cases
• Use @isTest(SeeAllData=false) — default for all test classes
• Custom Metadata records are accessible in test classes without SeeAllData=true; Custom Settings
require test data creation
• Use [Link]() for HTTP callout testing

Q: Why use [Link]() and [Link]()?


[Link]() resets governor limits for the code inside the test boundary — giving fresh limits.
[Link]() forces all asynchronous operations (future, batch, queueable) started within the block to
complete synchronously. This allows you to test async code results.

Q: Which exceptions cannot be caught in Apex?


[Link] (governor limits exceeded) cannot be caught — the transaction terminates
immediately. Most other exceptions (DMLException, QueryException, NullPointerException, etc.) can be
caught with catch(Exception e) or specific exception types.

Q: What annotations are used in test classes?


• @isTest — marks a class or method as a test
• @TestSetup — runs once before all test methods in the class to set up shared data
• @isTest(SeeAllData=true) — allows access to real org data (avoid)
• @isTest(IsParallel=true) — allows test to run in parallel with other tests

Q: What is the use case where SeeAllData=true is acceptable?


When testing against standard price books (Pricebook2) which require real data. In most other cases, create
your own test data. Alternatively, use [Link]() instead of querying.

Q: How to write test class for HTTP callouts?


Implement HttpCalloutMock interface and use [Link]():
@isTest
global class MockHttpResponse implements HttpCalloutMock {
global HTTPResponse respond(HTTPRequest req) {
HTTPResponse res = new HTTPResponse();
[Link](200);
[Link]('{"id":"123"}');
return res;
}
}
// In test method:
[Link]([Link], new MockHttpResponse());

Q: What are two methods specifically needed for Batch Apex test class?
[Link]() and [Link](). The [Link]() call must be between these two.
stopTest() forces the batch to complete synchronously so you can assert results.

Q: How to write test class for @future method?


Wrap the future call in [Link]() / [Link](). The stopTest() forces the future method to complete
before assertions.
[Link]();
[Link](recordId);
[Link]();
// Assert results after stopTest()

Q: Can we pass an sObject to a future method?


No — future methods only accept primitive data types and collections of primitives (String, Integer, List<Id>,
etc.) as parameters. Workaround: Pass a List<Id> and re-query inside the future method, OR serialize the
sObject to JSON (String) and deserialize inside the future method.

Q: What is a Wrapper Class? When to use?


A wrapper class is a custom Apex class used to group related data together — often combining data from
multiple objects or adding UI-specific properties not present in sObjects. Use cases: returning complex data to
LWC/Aura, combining Account with its related Contacts and Opportunities in one structure, adding UI state
like isSelected checkbox for datatables.

Q: Difference between virtual, abstract methods and interfaces?


Virtual class/method: Can be instantiated directly AND extended/overridden by subclasses. Use 'override'
keyword to override virtual methods.
Abstract class/method: Cannot be instantiated. Subclasses MUST implement abstract methods. Can contain
both abstract and non-abstract methods.
Interface: A contract — all methods must be implemented by the implementing class. Supports multiple
interface implementation (unlike single inheritance in Apex).

Q: What is [Link] row lock (FOR UPDATE)?


Adding FOR UPDATE to SOQL locks the selected records so no other transaction can update them until
current transaction completes. Used to prevent race conditions. UNABLE_TO_LOCK_ROW error occurs
when multiple concurrent transactions try to lock the same records simultaneously. Resolution: Implement
retry logic, reduce batch concurrency, or restructure data processing to avoid shared record access.

3. Apex Triggers
Q: What are the trigger events in Salesforce?
• before insert — record not yet saved; can modify field values
• after insert — record saved; Id available; cannot modify triggering records
• before update — record not yet saved with changes; can modify fields
• after update — changes saved; oldMap and newMap available
• before delete — record not yet deleted; [Link] available
• after delete — record deleted; [Link] available
• after undelete — records restored from Recycle Bin; [Link] available
Note: There is no 'before undelete'. Only after delete and after undelete exist for delete operations.

Q: When do you choose before vs after trigger?


Before trigger: When you need to validate or modify the triggering record's fields before it's saved — no DML
needed on the same record (just assign field values). Ideal for field population, validation logic.
After trigger: When you need the record Id (post-insert), need to update related records, insert child records,
or perform actions that shouldn't be part of the save operation. The triggering record is read-only in after
context.

Q: What is Trigger Framework / Handler Pattern?


A trigger framework separates trigger logic from the trigger file itself. The trigger file only contains event
routing to a handler class. Benefits: single responsibility, easier testing, recursion control, bypass logic.
// Trigger file (thin)
trigger AccountTrigger on Account(before insert, after insert, before update, after
update) {
AccountTriggerHandler handler = new AccountTriggerHandler();
if([Link] && [Link]) [Link]([Link]);
if([Link] && [Link]) [Link]([Link],
[Link]);
}

Q: Write a Trigger: Roll-up count of Contacts on Account.


trigger ContactTrigger on Contact(after insert, after update, after delete, after
undelete) {
Set<Id> accountIds = new Set<Id>();
List<Contact> contacts = [Link] ? [Link] : [Link];
for(Contact c : contacts) {
if([Link] != null) [Link]([Link]);
}
if([Link]) {
for(Contact c : [Link]) if([Link] != null) [Link]([Link]);
}
List<AggregateResult> results = [SELECT AccountId, COUNT(Id) cnt FROM Contact
WHERE AccountId IN :accountIds GROUP BY AccountId];
Map<Id, Integer> countMap = new Map<Id, Integer>();
for(AggregateResult ar : results) [Link]((Id)[Link]('AccountId'),
(Integer)[Link]('cnt'));
List<Account> toUpdate = new List<Account>();
for(Id accId : accountIds) {
[Link](new Account(Id = accId, Number_of_Contacts__c =
[Link](accId) ? [Link](accId) : 0));
}
update toUpdate;
}

Q: Write a Trigger: Prevent deletion of Account if related Contacts exist.


trigger AccountTrigger on Account(before delete) {
Map<Id, Account> accMap = new Map<Id, Account>([SELECT Id, (SELECT Id FROM Contacts
LIMIT 1)
FROM Account WHERE Id IN :[Link]]);
for(Account acc : [Link]) {
if(![Link]([Link]).[Link]()) {
[Link]('Cannot delete Account with related Contacts.');
}
}
}

Q: Write a Trigger: When Account BillingCity is updated, update all related Contact MailingCity.
trigger AccountTrigger on Account(after update) {
List<Account> changed = new List<Account>();
for(Account acc : [Link]) {
if([Link] != [Link]([Link]).BillingCity) [Link](acc);
}
if([Link]()) return;
Set<Id> accIds = new Map<Id, Account>(changed).keySet();
List<Contact> contacts = [SELECT Id, AccountId FROM Contact WHERE AccountId
IN :accIds];
Map<Id, String> cityMap = new Map<Id, String>();
for(Account a : changed) [Link]([Link], [Link]);
for(Contact c : contacts) [Link] = [Link]([Link]);
update contacts;
}

Q: Write a Trigger: Only System Admin can delete Tasks.


trigger TaskTrigger on Task(before delete) {
String profileName = [SELECT Name FROM Profile WHERE Id
= :[Link]()].Name;
if(profileName != 'System Administrator') {
for(Task t : [Link]) [Link]('Only System Administrators can delete
tasks.');
}
}

Q: Write a Trigger: Prevent duplicate Contact based on Email.


trigger ContactTrigger on Contact(before insert, before update) {
Set<String> emails = new Set<String>();
for(Contact c : [Link]) if([Link] != null) [Link]([Link]);
Map<String, Contact> existingMap = new Map<String, Contact>();
for(Contact c : [SELECT Id, Email FROM Contact WHERE Email IN :emails]) {
[Link]([Link], c);
}
for(Contact c : [Link]) {
if([Link] != null && [Link]([Link]) &&
[Link]([Link]).Id != [Link]) {
[Link]('A contact with this email already exists.');
}
}
}

Q: Write a Trigger: Sum of Opportunity Amounts on Account.


trigger OpportunityTrigger on Opportunity(after insert, after update, after delete, after
undelete) {
Set<Id> accIds = new Set<Id>();
for(Opportunity o : [Link] ? [Link] : [Link]) if([Link] !=
null) [Link]([Link]);
if([Link]) for(Opportunity o : [Link]) if([Link] != null)
[Link]([Link]);
Map<Id, Decimal> sumMap = new Map<Id, Decimal>();
for(AggregateResult ar : [SELECT AccountId, SUM(Amount) total FROM Opportunity WHERE
AccountId IN :accIds GROUP BY AccountId]) {
[Link]((Id)[Link]('AccountId'), (Decimal)[Link]('total'));
}
List<Account> toUpdate = new List<Account>();
for(Id id : accIds) [Link](new Account(Id = id, Total_Opportunity_Amount__c =
[Link](id) ? [Link](id) : 0));
update toUpdate;
}

Q: What is the maximum trigger depth in Salesforce?


Salesforce allows up to 16 levels of trigger recursion. After 16 recursive calls, a runtime exception is thrown.
This is separate from the recursion within a single trigger execution.

Q: How many triggers can we have on one object?


Salesforce allows multiple triggers per object, but best practice is one trigger per object. When there are
multiple triggers, the order of execution is not guaranteed between triggers (though within a single trigger,
order of execution applies). Managed packages have their own separate governor limit set for their triggers.

4. SOQL / SOSL
Q: Difference between SOQL and SOSL?
SOQL (Salesforce Object Query Language): Queries a single object and its related objects. Returns sObject
records. Used when you know which object to query.
SOSL (Salesforce Object Search Language): Searches across multiple objects simultaneously using full-text
search index. Returns List<List<SObject>>. Used when you don't know which object has the data or need
cross-object search.
// SOSL example
List<List<SObject>> results = [FIND 'Acme' IN ALL FIELDS RETURNING Account(Id, Name),
Contact(Id, Name)];

Q: What is Semi-join and Anti-join in SOQL?


Semi-join: Returns records where a field value EXISTS in a subquery. Example: SELECT Id FROM Account
WHERE Id IN (SELECT AccountId FROM Contact WHERE Email != null)
Anti-join: Returns records where a field value does NOT EXIST in a subquery. Example: SELECT Id FROM
Account WHERE Id NOT IN (SELECT AccountId FROM Contact)

Q: SOQL: Fetch Account with most number of Contacts.


SELECT AccountId, COUNT(Id) cnt FROM Contact GROUP BY AccountId ORDER BY COUNT(Id) DESC
LIMIT 1

Q: SOQL: Fetch Accounts with no related Contacts.


SELECT Id, Name FROM Account WHERE Id NOT IN (SELECT AccountId FROM Contact WHERE
AccountId != null)

Q: SOQL: Count of Opportunity Stages.


SELECT StageName, COUNT(Id) cnt FROM Opportunity GROUP BY StageName

Q: SOQL: Accounts with more than 3 Contacts.


SELECT AccountId, COUNT(Id) cnt FROM Contact GROUP BY AccountId HAVING COUNT(Id) > 3

Q: SOQL: Second highest Opportunity amount.


SELECT Amount FROM Opportunity ORDER BY Amount DESC LIMIT 1 OFFSET 1

Q: SOQL: Parent-to-child and Child-to-parent queries.


// Parent-to-child (inner query - standard objects use relationship name)
SELECT Id, Name, (SELECT Id, FirstName, LastName FROM Contacts) FROM Account
// Child-to-parent (dot notation)
SELECT Id, FirstName, [Link], [Link] FROM Contact
// Custom object child-to-parent (use __r instead of __c)
SELECT Id, Name, Account__r.Name FROM Invoice__c

Q: SOQL: Count duplicate Leads by Phone.


SELECT Phone, COUNT(Id) cnt FROM Lead GROUP BY Phone HAVING COUNT(Id) > 1

Q: SOQL: Role of a user.


SELECT [Link] FROM User WHERE Id = :userId

Q: SOQL: UserRoles not assigned to any User.


SELECT Id, Name FROM UserRole WHERE Id NOT IN (SELECT UserRoleId FROM User WHERE
UserRoleId != null)

Q: SOQL: Get deleted records from Recycle Bin.


SELECT Id, Name FROM Account WHERE IsDeleted = true ALL ROWS

Q: SOQL: Records created in last 4 years.


SELECT Id FROM Lead WHERE CreatedDate >= LAST_N_YEARS:4

Q: How to query both Contacts and Leads with same email?


SOSL is the best approach — it can search across multiple objects in one query:
List<List<SObject>> results = [FIND 'manjunath@[Link]' IN EMAIL FIELDS RETURNING
Contact(Id, Email), Lead(Id, Email)];

Q: What is an External ID field? Why use it?


An External ID is a custom field marked as an External ID — it gets indexed and can be used for upsert
operations by matching the external system's identifier. Use cases: (1) Upsert records using an external key
instead of Salesforce Id; (2) Mapping records during data migration from external systems; (3) Can be used in
relationship fields for foreign key lookups in Data Loader.

Q: What is an Indexed field? Why use it?


Indexed fields are stored with an index in the database, making queries on those fields faster. Standard
indexed fields: Id, Name, CreatedDate, SystemModstamp, OwnerId, External ID fields, fields marked as
Unique. Custom fields can be indexed if marked as External ID or Unique. For large data volumes, querying
non-indexed fields causes 'Non-selective query' errors. You can request Salesforce to add a custom index via
a support case.

5. Lightning Web Components (LWC)


Q: What are the Decorators in LWC?
• @api — makes a property or method public. Properties are reactive and can be set by parent
components. Methods are callable by parent via template ref.
• @track — makes private properties reactive — when the property changes, the component re-renders. In
modern LWC (API version 39+), all private properties are reactive by default for primitives and top-level
object/array reassignment. @track is needed for deep reactivity within nested objects/arrays.
• @wire — wires a property or function to a wire adapter (Salesforce data service or Apex method).
Automatically reactive — re-runs when parameters change. Data comes in {data, error} structure.

Q: Lifecycle Hooks in LWC — explain each.


• constructor() — runs first when component is created. Cannot access DOM or child elements. Use for
initializing properties. Call super() first. Do not fetch data here.
• connectedCallback() — runs when component is inserted into the DOM. Use for: data fetching, event
listener setup, initialization logic. Child components may not be rendered yet.
• renderedCallback() — runs after every render (including re-renders). Use cautiously — avoid DML/data
fetch here as it can cause infinite loops. Use a flag to run once: if([Link]) return; [Link]
= true;
• disconnectedCallback() — runs when component is removed from the DOM. Use for cleanup:
unsubscribe from events, clear timers.
• errorCallback(error, stack) — catches errors from child components. Acts as error boundary.

Q: Lifecycle order for Parent-Child components?


Construction order (top-down): Parent constructor → Parent connectedCallback → Child constructor → Child
connectedCallback → Child renderedCallback → Parent renderedCallback
So: connectedCallback fires top-down, renderedCallback fires bottom-up. A [Link] in child
renderedCallback fires before parent renderedCallback.

Q: When is @wire called in lifecycle?


Wire provisioning happens after connectedCallback and before renderedCallback. Wire is called when the
component is connected to the DOM and runs again whenever its reactive parameters change (prefixed with
$). It is NOT called manually — it is automatically managed by the framework.

Q: Difference between @wire and Imperative Apex call?


@wire: Declarative, automatic, reactive — re-runs when parameters change, caches results, cannot perform
DML (cacheable=true methods only). Data available as {data, error} object.
Imperative: Called explicitly (e.g., on button click or in connectedCallback). Can call non-cacheable methods
(DML allowed). Returns a Promise. More control over when the call happens.
// Wire example
@wire(getAccounts, { recordId: '$recordId' }) accounts;
// Imperative example
connectedCallback() {
getAccounts({ recordId: [Link] }).then(result => { [Link] =
result; }).catch(error => { [Link] = error; });
}

Q: How to make an Imperative call reactive (re-run when params change)?


Use getter/setter with @api or @track to detect changes, then call the Apex method inside the setter or use a
watcher pattern:
_recordId;
@api get recordId() { return this._recordId; }
set recordId(value) { this._recordId = value; [Link](); }
loadData() { getAccounts({ recordId: this._recordId }).then(r => [Link] = r); }

Q: Parent to Child communication in LWC?


(1) @api property: Parent sets a public property on child via HTML attribute. Child must mark it @api.
Reactive — child re-renders when parent changes the value.
(2) @api method: Parent calls a child's public method using a template reference.
// Child: expose method
@api refresh() { [Link](); }
// Parent HTML: <c-child ref='childComp'></c-child>
// Parent JS: [Link]();
(3) lwc:ref (API 59+): Modern way to get reference to child elements.

Q: Child to Parent communication in LWC?


Custom Events: Child dispatches a CustomEvent, parent listens with an event handler.
// Child JS
[Link](new CustomEvent('accountselected', { detail: { id:
[Link] } }));
// Parent HTML
<c-child onaccountselected={handleAccountSelected}></c-child>
// Parent JS
handleAccountSelected(event) { [Link] = [Link]; }

Q: Communication between unrelated components (not parent-child)?


Lightning Message Service (LMS): Publish-subscribe pattern for components across the DOM.
// Publisher
import { publish, MessageContext } from 'lightning/messageService';
import MY_CHANNEL from '@salesforce/messageChannel/MyChannel__c';
@wire(MessageContext) messageContext;
publish([Link], MY_CHANNEL, { recordId: [Link] });
// Subscriber
import { subscribe, MessageContext } from 'lightning/messageService';
connectedCallback() {
[Link] = subscribe([Link], MY_CHANNEL, (msg) =>
{ [Link] = [Link]; });
}
disconnectedCallback() { unsubscribe([Link]); }

Q: Grandparent to Grandchild (A → B → C) and reverse?


A → C (down): Pass @api property from A to B, B passes it to C.
C → A (up): C fires custom event with bubbles:true, composed:true. B doesn't need to handle it. A listens on
the child C tag. OR use LMS.
// In C (child):
[Link](new CustomEvent('notify', { detail: data, bubbles: true, composed: true
}));
// In A (grandparent HTML):
<c-b onnotify={handleNotify}></c-b> // event bubbles up through B to A

Q: What is Shadow DOM?


Shadow DOM is a browser feature that encapsulates a component's DOM and CSS. In LWC, each
component's template is rendered inside a shadow root, preventing styles from leaking in or out. Synthetic
shadow (polyfill) was used historically; native shadow is the modern approach. This encapsulation means
parent CSS cannot directly style child elements unless CSS custom properties (styling hooks) are used.

Q: Event bubbles and composed — what do they do?


bubbles: true — event propagates up the DOM tree (from child to parent).
composed: true — event crosses the shadow DOM boundary, allowing it to propagate across component
boundaries.
Default values: both are false. For cross-component event propagation: set both to true.

Q: What is LDS (Lightning Data Service)?


LDS provides wire adapters to read, create, edit, and delete records without writing Apex. It handles caching,
FLS, and sharing automatically. Key adapters:
• getRecord — fetch a single record's fields
• getRecordCreateDefaults — get defaults for creating a record
• getRelatedListRecords — fetch related list records
• createRecord, updateRecord, deleteRecord — from lightning/uiRecordApi
Advantage: Caches data in browser, auto-updates all components using the same record. Limitation: Cannot
handle complex logic like triggers or multi-object operations.
Q: What is refreshApex?
refreshApex() re-fetches data for a @wire property by making a new server call, bypassing the cache. Used
when you know data has changed (e.g., after a DML operation) and need to update the UI.
import { refreshApex } from '@salesforce/apex';
@wire(getAccounts) wiredAccounts;
handleSave() {
saveRecord({ ... }).then(() => refreshApex([Link]));
}

Q: Can we do DML inside a @wire method?


No — Apex methods annotated with @AuraEnabled(cacheable=true) (required for @wire) cannot perform
DML. If DML is needed, use an imperative call to a non-cacheable method. The framework throws an error if
cacheable=true and DML is attempted.

Q: Why does @AuraEnabled(cacheable=true) not allow DML?


When cacheable=true, Salesforce caches the result in the browser and local cache. If DML were allowed, the
cached value could become stale — inconsistent with the actual database state. By preventing DML,
Salesforce ensures data consistency between cached results and org data.

Q: Best practices for LWC?


• Use @wire for read operations, imperative for writes and user-triggered actions
• Unsubscribe from LMS in disconnectedCallback to prevent memory leaks
• Use lazy loading for large datasets — pagination or infinite scroll
• Avoid DML in renderedCallback — use a flag to prevent infinite loops
• Use SLDS for styling consistency
• Minimise @track usage — use @api for public, plain assignment for private
• Use lightning-record-form, lightning-record-view-form for standard record operations
• Handle errors gracefully — check both data and error from wire
• Use lwc:if/lwc:elseif instead of deprecated if:true/if:false

Q: Difference between lightning-record-form and lightning-record-edit-form?


lightning-record-form: Auto-layout, handles view/edit/create modes automatically, uses page layout field
order. Less customisable.
lightning-record-edit-form: Manual layout — you explicitly specify each field with lightning-input-field. More
customisable — custom validation, custom submit handling, custom field arrangement. Use this when you
need control over individual fields or custom logic on save.

Q: How to get recordId in LWC on a record page?


import { LightningElement, api } from 'lwc';
export default class MyComponent extends LightningElement {
@api recordId; // Automatically populated when placed on a record page
}
For a Quick Action (not a record page), the recordId may not be auto-populated — use
CurrentPageReference from lightning/navigation or pass it explicitly via design attributes.

Q: How to show Toast messages in LWC?


import { ShowToastEvent } from 'lightning/platformShowToastEvent';
[Link](new ShowToastEvent({ title: 'Success', message: 'Record saved!',
variant: 'success' }));
Variants: success (green), error (red), warning (yellow), info (blue). You can also set 'sticky' mode to keep the
toast until dismissed.

Q: How to call a flow from LWC?


// HTML
<lightning-flow flow-api-name='My_Flow' onstatuschange={handleStatusChange}></lightning-
flow>
// Can pass input variables:
<lightning-flow flow-api-name='My_Flow' flow-input-variables={inputVars}></lightning-flow>
// JS - inputVars is array of {name, type, value}
get inputVars() { return [{ name: 'recordId', type: 'String', value: [Link] }]; }

Q: How to call LWC from a Quick Action?


In the component's XML metadata file, set targets to include force:lightningQuickAction or
force:lightningQuickActionWithoutHeader. Then create a Quick Action of type 'Lightning Component' in Object
Manager pointing to your component.

Q: How to call LWC inside a Flow?


Add 'lightning__FlowScreen' as a target in the component's XML. The component must implement
FlowNavigationNextAction and FlowNavigationFinishAction interfaces if it needs to control navigation. Add
@api inputAttributes and outputAttributes as needed.

Q: What is LWC OSS?


LWC Open Source (OSS) is the open-source version of LWC that can run outside Salesforce — on [Link],
in static sites, or other platforms. It uses the same programming model but without Salesforce-specific
features like wire adapters, @salesforce imports, or platform authentication.

Q: What is the use of @track decorator in 2024/2025?


In modern LWC (API v39+), primitive properties are automatically reactive without @track. However, @track
is still needed for deep reactivity within nested objects or arrays — if you reassign a property of a nested
object (not the object itself), the UI won't update unless @track is used on the parent object.

Q: How to use static resources in LWC?


import myResource from '@salesforce/resourceUrl/MyLibrary';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
connectedCallback() {
loadScript(this, myResource + '/lib/[Link]').then(() => { /* use lib */ });
}

Q: What are slots in LWC?


Slots allow parent components to pass HTML content into child component templates. Unnamed slot:
<slot></slot> — accepts any content. Named slot: <slot name='header'></slot> — accepts content with
slot='header' attribute. Used to build reusable container components.

Q: Difference between Constructor and connectedCallback?


Constructor: Called when the component class is instantiated. DOM is not available — cannot access
[Link]. Primarily for property initialisation. Must call super().
connectedCallback: Called when component is inserted into the DOM. Template is accessible. Used for data
fetching, setting up subscriptions, and initialisation that needs DOM access.

Q: What is lwc:ref? What is lwc:spread?


lwc:ref: Template reference — allows JS to get a direct reference to an element or child component.
[Link] accesses the element.
lwc:spread: Spreads an object's properties as attributes on an element. Similar to JavaScript's spread
operator for HTML attributes. Available in newer API versions.

Q: How to check custom permissions in LWC?


import hasMyPermission from '@salesforce/customPermission/My_Permission_Name';
// Then in HTML: <template lwc:if={hasMyPermission}>... </template>

Q: How to call LWC from Aura and vice versa?


LWC inside Aura: Simply use the LWC as a child component in Aura's markup: <c:myLwcComponent
recordId='{![Link]}'>. Communication from LWC to Aura uses CustomEvents with bubbles:true,
composed:true.
Aura inside LWC: Not directly supported. You would need LMS or URL-based navigation as intermediaries.

Q: [Link] vs [Link] — difference?


[Link]: Standard DOM property — the current value of the input element that fired the event.
Used with native HTML inputs.
[Link]: LWC custom event property — data packaged by the component that dispatched the custom
event. Used with CustomEvent.

Q: Promises in LWC/JavaScript?
A Promise represents an asynchronous operation's eventual result. States: pending, fulfilled, rejected.
// Basic promise chain
getAccounts({ recordId: [Link] })
.then(result => { [Link] = result; })
.catch(error => { [Link] = error; })
.finally(() => { [Link] = false; });
// [Link] — run multiple promises in parallel
[Link]([getAccounts(p1), getContacts(p2)]).then(([accounts, contacts]) => { ... });
// Async/await (cleaner syntax)
async connectedCallback() {
try { [Link] = await getAccounts({ recordId: [Link] }); }
catch(e) { [Link] = e; }
}

Q: What is lazy loading in LWC?


Lazy loading defers loading content until it's needed — typically used for large data sets. In LWC, implement it
via: (1) Pagination — load records in pages; (2) lightning-datatable's enable-infinite-loading — load more
records as user scrolls; (3) Dynamic imports (for component-level lazy loading). Prevents loading all 50,000
records at once.

Q: How to handle a large dataset (50k+ records) in LWC?


• Pagination: Query with LIMIT and OFFSET, load page by page
• Infinite scrolling: Use lightning-datatable enable-infinite-loading
• SOQL cursor: Use [Link] with cursor patterns in Apex
• Aggregate data: Don't show raw records — show summaries/charts
• Server-side filtering: Let users narrow down before fetching

6. Flows in Salesforce
Q: What are the types of Flows in Salesforce?
• Screen Flow — presents UI screens to users; can be embedded in pages or quick actions
• Record-Triggered Flow — fires on record insert/update/delete (before/after save)
• Schedule-Triggered Flow — runs on a schedule for a batch of records
• Platform Event-Triggered Flow — fires when a platform event message is received
• Autolaunched Flow (No Trigger) — invoked programmatically from Apex, other flows, processes
• Flow Orchestration — coordinates multiple flows for complex multi-step approvals

Q: Difference between Before Save and After Save in Record-Triggered Flows?


Before Save: Runs before the record is committed to the database. Can update the triggering record's fields
without DML. Faster — same transaction. Cannot perform DML on other records.
After Save: Runs after the record is committed. Can perform DML on other records, send emails, call
subflows, call Apex actions. Slightly slower — separate transaction.

Q: When to use Flow vs Trigger?


Use Flow when: Simple declarative logic, admin-maintainable, field updates, email sends, record creates with
simple logic, no complex collections/loops needed.
Use Trigger when: Complex business logic, bulk processing, cross-object logic with many records, callouts
required, precise governor limit control, order of execution matters, performance is critical.

Q: If both a Flow and a Trigger exist on the same object, what happens?
Both execute — Salesforce doesn't prevent it. The order of execution: Validation Rules → Before Triggers →
After Triggers → Assignment Rules → Auto-Response Rules → Workflow Rules → Process Builder →
Record-Triggered Flows (After Save) → Escalation Rules → Entitlements → Roll-Up Summaries → Parent
workflows → Commit. Having both is not recommended for same logic — leads to complexity and potential
double-execution.

Q: How to call Apex from Flow?


Create an Apex class with a method annotated @InvocableMethod. The method must be public static, accept
a List parameter, and can return a List. Then in Flow, add an 'Action' element and select your Apex class.
public class FlowApexAction {
@InvocableMethod(label='Get Account Name')
public static List<String> getAccountName(List<Id> accountIds) {
List<String> names = new List<String>();
for(Account a : [SELECT Name FROM Account WHERE Id IN :accountIds])
[Link]([Link]);
return names;
}
}
Only one @InvocableMethod allowed per Apex class. Return type must be List<> to support bulk flow
invocations.

Q: How to fetch Account ID in Screen Flow?


(1) If the flow is on a record page — use {!$[Link]} as a resource variable. (2) Use a 'Get Records'
element to query the Account. (3) Pass it as an input variable when launching the flow. (4) Use the output of a
previous 'Create Records' or 'Get Records' element.

Q: Can we call a Flow from another Flow?


Yes — using a Subflow element. One flow can call another flow (must be an Autolaunched or Screen Flow).
You can pass input/output variables between flows.

Q: Can we call a future method from a Flow?


Not directly. You can call an @InvocableMethod from a flow, and that Apex method can internally call a
@future method. So indirectly yes, through an invocable Apex wrapper.

Q: Can we do callouts from Flows?


Yes — using the External Services feature (Swagger/OAS spec-based) or by calling Apex @InvocableMethod
that does the callout. Flows themselves use the Apex callout mechanism under the hood.

Q: What is a Platform Event-Triggered Flow?


A flow that fires when a specific Platform Event is published. The flow processes each event message. Use
cases: real-time integrations, event-driven automation, processing events from external systems without
custom Apex subscribers.

Q: How to handle errors in Record-Triggered Flows?


Use Fault connectors on elements that can fail (DML, Apex, subflows). Route fault path to a custom
notification or set error message. For screen flows, use Fault connectors to show custom error screens. Flow
errors also send email to flow admin by default.

Q: What are Dynamic Forms?


Dynamic Forms allow you to place individual fields and sections from a page layout directly on a Lightning
Record Page (App Builder) — as components rather than a monolithic layout. Benefits: (1) Field-level visibility
rules; (2) Different fields visible per profile/record type without multiple page layouts; (3) More flexible page
design. Available for custom objects and some standard objects.

7. Integration
Q: What is Remote Site Setting? What is Named Credential?
Remote Site Setting: Whitelists an external URL/endpoint so Salesforce allows callouts to it. Simple — just
the URL, no authentication details. Required when using hardcoded URLs in Apex callouts.
Named Credential: A more advanced alternative — stores both the endpoint URL AND authentication details
(username/password, OAuth tokens, certificates). In Apex, use 'callout:MyNamedCredential' instead of the full
URL. Advantages over RSS: (1) Authentication is handled by Salesforce — no credentials in code; (2)
Credentials can be rotated without code changes; (3) Supports OAuth, Basic Auth, JWT, etc.

Q: What is a Connected App?


A Connected App defines a trusted external application that can integrate with Salesforce via OAuth 2.0. It
provides Consumer Key and Consumer Secret used for OAuth authentication flows. Required for: inbound
integrations (external systems calling Salesforce APIs), SSO, and mobile apps.

Q: What is the difference between REST and SOAP integration?


REST: Uses HTTP methods (GET, POST, PUT, PATCH, DELETE). Returns JSON or XML. Lightweight,
stateless, faster. Better for mobile and web APIs. Salesforce's modern APIs (REST API, Apex REST) use
this.
SOAP: XML-based, uses WSDL for contract. More rigid, heavier, but has built-in error handling and WS-
Security. Used for legacy enterprise integrations. Salesforce SOAP API requires WSDL download.

Q: What are OAuth 2.0 grant types / flows?


• Web Server Flow (Authorization Code): User logs in via browser, gets auth code, exchanged for access
token. Used for web apps.
• User-Agent Flow (Implicit): Token returned directly to browser. Less secure — no client secret.
• Username-Password Flow: Credentials sent directly. Simple but less secure — no user interaction.
• JWT Bearer Flow: Uses a certificate-signed JWT instead of password. No user interaction — used for
server-to-server.
• Client Credentials Flow: Uses client ID/secret. For server-to-server without user context.
• Refresh Token Flow: Uses refresh token to get new access token without re-authentication.

Q: How to make a callout from Apex?


HttpRequest req = new HttpRequest();
[Link]('callout:MyNamedCredential/api/accounts');
[Link]('GET');
[Link]('Content-Type', 'application/json');
Http http = new Http();
HttpResponse res = [Link](req);
if([Link]() == 200) {
Map<String, Object> body = (Map<String, Object>)
[Link]([Link]());
}
Q: How to do callouts from Triggers?
Cannot do callouts directly in triggers (uncommitted DML causes 'uncommitted work pending' error). Solution:
Use @future(callout=true) — call the future method from the trigger, passing Ids. The future method then
makes the callout in a separate async transaction.

Q: How to expose Salesforce data to external systems (Inbound Integration)?


(1) Create an Apex REST Service using @RestResource annotation. (2) Create a Connected App in
Salesforce. (3) External system authenticates via OAuth (gets access token). (4) Calls the Apex REST
endpoint.
@RestResource(urlMapping='/accounts/*')
global class AccountRestService {
@HttpGet
global static Account getAccount() {
Id accId = [Link]('/');
return [SELECT Id, Name, BillingCity FROM Account WHERE Id = :accId];
}
}
Why global? Apex REST service classes must be global to be accessible externally.

Q: What is Bulk API?


Salesforce's Bulk API is optimised for loading or extracting large data volumes (millions of records). It
processes records asynchronously in batches. Two modes: Serial (one batch at a time) and Parallel (multiple
batches simultaneously — risk of row lock errors). Data Loader uses Bulk API. Bulk API 2.0 is the modern
version with simpler job management.

Q: What is difference between Authentication and Authorization?


Authentication: Verifying identity — 'Who are you?' (login with username/password, certificates, OAuth).
Authorization: Determining access rights — 'What can you do?' (profile permissions, sharing rules, scopes in
OAuth).

Q: What are Platform Events?


Platform Events are Salesforce's enterprise messaging feature. Publishers send event messages; subscribers
receive them asynchronously. Used for: real-time integrations, decoupled architectures, cross-org
communication. Differences from CDC: Platform Events are custom-defined; CDC (Change Data Capture)
automatically publishes events when standard/custom object records change.

Q: What is the Composite API?


The Composite API lets you execute multiple sub-requests in a single HTTP call and reference results from
earlier requests in later ones. More efficient than multiple individual API calls. Types: Composite Resources,
SObject Tree (create multiple related records in one call), Batch (multiple independent requests in one call).

8. Data & Deployment


Q: What Data Migration tools have you used?
• Data Loader: Salesforce's official desktop tool. Import/export/upsert/delete. Uses SOAP or Bulk API.
Supports up to 5 million records per operation.
• Data Import Wizard: Browser-based, simpler. Limited to 50,000 records. Supports standard objects only.
• Workbench: Web-based admin tool. SOQL queries, REST explorer, data import/export.
• [Link]: Cloud-based, scheduled jobs, supports multiple objects.
• MuleSoft / Informatica: ETL tools for complex migration with transformation.

Q: What deployment tools have you used?


• Change Sets: Point-and-click deployment between connected orgs. Limitations: slow, no version control,
no rollback.
• VS Code with Salesforce Extensions + SFDX CLI: Source-tracked orgs, Git-based, fast deployment.
• Copado: Full DevOps platform with CI/CD pipelines, version control, automated testing.
• DevOps Center: Salesforce's native CI/CD tool (successor to Change Sets).
• Ant Migration Tool: XML-based, scriptable deployments.
// SFDX deploy command
sf project deploy start --source-dir force-app --target-org myOrg

Q: Difference between Change Sets and DevOps Center?


Change Sets: Manual, UI-driven, no version control, no rollback, dependent metadata must be included
manually. Cannot deploy destructive changes easily.
DevOps Center: Git-based, supports version control, work items tracking, multi-stage pipelines, automated
deployments. The modern replacement for Change Sets.

Q: What are Custom Settings?


Custom Settings are custom objects that store hierarchical or list configuration data. Types:
• Hierarchy: Can be set at org, profile, or user level — more specific setting overrides. Accessible in Apex,
formula fields, validation rules.
• List: Flat key-value data accessible by name.
Data is cached — faster access than SOQL. Can be used in formula fields and validation rules directly.

Q: What is Custom Metadata?


Custom Metadata Types store configuration data that can be deployed as metadata (unlike Custom Settings
records, which are data). Key differences from Custom Settings: (1) Records are deployable via Change
Sets/packages; (2) Can be queried in Apex (SOQL); (3) Cannot be used directly in formula fields; (4) Better
for configuration that varies between sandboxes and production. Use Custom Metadata for: configuration that
changes per environment, feature flags, routing rules, integration settings.

Q: Types of Sandboxes?
• Developer: 200 MB data, 200 MB file storage. Fresh copy — no production data.
• Developer Pro: 1 GB data. More suitable for development and testing.
• Partial Copy: 5 GB data. Subset of production data. Refreshes every 5 days.
• Full: Full copy of production — same data, same storage. Refreshes every 29 days.

Q: What is the difference between freezing and deactivating a user?


Freeze: Temporarily prevents the user from logging in but preserves their license and setup. Reversible
quickly. Use when someone is on leave or during investigations.
Deactivate: Permanently disables the user account. Their license is freed and can be reassigned. Their
records remain with them as owner. Cannot log in. Takes effect immediately.

Q: What is Agile methodology? How does a Sprint work?


Agile is an iterative development methodology. Work is broken into Sprints (typically 2 weeks). Process:
Sprint Planning (select items from backlog, estimate using story points) → Daily Standups → Development →
Sprint Review/Demo → Sprint Retrospective. Tools: Jira, Azure DevOps. Ceremonies: Sprint Planning, Daily
Scrum, Sprint Review, Sprint Retrospective, Backlog Grooming.

9. Salesforce Object Model & Configuration


Q: Difference between Lookup and Master-Detail relationships?
Lookup: Loosely coupled — child can exist without parent. Parent deletion doesn't cascade. OWD is
independent. No rollup summary fields. Lookup field is not required.
Master-Detail: Tightly coupled — child cannot exist without parent. Parent deletion cascades to children. Child
inherits parent's OWD. Supports Rollup Summary fields on master. MD field is required and locked after data
exists.
Q: Can we convert Lookup to Master-Detail and vice versa?
Lookup → MD: Possible IF all existing records have a value in the lookup field (no nulls) and the relationship
doesn't already have data that violates MD rules. The 'Change Field Type' button appears when conditions
are met.
MD → Lookup: Possible, but you lose rollup summary fields and cascade delete behavior. OWD becomes
independent.

Q: What is a Junction Object?


A junction object implements a many-to-many relationship using two Master-Detail relationships. The primary
master (first MD relationship created) determines OWD inheritance. Standard examples: CampaignMember
(Campaign + Lead/Contact), OpportunityContactRole. For custom objects, the junction record is deleted when
either parent is deleted.

Q: What are Record Types?


Record Types allow different picklist values, page layouts, and business processes for different records of the
same object. Assigned to profiles — each profile can have a default record type per object. Use cases:
Different sales processes, different case types (IT vs HR), different opportunity stages per division.

Q: What are Custom Permissions?


Custom Permissions are feature-level permissions (not object/field level) that you define. Used to control
access to features: buttons, functionality, UI elements. Assigned via Permission Sets. Check in Apex:
[Link]('My_Permission'). Check in LWC: import hasPermission from
'@salesforce/customPermission/My_Permission'.

Q: Difference between Workflow Rule and Flow / Process Builder?


Workflow Rules: Legacy — simple field updates, email alerts, outbound messages, tasks. Single object only,
no complex logic. Salesforce has announced no new features for workflow rules.
Flow: Modern replacement — supports complex logic, multiple objects, user input (Screen Flow), scheduled
paths, subflows, Apex calls. Salesforce is retiring Process Builder — migrate to Flows.

Q: What are Field Sets in Salesforce?


Field Sets are groupings of fields on an object that can be referenced dynamically in Apex or
Visualforce/LWC. They allow admins to add/remove/reorder fields without code changes. In Apex:
[Link] fs = [Link].My_Field_Set; List<[Link]>
members = [Link]();

Q: How many ways can we make a field mandatory?


• Field definition: Check 'Required' checkbox on the field
• Page Layout: Mark field as 'Required' on a specific page layout
• Validation Rule: Add a formula that returns true when field is empty
• Apex Trigger: Use addError() to prevent save when field is empty
• Flow: Before Save record-triggered flow — check and throw fault
NOTE: Making a field required via trigger — yes it's possible using addError() in a before insert/update trigger.

Q: What is the Approval Process?


Approval Processes automate multi-step record approvals. Components: Entry Criteria → Approval Steps
(approver, criteria) → Approval/Rejection Actions. Features: Delegated approvers, queues as approvers,
escalation, email templates. Can be triggered from a button, Apex ([Link]), or
Flow.

Q: What is Email-to-Case?
Email-to-Case automatically creates Case records from incoming customer emails. Setup: Enable Email-to-
Case → Create routing address → Add email to your support mailbox. On-demand Email-to-Case uses
Salesforce email relay. Each email thread links to the case. Can set default values (Status, Priority, Queue
assignment).
Q: What are Entitlements and Milestones?
Entitlements define customers' support rights (e.g., how many cases they can submit, response time SLAs).
Milestones are required steps within an entitlement process with time targets (e.g., 'First Response within 2
hours'). Entitlement processes apply to cases and work orders.

10. Common Scenario-Based Questions


Q: Account has N contacts. Balance field = Saving / No. of Contacts. How to populate?
Use Batch Apex since N is unconfirmed (could be millions). Process accounts in chunks, calculate for each
batch.
global class BalanceBatch implements [Link]<sObject> {
global [Link] start([Link] bc) {
return [Link]('SELECT Id, Saving__c, (SELECT Id FROM Contacts)
FROM Account');
}
global void execute([Link] bc, List<Account> accounts) {
Set<Id> accIds = new Map<Id, Account>(accounts).keySet();
Map<Id, Integer> countMap = new Map<Id, Integer>();
for(AggregateResult ar : [SELECT AccountId, COUNT(Id) cnt FROM Contact WHERE
AccountId IN :accIds GROUP BY AccountId]) {
[Link]((Id)[Link]('AccountId'), (Integer)[Link]('cnt'));
}
List<Contact> toUpdate = new List<Contact>();
for(Account acc : accounts) {
Integer cnt = [Link]([Link]) ? [Link]([Link]) : 0;
if(cnt > 0) {
for(Contact c : [SELECT Id FROM Contact WHERE AccountId = :[Link]]) {
[Link](new Contact(Id = [Link], Balance__c = acc.Saving__c /
cnt));
}
}
}
update toUpdate;
}
global void finish([Link] bc) {}
}

Q: Map<String, Integer> — count accounts by Industry without SOQL aggregation.


public static Map<String, Integer> countAccountsByIndustry(List<Account> accounts) {
Map<String, Integer> result = new Map<String, Integer>();
for(Account acc : accounts) {
String ind = [Link] != null ? [Link] : 'Unknown';
[Link](ind, ([Link](ind) ? [Link](ind) : 0) + 1);
}
return result;
}

Q: Map<String, List<String>> — Account Name to list of Contact Names.


public static Map<String, List<String>> getAccountContacts(List<String> accountNames) {
Map<String, List<String>> result = new Map<String, List<String>>();
for(Account acc : [SELECT Name, (SELECT FirstName, LastName FROM Contacts) FROM
Account WHERE Name IN :accountNames]) {
List<String> names = new List<String>();
for(Contact c : [Link]) [Link]([Link] + ' ' + [Link]);
[Link]([Link], names);
}
return result;
}

Q: Account rating based on number of Opportunities.


trigger AccountRatingTrigger on Opportunity(after insert, after update, after delete,
after undelete) {
Set<Id> accIds = new Set<Id>();
for(Opportunity o : [Link] ? [Link] : [Link]) if([Link] !=
null) [Link]([Link]);
Map<Id, Integer> countMap = new Map<Id, Integer>();
for(AggregateResult ar : [SELECT AccountId, COUNT(Id) cnt FROM Opportunity WHERE
AccountId IN :accIds GROUP BY AccountId]) {
[Link]((Id)[Link]('AccountId'), (Integer)[Link]('cnt'));
}
List<Account> toUpdate = new List<Account>();
for(Id id : accIds) {
Integer cnt = [Link](id) ? [Link](id) : 0;
String rating = cnt < 3 ? 'Cold' : cnt <= 5 ? 'Warm' : 'Hot';
[Link](new Account(Id = id, Rating = rating));
}
update toUpdate;
}

Q: When Contact is created, check if Account exists with name 'ContactLastName-Account'. If


yes, tag contact. Else create Account and tag.
trigger ContactTrigger on Contact(before insert) {
Set<String> accNames = new Set<String>();
for(Contact c : [Link]) if([Link] != null) [Link]([Link] + '-
Account');
Map<String, Account> existingAccs = new Map<String, Account>();
for(Account a : [SELECT Id, Name FROM Account WHERE Name IN :accNames])
[Link]([Link], a);
List<Account> toInsert = new List<Account>();
for(Contact c : [Link]) {
String accName = [Link] + '-Account';
if([Link](accName)) { [Link] =
[Link](accName).Id; }
else { Account newAcc = new Account(Name = accName); [Link](newAcc);
[Link](accName, newAcc); }
}
insert toInsert;
for(Contact c : [Link]) if([Link] == null) [Link] =
[Link]([Link] + '-Account').Id;
}

Q: LWC — display Account and related Contacts on click of a button.


// apex class
@AuraEnabled
public static List<Account> getAccountsWithContacts() {
return [SELECT Id, Name, (SELECT Id, FirstName, LastName, Email FROM Contacts) FROM
Account LIMIT 50];
}
// LWC JS
import getAccountsWithContacts from
'@salesforce/apex/[Link]';
accounts = [];
handleLoad() {
getAccountsWithContacts().then(result => { [Link] = result; }).catch(e =>
[Link](e));
}
// HTML: <lightning-button label='Load' onclick={handleLoad}></lightning-button>
// <template for:each={accounts} for:item='acc'>...

11. JavaScript Concepts for LWC


Q: Difference between var, let, and const?
var: Function-scoped, hoisted to top of function (initialised as undefined), can be redeclared.
let: Block-scoped, hoisted but not initialised (temporal dead zone), cannot be redeclared in same scope.
const: Block-scoped, must be assigned at declaration, cannot be reassigned (but object properties can
change).
Best practice: Always prefer const; use let when reassignment needed; avoid var.

Q: Difference between == and ===?


== (loose equality): Compares values after type coercion. 0 == false is true, '5' == 5 is true.
=== (strict equality): Compares both value AND type. No coercion. '5' === 5 is false. Always prefer ===.

Q: What is hoisting in JavaScript?


Hoisting moves variable and function declarations to the top of their scope at compile time. var declarations
are hoisted and initialised as undefined. Function declarations are hoisted entirely. let/const are hoisted but
not initialised (accessing them before declaration throws ReferenceError — temporal dead zone).

Q: What is a closure in JavaScript?


A closure is a function that retains access to its outer scope's variables even after the outer function has
returned. Common use: factory functions, callbacks with state, module pattern. In LWC, closures are used in
event handlers that capture component properties.

Q: What is event bubbling vs event capture?


Event Capture (Capturing phase): Event travels from root DOWN to target element.
Event Bubbling: Event travels from target element UP to root.
[Link](): Stops the event from propagating further (either direction).
[Link](): Prevents the default browser action.

Q: Null vs Undefined in JavaScript?


undefined: A variable declared but not assigned a value. typeof undefined === 'undefined'.
null: Intentional absence of value — explicitly assigned. typeof null === 'object' (quirk). Use null to indicate 'no
value', undefined is the default for unassigned.

Q: What is 'this' keyword in LWC?


In LWC class methods, 'this' refers to the component instance. Arrow functions inherit 'this' from their
enclosing scope. Regular function declarations inside a class method may lose 'this' context in callbacks —
use arrow functions or .bind(this) to preserve context.
12. Order of Execution in Salesforce
Q: What is the Order of Execution in Salesforce?
When a record is saved, Salesforce executes in this order:
• 1. Load the original record (or initialise for new records)
• 2. Overwrite with new field values from the UI/API
• 3. Execute system validations (required fields, field formats)
• 4. Execute before-save flows
• 5. Execute before triggers
• 6. Run system and custom validation rules
• 7. Execute duplicate rules
• 8. Save the record to the database (not committed yet)
• 9. Execute after triggers
• 10. Execute assignment rules
• 11. Execute auto-response rules
• 12. Execute workflow rules, then re-evaluate validation rules if workflow updates fields
• 13. Execute processes (Process Builder — deprecated)
• 14. Execute escalation rules
• 15. Execute after-save flows
• 16. Execute roll-up summary fields on parent records (triggers parent workflows)
• 17. COMMIT the transaction to the database
• 18. Execute post-commit logic (emails, async processes)

13. Sales Cloud & Service Cloud


Q: What is the Lead Conversion process?
Lead Conversion creates an Account, Contact, and optionally an Opportunity from a Lead record. The Lead is
marked as Converted. Custom field mapping (Lead Field Mapping) can populate fields on the created objects.
Contact and Account creation are mandatory; Opportunity is optional (checkbox 'Do not create an
Opportunity').

Q: What is a Sales Process in Salesforce?


A Sales Process defines the Stage picklist values available for Opportunities of a specific Record Type.
Different products or regions may have different stages. Configured in Setup > Sales Processes, then
assigned to Opportunity Record Types.

Q: What are Assignment Rules?


Assignment Rules (Lead and Case) automatically assign records to users or queues based on criteria. Only
one rule can be active at a time. For Leads: triggered on insert/conversion. For Cases: triggered on insert or
when 'Assign using active assignment rules' is checked on update.

Q: What is Omni-Channel?
Omni-Channel is a Salesforce Service Cloud feature that routes work items (Cases, Chats, etc.) to agents
based on skills, availability, and capacity. Types of routing: Queue-Based, Skills-Based, External Routing.
Agents manage their availability via the Omni-Channel utility.

— End of Guide — Good luck with your interviews!

You might also like