Interview guides · Blue Flame Labs
Blue Flame Labs Software Engineer Interview Guide
Blue Flame Labs Software Engineer interview guide: four reported rounds, OOPs, SQL, DSA, JavaScript and Salesforce questions, plus a 7-day prep plan.
The 60-second brief
Blue Flame Labs delivers software for clients on the Salesforce platform, and candidates describe the Software Engineer role as hands-on work in that ecosystem. The work they list includes custom Apex triggers, Lightning Components and integrations with third-party systems, alongside database interactions and general back-end logic. Day to day, the role also covers code reviews, debugging existing systems, tuning performance, writing project documentation and joining architecture discussions with other engineers and product teams.
This guide is for candidates interviewing for a Software Engineer position at Blue Flame Labs, whether or not they have shipped Salesforce code before. It covers the four reported rounds, every technical question candidates report (OOPs, DSA, SQL and schema design, JavaScript and React, Salesforce platform concepts, debugging) and the behavioral prompts, then turns them into a one-week study sequence.
Candidates report four rounds over roughly three to five weeks: Technical Assessment, Technical Discussions, Scenario-Based Questions and Team Fit Evaluation. The first two lean on core computer science, and the last two lean on your experience and fit.
Focus areas
- OOPs (general)
- SQL (general)
- React
Overview
The reported question set is wide rather than deep in any one stack. It mixes classic computer science (the four pillars of OOP, overloading versus overriding, binary search), database work (a query that returns unique records while excluding a value, joins, aggregates, an e-commerce schema), front-end basics (let, var and const, React performance) and platform questions (Master-Detail versus Lookup, Apex triggers, callouts per transaction, Visualforce versus Lightning Components). Candidates describe the requirements as Java or a similar object-oriented language, solid SQL, HTML, CSS and JavaScript, and the ability to implement standard data structures and algorithms. Salesforce experience, React or Angular, and Node.js are listed as extras.
That mix means breadth with working code. For each topic, prepare a short spoken explanation, then a small program or query that shows it: a class hierarchy with an overridden method next to an overloaded one, a binary search with its loop invariant stated, a join written out against two tiny tables. Reported topics for the data structure side include merge sort, string reversal, anagrams, linked list operations and using a stack or queue for a practical problem, so practise those with Big O stated at the end of each solution.
Candidates also report being asked to code in a plain text editor or while sharing a screen. Do part of your practice with no autocomplete, no linter and no run button, so that syntax, off-by-one errors and null checks are yours to catch. The later rounds shift to your own history: walk through projects, the decisions you owned, how you debug, and why you want to work at this company, so have those stories ready before the technical rounds begin.
The Blue Flame Labs interview process
Candidates report four rounds spread over about three to five weeks. The stages below follow the names candidates use, and the questions are matched to a stage only by type, since reports do not tie a specific question to a specific round.
Technical Assessment
Candidates describe the opening stage as an assessment of technical and analytical ability, without a published format. Because the details are thin, prepare for the subjects the whole loop is reported to touch: object-oriented fundamentals, SQL, basic algorithms and the JavaScript and Java basics from the stated requirements. Aim to explain each concept in a few sentences and then show it in code you can write without autocomplete.
What to demonstrate
- Technical and analytical ability at a first-pass level
- Working command of object-oriented concepts and basic algorithms
- Ability to write correct code and queries without tool assistance
How to prepare
- Write a small class hierarchy showing encapsulation, inheritance, polymorphism and abstraction, and say which line demonstrates each pillar.
- Write overloading and overriding side by side, and explain which is resolved at compile time and which at run time.
- Implement binary search from memory in a plain editor and test it on empty, single-element and not-found inputs.
- Write a SQL query that returns distinct values while excluding one value, then add a join and an aggregate.
Technical Discussions
Candidates report deeper discussions, in person or virtual, focused on SQL, OOPs and algorithms. Expect to talk through your reasoning while you code or write queries, since reports stress explaining why you picked an algorithm or data structure and how you handle edge cases and complexity. Salesforce and front-end topics appear in the reported question list, so keep those warm as well.
What to demonstrate
- Depth in SQL, OOPs and algorithms as discussion topics
- Reasoning about edge cases, time complexity and space complexity
- Clarity when explaining a choice of algorithm or data structure
How to prepare
- Explain the join types using two small tables, including which rows survive and which become NULL, and write the nth highest salary query two ways.
- Practise abstract class versus interface, and exception handling strategy, with a concrete example for each.
- Write merge sort, a string reversal, an anagram check and a linked list reversal, and state time and space complexity out loud for each.
- Sketch a schema for an online shopping cart with keys and foreign keys, and justify where you normalize.
Scenario-Based Questions
Candidates describe this stage as scenario-based: it looks at your experience and how you handle situations posed to you. The reported material does not say what the scenarios are, so prepare two kinds. First, stories from your own work in which you debugged something hard or shipped under a constraint. Second, technical situations you can reason through step by step, such as choosing a relationship type, deciding where logic belongs in a trigger, or tracing a bug in unfamiliar code.
What to demonstrate
- How you apply experience to a scenario you have not seen
- Structured debugging and problem solving
- Ability to explain decisions and their consequences
How to prepare
- Prepare a debugging story and a story about solving a technical problem under constraints, each with your own decision and the result.
- Rehearse a debugging routine: reproduce, narrow down by bisection, form one hypothesis at a time, confirm with evidence, then fix and add a test.
- Turn the Salesforce questions into scenarios: when would you choose Master-Detail over Lookup, and what belongs in a before trigger versus an after trigger.
- Practise stating assumptions first when a scenario is vague, then working through it aloud.
Team Fit Evaluation
Candidates describe the final stage as an evaluation of fit with the existing team, and tips mention HR and hiring-manager conversations that cover communication, long-term goals and why you want to work at Blue Flame Labs. Treat it as a conversation built from your own history: you will probably be asked about projects, your part in them and the technologies you used, so have those facts crisp.
What to demonstrate
- Communication and how you describe your own work
- Motivation and long-term goals as you present them
- Fit with the team as the stage is named
How to prepare
- Write a two-minute answer to "Tell me about yourself and your project experience" covering role, stack and one decision.
- Prepare a clear, honest answer for why Blue Flame Labs and why Salesforce-centred client work, based on what you have actually read about the role.
- Choose two projects and note the technical challenge, your specific contribution, the technologies and what you would change now.
- Write three questions about the team's day-to-day work, code review habits and how new engineers learn the platform.
Where candidates lose points
Reciting OOP definitions without a code example
For each pillar, and for overloading versus overriding, write a few lines of code you can point to. State when the compiler picks the method and when the runtime does, and use abstract class versus interface to show why you would choose each.
Writing binary search that loops forever or misses an element
State the invariant (target lies within lo..hi), compute the midpoint without overflow, and move the bounds past mid. Test an empty array, a single element, the first and last items, and a missing value, in a plain editor, before you say you are done.
Answering the SQL questions with one memorised query
Practise the variants: DISTINCT with a filter, each join type on tiny tables, GROUP BY with HAVING, and the nth highest salary with both a subquery and a window function. Watch for NULLs, ties and one-to-many joins that inflate aggregates.
Treating the Salesforce questions as trivia
Learn the reason behind each answer: ownership and cascade delete for Master-Detail versus Lookup, when each trigger timing is appropriate, and why per-transaction limits shape how you write loops and callouts. Be ready to apply the rule to a scenario.
Relying on autocomplete and silent coding
Candidates report plain editors and shared screens, so rehearse without IDE help and narrate your approach as you write, including the alternative you rejected and the complexity of the solution.
Questions & practice
Can you explain Binary Search and provide an implementation?
Medium · Technical Foundations & Programming
Approach
- The input must be sorted. Keep lo and hi bounds, compare the middle element with the target, and discard the half that cannot contain it. That is O(log n) time and O(1) space iteratively; a recursive version uses O(log n) stack.
- Write it with lo = 0, hi = n - 1, while (lo <= hi), and mid = lo + (hi - lo) / 2, which avoids int overflow in Java. Return mid on a match, otherwise set lo = mid + 1 or hi = mid - 1, and return -1 when the loop ends.
- Test the edge cases aloud: empty array, one element, target smaller than all or larger than all, and target missing.
- For duplicates, write the lower-bound variant. On a half-open range [lo, hi), set hi = mid when a[mid] >= target, so it returns the first index whose value is >= target.
- Java's Arrays.binarySearch returns -(insertionPoint) - 1 when the key is absent, and does not say which index it returns when there are duplicates.
Follow-up
- Find the first and last occurrence of a value in a sorted array with duplicates.
- Search a sorted array that has been rotated at an unknown pivot.
- Use binary search on the answer to compute the integer square root of n.
Identify the heaviest tenants in a five-minute window under memory pressure
Medium · top-k · heavy hitters · streaming
The edge service handles about 3,000 requests per second across roughly 50,000 tenants, peaking near 9,000. Expose the 50 heaviest tenants by request count over the trailing five minutes so limits can be tightened before one tenant's backfill starves the fleet. You may not retain five minutes of raw records. Give the exact solution and its memory, then the bounded-memory approximation with its error stated as a formula, and say which you would ship and at what tenant cardinality that choice changes.
Approach
- Do the exact version first, because it is affordable at this cardinality: a ring of 300 one-second counters per tenant, advanced lazily, is 1,200 bytes of counters per tenant and roughly 60 to 90 MB for 50,000 tenants with overhead. Carry a running total and subtract the bucket you overwrite so a window read is O(1) rather than 300 adds.
- Extract the top 50 with a size-k min-heap over the tenant sums: O(d log k) for d tenants, against O(d log d) to sort them all. Maintaining the heap continuously instead of on query requires a tenant-to-heap-index map, because incrementing a count already inside the heap means sifting from a known position, and without that map you rebuild the heap on every request.
- State the approximation precisely rather than gesturing at sketches. Misra-Gries with m counters retains every item whose true count exceeds N/(m+1), and each retained count underestimates the truth by at most N/(m+1). With m = 1,000 and N = 900,000 requests in the window the error is roughly 900 requests, which is fine for spotting a tenant sending 50,000 and useless for ranking two tenants 200 apart.
- Say what breaks when the window slides: Misra-Gries and Space-Saving are insert-only and cannot be decremented as records age out. The workable construction is one summary per sub-window, say ten seconds, with 30 summaries merged at query time, and the merged error is the sum of the per-summary errors, so the bound degrades linearly in the number of sub-windows.
Follow-up
- The heaviest tenant is heavy because of one export job rather than user traffic. Should the limiter treat those as the same tenant?
- Two tenants sit tied at the boundary of the top 50. Does your answer flap, and does the flapping matter?
Collapse a redelivered event batch into per-aggregate high-water marks
Easy · hashing · at-least-once · aggregation
You drain a batch of up to 5,000,000 events, each (aggregate_id BIGINT, aggregate_version INT, event_type, payload). The log guarantees order within one aggregate only; the batch merges 64 partitions, and a relay failover has redelivered a range, so an older version for an aggregate can appear after a newer one. Given a map of last_applied_version per aggregate, produce the events worth applying, at most one per (aggregate_id, version), plus the count discarded. Target O(n) time. State the memory for 2,000,000 distinct aggregates and what you do when it does not fit.
Approach
- One pass, one hash map from aggregate_id to the highest version kept, and a discard counter. An event whose version is at or below last_applied_version for its aggregate is dropped without further work, which is the whole reason the event carries its version rather than a delta. O(n) expected time, O(d) space in distinct aggregates.
- Keep the maximum, never the last occurrence. The redelivered range means the final appearance of an aggregate in the batch can be an older version than one seen earlier in the same batch, so last-wins applies stale state over newer state and the projection regresses with no error anywhere.
- Cost the memory instead of calling it large: an 8-byte key plus a 4-byte version is 12 bytes of payload, and an open-addressed table held at a 0.7 load factor costs roughly 17 bytes per entry before per-slot metadata, so 2,000,000 aggregates is tens of megabytes in a native layout and several times that in a runtime that boxes both key and value.
- If the distinct set exceeds memory, partition on hash(aggregate_id) mod P and reduce each partition independently. Every event for one aggregate hashes to the same partition, so the per-partition result is exact and the merge is concatenation rather than a second reduction.
Follow-up
- The payload is a patch rather than a snapshot, so applying only the highest version loses the intermediate changes. What changes in your reduction?
- How do you detect that version 7 arrived while version 6 was never delivered, and what should the consumer do about the gap?
Write a SQL query to find unique records while excluding a specific value.
Medium · Database & SQL
Approach
- Pin down what 'unique' means first. It may mean distinct values (SELECT DISTINCT col FROM t WHERE col <> 'X'), or values that appear exactly once (GROUP BY col HAVING COUNT(*) = 1 plus the same filter).
- Handle NULLs explicitly. col <> 'X' evaluates to unknown for NULL rows, so they drop out. Add OR col IS NULL if they should stay. DISTINCT and GROUP BY both treat all NULLs as one group.
- If the exclusion is about entities (customers who never bought product X), use NOT EXISTS or a LEFT JOIN anti-join. NOT IN returns no rows when its subquery yields a NULL.
- Compare cost. DISTINCT and GROUP BY both need a sort or hash over the remaining rows. A <> filter is rarely selective enough to use an index, while an index on col can serve the grouping.
Follow-up
- Return the full rows (not just the column) for values that occur exactly once.
- Rewrite the query so it excludes a list of values supplied as a bind parameter.
- Why can NOT IN return zero rows here, and how do you fix it?
What are the differences between various SQL joins?
Medium · Database & SQL
Approach
- INNER JOIN keeps only matching pairs. LEFT JOIN keeps every left row and fills NULLs where there is no match; RIGHT JOIN is the mirror. FULL OUTER keeps unmatched rows from both sides. CROSS JOIN is the Cartesian product. A self join joins a table to itself (employee to manager).
- Show the anti-join: LEFT JOIN orders o ON o.customer_id = c.id WHERE o.id IS NULL finds customers with no orders.
- Explain ON versus WHERE for outer joins. A condition on the right table placed in WHERE removes the NULL-extended rows, so the LEFT JOIN behaves like an INNER JOIN. Put it in ON instead.
- Watch cardinality. A one-to-many join multiplies rows, so counts and sums inflate. NULL keys never match on equality. MySQL has no FULL OUTER JOIN, so emulate it with a LEFT JOIN UNION a RIGHT JOIN.
Follow-up
- Table A has 3 rows and B has 4. What are the minimum and maximum row counts for an inner, a left and a cross join?
- How does the database execute a join: nested loop, hash join or merge join, and when is each chosen?
- Find employees who earn more than their manager.
What are the four pillars of OOPs and how do you implement them?
Medium · Technical Foundations & Programming
Approach
- Name the four pillars: encapsulation, abstraction, inheritance and polymorphism. Give each a one-line definition and a code example, not just the word.
- Encapsulation: private fields with getters and setters that validate. A Bottle class with private capacityMl and currentMl, where fill() rejects overflow, works as the example.
- Abstraction: an abstract class or interface (say, Container with pour()) that callers code against. Inheritance: WaterBottle extends Bottle and reuses its state and behaviour.
- Polymorphism: a Container reference holding a WaterBottle calls the subclass's pour() at runtime (dynamic dispatch). Overloading is the compile-time form.
- Close on trade-offs. Prefer composition when the relationship is 'has-a', not 'is-a'. In Apex, a method can only be overridden if it is declared virtual or abstract, and the subclass must use the override keyword.
Follow-up
- When would you choose an abstract class over an interface, now that Java interfaces can have default methods?
- How does deep inheritance hurt maintainability, and how would you refactor it with composition?
- How do you keep a class immutable, and which pillar does that relate to?
Explain the difference between method overloading and overriding with code examples.
Medium · Technical Foundations & Programming
Approach
- Overloading means the same method name with a different parameter list (number, types or order) in the same class. The compiler picks the version at compile time, and a different return type alone does not create an overload.
- Overriding means a subclass redefines an inherited instance method with the same signature. The JVM picks it at runtime from the object's actual type, not the reference type.
- Show both in code. add(int, int) next to add(double, double), then Animal.speak() overridden in Dog with @Override, called through an Animal reference.
- State the overriding rules. Visibility cannot be narrowed, the return type may be covariant, no new or broader checked exceptions may be thrown, and final methods cannot be overridden. Static and private methods are not overridden: statics are hidden, privates are not inherited.
- Mention overload resolution order. Java prefers an exact match, then primitive widening, then boxing, then varargs. Passing null can make two reference overloads ambiguous.
Follow-up
- What happens if a subclass declares a static method with the same signature as a static method in its parent?
- Can you overload main, and which version does the JVM call?
- Why does @Override matter if the code compiles without it?
What is the difference between let, var, and const in JavaScript?
Medium · Technical Foundations & Programming
Approach
- var is function-scoped. It is hoisted and set to undefined, so reading it before its declaration gives undefined. It can be redeclared in the same scope.
- let and const are block-scoped. They are hoisted too, but sit in the temporal dead zone until their declaration runs, so an earlier read throws ReferenceError. Redeclaring either in the same scope is a SyntaxError.
- const must be initialised and its binding cannot be reassigned. The object it points to is still mutable (pushing to a const array works), and Object.freeze only freezes one level deep.
- Show the loop-closure case. for (var i = 0; i < 3; i++) setTimeout(() => console.log(i)) logs 3, 3, 3. With let, each iteration gets a fresh binding, so it logs 0, 1, 2.
- Give a default. Use const unless the value is reassigned, let when it is, and avoid var. A top-level var in a classic script also becomes a property of the global object.
Follow-up
- What does typeof return for a let variable read inside its temporal dead zone, and why is that different from an undeclared name?
- How would you make a nested object fully immutable?
- How were closures in loops handled before let existed?
How do you optimize the performance of a React application?
Medium · Technical Foundations & Programming
Approach
- Measure before changing anything. Use the React DevTools Profiler to find which components re-render and why, and a bundle analyser to see what ships to the browser.
- Cut needless re-renders. Wrap stable child components in React.memo, keep prop references stable with useMemo and useCallback, and move state down to the component that uses it.
- Split context by how often it changes. Every consumer re-renders when the context value changes, so a frequently changing value inside a large context object re-renders the whole tree.
- Handle large lists and heavy UI. Virtualise long lists (react-window), use stable keys rather than array indexes when items reorder, and debounce input or use useTransition / useDeferredValue so typing stays responsive.
- Shrink what loads. Code-split routes with React.lazy and Suspense, lazy-load images, and ship the production build. Memoisation has its own cost, so apply it where the profiler shows a problem.
Follow-up
- When does React.memo make performance worse rather than better?
- Why does using the array index as a key cause bugs when items are inserted or reordered?
- A list of 10,000 rows is slow to scroll. Walk through your fix.
How would you structure tables for an e-commerce application similar to Amazon?
Medium · Database & SQL
Approach
- List the core entities: users, addresses, products, categories, product variants or SKUs, inventory, carts and cart_items, orders and order_items, payments, shipments and reviews. Give each a surrogate primary key and foreign keys.
- Model many-to-many links with junction tables (product_categories). Give categories a parent_id for the hierarchy. Put a unique constraint on (cart_id, sku_id) so a cart holds one line per SKU.
- Copy unit_price and the product name onto order_items at purchase time, so later price changes do not rewrite past orders. Store money as DECIMAL, never float.
- Keep the schema in 3NF for writes, and index the foreign keys plus the access paths (orders by user_id, created_at). Denormalise or cache only read-heavy views such as product listings.
- Cover inventory concurrency. Decrement stock with a conditional UPDATE ... SET qty = qty - n WHERE sku_id = ? AND qty >= n and check the affected row count, or lock the row with SELECT ... FOR UPDATE inside the order transaction.
Follow-up
- Products in different categories have different attributes (shoe size, screen resolution). How would you store them?
- How would you track order status changes over time?
- Write the query for a user's last ten orders with their item counts, and say which index serves it.
Explain how to perform aggregate queries.
Medium · Database & SQL
Approach
- Aggregates collapse rows into groups: COUNT, SUM, AVG, MIN, MAX with GROUP BY. In standard SQL, every selected column that is not aggregated must appear in GROUP BY.
- WHERE filters rows before grouping. HAVING filters groups after, so HAVING COUNT(*) > 5 belongs in HAVING, not WHERE.
- Know the NULL rules. COUNT() counts rows, COUNT(col) skips NULLs, and COUNT(DISTINCT col) counts distinct non-NULL values. SUM and AVG ignore NULLs, so AVG(col) differs from SUM(col) / COUNT() when NULLs exist.
- Use a window function (SUM(amount) OVER (PARTITION BY customer_id)) when the detail rows must stay alongside the total. Pre-aggregate in a subquery before joining a one-to-many table, so sums do not inflate.
- Engines differ on integer averages. SQL Server's AVG over an int column returns an int, so cast to decimal. PostgreSQL returns numeric.
Follow-up
- Write a query for the nth highest salary, and say how ties change it (DENSE_RANK versus LIMIT/OFFSET on DISTINCT values).
- Return each department's highest-paid employee, with the employee's name.
- Why can a SUM come out too large after adding a join, and how do you fix it?
What is the difference between a Master-Detail and a Lookup relationship?
Medium · Salesforce Ecosystem
Approach
- Master-Detail is a tight parent-child link. The parent field is required on the child, deleting the master deletes its detail records, and the detail has no owner of its own: it inherits sharing and security from the master.
- Lookup is a loose link. The field is optional by default, and the child keeps its own owner and sharing. On delete, the default clears the field; it can be set to block the deletion, and a custom lookup can be set to cascade.
- Roll-up summary fields (COUNT, SUM, MIN, MAX) work natively only on the master of a Master-Detail. With a lookup you need Apex, a flow or a declarative tool.
- Limits and patterns: an object can have up to two Master-Detail relationships and up to 40 total. A junction object with two Master-Detail fields models many-to-many. Converting a lookup to Master-Detail requires every existing record to have the field filled.
- Choose by ownership. If the child cannot exist without the parent and should follow its access, use Master-Detail. If it has an independent life or its own owner, use a lookup.
Follow-up
- How would you get a roll-up total across a lookup relationship?
- Can a detail record be moved to a different master, and what setting controls that?
- Design a many-to-many between Students and Courses and explain which object owns sharing.
Explain the use of Apex triggers and the differences between before and after triggers.
Medium · Salesforce Ecosystem
Approach
- A trigger is Apex that runs on DML events: before or after insert, update, delete, and after undelete. It is used for logic declarative tools cannot express, such as cross-object updates or complex validation.
- Before triggers run before the record is saved. Change Trigger.new fields directly, with no DML needed, and use addError() to block the save. In before insert the Id is still null.
- After triggers run once the record is saved, so Id and system fields such as CreatedDate exist. Trigger.new is read-only there, so use after triggers to create or update related records.
- Bulkify. A trigger receives records in chunks of up to 200, so collect Ids, run one SOQL query and one DML outside any loop, and stay within the 100 synchronous SOQL and 150 DML statement limits. Keep one trigger per object that delegates to a handler class.
- Guard against recursion (an after-update trigger whose own update refires it) with a static flag or a set of processed Ids. Trigger.oldMap does not exist on insert, and Trigger.newMap does not exist in before insert.
Follow-up
- Your trigger hits 'Too many SOQL queries: 101'. How do you find and fix the cause?
- Where do triggers fall in the order of execution relative to validation rules and flows?
- How would you make an HTTP callout in response to a record update?
How many callouts can be performed in a single transaction?
Medium · Salesforce Ecosystem
Approach
- Give the number: an Apex transaction can make up to 100 HTTP callouts. The cumulative callout timeout is 120 seconds, and each callout's own timeout defaults to 10 seconds, adjustable up to 120.
- Callouts cannot follow uncommitted DML in the same transaction; doing so throws a 'You have uncommitted work pending' CalloutException. Do the callout first, or move it to an asynchronous context.
- Triggers cannot make synchronous callouts. Use an @future(callout=true) method or a Queueable that implements Database.AllowsCallouts, and pass Ids rather than sObjects to @future.
- For more volume, Batch Apex with Database.AllowsCallouts gets fresh limits per execute() chunk. Use Named Credentials for endpoints and auth, and check Limits.getCallouts() against Limits.getLimitCallouts() before each call.
- Test with HttpCalloutMock and Test.setMock. Real callouts are not allowed in test methods.
Follow-up
- You need to sync 5,000 records to an external API. How do you structure that without hitting limits?
- Why can't you make a callout after a DML statement in the same transaction?
- How would you handle retries when the external system is down?
What is the difference between Visualforce and Lightning Components?
Medium · Salesforce Ecosystem
Approach
- Visualforce is a page-centric, server-rendered markup framework. Pages bind to standard or custom Apex controllers, keep view state between requests, and most interactions round-trip to the server.
- Lightning components are client-side and component-based. There are two models: Aura and Lightning Web Components (LWC). LWC is built on web standards (custom elements, shadow DOM, ES modules), so it is lighter and closer to plain JavaScript.
- Data access differs. LWC reads records through Lightning Data Service and @wire adapters with client caching, and calls Apex methods marked @AuraEnabled. Visualforce uses controller getters and action methods.
- In Lightning Experience, Visualforce pages render inside an iframe and look out of place. Lightning components fit the record pages, App Builder and mobile.
- Visualforce still fits renderAs="pdf" documents and existing pages that work. For new UI, choose LWC, and wrap an LWC in Aura only where a feature still requires an Aura container.
Follow-up
- How do two sibling LWC components communicate?
- How would you migrate a Visualforce page with a custom controller to LWC?
- When would you call Apex imperatively instead of using @wire?
How do you approach debugging a complex piece of code?
Medium · Behavioral & Problem Solving
Approach
- Reproduce it first. Get a reliable, minimal reproduction (the exact input, environment and steps) before changing any code, and read the full error and stack trace rather than the first line.
- Narrow the search space by bisection. Use git bisect against the last known good version, halve the input, or disable half the code path, so each check rules out half the candidates.
- Check assumptions with evidence. Add targeted logging or breakpoints at the boundary where the state goes from correct to wrong, and inspect actual values, not the ones you expect. On Salesforce, debug logs show SOQL, DML and governor-limit usage per transaction.
- Separate the cause from the symptom. Explain why the bug happens, fix the root cause, then write a test that fails without the fix and passes with it.
- For intermittent bugs, look at shared state, ordering, time zones, caching and concurrency, and log enough context (ids, timestamps) to catch the failing case.
Follow-up
- The bug only happens in production and you cannot attach a debugger. What do you do?
- How do you confirm your fix removed the cause and did not just hide the symptom?
- Tell me about the hardest bug you tracked down and how you found it.
Suggested practice checklist
Each day covers one cluster of reported questions: OOP, algorithms, SQL, front-end, Salesforce, and then behavioral and debugging. The first day sets up your plain-editor routine, and the last runs a mixed rehearsal.
Day 1 — Map the loop and set up plain-editor practice
- Write the four reported rounds in order and next to each one list the topics it is reported to touch.
- Set up a bare text editor or an empty shared document with no autocomplete, and write FizzBuzz plus a string reversal in it.
- Rate yourself from one to five on OOPs, DSA, SQL, JavaScript and React, Salesforce and behavioral, and mark the two weakest.
Deliverable: A one-page round map, a self-rating table with two weak areas chosen, and two short programs written in a plain editor.
Day 2 — Object-oriented programming
- Write a Bottle class and use it to demonstrate encapsulation, inheritance, polymorphism and abstraction.
- Write one example of overloading and one of overriding, and note which is resolved at compile time and which at run time.
- Prepare a spoken comparison of abstract classes and interfaces, plus an outline of how you handle exceptions.
Deliverable: One runnable class hierarchy, one overload and override pair, and a spoken script for the abstract class versus interface comparison.
Day 3 — Algorithms and data structures
- Implement binary search iteratively and recursively, then test empty, single, duplicate and missing inputs.
- Write merge sort, a string reversal, an anagram check and a linked list reversal, stating time and space for each.
Deliverable: Five working solutions with complexity written beside each, and a short list of mistakes you made in the plain editor.
Day 4 — SQL and schema design
- Create two small tables and write each join type, noting which rows are kept and where NULLs appear.
- Write the unique-records-excluding-a-value query, the nth highest salary query two ways, and a GROUP BY with HAVING.
- Design an e-commerce schema (customers, products, orders, order items, payments) with keys, and decide where to normalize.
Deliverable: A SQL file containing every query with sample output, and a schema diagram for the shopping cart design.
Day 5 — JavaScript, React and front-end basics
- Write short snippets that show scoping, hoisting and reassignment for let, var and const, including the closure-in-a-loop case.
- List React performance techniques with the problem each solves, such as memoization, stable keys, list virtualization and code splitting, and when you would measure first.
- Refresh HTML and CSS layout basics, since they appear in the stated requirements.
Deliverable: A snippet file for variable declarations, a one-page React performance checklist, and a spoken two-minute answer for each.
Day 6 — Salesforce platform concepts
- Compare Master-Detail and Lookup in a table covering ownership, cascade delete, roll-up summaries and required fields.
- Write trigger examples that use before and after timing correctly, and explain the case for each.
- Look up the current per-transaction callout limit in Salesforce's documentation and explain how you would batch or defer work to stay within it.
- Compare Visualforce and Lightning Components and say when each is the right tool.
Deliverable: A one-page Salesforce sheet with the four comparisons, two trigger examples and the verified callout limit with its source.
Day 7 — Debugging, behavioral stories and full rehearsal
- Write a debugging routine and apply it aloud to a bug from your own past.
- Run a mixed rehearsal: one OOP answer, one SQL query, one algorithm and one story, in the plain editor and out loud.
Deliverable: A debugging checklist, two story outlines with decisions and outcomes, and a recorded mixed rehearsal you have replayed.
Project stories and constraint stories
Candidates report that the later rounds ask about your own work: your projects, how you debug, how you handle limits, and why you want the job. Prepare stories where you made the decision, name the technologies, and say what the result was.
- How do you approach debugging a complex piece of code?
- Walk me through a project where you owned a technical decision. What were the alternatives and what did it cost?
- Why do you want to work at Blue Flame Labs, and where do you want your career to go?
Tell me about yourself and your project experience.
Medium · Behavioral & Problem Solving
Approach
- Use a present, past, future shape: where you are now and what you work on, one or two projects that show your range, and why this role is the next step. Keep it short enough that the follow-up questions are where depth appears.
- For each project, state the problem in one sentence, your own role, the technologies you used, one technical decision you owned and the outcome. Match the technologies to the loop: Java or another object-oriented language, SQL, front-end work, and Salesforce if you have it.
- Say what you did in the first person. A tour of what the team did hides your contribution, and the story only works if the interviewer can tell which decisions were yours.
- Choose a decision you can defend with its trade-off, such as a schema choice, a caching or indexing change, or a refactor, and state what it cost as well as what it gained.
- Do not recite your resume in date order and do not exaggerate. Anything on your resume can be explored in depth, so be ready to go one level deeper on every technology you name.
Follow-up
- What was your specific contribution, as opposed to the team's?
- Which technical decision in that project had the biggest effect on the result, and what would you change now?
- What was the hardest bug or setback on that project and how did you find the cause?
Describe a time you had to solve a technical problem under constraints.
Medium · Behavioral & Problem Solving
Approach
- Pick a real problem with a clear constraint: a hard deadline, a platform or API limit, a legacy schema you could not change, limited memory or a small team. Name the constraint in your first sentence so the listener knows what made it hard.
- Use situation, task, action and result, but spend most of the time on the options. Explain the two or three approaches you weighed, why the one you chose fit the constraint and what you gave up on purpose.
- Give the technical specifics: what you built, which data structure, query or design you used, how you checked it worked, and how you limited the risk of the shortcut. If you have Salesforce experience, per-transaction platform limits make a natural example.
- Close with the result and a lesson. State what you measured or observed afterwards, what you had to revisit and what you would do differently.
- The usual mistake is a story with no alternatives, such as long hours that finished the work. The answer needs a decision and a reason.
Follow-up
- What options did you reject and why?
- What did you knowingly leave undone, and how did you make sure it did not hurt later?
- How did you confirm that the solution actually worked under the constraint?
Ship under a deadline and bound the debt you chose
Medium · pagination · technical debt · tradeoffs
You have four days to ship a tenant-facing listing endpoint. The version you would defend uses keyset pagination over (tenant_id, status, updated_at DESC, resource_id DESC); the version you can finish uses LIMIT/OFFSET with no matching index. Describe a deadline call you actually made of this shape: what you shipped, what you knowingly deferred, how you bounded the damage with a mechanism rather than an intention, and the specific numeric condition that would force the follow-up. Name who you told and where you wrote it down.
Approach
- Name the deferred failure precisely instead of calling it slow. OFFSET n makes the database produce and discard n rows, so cost grows with page depth; without an index matching the sort, every matching row is read and sorted before the limit applies; and rows inserted between two page fetches shift across the boundary so items are skipped or repeated with nothing in the response to signal it.
- Bound the blast radius with something mechanical rather than a promise: cap maximum page depth, cap page size, restrict the endpoint to one internal caller, or keep it behind a flag. State which failure each cap removes and which it leaves standing.
- Attach a number to the trigger and wire it to an alarm: the first tenant crossing N resources, or the endpoint's p99 crossing its share of the 400 ms budget, so the debt announces itself instead of waiting to be remembered.
- Write it where the next engineer looks, which is the code and the ticket, not a chat message: what was deferred, why, the cap, and the trigger.
Follow-up
- At what page depth does the offset version breach your latency budget, given your page size and row counts?
- What breaks first when you switch to keyset pagination later, and what does a client holding an old page token see?