Salesforce interviews test your knowledge of the platform's data model, security, automation, development tools, and integration patterns. This guide covers 50 common questions — with concise answers and examples for both developers and admins.
Quick reference
| Topic | Most asked questions |
|---|---|
| Platform Basics | Objects, fields, relationships, schema |
| Security | Profiles, permission sets, sharing rules, OWD |
| Automation | Flows, process builder, workflow rules, triggers |
| APEX | Classes, triggers, governor limits, async |
| SOQL/SOSL | Queries, relationships, aggregate functions |
| LWC | Components, data binding, events, lifecycle |
| Integrations | REST/SOAP APIs, connected apps, platform events |
| Admin Concepts | Validation rules, page layouts, record types |
| Testing | Test classes, code coverage, @TestSetup |
| Deployment | Change sets, metadata API, Salesforce DX |
Platform Basics
1. What is Salesforce and what are its main clouds?
Salesforce is a cloud-based CRM (Customer Relationship Management) platform. It offers several clouds for different business functions:
| Cloud | Purpose |
|---|---|
| Sales Cloud | Lead, opportunity, account, and contact management |
| Service Cloud | Case management, omni-channel support, knowledge base |
| Marketing Cloud | Email, social, journey builder, advertising |
| Commerce Cloud | B2B and B2C e-commerce |
| Experience Cloud | Customer/partner portals and communities |
| Analytics Cloud (Tableau CRM) | Business intelligence and dashboards |
| Platform (Force.com) | Custom app development |
2. What is the difference between Standard and Custom objects?
Standard objects are provided out-of-the-box by Salesforce (Account, Contact, Lead, Opportunity, Case). They have predefined fields and relationships aligned to common CRM use cases.
Custom objects are created by developers/admins to store business-specific data (e.g., Invoice__c, Project__c). Custom objects end with __c suffix.
// Querying a custom object
List<Invoice__c> invoices = [
SELECT Id, Name, Amount__c, Status__c
FROM Invoice__c
WHERE Status__c = 'Open'
];
3. What are the types of relationships in Salesforce?
| Relationship | Description | Max per object | Cascade delete |
|---|---|---|---|
| Lookup | Loosely coupled, child can exist without parent | 25 | No |
| Master-Detail | Tightly coupled, child deleted with parent | 2 | Yes |
| Many-to-Many | Junction object with two master-detail | — | Yes |
| Hierarchical | Self-referential (User object only) | 1 | No |
| External Lookup | Links to external object | 25 | No |
Master-Detail relationships roll up summary fields (COUNT, SUM, MIN, MAX) to the parent.
4. What is a junction object?
A junction object implements a many-to-many relationship using two Master-Detail relationships:
Account ←── Account_Contact__c ───→ Contact
The junction object (Account_Contact__c) has a Master-Detail field to each parent. Deleting either parent deletes the junction records.
5. What are the Salesforce data types for custom fields?
| Data type | Use case |
|---|---|
| Text | Short strings (up to 255 chars) |
| Text Area (Long) | Up to 131,072 chars |
| Number | Numeric values with decimal places |
| Currency | Monetary values, respects org currency |
| Date / DateTime | Date or date+time values |
| Checkbox | Boolean (true/false) |
| Picklist | Single-select dropdown |
| Multi-Select Picklist | Multiple values, stored as semicolon-separated |
| Formula | Calculated read-only values |
| Roll-Up Summary | Aggregates from child records (Master-Detail only) |
| Lookup Relationship | Reference to another record |
| URL / Email / Phone | Validated format fields |
Security Model
6. What is the Salesforce security model?
Salesforce uses a layered security model:
Organisation-level → Profile/Permission Sets → Object-level → Field-level → Record-level
- Org-level: Login hours, IP restrictions, password policies
- Object-level: CRUD permissions via profiles/permission sets
- Field-level security (FLS): Visible/editable per field per profile
- Record-level: OWD + sharing rules + manual sharing + role hierarchy
7. What is the difference between Profiles and Permission Sets?
| Feature | Profile | Permission Set |
|---|---|---|
| Assignment | One per user (required) | Many per user (additive) |
| Purpose | Baseline permissions | Grant additional access |
| Best practice | Use for minimum access | Use to extend access |
| System permissions | Yes | Yes |
| Object/field permissions | Yes | Yes |
Profiles define the minimum access; Permission Sets add access on top.
8. What is OWD (Organisation-Wide Defaults)?
OWD is the baseline sharing setting for each object. It determines the default level of access users have to records they don't own:
| OWD Setting | Access |
|---|---|
| Private | Only record owner and above in role hierarchy |
| Public Read Only | All users can view, only owner can edit |
| Public Read/Write | All users can view and edit |
| Controlled by Parent | Inherits from master object (detail records) |
OWD is the most restrictive setting; you then open it up with sharing rules and role hierarchy.
9. What are Sharing Rules?
Sharing Rules automatically extend access to records beyond what OWD allows, based on:
- Criteria-based sharing: Share records matching field criteria (e.g., all Leads in a specific region)
- Owner-based sharing: Share records owned by users in a specific group or role
OWD: Private → Sharing Rule: Share all Open Opportunities with Sales Manager role
10. What is Field-Level Security (FLS)?
FLS controls whether a field is visible and/or editable for a profile. It restricts access at the field level even if the user has object access.
FLS affects:
- Page layouts (hidden fields not shown)
- SOQL queries (FLS-enforced via
WITH SECURITY_ENFORCEDorSecurity.stripInaccessible) - Apex code (must explicitly enforce FLS in code)
Automation
11. What are the automation tools in Salesforce, and when to use each?
| Tool | When to use | Code required |
|---|---|---|
| Validation Rules | Prevent invalid data entry | No |
| Workflow Rules | Simple field updates, email alerts, tasks (legacy) | No |
| Process Builder | Multi-step automation with conditions (legacy) | No |
| Flow (Record-Triggered) | Replace Process Builder and Workflow Rules | No |
| Flow (Screen Flow) | Guided user-facing processes | No |
| Apex Trigger | Complex logic, bulk operations, async processing | Yes |
| Scheduled Apex | Time-based batch processing | Yes |
Salesforce recommendation (2024+): Use Flows for declarative automation; Apex for what Flows can't do.
12. What is a Flow and what types exist?
A Flow is a declarative automation tool that can query, update records, interact with users, and call Apex.
| Flow type | Trigger |
|---|---|
| Record-Triggered Flow | When a record is created/updated/deleted |
| Screen Flow | Launched by user interaction (button, component) |
| Scheduled Flow | Runs on a schedule |
| Platform Event-Triggered | When a platform event fires |
| Autolaunched Flow | Invoked from Apex, REST API, or other flows |
13. What is a Validation Rule?
A Validation Rule uses a formula that returns TRUE when the data is invalid, preventing the record from being saved:
// Only allow Status = 'Closed' if CloseDate is in the past
AND(
ISPICKVAL(Status__c, 'Closed'),
CloseDate > TODAY()
)
Error message is shown to the user when the formula evaluates to true.
14. What is the execution order for Salesforce triggers and automation?
When a record is saved, Salesforce processes in this order:
- System validation (required fields, field format)
- Before triggers
- Custom validation rules
- Duplicate rules
- After triggers
- Assignment rules
- Auto-response rules
- Workflow rules (field updates re-trigger before/after triggers once)
- Processes
- Escalation rules
- Record-triggered flows (before save, then after save)
- Entitlement rules
- Roll-up summaries + parent triggers
APEX
15. What is Apex and how is it different from Java?
Apex is Salesforce's proprietary, cloud-hosted programming language. It's syntactically similar to Java but:
- Runs on Salesforce servers (not your infrastructure)
- Has built-in DML (database operations) and SOQL
- Is subject to governor limits to ensure multitenant fairness
- Has no file system access
- Cannot spawn threads (async via
Future,Queueable,Batch)
public class AccountHelper {
public static void updateAccountName(Id accountId, String newName) {
Account acc = [SELECT Id, Name FROM Account WHERE Id = :accountId];
acc.Name = newName;
update acc;
}
}
16. What are Governor Limits in Apex?
Governor limits prevent any single org from monopolising shared Salesforce resources:
| Limit | Per transaction |
|---|---|
| SOQL queries | 100 |
| SOQL query rows returned | 50,000 |
| DML statements | 150 |
| DML rows | 10,000 |
| CPU time | 10,000 ms |
| Heap size | 6 MB (12 MB async) |
| Callouts (HTTP/Web service) | 100 |
| Future method calls | 50 |
| Queueable jobs | 50 |
Key principle: Always write bulkified code — never put SOQL or DML inside loops.
17. What is trigger bulkification and why is it important?
Triggers receive up to 200 records at once. Non-bulkified code hits governor limits:
// BAD — SOQL inside loop, hits 101 query limit
trigger BadTrigger on Contact (before insert) {
for (Contact c : Trigger.new) {
Account acc = [SELECT Id FROM Account WHERE Id = :c.AccountId]; // N queries!
c.Description = acc.Name;
}
}
// GOOD — Bulkified
trigger GoodTrigger on Contact (before insert) {
Set<Id> accountIds = new Set<Id>();
for (Contact c : Trigger.new) {
accountIds.add(c.AccountId);
}
Map<Id, Account> accounts = new Map<Id, Account>(
[SELECT Id, Name FROM Account WHERE Id IN :accountIds]
);
for (Contact c : Trigger.new) {
c.Description = accounts.get(c.AccountId)?.Name;
}
}
18. What are the different async Apex patterns?
| Pattern | Use case | When runs |
|---|---|---|
@future |
Simple async callouts, mixed DML | After current transaction |
Queueable |
Chaining jobs, pass objects | After current transaction |
Batch Apex |
Process millions of records | Chunked (200 records/batch) |
Scheduled Apex |
Time-based execution | Cron schedule |
// Batch Apex example
public class AccountBatch implements Database.Batchable<SObject> {
public Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator('SELECT Id, Name FROM Account');
}
public void execute(Database.BatchableContext bc, List<Account> scope) {
// Process up to 200 records per chunk
for (Account acc : scope) {
acc.Description = 'Processed';
}
update scope;
}
public void finish(Database.BatchableContext bc) {
// Send email or trigger next job
}
}
// Run: Database.executeBatch(new AccountBatch(), 200);
19. What is a Trigger Handler pattern and why use it?
The Trigger Handler pattern keeps trigger logic out of the trigger file, enabling:
- Single trigger per object
- Easier unit testing
- Context-aware dispatch
// Trigger file (thin)
trigger AccountTrigger on Account (before insert, before update, after insert, after update) {
AccountTriggerHandler handler = new AccountTriggerHandler();
if (Trigger.isBefore) {
if (Trigger.isInsert) handler.beforeInsert(Trigger.new);
if (Trigger.isUpdate) handler.beforeUpdate(Trigger.new, Trigger.oldMap);
}
if (Trigger.isAfter) {
if (Trigger.isInsert) handler.afterInsert(Trigger.new, Trigger.newMap);
}
}
// Handler class
public class AccountTriggerHandler {
public void beforeInsert(List<Account> newAccounts) {
for (Account acc : newAccounts) {
acc.Description = 'Created via trigger';
}
}
public void beforeUpdate(List<Account> newAccounts, Map<Id, Account> oldMap) {
// Compare new vs old values
}
public void afterInsert(List<Account> newAccounts, Map<Id, Account> newMap) {
// Async callouts, platform events
}
}
20. What is Database.SaveResult and when to use Database.insert vs insert?
| Method | On error |
|---|---|
insert records |
Rolls back all records if any fail |
Database.insert(records, false) |
Partial success — saves valid records, logs errors |
List<Account> accounts = new List<Account>{
new Account(Name = 'Valid'),
new Account() // Missing required Name field
};
List<Database.SaveResult> results = Database.insert(accounts, false);
for (Database.SaveResult sr : results) {
if (!sr.isSuccess()) {
for (Database.Error err : sr.getErrors()) {
System.debug('Error: ' + err.getMessage());
}
}
}
SOQL & SOSL
21. What is SOQL and how does it differ from SQL?
SOQL (Salesforce Object Query Language) queries Salesforce data:
| Feature | SOQL | SQL |
|---|---|---|
| JOIN | Relationship traversal (Account.Name) |
Explicit JOIN keyword |
| DML in queries | Not supported | Subquery updates possible |
SELECT * |
Not supported (must list fields) | Supported |
| Semi-joins | WHERE Id IN (SELECT ...) |
WHERE Id IN (SELECT ...) |
| Subqueries | Only in FROM clause for child objects | Full subquery support |
| Aggregate functions | COUNT, SUM, MIN, MAX, AVG | Full aggregate support |
-- Parent-to-child (subquery)
SELECT Id, Name, (SELECT Id, LastName FROM Contacts) FROM Account
-- Child-to-parent (dot notation)
SELECT Id, LastName, Account.Name, Account.BillingCity FROM Contact WHERE Account.Industry = 'Technology'
-- Aggregate
SELECT StageName, COUNT(Id) cnt, SUM(Amount) total FROM Opportunity GROUP BY StageName
22. What is the difference between SOQL and SOSL?
| Feature | SOQL | SOSL |
|---|---|---|
| Searches | One object at a time | Multiple objects at once |
| Performance | Faster for known object | Better for text search across objects |
| Syntax | SELECT … FROM Object WHERE … |
FIND 'term' IN ALL FIELDS RETURNING … |
| Returns | List<SObject> |
List<List<SObject>> |
| Use case | Precise record retrieval | Full-text search |
// SOSL example
List<List<SObject>> results = [
FIND 'Salesforce' IN ALL FIELDS
RETURNING Account(Id, Name), Contact(Id, FirstName, LastName)
];
List<Account> accounts = (List<Account>) results[0];
List<Contact> contacts = (List<Contact>) results[1];
23. What are aggregate functions in SOQL?
-- COUNT with GROUP BY
SELECT StageName, COUNT(Id) numOpps, SUM(Amount) totalAmount
FROM Opportunity
WHERE IsClosed = false
GROUP BY StageName
HAVING COUNT(Id) > 5
ORDER BY SUM(Amount) DESC
LIMIT 10
Aggregate results are returned as AggregateResult[]:
List<AggregateResult> results = [
SELECT StageName, COUNT(Id) cnt FROM Opportunity GROUP BY StageName
];
for (AggregateResult ar : results) {
System.debug(ar.get('StageName') + ': ' + ar.get('cnt'));
}
24. What are SOQL semi-joins and anti-joins?
-- Semi-join: Contacts who have an open case
SELECT Id, Name FROM Contact
WHERE Id IN (SELECT ContactId FROM Case WHERE Status != 'Closed')
-- Anti-join: Contacts with NO open case
SELECT Id, Name FROM Contact
WHERE Id NOT IN (SELECT ContactId FROM Case WHERE Status != 'Closed')
25. How do you avoid SOQL injection in dynamic SOQL?
// VULNERABLE — never concatenate user input
String query = 'SELECT Id FROM Account WHERE Name = \'' + userInput + '\'';
// SAFE — use bind variables
String safeName = userInput;
List<Account> accs = Database.query('SELECT Id FROM Account WHERE Name = :safeName');
// SAFE — use String.escapeSingleQuotes() if bind var not possible
String escaped = String.escapeSingleQuotes(userInput);
Lightning Web Components (LWC)
26. What is LWC and how does it differ from Aura?
LWC (Lightning Web Components) is Salesforce's modern UI framework based on Web Standards (Shadow DOM, Custom Elements, ES modules). Aura is the older proprietary framework.
| Feature | LWC | Aura |
|---|---|---|
| Technology | Web Standards | Proprietary framework |
| Performance | Faster (native browser support) | Slower |
| JS syntax | Modern ES6+ | Custom Aura JS |
| Interop | Can use Aura components | Can host LWC |
| File structure | HTML + JS + CSS + XML | Multiple helper files |
| Testing | Jest | Jasmine (manual DOM) |
27. What are the decorators in LWC?
| Decorator | Purpose |
|---|---|
@api |
Exposes property/method to parent component |
@track |
Reactive private property (object/array mutation tracking) |
@wire |
Wires Salesforce data services or Apex methods |
import { LightningElement, api, track, wire } from 'lwc';
import getContacts from '@salesforce/apex/ContactController.getContacts';
import { getRecord } from 'lightning/uiRecordApi';
export default class ContactList extends LightningElement {
@api recordId; // Passed from parent or record page context
@track contacts = []; // Private reactive state
@wire(getRecord, { recordId: '$recordId', fields: ['Account.Name'] })
account;
@wire(getContacts, { accountId: '$recordId' })
wiredContacts({ error, data }) {
if (data) this.contacts = data;
if (error) console.error(error);
}
}
28. How does data binding work in LWC?
LWC uses one-way data binding from parent to child. For child-to-parent communication, use events.
<!-- parent.html -->
<template>
<c-child name={parentName} ongreet={handleGreet}></c-child>
</template>
// child.js
import { LightningElement, api } from 'lwc';
export default class Child extends LightningElement {
@api name;
handleClick() {
this.dispatchEvent(new CustomEvent('greet', { detail: this.name }));
}
}
29. What are the LWC lifecycle hooks?
| Hook | When it fires |
|---|---|
constructor() |
Component instance created |
connectedCallback() |
Component inserted into DOM |
renderedCallback() |
After every render (use carefully) |
disconnectedCallback() |
Component removed from DOM |
errorCallback(error, stack) |
When child throws an error |
connectedCallback() {
// Safe to access this.template here
// DOM not yet rendered
}
renderedCallback() {
// DOM is rendered — access elements with this.template.querySelector
// Guard against infinite loops!
if (!this.initialized) {
this.initialized = true;
this.template.querySelector('input')?.focus();
}
}
30. How do you call Apex from LWC?
Two patterns:
// 1. @wire — automatic, reactive
@wire(getContacts, { accountId: '$recordId' })
contacts;
// 2. Imperative — on-demand (button click, conditional)
import getContacts from '@salesforce/apex/ContactController.getContacts';
async handleSearch() {
try {
this.contacts = await getContacts({ accountId: this.recordId });
} catch (error) {
this.error = error;
}
}
Integrations
31. What are the Salesforce integration patterns?
| Pattern | Description | Tools |
|---|---|---|
| Request-Reply | Synchronous callout | REST/SOAP API callout from Apex |
| Fire and Forget | Async, no response needed | Platform Events, Outbound Messages |
| Batch Data Sync | Scheduled bulk data transfer | Bulk API 2.0, Scheduled Apex |
| Remote Call-In | External system calls Salesforce | REST API, Streaming API |
| UI Update | Real-time UI from events | Streaming API, Platform Events + LWC |
32. What is the Salesforce REST API?
Salesforce exposes a REST API for CRUD operations on records:
-- Query
GET /services/data/v59.0/query?q=SELECT+Id,Name+FROM+Account+LIMIT+10
Authorization: Bearer {access_token}
-- Create
POST /services/data/v59.0/sobjects/Account/
Content-Type: application/json
{ "Name": "New Account", "Industry": "Technology" }
-- Update
PATCH /services/data/v59.0/sobjects/Account/{recordId}
{ "Industry": "Finance" }
-- Delete
DELETE /services/data/v59.0/sobjects/Account/{recordId}
33. What are Platform Events?
Platform Events are a publish-subscribe messaging system within Salesforce:
// Publish
Order_Event__e event = new Order_Event__e(
Order_Id__c = orderId,
Status__c = 'Shipped'
);
Database.SaveResult sr = EventBus.publish(event);
// Subscribe via Trigger
trigger OrderEventTrigger on Order_Event__e (after insert) {
for (Order_Event__e e : Trigger.new) {
// Process event
}
}
Platform Events decouple systems and survive transaction rollbacks.
34. What is the Bulk API and when to use it?
Bulk API 2.0 is designed for loading/extracting millions of records asynchronously. It processes records in batches of up to 10,000 and is the recommended tool for:
- Initial data migrations
- Regular large-scale data syncs
- Mass updates/deletes
Compared to REST API (which handles up to 200 records per composite request), Bulk API handles millions with much higher governor limits.
35. What is a Connected App?
A Connected App defines an external application's OAuth integration with Salesforce. It provides:
- Client ID and Client Secret for OAuth flows
- Scope restrictions (what data the external app can access)
- IP whitelisting and session policies
OAuth flows:
- Web Server Flow: Server-side apps (most secure)
- User-Agent Flow: Client-side apps
- JWT Bearer Token Flow: Server-to-server (no user login required)
- Username-Password Flow: Legacy, avoid in production
Testing
36. Why is test coverage important in Salesforce?
Salesforce requires 75% code coverage to deploy Apex to production. However, tests exist to:
- Verify business logic correctness
- Prevent regressions
- Meet platform deployment requirements
Best practices:
- Test positive paths, negative paths, and bulk scenarios (200 records)
- Use
@TestSetupfor shared test data creation - Never use
SeeAllData=trueunless absolutely necessary
37. What is @TestSetup and why use it?
@TestSetup creates test data once per test class, shared across all test methods (each method gets its own rollback):
@isTest
public class AccountTriggerTest {
@TestSetup
static void setup() {
// Runs once — data visible to all test methods
Account acc = new Account(Name = 'Test Account');
insert acc;
}
@isTest
static void testBeforeInsert() {
Account acc = [SELECT Id, Description FROM Account WHERE Name = 'Test Account'];
System.assertEquals('Created via trigger', acc.Description, 'Description should be set');
}
@isTest
static void testBulkInsert() {
List<Contact> contacts = new List<Contact>();
Account acc = [SELECT Id FROM Account LIMIT 1];
for (Integer i = 0; i < 200; i++) {
contacts.add(new Contact(LastName = 'Test' + i, AccountId = acc.Id));
}
Test.startTest();
insert contacts;
Test.stopTest();
System.assertEquals(200, [SELECT COUNT() FROM Contact WHERE AccountId = :acc.Id]);
}
}
38. What is Test.startTest() / Test.stopTest()?
Test.startTest()resets governor limits for the code under testTest.stopTest()flushes all async operations (future methods, batch jobs) and waits for completion
@isTest
static void testAsyncMethod() {
Account acc = new Account(Name = 'Async Test');
insert acc;
Test.startTest();
MyAsyncClass.processAccount(acc.Id); // @future method
Test.stopTest(); // Future method runs synchronously here
// Assert after stopTest
Account updated = [SELECT Id, Description FROM Account WHERE Id = :acc.Id];
System.assertNotEquals(null, updated.Description);
}
39. How do you mock callouts in Apex tests?
You cannot make real HTTP callouts in tests. Use HttpCalloutMock:
// Mock implementation
@isTest
global class MockHttpResponse implements HttpCalloutMock {
global HTTPResponse respond(HTTPRequest req) {
HTTPResponse res = new HTTPResponse();
res.setHeader('Content-Type', 'application/json');
res.setBody('{"status": "success"}');
res.setStatusCode(200);
return res;
}
}
// Test using mock
@isTest
static void testCallout() {
Test.setMock(HttpCalloutMock.class, new MockHttpResponse());
Test.startTest();
String result = MyCalloutClass.fetchData();
Test.stopTest();
System.assertEquals('success', result);
}
Admin Concepts
40. What is the difference between a Role and a Profile?
| Feature | Profile | Role |
|---|---|---|
| Controls | Object/field permissions, page layouts, app access | Record visibility via role hierarchy |
| Required | Yes (one per user) | No (optional) |
| Affects | What user can do | What records user can see |
Roles build a hierarchy — users can see records owned by users below them in the hierarchy (when OWD is Private and hierarchy grants access is enabled).
41. What is Record Type?
Record Types allow different page layouts, picklist values, and business processes for the same object based on user profile:
Case object:
├── Technical Support (record type) → Technical Layout, Priority picklist: High/Medium/Low
└── Billing Dispute (record type) → Billing Layout, Priority picklist: Urgent/Normal
Users see only the picklist values assigned to their record type.
42. What are Formula Fields vs Roll-Up Summary Fields?
| Feature | Formula Field | Roll-Up Summary |
|---|---|---|
| Object | Parent or child | Parent only (Master-Detail) |
| Data source | Other fields on same record | Aggregates from child records |
| Functions | Date, text, math, logic | COUNT, SUM, MIN, MAX |
| Real-time | Yes | Yes (may be deferred for large datasets) |
| DML | Read-only | Read-only |
Formula: Discount_Amount__c = Amount * Discount_Percent__c / 100
Roll-Up: Total_Cases__c = COUNT of Cases on Account
43. What are Process Builder and Workflow Rules (legacy)?
Both are legacy automation tools being replaced by Flows:
- Workflow Rules: Fire on record save → field update, email alert, task, outbound message
- Process Builder: Multi-criteria, multi-action, can create/update related records, call Flows
Salesforce recommends migrating both to Record-Triggered Flows for new automation.
Deployment
44. What are Change Sets?
Change Sets are a GUI-based deployment method between connected Salesforce orgs (e.g., Sandbox → Production). They:
- Contain metadata (Apex, objects, page layouts, flows, etc.)
- Require the orgs to be in the same Salesforce organisation environment
- Are one-directional (Outbound from source, Inbound in target)
- Do not support automated pipelines
45. What is Salesforce DX (SFDX)?
Salesforce DX is the modern developer-first approach using:
- Scratch Orgs: Short-lived disposable orgs for development
- Source-format metadata: Version-controlled in Git
- sf CLI: Command-line interface for all operations
- Unlocked Packages: Modular, versioned deployments
# Authenticate to org
sf org login web --alias myOrg
# Create scratch org
sf org create scratch --definition-file config/project-scratch-def.json --alias dev
# Push source to scratch org
sf project deploy start
# Pull changes from scratch org
sf project retrieve start
# Run tests
sf apex run test --test-level RunLocalTests --result-format human
46. What is a Metadata API deployment?
Metadata API is used for programmatic deployments via:
- Ant Migration Tool (legacy)
- sf CLI (
sf project deploy start) - CI/CD pipelines (GitHub Actions + sf CLI)
# GitHub Actions example
- name: Deploy to Production
run: |
sf project deploy start \
--source-dir force-app \
--target-org production \
--test-level RunLocalTests
Advanced Topics
47. What is Mixed DML Exception and how to fix it?
Mixed DML Exception occurs when you try to insert/update setup objects (User, UserRole, Profile, PermissionSet) and non-setup objects in the same transaction:
// THROWS MixedDmlException
insert new Account(Name = 'Test');
insert new User(Username = 'test@example.com', ...);
// FIX — Use @future to separate transactions
public class UserHelper {
@future
public static void createUser(String username) {
insert new User(Username = username, ...);
}
}
// Then: UserHelper.createUser('test@example.com');
48. What is with sharing vs without sharing in Apex?
| Keyword | Sharing rules enforced? | Use when |
|---|---|---|
with sharing |
Yes | User-facing logic (default recommended) |
without sharing |
No | Admin/system-level operations, batch jobs |
inherited sharing |
Inherits from calling class | Utility classes |
public with sharing class ContactHelper {
// Users see only contacts they have access to
public static List<Contact> getContacts() {
return [SELECT Id, Name FROM Contact];
}
}
49. What are Custom Metadata Types vs Custom Settings?
| Feature | Custom Metadata Types | Custom Settings |
|---|---|---|
| Deployable | Yes (included in metadata) | Hierarchy: partially; List: no |
| Queryable in SOQL | Yes | Yes |
| SOQL limits apply | No (free query) | Yes for Hierarchy, No for List via cached access |
| Use case | App configuration, mapping tables | User/profile-specific settings |
// Custom Metadata — no governor limit
List<My_Config__mdt> configs = [SELECT Value__c FROM My_Config__mdt];
// Custom Setting — cached access (no SOQL limit)
My_Setting__c setting = My_Setting__c.getOrgDefaults();
50. What is the difference between Queueable and Batch Apex?
| Feature | Queueable | Batch Apex |
|---|---|---|
| Chaining | Yes (System.enqueueJob() in execute) |
Limited |
| Record volume | No built-in chunking | Chunked automatically (up to 2000 records/chunk) |
| Monitoring | Job ID | AsyncApexJob |
| Best for | Sequential async jobs, passing objects | Processing millions of records |
| Callouts allowed | Yes | Only in start() unless Database.AllowsCallouts |
public class ChainedJob implements Queueable {
private Integer step;
public ChainedJob(Integer step) { this.step = step; }
public void execute(QueueableContext ctx) {
// Do work for this step
System.debug('Running step: ' + step);
if (step < 5) {
System.enqueueJob(new ChainedJob(step + 1)); // Chain next job
}
}
}
// Start: System.enqueueJob(new ChainedJob(1));
Common mistakes
| Mistake | Problem | Fix |
|---|---|---|
| SOQL inside loop | Governor limit (101 query limit) | Collect IDs, query outside loop |
| DML inside loop | Governor limit (151 DML limit) | Collect records, DML outside loop |
No with sharing |
Users see all records | Use with sharing by default |
SeeAllData=true in tests |
Tests depend on org data | Create test data explicitly |
| Hard-coding IDs | Breaks between orgs | Use Custom Metadata or SOQL |
| No error handling in triggers | Silent failures | Use try/catch, addError() |
| Ignoring FLS | Security vulnerability | Use WITH SECURITY_ENFORCED or stripInaccessible |
| One trigger per object | Multiple triggers, order unpredictable | Single trigger + handler pattern |
Salesforce developer vs admin roles
| Skill | Admin | Developer |
|---|---|---|
| Flows | Yes | Yes |
| APEX | No | Yes |
| LWC | No | Yes |
| SOQL | Basic | Advanced |
| API integrations | No | Yes |
| Declarative tools | Primary | Secondary |
| Certifications | Admin, Advanced Admin | Platform Dev I/II |
Frequently asked questions
Q: What Salesforce certifications should I get?
Start with Salesforce Certified Administrator (foundation for all roles). Developers should add Platform Developer I (Apex, SOQL, LWC basics) and then Platform Developer II (advanced patterns). Architects pursue the Architect Journey certifications.
Q: What is the difference between insert and upsert in Apex?insert always creates a new record. upsert creates or updates based on an external ID field (or the record's Salesforce ID). Use upsert for data migrations where you want idempotent operations.
Q: Can you call a trigger from a Flow?
No — but when a Flow performs DML (creates/updates a record), triggers on that object fire normally. Flows and triggers can indirectly interact through the standard save order.
Q: What is the difference between a List View and a Report?
List Views show records from a single object with basic filters. Reports can span multiple objects (with relationships), support grouping, summaries, charts, and can be scheduled/emailed. Reports are more powerful for analytics.
Q: How do you handle errors in LWC?
Use try/catch in imperative Apex calls, and check the error property from @wire. Show errors with lightning-card or lightning-formatted-text:
@wire(getContacts, { accountId: '$recordId' })
wiredContacts({ error, data }) {
if (data) {
this.contacts = data;
this.error = undefined;
} else if (error) {
this.error = error.body?.message || 'Unknown error';
this.contacts = undefined;
}
}
Q: What is the Salesforce Well-Architected Framework?
Salesforce's equivalent of cloud architecture best practices. It covers four pillars: Trusted (security, compliance), Easy (user adoption, usability), Adaptable (extensibility, scalability), and Compliant (data governance, regulations).