CompanyLogixal
Focus AreaSalesforce Developer
Questions19+
Topics4
Logixal – Salesforce Developer Interview Questions
What's Covered
Topics covered in this interview.
01SOQL & Data1
02Apex & Triggers7
03Salesforce Core Concepts5
04General & Experience6
All Interview Questions
Every question asked in this interview, listed one by one.
1Explain GetQueryLocator and iterable
2Explain batch apex Syntax
3In chunk if any records will fail how can we store it and send the mail for failed records in batch?
4Can we define the order of execution of records in execute method?
5Best practices for batch apex.
6Can we call future method from batch? What is the use of future method and why you choose future method over batch.
7Explain queueable apex.
8Trigger : Whenever an Account phone is modified then update Contact Mobile field with same.
9How all developers us one sandbox how to manage implementation and deployment?
10Have you worked on Integration? explain what you did.
11Worked in change set deployment? explain.
12How we manage deployments using Copado?
13Scenario based questions on permission set and profile.
14What are the activities you performed on production.
15Have you faced CPU time exception, explain scenario.
16How to get all keys from map?
17What are the collections and its uses?
18How to find duplicate in List<String>.
19Current project related question.
Preparing for a Salesforce developer interview?
Browse more real company interview experiences and hands-on Apex trigger patterns.
Quick answers to key questions
- QueryLocator and Iterable in batch Apex.
Database.getQueryLocatorreturns a SOQL query and can process up to 50 million records, because it skips the 50,000 row limit. AnIterablelets you process a custom collection or complex logic, but the normal row limits apply. - Order of records in execute. The order of batches is not guaranteed, and each
executecall is a separate transaction. You can useORDER BYin the start query, but do not depend on batch order. - Batch best practices. Keep logic out of loops that run SOQL or DML, use a smaller scope when you make callouts, avoid heavy use of
Database.Stateful, handle partial failures, write tests for a full batch, and keep the query selective. - Can we call a future method from a batch? No. A future method cannot be called from a batch or another future method. Use queueable Apex instead. Future methods are best for simple, short background work, while batch is for large volumes of records.
- What is queueable Apex? A class that implements
Queueableand runs when you callSystem.enqueueJob(). It can accept complex types as parameters, returns a job Id that you can monitor, and can chain another job. - Many developers using one sandbox. Give each developer their own developer sandbox or scratch org, keep the code in Git with branches and pull requests, and merge into a shared integration environment. A CI/CD pipeline then validates and deploys it.
- Change sets and Copado. A change set is a bundle of components that you send from one org to another that has a deployment connection. Copado is a DevOps tool that manages user stories, commits changes to Git, promotes them through environments and validates and deploys them with a pipeline.
- CPU time limit exception. It happens when too much work is done in one transaction, such as nested loops, recursion or several triggers and flows running on the same record. Fix it with maps, bulkified code, fewer loops and moving heavy work to async Apex.
- Get all keys from a map. Use
myMap.keySet(), which returns a Set.
Batch with failure handling
Use Database.update(records, false) so one failed record does not roll back the whole chunk, keep the failures in a stateful list, and email them in finish.
global class UpdateAccountsBatch implements Database.Batchable<SObject>, Database.Stateful {
global List<String> errors = new List<String>();
global Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator([SELECT Id, Name FROM Account]);
}
global void execute(Database.BatchableContext bc, List<Account> scope) {
Database.SaveResult[] results = Database.update(scope, false);
for (Integer i = 0; i < results.size(); i++) {
if (!results[i].isSuccess()) {
errors.add(scope[i].Id + ': ' + results[i].getErrors()[0].getMessage());
}
}
}
global void finish(Database.BatchableContext bc) {
if (!errors.isEmpty()) {
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(new String[] { 'admin@example.com' });
mail.setSubject('Batch finished with errors');
mail.setPlainTextBody(String.join(errors, '\n'));
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
}
}Update Contact mobile when the Account phone changes
trigger AccountPhoneTrigger on Account (after update) {
Map<Id, String> newPhones = new Map<Id, String>();
for (Account a : Trigger.new) {
if (a.Phone != Trigger.oldMap.get(a.Id).Phone) {
newPhones.put(a.Id, a.Phone);
}
}
if (newPhones.isEmpty()) return;
List<Contact> toUpdate = new List<Contact>();
for (Contact c : [SELECT Id, AccountId, MobilePhone FROM Contact WHERE AccountId IN :newPhones.keySet()]) {
c.MobilePhone = newPhones.get(c.AccountId);
toUpdate.add(c);
}
update toUpdate;
}Find duplicates in a List of Strings
Set<String> seen = new Set<String>();
Set<String> duplicates = new Set<String>();
for (String s : items) {
if (!seen.add(s)) { // add() returns false if the value is already in the set
duplicates.add(s);
}
}
System.debug(duplicates);