Salesforce-Platform-Developer-II Exam Questions With Explanations

The best Salesforce-Platform-Developer-II practice exam questions with research based explanations of each question will help you Prepare & Pass the exam!

Over 15K Students have given a five star review to SalesforceKing

Why choose our Practice Test

By familiarizing yourself with the Salesforce-Platform-Developer-II exam format and question types, you can reduce test-day anxiety and improve your overall performance.

Up-to-date Content

Ensure you're studying with the latest exam objectives and content.

Unlimited Retakes

We offer unlimited retakes, ensuring you'll prepare each questions properly.

Realistic Exam Questions

Experience exam-like questions designed to mirror the actual Salesforce-Platform-Developer-II test.

Targeted Learning

Detailed explanations help you understand the reasoning behind correct and incorrect answers.

Increased Confidence

The more you practice, the more confident you will become in your knowledge to pass the exam.

Study whenever you want, from any place in the world.

Salesforce Salesforce-Platform-Developer-II Exam Sample Questions 2026

Start practicing today and take the fast track to becoming Salesforce Salesforce-Platform-Developer-II certified.

22024 already prepared
Salesforce 2026 Release
202 Questions
4.9/5.0

A Visuzlforce page loads slowly due to the large amount of data it displays. Which strategy can a developer use to improve the performance?

A. Use lazy loading to load the data on demand, instead of in the controller's constructor.

B. Use an apex:actionPoller in the page to load all of the data asynchronously.

C. Use the transient keyword for the List variables used in the custom controller.

D. Use Javascript to move data processing to the browser instead of the controller.

A.   Use lazy loading to load the data on demand, instead of in the controller's constructor.

Explanation:

To improve the performance of a Visualforce page that is slow due to loading a large amount of data, it's essential to optimize both the amount of data retrieved and when it is retrieved. Performance bottlenecks are often caused by querying too much data up front or processing it unnecessarily on the server side during page load.

✅ Correct Answer: A. Use lazy loading to load the data on demand, instead of in the controller's constructor.
Lazy loading is a best practice in Visualforce development when dealing with large datasets. Instead of loading all data in the controller's constructor (which executes before the page renders), you defer the loading of data until it's actually needed — such as through a button click or an AJAX request. This results in faster initial page loads, reduced memory usage, and better user experience.
For example, rather than loading thousands of records when the page opens, you can load only a few or none, and fetch more when the user interacts.
This approach is often implemented using action functions, remote actions, or components.

❌ Option B: Use an apex:actionPoller in the page to load all of the data asynchronously.
This is incomplete and cannot be evaluated as a valid answer. It may have been cut off or incorrectly written. If this was meant to reference something like or another technique, it needs full context.

❌ Option C: Use the transient keyword for the List variables used in the custom controller.
The transient keyword is used to avoid storing non-essential view state variables in the Visualforce page state. While it helps reduce view state size, it does NOT improve initial data load performance — especially if data is still queried in the constructor. Additionally, transient variables are reset on postback, so they cannot hold data across requests unless re-queried.
View state optimization is helpful, but it’s not the best solution for slow page load caused by querying large volumes of data.

❌ Option D: Use JavaScript to move data processing to the browser instead of the controller.
While client-side processing with JavaScript can improve interactivity and reduce server calls, this option does not help with the initial load time if the data is still being queried and rendered server-side via Apex. Also, pushing large data sets to the browser can increase memory usage and affect performance negatively.
This approach is better suited for lightweight client-side calculations or UI manipulation after data has been loaded, not for managing large data volumes initially.

📚 References:
Salesforce Developer Guide: Improve Visualforce Page Performance
Salesforce Trailhead – Visualforce Performance Optimization
Visualforce Lazy Loading Techniques

An org has a requirement that an Account must always have one and only one Contact listed as Primary. So selecting one Contact will de-select any others. The client wants a checkbox on the Contact called 'Is Primary’ to control this feature. The client also wants to ensure that the last name of every Contact is stored entirely in uppercase characters. What is the optimal way to implement these requirements?

A. Write a Validation Rule on the Contact for the Is Primary logic and a before update trigger on Contact for the last name logic.

B. Write an after update trigger on Contact for the Is Primary logic and a separate before update trigger on Contact for the last name logic.

C. Write a single trigger on Contact for both after update and before update and callout to helper classes to handle each set of logic.

D. Write an after update trigger on Account for the Is Primary logic and a before update trigger on Contact for the last name logic.

C.   Write a single trigger on Contact for both after update and before update and callout to helper classes to handle each set of logic.

Explanation:

