Update : ✨ Agentforce Batch - Starts 23rd Oct 2025, 8 AM IST || ✨ Admin & Dev Batch - Starts 22nd Oct 2025, 6 PM IST | Contact us for more info +91 - 709 7777 111
Welcome to SfdcIndia

Development Scenario Based Interview Questions

  • How would you assign a lead to a specific queue based on the lead source being "Web"? +

    Use an If Condition: Check if the lead source equals "Web" before assigning the lead to the queue.

    Example:

               if (lead.LeadSource == 'Web') {
                lead.OwnerId = queueId;
                update lead;
                }

    • Purpose: Directs the lead to the appropriate owner based on its source. 

  • How would you prevent null pointer exceptions when accessing a field that might be null? +

    • Use an If Condition: Check if the field is not null before accessing it.

    Example:

                    if (contact.Email != null) {
                     System.debug('Email: ' + contact.Email);
                     }

    • Purpose: Avoids runtime errors by ensuring the field is not null before use.

  • How would you execute different logic for an opportunity based on its record type? +

    • Use an If Condition: Check the record type before executing the corresponding logic.

    Example:

                if (opp.RecordType.Name == 'Enterprise') {
                // Logic for Enterprise
                 } else if (opp.RecordType.Name == 'SMB') {
                // Logic for SMB
                 }

    • Purpose: Tailors the logic based on the specific record type of the opportunity.

  • How would you prevent an update to a case if its status is "Closed"? +

    • Use an If Condition: Check the case status before allowing updates.

    Example:

                 if (caseRecord.Status != 'Closed') {
                  update caseRecord;
                   } 

    • Purpose: Ensures that closed cases are not inadvertently updated.
     

  • How would you send an email alert only if a contact’s last activity date is older than 30 days? +

    Use an If Condition: Compare the last activity date with the current date before sending the email.

    Example:

                if (contact.LastActivityDate < Date.today().addDays(-30)) {
                 // Send email
                  }

    • Purpose: Ensures emails are sent only when the condition is met, avoiding unnecessary alerts.

  • How would you process a list of accounts but skip those that have no related opportunities? +

    • Use an If Condition Within a Loop: Check if there are related opportunities before processing the account.

    Example:

                 for (Account acc : accounts) {
                  if (acc.Opportunities.size() > 0) {
                  // Process account
                    }
                  }

    • Purpose: Optimises processing by skipping irrelevant records. 

  • How would you loop through a list of contacts and update the "Email Opt-Out" field to true for each contact? +

    • Use a for Loop: Iterate through the list of contacts and update the field within the loop.

    Example:
                 List<Contact> contacts = [SELECT Id, Email_Opt_Out__c FROM Contact];
                 for (Contact c : contacts) {
                 c.Email_Opt_Out__c = true;
                 }
                update contacts;

    • Purpose: Efficiently processes each record in the list and updates the specified field.

  • How would you loop through a list of opportunities to calculate the total amount for a specific account? +

    Use a for Loop: Sum the amounts of all opportunities related to the account within the loop.

    Example:
                 Decimal totalAmount = 0;
                 List<Opportunity> opps = [SELECT Amount FROM Opportunity WHERE AccountId = :accountId];
                 for (Opportunity opp : opps) {
                 totalAmount += opp.Amount;
                  }

    • Purpose: Aggregates data across multiple records to provide a cumulative value. 

  • How would you use nested loops to iterate over accounts and their related contacts? +

    • Use Nested for Loops: Loop through accounts and then loop through each account’s contacts.

    Example:
                List<Account> accounts = [SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account];
                for (Account acc : accounts) {
                     for (Contact con : acc.Contacts) {
                System.debug('Account: ' + acc.Name + ', Contact: ' + con.Name);
                        }
                 }

    • Purpose: Efficiently processes parent-child data structures in Salesforce.

  • How would you skip certain records during iteration, such as skipping accounts that have no contacts? +

    Use a Conditional continue Statement: Use continue to skip to the next iteration if the condition is met.

    Example:
                 for (Account acc : accounts) {
                    if (acc.Contacts.isEmpty()) {
                       continue;
                     }
               // Process accounts with contacts
                }

    • Purpose: Optimizes loop processing by skipping irrelevant records. 
     

  • How would you skip certain records during iteration, such as skipping accounts that have no contacts? +

    • Use a Conditional continue Statement: Use continue to skip to the next iteration if the condition is met.

    Example:
             for (Account acc : accounts) {
             if (acc.Contacts.isEmpty()) {
              continue;
                 }
            // Process accounts with contacts
              }

    • Purpose: Optimizes loop processing by skipping irrelevant records.
     

  • How would you exit a loop early if a certain condition is met, such as finding the first opportunity that exceeds a certain amount? +

    • Use a break Statement: Exit the loop when the condition is satisfied.

    Example:
                 for (Opportunity opp : opps) {
                 if (opp.Amount > 100000) {
                 System.debug('High-value opportunity found: ' + opp.Name);
                 break;
                 }
                 }

    • Purpose: Improves efficiency by stopping further iterations once the desired condition is met. 

  • How would you loop through a Set of unique product codes and perform an operation for each one? +

    • Use a for Loop with Set: Loop through the Set to process each unique value.

    Example:
                Set<String> productCodes = new Set<String>{'P001', 'P002', 'P003'};
                for (String code : productCodes) {
               System.debug('Processing product code: ' + code);
                }

    • Purpose: Handles collections of unique values effectively.
     

  • How would you iterate through a Map to access both keys (e.g., account IDs) and values (e.g., account names)? +

    • Use a for Loop with Map Entries: Loop through the Map using Map.Entry.

    Example:
                  Map<Id, String> accountMap = new Map<Id, String>{};
                  for (Map<Id, String>.Entry entry : accountMap.entrySet()) {
                  System.debug('Account ID: ' + entry.getKey() + ', Account Name: ' +
                  entry.getValue());
                   }

    • Purpose: Allows access to both the key and value in a Map.
     

  • How would you use a loop to process records in batches, ensuring you stay within Salesforce governor limits? +

    • Use a for Loop with Subsets: Break the list into smaller batches and process each separately. 

    Example:
                  Integer batchSize = 100;
                  for (Integer i = 0; i < allRecords.size(); i += batchSize) {
                  List<SObject> batch = allRecords.subList(i, Math.min(i +
                  batchSize, allRecords.size()));
                  // Process each batch
                   }

    • Purpose: Ensures efficient processing without exceeding Salesforce governor limits.

  • How would you use an array to store multiple account names and then iterate over them to print each name? +

    • Use an Array: Declare an array of strings to store the account names.

    Example:
                  String[] accountNames = new String[] {'Acme Corp', 'Global Media', 'Tech Solutions'};
                  for (Integer i = 0; i < accountNames.size(); i++) {
                  System.debug('Account Name: ' + accountNames[i]);
                  }

    • Purpose: Arrays are used to store multiple values of the same data type and iterate through them for processing.

  • How would you dynamically add contact email addresses to an array as they are retrieved from a query? +

    • Use ArrayList: Use a dynamic array (List) to add email addresses as they are retrieved.

    Example:
                String[] emailAddresses = new String[]{};
                for (Contact c : [SELECT Email FROM Contact WHERE AccountId = :accountId])
                {
                emailAddresses.add(c.Email);
                } 

    • Purpose: Dynamically build an array when the number of elements isn’t known beforehand.

  • How would you remove specific elements from an array, such as removing all null values from an array of integers? +

    • Filter Array: Iterate through the array and remove elements that meet the criteria.

    Example:
                Integer[] numbers = new Integer[]{1, null, 2, null, 3};
                numbers.removeAll(new List<Integer>{null});

    • Purpose: Clean up an array by removing unwanted or null elements.

  • How would you sort an array of opportunity amounts in descending order? +

    • Use Sorting: Utilize the sort() method with a custom comparator for descending order.

    Example:
                  Decimal[] amounts = new Decimal[]{1000, 5000, 2000};
                  amounts.sort();
                  amounts.reverse();
                  System.debug(amounts);

    • Purpose: Order array elements to meet specific sorting requirements.

  • How would you combine two arrays of account names into a single array? +

    • Use addAll: Combine two arrays using the addAll() method.

    Example:
                 String[] array1 = new String[]{'Acme', 'Global Media'}; 
                 String[] array2 = new String[]{'Tech Solutions', 'Innovate LLC’};
                 array1.addAll(array2);
                 System.debug(array1);

    • Purpose: Merge multiple arrays into one for combined processing.
     

  • How would you check if a specific account name exists in an array of account names? +

    • Use contains: Check for the presence of a value in the array using contains().

    Example:
                 String[] accountNames = new String[]{'Acme Corp', 'Global Media', 'Tech Solutions'};
                 if (accountNames.contains('Acme Corp')) {
                 System.debug('Acme Corp exists in the array');
                  }

    • Purpose: Determine whether a specific value is present in an array.
     

  • How would you convert a List of opportunity names to an array for further processing? +

    • Use toArray: Convert a List to an array using the toArray() method.

    Example:
               List<String> opportunityNames = new List<String>{'Opportunity A', 'Opportunity B'};
               String[] oppArray = opportunityNames.toArray(new String[]{});

    • Purpose: Utilize array operations on data initially stored in a List.
     

  • How would you use a List to store the results of a SOQL query that retrieves all contacts related to a specific account? +

    • Use a List: Store the query results in a List<Contact> and then process them. 

    Example:
                 List<Contact> contacts = [SELECT Id, Name, Email FROM Contact WHERE
                 AccountId = :accountId];
                 for (Contact c : contacts) {
                 System.debug('Contact Name: ' + c.Name);
                  }

    • Purpose: Lists are used to hold multiple records retrieved from a SOQL query for further processing.
     

  • How would you dynamically add opportunity names to a List during processing? +

    • Use add Method: Use the add() method to dynamically add elements to the List.

    Example:
                List<String> oppNames = new List<String>();
                for (Opportunity opp : [SELECT Name FROM Opportunity WHERE Amount > 50000])
                 {
                 oppNames.add(opp.Name);
                   }

    • Purpose: Dynamically build a List when the number of elements is not predetermined.

  • How would you remove all tasks with a "Completed" status from a List of tasks? +

    • Use a Loop and remove Method: Iterate through the List and remove items that meet the condition.

    Example:
               List<Task> tasks = [SELECT Id, Status FROM Task WHERE Status = 'Completed'];
               for (Integer i = tasks.size() - 1; i >= 0; i--) {
               if (tasks[i].Status == 'Completed') {
               tasks.remove(i);
                }} 

    • Purpose: Clean up a List by removing unwanted or completed tasks.

  • How would you check if a List of strings contains a specific account name? +

    Use contains Method: Use the contains() method to check for the presence of an element.

    Example:

              List<String> accNames = new List<String>{'Acme Corp','Global Media',‘Tech Solutions'};

              if (accNames.contains('Acme Corp')) {

              System.debug('Acme Corp exists in the list.');

               }

    Purpose: Quickly check if a specific value is present in a List.

  • How would you sort a List of integers representing sales figures in descending order? +

    Use sort() Method: Use the sort() method and then reverse the List to sort in descending order.

    Example:

                    List<Integer> salesFigures = new List<Integer>{1000, 5000, 2000};

                         salesFigures.sort();

                         salesFigures.reverse();

                   System.debug(salesFigures);

    Purpose: Order List elements based on specific sorting requirements.

  • How would you find the maximum opportunity amount in a List of opportunities? +

    Use a Loop: Iterate through the List to identify the maximum value.

    Example:

                Decimal maxAmount = 0;

                List<Opportunity> opps = [SELECT Amount FROM Opportunity];

                for (Opportunity opp : opps) {

                if (opp.Amount > maxAmount) {

                maxAmount = opp.Amount;

                 }

                }

                System.debug('Maximum Amount: ' + maxAmount);

    Purpose: Identify the highest value in a collection of records.

  • How would you combine two Lists of contact names into a single List? +

    Use addAll Method: Combine the Lists using the addAll() method.

    Example:

                   List<String> list1 = new List<String>{'John Doe', 'Jane Smith'};

                   List<String> list2 = new List<String>{'Alice Brown', 'Bob White’};

                        list1.addAll(list2);

                  System.debug(list1);

    Purpose: Merge multiple Lists into one for combined processing.

  • How would you convert a List of email addresses to a Set to ensure uniqueness? +
    •  Use the Set Constructor: Convert the List to a Set to remove duplicates.

    Example:

                List<String> emailList = new List<String>{'test@example.com', 'user@example.com', 'test@example.com'};

                Set<String> emailSet = new Set<String>(emailList);

                 System.debug(emailSet);

    • Purpose: Ensure that all elements in the collection are unique.
  • How would you process a large List of records in smaller subsets to stay within governor limits? +

    Use subList() Method: Break down the List into smaller batches and process each separately.

    Example:

                   List<Account> accounts = [SELECT Id, Name FROM Account];

                   Integer batchSize = 100;

                  for (Integer i = 0; i < accounts.size(); i += batchSize) {

                  List<Account> batch = accounts.subList(i, Math.min(i + batchSize,

                  accounts.size()));

                 // Process each batch

                  }

    Purpose: Efficiently handle large data sets by processing in manageable chunks to avoid hitting governor limits.

  • How would you use a Set to ensure that only unique email addresses are processed when adding leads to a campaign? +
    • Use a Set: Add email addresses to a Set<String>, which automatically ensures uniqueness.

    Example:

                 Set<String> uniqueEmails = new Set<String>();

                 for (Lead lead : [SELECT Email FROM Lead WHERE CampaignId = :campaignId]) {

                 uniqueEmails.add(lead.Email);

                 }

    Purpose: A Set automatically removes duplicates, ensuring only unique email addresses are processed.

  • How would you use a Set to check if a specific product code exists in a list of products? +

    Use contains Method: Use the contains() method to check if the Set includes the product code.

    Example:

              Set<String> productCodes = new Set<String>{'P001', 'P002', 'P003'};

              if (productCodes.contains('P002')) {

              System.debug('Product code P002 exists.');

               }

    Purpose: Efficiently checks for the presence of a value within a collection.

     

  • How would you convert a list of contact email addresses to a Set to remove duplicates? +

    Convert List to Set: Use a Set to automatically remove duplicates from the list.

    Example:

               List<String> emailList = new List<String>{'test@example.com', 'user@example.com', 'test@example.com'};

                Set<String> uniqueEmails = new Set<String>(emailList);

    Purpose: Convert a List to a Set to ensure all values are unique.

  • How would you find common elements between two sets of account IDs? +

    Use retainAll Method: Use the retainAll() method to find the intersection of two Sets.

    Example:

              Set<Id> set1 = new Set<Id>{'001xx000003DGbX', '001xx000003DGbY'};

              Set<Id> set2 = new Set<Id>{'001xx000003DGbY', '001xx000003DGbZ'};

              set1.retainAll(set2);

              System.debug('Common Account IDs: ' + set1);

    Purpose: Finds and retains only the common elements between two Sets.

  • How would you find common elements between two sets of account IDs? +

    Use retainAll Method: Use the retainAll() method to find the intersection of two Sets.

    Example:

              Set<Id> set1 = new Set<Id>{'001xx000003DGbX', '001xx000003DGbY'};

              Set<Id> set2 = new Set<Id>{'001xx000003DGbY', '001xx000003DGbZ'};

              set1.retainAll(set2);

              System.debug('Common Account IDs: ' + set1);

    Purpose: Finds and retains only the common elements between two Sets.

  • How would you add values to a Set only if they meet certain criteria, such as only adding active users? +

    Use a Conditional Check: Use an if statement within a loop to add values to the Set conditionally.

    Example:

                Set<Id> activeUserIds = new Set<Id>();

                 for (User user : [SELECT Id FROM User WHERE IsActive = true]) {

                activeUserIds.add(user.Id);

                   }

    Purpose: Add elements to a Set based on specific conditions.

  • How would you remove inactive user IDs from a Set of all user IDs? +

    Use remove Method: Use the remove() method to delete elements from the Set.

    Example:

               Set<Id> userIds = new Set<Id>{/* some user IDs */};

               for (User user : [SELECT Id FROM User WHERE IsActive = false]) {

               userIds.remove(user.Id);

                }

    Purpose: Removes elements from a Set based on certain criteria.

  • How would you convert a Set of account names to a List for ordered processing? +

    Convert Set to List: Use the List constructor to convert the Set.

    Example:

               Set<String> accountNamesSet = new Set<String>{'Acme Corp', 'Global Media'};

               List<String> accountNamesList = new List<String>(accountNamesSet);

               System.debug(accountNamesList);

    Purpose: Convert a Set to a List when order and indexing are needed.

  • How would you use a Set to efficiently delete duplicate contact records? +

    Store IDs in Set: Use a Set to store unique contact IDs for deletion.

    Example:

              Set<Id> contactIdsToDelete = new Set<Id>();

              for (Contact c : [SELECT Id, Email FROM Contact WHERE Email  IN :duplicateEmails]) {

               contactIdsToDelete.add(c.Id);

                  }

              delete contactIdsToDelete;

    Purpose: Efficiently perform bulk deletion by ensuring no duplicates are processed.

  • How would you use a Set to quickly determine if an opportunity has already been processed? +

    Store Processed IDs in a Set: Use a Set to keep track of processed opportunity IDs and check against it.

    Example:

              Set<Id> processedOppIds = new Set<Id>{/* some processed IDs */};

              for (Opportunity opp : [SELECT Id, Name FROM Opportunity]) {

              if (!processedOppIds.contains(opp.Id)) {

               // Process the opportunity

               processedOppIds.add(opp.Id);

                } }

    Purpose: Use a Set for efficient lookups to avoid re-processing records.

  • How would you use a Map to create a lookup between account names and their corresponding account records? +

    Use a Map: Create a Map<String, Account> where the key is the account name and the value is the Account record.

    Example:

               Map<String, Account> accountMap = new Map<String, Account>();

                for (Account acc : [SELECT Id, Name FROM Account]) {

                accountMap.put(acc.Name, acc);

                 }

    Purpose: This allows quick retrieval of account records based on the account name.

  • How would you use a Map to aggregate the total opportunity amount for each account? +

    Use a Map: Create a Map<Id, Decimal> to store the aggregated opportunity amount by account ID.

    Example:

               Map<Id, Decimal> accountTotals = new Map<Id, Decimal>();

               for (Opportunity opp : [SELECT AccountId, Amount FROM Opportunity]) {

              if (accountTotals.containsKey(opp.AccountId)) {

                accountTotals.put(opp.AccountId, accountTotals.get(opp.AccountId) +

               opp.Amount);

                } else {

                accountTotals.put(opp.AccountId, opp.Amount);

                }

                 }

    Purpose: Aggregates data where the key is an account and the value is the total opportunity amount.

  • How would you use a Map to update a list of contacts with data from a related custom object? +

    Use a Map: Create a Map<Id, CustomObject__c> to store custom object records, keyed by

    the related contact ID.

    Example:

             Map<Id, CustomObject__c> customObjMap = new Map<Id, CustomObject__c>();

             for (CustomObject__c obj : [SELECT Id, Contact__c, Field__c FROM

              CustomObject__c]) {

               customObjMap.put(obj.Contact__c, obj);

                }

              for (Contact con : [SELECT Id, Name FROM Contact WHERE Id

              IN :customObjMap.keySet()]) {

              con.Field__c = customObjMap.get(con.Id).Field__c;

              }

            update con; 

    Purpose: Efficiently update records by leveraging data stored in a Map.

  • How would you handle a scenario where you need to store multiple contacts under the same account name in a Map? +

    Use a Map with List Values: Create a Map<String, List<Contact>> where the key is the account name and the value is a list of contacts.

    Example:

            Map<String, List<Contact>> accountContactsMap = new Map<String, List<Contact>>();

            for (Contact con : [SELECT Id, Name, Account.Name FROM Contact]) {

            if (!accountContactsMap.containsKey(con.Account.Name)) {

             accountContactsMap.put(con.Account.Name, new List<Contact>());

              }

            accountContactsMap.get(con.Account.Name).add(con);

             }

    Purpose: Manage multiple values under a single key by storing lists within the Map.

  • How would you create a Map to relate opportunities with their corresponding account names? +

    Use a Map: Create a Map<Id, String> to map account IDs to account names, and then use this Map while processing opportunities.

    Example:

                Map<Id, String> accountNameMap = new Map<Id, String>();

                for (Account acc : [SELECT Id, Name FROM Account]) {

                accountNameMap.put(acc.Id, acc.Name);

                 }

                for (Opportunity opp : [SELECT Id, AccountId FROM Opportunity]) {

                System.debug('Opportunity Account: ' +

                accountNameMap.get(opp.AccountId));

                  }

    Purpose: Easily access related data across multiple objects using a Map.

  • How would you use a Map to process a large set of records without making repeated SOQL queries? +

    Use a Map: Query related data once and store it in a Map, then use this Map to process records without additional queries.

    Example:

                Map<Id, Account> accountMap = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE

                Industry = 'Technology']);

                for (Opportunity opp : [SELECT Id, AccountId FROM Opportunity WHERE Amount > 100000]) {

                 Account acc = accountMap.get(opp.AccountId);

                 if (acc != null) {

                  System.debug('Processing Opportunity for Account: ' + acc.Name);

                  }

                   }

    Purpose: Reduces SOQL queries by storing and reusing data in a Map.

  • How would you merge data from two different objects into a single Map for reporting? +

    Use Multiple Maps: Create Maps for each object, then merge the data as needed.

    Example:

             Map<Id, Account> accountMap = new Map<Id, Account>([SELECT Id, Name FROM Account]);

             Map<Id, Opportunity> oppMap = new Map<Id, Opportunity>([SELECT Id, AccountId FROM Opportunity]);

              for (Id accId : accountMap.keySet()) {

              if (oppMap.containsKey(accId)) {

               System.debug('Account: ' + accountMap.get(accId).Name + ', Opportunity: ' + oppMap.get(accId).Name);

               }

                 }

    Purpose: Combine data from different sources for comprehensive analysis.

  • How would you filter a Map to remove entries that do not meet specific criteria, such as accounts without active opportunities? +

    Use remove Method: Iterate through the Map and remove entries that don’t meet the criteria.

    Example:

                 Map<Id, Account> accountMap = new Map<Id, Account>([SELECT Id, Name FROM Account]);

                  for (Id accId : new Map<Id, Account>(accountMap).keySet()) {

                 if (!oppMap.containsKey(accId)) { // Assuming oppMap holds active opportunities

                  accountMap.remove(accId);

                 }

                  }

    Purpose: Clean up a Map by removing entries that are not relevant.

  • How would you pass a Map of account IDs and their corresponding account names to a method for processing? +

    Method Parameter: Define the method to accept a Map as a parameter and pass the Map to it.

    Example:

             public void processAccounts(Map<Id, String> accountMap) {

             for (Id accId : accountMap.keySet()) {

             System.debug('Processing Account: ' + accountMap.get(accId));

              }

              }

           Map<Id, String> accounts = new Map<Id, String>{/* account data */};

           processAccounts(accounts);

    Purpose: Use Maps as method parameters to handle complex data structures.

  • How would you retrieve all active accounts in Salesforce where the IsActive__c custom field is true? +

    SOQL Query:

                    SELECT Id, Name FROM Account WHERE IsActive__c = true

    • Explanation: This query filters accounts based on the custom IsActive__c field, retrieving only those that are marked as active.

  • How would you query contacts that have an email address ending with @example.com? +

    SOQL Query:

                       SELECT Id, Name, Email FROM Contact WHERE Email LIKE ‘%@example.com'

    • Explanation: The LIKE operator is used with the % wildcard to match any contact email that ends with @example.com.

  • How would you retrieve all cases that were created in the last 30 days? +

    SOQL Query:

                      SELECT Id, CaseNumber FROM Case WHERE CreatedDate = LAST_N_DAYS:30

    • Explanation: The LAST_N_DAYS function filters cases based on their creation date, retrieving those created in the past 30 days.

  • How would you query all accounts with a specific record type? +

    SOQL Query:

                       SELECT Id, Name FROM Account WHERE RecordType.Name = ‘Customer'

    • Explanation: This query filters accounts by the RecordType.Name field, returning only those with the record type “Customer".

  • How would you retrieve all opportunities with an amount between $10,000 and $50,000? +

    SOQL Query:

                        SELECT Id, Name, Amount FROM Opportunity WHERE Amount >= 10000 AND Amount <= 50000

    • Explanation: The WHERE clause uses the AND operator to filter opportunities within the specified amount range.

  • How would you retrieve all cases that are open and have a high priority? +

    SOQL Query:

                    SELECT Id, CaseNumber FROM Case WHERE Status = 'Open' AND Priority = ‘High'

    • Explanation: The query uses the AND operator to filter cases that are both open and have a high priority.

  • How would you retrieve all opportunities associated with accounts in the technology industry? +

    SOQL Query:

                   SELECT Id, Name FROM Opportunity WHERE Account.Industry = ‘Technology'

    • Explanation: This query filters opportunities based on a field (Industry) from a related object (Account), returning those associated with accounts in the technology industry.

  • How would you retrieve the first 10 accounts from the database? +

    SOQL Query:

                    SELECT Id, Name FROM Account LIMIT 10

    • Explanation: The LIMIT keyword restricts the number of records returned by the query to 10, useful for displaying a subset of data.

  • How would you retrieve the next 20 opportunities after the first 40? +

    SOQL Query:

                     SELECT Id, Name FROM Opportunity LIMIT 20 OFFSET 40

    • Explanation: The OFFSET keyword is used with LIMIT to skip the first 40 records and then retrieve the next 20, useful for pagination.

  • How would you retrieve all records, including those that have been deleted, from the Contact object? +

    SOQL Query:

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

    • Explanation: The ALL ROWS keyword retrieves both active and deleted records, allowing you to include records in the Recycle Bin in your results.

  • How would you create a report that only shows the top 5 highest-value opportunities? +

    SOQL Query:

                     SELECT Id, Name, Amount FROM Opportunity ORDER BY Amount DESC LIMIT 5

    • Explanation: The ORDER BY clause sorts the opportunities by amount in descending order, and LIMIT restricts the results to the top 5.

  • How would you retrieve the most recent 3 deleted accounts? +

    SOQL Query:

                  SELECT Id, Name FROM Account WHERE IsDeleted = true ORDER BY LastModifiedDate DESC LIMIT 3 ALL ROWS

    • Explanation: This query uses ORDER BY and LIMIT in conjunction with ALL ROWS to retrieve the 3 most recently deleted accounts.

  • How would you retrieve the 5 oldest accounts in your Salesforce org? +

    SOQL Query:

                    SELECT Id, Name FROM Account ORDER BY CreatedDate ASC LIMIT 5

    • Explanation: The ORDER BY CreatedDate ASC clause sorts the records by creation date in ascending order, and LIMIT restricts the results to the oldest 5 records.

  • How would you retrieve both deleted and active opportunities with a value greater than $1 million? +

    SOQL Query:

                         SELECT Id, Name, Amount FROM Opportunity WHERE Amount > 1000000 ALL ROWS

    • Explanation: The ALL ROWS keyword allows you to retrieve both active and deleted opportunities that meet the specified criteria.

  • How would you retrieve the total number of opportunities grouped by their stage? +

    SOQL Query:

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

    • Explanation: The GROUP BY clause groups opportunities by their stage name, and COUNT(Id) returns the number of opportunities in each stage.

  • How would you retrieve stages that have more than 10 opportunities? +

    SOQL Query:

                  SELECT StageName, COUNT(Id) FROM Opportunity GROUP BY StageName HAVING COUNT(Id) > 10

    • Explanation: The HAVING clause filters the grouped results to include only those stages with more than 10 opportunities.

  • How would you lock a set of account records to prevent other transactions from modifying them while your transaction is in progress? +

    SOQL Query:

                    SELECT Id, Name FROM Account WHERE Industry = 'Technology' FOR UPDATE

    • Explanation: The FOR UPDATE keyword locks the selected records, preventing other transactions from modifying them until your transaction completes.

  • How would you group opportunities by both their stage and close date? +

    SOQL Query:

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

    • Explanation: The GROUP BY clause groups opportunities first by stage and then by close date, allowing you to see counts for each combination.

  • How would you retrieve accounts that have more than 5 opportunities with an amount greater than $50,000? +

    SOQL Query:

                     SELECT AccountId, COUNT(Id) FROM Opportunity WHERE Amount > 50000 GROUP BY AccountId HAVING COUNT(Id) > 5

    • Explanation: The query groups opportunities by account and filters the groups to include only those accounts with more than 5 opportunities exceeding $50,000.

  • How would you order the grouped results of opportunities by the total amount in descending order? +

    SOQL Query:

                    SELECT AccountId, SUM(Amount) FROM Opportunity GROUP BY AccountId ORDER BY SUM(Amount)  DESC

    • Explanation: The ORDER BY clause sorts the grouped results based on the total opportunity amount in descending order.

  • How would you retrieve the 5th to 15th most recently created cases? +

    SOQL Query:

                       SELECT Id, CaseNumber FROM Case ORDER BY CreatedDate DESC OFFSET 4 LIMIT 11

    • Explanation: The OFFSET 4 skips the first 4 cases, and LIMIT 11 retrieves the next 11, giving you the 5th to 15th records.

  • How would you efficiently paginate through a large dataset of accounts ordered by name? +

    SOQL Query:

                       SELECT Id, Name FROM Account ORDER BY Name OFFSET 0 LIMIT 100

    • Explanation: Start with OFFSET 0 LIMIT 100 for the first page, and increment the OFFSET for subsequent pages to retrieve the next sets of 100 records.

  • How would you construct a dynamic SOQL query to retrieve records from the Contact object based on a user-provided search term for last name? +

    Dynamic SOQL Example:

                  String searchTerm = 'Smith';

                  String query = 'SELECT Id, Name FROM Contact WHERE LastName LIKE \'%' + searchTerm + '%\'';

                 List<Contact> contacts = Database.query(query);

    • Explanation: This code constructs a SOQL query string dynamically using the user's input and then executes it using Database.query().

  • How would you write a dynamic SOQL query that can be used to retrieve records from different objects based on a selected object name? +

    Dynamic SOQL Example:

               String objectName = 'Account';

              String query = 'SELECT Id, Name FROM ' + objectName + ' LIMIT 10';

              List<SObject> records = Database.query(query);

    • Explanation: The object name is dynamically inserted into the SOQL query, allowing the same code to retrieve records from various objects.

  • How would you build a dynamic SOQL query that includes multiple WHERE conditions based on optional user inputs? +

    Dynamic SOQL Example:
                String baseQuery = 'SELECT Id, Name FROM Account WHERE ';
                String conditions = '';
                  if (industry != null) conditions += 'Industry = \'' + industry + '\'';
                 if (annualRevenue != null) {
                if (conditions != '') conditions += ' AND ‘;
               conditions += 'AnnualRevenue > ' + annualRevenue;
                  }
                String finalQuery = baseQuery + conditions;
                List<Account> accounts = Database.query(finalQuery);
    • Explanation: The query string is dynamically built by appending conditions only if the corresponding variables are not null.
     

  • How would you create a dynamic SOQL query that sorts records based on a user- selected field? +

    Dynamic SOQL Example:

               String sortBy = 'CreatedDate';

              String query = 'SELECT Id, Name FROM Opportunity ORDER BY ' + sortBy + ' DESC';

              List<Opportunity> opportunities = Database.query(query);

    • Explanation: The field to sort by is determined at runtime based on user input, allowing for flexible query construction.

  • How would you handle a dynamic SOQL query where multiple filters may or may not be applied based on user input? +

    Dynamic SOQL Example:

             String query = 'SELECT Id, Name FROM Contact WHERE 1=1';

             if (firstName != null) query += ' AND FirstName = \'' + firstName + '\'';

            if (lastName != null) query += ' AND LastName = \'' + lastName + '\'';

           if (email != null) query += ' AND Email = \'' + email + '\'';

           List<Contact> contacts = Database.query(query);

    Explanation: The query starts with a base WHERE clause (1=1), and additional conditions are appended based on non-null inputs.

  • How would you write a dynamic SOQL query that can handle different data types, such as strings, numbers, and dates? +

    Dynamic SOQL Example:

               String fieldName = 'CloseDate';

              Date dateValue = Date.today().addDays(-30);

              String query = 'SELECT Id, Name FROM Opportunity WHERE ' + fieldName + ' >= ' + dateValue.format();

              List<Opportunity> opportunities = Database.query(query);

    • Explanation: This example demonstrates how to dynamically handle date fields, converting the Date object to a string using format() for insertion into the query.

  • How would you combine static SOQL with dynamic components to retrieve records based on varying conditions? +

    Dynamic SOQL Example:

                      String query = 'SELECT Id, Name FROM Lead WHERE IsConverted = false’;

                      if (leadSource != null) {

                      query += ' AND LeadSource = \'' + leadSource + '\'';

                       }

                      List<Lead> leads = Database.query(query);

    • Explanation: The base query is static, but additional conditions are appended dynamically based on input variables.

  • How would you write a dynamic SOQL query that includes a relationship query based on the user's selection? +

    Dynamic SOQL Example:

                  String relatedObject = 'Contacts';

                 String query = 'SELECT Id,Name,(SELECT LastName FROM '+relatedObject + ') FROM Account';

                 List<Account> accounts = Database.query(query);

     • Explanation: This query dynamically inserts the related object into the query string, allowing for flexible retrieval of related records.

  • How would you write a SOQL query to retrieve all contacts associated with a specific account? +

    SOQL Query:

                       SELECT Id, Name,(SELECT Id, Name FROM Contacts) FROM Account WHERE Id = ‘001xx000003DGbX'

    • Explanation: This query retrieves the account with a specific ID and all related contacts. The Contacts relationship name is used in the subquery to fetch child records.

  • How would you retrieve all opportunities related to a list of accounts? +

    SOQL Query:

                   SELECT Id, Name, (SELECT Id, Name, StageName FROM Opportunities) FROM Account WHERE Id IN ('001xx000003DGbX', ‘001xx000003DGbY')

    • Explanation: The subquery (SELECT Id, Name, StageName FROM Opportunities) fetches all related opportunities for the specified accounts.

  • How would you retrieve all Project__c records and their associated Task__c records? +

    SOQL Query:

                      SELECT Id, Name, (SELECT Id, Name, Status__c FROM Tasks__r) FROM Project__c

    • Explanation: The subquery fetches all related Task__c child records using the relationship name Tasks__r.

  • How would you retrieve all Order__c records and their related OrderItem__c records where the quantity is greater than 10? +

    SOQL Query:

                         SELECT Id, Name, (SELECT Id, Product__c, Quantity__c FROM OrderItems__r WHERE Quantity__c > 10) FROM Order__c

    • Explanation: The subquery fetches related OrderItem__c records where the quantity exceeds 10.

  • How would you retrieve all contacts related to accounts in the "Technology" industry? +

    SOQL Query:

                       SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account WHERE Industry = ‘Technology'

    • Explanation: The query filters accounts by industry and retrieves all related contacts.

  • How would you retrieve contact details along with their related account names and industry? +

    SOQL Query:

                            SELECT Id, Name, Account.Name, Account.Industry FROM Contact

    • Explanation: This query retrieves contact details and uses the relationship to the Account object to fetch the account name and industry for each contact.

  • How would you retrieve Project__c details from Task__c records? +

    SOQL Query:

                          SELECT Id, Name, Project__r.Name, Project__r.Status__c FROM Task__c

    • Explanation: This query retrieves Task__c details and uses the relationship to the Project__c parent object to fetch the project name and status.

  • How would you retrieve Course__c details from Enrollment__c records in a many- to-many relationship? +

    SOQL Query:

                        SELECT Id, Name, Course__r.Name, Course__r.Credits__c FROM Enrollment__c

    Explanation: The query retrieves Enrollment__c records and uses the relationship to fetch related Course__c details.

  • How would you retrieve Order__c details from OrderLineItem__c records where the order status is "Shipped"? +

    SOQL Query:

                         SELECT Id, Quantity__c, Order__r.Name, Order__r.Status__c FROM OrderLineItem__c WHERE Order__r.Status__c = ‘Shipped'

    Explanation: The query retrieves OrderLineItem__c records and fetches details from the related Order__c where the status is "Shipped".

  • How would you retrieve Account information from Case records, and also include the parent Account industry? +

    SOQL Query:

                             SELECT Id, CaseNumber, Account.Name, Account.Parent.Industry FROM Case

    • Explanation: This query retrieves case details, the related account's name, and the industry of the parent account through the relationship chain.

  • How would you search for a specific keyword like "Acme" across multiple objects such as Accounts, Contacts, and Opportunities? +

    SOSL Query:

                          FIND 'Acme' IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, FirstName, LastName), Opportunity(Id, Name)

    Explanation: This SOSL query searches for the keyword "Acme" in all fields across the Account, Contact, and Opportunity objects and returns specified fields from each.

  • How would you use SOSL to find all accounts with names starting with "Acme"? +

    SOSL Query:

                   FIND 'Acme*' IN NAME FIELDS RETURNING Account(Id, Name)

    Explanation: The asterisk (*) is used as a wildcard in SOSL to search for all account names starting with “Acme”.

  • How would you perform a SOSL search for multiple keywords like "Acme" and "Global"? +

    SOSL Query:

                FIND 'Acme OR Global' IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, FirstName, LastName)

    • Explanation: The OR operator in SOSL allows you to search for multiple keywords across all fields.

  • How would you ensure that your SOSL search is case-insensitive? +

    Example Query:

                          FIND 'john doe' IN ALL FIELDS RETURNING Contact(Id, FirstName, LastName)

    • Explanation: SOSL searches are inherently case-insensitive, so a query like FIND 'john doe' will match John Doe, JOHN DOE, etc.

  • How would you search for a contact with an email domain of "example.com"? +

    SOSL Query:

                         FIND '*@example.com' IN EMAIL FIELDS RETURNING Contact(Id, FirstName, LastName, Email)

    Explanation: The wildcard * is used to search for any email address containing the domain "example.com".

  • How would you insert multiple contact records into Salesforce in a single DML operation? +

    Example:

                   List<Contact> contacts = new List<Contact>{

                   new Contact(FirstName = 'John', LastName = 'Doe', Email = 'john.doe@example.com'),

                   new Contact(FirstName = 'Jane', LastName = 'Doe', Email = 'jane.doe@example.com')

                    };

                   insert contacts;

    • Explanation: This code creates a list of Contact objects and inserts them into Salesforce in a single DML operation using the insert keyword.

  • How would you update the email addresses of a list of contacts? +

    Example:

                 List<Contact> contactsToUpdate = [SELECT Id, Email FROM Contact WHERE LastName = 'Doe'];

                for (Contact c : contactsToUpdate) {

                 c.Email = 'newemail@example.com';

                  }

                update contactsToUpdate;

    • Explanation: This query retrieves contacts with the last name "Doe," updates their email addresses, and performs a bulk update DML operation.

  • How would you delete all closed cases that were created more than a year ago? +

    Example:

                       List<Case> casesToDelete = [SELECT Id FROM Case WHERE Status = 'Closed' AND CreatedDate < LAST_YEAR];

                       delete casesToDelete;

    • Explanation: The query fetches closed cases older than a year, and the delete keyword removes them in a single DML operation.

  • How would you perform a DML operation that allows partial success and handles errors for failed records? +

    Example:

                 Database.SaveResult[] results = Database.insert(contactsToInsert, false);

                  for (Database.SaveResult result : results) {

                  if (result.isSuccess()) {

                 System.debug('Record inserted: ' + result.getId());

                 } else {

                System.debug('Error: ' + result.getErrors()[0].getMessage());

                 }}

    • Explanation: This approach uses Database.insert with allOrNone set to false, allowing partial success and handling errors for individual records.

  • How would you use DML options to bypass workflow rules or to insert records despite validation rules? +

    Example:

                  Database.DMLOptions dmlOpts = new Database.DMLOptions();

                  dmlOpts.EmailHeader.triggerUserEmail = false;

                  dmlOpts.ValidationOptions.skipValidation = true;

                 Account newAccount = new Account(Name = 'Test Account');

                 Database.insert(newAccount, dmlOpts);

    • Explanation: DML options are configured to bypass certain processes (e.g., email alerts, validation rules) during the insert operation.

  • How would you handle a DML exception when an insert operation fails due to a validation rule? +

    Example:

                      try {

                     insert new Contact(FirstName = 'John', LastName = 'Doe');

                     } catch (DmlException e) {

                     System.debug('DML Exception: ' + e.getMessage());

                     }

    • Explanation: The try-catch block handles any DmlException that occurs during the insert operation, allowing you to capture and log the error.

  • How would you insert a list of contacts and handle the scenario where some records might fail due to validation rules? +

    Example:

                   List<Contact> contactsToInsert = new List<Contact>{

                  new Contact(FirstName = 'John', LastName = 'Doe', Email = 'john.doe@example.com'),

                  new Contact(FirstName = null, LastName = 'Smith') // This will fail due to a

                  validation rule

                  };

                   Database.SaveResult[] results = Database.insert(contactsToInsert, false);

                    for (Database.SaveResult result : results) {

                  if (result.isSuccess()) {

                 System.debug('Record inserted: ' + result.getId());

                  } else {

                System.debug('Error: ' + result.getErrors()[0].getMessage());

                 }

                   }

    • Explanation: The Database.insert method with false for allOrNone allows partial success, inserting valid records and handling errors for failed records individually.

  • How would you update a list of accounts and handle any errors without stopping the entire operation? +

    Example:

                  List<Account> accountsToUpdate = [SELECT Id, Name FROM Account WHERE Name LIKE 'Test%'];

                   for (Account acc : accountsToUpdate) {

                    acc.Name = 'Updated ' + acc.Name;

                    }

                 Database.SaveResult[] results = Database.update(accountsToUpdate, false);

                 for (Database.SaveResult result : results) {

                 if (!result.isSuccess()) {

                for (Database.Error error : result.getErrors()) {

               System.debug('Error updating account: ' + error.getMessage());

                } } }

    Explanation: The use of Database.update with partial success allows for error handling without interrupting the entire update process.

  • How would you delete a list of case records, ensuring that the operation continues even if some records fail to delete? +

    Example:

                 List<Case> casesToDelete = [SELECT Id FROM Case WHERE Status = 'Closed'];

                 Database.DeleteResult[] results = Database.delete(casesToDelete, false);

                for (Database.DeleteResult result : results) {

                 if (!result.isSuccess()) {

                   System.debug('Error deleting case: ' + result.getErrors() [0].getMessage());

                   }

                  }

    • Explanation: The Database.delete method allows for partial success, deleting records while continuing the operation even if some deletions fail.

  • How would you ensure that records are not updated by another process while you are updating them? +

    Example:

                   List<Account> accountsToLock = [SELECT Id, Name FROM Account WHERE Industry = 'Technology' FOR UPDATE];

                  for (Account acc : accountsToLock) {

                   acc.Name = 'Locked ' + acc.Name;

                    }

                   Database.update(accountsToLock);

    Explanation: The FOR UPDATE keyword locks the selected records, preventing other transactions from modifying them until the current transaction is complete.

  • How would you update a parent account record and all related contacts in a single transaction? +

    Example:

                     Account parentAccount = [SELECT Id, Name, (SELECT Id, LastName FROM Contacts) FROM

                    Account WHERE Name = 'Global Media'];

                    parentAccount.Name = 'Global Media Group';

                    List<Contact> relatedContacts = parentAccount.Contacts;

                     for (Contact c : relatedContacts) {

                     c.LastName = 'Updated ' + c.LastName;

                     }

                   Database.update(new List<SObject>{parentAccount}.addAll(relatedContacts), false);

     • Explanation: This approach updates the parent account and all related contacts in a single Database.update operation, allowing for error handling.

  • How would you use a Database.rollback operation to undo changes if an error occurs during a transaction? +

    Example:

                  Savepoint sp = Database.setSavepoint();

                    try {

                    Account newAccount = new Account(Name = 'Test Account');

                  Database.insert(newAccount);

                   Contact newContact = new Contact(LastName = 'Test', AccountId =

                   newAccount.Id);

                   Database.insert(newContact);

                   } catch (DmlException e) {

                   Database.rollback(sp);

                    System.debug('Transaction rolled back due to error: ' + e.getMessage());

                    }

    • Explanation: The use of Database.update with partial success allows for error handling without interrupting the entire update process.

  • How would you delete a list of case records, ensuring that the operation continues even if some records fail to delete? +

    Example:

                 List<Case> casesToDelete = [SELECT Id FROM Case WHERE Status = 'Closed'];

                Database.DeleteResult[] results = Database.delete(casesToDelete, false);

                for (Database.DeleteResult result : results) {

                if (!result.isSuccess()) {

               System.debug('Error deleting case: ' + result.getErrors() [0].getMessage());

               }

               }

    • Explanation: The Database.delete method allows for partial success, deleting records while continuing the operation even if some deletions fail.

  • How would you ensure that records are not updated by another process while you are updating them? +

    Example:

                List<Account> accountsToLock = [SELECT Id, Name FROM Account WHERE Industry = 'Technology' FOR UPDATE];

                for (Account acc : accountsToLock) {

                 acc.Name = 'Locked ' + acc.Name;

                 }

                Database.update(accountsToLock);

    Explanation: The FOR UPDATE keyword locks the selected records, preventing other transactions from modifying them until the current transaction is complete.

  • How would you update a parent account record and all related contacts in a single transaction? +

    Example:

                     Account parentAccount = [SELECT Id, Name, (SELECT Id, LastName FROM Contacts) FROM Account WHERE Name = 'Global Media'];

                       parentAccount.Name = 'Global Media Group';

                     List<Contact> relatedContacts = parentAccount.Contacts;

                    for (Contact c : relatedContacts) {

                   c.LastName = 'Updated ' + c.LastName;

                     }

                    Database.update(new List<SObject>{parentAccount}.addAll(relatedContacts), false);

    • Explanation: This approach updates the parent account and all related contacts in a single Database.update operation, allowing for error handling.

  • How would you use a Database.rollback operation to undo changes if an error occurs during a transaction? +

    Example:

                  Savepoint sp = Database.setSavepoint();

                    try {

                   Account newAccount = new Account(Name = 'Test Account');

                   Database.insert(newAccount);

                   Contact newContact = new Contact(LastName = 'Test', AccountId =

                   newAccount.Id);

                   Database.insert(newContact);

                   } catch (DmlException e) {

                  Database.rollback(sp);

                   System.debug('Transaction rolled back due to error: ' +

                  e.getMessage());

                   }

    • Explanation: The Database.rollback method reverts the transaction to a savepoint, undoing all changes made after that point in case of an error.

  • How would you send a basic email to a contact when a new case is created? +

    Example:

                   Messaging.SingleEmailMessage mail= new Messaging.SingleEmailMessage();

                   mail.setToAddresses(new String[] {'contact@example.com'});

                  mail.setSubject('New Case Created');

                  mail.setPlainTextBody('A new case has been created.');

                   Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

    • Explanation: This code sends a plain text email to the specified contact when a new case is created.

  • How would you send an email using an existing email template to an opportunity owner when an opportunity is closed? +

    Example:

                     Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

                    mail.setTargetObjectId(opportunity.OwnerId);

                    mail.setTemplateId('00Xxx0000001ABc');

                    mail.setWhatId(opportunity.Id);

                    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

    • Explanation: The email is sent using a predefined template and is personalized based on the opportunity owner's information.

  • How would you send an email to multiple recipients (e.g., all contacts related to an account)? +

                    List<Contact> contacts = [SELECT Email FROM Contact WHERE AccountId = :accountId];

                    List<String> emails = new List<String>();

                    for (Contact c : contacts) {

                    emails.add(c.Email);

                     }

                     Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

                     mail.setToAddresses(emails);

                      mail.setSubject('Important Update');

                      mail.setPlainTextBody('Please be informed of the following...');

                      Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

    • Explanation: The email is sent to all contacts associated with a specific account.

  • How would you send an email with a PDF attachment? +

    Example:

                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

                  mail.setToAddresses(new String[] {'contact@example.com'});

                  mail.setSubject('Attached PDF');

                  mail.setPlainTextBody('Please find the attached PDF document.');

                 Blob pdfBlob = Blob.valueOf('PDF Content');

                 Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();

                 attachment.setFileName('document.pdf');

                 attachment.setBody(pdfBlob);

                mail.setFileAttachments(new Messaging.EmailFileAttachment[] { attachment });

               Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

    • Explanation: This example demonstrates sending an email with a PDF file as an attachment.

  • How would you send an email with HTML content instead of plain text? +

    Example:

                    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

                    mail.setToAddresses(new String[] {'contact@example.com'});

                    mail.setSubject('Welcome!');

                  mail.setHtmlBody('<h1>Welcome to our service!</h1><p>We are glad to have you.</p>');

                  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

    • Explanation: The email body is set using HTML, allowing for more formatting options.

  • How would you track if an email sent to a lead has been delivered or not? +
    • Explanation: Salesforce provides email deliverability tracking through its Email Logs and the Messaging.SingleEmailMessage.getOrgWideEmailAddressId() method. However, detailed tracking like opens and clicks often requires integration with third-party services or Salesforce Marketing Cloud.
  • How would you handle email bounces and ensure your system is updated? +
    • Explanation: Salesforce can handle bounce management via the standard "Email Bounced" fields on the Contact and Lead objects. You can automate bounce processing by setting up workflow rules or triggers that react when these fields are updated.
  • How would you send a mass email to all leads in your Salesforce org? +

    Example:

                 List<Messaging.SingleEmailMessage> mails = new

                List<Messaging.SingleEmailMessage>();

               List<Lead> leads = [SELECT Email FROM Lead WHERE Email != null];

               for (Lead l : leads) {

                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

                mail.setToAddresses(new String[] {l.Email});

               mail.setSubject('Important Update');

               mail.setPlainTextBody('Please review the latest updates.');

               mails.add(mail);

               }

               Messaging.sendEmail(mails);

    • Explanation: This approach sends individual emails to all leads, ensuring each email is personalized.

  • How would you customize the sender’s email name in a Salesforce email? +

    Example:

                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

                 mail.setToAddresses(new String[] {'contact@example.com'});

                 mail.setSenderDisplayName('Acme Support');

                mail.setSubject('Support Inquiry');

               mail.setPlainTextBody('Thank you for contacting Acme Support.');

               Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

    • Explanation: The setSenderDisplayName method customizes the name that appears in the recipient's inbox.

  • How would you process a large number of records (e.g., over 50,000) in Salesforce without hitting governor limits? +

                     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)

                   {

                  for (Account acc : scope) {

                  // Perform processing

                      }

                  update scope;

                      }

                public void finish(Database.BatchableContext BC) {

                // Post-batch operations

                 }

                  }

    • Explanation: Batch Apex is designed to process large volumes of records in chunks, allowing you to stay within governor limits by processing data in manageable batches.

  • How would you schedule a Batch Apex job to run daily at midnight? +

                 AccountBatch batchJob = new AccountBatch();

                String cronExp = '0 0 0 * * ?'; // At midnight every day

               System.schedule('Daily Account Batch', cronExp, batchJob);

    • Explanation: The System.schedule method allows you to schedule Batch Apex jobs using a cron expression.

  • How would you send an email notification to the admin after a batch job completes? +

                     public void finish(Database.BatchableContext BC) {

                    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

                     mail.setToAddresses(new String[] {'admin@example.com'});

                    mail.setSubject('Batch Job Completed');

                    mail.setPlainTextBody('The batch job has finished processing.');

                   Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

                    }

    • Explanation: The finish method in Batch Apex is ideal for executing post-processing tasks, such as sending email notifications.

  • How would you maintain state across different executions of the execute method in Batch Apex? +

                public class AccountBatch implements Database.Batchable<SObject>, Database.Stateful {

               public Integer processedRecords = 0;

               public void execute(Database.BatchableContext BC, List<Account> scope) {

               processedRecords += scope.size();

              update scope;

              public void finish(Database.BatchableContext BC) {

              System.debug('Total records processed: ' + processedRecords);

               }

               }

               }

    • Explanation: Implementing Database.Stateful allows you to maintain state across multiple execute method invocations, such as counting processed records.

  • How would you handle errors within a Batch Apex job to ensure processing continues? +

    Answer:

                   public void execute(Database.BatchableContext BC, List<Account> scope) {

                  for (Account acc : scope) {

                  try {

                 // Perform processing

                  update acc;

                 } catch (Exception e) {

                System.debug('Error processing record: ' + acc.Id + ', Error: ' +

               e.getMessage());

                 }

                  }

                 }

    • Explanation: Using a try-catch block within the execute method allows you to handle errors at the record level, ensuring that the batch job continues processing other records.

  • How would you ensure your batch job can handle large query results that exceed the heap size limit? +

                  public Database.QueryLocator start(Database.BatchableContext BC) {

                  return Database.getQueryLocator('SELECT Id, Name FROM Contact WHERE CreatedDate > LAST_YEAR');

                  }

    • Explanation: Database.getQueryLocator returns a QueryLocator object that efficiently handles large query results by breaking them into smaller batches.

  • How would you ensure your Batch Apex job is bulkified to handle large data volumes? +

                public void execute(Database.BatchableContext BC, List<Account> scope) {

                  List<Account> accountsToUpdate = new List<Account>();

                 for (Account acc : scope) {

                acc.Name = 'Updated ' + acc.Name;

                accountsToUpdate.add(acc);

                 }

                 update accountsToUpdate;

                }

    • Explanation: Collecting records into a list and performing DML operations in bulk ensures the code is bulkified and can handle large volumes of data efficiently.
  • How would you configure a Batch Apex job to process records in smaller chunks, such as 10 records per batch? +

                        public void executeBatch() {

                       Database.executeBatch(new AccountBatch(), 10);

                          }

    • Explanation: The second parameter in Database.executeBatch specifies the batch size, allowing you to process records in smaller chunks.

  • How would you write a Batch Apex job to process a custom object Project__c? +

                     public class ProjectBatch implements Database.Batchable<SObject> {

                    public Database.QueryLocator start(Database.BatchableContext BC) {

                   return Database.getQueryLocator('SELECT Id, Name FROM Project__c WHERE

                  Status__c = \'In Progress\'');

                  }

                 public void execute(Database.BatchableContext BC, List<SObject> scope) {

               List<Project__c> projects = (List<Project__c>)scope;

                 for (Project__c proj : projects) {

                proj.Status__c = 'Completed';

                 }

                 update projects;

                  }

               public void finish(Database.BatchableContext BC) {

              // Post-processing actions

                }

                }

    • Explanation: This Batch Apex job processes records from the Project__c custom object, updating the status of each project.

  • How would you schedule an Apex class to run every day at 2:00 AM? +

                 public class DailyJob implements Schedulable {

                 public void execute(SchedulableContext SC) {

                // Your logic here

                 }

                 }

               String cronExp = '0 0 2 * * ?'; // 2:00 AM daily

                System.schedule('Daily Job', cronExp, new DailyJob());

    • Explanation: The System.schedule method is used with a cron expression to schedule the DailyJob class to run every day at 2:00 AM.

  • How would you schedule an Apex job to run every Monday at 6:00 AM? +

               public class WeeklyJob implements Schedulable {

               public void execute(SchedulableContext SC) {

               // Your logic here

                }

                }

               String cronExp = '0 0 6 ? * MON'; // 6:00 AM every Monday

               System.schedule('Weekly Job', cronExp, new WeeklyJob());

    • Explanation: The cron expression 0 0 6 ? * MON is used to run the job every Monday at 6:00 AM.

  • How would you schedule a job to run at 11:59 PM on the last day of every month? +

                public class MonthlyJob implements Schedulable {

                 public void execute(SchedulableContext SC) {

               // Your logic here

                  }

                  }

                String cronExp = '0 59 23 L * ?'; // 11:59 PM on the last day of each month

                System.schedule('Monthly Job', cronExp, new MonthlyJob());

    • Explanation: The cron expression 0 59 23 L * ? schedules the job to run at 11:59 PM on the last day of every month.
  • How would you schedule a job to run every hour on the hour? +

                    public class HourlyJob implements Schedulable {

                   public void execute(SchedulableContext SC) {

                 // Your logic here

                    }

                    }

               String cronExp = '0 0 * * * ?'; // At the top of every hour

               System.schedule('Hourly Job', cronExp, new HourlyJob());

    • Explanation: The cron expression 0 0 * * * ? schedules the job to run at the start of every hour.

  • How would you dynamically schedule an Apex job to run a specified number of minutes from now? +

                 public class DynamicJob implements Schedulable {

                 public void execute(SchedulableContext SC) {

                // Your logic here

                }

                 }

              Integer minutesFromNow = 30;

               Datetime runTime = System.now().addMinutes(minutesFromNow);

               String cronExp = runTime.format('s m H d M ? yyyy');

               System.schedule('Dynamic Job', cronExp, new DynamicJob());

    • Explanation: This solution calculates the future run time dynamically and converts it into a cron expression for scheduling.

  • How would you schedule a second job to run immediately after a batch job completes? +

                          public class FirstJob implements Schedulable {

                          public void execute(SchedulableContext SC) {

                        // Your logic here

                      System.schedule('Second Job', System.now().format('s m H d M ? yyyy'), new SecondJob());

                        }

                        }

                    public class SecondJob implements Schedulable {

                    public void execute(SchedulableContext SC) {

                    // Logic for second job

                     }

                    }

    • Explanation: The second job is scheduled within the execute method of the first job, ensuring it runs immediately after the first job completes.

  • How would you ensure that a scheduled job does not start if a previous instance of the same job is still running? +

                public class SafeJob implements Schedulable {

               public void execute(SchedulableContext SC) {

               if (!Lock__c.getInstance().isLocked()) {

               Lock__c.getInstance().lock();

               try {

                 // Your job logic here

                } finally {

               Lock__c.getInstance().unlock();

               }

                } else {

               System.debug('Job already running.');

               }

               }

                 }

    • Explanation: A custom locking mechanism is used to check whether the job is already running. If it is, the new instance does not start.

  • How would you schedule a job to run daily for the next 7 days only? +

                 public class LimitedLifespanJob implements Schedulable {

                 public void execute(SchedulableContext SC) {

                 if (System.today() <= Date.today().addDays(7)) {

                 // Your job logic here

                 } else {

               System.abortJob(SC.getTriggerId());

              }

                  String cronExp = '0 0 2 * * ?'; // 2:00 AM daily

                    System.schedule('Limited Lifespan Job', cronExp, new LimitedLifespanJob());

    • Explanation: The job checks the current date and aborts itself after 7 days.

  • How would you schedule a job that requires an Apex class parameter at runtime? +

                public class ParametrizedJob implements Schedulable {

               private String param;

               public ParametrizedJob(String param) {

               this.param = param;

              }

             public void execute(SchedulableContext SC) {

            System.debug('Parameter: ' + param);

            // Your logic here

             }

               }

             String cronExp = '0 0 12 * * ?';

             ParametrizedJob job = new ParametrizedJob('Parameter Value');

             System.schedule('Parametrized Job', cronExp, job);

    • Explanation: The job is scheduled with a parameter passed through its constructor, allowing for dynamic behavior.

  • How would you unschedule a job that has been previously scheduled? +

               CronTrigger ct = [SELECT Id FROM CronTrigger WHERE CronJobDetail.Name = 'Job to Unschedule' LIMIT 1];

              System.abortJob(ct.Id);

    • Explanation: The job is unscheduled using the System.abortJob method, which requires the job’s ID.

  • How would you use a future method to perform a callout to an external web service after an account record is updated? +

              public class AccountHandler {

              @future(callout=true)

              public static void performCallout(Id accountId) {

              Account acc = [SELECT Id, Name FROM Account WHERE Id = :accountId];

              // Perform the callout logic here

               }

               }

    • Explanation: The future method is marked with @future(callout=true) to allow a callout from within the method, ensuring the callout is processed asynchronously after the account update.

  • How would you process a large number of records asynchronously using a future method? +

              public class DataProcessor {

              @future

             public static void processLargeDataSet(List<Id> recordIds) {

              List<SObject> records = [SELECT Id, Name FROM SObject WHERE Id IN :recordIds];

              // Perform processing on the records

               }

               }

    • Explanation: The future method processes a list of record IDs asynchronously, which is useful for handling large data volumes without hitting synchronous processing limits.

  • How would you use a future method to bypass mixed DML operation limits, such as inserting a user and updating a record in the same transaction? +

                          public class MixedDMLOperationHandler {

                          public void createUserAndUpdateRecord() {

                         User newUser = new User(Username = 'newuser@example.com', ...);

                         insert newUser;

                        updateRecordAsync();

                        }

                      @future

                   public static void updateRecordAsync() {

                  // Perform the record update here

                  }

                  }

    Explanation: The future method updateRecordAsync is used to perform the DML operation on a setup object asynchronously, avoiding the mixed DML error.

  • How would you handle a long-running operation, such as recalculating values for a large number of records, using a future method? +

               public class LongRunningOperation {

              @future

              public static void recalculateValues(List<Id> recordIds) {

              for (Id recordId : recordIds) {

              // Perform the long-running operation

               }

              }

             }

    • Explanation: The future method is ideal for executing operations that might take a long time to complete, ensuring they do not block the main transaction.

  • How would you update records in Salesforce based on the response from an external web service using a future method? +

                    public class ExternalServiceHandler {

                    @future(callout=true)

                    public static void updateRecordsFromService(Id recordId) {

                    // Callout to the external service

                     // Update the record based on the response

                     }

                     }

    • Explanation: The future method is used to make the callout and update records asynchronously, ensuring the callout does not delay the original transaction.

  • How would you call a future method from a trigger to avoid hitting governor limits? +

                trigger AccountTrigger on Account (after update) {

                List<Id> accountIds = new List<Id>();

                for (Account acc : Trigger.new) {

                accountIds.add(acc.Id);

                    }

                AccountHandler.handleAccountUpdates(accountIds);

                }

               public class AccountHandler {

                @future

                public static void handleAccountUpdates(List<Id> accountIds) {

                // Process the accounts asynchronously

                  }

                 }

    • Explanation: The future method handleAccountUpdates is called from the trigger to process account updates asynchronously, helping to avoid governor limits.
  • How would you send email notifications asynchronously after a record is updated? +

               public class EmailNotifier {

               @future

              public static void sendNotification(List<Id> recordIds) {

              List<SObject> records = [SELECT Id, Name FROM SObject WHERE Id IN :recordIds];

             // Send email notifications

                }

               }

    • Explanation: The future method sends email notifications asynchronously, ensuring the main transaction is not delayed by email processing.

  • How would you pass parameters, such as a list of IDs, to a future method for processing? +

                 public class BatchProcessor {

                 @future

                public static void processRecords(List<Id> recordIds) {

               List<SObject> records = [SELECT Id, Name FROM SObject WHERE Id IN :recordIds];

                // Perform processing on the records

                }

                 }

    • Explanation: Future methods can accept primitive data types or collections of primitive types as parameters, allowing you to pass necessary data for asynchronous                                         processing.

  • How would you handle exceptions that occur within a future method? +

                  public class ExceptionHandler {

                    @future

                  public static void processWithExceptionHandling() {

                   try {

                // Perform operations that might throw an exception

                } catch (Exception e) {

                System.debug('Exception: ' + e.getMessage());

                  }

                  }

                  }

    • Explanation: A try-catch block is used within the future method to handle exceptions and prevent the asynchronous process from failing silently.

  • How would you use a future method to integrate Salesforce with an external system by sending data asynchronously? +

                   public class DataIntegration {

                  @future(callout=true)

                 public static void sendDataToExternalSystem(Id recordId) {

                // Prepare data and perform callout to the external system

                  }

               }

    •  Explanation: The future method is marked with @future(callout=true) to handle the data integration asynchronously, ensuring Salesforce remains responsive                              while the integration is performed.
  • How would you handle a scenario where you need to process a large set of records asynchronously using Queueable Apex? +

                public class ProcessLargeDataSet implements Queueable {

                public void execute(QueueableContext context) {

                 List<Account> accounts = [SELECT Id, Name FROM Account WHERE Industry = 'Technology'];

                 for (Account acc : accounts) {

                   acc.Name = acc.Name + ' - Processed';

                        }

                    update accounts;

                        }

                        }

    • Explanation: Queueable Apex is ideal for handling large data sets asynchronously, allowing you to process records without hitting synchronous governor limits.

  • How would you chain multiple Queueable jobs to ensure that they run sequentially? +

                 public class FirstJob implements Queueable {

                 public void execute(QueueableContext context) {

                  // Processing logic for the first job

                 System.enqueueJob(new SecondJob());

                 }

                 }

              public class SecondJob implements Queueable {

               public void execute(QueueableContext context) {

                 // Processing logic for the second job

                     }

                      }

    • Explanation: Queueable Apex supports job chaining, where you can enqueue another job from within the execute method, ensuring sequential execution.
  • How would you perform a callout to an external web service using Queueable Apex? +

                  public class CalloutJob implements Queueable, Database.AllowsCallouts {

                  public void execute(QueueableContext context) {

                 HttpRequest req = new HttpRequest();

                req.setEndpoint('https://example.com/api');

                req.setMethod(‘GET');

               HttpResponse res = new Http().send(req);

              // Process the response

               }

               }

    • Explanation: Implementing the Database.AllowsCallouts interface in Queueable Apex allows you to make HTTP callouts asynchronously.

  • How would you pass complex data, such as SObject records, to a Queueable job? +

                      public class ProcessRecordsJob implements Queueable {

                      private List<Account> accountsToProcess;

                      public ProcessRecordsJob(List<Account> accounts) {

                     this.accountsToProcess = accounts;

                      }

                   public void execute(QueueableContext context) {

                  for (Account acc : accountsToProcess) {

                 acc.Name = acc.Name + ' - Processed';

                   }

                update accountsToProcess;

                  }

                  }

    • Explanation: Queueable Apex allows you to pass complex data types, like SObject records, via the class constructor, making it easier to handle specific records                         asynchronously.
  • How would you maintain state across multiple executions of Queueable jobs? +

                public class StatefulQueueableJob implements Queueable, Database.Stateful {

                public Integer processedCount = 0;

                public void execute(QueueableContext context) {

                // Process records and update processedCount

                  processedCount += 10;

               System.debug('Processed so far: ' + processedCount);

                 }

                   }

    • Explanation: Implementing Database.Stateful in Queueable Apex allows you to maintain state across multiple job executions, such as tracking the number of                             processed records.
  • How would you prioritize a Queueable job in the Flex Queue if it needs to be processed immediately? +

              AsyncApexJob job = [SELECT Id FROM AsyncApexJob WHERE JobType = 'Queueable' AND Status = 'Holding' ORDER BY CreatedDate DESC LIMIT 1];

                  System.moveToStartOfQueue(job.Id);

    • Explanation: The System.moveToStartOfQueue method is used to move a job to the front of the Flex Queue, ensuring it gets processed as soon as possible.
  • How would you ensure that errors in a Queueable job are handled and logged? +

              public class ErrorHandlingJob implements Queueable {

               public void execute(QueueableContext context) {

               try {

                 // Perform processing

                 } catch (Exception e) {

                 System.debug('Error: ' + e.getMessage());

               // Log the error or handle it accordingly

                }

               }

                 }

    • Explanation: A try-catch block within the execute method ensures that errors are caught and logged, preventing the job from failing silently.
  • How would you manage dependencies between Queueable jobs using the Flex Queue? +

                 public class FirstJob implements Queueable {

                 public void execute(QueueableContext context) {

                 // Processing logic for the first job

                   System.enqueueJob(new SecondJob());

                  }

                    }

                public class SecondJob implements Queueable {

                public void execute(QueueableContext context) {

                // Processing logic for the second job

                System.enqueueJob(new ThirdJob());

                   }

                  }

    • Explanation: By chaining Queueable jobs, you can manage complex dependencies and ensure that jobs run in a specific order within the Flex Queue.
  • How would you schedule a Queueable job to run at a specific time? +

                  public class ScheduledJob implements Schedulable {

                 public void execute(SchedulableContext SC) {

                System.enqueueJob(new ProcessRecordsJob());

                }

                }

               String cronExp = '0 0 12 * * ?'; // Run at 12:00 PM every day

               System.schedule('Daily Queueable Job', cronExp, new ScheduledJob());

    • Explanation: A Schedulable class is used to schedule the Queueable job, ensuring it runs at the specified time.
  • How would you monitor the status of Queueable jobs in the Flex Queue? +

                  List<AsyncApexJob> jobs = [SELECT Id, Status, CreatedDate FROM AsyncApexJob WHERE JobType = 'Queueable'];

                  for (AsyncApexJob job : jobs) {

                  System.debug('Job ID: ' + job.Id + ', Status: ' + job.Status);

                   }

    • Explanation: By querying the AsyncApexJob object, you can monitor the status of Queueable jobs, track their progress, and manage them within the Flex Queue.

  • How would you write an Apex trigger to prevent the insertion of duplicate Contact records based on email address? +

               trigger PreventDuplicateContacts on Contact (before insert) {

              Set<String> emailSet = new Set<String>();

              for (Contact con : Trigger.new) {

              if (con.Email != null) {

              emailSet.add(con.Email);

               }

                }

             List<Contact> existingContacts = [SELECT Id, Email FROM Contact WHERE Email IN :emailSet];

          for (Contact con : Trigger.new) {

         if (existingContacts.contains(con.Email)) {

           con.addError('A contact with this email already exists.');

            }

           }

            }

    • Explanation: The trigger runs before insert, checks for existing contacts with the same email address, and prevents the insertion of duplicates by adding an                                 error message.

    Using Trigger Handler Class :

    Trigger:

              trigger PreventDuplicateContacts on Contact (before insert) {

             ContactTriggerHandler.preventDuplicates(Trigger.new);

                }

    Handler Class:

              public class ContactTriggerHandler {

              public static void preventDuplicates(List<Contact> newContacts) {

              Set<String> emailSet = new Set<String>();

              for (Contact con : newContacts) {

              if (con.Email != null) {

               emailSet.add(con.Email);

              }

              }

              List<Contact> existingContacts = [SELECT Id, Email FROM Contact WHERE Email IN :emailSet];

              for (Contact con : newContacts) {

             if (existingContacts.contains(con.Email)) {

             con.addError('A contact with this email already exists.');

             }

             }

             }

             }

  • How would you create a trigger that updates all related Opportunities when an Account's industry changes? +

             trigger UpdateOpportunitiesOnAccountChange on Account (after update) {

             List<Opportunity> oppsToUpdate = new List<Opportunity>();

             for (Account acc : Trigger.new) {

             Account oldAcc = Trigger.oldMap.get(acc.Id);

             if (acc.Industry != oldAcc.Industry) {

             oppsToUpdate.addAll([SELECT Id FROM Opportunity WHERE AccountId = :acc.Id]);

             }

            for (Opportunity opp : oppsToUpdate) {

           opp.Description = 'Updated due to Account industry change';

             }

            }

           update oppsToUpdate;

              }

    • Explanation: The trigger updates all opportunities related to an account when the account’s industry changes, adding a note in the opportunity description.

    Using Trigger Handler Class :

    Trigger:

                trigger UpdateOpportunitiesOnAccountChange on Account (after update) {

                AccountTriggerHandler.updateOpportunitiesOnIndustryChange(Trigger.new, Trigger.oldMap);

                  }

    Handler Class:

              public class AccountTriggerHandler {

              public static void updateOpportunitiesOnIndustryChange(List<Account>

              newAccounts, Map<Id, Account> oldAccountMap) {

               List<Opportunity> oppsToUpdate = new List<Opportunity>();

               for (Account acc : newAccounts) {

               Account oldAcc = oldAccountMap.get(acc.Id);

              if (acc.Industry != oldAcc.Industry) {

           oppsToUpdate.addAll([SELECT Id FROM Opportunity WHERE AccountId = :acc.Id]);

               }

              }

              }

             }

            for (Opportunity opp : oppsToUpdate) {

            opp.Description = 'Updated due to Account industry change';

            if (!oppsToUpdate.isEmpty()) {

            update oppsToUpdate;

            }

            }

  • How would you write a trigger that automatically creates a Case record when a Contact is inserted? +

                   trigger CreateCaseOnContactInsert on Contact (after insert) {

                   List<Case> casesToCreate = new List<Case>();

                   for (Contact con : Trigger.new) {

                   Case newCase = new Case(

                   ContactId = con.Id,

                   Subject = 'New Case for ' + con.LastName

                     );

                    casesToCreate.add(newCase);

                     }

                insert casesToCreate;

                        }

    • Explanation: This trigger runs after a contact is inserted and creates a related case for each new contact, setting the subject based on the contact’s last name.

    Using Trigger Handler Class :

    Trigger:

                    trigger CreateCaseOnContactInsert on Contact (after insert) {

                     ContactTriggerHandler.createCasesForNewContacts(Trigger.new);

                       }

    Handler Class:

                      public class ContactTriggerHandler {

                      public static void createCasesForNewContacts(List<Contact> newContacts) {

                      List<Case> casesToCreate = new List<Case>();

                       for (Contact con : newContacts) {

                        Case newCase = new Case(

                        ContactId = con.Id,

                         Subject = 'New Case for ' + con.LastName

                          );

                         casesToCreate.add(newCase);

                          if (!casesToCreate.isEmpty()) {

                           insert casesToCreate;

                          }

                          }

                          }

                          }

  • How would you write a trigger to ensure that an Opportunity's close date is not set to a past date? +

                    trigger ValidateOpportunityCloseDate on Opportunity (before insert, before update)

                    {

                   for (Opportunity opp : Trigger.new) {

                   if (opp.CloseDate < Date.today()) {

                   opp.addError('Close Date cannot be in the past.');

                    }

                   }

                    }

    • Explanation: The trigger validates the close date of an opportunity and prevents the record

    from being saved if the close date is in the past.

    Using Trigger Handler Class :

    Trigger:

    trigger ValidateOpportunityCloseDate on Opportunity (before insert, before update) {

    OpportunityTriggerHandler.validateCloseDate(Trigger.new);

    }

    Handler Class:

    public class OpportunityTriggerHandler {

    public static void validateCloseDate(List<Opportunity> opportunities) {

    for (Opportunity opp : opportunities) {

    if (opp.CloseDate < Date.today()) {

    opp.addError('Close Date cannot be in the past.');

    }

    }

    }

    }

    • Explanation: The trigger validates the close date of an opportunity and prevents the record from being saved if the close date is in the past.

    Using Trigger Handler Class :

    Trigger:

              trigger ValidateOpportunityCloseDate on Opportunity (before insert, before update) {

              OpportunityTriggerHandler.validateCloseDate(Trigger.new);

                 }

    Handler Class:

                 public class OpportunityTriggerHandler {

                 public static void validateCloseDate(List<Opportunity> opportunities) {

                 for (Opportunity opp : opportunities) {

                 if (opp.CloseDate < Date.today()) {

                opp.addError('Close Date cannot be in the past.');

                 }

                 }

                 }

                 }

  • How would you write a trigger to roll up the count of Order__c records to the parent Account? +

                 trigger RollupOrderCount on Order__c (after insert, after delete, after undelete)

                  { 

                Set<Id> accountIds = new Set<Id>();

                for (Order__c order : Trigger.isDelete ? Trigger.old : Trigger.new) {

                accountIds.add(order.Account__c);

                 }

                Map<Id, Account> accountsToUpdate = new Map<Id, Account>([SELECT Id, (SELECT Id FROM Orders__r) FROM Account WHERE Id IN :accountIds]);

              for (Account acc : accountsToUpdate.values()) {

              acc.Order_Count__c = acc.Orders__r.size();

                }

              update accountsToUpdate.values();

                }

    • Explanation: This trigger rolls up the count of Order__c records to the parent account by updating a custom field Order_Count__c on the Account.

     

    Using Trigger Handler Class :

    Trigger:

              trigger RollupOrderCount on Order__c (after insert, after delete, after undelete) {

              OrderTriggerHandler.updateOrderCount(Trigger.new, Trigger.old, Trigger.isDelete);

                }

    Handler Class:

               public class OrderTriggerHandler {

               public static void updateOrderCount(List<Order__c> newOrders, List<Order__c> oldOrders, Boolean isDelete) {

               Set<Id> accountIds = new Set<Id>();

               for (Order__c order : isDelete ? oldOrders : newOrders) {

                accountIds.add(order.Account__c);

                 }

               Map<Id, Account> accountsToUpdate = new Map<Id, Account>([SELECT Id, (SELECT Id FROM Orders__r) FROM Account WHERE Id IN :accountIds]);

            for (Account acc : accountsToUpdate.values()) {

             acc.Order_Count__c = acc.Orders__r.size();

              }

             if (!accountsToUpdate.isEmpty()) {

              update accountsToUpdate.values();

                }

                }

                }

  • How would you write a trigger that handles both insert and update events for the Lead object? +

                    trigger LeadTrigger on Lead (before insert, before update) {

                   for (Lead lead : Trigger.new) {

                  if (lead.Status == 'Qualified' && lead.Industry == null) {

                  lead.addError('Industry must be specified for Qualified leads.');

                   }

                 }

                 }

    • Explanation: The trigger runs before both insert and update events, ensuring that the Industry field is populated when the lead’s status is set to Qualified.

    Using Trigger Handler Class :

    Trigger:

            trigger LeadTrigger on Lead (before insert, before update) {

            LeadTriggerHandler.validateQualifiedLead(Trigger.new);

            }

    Handler Class:

              public class LeadTriggerHandler {

             public static void validateQualifiedLead(List<Lead> leads) {

             for (Lead lead : leads) {

            if (lead.Status == 'Qualified' && lead.Industry == null) {

            lead.addError('Industry must be specified for Qualified leads.');

             }

             }

            }

            }

  • How would you write a trigger to prevent the deletion of Account records that have related Opportunities? +

                     trigger PreventAccountDeletion on Account (before delete) {

                     for (Account acc : Trigger.old) {

                    Integer oppCount = [SELECT COUNT() FROM Opportunity WHERE AccountId = :acc.Id];

                   if (oppCount > 0) {

                    acc.addError('Cannot delete account with related opportunities.');

                     }

                    }

                    }

    • Explanation: The trigger checks if an account has related opportunities and prevents the deletion of the account if opportunities exist.

    Using Trigger Handler Class :

    Trigger:

               trigger PreventAccountDeletion on Account (before delete) {

               AccountTriggerHandler.preventAccountDeletionWithOpportunities(Trigger.old);

               }

    Handler Class:

               public class AccountTriggerHandler {

               public static void preventAccountDeletionWithOpportunities(List<Account> oldAccounts)

              {

             for (Account acc : oldAccounts) {

             Integer oppCount = [SELECT COUNT() FROM Opportunity WHERE AccountId = :acc.Id];

            if (oppCount > 0) {

            acc.addError('Cannot delete account with related opportunities.');

            }

            }

             }

           }

  • How would you write a trigger to automatically update a Contact's Last_Contacted_Date__c field whenever a related Task is completed? +

                  trigger UpdateLastContactedDate on Task (after update) {

                  Map<Id, Contact> contactsToUpdate = new Map<Id, Contact>();

                  for (Task task : Trigger.new) {

                 if (task.Status == 'Completed' && task.WhoId != null && task.Who.Type == 'Contact') {

               contactsToUpdate.put(task.WhoId, new Contact(Id = task.WhoId,

               Last_Contacted_Date__c = task.ActivityDate));

                 }

                 }

               update contactsToUpdate.values();

                  }

    • Explanation: The trigger updates the Last_Contacted_Date__c field on a contact whenever a related task is marked as completed.

    Using Trigger Handler Class :

    Trigger:

               trigger UpdateLastContactedDate on Task (after update) {

               TaskTriggerHandler.updateLastContactedDate(Trigger.new);

                 } 

    Handler Class:

                public class TaskTriggerHandler {

                public static void updateLastContactedDate(List<Task> tasks) {

                Map<Id, Contact> contactsToUpdate = new Map<Id, Contact>();

                for (Task task : tasks) {

                 if (task.Status == 'Completed' && task.WhoId != null && task.Who.Type == 'Contact') {

                 contactsToUpdate.put(task.WhoId, new Contact(Id = task.WhoId,

                  Last_Contacted_Date__c = task.ActivityDate));

                  }

                 }

             if (!contactsToUpdate.isEmpty()) {

             update contactsToUpdate.values();

                 }

                }

                }

  • How would you prevent a trigger from running recursively on the Opportunity object? +

                  public class TriggerHelper {

                  public static Boolean isTriggerExecuted = false;

                  }

                trigger OpportunityTrigger on Opportunity (before update) {

               if (TriggerHelper.isTriggerExecuted) return;

                TriggerHelper.isTriggerExecuted = true;

                 for (Opportunity opp : Trigger.new) {

               // Perform logic

                   }

                   }

        • Explanation: A static Boolean variable is used to track whether the trigger has already run, preventing recursive execution.

    Using Trigger Handler Class :

    Trigger:

              trigger OpportunityTrigger on Opportunity (before update) {

              if (TriggerHelper.isTriggerExecuted) return;

             TriggerHelper.isTriggerExecuted = true;

               OpportunityTriggerHandler.handleOpportunityUpdate(Trigger.new);

                }

    Helper Class:

              public class TriggerHelper {

              public static Boolean isTriggerExecuted = false;

                 }

    Handler Class:

               public class OpportunityTriggerHandler {

                public static void handleOpportunityUpdate(List<Opportunity> opportunities) {

               // Implement your logic here

                 }

                 }

  • How would you write a trigger to update the Account's Last_Opportunity _Closed _Date__c when an opportunity is closed? +

                    trigger UpdateAccountOnOpportunityClose on Opportunity (after update) {

                    Map<Id, Account> accountsToUpdate = new Map<Id, Account>();

                   for (Opportunity opp : Trigger.new) {

                  if (opp.StageName == 'Closed Won') {

                 Account acc = accountsToUpdate.get(opp.AccountId);

                 if (acc == null) {

               acc = new Account(Id = opp.AccountId);

               accountsToUpdate.put(acc.Id, acc);

               }

             acc.Last_Opportunity_Closed_Date__c = opp.CloseDate;

              }

             }

             update accountsToUpdate.values();

            }

    • Explanation: The trigger updates the Last_Opportunity_Closed_Date__c field on the account when an opportunity related to that account is closed.

    Using Trigger Handler Class :

    Trigger:

                trigger UpdateAccountOnOpportunityClose on Opportunity (after update) {

                OpportunityTriggerHandler.updateAccountOnOpportunityClose(Trigger.new);

                 }

    Handler Class:

                 public class OpportunityTriggerHandler {

                 public static void updateAccountOnOpportunityClose(List<Opportunity> opportunities) {

                Map<Id, Account> accountsToUpdate = new Map<Id, Account>();

                for (Opportunity opp : opportunities) {

               if (opp.StageName == 'Closed Won') {

               Account acc = accountsToUpdate.get(opp.AccountId);

              if (acc == null) {

              acc = new Account(Id = opp.AccountId);

             accountsToUpdate.put(acc.Id, acc);

              }

               acc.Last_Opportunity_Closed_Date__c = opp.CloseDate;

               }

            if (!accountsToUpdate.isEmpty()) {

           update accountsToUpdate.values();

             }

            }

            }

             }

  • How would you write a test class to verify that a trigger prevents duplicate Contact records based on email? +

    Test Class:

                    @isTest

                    public class ContactTriggerHandlerTest {

                    @isTest

                    static void testPreventDuplicateContacts() {

                    Contact con1 = new Contact(FirstName = 'John', LastName = 'Doe', Email = 'john.doe@example.com');

                   Contact con2 = new Contact(FirstName = 'Jane', LastName = 'Doe', Email = 'john.doe@example.com');

                    insert con1;

                   Test.startTest();

               try {

               insert con2;

               System.assert(false, 'Expected exception not thrown.');

               } catch (DmlException e) {

                System.assert(e.getMessage().contains('A contact with this email already exists.'));

                 }

            Test.stopTest();

               }

                 }

    • Explanation: This test class inserts a contact and then attempts to insert another contact with the same email. It verifies that the trigger prevents the insertion by                         checking for an exception.
  • How would you write a test class to verify that a trigger updates all related Opportunities when an Account's industry changes? +

    Test Class:

    @isTest

    public class AccountTriggerHandlerTest {

    @isTest

    static void testUpdateOpportunitiesOnIndustryChange() {

    Account acc = new Account(Name = 'Test Account', Industry = 'Technology');

    insert acc;

    Opportunity opp = new Opportunity(Name = 'Test Opportunity', AccountId =

    acc.Id, StageName = 'Prospecting', CloseDate = Date.today().addMonths(1));

    insert opp;

    acc.Industry = 'Healthcare';

    Test.startTest();

    update acc;

    Test.stopTest();

    Opportunity updatedOpp = [SELECT Id, Description FROM Opportunity WHERE Id

    = :opp.Id];

    System.assertEquals('Updated due to Account industry change',

    updatedOpp.Description);

    }

    }

    • Explanation: The test class updates an account’s industry and verifies that the related

    opportunity’s description is updated as expected by the trigger.

  • How would you write a test class to ensure a Case record is created when a Contact is inserted? +

    Test Class:

                     @isTest

                     public class ContactTriggerHandlerTest {

                     @isTest

                     static void testCreateCaseOnContactInsert() {

                    Contact con = new Contact(FirstName = 'John', LastName = 'Doe'); Test.startTest();

                      insert con;

                    Test.stopTest();

                    Case createdCase = [SELECT Id, Subject FROM Case WHERE ContactId = :con.Id];

                     System.assertEquals('New Case for Doe', createdCase.Subject);

                       }

                       }

    • Explanation: The test class inserts a contact and checks that a case is automatically created with the correct subject based on the contact’s last name.
  • How would you write a test class to validate that an Opportunity's close date cannot be set to a past date? +

    Test Class:

                         @isTest

                     public class OpportunityTriggerHandlerTest {

                         @isTest

                    static void testValidateCloseDate() {

                  Opportunity opp = new Opportunity(Name = 'Test Opportunity', StageName = 'Prospecting', CloseDate = Date.today().addDays(-1));

                   Test.startTest();

                   try {

                  insert opp;

                 System.assert(false, 'Expected exception not thrown.');

                 } catch (DmlException e) {

                  System.assert(e.getMessage().contains('Close Date cannot be in the past.'));

                  }

              Test.stopTest();

                    }

                     }

    • Explanation: This test class attempts to insert an opportunity with a past close date and verifies that the trigger correctly prevents the insertion.
  • How would you write a test class to verify that a trigger correctly rolls up the count of Order__c records to the parent Account? +

    Test Class:

                    @isTest

                public class OrderTriggerHandlerTest {

                    @isTest

                static void testRollupOrderCount() {

                Account acc = new Account(Name = 'Test Account');

                      insert acc;

                Order__c order1 = new Order__c(Account__c = acc.Id);

                Order__c order2 = new Order__c(Account__c = acc.Id);

                insert new List<Order__c>{order1, order2};

                 Test.startTest();

                 OrderTriggerHandler.updateOrderCount(Trigger.new, null, false);

                   Test.stopTest();

                  Account updatedAccount = [SELECT Order_Count__c FROM Account WHERE Id = :acc.Id];

                  System.assertEquals(2, updatedAccount.Order_Count__c);

    • Explanation: The test class creates an account and two related orders, then verifies that the account’s Order_Count__c field is correctly updated by the trigger.
  • How would you write a test class to verify that a trigger correctly handles both insert and update events for the Lead object? +

    Test Class:

                            @isTest

                   public class LeadTriggerHandlerTest {

                           @isTest

                 static void testLeadTrigger() {

                 Lead lead = new Lead(FirstName = 'John', LastName = 'Doe', Company = 'Test  Company', Status = 'Qualified');

                 Test.startTest();

                      try {

                   insert lead;

                   System.assert(false, 'Expected exception not thrown.');

                     } catch (DmlException e) {

                    System.assert(e.getMessage().contains('Industry must be specified for Qualified leads.'));

                     }

                   lead.Industry = 'Technology';

                   update lead;

                  Test.stopTest();

               Lead updatedLead = [SELECT Industry FROM Lead WHERE Id = :lead.Id];

                    System.assertEquals('Technology', updatedLead.Industry);

                   }

                    }

    • Explanation: The test class first tries to insert a lead without an industry and verifies the trigger prevents it. Then it updates the lead with a valid industry and                               confirms the update is successful.
  • How would you write a test class to ensure that an Account with related Opportunities cannot be deleted? +

    Test Class:

                          @isTest

               public class AccountTriggerHandlerTest {

                         @isTest

               static void testPreventAccountDeletion() {

              Account acc = new Account(Name = 'Test Account');

                       insert acc;

                Opportunity opp = new Opportunity(Name = 'Test Opportunity',

                AccountId = acc.Id, StageName = 'Prospecting', CloseDate = Date.today().addMonths(1));

                 insert opp;

                Test.startTest();

                 try {

                 delete acc;

                 System.assert(false, 'Expected exception not thrown.');

                  } catch (DmlException e) {

                  System.assert(e.getMessage().contains('Cannot delete account with related opportunities.'));

                  }

                  Test.stopTest();

                 }

                  }

    • Explanation: The test class attempts to delete an account that has related opportunities and verifies that the trigger prevents the deletion.
  • How would you write a test class to verify that a trigger correctly updates the Last_Contacted_Date__c field on a Contact when a related Task is completed? +

    Test Class:

                       @isTest

                  public class TaskTriggerHandlerTest {

                       @isTest

                 static void testUpdateLastContactedDate() {

                Contact con = new Contact(FirstName = 'John', LastName = 'Doe');

                  insert con;

                  Task task = new Task(WhoId = con.Id, Status = 'Not Started', ActivityDate = Date.today());

                   insert task;

                  task.Status = 'Completed';

                  Test.startTest();

                   update task;

                   Test.stopTest();

                    Contact updatedContact = [SELECT Last_Contacted_Date__c FROM Contact WHERE Id = :con.Id];

                   System.assertEquals(Date.today(), updatedContact.Last_Contacted_Date__c);

                     }

                      }

    • Explanation: The test class verifies that the Last_Contacted_Date__c field on a contact is correctly updated when a related task is marked as completed.
  • How would you write a test class to ensure that a trigger does not run recursively? +

    Test Class:

                       @isTest

                 public class OpportunityTriggerHandlerTest {

                      @isTest

                 static void testTriggerRecursionPrevention() {

                 // Create an opportunity

                  Opportunity opp = new Opportunity(Name = 'Test Opportunity', StageName = 'Prospecting', CloseDate = Date.today().addMonths(1));

                   insert opp;

                 // Update the opportunity to simulate trigger execution

                   opp.StageName = 'Qualification';

                  Test.startTest();

                     update opp;

                    Test.stopTest();

                 // Since the trigger is designed to prevent recursion,

                // we would check for some indicator in the logic (e.g., a static variable or a field update)

               // Here, we assume that the trigger only modifies the record once

               Opportunity updatedOpp = [SELECT StageName FROM Opportunity WHERE Id = :opp.Id];

               System.assertEquals('Qualification', updatedOpp.StageName); // Assuming no further change by trigger recursion

               }

               }

    • Explanation: The test class creates an opportunity, updates it to trigger the OpportunityTrigger, and verifies that the trigger does not execute recursively by                                 ensuring the StageName remains as updated.
  • How would you write a test class to verify that a trigger correctly updates the Last_Opportunity_Closed_Date__c field on an Account when a related Opportunity is closed? +

    Test Class:

                           @isTest

                    public class OpportunityTriggerHandlerTest {

                          @isTest

                    static void testUpdateAccountOnOpportunityClose() {

                    // Create an account

                   Account acc = new Account(Name = 'Test Account');

                     insert acc;

                  // Create an opportunity related to the account

                   Opportunity opp = new Opportunity(Name = 'Test Opportunity', AccountId =

                 acc.Id, StageName = 'Prospecting', CloseDate = Date.today().addMonths(1));

                    insert opp;

                  // Update the opportunity to 'Closed Won'

                  opp.StageName = 'Closed Won';

                  opp.CloseDate = Date.today();

                  Test.startTest();

                   update opp;

                 Test.stopTest();

               // Verify the Account's Last_Opportunity_Closed_Date__c field was updated

                 Account updatedAccount = [SELECT Last_Opportunity_Closed_Date__c FROM

                 Account WHERE Id = :acc.Id];

                 System.assertEquals(Date.today(),

                updatedAccount.Last_Opportunity_Closed_Date__c);

                  }

                   }

    • Explanation: The test class verifies that the Last_Opportunity_Closed_Date__c field on the account is updated correctly when the related opportunity is marked                         as Closed Won. The trigger ensures that this date is set based on the opportunity’s CloseDate when the opportunity is closed.