Apex Interview
Apex Interview
Apex Interview
Ans: Since salesforce runs on multi-tenant environment and in order to have the same performance to the
database, it has imposed some run time limits called as governor limits.
Some governor limits are:
a. Pre Transaction Apex Limits:
These limits count for each apex transaction. For Batch Apex, these limits are
reset for each execution of a batch of records in the execute method.
Viz:
These types of queries have limits of three times the limits of top-level queries. The limits for sub-queries corresponds to
the value that Limits.getLimitAggregrateQueries() return. The row counts for these relationship queries contribute to
the row counts of the overall code execution.
In the above query there are a total of 3 subqueries + 1 parent query. So, in total there are 4 queries. But, Salesforce
doesn’t count subqueries against governor limits of 100 SOQLs. It only counts root query which means only 1 SOQL
query would be consumed.
Subqueries are counted separately as AggregateQueries. You can check those with Limits.getAggregateQueries() and
Limits.getLimitAggregateQueries(). You cannot have more than 300 aggregations in a single transaction.
This limit does not apply to custom metadata types. In a single Apex transaction custom metadata records can have
unlimited SOQL queries. (Although there is one exception that:
a. When you query a long text area field from metadata it does count against the limits.)
In addition to static SOQL statements, calls to the following methods count against the number of SOQL statements
issued in a request:
a. Database.countQuery ----
i. Returns the number of records that a dynamic SOQL query would return when
executed. Its return value is Integer.
ii. Database.countQuery cannot be used for non-count queries.
b. Database.getQueryLocator
c. Database.query
b. Total number of records retrieved by a single SOQL query---50,000
c. Total number of records retrieved by Database.QueryLocator----10,000 Commented [PG1]: Learn more on this
d. Total number of SOSl queries---20 Database.QueryLocator
e. Total number of records retrieved by a single SOSL query---2,000
Commented [PG2]: More about SOSL and its use cases.
b. Static Apex Limits:
a. Default timeout for callouts (HTTP requests or Web Service calls) in a single transaction---10 seconds.
b. Maximum size of the callout request or response (HTTP requests or Web Service calls) ---6 mb for
Synchronous and 12 mb for asynchronous.
c. Maximum number of class and trigger code units in a deployment of Apex---5000
c. Lightning Platform Apex Limits:
These limits are not specific to apex transaction and are solely enforced by Lightning Platform.
Other limits include Pre-Transaction certified managed package limits, push notification limits, API request limits and
allocations, Bulk API limits, Chatter REST API limits, SOAP API limits, visual force limits,
Metadata Limits:
These limits apply to Force.com IDE, the Ant Migration Tool, and the Metadata API. As for example you can deploy or
retrieve up to 10,000 files of meta data at once and the maximum size is 39mb. Inbound or outbound change sets can
have 10,000 files of metadata.
ANS: Multi-Tenant architecture is something where a single instance of a software runs on a server,
serving multiple client organizations(tenants). It’s like placing the data from multiple companies (org in
Salesforce) on the same server, generally separating them from each other via a simple partition that prevents
the data from migrating from one company to another or put forward in a simple way it’s like an apartment
building where all residents/tenants share the space or portions with each other. Just like a tenant does not own
the house he is living in, a cloud tenant also does not own the data. He is simply paying for the data storage of
his data elsewhere.
Benefits:
Cost savings.
No upgrades headache for the client (and faster and smoother upgrade for vendor).
Flexibility.
Scalability.
High performance
Low operational costs etc.
DML operations on certain sObjects, sometimes referred to as setup objects cannot be mixed with DML on other
sObjects on the same transaction. This restriction exists because some sObjects affect the user’s access to
records in the org.
You must insert or update these types of sObjects in a different transaction to prevent operations from
happening with incorrect access-level permissions.
Example: You cannot update account and a user role in a single transaction. However, deleting a DML operation
has no restrictions.
You cannot use the following sObjects with other sObjects when performing DML operations in the same
transaction.
a. FieldPermissions
b. Group
c. GroupMember
d. ObjectPermissions
e. PermissionSet
f. PermissionSetAssignment
g. QueuesObject
h. ObjectTerritory2AssignmentRule
i. ObjectTerritory2AssignmentRuleItem
j. RuleTerritory2Association
k. SetupEntityAccess
l. Territory2
m. Territory2Model
n. UserTerritory2Association
o. User
p. UserRole
q. UserTerritory
r. Territory
Although you can perform DML operations on more than one type of sObject in a single class using the following
process:
1. Create a method that performs DML operation on one type of sObject.
2. Create a second method that uses the future annotation to manipulate a second sObject type. (Example
below)
Mixed DML Operations in Test Methods:
Test methods allow for performing mixed Data Manipulation Language (DML) operations that include both setup
sObjects and other sObjects if the code that does the DML operation is enclosed within System.runAs method blocks.
Example:
As we know that Mixed DML operations within a single transaction is not allowed. You can’t perform DML on a setup
sObject and another sObject on the same transaction.
However, you can perform one type of DML as part of an asynchronous job and the other in the original transaction.
The following class contains a @future method to be called by the class in the subsequent example:
NOTE: All standard and custom objects can also be accessed through the SOAP API. ProcessInstance is an exception. You
can’t create, update or delete ProcessInstance in the SOAP API.
3. a. Future Methods:
@future annotation is used to define a future method (a method that runs asynchronously). The method must
be static and return type of the method should be void and take primitive data types or arrays of primitive data
types or collections of primitive data types as arguments. Notably, future methods can’t take standard or
custom objects as arguments. A common pattern is to pass the method with a List of record IDs that you want to
process asynchronously.
NOTE: The reason why objects can’t be passed as arguments to future methods is because the object can
change between the time you call the method and the time that it actually executes. Remember, future
methods are executed when system resources become available. In this case, the future method may have an
old object value when it actually executes, which can cause all sorts of bad things to happen.
It’s important to note that future methods are not guaranteed to execute in the same order as they are called. If
you need this type of functionality, then Queue able Apex might be a better solution. When using future
methods, it’s also possible that two future methods could run concurrently, which could result in record locking
and a nasty runtime error if the two methods were updating the same record.
For both cases SOQL Limit is 50,000 records per transaction. Generally Asynchronous processes have
higher governor limits compared to synchronous apex.
*****
https://developer.salesforce.com/docs/atlas.enus.apexcode.meta/apexcode/apex_dml_non_mix_sobjects.htm
Inserting a User with a non-null role must be done in a separate thread from DML operations on other sObjects. The
following example uses a future method to achieve this:
This is the class containing the main method that calls the future method declared above:
Limitations to be kept in mind:
3. You can invoke future methods the same way as you invoke normal methods. However a future method
cannot invoke another future method.
4. No more than 50 method calls per Apex transaction.
5. The max number of future method invocations per a 24 hr period is 250000 or the number of licenses
(Standard Salesforce and App subscription licences) in your org multiplied by 200, whichever is greater.
6. The limit in your entire org is shared with all asynchronous apex: Batch Apex, Queueable Apex,
Scheduled Apex and Future methods.
To test future methods, call the class containing the method in a startTest(), stopTest() code block.
All the asynchronous calls made after the startTest method are collected by the system. When stopTest is executed,
all asynchronous processes are run synchronously.
Avoid adding large numbers of future methods to the asynchronous queue, if possible. If more than 2,000
unprocessed requests from a single organization are in the queue, any additional requests from the same
organization will be delayed while the queue handles requests from other organizations.
Ensure that future methods execute as fast as possible. To ensure fast execution of batch jobs, minimize Web
service callout times and tune queries used in your future methods.
Test your future methods at scale. This will help determine if delays will occur.
Consider using batch Apex instead of future methods to process large numbers of records.
For Apex processes that run for a long time like data base operations or external web service callouts, one can
run them asynchronously by implementing the Queueable interface and adding a job to the Apex job queue.
In this way the asynchronous job runs in the background in its own thread and does not delay the execution of
your main apex logic.
Each queued jobs run only when the system resources become available.
a. Queueable apex jobs are similar to future methods with some added extra functionalities as:
1. Getting an ID for your job: When you submit your job by invoking the System.enqueueJob method, the
method returns the ID of the new job. This ID corresponds to the ID of the AsyncApexJob record. You can
use this id to identify your job and monitor your progress either through Salesforce UI in the Apex jobs page
or programmatically querying your record from AsyncApexJob.
2. Using non-primitive types: Your Queueable class contains member variables of non-primitive data types, such
as sObjects or custom Apex types. Those objects can be accessed when the job executes.
IMPORTANT:
One important point of difference is the methods inside the Queueable Apex class should not be static unlike
future methods but the return type should be void.
To call this class now from Anonymous Block call the following method like:
ID jobID = System.enqueueJob(new AsyncExecutionExample()); // to fetch the id of the apex job
AsyncApexJob jobInfo = [SELECT Status,NumberOfErrors FROM AsyncApexJob WHERE Id=:jobID];
System.debug(jobInfo);
3. Chaining Jobs: You can chain one job to another by starting a second job from a running job. Chaining Jobs is
useful when you wish to do some processing that depends on another process to have run first.
Example:
5. Apex Scheduler:
To invoke apex classes to run at specific times, first implement the Schedulable interface class, then specify the
Schedule using either the Schedule Apex Page in Salesforce UI or the System.Schedule method.
You can have 100 scheduled Apex Jobs at one time.
You can programmatically query the CronTrigger and CronJobDetail objects to get the count of the Apex
Scheduled Jobs.
Extreme care should be taken if planning to schedule a class from a Trigger. One must ensure that the
trigger won’t add more scheduled classes than the limit. In particular consider the API Bulk updates,
import wizards, mass record changes through User Interface, and all cases where more than one record
can be updated at a time.
If there are one or more active Scheduled Jobs for an Apex Class, you cannot update the class or any
classes referenced by this class through Salesforce UI. However you can enable deployments to update
the class with active Scheduled Jobs by using Metadata API.
Extreme care should be taken if planning to schedule a class from a Trigger. One must ensure that the
trigger won’t add more scheduled classes than the limit. In particular consider the API Bulk updates,
import wizards, mass record changes through User Interface, and all cases where more than one record
can be updated at a time.
Batch Jobs can be programmatically scheduled to run at specific times using Apex Scheduler or using the
Schedule Apex Page in Salesforce User Interface.
Before TRIGGER:
The key thing to remember is that in before Triggers the record is not yet committed to the database, which
means you can’t query on those records in Trigger.New. Something like:
Won’t work in before insert trigger because the records are still not there but will work for before update
Triggers.
Formula fields won’t be available in before insert Triggers as well.
The major advantage of before Trigger is you can modify the values of Trigger.New and by doing so you don’t
need an additional DML to modify the data. So if you need to modify the values in Trigger.New before Triggers
are better option.
a. Before Triggers should be used when you want to do some custom validation checks on the same
object.
b. Update the same record/object.
c. Setting a default value.
AFTER TRIGGER:
In after Triggers the records are already changed in the database. So you can query the records. But since the
data manipulation is already done. You can’t modify the value in Trigger.New.
But still if you want to modify the values of the same record in an after Trigger you will have to generate a new List.
Something like:
List<Account> acclist= new List<account> ();
For (Account acc: Trigger.New)
{
Account newAcc= new Account();
newAcc.id= acc.Id;
newAcc.Name = acc.Name +’Test’;
acclist.add(newAcc);
}
Update acclist;
The above functionality could have been easily achieved in a before Trigger.
7. What are the assert methods under System class? Use cases for each of the methods.
ANS: There are three assert methods under System class. They are:
a. System.assert(condition,msg) : This method asserts that the specified condition is true. If it is not true, a
fatal error is returned that causes code execution to a halt.
The method has two parameters, one
is condition which is of Boolean type and msg which is optional and of object type.
b. System.assertEquals(expected,actual,msg) : This method asserts that the first two conditions are same.
If it is not true, a fatal error is returned that causes code execution to a halt.
This method has three parameters,
one is expected which is of type object, 2nd is actual which is also of type object and the 3rd is msg which is
optional and of type object.
c. System.assertnotEquals(expected,actual,msg) : This method asserts that the first two conditions are
not same. . If they are same, a fatal error is returned that causes code execution to a halt.
This method has three
parameters, one is expected which is of type object, 2nd is actual which is also of type object and the
3rd is msg which is optional and of type object.
Viz: System.assertnotEquals(2008, Today.Year(), ‘It is not 2008, You are correct);
Each Salesforce record is represented as an sObject before it is inserted into Salesforce. Similarly when persisted records
are retrieved from Salesforce they are stored in sObject variable.
Unlike specific sObject types generic sObjects can be created only through the newSObject() method. Also the fields in
generic sObject can be accessed only through the put() and get() methods.
10. What is Schema Class? And also mention some use cases for the same.
ANS:
a. Schema Describe is a way to programmatically learn about the metadata of your data model in Apex.
b. Schema Describe calls provides the ability to programmatically describe the information about the current org
schema such as list of top level objects including custom objects and their fields.
Returns map of all sObjects names or keys to sObject tokens or values for the standard and custom objects
defined in the organization.
c. We can also use SchemaDescribe() to create tree structure of all objects and fields in the schema browser, to do
this we need to use the codemap.
The following are the methods for Schema. All the methods are static.
a. getGlobalDescribe()
Returns a map of all sObject names(keys) to sObject tokens(values) for the standard and custom object defined
in your organization.
Return value: Map<String,Schema.SObjectType>
b. describeDataCategoryGroups(List<String>)
Returns a list of category groups associated with the specified
objects. The describeDataCategoryGroups method returns a Schema.DescribeDataCategoryGroupResult object
containing the list of the category groups associated with the specified object.
Return value: List<Schema.DescribeDataCategoryGroupResult>
The following is an example of how to instantiate a data category group describe result object:
List <String> objType = new List<String>();
objType.add('KnowledgeArticleVersion');
objType.add('Question');
List<Schema.DescribeDataCategoryGroupResult> describeCategoryResult =
Schema.describeDataCategoryGroups(objType);
c. describeSObjects(List<String>)
Describes metadata only i.e object properties for the specified sObject or array of sObjects.
Return value: List<Schema.DescribeSObjectResult>
Schema.DescribeSObjectResult[] descResult =
Schema.describeSObjects(new String[]{'Account','Contact'});
d. describeTabs()
Returns the information about the standard and custom apps available to the running user.
Return value: List<Schema.DescribeTabSetResult>
e. describeDataCategoryGroupStructures(List<Schema.DataCategoryGroupSobjectTypePair>)
Returns available category groups along with their data category structure for objects specified in the request.
Return value: List<Schema.DescribeDataCategoryGroupStructureResult>
To create a dynamic SOQL query at runtime, use the database query method, in one of the following ways:
a. Return a single SObject when the query returns a single record:
sObject s = Database.query(string_limit_1);
b. Return a list of the sObjects when the query returns more than one record:
The dynamic SOQL can be used anywhere where an inline SOQL query can be used.
Dynamic SOQL results can be specified as concrete sObjects or generic sObject data type. At run time, the system
validates that the type of the query matches the declared type of the variable. If the query doesnot return the
correct sObject type, a run time error is thrown.
i. You can use simple bind variables in dynamic SOQL query strings. The following is allowed:
ii. However like inline SOQL, dynamic SOQL can’t use bind variables field in the query string. The
following example will throw an error i.e. Variable does not exist.
iii. You can instead resolve the variable field into a string and use the string in your dynamic SOQL
query:
To prevent SOQL injection, use the escapeSingleQuotes method. This method adds the escape character (\) to all single
quotation marks in a string that is passed from the user. This method ensures that all single quotation marks are treated
as enclosing strings instead of database commands.
Sample SOSL:
FIND (‘Wingo’) IN ALL FIELDS RETURNING Account(Name), Contact(FirstName,LastName,Department)
------To be used for Apex.
1. SearchQuery is the text to search for (a single word or a phrase). Search terms can be grouped with
logical operators (AND, OR) and parenthesis.
2. Also search terms can include wildcard characters (*,?). The * wildcard matches zero or more characters
at the middle or the end of the search term. The ? card matches only one term at the middle or end of
the search term.
3. Text searches are case insensitive.
4. SearchGroup is optional. It is the scope of the fields to search. If not specified, the default search scope
is all fields. SearchGroup can take one of the following values:
a. ALL FIELDS
b. NAME FIELDS
c. EMAIL FIELDS
d. PHONE FIELDS
e. SIDEBAR FIELDS
5. ObjectsAndFields is optional. It is the information to return in the search results a list of one or more
sObjects and within each sObject list of one or more fields. If not specified the search results contains ID
of all objects found.
SOQL SOSL
Only one standard or custom object at a time can be Multiple or even the entire organization or database can
queried be queried in a single SOSL query.
Cn query all type of fields Can query only email, text or phone type of fields.
It can be used in classes and triggers. It can be used in classes but not in triggers.
DML operations can be performed with the queried DML operations cannot be performed with the searched
records. records.
Use SOQL to retrieve records for a single object. Use SOSL to search fields across multiple objects.
The visibility of a test method doesn’t matter, so declaring a test method as public or private does not make any
difference as the testing framework is always able to access test methods. For this reason access modifiers are omitted
in the syntax.
@isTest
Private class MyTestClass{
@isTest static void myTest(){
//code block
}
}
Test classes can be public or private. If you are using Test classes for unit testing only, declare it private. Public test
classes are generally used for test data factory classes.
a. Even though it is not a best practice but there are times when the test method needs access to preexisting
data.
b. To access org data, annotate the test method with @isTest(SeeAllData = true)
c. You can save upto 6 mb of apex code in each org. Test classes annotated with @isTest don’t count towards
this limit.
d. Each though test data rolls back once execution is finished, but no separate database is used for testing. As a
result some of the sObjects that have fields with unique constraints, inserting duplicate sObject records
results in error.
e. Test methods can’t make callouts to external services. But you can use mock callouts in Tests.
f. SOSL searches performed in a test returns empty results. To ensure predictable results, use
Test.setFixedSearchResults() to define the records to be returned by the search.
i. Public test utility classes are defined with the isTest annotation, and as such are excluded from the organization
code size limit and execute in test context.
ii. They can be called by test methods but not non-test code.
iii. The methods in the public test utility classes are defined in the same way as methods in the non-test classes.
They can take parameters and can return some value.
iv. The methods should be declared as public or global to be visible to other test classes.
v. These common methods can be called by any Apex classes to set up test data before running the test.
vi. While you can create public utility methods for test data creation in regular Apex classes, without the isTest
annotation you don’t get the benefit of excluding this code from organization code size limit.
A trigger is an apex code that executes before or after the following types of operations:
g. Insert
h. Update
i. Delete
j. Merge
k. Upsert
l. Undelete
There are two types of Triggers:
a. Before Triggers: It is used to update or validate records before they are saved to the
database.
b. After Triggers: It is used to access values of the record that are stored in the database
and use this values to make changes to other related records. After triggers are read
only.
b. isInsert: Returns true if the Trigger was fired due to an Insert operation.
c. isUpdate : Returns true if the trigger was fired due to an Update operation.
d. isDelete: Returns true if the Trigger was fired due to a delete operation.
e. isBefore: Returns true if the trigger was fired before any record was saved.
f. isAfter : Returns true if the Trigger was fired after all records were saved.
h. new: Returns a list of the new versions of the sObject records. This sObject list is only available in insert, update
and undelete triggers and the records can only be modified in before Triggers.
i. newMap : A map of IDs to the new version of the sObject records. This map is only available in after insert,
before update, after update and after undelete triggers.
j. old: Returns a list of the old versions of the sObject records. This sObject list is only available in update and
delete triggers.
k. oldMap: Returns a map of IDs of the old versions of the sObject records. This map is only available in update and
delete records.
l. size : Returns the total number of records in a trigger invocation, both old and new.
The following are the list of considerations about actions of different Trigger Events.
Trigger Event Can change fields using Can update original object Can delete original object
Trigger.New using an update DML using a delete DML
operation. operation.
Beforeinsert Allowed. Not Applicable. Not Applicable.
Beforeupdate Allowed. Not allowed. A run time Not allowed. A runtime
error is thrown. error is thrown.
Beforedelete Not allowed. A run time Allowed. Update by DML Not allowed.
error is thrown. means you have to create a
Trigger.new is not available copy of the object from
in before delete Triggers. Trigger.old, then execute
the update call using that
copy.
afterinsert Not allowed. A runtime Allowed. Allowed but unnecessary.
error is thrown as The object is deleted
trigger.new is already immediately after being
saved. inserted.
Afterupdate Not allowed. A runtime Allowed. Allowed.
error is thrown as
trigger.new is already
saved.
Afterdelete Not allowed. A runtime Not applicable. Not applicable.
error is thrown as
Trigger.New is not available
in after delete triggers.
afterUndelete Allowed. But not allowed Allowed. Allowed, but unnecessary.
for Trigger.old because
Trigger.old is not available
in after undelete trigger.
17. Name on thing that cannot be built with Declarative Tools in Salesforce?
ANS: Buiding a connection or integration with third-party systems.
18. Name one standard object which also acts as junction object.
ANS:
a. Opportunity Contact Role is a junction object between Opportunity and Contact.
b. Quote is a junction object between Contract and Opportunity.
c. Opportunity Product (API name: OpportunityLineItem) is a junction object between Opportunity and Product2.
d. PriceBookEntry is a junction object between Product2 and PriceBook2.
The following examples illustrate how you can use custom settings:
A shipping application requires users to fill in the country codes for international deliveries. By creating a
list setting of all country codes, users have quick access to this data without needing to query the
database.
An application displays a map of account locations, the best route to take, and traffic conditions. This
information is useful for sales reps, but account executives only want to see account locations. By
creating a hierarchy setting with custom checkbox fields for route and traffic, you can enable this data
for just the “Sales Rep” profile.
NOTE: If you want to migrate the records consider using custom metadata types instead of custom list settings.
However querying custom settings data using SOQL does not make use of the application cache and is similar to
querying a custom object. To benefit from caching use Apex custom settings method.
Benefits:
Reusability: with your logic inside a class, you can reuse it outside of triggers, for example in a visualforce page,
test class, batch apex etc.
Simplicity: every “trigger” gets reduced to just two lines of code in the master trigger. An object oriented code
base is more organized, predictable, and modular too.
Control your order of execution: in Apex the order of execution isn’t guaranteed for multiple triggers on the
same object. This pattern gives you total control.
16. Write a SOQL query that counts the number of active Contacts for each Account in a set.
ANS:
List<Account> acc = Database.query('Select Id from Account');
System.debug(acc);
Set<Id> stAccIds = (new Map<Id,Account>(acc)).keyset();
System.debug(stAccIds);
Map<Id,Integer> accountIdsWithContact = new Map<Id,Integer>();
for(Account accs: [Select Id, Name, (Select Id from Contacts) from Account where Id In:stAccIds]){
accountIdsWithContact.put(accs.id,accs.Contacts.size());
}
System.debug(accountIdsWithContact);
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm
https://success.salesforce.com/answers?id=90630000000DQzEAAW
Integration Basics:
a. API stands for Application Programming Interface which means basically something that allows one
piece of software to talk to another software.