React Native Interview Handbook — Part 2 of 2
This part contains 243 reviewed questions. The complete 2-part series contains 719 questions, each with a technical answer and practical context.
Topics in this part
- System Design — 20 questions
- Mobile Databases (SQLite, Realm & WatermelonDB) — 7 questions
- Monorepos (Nx & Turborepo) — 5 questions
- AI-Assisted Mobile Development — 5 questions
- Coding Problems — 75 questions
- Output-Based JavaScript Questions — 111 questions
- Scenario-Based Questions — 13 questions
- HR & Behavioral Questions — 7 questions
How to use this guide
Answer each question before reading the response. For coding questions, clarify assumptions and complexity. For output questions, state the exact result first. Adapt behavioral examples to your truthful experience.
System Design
20 reviewed questions.
Intermediate level
1. Design a production login flow?
Answer
Answer: On launch I show a splash while reading the refresh token from secure storage. If present, I refresh the session; otherwise I show AuthStack. After login I keep the access token in memory, refresh token in Keychain/Keystore, reset to AppStack, and register the push token. On 401 a single-flight refresh retries queued requests. Logout revokes tokens, clears persisted user data, unregisters push where needed, and resets navigation.
2. Offline React Native design?
Answer
Answer: I distinguish cached reads from queued writes. Reads come from a local DB/cache with freshness metadata. Writes are saved as durable operations with ids, timestamps, retry count, and idempotency key, then flushed when NetInfo reports connectivity. I use exponential backoff, conflict strategy, transactions, and visible sync status. MMKV fits small data; SQLite or WatermelonDB fits large relational datasets.
Advanced level
3. Design a New Architecture migration for a large React Native application?
Answer
Answer: Inventory native modules, view managers, code generation, animation, storage, navigation, and build tooling, then classify each dependency as compatible, replaceable, patchable, or blocking. Enable the architecture in controlled environments, migrate high-risk native boundaries incrementally, and compare startup, memory, rendering, crashes, and business flows. Preserve build-level rollback until both platforms and production cohorts are stable. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
4. Design a background media-download manager?
Answer
Answer: Model every download as a durable state machine keyed by content ID, with URL, destination, expected size, checksum, downloaded bytes, retry state, and ownership. Use platform background-transfer capabilities where continuity is required, publish throttled progress to active UI subscribers, and persist lifecycle checkpoints. Reconcile database state with actual files after restart and enforce storage, network, battery, and entitlement policies.
5. Design a feature-flag and remote-configuration platform for mobile?
Answer
Answer: Ship safe defaults in the binary and fetch signed, versioned configuration with cache expiry and schema validation. Evaluate targeting deterministically from non-sensitive attributes, record exposure events, and provide kill switches for risky features. Configuration must not attempt to activate native capability absent from the installed binary.
6. Design a mobile analytics architecture that protects privacy?
Answer
Answer: Define a typed event catalog with owner, purpose, allowed properties, retention, and consent requirement. Route events through one client that validates schemas, removes prohibited data, batches delivery, and honors opt-out state before collection. Version events deliberately and reconcile mobile telemetry with backend facts for critical business outcomes.
7. Design a modular CI/CD pipeline for Android and iOS?
Answer
Answer: Use reproducible dependency installation, static analysis, unit tests, native build validation, signing isolation, artifact provenance, automated distribution, and release approval gates. Cache only deterministic inputs and keep credentials in the CI secret store with least privilege. Promote the same verified artifact through environments when platform rules allow, and capture version, commit, configuration, and dependency manifests.
8. Design a multi-brand or white-label React Native platform?
Answer
Answer: Separate shared product capabilities from tenant configuration, assets, design tokens, entitlements, API endpoints, and native identifiers. Generate deterministic brand builds from validated configuration and keep brand-specific behavior behind typed capability flags rather than scattered conditions. CI should test shared journeys for every supported configuration and protect signing assets independently.
9. Design a production observability architecture for a React Native application?
Answer
Answer: Combine crash reporting, handled-error telemetry, performance traces, structured breadcrumbs, release metadata, network correlation IDs, and business journey metrics. Normalize Android, iOS, JavaScript, and native symbols so incidents can be grouped accurately. Define service-level indicators such as crash-free sessions, startup percentiles, API failure rate, and checkout success, with alerts tied to user impact.
10. Design a push-notification delivery and navigation system?
Answer
Answer: The backend stores token, platform, app version, user, locale, permission, and freshness metadata and removes invalid tokens from provider feedback. Payloads contain a typed navigation intent rather than arbitrary route data. The app uses one handler for foreground, background, and terminated launches, validates authentication and authorization, and queues navigation until the root navigator is ready.
11. Design a real-time chat architecture with offline support?
Answer
Answer: Persist conversations and pending messages locally, use client-generated message IDs, and synchronize through a WebSocket plus a paginated REST recovery path. Model sending, sent, delivered, read, and failed states explicitly; preserve ordering with server sequence numbers rather than device clocks. Reconnect with backoff, request missed ranges, and keep media uploads separate from message creation.
12. Design a resilient React Native and PWA integration boundary?
Answer
Answer: Define a versioned, allow-listed message protocol with schema validation, origin checks, correlation IDs, timeouts, and explicit success and error responses. Keep authentication and sensitive operations native where possible, and sign messages when the threat model requires integrity across the boundary. Navigation, lifecycle, retry, and backward compatibility must be specified rather than inferred.
13. Design a resilient payment flow in React Native?
Answer
Answer: Treat the backend as the payment source of truth and model the client flow as explicit states such as initiated, awaiting authorization, processing, succeeded, failed, and unknown. Every create or confirm operation uses an idempotency key, and app restarts reconcile status from the backend. Sensitive data stays inside approved SDK boundaries, while logs exclude secrets and payment details.
14. Design a safe OTA update and staged-release strategy?
Answer
Answer: Separate JavaScript-compatible OTA changes from updates that require a new native binary. Sign updates, enforce runtime compatibility, stage rollout by cohort, monitor crash and business metrics, and support automatic or manual rollback. App Store and Play Store releases should also use phased rollout, release gates, and immutable build provenance.
15. Design a scalable, image-heavy social feed in React Native?
Answer
Answer: Use cursor pagination, normalized entities, a virtualized list, stable row contracts, thumbnail-first image loading, memory and disk caching, and cancellation for off-screen work. Separate server state from local interaction state and prefetch conservatively based on measured scroll behavior. Track frame rate, blank cells, image failures, memory, cache hit rate, and time to first useful content.
16. Design a secure authentication and token-rotation architecture for a mobile app?
Answer
Answer: Keep short-lived access tokens in memory when practical and refresh credentials in Keychain or Keystore-backed storage. Centralize authentication in one request layer, allow only one refresh operation at a time, replay eligible requests after success, and clear all protected state after definitive refresh failure. Add device binding or proof-of-possession only when the threat model justifies the complexity.
17. Design an offline-first mutation and synchronization engine for React Native?
Answer
Answer: Write mutations to a durable local outbox with a client operation ID, entity version, payload, and retry metadata. Update the UI optimistically from the local database, then drain the outbox when connectivity and OS scheduling allow. The server must support idempotency and conflict detection; the client needs bounded retry, authentication recovery, dead-letter handling, and observable sync state.
18. Design an offline-first mutation flow?
Answer
Answer: Write domain changes and an outbox record transactionally with client IDs and idempotency keys, update UI optimistically, retry under connectivity and OS constraints, and reconcile server acknowledgements and conflicts.
19. How do you design offline synchronization?
Answer
Answer: Use a local database as source of truth, a durable outbox, idempotent APIs, bounded retry, connectivity and OS scheduling, explicit conflict rules, and visible sync state.
20. How would you design a production chat feature?
Answer
Answer: Use a local database as UI source of truth, realtime transport for events, HTTP for history and media, client IDs and server sequences, message states, an offline outbox, pagination, virtualization, and reconnect rules.
Mobile Databases (SQLite, Realm & WatermelonDB)
7 reviewed questions.
Intermediate level
1. When do you use SQLite?
Answer
Answer: Use SQLite for relational, queryable, transactional local data such as offline domain records and outboxes.
Advanced level
2. How do you design safe mobile database migrations?
Answer
Answer: Version every schema, make migrations deterministic and resumable where possible, preserve a backup or recovery path, and test upgrades from every supported production version. Large transforms should avoid blocking startup and must tolerate interruption. Record migration duration and failures without logging sensitive records.
3. How do you optimize SQLite performance in React Native?
Answer
Answer: Use transactions for batches, parameterized queries, appropriate indexes, pagination, projection of only required columns, and background work where supported. Inspect query plans and avoid one query per rendered row. Keep database access behind a repository or data layer so UI code cannot create uncontrolled query patterns.
4. How do you synchronize a local mobile database with a backend?
Answer
Answer: Track server cursors or versions, client operation IDs, local dirty state, tombstones, and an outbox for mutations. Pull changes incrementally, apply them transactionally, push idempotent operations, and resolve conflicts with a domain-specific policy. Expose sync health and recoverable failures to the UI while keeping partial progress durable.
5. How should database encryption and key management work on mobile?
Answer
Answer: Use a maintained encrypted database implementation when the threat model requires data-at-rest protection, and store the encryption key in Keychain or Keystore-backed storage rather than in source code or ordinary preferences. Define key rotation, logout cleanup, backup behavior, rooted-device limitations, and recovery. Minimize stored sensitive data even when encryption is enabled.
6. SQLite versus Realm versus WatermelonDB: how do you choose?
Answer
Answer: SQLite offers a mature relational foundation and direct query control but requires schema, mapping, and synchronization design. Realm provides an object-oriented database and reactive model with its own runtime and ecosystem trade-offs. WatermelonDB builds a lazy, observable data layer over SQLite-oriented storage for large React Native datasets. Choose from query shape, data size, reactivity, migration, sync, native footprint, maintenance, and team expertise.
7. When do you use WatermelonDB?
Answer
Answer: WatermelonDB targets large offline-first datasets with lazy observable queries and synchronization patterns.
Monorepos (Nx & Turborepo)
5 reviewed questions.
Advanced level
1. How do you optimize CI for a React Native monorepo?
Answer
Answer: Use the dependency graph to run lint, tests, builds, and native validation only for affected projects while preserving periodic full verification. Cache package installation, JavaScript outputs, Gradle, CocoaPods, and derived artifacts only with complete deterministic keys. Separate fast pull-request feedback from signed release pipelines and monitor cache correctness and restore time.
2. How should native modules and Codegen be managed in a monorepo?
Answer
Answer: Give each native-capable package a clear JavaScript API, Codegen specification, Android and iOS implementation, build metadata, and compatibility policy. Apps should consume released or workspace-resolved package entry points rather than native source through accidental relative paths. CI must validate Codegen and native builds for every affected application.
3. How would you structure a React Native monorepo with Nx?
Answer
Answer: Keep deployable mobile apps separate from domain, UI, platform, tooling, and configuration libraries. Use project boundaries and tags to prevent feature packages from importing app internals, expose public entry points, and configure affected builds and tests from the dependency graph. Native projects retain clear ownership while shared TypeScript code remains platform-aware.
4. Nx versus Turborepo for a React Native monorepo: what are the trade-offs?
Answer
Answer: Nx provides an explicit project graph, generators, affected commands, dependency constraints, and a larger integrated toolchain. Turborepo focuses on task orchestration and local or remote caching with fewer architectural opinions. The decision depends on repository scale, governance needs, existing package-manager workspaces, CI design, and whether the team values integrated conventions or a smaller surface.
5. What Metro configuration issues commonly appear in React Native monorepos?
Answer
Answer: Common issues include duplicate React copies, unresolved workspace packages, files outside watched roots, symlink behavior, asset paths, platform extension resolution, and incompatible package exports. Configure project root, watch folders, resolver paths, and package-manager layout deliberately, then verify that React and React Native resolve to one compatible instance.
AI-Assisted Mobile Development
5 reviewed questions.
Advanced level
1. How can AI assistants improve React Native debugging without replacing evidence?
Answer
Answer: Provide a minimal reproduction, exact platform and versions, logs, stack traces, recent changes, and observed versus expected behavior. Ask for ranked hypotheses and the evidence that would distinguish them, then verify each hypothesis with profiling, instrumentation, or a controlled experiment. Keep the final root-cause analysis tied to runtime evidence.
2. How do you review AI-generated React Native code?
Answer
Answer: Check requirements, platform behavior, lifecycle cleanup, thread assumptions, state ownership, error handling, accessibility, performance, security, dependency health, and test quality. Verify every API against the installed package version and inspect native configuration changes separately. Prefer a small understandable change over a large generated abstraction.
3. How should Cursor or GitHub Copilot be used safely in React Native development?
Answer
Answer: Use AI assistants for bounded tasks such as scaffolding, test cases, migration checklists, documentation, and code exploration, while keeping the engineer accountable for requirements and output. Provide relevant local context, request assumptions and edge cases, review every dependency and platform API, and run the same tests and security checks required for human-written code.
4. How would you establish team governance for AI-assisted development?
Answer
Answer: Define approved tools and repositories, prohibited data, human-review requirements, attribution rules, dependency policy, security scanning, and incident handling. Train developers on prompt hygiene and verification, record exceptions, and measure outcomes such as review time, escaped defects, and test quality rather than generated-line counts.
5. What data should never be sent to an AI coding assistant?
Answer
Answer: Do not send production secrets, signing keys, access tokens, private customer data, proprietary source outside approved policy, incident payloads containing personal data, or confidential contracts. Follow organizational retention, model-training, regional, and vendor controls. Redact examples and use approved enterprise configurations when sensitive repositories are involved.
Coding Problems
75 reviewed questions.
Beginner level
1. How do you build a character-frequency map?
Code example:Answer
Answer: Iterate characters and increment a count keyed by each character.
const freq=s=>[...s].reduce((m,c)=>(m[c]=(m[c]||0)+1,m),{});
2. How do you check whether a string is a palindrome?
Code example:Answer
Answer: Normalize the string and compare it with its reverse.
const isPalindrome=s=>{s=s.toLowerCase();return s===[...s].reverse().join('')}
3. How do you count vowels in a string?
Code example:Answer
Answer: Match vowels case-insensitively and use zero when there is no match.
const vowels=s=>(s.match(/[aeiou]/gi)||[]).length;
4. How do you find the largest number in an array?
Code example:Answer
Answer: Use Math.max with spread for moderate arrays or scan once for very large arrays.
const max=a=>Math.max(...a);
5. How do you implement a usePrevious hook?
Code example:Answer
Answer: Store the current value in a ref after commit and return the ref's previous content during render.
const ref=useRef(); useEffect(()=>{ref.current=value},[value]); return ref.current;
6. How do you remove duplicates from an array?
Code example:Answer
Answer: Create a Set from the array and spread it back into an array. This preserves the first occurrence order.
const unique=a=>[...new Set(a)];
7. How do you reverse a string?
Code example:Answer
Answer: Split into characters, reverse, and join; use Array.from or spread when Unicode code points matter.
const reverse=s=>[...s].reverse().join('');
Intermediate level
8. Array.prototype.map polyfill (Medium)?
Code example:Answer
Answer: Creates a new array and preserves sparse-array holes.
I include value, index and source arguments, support thisArg, and avoid invoking the callback for missing sparse indexes. A full spec polyfill has additional coercion details.
Array.prototype.myMap = function (callback, thisArg) {
if (this == null) throw new TypeError('Invalid receiver');
const source = Object(this);
const length = source.length >>> 0;
const result = new Array(length);
for (let i = 0; i < length; i++) {
if (i in source) {
result[i] = callback.call(thisArg, source[i], i, source);
}
}
return result;
};
9. Array.prototype.reduce polyfill (Medium)?
Code example:Answer
Answer: Matches core reduce behavior, including a missing initial value.
The important edge case is an empty array without an initial value. I also skip sparse holes and pass all four callback arguments.
Array.prototype.myReduce = function (callback, initialValue) {
const source = Object(this);
const length = source.length >>> 0;
let index = 0;
let accumulator;
if (arguments.length > 1) {
accumulator = initialValue;
} else {
while (index < length && !(index in source)) index++;
if (index >= length) throw new TypeError('Empty array');
accumulator = source[index++];
}
for (; index < length; index++) {
if (index in source) {
accumulator = callback(accumulator, source[index], index, source);
}
}
return accumulator;
};
10. Challenge A: useDebounce?
Code example:Answer
Answer: Keep a debounced value in state, start a timeout whenever the source value or delay changes, and clear the previous timeout in effect cleanup. The hook returns the last value whose delay completed. Tests should cover rapid changes, delay changes, unmount cleanup, and the initial value.
function useDebounce(value, delay = 300) {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const id = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(id);
}, [value, delay]);
return debounced;
}
11. Challenge B: Infinite scroll + pull to refresh?
Code example:Answer
Answer: Keep initial loading, pagination, and refresh states separate. Guard onEndReached while a page request is active, deduplicate items by stable identifier, and ignore or cancel stale responses. Refresh resets the cursor and replaces data only after the first-page request succeeds, while pagination appends the next confirmed page.
const loadMore = () => {
if (!loadingMore && hasNextPage) fetchNextPage();
};
12. Challenge C: API hook with loading/error?
Code example:Answer
Answer: I keep data, error, and loading state in a custom hook, run the supplied fetcher in an effect, abort on cleanup, ignore AbortError, and return the three states to the screen.
function useApi(fetcher) {
const [state, setState] = useState({ loading: true });
useEffect(() => {
const controller = new AbortController();
setState({ loading: true });
fetcher(controller.signal)
.then(data => setState({ data, loading: false }))
.catch(error => {
if (error.name !== 'AbortError') setState({ error, loading: false });
});
return () => controller.abort();
}, [fetcher]);
return state;
}
13. Check a normalized palindrome (Easy)?
Code example:Answer
Answer: Expected result: true
Explanation: I clarify whether case, spaces, punctuation and Unicode must be ignored. The two-pointer comparison avoids creating a second reversed string.
function isPalindrome(value) {
const clean = value.toLowerCase().replace(/[^a-z0-9]/g, '');
let left = 0;
let right = clean.length - 1;
while (left < right) {
if (clean[left++] !== clean[right--]) return false;
}
return true;
}
isPalindrome('A man, a plan, a canal: Panama');
14. Check two strings are anagrams without sort (Easy/Medium)?
Code example:Answer
Answer: areAnagrams('listen', 'silent') returns true.
This frequency-map solution avoids O(n log n) sorting. I first confirm normalization rules and mention that this exact style has appeared in React Native coding rounds.
function areAnagrams(a, b) {
const left = a.toLowerCase().replace(/\s/g, '');
const right = b.toLowerCase().replace(/\s/g, '');
if (left.length !== right.length) return false;
const counts = new Map();
for (const char of left) {
counts.set(char, (counts.get(char) ?? 0) + 1);
}
for (const char of right) {
const next = (counts.get(char) ?? 0) - 1;
if (next < 0) return false;
counts.set(char, next);
}
return true;
}
15. Debounce search TextInput?
Code example:Answer
Answer: Update local text immediately and debounce only the search side effect. Clear the previous timer when text changes, cancel the active request when possible, and ignore stale responses so an older query cannot replace newer results.
function SearchInput() {
const [text, setText] = useState('');
const query = useDebounce(text, 300);
useEffect(() => {
if (query) searchApi(query);
}, [query]);
return <TextInput value={text} onChangeText={setText} />;
}
16. Deep clone nested arrays and plain objects (Medium)?
Code example:Answer
Answer: Expected result: Returns an independent nested copy and preserves circular references.
Explanation: I state the supported types. JSON stringify is not a true deep clone because it loses undefined, Date, BigInt and circular references. In modern production code, structuredClone may be appropriate.
function deepClone(value, seen = new WeakMap()) {
if (value === null || typeof value !== 'object') return value;
if (seen.has(value)) return seen.get(value);
if (value instanceof Date) return new Date(value);
const copy = Array.isArray(value) ? [] : {};
seen.set(value, copy);
for (const key of Reflect.ownKeys(value)) {
copy[key] = deepClone(value[key], seen);
}
return copy;
}
17. Find the first non-repeating character (Easy)?
Code example:Answer
Answer: c
The first pass counts; the second preserves original order. I return null explicitly when no unique character exists.
function firstUnique(value) {
const counts = new Map();
for (const char of value) {
counts.set(char, (counts.get(char) ?? 0) + 1);
}
for (const char of value) {
if (counts.get(char) === 1) return char;
}
return null;
}
firstUnique('aabbcddee');
18. Flatten a nested array without flat() (Medium)?
Code example:Answer
Answer: [1, 2, 3, 4, 5]
I explain the recursive base case. For extremely deep input I would use an explicit stack to avoid call-stack overflow.
function flatten(values) {
return values.reduce(
(result, value) =>
result.concat(Array.isArray(value) ? flatten(value) : value),
[],
);
}
flatten([1, [2, [3, 4]], 5]);
19. Flatten object?
Code example:Answer
Answer: Walk the object recursively and build each output key from its parent path and current property. Clarify how arrays, null, dates, separator characters, circular references, and empty containers should be handled.
function flatten(object, parent = '', result = {}) {
for (const [key, value] of Object.entries(object)) {
const path = parent ? `${parent}.${key}` : key;
if (value && typeof value === 'object' && !Array.isArray(value)) {
flatten(value, path, result);
} else {
result[path] = value;
}
}
return result;
}
20. Flatten only to a requested depth (Medium)?
Code example:Answer
Answer: [1, 2, 3, [4]]
I validate depth in production and preserve remaining nested arrays once depth reaches zero. This exact depth-based variation has appeared in a React Native interview report.
function flattenDepth(values, depth = 1) {
if (depth === 0) return values.slice();
return values.reduce((result, value) => {
return result.concat(
Array.isArray(value)
? flattenDepth(value, depth - 1)
: value,
);
}, []);
}
flattenDepth([1, [2, [3, [4]]]], 2);
21. Function.prototype.bind polyfill (Medium/Hard)?
Code example:Answer
Answer: Returns a function with fixed context and optional partial arguments.
A good bind answer must discuss constructor usage: new should ignore the bound context. A fully spec-compliant implementation also handles metadata and edge cases.
Function.prototype.myBind = function (context, ...preset) {
const target = this;
function bound(...later) {
const receiver = this instanceof bound ? this : context;
return target.apply(receiver, [...preset, ...later]);
}
bound.prototype = Object.create(target.prototype);
return bound;
};
22. Group objects by a property (Easy/Medium)?
Code example:Answer
Answer: An object whose keys are professions and values are user arrays.
I define behavior for a missing property. In production I may prefer Map if keys are not strings or if prototype-safe storage matters.
function groupBy(items, key) {
return items.reduce((groups, item) => {
const group = item[key] ?? 'unknown';
(groups[group] ??= []).push(item);
return groups;
}, {});
}
groupBy(users, 'profession');
23. How do you add a timeout to a Promise?
Code example:Answer
Answer: Race the operation against a timer Promise that rejects. Clear the timer in a production helper and cancel the underlying operation when possible.
function withTimeout(p,ms){return Promise.race([p,new Promise((_,reject)=>setTimeout(()=>reject(new Error('Timeout')),ms))])}
24. How do you check whether two strings are anagrams?
Code example:Answer
Answer: Normalize both strings and compare sorted characters, or compare frequency maps for linear time.
const anagram=(a,b)=>[...a].sort().join('')===[...b].sort().join('');
25. How do you find a missing number from 1 through n?
Code example:Answer
Answer: Subtract the array sum from n(n+1)/2, assuming exactly one number is missing and values are valid.
const missing=(a,n)=>n*(n+1)/2-a.reduce((x,y)=>x+y,0);
26. How do you find pairs that sum to a target?
Code example:Answer
Answer: Scan once with a Set of prior values; when target minus the current value has been seen, record the pair.
function twoSum(a,t){const seen=new Set(),out=[];for(const n of a){if(seen.has(t-n))out.push([t-n,n]);seen.add(n)}return out}
27. How do you find the first non-repeating character?
Code example:Answer
Answer: Build a frequency map, then scan the original string and return the first character with count one.
function firstUnique(s){const m=freq(s);for(const c of s)if(m[c]===1)return c}
28. How do you find the longest substring without repeating characters?
Code example:Answer
Answer: Use a sliding window and map each character to its latest index. Move the left edge past a duplicate and track the maximum width.
function longest(s){const seen=new Map();let l=0,b=0;for(let r=0;r<s.length;r++){if((seen.get(s[r])??-1)>=l)l=seen.get(s[r])+1;seen.set(s[r],r);b=Math.max(b,r-l+1)}return b}
29. How do you find the maximum subarray sum?
Code example:Answer
Answer: Kadane's algorithm tracks the best subarray ending at each index and the best seen overall in O(n) time.
function maxSubArray(a){let cur=a[0],best=a[0];for(let i=1;i<a.length;i++){cur=Math.max(a[i],cur+a[i]);best=Math.max(best,cur)}return best}
30. How do you find the second-largest distinct number?
Code example:Answer
Answer: Track the largest and second-largest distinct values in one pass, updating both when a new maximum appears.
function secondMax(a){let x=-Infinity,y=-Infinity;for(const n of a){if(n>x){y=x;x=n}else if(n>y&&n!==x)y=n}return y}
31. How do you flatten a nested object?
Code example:Answer
Answer: Recursively visit nested plain objects, joining path segments, and assign leaf values to the output.
function flattenObj(o,p='',out={}){for(const[k,v]of Object.entries(o)){const key=p?`${p}.${k}`:k;if(v&&typeof v==='object'&&!Array.isArray(v))flattenObj(v,key,out);else out[key]=v}return out}
32. How do you flatten an array of any depth?
Code example:Answer
Answer: Use flat(Infinity) or recurse into array elements while accumulating scalar values.
const flat=nested.flat(Infinity);
function flatten(a){return a.reduce((r,v)=>r.concat(Array.isArray(v)?flatten(v):v),[])}
33. How do you group an array of objects by a property?
Code example:Answer
Answer: Reduce into an object whose property values are arrays, creating each group on first use.
function groupBy(a,k){return a.reduce((m,o)=>((m[o[k]]??=[]).push(o),m),{})}
34. How do you implement a reusable API hook?
Code example:Answer
Answer: Model data, loading, and error; start work in an effect; abort during cleanup; and ignore abort errors.
function useApi(fetcher) {
const [state, setState] = useState({ loading: true });
useEffect(() => {
const controller = new AbortController();
fetcher(controller.signal)
.then(data => setState({ data, loading: false }))
.catch(error => {
if (error.name !== 'AbortError') setState({ error, loading: false });
});
return () => controller.abort();
}, [fetcher]);
return state;
}
35. How do you implement a theme provider?
Code example:Answer
Answer: Store mode in context, derive theme tokens, expose a toggle, and consume through a focused useTheme hook.
<ThemeContext.Provider value={{theme,mode,toggle}}>
36. How do you implement a useDebounce hook?
Code example:Answer
Answer: Keep a debounced value in state, start a timeout whenever the source value or delay changes, and clear the previous timeout in effect cleanup. The hook returns the last value whose delay completed. Tests should cover rapid changes, delay changes, unmount cleanup, and the initial value.
useEffect(() => { const id=setTimeout(()=>setDebounced(value),delay); return ()=>clearTimeout(id); }, [value,delay]);
37. How do you implement a useThrottle hook?
Code example:Answer
Answer: Track the last publication time, update immediately when the interval has elapsed, otherwise schedule the remaining delay and clean up that timer.
function useThrottle(value, delay) {
const [throttled, setThrottled] = useState(value);
const lastRun = useRef(0);
useEffect(() => {
const remaining = Math.max(0, delay - (Date.now() - lastRun.current));
const id = setTimeout(() => {
lastRun.current = Date.now();
setThrottled(value);
}, remaining);
return () => clearTimeout(id);
}, [value, delay]);
return throttled;
}
38. How do you implement an Error Boundary?
Code example:Answer
Answer: Use a class component with getDerivedStateFromError for fallback state and componentDidCatch for reporting.
class ErrorBoundary extends React.Component { componentDidCatch(e,info){logError(e,info)} }
39. How do you implement debounce for search TextInput?
Code example:Answer
Answer: I keep the raw text in state for the input, then debounce that value with a custom useDebounce hook. A second effect depends on the debounced query and calls the API. That way we do not hit the server on every keystroke.
<TextInput value={text} onChangeText={setText} />
40. How do you implement debounce?
Code example:Answer
Answer: Keep a timer in a closure, clear it on every call, and schedule the function after the quiet period.
function debounce(fn,wait){let t; return function(...args){clearTimeout(t); t=setTimeout(()=>fn.apply(this,args),wait)}}
41. How do you implement deep equality?
Code example:Answer
Answer: Return true for identical values, reject incompatible non-objects, compare key counts, then recursively compare corresponding properties. Production code must handle cycles, symbols, prototypes, and special types.
function deepEqual(a,b){if(Object.is(a,b))return true;if(!a||!b||typeof a!=='object'||typeof b!=='object')return false;const ka=Object.keys(a),kb=Object.keys(b);return ka.length===kb.length&&ka.every(k=>Object.hasOwn(b,k)&&deepEqual(a[k],b[k]))}
42. How do you implement infinite scroll with pull-to-refresh?
Code example:Answer
Answer: Track data, page, refresh, and load-more state; replace data on refresh, append on pagination, guard duplicate requests, and provide stable list keys.
<FlatList
data={items}
refreshing={refreshing}
onRefresh={refresh}
onEndReached={loadMore}
renderItem={renderItem}
/>
43. How do you implement memoize?
Code example:Answer
Answer: Cache results by an argument key and return the cached value on repeated calls. Real implementations need an appropriate key strategy and eviction policy.
function memoize(fn){const c=new Map();return(...a)=>{const k=JSON.stringify(a);if(c.has(k))return c.get(k);const v=fn(...a);c.set(k,v);return v}}
44. How do you implement once?
Code example:Answer
Answer: Keep called and result in a closure. Invoke the target only on the first call and return the stored result thereafter.
function once(fn){let called=false,result;return(...a)=>{if(!called){called=true;result=fn(...a)}return result}}
45. How do you implement throttle?
Code example:Answer
Answer: Track the last execution time and invoke only when the minimum interval has elapsed.
function throttle(fn,wait){let last=0; return function(...args){const now=Date.now(); if(now-last>=wait){last=now; fn.apply(this,args)}}}
46. How do you move all zeros to the end of an array?
Code example:Answer
Answer: Write nonzero values forward in one pass, then fill the remaining positions with zeros.
function moveZeroes(a){let i=0;for(const x of a)if(x!==0)a[i++]=x;while(i<a.length)a[i++]=0;return a}
47. How do you run an array of async functions sequentially?
Code example:Answer
Answer: Use for...of and await each function before starting the next, collecting results in order.
async function sequential(fns){const out=[];for(const fn of fns)out.push(await fn());return out}
48. How do you run-length compress a string?
Code example:Answer
Answer: Scan each run of equal characters, append the character and run length, then continue from the next run.
function compress(s){let out='',i=0;while(i<s.length){let j=i;while(j<s.length&&s[j]===s[i])j++;out+=s[i]+(j-i);i=j}return out}
49. Implement debounce (Medium)?
Code example:Answer
Answer: Expected result: Only the latest call runs after calls stop for delay milliseconds.
Explanation: I preserve this and arguments, and expose cancel for component cleanup. In React Native search, I keep the debounced function reference stable and cancel it on unmount.
function debounce(fn, delay) {
let timer;
function debounced(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
}
debounced.cancel = () => clearTimeout(timer);
return debounced;
}
50. Implement debounce and throttle?
Code example:Answer
Answer: Debounce clears the previous timer and schedules a new one, so only the final call after quiet time executes. Throttle tracks last execution or a pending timer so calls occur at most once per interval. I preserve this and arguments, expose cancel when useful, and clean it on component unmount.
const debounce = (fn, delay) => {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
};
const throttle = (fn, delay) => {
let ready = true;
return (...args) => {
if (!ready) return;
ready = false;
fn(...args);
setTimeout(() => { ready = true; }, delay);
};
};
51. Implement debounce?
Code example:Answer
Answer: Return a wrapper that clears the previous timer and schedules the latest call after the delay while preserving this and arguments. A production implementation should define leading and trailing execution and expose cancel and flush behavior.
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
52. Implement throttle (Medium)?
Code example:Answer
Answer: Expected result: At most one call runs per delay window.
Explanation: This is a leading-only throttle. I explicitly ask whether trailing calls, cancel, flush or maxWait are required because those change the implementation.
function throttle(fn, delay) {
let waiting = false;
return function (...args) {
if (waiting) return;
waiting = true;
fn.apply(this, args);
setTimeout(() => {
waiting = false;
}, delay);
};
}
53. Implement throttle?
Code example:Answer
Answer: Return a wrapper that runs at most once per interval while preserving this and arguments. Track the last execution and optionally schedule the latest trailing call; define leading, trailing, cancel, and flush semantics before coding.
function throttle(fn, delay) {
let ready = true;
return function (...args) {
if (!ready) return;
ready = false;
fn.apply(this, args);
setTimeout(() => { ready = true; }, delay);
};
}
54. Implement useDebounce and explain when to use it?
Code example:Answer
Answer: useDebounce returns a value only after it has stopped changing for a delay. I use it for search input and validation to avoid one API call per keystroke. Cleanup clears the previous timeout; that reset behavior is the key difference from throttle.
function useDebounce(value, delay = 300) {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const id = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(id);
}, [value, delay]);
return debounced;
}
55. Reverse a string (Easy)?
Code example:Answer
Answer: evitaN tcaeR
I use Array.from instead of split('') because it handles Unicode code points such as many emoji better. A follow-up can ask for an in-place array reversal.
function reverseString(value) {
return Array.from(value).reverse().join('');
}
console.log(reverseString('React Native'));
56. Run async tasks with a concurrency limit (Hard)?
Code example:Answer
Answer: Runs no more than limit tasks simultaneously and preserves result order.
I accept task functions rather than already-started Promises so concurrency can actually be controlled. I ask whether one rejection should fail fast or whether all results should be collected.
async function runLimited(tasks, limit) {
if (limit < 1) throw new RangeError('limit must be positive');
const results = new Array(tasks.length);
let next = 0;
async function worker() {
while (true) {
const index = next++;
if (index >= tasks.length) return;
results[index] = await tasks[index]();
}
}
const workers = Array.from(
{ length: Math.min(limit, tasks.length) },
worker,
);
await Promise.all(workers);
return results;
}
57. Safely access a nested property by path (Easy/Medium)?
Code example:Answer
Answer: Returns the city or Unknown without throwing.
For a fixed known path I prefer optional chaining. A helper is useful for dynamic paths, but production parsing needs clear rules for escaping and unsafe keys.
function get(object, path, fallback) {
const keys = Array.isArray(path)
? path
: path.replace(/\[(\w+)\]/g, '.$1').split('.').filter(Boolean);
let current = object;
for (const key of keys) {
if (current == null) return fallback;
current = current[key];
}
return current === undefined ? fallback : current;
}
get(user, 'profile.address.city', 'Unknown');
58. Two Sum?
Code example:Answer
Answer: I scan once with a Map from value to index. For each number I check whether target minus that number was already seen; if yes I return both indices. This is O(n) time and O(n) space, better than the O(n squared) nested-loop solution.
function twoSum(nums, target) {
const seen = new Map();
for (let i = 0; i < nums.length; i++) {
const need = target - nums[i];
if (seen.has(need)) return [seen.get(need), i];
seen.set(nums[i], i);
}
return [];
}
59. What is the difference between debounce and throttle?
Code example:Answer
Answer: Debounce waits until calls stop for a quiet period; throttle limits execution to at most once per interval. Debounce fits search input, while throttle fits continuous scroll updates.
const debouncedSearch = debounce(search, 300);
const throttledScroll = throttle(onScroll, 300);
60. Why is JSON.parse(JSON.stringify(value)) not a general deep clone?
Code example:Answer
Answer: It loses undefined and functions, converts Date to string, Map/Set to empty objects, NaN/Infinity to null, throws on BigInt and cycles, and does not preserve prototypes. Prefer structuredClone or a type-aware clone.
const source = { missing: undefined, createdAt: new Date() };
const clone = JSON.parse(JSON.stringify(source));
console.log(clone); // createdAt is a string; missing is removed
Advanced level
61. How do you expose battery level through a native module?
Code example:Answer
Answer: Define a narrow asynchronous typed method, read BatteryManager or the iOS equivalent on the correct queue, resolve a Promise, and expose the generated module contract.
const level = await NativeModules.Battery.getLevel();
console.log(`Battery level: ${level}%`);
62. How do you implement Array.prototype.filter?
Code example:Answer
Answer: Iterate existing indices, call the predicate with the standard arguments and optional thisArg, and push values whose predicate is truthy.
Array.prototype.myFilter=function(cb,thisArg){const out=[];for(let i=0;i<this.length;i++)if(i in this&&cb.call(thisArg,this[i],i,this))out.push(this[i]);return out}
63. How do you implement Array.prototype.map?
Code example:Answer
Answer: Iterate existing indices, call the callback with value, index, and source using the optional thisArg, preserve holes, and return a new array.
Array.prototype.myMap=function(cb,thisArg){const out=[];for(let i=0;i<this.length;i++)if(i in this)out[i]=cb.call(thisArg,this[i],i,this);return out}
64. How do you implement Array.prototype.reduce?
Code example:Answer
Answer: Use the supplied initial value when present; otherwise find the first existing element or throw for an empty array. Fold remaining existing indices with accumulator, value, index, and source.
Array.prototype.myReduce=function(cb,init){let i=0,acc;if(arguments.length>1)acc=init;else{while(i<this.length&&!(i in this))i++;if(i>=this.length)throw TypeError();acc=this[i++]}for(;i<this.length;i++)if(i in this)acc=cb(acc,this[i],i,this);return acc}
65. How do you implement Function.prototype.bind?
Code example:Answer
Answer: Capture the target, thisArg, and preset arguments and return a function that applies the target with combined arguments. A production polyfill must also preserve new-constructor behavior.
Function.prototype.myBind=function(ctx,...pre){const fn=this;return function(...args){return fn.apply(ctx,[...pre,...args])}}
66. How do you implement Promise.all?
Code example:Answer
Answer: Normalize each input with Promise.resolve, preserve index order, count fulfillments, resolve when all complete, and reject on the first rejection. Resolve an empty iterable immediately.
function promiseAll(ps){return new Promise((resolve,reject)=>{const a=Array.from(ps),r=[]; if(!a.length)return resolve([]); let n=0; a.forEach((p,i)=>Promise.resolve(p).then(v=>{r[i]=v;if(++n===a.length)resolve(r)},reject))})}
67. How do you implement Pub/Sub?
Code example:Answer
Answer: Maintain subscriber sets by topic; subscribe adds and returns an unsubscribe function, while publish calls a snapshot of current subscribers.
function bus(){const m=new Map();return{subscribe(t,f){const s=m.get(t)||new Set();s.add(f);m.set(t,s);return()=>s.delete(f)},publish(t,v){[...(m.get(t)||[])].forEach(f=>f(v))}}}
68. How do you implement a cycle-safe deepClone?
Code example:Answer
Answer: Return primitives directly, copy special types, register each source object in a WeakMap before recursing, and clone all own keys so cycles reuse the prior copy.
function deepClone(v,m=new WeakMap()){if(v===null||typeof v!=='object')return v;if(m.has(v))return m.get(v);if(v instanceof Date)return new Date(v);const out=Array.isArray(v)?[]:{};m.set(v,out);for(const k of Reflect.ownKeys(v))out[k]=deepClone(v[k],m);return out}
69. How do you implement an EventEmitter?
Code example:Answer
Answer: Store listeners by event, let on add and off remove callbacks, emit over a snapshot, and implement once with a wrapper that unsubscribes before invoking.
class EventEmitter{constructor(){this.m=Object.create(null)} on(e,f){(this.m[e]??=[]).push(f);return this} off(e,f){this.m[e]=(this.m[e]||[]).filter(x=>x!==f)} emit(e,...a){(this.m[e]||[]).slice().forEach(f=>f(...a))} once(e,f){const w=(...a)=>{this.off(e,w);f(...a)};return this.on(e,w)}}
70. How do you implement an LRU cache?
Code example:Answer
Answer: Use insertion order in a Map: on get, delete and reinsert the key as most recent; on set, refresh the key and evict the first key when over capacity.
class LRU{constructor(n=10){this.n=n;this.m=new Map()}get(k){if(!this.m.has(k))return;const v=this.m.get(k);this.m.delete(k);this.m.set(k,v);return v}set(k,v){this.m.delete(k);this.m.set(k,v);if(this.m.size>this.n)this.m.delete(this.m.keys().next().value)}}
71. How do you implement inheritance without class syntax?
Code example:Answer
Answer: Call the parent constructor for own fields, set the child prototype to Object.create(parent.prototype), and restore child.prototype.constructor.
function Animal(n){this.name=n} Animal.prototype.speak=function(){return this.name}; function Dog(n){Animal.call(this,n)} Dog.prototype=Object.create(Animal.prototype); Dog.prototype.constructor=Dog;
72. How do you implement offline retry?
Code example:Answer
Answer: Retry eligible transient network failures with bounded exponential backoff and jitter, then persist a replay-safe mutation in an outbox for reconnect.
async function retry(request, attempts = 3, baseDelay = 200) {
try {
return await request();
} catch (error) {
if (attempts <= 1) throw error;
const delay = baseDelay * 2 ** (3 - attempts);
await new Promise(resolve => setTimeout(resolve, delay));
return retry(request, attempts - 1, baseDelay);
}
}
73. How do you limit concurrent asynchronous operations?
Code example:Answer
Answer: Start a fixed number of worker loops that claim the next index and await its work. Await all workers and store results by original index.
async function mapPool(items,limit,worker){const out=[],workers=[];let i=0;async function run(){while(i<items.length){const n=i++;out[n]=await worker(items[n],n)}} for(let n=0;n<Math.min(limit,items.length);n++)workers.push(run());await Promise.all(workers);return out}
74. How do you retry a failed Promise with exponential backoff?
Code example:Answer
Answer: Loop through a bounded number of attempts, return on success, and after each retryable failure await an exponentially increasing delay before rethrowing the final error.
async function retry(fn,n=3,d=300){let e; for(let i=0;i<n;i++){try{return await fn()}catch(x){e=x; await new Promise(r=>setTimeout(r,d*2**i))}} throw e}
75. LRU cache design?
Code example:Answer
Answer: An LRU cache evicts the least recently used item when capacity is exceeded. In JavaScript, Map preserves insertion order, so get deletes and reinserts a key to mark it recent; set removes the oldest map key when over capacity. A production cache also defines TTL, memory limits, and whether undefined is a valid value.
class LRUCache {
constructor(capacity) {
this.capacity = capacity;
this.cache = new Map();
}
get(key) {
if (!this.cache.has(key)) return undefined;
const value = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, value);
return value;
}
set(key, value) {
this.cache.delete(key);
this.cache.set(key, value);
if (this.cache.size > this.capacity) {
this.cache.delete(this.cache.keys().next().value);
}
}
}
Output-Based JavaScript Questions
111 reviewed questions.
Intermediate level
1. Array equality compares references?
Code example:Answer
Answer: Exact output: false, then true
Why: Each array literal creates a distinct object; b points to the same object as a.
console.log([] === []);
const a = [];
const b = a;
console.log(a === b);
2. Arrow function and arguments?
Code example:Answer
Answer: Exact output: outer
Why: Arrow functions do not create their own arguments object; they capture the surrounding one.
function outer() {
const arrow = () => console.log(arguments[0]);
arrow('inner');
}
outer('outer');
3. Async function return value?
Code example:Answer
Answer: Exact output: true, then 42
Why: An async function always returns a Promise fulfilled with its returned value.
async function getValue() {
return 42;
}
console.log(getValue() instanceof Promise);
getValue().then(console.log);
4. Basic var hoisting?
Code example:Answer
Answer: Exact output: undefined, then 10
Why: The declaration is hoisted and initialized with undefined; the assignment stays in place.
console.log(a);
var a = 10;
console.log(a);
5. Boolean arithmetic?
Code example:Answer
Answer: Exact output: 2, 1, 0
Why: Numeric conversion maps true to 1 and false to 0.
console.log(true + true);
console.log(true + false);
console.log(Number(false));
6. Chained map and filter order?
Code example:Answer
Answer: Exact output: [6, 8]
Why: map first creates [2, 4, 6, 8], then filter keeps values above 4.
const result = [1, 2, 3, 4]
.map(value => value * 2)
.filter(value => value > 4);
console.log(result);
7. Changing key resets state?
Code example:Answer
Answer: Exact output: A changed userId resets Profile's local state
Why: Changing the key makes React treat it as a different component instance.
<Profile key={userId} userId={userId} />
8. Class Temporal Dead Zone?
Code example:Answer
Answer: Exact output: ReferenceError
Why: Class declarations are not usable before their declaration is evaluated.
const user = new User();
class User {}
9. Closure counter?
Code example:Answer
Answer: Exact output: 1, 2
Why: The returned function retains access to its lexical environment.
function counter() {
let count = 0;
return () => ++count;
}
const next = counter();
console.log(next());
console.log(next());
10. Closure with let in a loop?
Code example:Answer
Answer: Exact output: 0, 1, 2
Why: let creates a new binding for every iteration.
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
11. Closure with var in a loop?
Code example:Answer
Answer: Exact output: 3, 3, 3
Why: All callbacks close over the same function-scoped variable.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
12. Default parameter scope?
Code example:Answer
Answer: Exact output: ReferenceError
Why: The parameter's own uninitialized binding shadows the outer value in the default-expression scope.
let value = 5;
function show(value = value) {
return value;
}
show();
13. Default sort is lexicographic?
Code example:Answer
Answer: Exact output: [1, 10, 2]
Why: Without a comparator, sort compares string representations.
const values = [10, 2, 1];
values.sort();
console.log(values);
14. Destructuring defaults and holes?
Code example:Answer
Answer: Exact output: 10, null, 30
Why: Defaults apply to undefined or a missing element, but not to null.
const [a = 10, b = 20, c = 30] = [undefined, null];
console.log(a, b, c);
15. Destructuring defaults?
Code example:Answer
Answer: Exact output: null, 20
Why: A default value is used only when the property is undefined.
const { a = 10, b = 20 } = {
a: null,
b: undefined,
};
console.log(a, b);
16. Duplicate function declarations?
Code example:Answer
Answer: Exact output: 2
Why: In the same scope, the later function declaration replaces the earlier declaration.
console.log(getValue());
function getValue() { return 1; }
function getValue() { return 2; }
17. Effect cleanup order?
Code example:Answer
Answer: Exact output: For 0 to 1: effect 0, cleanup 0, effect 1
Why: React cleans up the previous effect before running the replacement.
useEffect(() => {
console.log('effect', count);
return () => console.log('cleanup', count);
}, [count]);
18. Empty array conversions?
Code example:Answer
Answer: Exact output: empty string, 0, true
Why: An empty array converts to an empty string, which converts to zero for numeric comparison.
console.log(String([]));
console.log(Number([]));
console.log([] == false);
19. Empty dependency stale closure?
Code example:Answer
Answer: Exact output: It repeatedly logs the initial count
Why: The effect callback captures count from the first render.
useEffect(() => {
const id = setInterval(() => console.log(count), 1000);
return () => clearInterval(id);
}, []); // captures the initial count
20. Event loop: Promise vs timer?
Code example:Answer
Answer: Exact output: A, D, C, B
Why: Synchronous code runs first, then microtasks, then timer tasks.
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');
21. FlatList and extraData?
Code example:Answer
Answer: Exact output: Rows may not update when only selectedId changes
Why: FlatList behaves like a PureComponent and may skip work when its relevant props remain shallow-equal.
<FlatList
data={items}
renderItem={({ item }) => (
<Row item={item} selected={selectedId === item.id} />
)}
/>
22. Function closure after return?
Code example:Answer
Answer: Exact output: 1, then 2
Why: inner retains the lexical environment of the completed outer call.
function outer() {
let value = 1;
return function inner() {
console.log(value++);
};
}
const next = outer();
next();
next();
23. Function declaration and var assignment?
Code example:Answer
Answer: Exact output: function, then number
Why: The function declaration initializes value first; the runtime assignment later replaces it with 10.
console.log(typeof value);
var value = 10;
function value() {}
console.log(typeof value);
24. Function declaration hoisting?
Code example:Answer
Answer: Exact output: Hello
Why: A function declaration is hoisted together with its function body.
sayHello();
function sayHello() {
console.log('Hello');
}
25. Function expression hoisting?
Code example:Answer
Answer: Exact output: TypeError: sayHello is not a function
Why: Only the var declaration is hoisted. Its value is undefined at the call.
sayHello();
var sayHello = function () {
console.log('Hello');
};
26. Function length?
Code example:Answer
Answer: Exact output: 3, 1, 0
Why: Function length counts parameters before the first default and excludes the rest parameter.
function first(a, b, c) {}
function second(a, b = 2, c) {}
function third(...args) {}
console.log(first.length, second.length, third.length);
27. Functional state updates?
Code example:Answer
Answer: Exact output: After one press, count is 3
Why: React applies each updater to the result of the previous queued updater.
setCount(c => c + 1);
setCount(c => c + 1);
setCount(c => c + 1);
28. Getter execution?
Code example:Answer
Answer: Exact output: getter, then React Native
Why: Reading an accessor property executes its getter function.
const user = {
first: 'React',
last: 'Native',
get name() {
console.log('getter');
return `${this.first} ${this.last}`;
},
};
console.log(user.name);
29. Heavy JavaScript work and UI?
Code example:Answer
Answer: Exact output: The app can freeze or drop frames until the loop finishes
Why: Heavy synchronous work blocks the JavaScript thread and delays event handling and React updates.
const press = () => {
const result = expensiveSynchronousLoop();
setResult(result);
};
30. Hoisting with var?
Code example:Answer
Answer: Exact output: undefined
Why: The local declaration is hoisted, but the assignment remains in its original place.
var x = 21;
function test() {
console.log(x);
var x = 20;
}
test();
31. Lazy state initializer?
Code example:Answer
Answer: Exact output: Normally initialize prints only on mount
Why: React calls the initializer to create initial state, not on every ordinary re-render.
const [value] = useState(() => {
console.log('initialize');
return expensiveCalculation();
});
32. Local var shadows outer variable?
Code example:Answer
Answer: Exact output: undefined
Why: The local var is hoisted and shadows the outer count throughout the function.
var count = 10;
function show() {
console.log(count);
var count = 20;
}
show();
33. Logging immediately after setState?
Code example:Answer
Answer: Exact output: The first press logs 0
Why: The handler continues using state from the render that created it.
const [count, setCount] = useState(0);
const press = () => {
setCount(1);
console.log(count);
};
34. Loose vs strict equality?
Code example:Answer
Answer: Exact output: true, false, true, false
Why: Loose equality performs type coercion; strict equality requires matching types.
console.log(0 == false);
console.log(0 === false);
console.log('' == false);
console.log('' === false);
35. Multiple Promise microtasks?
Code example:Answer
Answer: Exact output: start, end, p1, p2
Why: Promise callbacks are queued in registration order after synchronous code.
console.log('start');
Promise.resolve().then(() => console.log('p1'));
Promise.resolve().then(() => console.log('p2'));
console.log('end');
36. Mutating React state?
Code example:Answer
Answer: Exact output: A re-render may be skipped
Why: The setter receives the same object reference, so React can consider the state unchanged.
const [user, setUser] = useState({ name: 'Alex' });
const press = () => {
user.name = 'Sam';
setUser(user);
};
37. NaN equality?
Code example:Answer
Answer: Exact output: false, true, true
Why: NaN is unequal to every value under ===, including itself.
console.log(NaN === NaN);
console.log(Object.is(NaN, NaN));
console.log(Number.isNaN(NaN));
38. Named function expression scope?
Code example:Answer
Answer: Exact output: function, then undefined
Why: The expression's name is available inside its own body, not in the surrounding scope.
const run = function internal() {
console.log(typeof internal);
};
run();
console.log(typeof internal);
39. Nested Promise microtasks?
Code example:Answer
Answer: Exact output: 1, 2, 3
Why: The inner Promise callback is queued before the next chained reaction becomes runnable.
Promise.resolve()
.then(() => {
console.log(1);
Promise.resolve().then(() => console.log(2));
})
.then(() => console.log(3));
40. OR vs nullish coalescing?
Code example:Answer
Answer: Exact output: 100, 0, 100
Why: || falls back for all falsy values; ?? only for null or undefined.
console.log(0 || 100);
console.log(0 ?? 100);
console.log(null ?? 100);
41. Object dependency causes repeated effects?
Code example:Answer
Answer: Exact output: fetch runs after every render
Why: A new options object is created on every render.
const options = { page: 1 };
useEffect(() => {
console.log('fetch');
}, [options]);
42. Object keys are coerced to strings?
Code example:Answer
Answer: Exact output: second
Why: Both object keys become the same string, '[object Object]'.
const store = {};
const first = { id: 1 };
const second = { id: 2 };
store[first] = 'first';
store[second] = 'second';
console.log(store[first]);
43. Object.assign is shallow?
Code example:Answer
Answer: Exact output: true
Why: Object.assign copies the nested reference rather than cloning it.
const source = { settings: { dark: false } };
const copy = Object.assign({}, source);
copy.settings.dark = true;
console.log(source.settings.dark);
44. Object.freeze is shallow?
Code example:Answer
Answer: Exact output: Pune
Why: The outer object is frozen, but the nested address object is not.
const user = Object.freeze({
name: 'Alex',
address: { city: 'Delhi' },
});
user.address.city = 'Pune';
console.log(user.address.city);
45. Optional chaining?
Code example:Answer
Answer: Exact output: undefined, Guest
Why: Optional chaining stops safely at null/undefined; ?? supplies the fallback.
const user = null;
console.log(user?.profile?.name);
console.log(user?.profile?.name ?? 'Guest');
46. Parameter and var with the same name?
Code example:Answer
Answer: Exact output: 10, then 20
Why: The parameter supplies the initial local value; redeclaring it with var does not reset it.
function show(value) {
console.log(value);
var value = 20;
console.log(value);
}
show(10);
47. Promise chain values?
Code example:Answer
Answer: Exact output: 2, 4
Why: Each then receives the value returned by the previous callback.
Promise.resolve(1)
.then(v => v + 1)
.then(v => {
console.log(v);
return v * 2;
})
.then(console.log);
48. Promise error recovery?
Code example:Answer
Answer: Exact output: error, recovered
Why: catch handles the rejection and returns a fulfilled value to the next then.
Promise.reject('error')
.catch(value => {
console.log(value);
return 'recovered';
})
.then(console.log);
49. Promise executor is synchronous?
Code example:Answer
Answer: Exact output: 1, 2, 4, 3
Why: The Promise constructor executes immediately. The then callback is a microtask.
console.log(1);
new Promise(resolve => {
console.log(2);
resolve();
}).then(() => console.log(3));
console.log(4);
50. Promise.race?
Code example:Answer
Answer: Exact output: fast
Why: race settles with the first input to settle, not the first item in array order.
Promise.race([
new Promise(resolve => setTimeout(() => resolve('slow'), 20)),
Promise.resolve('fast'),
]).then(console.log);
51. Prototype property lookup?
Code example:Answer
Answer: Exact output: admin, then editor
Why: user has no own role, so lookup follows its prototype reference.
const parent = { role: 'admin' };
const user = Object.create(parent);
user.name = 'Alex';
console.log(user.role);
parent.role = 'editor';
console.log(user.role);
52. React.memo and inline object?
Code example:Answer
Answer: Exact output: Child can log again whenever Parent renders
Why: The inline style is a new object reference, so shallow prop comparison fails.
<View style={style} />;
});
function Parent() {
return <Child style={{ flex: 1 }} />;
}
53. Ref updates?
Code example:Answer
Answer: Exact output: It increases once for each render
Why: A ref persists between renders, but changing current does not cause a render.
const renders = useRef(0);
renders.current += 1;
console.log(renders.current);
54. Regular method vs arrow this?
Code example:Answer
Answer: Exact output: Alex, then usually undefined
Why: A regular method receives the calling object as this. An arrow captures lexical this.
const user = {
name: 'Alex',
regular() { console.log(this.name); },
arrow: () => console.log(this.name),
};
user.regular();
user.arrow();
55. Render and effect order?
Code example:Answer
Answer: Exact output: Production: render, effect
Why: The component renders first; the passive effect runs after commit.
<Text>Hello</Text>;
}
56. Repeated direct state updates?
Code example:Answer
Answer: Exact output: After one press, count is 1
Why: All calls calculate the next value from count captured by the current render.
const [count, setCount] = useState(0);
const press = () => {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
};
57. Rest parameters?
Code example:Answer
Answer: Exact output: 1, then [2, 3, 4]
Why: The rest parameter collects remaining arguments into a real array.
function inspect(first, ...rest) {
console.log(first);
console.log(rest);
}
inspect(1, 2, 3, 4);
58. ScrollView vs FlatList output behavior?
Code example:Answer
Answer: ScrollView mounts its children eagerly, which is simple and appropriate for bounded content. FlatList virtualizes data-backed rows and is usually the safer baseline when item count or row cost can grow, but it adds tuning and state-preservation considerations. I choose from measured memory, fill rate, interaction cost, and product constraints rather than a fixed item-count rule.
<ScrollView>
{items.map(item => <Row key={item.id} item={item} />)}
</ScrollView>
59. Shallow object equality?
Code example:Answer
Answer: Exact output: false, false
Why: Both operators compare object identity, and these are separate objects.
const a = { value: 1 };
const b = { value: 1 };
console.log(a === b);
console.log(Object.is(a, b));
60. Shallow spread copy?
Code example:Answer
Answer: Exact output: Sam
Why: Spread creates a new outer object but shares nested references.
const a = { user: { name: 'Alex' } };
const b = { ...a };
b.user.name = 'Sam';
console.log(a.user.name);
61. Shared object reference?
Code example:Answer
Answer: Exact output: Sam
Why: a and b contain references to the same object.
const a = { name: 'Alex' };
const b = a;
b.name = 'Sam';
console.log(a.name); // 'Sam'
62. Spread creates a shallow array copy?
Code example:Answer
Answer: Exact output: 9
Why: The array container is new, but the nested object reference is shared.
const first = [{ value: 1 }];
const second = [...first];
second[0].value = 9;
console.log(first[0].value);
63. Strict Mode console output?
Code example:Answer
Answer: Exact output: Development may print render twice; production normally once
Why: Strict Mode repeats selected work in development to expose impure rendering and missing cleanup.
<Text>Profile</Text>;
}
64. String addition vs numeric subtraction?
Code example:Answer
Answer: Exact output: 52, 3, 51
Why: The + operator concatenates when a string is involved; subtraction converts operands to numbers.
console.log('5' + 2);
console.log('5' - 2);
console.log(5 + '2' - 1);
65. String plus number coercion?
Code example:Answer
Answer: Exact output: 52, 3, 7
Why: + concatenates when one operand is a string; subtraction performs numeric coercion.
console.log('5' + 2);
console.log('5' - 2);
console.log(Number('5') + 2);
66. Strings are immutable?
Code example:Answer
Answer: Exact output: React
Why: Assigning to a string index does not modify the string value.
let text = 'React';
text[0] = 'X';
console.log(text);
67. Temporal Dead Zone?
Code example:Answer
Answer: Exact output: ReferenceError
Why: let is hoisted but cannot be accessed before its declaration is initialized.
console.log(value);
let value = 10;
68. Throwing inside then?
Code example:Answer
Answer: Exact output: data, caught
Why: An exception in a then callback rejects the Promise returned by that then.
Promise.resolve('data')
.then(value => {
console.log(value);
throw new Error('broken');
})
.catch(() => console.log('caught'));
69. Timer callback creates a microtask?
Code example:Answer
Answer: Exact output: start, end, timer 1, promise, timer 2
Why: After each timer task, JavaScript drains newly queued microtasks before the next timer task.
console.log('start');
setTimeout(() => {
console.log('timer 1');
Promise.resolve().then(() => console.log('promise'));
}, 0);
setTimeout(() => console.log('timer 2'), 0);
console.log('end');
70. Truthiness of string values?
Code example:Answer
Answer: Exact output: true, true, false, true
Why: Every non-empty string and every object is truthy.
console.log(Boolean('false'));
console.log(Boolean('0'));
console.log(Boolean(''));
console.log(Boolean([]));
71. What is the output of a closure counter called three times?
Code example:Answer
Answer: It prints 1, 2, 3 because every call updates the same closed-over count. Separate calls to outer create independent closure environments.
function outer(){let count=0; return ()=>console.log(++count)}
const fn=outer(); fn(); fn(); fn(); // 1 2 3
72. What is the output of synchronous logs, Promise.then, and setTimeout(0)?
Code example:Answer
Answer: The output is 1, 4, 3, 2: synchronous logs run first, then the Promise microtask, then the timer macrotask. The interview-worthy reasoning is to evaluate operands and side effects in source order, then apply the relevant coercion, scope, or scheduling rule before stating the result.
console.log('1');
setTimeout(()=>console.log('2'),0);
Promise.resolve().then(()=>console.log('3'));
console.log('4');
// 1 4 3 2
73. What is the output of var versus let in a loop with setTimeout?
Code example:Answer
Answer: var produces 3,3,3 because all callbacks share one function-scoped binding after the loop. let produces 0,1,2 because each iteration gets a new binding.
for(var i=0;i<3;i++)setTimeout(()=>console.log(i)); // 3 3 3
for(let i=0;i<3;i++)setTimeout(()=>console.log(i)); // 0 1 2
74. What is the output when Promise.then and queueMicrotask are queued before a timer?
Code example:Answer
Answer: It prints A, E, C, D, B. Synchronous logs run first; Promise.then and queueMicrotask then run in enqueue order; the timer runs afterward.
console.log('A'); setTimeout(()=>console.log('B')); Promise.resolve().then(()=>console.log('C')); queueMicrotask(()=>console.log('D')); console.log('E'); // A E C D B
75. What is the output when a property exists only on the prototype?
Code example:Answer
Answer: It prints John because property lookup falls through the instance to Person.prototype. The interview-worthy reasoning is to evaluate operands and side effects in source order, then apply the relevant coercion, scope, or scheduling rule before stating the result.
function Person(){} Person.prototype.name='John'; const p=new Person(); console.log(p.name); // John
76. What is the result of [] + []?
Code example:Answer
Answer: It is an empty string because both arrays convert to empty strings and + performs string concatenation. The interview-worthy reasoning is to evaluate operands and side effects in source order, then apply the relevant coercion, scope, or scheduling rule before stating the result.
[] + [] // ''
77. What is the result of [] == false?
Code example:Answer
Answer: It is true: the array converts to an empty string and then 0, while false converts to 0. The interview-worthy reasoning is to evaluate operands and side effects in source order, then apply the relevant coercion, scope, or scheduling rule before stating the result.
[] == false // true
78. What is the result of {} + []?
Code example:Answer
Answer: The result is parsing-context dependent: leading {} may be parsed as a block, while parenthesized objects convert to '[object Object]'. Never rely on this ambiguity.
({}) + [] // '[object Object]'
79. async/await ordering?
Code example:Answer
Answer: Exact output: 3, 1, 4, 2
Why: The function runs synchronously until await. Its continuation is a microtask.
async function run() {
console.log(1);
await Promise.resolve();
console.log(2);
}
console.log(3);
run();
console.log(4);
80. await with a non-Promise value?
Code example:Answer
Answer: Exact output: A, C, B
Why: await behaves like awaiting Promise.resolve(10), so continuation is asynchronous.
async function run() {
console.log('A');
await 10;
console.log('B');
}
run();
console.log('C');
81. call, apply and bind?
Code example:Answer
Answer: Exact output: Alex-Delhi, Alex-Pune, Alex-Noida
Why: call invokes with separate arguments, apply invokes with an array-like list, and bind returns a function.
function intro(city) {
return `${this.name}-${city}`;
}
const user = { name: 'Alex' };
console.log(intro.call(user, 'Delhi'));
console.log(intro.apply(user, ['Pune']));
console.log(intro.bind(user, 'Noida')());
82. catch recovers a Promise chain?
Code example:Answer
Answer: Exact output: failed, recovered
Why: Returning from catch fulfills the next Promise.
Promise.reject('failed')
.catch(error => {
console.log(error);
return 'recovered';
})
.then(console.log);
83. const before declaration?
Code example:Answer
Answer: Exact output: ReferenceError
Why: const also remains in the Temporal Dead Zone until its declaration executes.
console.log(apiUrl);
const apiUrl = 'example.com';
84. const object mutation?
Code example:Answer
Answer: Exact output: Sam
Why: const prevents rebinding, not mutation of the referenced object.
const user = { name: 'Alex' };
user.name = 'Sam';
console.log(user.name);
85. delete leaves an array hole?
Code example:Answer
Answer: Exact output: 3, then false
Why: delete removes the indexed property but does not shift elements or change length.
const values = [10, 20, 30];
delete values[1];
console.log(values.length);
console.log(1 in values);
86. delete reveals a prototype value?
Code example:Answer
Answer: Exact output: 2, then 1
Why: Deleting the own property exposes the inherited property during the next lookup.
const parent = { value: 1 };
const child = Object.create(parent);
child.value = 2;
console.log(child.value);
delete child.value;
console.log(child.value);
87. fill shares object references?
Code example:Answer
Answer: Exact output: [5, 5, 5]
Why: fill inserts the same object reference into every position.
const rows = Array(3).fill({ count: 0 });
rows[0].count = 5;
console.log(rows.map(row => row.count));
88. filter(Boolean)?
Code example:Answer
Answer: Exact output: [1, 'RN']
Why: Boolean removes all falsy values, not only null and undefined.
const values = [0, 1, '', 'RN', null, undefined, false];
console.log(values.filter(Boolean));
89. finally does not replace a value?
Code example:Answer
Answer: Exact output: data
Why: A normal return from finally does not replace the settled value.
Promise.resolve('data')
.finally(() => 'other')
.then(console.log);
90. forEach return value?
Code example:Answer
Answer: Exact output: undefined
Why: forEach is for side effects and always returns undefined.
const result = [1, 2, 3].forEach(value => value * 2);
console.log(result);
91. in vs own property?
Code example:Answer
Answer: Exact output: true, then false
Why: in checks the prototype chain; Object.hasOwn checks only the object itself.
const parent = { role: 'admin' };
const user = Object.create(parent);
user.name = 'Alex';
console.log('role' in user);
console.log(Object.hasOwn(user, 'role'));
92. includes handles NaN?
Code example:Answer
Answer: Exact output: -1, true
Why: indexOf uses strict-equality-like comparison; includes uses SameValueZero, which matches NaN.
const values = [1, NaN, 3];
console.log(values.indexOf(NaN));
console.log(values.includes(NaN));
93. let before declaration?
Code example:Answer
Answer: Exact output: ReferenceError
Why: let is hoisted but remains uninitialized in the Temporal Dead Zone.
console.log(a);
let a = 10;
94. let function expression?
Code example:Answer
Answer: Exact output: ReferenceError
Why: The let binding exists but is still in the Temporal Dead Zone.
greet();
let greet = function () {
console.log('Hello');
};
95. let is block-scoped?
Code example:Answer
Answer: Exact output: ReferenceError
Why: The let binding exists only inside the if block.
function test() {
if (true) {
let message = 'inside';
}
console.log(message);
}
test();
96. map callback without return?
Code example:Answer
Answer: Exact output: [undefined, undefined, undefined]
Why: A block-bodied arrow function needs an explicit return.
const result = [1, 2, 3].map(value => {
value * 2;
});
console.log(result);
97. map with an async callback?
Code example:Answer
Answer: Exact output: true
Why: An async callback always returns a Promise, so map creates an array of Promises.
const results = [1, 2, 3].map(async value => value * 2);
console.log(results[0] instanceof Promise);
98. map with parseInt?
Code example:Answer
Answer: Exact output: [1, NaN, NaN]
Why: map supplies value, index and array. parseInt treats the index as its radix.
console.log(['1', '2', '3'].map(parseInt));
99. null and undefined arithmetic?
Code example:Answer
Answer: Exact output: 1, NaN, 0, NaN
Why: Numeric conversion turns null into 0 and undefined into NaN.
console.log(null + 1);
console.log(undefined + 1);
console.log(Number(null));
console.log(Number(undefined));
100. null compared with undefined?
Code example:Answer
Answer: Exact output: true, false
Why: Loose equality has a special rule making null equal to undefined; strict equality distinguishes them.
console.log(null == undefined);
console.log(null === undefined);
101. push return value?
Code example:Answer
Answer: Exact output: 4, then [1, 2, 3, 4]
Why: push mutates the array and returns its new length.
const values = [1, 2, 3];
const result = values.push(4);
console.log(result);
console.log(values);
102. reduce without an initial value?
Code example:Answer
Answer: Exact output: 6
Why: The first element becomes the initial accumulator and iteration starts at index 1.
const values = [1, 2, 3];
const total = values.reduce((sum, value) => sum + value);
console.log(total);
103. replace changes only the first string match?
Code example:Answer
Answer: Exact output: RN JS JS, then RN RN RN
Why: A string search in replace affects only the first occurrence; replaceAll affects all.
const text = 'JS JS JS';
console.log(text.replace('JS', 'RN'));
console.log(text.replaceAll('JS', 'RN'));
104. slice vs splice?
Code example:Answer
Answer: Exact output: [2, 3], [1, 2, 3, 4], [2, 3], [1, 4]
Why: slice returns a non-mutating copy; splice removes/replaces elements in the original.
const values = [1, 2, 3, 4];
console.log(values.slice(1, 3));
console.log(values);
console.log(values.splice(1, 2));
console.log(values);
105. slice with negative indexes?
Code example:Answer
Answer: Exact output: Script, then JavaScript
Why: slice counts negative indexes from the end; substring treats negative values as zero.
const text = 'JavaScript';
console.log(text.slice(-6));
console.log(text.substring(-6));
106. typeof null?
Code example:Answer
Answer: Exact output: 'object'
Why: This is a historical JavaScript language quirk.
console.log(typeof null); // 'object'
107. useCallback reference stability?
Code example:Answer
Answer: Exact output: The function reference stays stable until count changes
Why: useCallback returns the same function while dependencies are equal.
const onPress = useCallback(() => {
console.log(count);
}, [count]);
108. useMemo dependencies?
Code example:Answer
Answer: Exact output: calculate runs on mount and when the items reference changes
Why: useMemo reuses its cached value while dependencies remain equal by Object.is.
const total = useMemo(() => {
console.log('calculate');
return items.reduce((sum, x) => sum + x.price, 0);
}, [items]);
109. var function expression?
Code example:Answer
Answer: Exact output: undefined, then TypeError
Why: The variable exists as undefined, but the function assignment has not executed.
console.log(typeof greet);
greet();
var greet = function () {
console.log('Hello');
};
110. var is function-scoped?
Code example:Answer
Answer: Exact output: inside
Why: var does not create an if-block scope.
function test() {
if (true) {
var message = 'inside';
}
console.log(message);
}
test();
111. var vs let in loop?
Code example:Answer
Answer: Exact output: var prints 3, 3, 3; let prints 0, 1, 2.
Why: var shares one function-scoped binding; let creates a binding per iteration.
for (var i = 0; i < 3; i++) setTimeout(() => console.log(i)); // 3 3 3
for (let i = 0; i < 3; i++) setTimeout(() => console.log(i)); // 0 1 2
Scenario-Based Questions
13 reviewed questions.
Intermediate level
1. Context causes input lag in a large form?
Answer
Answer: A changing Provider value notifies every consumer, so one Context containing fifteen fields can re-render the whole form per keystroke. I keep field state local or use React Hook Form with field subscriptions, split stable contexts, and memoize Provider values. Context is dependency distribution, not automatically an efficient high-frequency store.
2. Images cause OutOfMemoryError on Android?
Answer
Answer: I capture memory evidence and check decoded bitmap dimensions rather than only compressed file size. I request correctly sized images, avoid mounting too many at once, limit concurrent decodes, and use a maintained image pipeline with memory and disk caching. I then repeat the failing scroll path under constrained memory to verify that the peak and retained heap are lower.
3. Push works in foreground but not when app is killed?
Answer
Answer: I verify FCM and APNs credentials for the correct environment, bundle/package identifiers, Android channels, payload type, iOS entitlements, provisioning, and Background Modes. I test a fully killed release build on a real device because foreground JavaScript handlers are not sufficient for terminated state.
4. Screen re-renders every second with no visible change?
Answer
Answer: I use the React Profiler to identify the component that commits and inspect which state, props, or context value changed. Common causes include timer-driven state, recreated provider values, parent updates, and duplicated focus listeners. I remove unnecessary state writes or move rapidly changing state to the smallest owner, then profile the same interaction again.
5. TextInput is hidden behind the keyboard on Android?
Answer
Answer: I inspect the window soft-input mode, edge-to-edge insets, keyboard-aware layout, and scroll-container hierarchy. Depending on the navigation and Android configuration, I use an inset-aware keyboard controller or KeyboardAvoidingView and ensure the focused field can scroll into view. I verify the result on representative real devices because adjustResize behavior varies with window configuration.
6. onEndReached fires multiple times and duplicates pagination data. How do you fix it?
Answer
Answer: I add an isFetchingNextPage guard, track whether more data exists, and deduplicate records by stable id. I avoid changing the data reference unnecessarily during momentum and can use onMomentumScrollBegin when the UX requires it. With React Query I use fetchNextPage and its built-in isFetchingNextPage flag. The backend should preferably use cursor pagination so repeated requests are idempotent.
Advanced level
7. How would you diagnose a page becoming unresponsive after processing a large dataset?
Answer
Answer: Profile to confirm synchronous CPU work, then reduce complexity, virtualize rendered data, and chunk, defer, or move computation off the critical thread.
8. How would you migrate a legacy application to the New Architecture?
Answer
Answer: Upgrade incrementally, baseline crashes and performance, inventory libraries, replace abandoned dependencies, migrate custom specs, establish release E2E coverage, and stage the rollout with flags. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
9. How would you optimize an app with rising memory, slow renders, and long synchronous tasks?
Answer
Answer: Profile each symptom separately, fix retained resources, virtualize large lists, reduce hot re-renders, memoize measured bottlenecks, and split or move long synchronous work.
10. How would you redesign an app that has become difficult to maintain?
Answer
Answer: I first map dependencies, state ownership, API boundaries, native integrations, and pain metrics. I define feature boundaries and shared platform services, introduce typed interfaces and tests around current behavior, then migrate one vertical feature at a time. I separate server state from client state, centralize design tokens/network/security, add observability and CI gates, and avoid a risky full rewrite unless evidence justifies it.
11. How would you safely adopt React 19 in an existing React Native application?
Answer
Answer: Start from the React version supported by the selected React Native release rather than upgrading React independently. Audit native libraries, navigation, testing tools, custom render behavior, and deprecated APIs; then upgrade on a branch, run Android and iOS regression suites, profile startup and rendering, and use a staged rollout. Keep a rollback path until crash-free sessions and business journeys are stable. In React Native, availability follows the React version bundled by the chosen React Native release, so I verify that toolchain before using the API.
12. How would you structure a large React Native codebase?
Answer
Answer: Organize by product domains and public interfaces; presentation depends on use cases and domain models; infrastructure implements APIs, storage, analytics, and native adapters; a design system owns primitives.
13. The app is slow. Walk through your investigation?
Answer
Answer: I first define the symptom: startup, navigation, scrolling, input, network, or memory. I reproduce in release mode and inspect JS/UI FPS, React renders, Hermes CPU, native traces, network timing, images, and memory. I form one hypothesis, change one bottleneck, compare metrics, and add a regression guard. I never begin by adding memoization everywhere.
HR & Behavioral Questions
7 reviewed questions.
Advanced level
1. Describe a production mistake you made and what changed afterward?
Answer
Answer: Use a specific STAR story, own your contribution without blaming others, explain the immediate recovery, and quantify both user impact and the result. Finish with the durable process, test, observability, or design change you helped implement and how you verified it reduced recurrence.
2. How do you handle disagreement on architecture?
Answer
Answer: Restate constraints and success criteria, compare trade-offs, migration, failure modes, and reversibility, time-box evidence-gathering, record the ADR and revisit trigger, then support the decision.
3. How do you lead a performance improvement across a team?
Answer
Answer: Turn 'slow' into agreed metrics and representative devices, baseline, assign bottleneck ownership, review traces, set budgets, prioritize user impact, and encode proven patterns in shared components.
4. How do you mentor engineers while maintaining delivery speed?
Answer
Answer: Match support to risk and experience through pairing, examples, bounded ownership, and reasoning-focused reviews; protect feedback time and remove recurring friction with tooling and docs.
5. Tell me about a production incident—how should a senior answer?
Answer
Answer: Use a quantified situation, detection and containment, evidence-based cause, communication, and durable prevention. Separate the trigger from systemic contributors and state the learning.
6. Tell me about a time you disagreed with a technical decision?
Answer
Answer: Use a truthful STAR example that explains the shared goal, the evidence behind your disagreement, how you listened and proposed an experiment, the decision the team made, and the measured result. Show that you can disagree without turning the discussion into a contest and can commit after a decision.
7. What do you look for in code review as a senior engineer?
Answer
Answer: Review correctness, cancellation and failure paths, state ownership, security, privacy, accessibility, realistic performance, tests, native lifecycle, and observability; separate blockers from suggestions and explain why.
Continue the series
You have reached the final part. Revisit weak topics and practise answering them aloud.
Top comments (0)