✅ Correct Answer: C. Write a single trigger on Contact for both after update and before update and call out to helper classes to handle each set of logic 🧠
This is the optimal solution because it efficiently separates concerns while maintaining performance, scalability, and testability. Salesforce encourages developers to follow best practices by using a single trigger per object and delegating business logic to helper classes. This architecture ensures clean, modular code that is easier to maintain and extend.

The requirement to enforce only one Contact marked as "Is Primary" per Account needs to be handled after DML because it may require reviewing or updating other sibling contacts—records not necessarily in the trigger context. Therefore, it’s appropriate to handle this logic in the after update or after insert context, where all related records can be queried and modified accordingly.

On the other hand, the requirement to store the Contact’s last name in uppercase is best addressed in the before update or before insert context. This way, the data is modified before it hits the database, avoiding unnecessary updates or recursion. By combining both trigger events (before and after) in a single trigger, and delegating the logic to a helper class or service class, the solution remains clean and adheres to Salesforce's governor limits and coding standards.

❌ Option A: Write a Validation Rule on the Contact for the Is Primary logic and a before update trigger on Contact for the last name logic ⚠️
Using a Validation Rule to enforce the "only one primary contact per account" requirement is not viable. Validation rules cannot perform cross-record comparisons or updates. They can only evaluate conditions on the current record or related parent fields, not sibling records. Since this use case requires scanning all Contacts related to an Account to ensure only one is marked as primary, a validation rule cannot satisfy this constraint.

While the second part—converting the last name to uppercase—is fine in a before update trigger, relying on validation rules for complex data integrity enforcement that involves multiple records leads to limitations. This approach would leave the primary contact logic incomplete and prone to failure if multiple users attempt updates concurrently.

❌ Option B: Write an after update trigger on Contact for the Is Primary logic and a separate before update trigger on Contact for the last name logic 🧩
While technically correct, this approach violates the “one trigger per object” best practice. Having multiple triggers on the same object leads to maintenance problems, ordering conflicts, and increased risk of recursion or redundant logic. Salesforce does not guarantee trigger execution order when more than one trigger exists for the same object and event, which can lead to unpredictable behavior.

Moreover, splitting the logic into separate triggers for before update and after update increases complexity and decreases traceability. Even though this would work functionally, it is not optimal for long-term maintainability and testability. A unified trigger with clear delegation to helper classes is the more scalable solution.

❌ Option D: Write an after update trigger on Account for the Is Primary logic and a before update trigger on Contact for the last name logic ❌
This option mistakenly places the primary contact logic on the Account object, which is incorrect. The checkbox indicating whether a Contact is primary resides on the Contact record, and the logic that ensures only one is selected must execute in response to Contact changes, not Account changes. Using an Account trigger for this would require querying and acting upon unrelated child records and could introduce unnecessary complexity and performance issues.

Additionally, although the before update trigger for capitalizing the last name is appropriate, splitting the logic between two object triggers and two different scopes complicates the codebase. This design is not aligned with the principle of handling logic on the object that owns the field being changed.

Reference:
Trigger Context Variables
Trigger and Bulk Request Best Practices

A developer wrote a trigger on Opportunity that will update a custom Last Sold Date field on the Opportunity's Account whenever an Opportunity is closed. In the test class for the trigger, the assertion to validate the Last Sold Date field fails. What might be causing the failed assertion?

A. The test class has not defined an Account owner when inserting the test data.

B. The test class has not implemented seealldata=true in the test method.

C. The test class has not re-queried the Account record after updating the Opportunity.

D. The test class is not using System. runs () to run tests as a Salesforce administrator.

C.   The test class has not re-queried the Account record after updating the Opportunity.

Explanation:

To understand why the assertion fails in this trigger test scenario, we need to focus on how data is handled in Apex tests, especially regarding trigger behavior and record state in memory vs. the database.

✅ Correct Answer: C. The test class has not re-queried the Account record after updating the Opportunity.

✅ Explanation:
When you update a record in Apex (like an Opportunity), any related changes made by triggers (like updating a field on the parent Account) occur in the database. However, the in-memory version of the Account (from earlier in the test method) does not automatically reflect those changes.
So, if your trigger updates the Last_Sold_Date__c field on Account when an Opportunity is closed, but the test class does not perform a fresh SOQL query to retrieve the updated Account, then any assertion against that field will still reflect the old value (likely null) — causing the test to fail.

✅ Proper fix in the test class:
Account acct = [SELECT Id, Last_Sold_Date__c FROM Account WHERE Id = :accountId];
System.assertEquals(expectedDate, acct.Last_Sold_Date__c);

🔗 Reference: Salesforce Developer Docs – Testing Triggers

