Salesforce Interview Questions That Trip Candidates — Triggers, Governor Limits, Relationships & Packages Explained With Real World Examples
Salesforce Admin & Developer Interview Questions — Clouds, Automation, Relationships & Packages Explained
Sales Cloud vs Service Cloud, Record Types, Governor Limits, Triggers, Packages & More — Real Scenarios for Interviews
| Feature | Sales Cloud | Service Cloud |
|---|---|---|
| Primary Focus | Lead → Opportunity → Revenue | Case → Resolution → Satisfaction |
| Key Objects | Lead, Opportunity, Quote | Case, Entitlement, Work Order |
| Key Features | Forecasting, Territory Mgmt | Omni-Channel, Live Agent, Knowledge |
| Console | Sales Console | Service Console |
| SLA Tracking | ❌ | ✅ Entitlements & Milestones |
| CTI / Telephony | ❌ Limited | ✅ Built-in support |
| Field Service | ❌ | ✅ FSL Add-on |
- ✅Sales Cloud → Manages the revenue pipeline from Lead to closed deal
- ✅Service Cloud → Manages post-sales customer support and case resolution
- ❌Neither is "better" — many companies use both together in the same org
- ✅Both share the same platform, Apex, LWC, and core objects like Account & Contact
Your company uses Sales Cloud — Leads from IndiaMART → Opportunity → Quote → Order. If you added after-sales complaint management with SLA tracking, that would be Service Cloud territory.
- 🔥Both run on the same Salesforce platform and can be in the same org
- 💡Service Cloud adds Case Management, Omni-Channel, Knowledge Base, Entitlements
- 💡Sales Cloud adds Forecasting, Opportunity Splits, Territory Management
- 💡They are licensed separately — you pay for what you need
| Scenario | Use |
|---|---|
| Different fields visible for different teams | Page Layout |
| Different picklist values for different teams | Record Type ✅ |
| Different Sales / Support processes | Record Type ✅ |
| Same data, just different field order | Page Layout |
| A/B user experience on same record type | Page Layout assigned to Profile |
| Multiple business units using same object | Record Type ✅ |
- ✅Page Layout → Field order, Required fields, Related Lists, Button visibility
- ✅Record Type → Picklist values, Page Layout assignment (per profile), Business Process
- ❌Page Layout alone cannot restrict picklist values
- ❌Record Type alone doesn't reorder fields — it assigns a layout
Your Quote object — Domestic and Export quotes may need different currency picklist values and approval processes → that's a Record Type call. But if the Export team just needs a few extra fields visible, a separate Page Layout assigned to their profile is enough.
- 🔥Record Type is the parent, Page Layout is assigned under it per profile
- 💡You need at least 2 Record Types to assign 2 different Page Layouts per profile
- 💡Record Types also drive Business Processes for Opportunity, Case, Lead, Solution
- 💡Default Record Type matters — users without a choice get the default
| Feature | Profile | Role | Record Type | Page Layout |
|---|---|---|---|---|
| Field-level Security | ✅ | ❌ | ❌ | ✅ (visibility only) |
| Picklist Values per group | ❌ | ❌ | ✅ | ❌ |
| Record Visibility | ❌ | ✅ | ❌ | ❌ |
| Page Layout Assignment | ✅ (basic) | ❌ | ✅ (with profile combo) | ✅ |
| Business Process | ❌ | ❌ | ✅ | ❌ |
- ✅Profile → Login access, Object CRUD, FLS, App visibility
- ✅Role → OWD-based record sharing upward in hierarchy
- ❌Role has zero impact on UI or field visibility
- ❌Profile alone can assign a layout but cannot restrict picklist values
If Domestic Sales and Export Sales are on the same profile, you cannot give them different Stage picklist values using Profile. You need a Record Type for that.
- 🔥Profiles are security-layer, Roles are data-access-layer
- 💡Record Types bridge the gap for business process differentiation
- 💡This is a very common interview trap — know the boundary clearly
| Relationship | Cascade Delete | Sharing Inherited | Required on Child | Roll-up Summary |
|---|---|---|---|---|
| Master-Detail | ✅ | ✅ From Parent | ✅ Always | ✅ |
| Lookup | ❌ Optional | ❌ | ❌ Optional | ❌ |
| Hierarchical | ❌ | ❌ | ❌ | ❌ |
| External Lookup | ❌ | ❌ | ❌ | ❌ |
| Indirect Lookup | ❌ | ❌ | ❌ | ❌ |
- ✅Master-Detail → Tight coupling, child cannot exist without parent
- ✅Lookup → Loose coupling, child survives parent deletion (optional clear/restrict)
- ✅Hierarchical → Only for User object (e.g., Manager field)
- ✅External Lookup → Links to External Object via External ID
- ✅Indirect Lookup → Links Standard/Custom object to External Object via unique field
Your Order → Account is likely a Lookup. Your Order Line Items → Order is a Master-Detail (OLI can't exist without an Order).
- 🔥Hierarchical is only for the User object — this is a very common trick question
- 💡External & Indirect Lookups are for Salesforce Connect / External Objects
- 💡A Lookup can be made required to behave almost like MD — but still no roll-up
| Relationship Type | Maximum Allowed |
|---|---|
| Master-Detail | 2 |
| Lookup | 40 (shared with MD in total count) |
| Total Relationship Fields | 40 per object |
- ✅2 MD max → object becomes a junction object when both slots are used
- ✅40 total relationship fields per object (MD + Lookup combined)
- ❌You cannot add a 3rd MD — Salesforce will block it at setup
Junction Object like Campaign Member has MD to both Campaign and Contact — that uses both MD slots. It creates a Many-to-Many relationship.
- 🔥When an object has 2 MDs → it's called a Junction Object (Many-to-Many)
- 💡Roll-up Summary fields are only available on MD parent, not Lookup parent
- 💡Converting MD to Lookup is possible but Roll-up Summaries must be deleted first
| Child Relationship | Count Method |
|---|---|
| Master-Detail Child 1 | ✅ Roll-Up Summary (COUNT) directly on Account |
| Master-Detail Child 2 | ✅ Roll-Up Summary (COUNT) directly on Account |
| Lookup Child | ❌ No native Roll-Up → Use Trigger / Flow / DLRS |
| Approach | Works on Lookup? | No Code? | Best For |
|---|---|---|---|
| Roll-Up Summary | ❌ MD only | ✅ | Master-Detail only |
| Apex Trigger | ✅ | ❌ | Complex logic, insert+delete+undelete |
| Record-Triggered Flow | ✅ | ✅ Mostly | Simple count, no-code teams |
| DLRS (AppExchange) | ✅ | ✅ | Declarative, enterprise orgs |
If Account has a custom Lookup child like Complaint__c, you'd write a trigger on Complaint__c to keep Account.Total_Complaints__c up to date — handling insert, delete, and undelete events.
- 🔥Classic interview trap — show you know Roll-Up doesn't work on Lookup
- 💡DLRS (Declarative Lookup Rollup Summary) is the go-to declarative AppExchange solution — mention it for extra points
- 💡Trigger approach must handle insert + delete + undelete all three events
| Feature | Workflow Rule | Process Builder | Flow |
|---|---|---|---|
| Complexity | Very Simple | Moderate | Full Power |
| Learning Curve | Low | Low-Medium | Medium-High |
| Multi-object update | ❌ | ✅ Limited | ✅ |
| Loops / Collections | ❌ | ❌ | ✅ |
| Before-save logic | ❌ | ❌ | ✅ |
| Callouts / Apex | ❌ | ✅ Apex | ✅ |
| Retirement Status | ⚠️ Retired | ⚠️ Retired | ✅ Active |
- ✅Workflow → Extremely fast to set up, Time-Based Actions were simpler to configure
- ✅Process Builder → Visual click-based UI, easier for non-developers
- ❌Both had severe governor limit issues at scale
- ❌Neither supported loops, complex logic, or subflows
- 🔥Workflow & PB are officially retired — Salesforce wants everything in Flow
- 💡The only relevance today is legacy orgs that haven't migrated yet
- 💡Knowing this shows maturity — never recommend Workflow/PB for new builds
LimitException being the only one that cannot be caught. 🚨| Exception Type | When It Occurs | Catchable? |
|---|---|---|
| DMLException | Insert/Update/Delete fails (validation rule, duplicate) | ✅ |
| QueryException | SOQL returns 0 or 2+ rows when 1 expected | ✅ |
| NullPointerException | Accessing property on a null object | ✅ |
| ListException | Accessing index out of bounds in a List | ✅ |
| LimitException | Governor limit exceeded | ❌ Cannot be caught! |
| CalloutException | HTTP callout fails or times out | ✅ |
| MathException | Division by zero | ✅ |
| TypeException | Invalid type cast | ✅ |
| JSONException | JSON parsing / serialization error | ✅ |
| Custom Exception | User-defined business logic | ✅ |
In your BC integration triggers — a CalloutException needs to be caught so that a failed BC API call doesn't crash the whole Apex transaction and roll back unrelated record updates.
- 🔥LimitException cannot be caught — it's platform-enforced and causes full rollback
- 💡Always catch specific exceptions before generic Exception in try/catch blocks
- 💡Custom exceptions must extend Exception class — mention this clearly
- 💡DMLException has .getDmlMessage(i) and .getDmlStatusCode(i) helper methods
| Error | Limit | Root Cause |
|---|---|---|
| 101 Error | 100 SOQL queries per sync transaction | SOQL query inside a for loop |
| 151 Error | 150 DML statements per sync transaction | DML (insert/update/delete) inside a for loop |
- ✅100 SOQL queries per synchronous transaction
- ✅150 DML statements per synchronous transaction
- ❌These limits cannot be caught — LimitException is thrown and transaction rolls back
- ✅Async (Batch/Queueable/Future) methods get fresh governor limits
Classic mistake — putting a SOQL inside a for loop in a trigger. If 101+ records are processed at once, the query fires 101+ times → 101 error. The fix is always bulkification.
- 🔥Root cause is almost always SOQL or DML inside a for loop
- 💡Fix = bulkify the code (collections + single query outside loop)
- 💡Use
Limits.getQueries()to debug how many queries have been used at runtime
| Step | Action |
|---|---|
| 1 | Identify SOQL or DML inside for loops |
| 2 | Move SOQL outside the loop |
| 3 | Use Collections (List, Set, Map) to gather IDs first |
| 4 | Query once, store in Map, access in loop |
| 5 | Use Limits.getQueries() to verify count at runtime |
- 🔥Always bulkify triggers — assume 200 records minimum as the batch size
- 💡Use
Limits.getQueries()andLimits.getLimitQueries()to debug - 💡Async methods (Future/Queueable) reset governor limits but still can't have SOQL in loops
| Limit | Synchronous | Asynchronous |
|---|---|---|
| SOQL Queries | 100 | 200 |
| DML Statements | 150 | 150 |
| DML Rows | 10,000 | 10,000 |
| SOQL Rows Returned | 50,000 | 50,000 |
| CPU Time | 10,000 ms | 60,000 ms |
| Heap Size | 6 MB | 12 MB |
| Callouts | 100 | 100 |
| Future calls per transaction | 50 | — |
| Queueable jobs enqueued | 50 | — |
| Batch Apex concurrent jobs | 5 | — |
- ✅Every Apex transaction (trigger, class, batch) has its own limit counter
- ✅Batch Apex gets fresh limits per execute() chunk
- ❌Limits reset per transaction — not per record
- ❌
LimitExceptioncannot be caught — transaction rolls back entirely
Your BC integration uses a Queueable to avoid SOQL limit issues from the INR Dated Conversion logic — exactly why async gets more CPU time (60s vs 10s sync).
- 🔥Use
System.Limitsclass to check limits in real-time during debugging - 💡Batch Apex is the go-to solution when processing 10,000+ records
- 💡Always design for bulkification first — assume worst-case record volume
| Scenario | What Happens |
|---|---|
| 2 triggers, both on after insert | Both fire — but order is NOT guaranteed |
| Logic depends on execution order | Can cause bugs and data corruption |
| One trigger + handler class | Full control over execution sequence ✅ |
- 🔥This is a very commonly asked question — answer = technically unlimited, but 1 is the standard
- 💡Always follow the Trigger Handler Framework pattern — single entry point, all logic in handler class
- 💡Frameworks like Kevin O'Hara's Trigger Framework enforce this at org level
| Problem | Real Impact |
|---|---|
| Trigger A sets a field value | Trigger B may overwrite it unpredictably |
| Trigger B depends on Trigger A's output | May fail silently or give wrong result |
| Deployed at different times | Order can change after any metadata deploy |
| Debugging | Near impossible to trace which trigger caused the bug |
- ✅Single trigger gives you explicit control over order of operations
- ✅Makes unit testing cleaner — one entry point for all test scenarios
- ❌Multiple triggers = race condition equivalent in Apex
- ✅Some orgs use Custom Metadata to enable/disable trigger logic without deployment
- 🔥This is a design maturity question — shows you understand the "why" not just "what"
- 💡Mention Kevin O'Hara's Trigger Framework for extra depth
- 💡Custom Metadata toggle pattern = zero-deployment way to enable/disable trigger logic
| Method | Where Enforced | Can Be Bypassed? | Conditional? |
|---|---|---|---|
| Field Definition (checkbox in field setup) | UI + API + Apex | ❌ No — database-level | ❌ No |
| Page Layout (drag to required section) | UI only | ✅ Yes — API/Apex skip it | ❌ No |
| Validation Rule | UI + API + Apex | ❌ Hard to bypass | ✅ Yes |
| Apex Code (programmatic check) | Only when Apex runs | ✅ Depends on code path | ✅ Yes |
- ✅Field-level required = most powerful — enforced at database level, no bypass
- ✅Page Layout required = UI only — integrations and API completely bypass it
- ✅Validation Rule = most flexible — can add conditions ("required only if Status = Active")
- ✅Apex = context-dependent — must be in the execution path to have any effect
Your KYC validation uses Validation Rules — not field-level required — because KYC should be mandatory only when the opportunity reaches a certain stage, not always.
- 🔥Most interviewers want to hear all 4 with the distinction between them
- 💡Field-level required is permanent and affects all interfaces including API
- 💡Validation Rules are the most flexible required enforcement mechanism
| Feature | Managed Package | Unmanaged Package |
|---|---|---|
| Code Visibility | ❌ Hidden (protected) | ✅ Fully visible |
| Upgradeable | ✅ Yes | ❌ No |
| Namespace Required | ✅ Yes | ❌ Optional |
| IP Protection | ✅ Yes | ❌ No |
| Modifiable after install | ❌ Locked | ✅ Full control |
| Best For | ISV Products, AppExchange | Internal templates, one-time deploys |
| Post-install scripts | ✅ Supported | ❌ Not supported |
| License Management | ✅ Yes (via LMA) | ❌ No |
- ✅Managed → What ISVs (AppExchange vendors) use for commercial products
- ✅Unmanaged → What you'd use for sharing a project template internally
- ❌Managed code cannot be modified by the installing org
- ✅Unmanaged code becomes the installing org's own code after install
DLRS (Declarative Lookup Rollup Summary) from AppExchange is a Managed Package — you can't see its Apex code, but you get version upgrades whenever the vendor ships improvements.
- 🔥Managed packages require a Developer Edition org with namespace to create
- 💡Managed packages can have subscriber-specific license types via LMA
- 💡Unmanaged = like a ZIP deploy — no ongoing relationship with the publisher
| Capability | Unmanaged Package | Managed Package |
|---|---|---|
| Sell on AppExchange | ❌ | ✅ |
| Push upgrades to all subscribers | ❌ | ✅ |
| Hide proprietary logic | ❌ | ✅ |
| License Management App (LMA) | ❌ | ✅ |
| Beta version before GA | ❌ | ✅ |
If XYZ Company built a custom Salesforce app for pharma order management and wanted to sell it to 50 other pharma companies — a Managed Package means competitors can't steal the code, and all 50 customers stay on the latest version via push upgrades.
- 🔥For ISVs this is non-negotiable — it's how AppExchange works
- 💡Managed packages enable the License Management App (LMA) for tracking subscribers
- 💡You can have beta versions before going GA — useful for staged rollouts