Earlier this year I was asked to be on the hiring committee for an SFDC Admin/Analyst. I was to provide the technical assessment. A few months earlier, I elected to become the engineer most familiar with our Heroku Connect integration, and through that, closer to Salesforce in general. While most developers tend to steer away from Salesforce, it was an important part of the company’s process, and I’m always eager to see the big picture.

With this position never filled before in the company’s history, let alone defined, there was quite a bit of work to do.

Trivia or Hands-on?

When I was a junior developer, interviews were filled with questions like,”What is encapsulation? What about inheritance? What is the big O of retrieving an item in a hash map?”. These can be a bit silly as candidates can recite answers to these questions without actually knowing how to use such concepts correctly. I felt that Salesforce trivia could fall into the same trap.

I wanted to see how someone could solve problems on the platform in real time.

Enter Sandbox

An important part of the Salesforce platform is the deploy process. It’s rather restrictive, and often criticized for being slow. One reason is the requirement to deploy from another environment called a “sandbox”. These sandboxes are one way of developing and testing code, and even involved in the deployment process.

My employer had a “partial sandbox”, which was capable of copying production’s configuration and a small slice of data across all types of data.

To me, this was the perfect environment to execute an interview. We had a handful of bugs in production that were solved but not fixed/deployed yet. I could ask the candidate to solve business problems related to our actual domain by inserting them into our platform configuration and data!

Isolating the assessment.

I had a plan, but there were some obstacles.

The first problem concerned easily reproducing the “problem data/configuration”. I needed a way of wiping any sort of solution that a candidate could implement, so that the same problem could be solved by the next candidate.

To accomplish this, I copied the partial sandbox into a sandbox labeled interview. I configured any additional data by hand (most objects are not copied for developer sandboxes) to represent a basic level of most flows/processes in our production org.

From then on out, I would clone the interview sandbox for each new candidate, and manually make a User for them. I’d give them their credentials at the start of each interview and let them know the sandboxes would live for 24-48 hours, incase they wanted to explore it later.

Secondly, while I wanted the candidate to solve problems in our actual configuration, I didn’t want the candidate to see more sensitive data of every employee/user in our company, like titles, contact info, etc. After you’ve read a few Mitnick stories, you see social engineering as a viable attack vector. I wrote the below APEX script to scrub all sensitive fields with garbled values. Running this in the interview sandbox ensured that all derived sandboxes would be clean.

// generateRandomString(int) implementation can be found here - https://salesforce.stackexchange.com/a/43826/60833

List<String> doNotEditIds = new List<String>{ '005U0000003TZ49', '0050B0000080YI2QAM', '0050B000007zsmKQAQ', '0050B000007zsmLQAQ'};
Set<String> unableToDeactivateIds = new Set<String> {'0050B000007C3ZwQAK', '0050B000007zsmKQAQ', '005U0000005sd5PIAQ','0050B000006qMw2QAE','005U0000003FOvxIAG','0050B0000080e7ZQAQ', '005U0000004PBGOIA4', '0050B000006qCyN', '0050B0000080Dpy', '005U0000006FECa'}; 

List<User> allUsers;
allUsers = [SELECT Id, isActive from User where Id NOT IN :doNotEditIds and UserType != 'AutomatedProcess' AND Phone != 'FIXED' limit 148];

for(User u: allUsers)
   String garbageEmail = 'interview=' + generateRandomString(10) + '@interview.com';
   u.FirstName = generateRandomString(5);
   u.LastName = generateRandomString(5);
   u.PostalCode = '';
   u.UserName = garbageEmail;
   u.Email = garbageEmail;
   u.MobilePhone = '' ;
   u.Phone = 'FIXED';
   if(!unableToDeactivateIds.contains(u.Id)) {
      u.IsActive = false;
   try {
     update u;
   } catch (Exception e) {

Full Source Code

It’s important to note that due to the DML limit, we are restricted from scrubbing/anonymizing all data without multiple runs of the above. I’m not sure if it would be possible to improve upon this, as certain data points, like users’ emails, must be unique.

Unfortunately, as I was writing this blog, I discovered that email addresses will not change via this fashion without a verification email is sent to a new one. This feature can be turned off, but its rather cumbersome and requires you to file a support ticket with SFDC. Seeing this now, the users I tried to protect were easily identified by their email. It’s the thought that counts though, right? ☹️️

The Assessment

With our environment now easily reproducible and relatively secure, we can move onto the problems presented. I wanted them the process to follow a few principles:

  • Requirements would be partially vague. Problems were presented based upon a business need, and explained from a business perspective.

The first two were rather simple “adminstrator” type things.

First was adding a simple boolean field to a custom object, representing VIP accounts. This is an ice-breaker question to ease the candidate into the process since a hands-on interview with screen share can be a bit nerve wrecking. Since most people solve this, I tended to focus on how they navigated throughout the platform.

The second is a simple relationship field for a newly created custom object. I mixed a trivia like approach with the hands on task by quizzing the candiate on what type of relationship (lookup vs. master-detail) was best for the problem.

The third, and often unused problem, was a bug in an APEX controller that handled a search query for addresses. It did not properly escape special characters, like ', so it would fail on addresses containing such. Most candidates did not have a APEX/Visualforce/programming background, so this was rarely asked. However, this was a bug in our production environment, albeit solved, would hopefully give a similar experience for the position.


My results interviewing were mixed. Part of the issue was identifying what the role’s actual responsibilities were. This was vague for a bit of time during the hiring process, and probably the greatest detractor. Salesforce is an enormous levithan that can be amplified in complexity once integrations are involved, especially custom ones. Since we heavily rely upon a couple custom integrations (powered through Heroku Connect and Python), it was hard to establish to the hiring committee that an SFDC Admin would be powerless to customize these custom integrations.

As a developer, I was biased towards finding someone fairly technical with SFDC, rather then generally procifient. This was a mistake, as we were hiring a Salesforce Admin, not a programmer. Thus, the third problem was never really asked. The lesson learned is to fully understand what role your employer has budget for, the responsibilities it intends to fill, and whether or not they will be directly supported by others (i.e. developer help).

The biggest success came from the hands-on approach. Being able to watch a candidate navigate around Salesforce and solve problems, albeit sometimes simple ones, provided lots of information. There were some that knew shortcuts, some that didn’t. One candidate even critiqued a custom Visualforce component that a previous contractor built, pointing out some flaws that I hadn’t thought about before.

Despite the startup costs of configuring the initial sandbox and scrubbing the data, the process was heavily automated and required little effort on my part to maintain, about 5 minutes for each candidate. Each candidate had access to the sandbox about a day after the interview. I like to think that this inspired some confidence in more senior candidates. I was giving them an accurate view to what they would be handed responsibility of in a way, and it wasn’t sugarcoated.