❌ A. The test class has not defined an Account owner when inserting the test data.
This is not necessary unless your trigger or validation rules explicitly depend on OwnerId. Salesforce assigns a default owner (usually the running user) if none is provided. So this won’t affect the Last_Sold_Date__c update unless additional logic is involved (not mentioned here).

❌ B. The test class has not implemented seeAllData=true in the test method.
Using seeAllData=true is discouraged and unnecessary here. Since you're inserting test Account and Opportunity records within the test method, no real org data is required. The test should work with only mock/test data.

❌ D. The test class is not using System.runAs() to run tests as a Salesforce administrator.
System.runAs() is used to test behavior under different user roles or profiles (e.g., field-level security or sharing rules). It is not required for triggers to function unless access issues are part of the logic. Again, this isn’t relevant in the scenario described.

✅ Final Verdict:
C. The test class has not re-queried the Account record after updating the Opportunity is the correct answer because without re-querying, the test accesses stale data, leading to a failed assertion.

A developer implemented a custom data table in a Lightning web component with filter functionality. However, users are submitting support tickets about long load times when the filters are changed. The component uses an Apex method that is called to query for records based on the selected filters. What should the developer do to improve performance of the component?

A. Return all records into a list when the component is created and filter the array In JavaScript.

B. Use a selective SOQL query with a custom Index.

C. Use SOSL to query the records on filter change.

D. Use setstoraclel() in the Apex method to store the response In the client-side cache.

B.   Use a selective SOQL query with a custom Index.

Explanation:

🔍 Question Context Recap
A Lightning Web Component (LWC) is experiencing long load times when filters are changed. Each time the user changes a filter, an Apex method is invoked that queries Salesforce records using SOQL (Salesforce Object Query Language). The issue is clearly related to inefficient querying, causing performance bottlenecks.

✅ Correct Answer: B. Use a selective SOQL query with a custom Index

🔧 What is a Selective SOQL Query?
A selective SOQL query is a query that uses selective filters (like indexed fields) to limit the number of records retrieved from the database. Salesforce strongly encourages the use of selective queries because they optimize performance, especially in large data sets.
A query is considered selective when it filters on an indexed field and does not scan a large percentage of the data (generally less than 10% of records in a large object).
Non-selective queries can lead to full table scans, which are expensive and slow, especially when the object contains hundreds of thousands or millions of records.

🔎 What is a Custom Index?

While some fields (e.g., Id, Name, CreatedDate, LastModifiedDate) are automatically indexed by Salesforce, custom fields are not indexed by default.

However, Salesforce allows you to request a custom index on a field by contacting Salesforce Support. Fields that are often good candidates for custom indexing include:
Fields frequently used in WHERE clauses.
Fields used in filters on reports or Apex queries.
Fields with a good amount of selectivity (i.e., the field values vary widely across records).

✅ Why This Solves the Problem:
When filters are applied in the LWC, the Apex method uses them in a SOQL query.
If that query is non-selective (e.g., filtering on a non-indexed custom field), Salesforce may scan the entire table to find matching records, causing delays.
By indexing the relevant filter fields and designing the SOQL query to use highly selective filters, the query performance improves drastically, reducing the page’s loading time.

❌ Explanation of Incorrect Options:


❌ A. Return all records into a list when the component is created and filter the array in JavaScript

Why it’s wrong:
This approach means loading all records at once into the client (browser) — which is a huge performance and scalability issue.
It violates the principle of lazy loading or on-demand querying, which is necessary in applications with potentially thousands of records.
It may hit governor limits (especially the heap size limit) in Apex, leading to runtime errors.
It’s also a security risk, as users might receive data they are not authorized to see.

❌ C. Use SOSL to query the records on filter change

Why it’s wrong:
SOSL (Salesforce Object Search Language) is designed for full-text search across multiple objects.
It is optimal when you need to search across multiple fields or multiple objects for a keyword (e.g., global search).
In this scenario, you are querying specific fields with filters, so SOQL is the correct tool.
SOSL is not filter-oriented and does not support complex filtering like SOQL.
Using SOSL may actually lead to less accurate or irrelevant results and poor performance if misused.

❌ D. Use setStorable() in the Apex method to store the response in the client-side cache

Why it’s wrong:
setStorable() is used to cache Apex method results on the client side to avoid repeat server trips. While it helps reduce server round-trips, it does not improve the performance of the Apex method itself.
In this case, the problem occurs every time filters change, triggering a new query, which means the results are not cached unless the exact same filter was used before.
It’s a good technique for read-heavy, rarely changing data, but not useful when the filters dynamically change.

📘 Real-World Example and Reference:
Imagine querying a Case__c object with millions of records. If you filter on a field like Status__c which is not indexed, the query may take seconds or timeout. But if you create a custom index on Status__c and make sure the value being filtered occurs in fewer than 10% of records (good selectivity), your query may execute in milliseconds.

Salesforce Best Practices Documentation:
SOQL Performance Tuning
Using Selective Queries
Custom Indexes in Salesforce

Universal Containers ne=ds to integrate with several external systems. The process Is Initiated when a record Is created in Salesforce, The remote systems do not require Salesforce to wait for a response before continuing. What is the recommended best solution to accomplish this?

A. PushTopic event

B. Qutbound message

C. Trigger with HTTP callout

D. Platform event

D.   Platform event

Explanation:

Universal Containers needs to initiate integration with external systems asynchronously (i.e., Salesforce should not wait for a response). The best-fit solution for this fire-and-forget integration is a Platform Event.

✅ Why D is correct:
➟ Platform Events are designed for asynchronous, event-driven architecture.
➟ They allow Salesforce to publish messages that can be consumed by external systems via CometD (Streaming API) or middleware like MuleSoft, Kafka, etc.
➟ They decouple the system: Salesforce fires the event, and doesn't wait for a response.
➟ This is the modern, scalable approach for such integrations.

❌ Why the other options are incorrect:

A. PushTopic event
➟ Designed for streaming record changes (insert/update/delete) in Salesforce to clients via the Streaming API.
➟ It’s not recommended for initiating business processes or integration flows.
➟ It’s not flexible or event-based, and deprecated in many real-time use cases.

B. Outbound message
Outbound Messages are declarative and can send messages via SOAP, but they are limited:
➟ No support for complex logic
➟ Only SOAP, not REST
➟ Difficult to customize error handling
➟ Less flexible and older pattern compared to Platform Events.

C. Trigger with HTTP callout
➟ You cannot make an HTTP callout after a DML operation in the same transaction.
➟ Requires callout logic in a @future or Queueable, which adds complexity.
➟ Less scalable and harder to maintain than Platform Events.

📚 Reference:
Salesforce Platform Events Overview
Comparison of Integration Options

🧠 Key Takeaway:
Use Platform Events for asynchronous, scalable, loosely coupled integrations with external systems, especially when Salesforce doesn't need to wait for a response.

Prep Smart, Pass Easy Your Success Starts Here!

Transform Your Test Prep with Realistic Salesforce-Platform-Developer-II Exam Questions That Build Confidence and Drive Success!

Frequently Asked Questions

The Salesforce Platform Developer II certification validates advanced knowledge in Apex, Lightning components, integration patterns, and deployment. It’s designed for developers with hands-on experience building scalable business applications on the Salesforce Platform.
  • Experienced Salesforce developers
  • Technical consultants and architects
  • Professionals aiming to showcase mastery in Apex, Visualforce, Lightning Web Components (LWC), and integrations
You must first hold the Salesforce Platform Developer I certification. Salesforce recommends 2–3 years of development experience on the platform before attempting PDII.
  • Questions: 60 multiple-choice/multiple-select
  • Time: 120 minutes
  • Passing Score: ~70%
  • Cost: USD $200 (plus taxes)
  • Delivery: Online proctored or Pearson VUE test center
  • Advanced Apex programming (asynchronous operations, exception handling)
  • Security & sharing model considerations
  • Integration techniques (REST, SOAP, external services)
  • Testing & debugging
  • Deployment & packaging best practices
Yes. Expect scenario-based questions that test your problem-solving and coding ability, including debugging, refactoring code, and recommending the best architectural approach.
  • Retake after 1 day for the first attempt
  • Retake after 14 days for further attempts
  • Maximum of 3 attempts per release cycle
  • Platform Developer I (PDI): Focuses on core Apex, SOQL, and declarative development.
  • Platform Developer II (PDII): Tests advanced coding, performance, architecture, and integration skills.
  • REST: Lightweight, modern, mobile/web integrations.
  • SOAP: Legacy or when strict contract/WSDL is required.
  • Platform Events: Real-time, event-driven architecture.
  • Change Data Capture (CDC): Sync Salesforce data with external systems automatically.
In the exam, pick the method that balances governor limits, scalability, and reliability.
  • Writing test classes with >75% coverage that assert actual outcomes.
  • Using dependency injection, stubs, and mocks for isolation.
  • Knowing when to use Unlocked Packages, Change Sets, or SFDX CLI.
  • In practice exams, review every “deployment” question twice — they’re often scenario-based and easy to misread.
  • Update LinkedIn and resume with “Salesforce Platform Developer II Certified” — highly valued by employers.
  • Join Salesforce Developer Community Groups to network.
  • Contribute to open-source Salesforce projects or blogs — recruiters notice active contributors.