Frontend Developer Mid-Level Interview Preparation Guide (FAANG Standards)
This guide is based on general FAANG interview practices and may not reflect specific company procedures.
FAANG companies typically conduct 6-8 interview rounds for mid-level frontend developers, progressing from recruiter screening through multiple technical evaluations (coding, UI implementation, and system design), behavioral assessment, and leadership conversations. Mid-level candidates are expected to demonstrate strong technical proficiency, ability to own projects end-to-end, mentorship of junior developers, and alignment with company culture. The interview process emphasizes problem-solving approach, communication, code quality, and growth trajectory.
Interview Rounds
Recruiter Screening
What to Expect
Initial conversation with a technical recruiter to assess general fit, background, career trajectory, and alignment with the role and company. This is a preliminary filter to ensure you meet minimum requirements and are genuinely interested. Expect questions about your current role, motivation for the move, location/visa requirements, and timeline.
Tips & Advice
Be clear and concise about your motivation for applying. Have a strong 2-minute summary of your frontend development experience ready. Ask thoughtful questions about the role, team structure, and technology stack. Emphasize your track record with performance, user experience, or specific technical achievements. Be honest about timeline and constraints to avoid mismatches later.
Focus Topics
Technical Stack Familiarity
Discuss your hands-on experience with relevant technologies: modern JavaScript frameworks (React, Vue, Angular), CSS, responsive design, state management, API integration, and performance optimization tools.
Practice Interview
Study Questions
Motivation and Company Alignment
Articulate why you're interested in this specific role and company. Connect your interests (e.g., working on high-scale systems, specific technology stack, company mission) to genuine alignment rather than generic reasons.
Practice Interview
Study Questions
Career Background and Progression
Clearly articulate your 2-5 years of frontend development experience, key projects you've led or contributed to, and progression from junior to mid-level responsibilities. Discuss growth in technical depth and scope of ownership.
Practice Interview
Study Questions
Technical Phone Screen (JavaScript Fundamentals)
What to Expect
First technical round conducted via video call, focusing on core JavaScript knowledge and basic problem-solving. Expect 1-2 coding problems of medium difficulty that test understanding of JavaScript fundamentals, data structures, and algorithms. May include live coding on a shared platform (CodePen, CoderPad, or similar). This round assesses whether you have strong foundational JavaScript knowledge required for more advanced rounds.
Tips & Advice
Think aloud throughout the problem-solving process. Start by clarifying the problem and edge cases before writing code. Write clean, readable code with meaningful variable names. Test your solution mentally with examples. If stuck, communicate your thinking and ask for hints rather than sitting silently. Optimize after getting a working solution if time permits. Practice on LeetCode medium-level problems and JavaScript-specific challenges (implementing Array methods, Promise polyfills, etc.).
Focus Topics
DOM Manipulation and Browser APIs
Understanding of DOM structure, methods for selecting and manipulating elements (querySelector, getElementById, etc.), event handling, and browser APIs relevant to frontend development.
Practice Interview
Study Questions
Problem Solving and Algorithm Thinking
Ability to break down problems into smaller steps, consider edge cases, and optimize solutions. Understand basic algorithmic concepts like sorting, searching, and time complexity analysis.
Practice Interview
Study Questions
Array and Object Manipulation
Proficiency with array methods (map, filter, reduce, sort, find, etc.), object manipulation techniques, and common data transformation patterns. Understand time and space complexity of these operations.
Practice Interview
Study Questions
JavaScript ES6+ Fundamentals
Master modern JavaScript syntax and features including arrow functions, destructuring, spread operator, template literals, let/const scoping, classes, async/await, Promises, and modules. Understand the event loop, closure, prototypal inheritance, and the this keyword in different contexts.
Practice Interview
Study Questions
Technical On-site Round 1 (Advanced JavaScript & Framework Expertise)
What to Expect
Second technical round (typically on-site or extended video interview) focusing on deeper JavaScript knowledge and framework expertise. Expect 1-2 coding problems that may involve implementing utilities, understanding framework concepts, or solving real-world frontend challenges. Questions may explore state management patterns, component lifecycle, hooks (if React), reactivity (if Vue), or dependency injection (if Angular).
Tips & Advice
Before the interview, review your most recent framework project in detail. Be prepared to discuss architectural decisions and trade-offs. Practice implementing utility functions commonly found in production (debounce, throttle, memoization, etc.). Understand async patterns deeply—how Promises chain, error handling in async/await, and race conditions. Prepare to explain how your chosen framework handles reactivity, component updates, and performance. Code with production quality in mind: error handling, edge cases, maintainability.
Focus Topics
Closures and Scope in Practical Context
Deep understanding of JavaScript closures, lexical scope, and how they apply to real patterns like event handlers, callbacks, custom hooks, and module patterns. Ability to identify and fix closure-related bugs.
Practice Interview
Study Questions
State Management Patterns
Understanding of different state management approaches: local component state, lifting state up, Context API, Redux/Vuex patterns, or other state libraries. Knowledge of when to use each approach and trade-offs between complexity and scalability.
Practice Interview
Study Questions
Performance Optimization Techniques
Practical techniques for optimizing frontend performance: memoization, React.memo, useMemo, useCallback hooks, code splitting, lazy loading, bundle optimization, and understanding rendering performance issues. Knowledge of tools like Chrome DevTools and Lighthouse.
Practice Interview
Study Questions
Asynchronous Programming and Promises
Complete mastery of Promises, async/await, error handling, race conditions, and common patterns like Promise.all(), Promise.race(), Promise.allSettled(). Understanding of callback patterns, event-driven architecture, and how async operations integrate with component lifecycle.
Practice Interview
Study Questions
React Fundamentals (or Vue/Angular depending on expertise)
Deep understanding of component architecture, hooks (useState, useEffect, useContext, useReducer, custom hooks), lifecycle methods, rendering optimization, and component composition patterns. Knowledge of controlled vs uncontrolled components, prop drilling vs context API, and when to use each pattern.
Practice Interview
Study Questions
Technical On-site Round 2 (UI Component Implementation & Practical Coding)
What to Expect
Third technical round focused on practical UI component implementation. You'll be asked to build a UI component or small application feature from scratch using HTML, CSS, and JavaScript (typically in your chosen framework). Examples include building an autocomplete dropdown, carousel, pagination component, form with validation, or similar. This round tests your ability to translate requirements into working code, handle edge cases, and produce production-quality UI.
Tips & Advice
Read the requirements carefully and ask clarifying questions before starting. Plan your approach: break the component into smaller pieces, think through state and event handling, then implement. Write semantic HTML first, then add styling and interactivity. Consider accessibility from the start (ARIA labels, keyboard navigation, screen reader compatibility). Test your implementation mentally or in the browser with edge cases. Write clean CSS—organize styles logically, avoid inline styles, consider responsiveness. For the JavaScript, handle events properly, manage component state clearly, and write reusable code. Leave time to refactor or optimize if the basic implementation is working.
Focus Topics
Cross-browser Compatibility and Testing
Knowledge of common browser compatibility issues, progressive enhancement, polyfills when needed, and testing across different browsers and devices. Understanding of how to use browser DevTools to debug issues.
Practice Interview
Study Questions
Component State Management and Props
Managing component state effectively, understanding when to use local state vs lifted state, prop passing, handling prop changes, and avoiding common pitfalls like stale closures or missing dependency arrays.
Practice Interview
Study Questions
Form Handling and Validation
Building forms with proper validation, error messaging, disabled states, and user feedback. Handling form submission, preventing double-submission, and integrating with backend APIs. Understanding controlled vs uncontrolled components in React context.
Practice Interview
Study Questions
Event Handling and User Interaction
Proper implementation of click handlers, form submissions, keyboard events, touch events, and event delegation. Understanding of event bubbling, event target, and how to handle events efficiently.
Practice Interview
Study Questions
Semantic HTML and Accessibility
Writing semantic, accessible HTML using appropriate elements (form, button, nav, article, etc.), ARIA attributes where needed, keyboard navigation support, screen reader compatibility, and inclusive design principles. Understanding of WCAG guidelines at a practical level.
Practice Interview
Study Questions
Responsive CSS and Layout
Mastery of CSS Grid, Flexbox, media queries, and responsive design principles. Understanding of CSS specificity, cascading, box model, and how to write maintainable CSS. Knowledge of CSS-in-JS approaches if using them. Ability to style components to match design specifications.
Practice Interview
Study Questions
System Design Round (Frontend Architecture & Scalability)
What to Expect
Focused on architectural thinking, scalability, and design patterns at the frontend level. You may be asked to design a system for a feature (e.g., designing a real-time notification system UI, building an infinite scroll implementation, architecting a complex form with multiple steps, or designing state management for a large application). This round tests your ability to think about scalability, performance, maintainability, and trade-offs. Unlike backend system design, frontend system design emphasizes user experience, performance, state management, and component architecture.
Tips & Advice
Start by understanding the requirements and constraints. Ask clarifying questions about scale, user expectations, performance requirements, and device support. Sketch your approach on a whiteboard or document—show component structure, data flow, state management approach. Discuss trade-offs: simplicity vs scalability, client-side vs server-side rendering, caching strategies, performance optimization techniques. Consider edge cases like network failures, loading states, error handling, and accessibility. Be prepared to dive deeper into specific areas (e.g., state management library selection, performance monitoring, testing strategy). For mid-level, demonstrate that you've thought about scaling beyond a simple solution.
Focus Topics
Handling Real-time Data and Server Communication
Strategies for managing real-time updates (WebSockets, Server-Sent Events, polling), synchronizing state with backend, handling offline scenarios, conflict resolution, and optimistic UI updates. Understanding of caching and data consistency.
Practice Interview
Study Questions
Testing Strategy and Error Handling
Planning a testing strategy for frontend systems: unit tests, integration tests, E2E tests, and the testing pyramid. Error boundaries, error recovery, graceful degradation, and user feedback mechanisms.
Practice Interview
Study Questions
Frontend Performance and Optimization
Strategies for optimizing performance: code splitting, lazy loading, caching (browser cache, CDN, memoization), bundling optimization, critical rendering path optimization, and monitoring tools. Understanding of Core Web Vitals and real user monitoring.
Practice Interview
Study Questions
State Management Strategy
Choosing appropriate state management solutions for different scenarios: local state for isolated components, lifted state for multiple components, Context API for shared state, or external libraries like Redux/Vuex for complex applications. Understanding when each approach is suitable.
Practice Interview
Study Questions
Component Architecture and Design Patterns
Designing scalable component hierarchies, understanding container vs presentational components, composition over inheritance, render props, higher-order components, or hooks patterns. Ability to break down complex UIs into manageable, reusable components.
Practice Interview
Study Questions
Behavioral Round (Project Ownership & Collaboration)
What to Expect
Focused on your past experiences, leadership qualities, teamwork, project ownership, and ability to mentor junior developers. Expect behavioral questions using the STAR method (Situation, Task, Action, Result). Questions typically explore: a challenging technical problem you solved, a time you took ownership of a project, conflict with a team member, mentoring a junior developer, learning something new, and handling ambiguous requirements. For mid-level, emphasize examples showing you own projects end-to-end, collaborate effectively, and develop others.
Tips & Advice
Prepare 5-7 concrete stories from your actual experience that demonstrate different competencies (ownership, learning, collaboration, problem-solving, mentorship). Use the STAR method: clearly set up the situation, explain your specific task/responsibility, describe the action you took (focus on 'I' not 'we'), and quantify the result. Be specific with metrics where possible (e.g., 'improved page load time by 40%', 'mentored 2 junior developers'). Practice telling these stories concisely—each should take 2-3 minutes. Show self-awareness: acknowledge mistakes honestly and explain what you learned. For mid-level, show examples of ownership (leading features, making technical decisions), not just individual contribution.
Focus Topics
Handling Ambiguity and Taking Initiative
Examples of working on projects with unclear requirements, how you clarified ambiguity, took initiative to propose solutions, and drove clarity in ambiguous situations.
Practice Interview
Study Questions
Collaboration and Cross-functional Teamwork
Examples of working closely with designers, backend engineers, product managers, or other teams. How you communicate, handle disagreements professionally, and find solutions that balance different perspectives.
Practice Interview
Study Questions
Technical Problem-Solving and Learning Agility
Examples of difficult technical problems you solved, your approach to understanding complex systems, how you troubleshoot issues, and examples of learning new technologies or frameworks on the job.
Practice Interview
Study Questions
Mentorship and Developing Others
Specific examples of mentoring junior developers: code reviews you led, teaching moments, helping someone grow technically, or onboarding them to projects. Show how you provide feedback, support growth, and improve code quality.
Practice Interview
Study Questions
Project Ownership and End-to-End Delivery
Examples of projects where you took ownership from design through deployment, made technical decisions, managed scope, handled setbacks, and delivered results. Demonstrate ability to see projects through completion and take accountability.
Practice Interview
Study Questions
Hiring Manager Round
What to Expect
Final round with the hiring manager or senior team member to assess overall fit, career aspirations, growth mindset, and alignment with team culture. This round is more conversational and less about technical testing. Expect questions about your career goals, what kind of problems interest you, how you prefer to work, your approach to code quality, and your understanding of the role's responsibilities. The hiring manager is assessing whether you'll be a good long-term fit and how you'll grow in the role.
Tips & Advice
Research the team, products, and impact they're working on. Prepare thoughtful questions about the role, team dynamics, growth opportunities, and company culture. Be authentic about your career interests and growth areas—this is not a time to oversell or pretend to be someone you're not. Show curiosity about the work and genuine enthusiasm. Listen carefully to the manager's description of the role and respond thoughtfully. Ask about the biggest technical challenges the team faces, the team's culture and working style, and opportunities for growth. Be honest about your strengths and areas for development.
Focus Topics
Understanding of Role Responsibilities
Demonstrate that you understand what mid-level frontend developers do at FAANG: own features end-to-end, mentor juniors, contribute to architectural decisions, and drive code quality. Show realistic expectations about the role.
Practice Interview
Study Questions
Cultural Fit and Values Alignment
Understanding and genuine alignment with company values (e.g., Amazon's Leadership Principles, Meta's values, Google's philosophy). Examples from your experience that demonstrate these values.
Practice Interview
Study Questions
Code Quality and Engineering Excellence
Your philosophy on code quality, testing, refactoring, and continuous improvement. How you approach technical debt, code reviews, and maintaining high standards while shipping features.
Practice Interview
Study Questions
Career Goals and Growth Mindset
Clear articulation of your career trajectory, where you want to go (senior IC, tech lead, architect), what skills you're developing, and how this role fits into your growth plan. Show commitment to continuous learning and improving.
Practice Interview
Study Questions
Frequently Asked Frontend Developer Interview Questions
Implement a React ErrorBoundary component that logs errors to a provided logger (for example, an error-tracking service like Sentry) and displays a localized fallback UI when a child component throws during render. Then write a React Testing Library test that asserts the logger was called and that the fallback text is rendered. Explain what an ErrorBoundary will and will not catch, and discuss the trade-off between showing a retry UI and surfacing the raw error to the user.
Sample Answer
Direct answer
A React error boundary catches rendering errors thrown by any component in its subtree during render, in lifecycle methods, and in constructors, logs the error with enough context to diagnose it, and shows a fallback UI instead of leaving the user with a blank screen or React's own default error overlay; it does not catch errors in event handlers, asynchronous code, or errors thrown in the boundary component itself.
Structured elaboration
What it catches. Errors thrown during the render phase of any component below the boundary in the tree, including errors in lifecycle methods (componentDidMount, etc.) and in constructors. This is React's mechanism for preventing one broken component from crashing the entire application.
What it does NOT catch, and why that matters. Event handlers (a click handler that throws is a normal JavaScript exception, not a React rendering error, and needs its own try/catch); asynchronous code (a .then() callback or an async function's rejection happens outside React's render cycle entirely); server-side rendering errors; and errors thrown by the error boundary component itself (a boundary cannot catch its own failures, which is why the boundary component should be kept as simple as possible, with minimal logic that could itself throw).
Logging to an error-tracking service. componentDidCatch(error, info) receives both the error object and a componentStack describing which component tree led to the failure; sending both to a service like Sentry, tagged with any available user or session context, turns "a customer reported a blank page" into "we can see exactly which component threw, with what stack, for which user" without waiting for the customer to describe what they were doing.
Retry UI versus surfacing the raw error. A "try again" button that resets the boundary's state and re-attempts rendering the subtree is appropriate when the failure might be transient (a component that failed because of a momentary bad prop from a slow API response); it is misleading for a deterministic bug that will fail identically on every retry, where a generic "something went wrong, we've been notified" message (with no false promise that retrying will help) is more honest to the user, even though it is less satisfying than a button that appears to offer control.
Worked example
class ErrorBoundary extends React.Component {
constructor(props) { super(props); this.state = { hasError: false }; }
static getDerivedStateFromError(error) { return { hasError: true }; }
componentDidCatch(error, info) {
if (this.props.logger) this.props.logger.logError(error, info.componentStack);
}
render() {
if (this.state.hasError) {
return <div role="alert">{this.props.fallbackText || 'Something went wrong.'}</div>;
}
return this.props.children;
}
}
Executed (React Testing Library, verified): rendering <ErrorBoundary logger={logger} fallbackText="We hit a snag. Please retry."><Boom /></ErrorBoundary>, where Boom throws during render, confirms screen.getByRole('alert') shows the fallback text and logger.logError was called exactly once with the thrown Error object. A second test confirms that when no child throws, the boundary renders its children normally and logger.logError is never called, so the boundary is confirmed to be transparent in the non-error case, not just functional in the error case.
Trade-offs and pitfalls
A single application-wide error boundary at the root catches everything but takes down the ENTIRE page for a failure in one small, non-critical widget; placing boundaries around individual independent sections (a sidebar widget, a comments section) means one broken component degrades gracefully to just that section showing a fallback, while the rest of the page keeps working, which is almost always the better default for anything with multiple independent sections. The most common mistake is assuming an error boundary catches an async data-fetching failure inside a useEffect: it does not, since that error occurs outside the render phase entirely, and needs its own explicit error state managed by the component, separate from the boundary mechanism.
Your team wants to build a stronger culture of craftsmanship. Describe three concrete daily or weekly habits you would adopt or promote to improve code quality, testing rigor, and design, and how you'd measure adoption and success.
Sample Answer
Direct answer
Three habits that compound because they're small enough to do daily and social enough to spread on their own: writing or updating a test alongside the code you're touching rather than as a separate later step, a weekly small-group code walkthrough where one person shares something interesting they wrote or found, and leaving code slightly better than you found it on every touch. Measure adoption with leading signals and success with a trailing signal a few months later, not a mandate announcement alone.
Structured elaboration
Habit one, daily: test alongside code. When touching a function, write or update its test in the same sitting, before moving on, instead of batching "add tests" as a separate task for later, which in practice usually means never. It's a small discipline per instance that compounds over months.
Habit two, weekly: a code walkthrough. A thirty-minute session where one person shows a piece of code they wrote or found interesting, a clever refactor, a tricky bug fix, a design decision they're unsure about, open discussion rather than a formal review. This spreads a tacit sense of what good looks like faster than a written standards document, and normalizes talking about code quality socially instead of only through review comments.
Habit three, on every touch: leave it better. A small, scoped improvement to whatever code you're touching, renaming an unclear variable, adding a missing test to an adjacent untested function, tightening an interface, bounded so it doesn't turn into unplanned scope creep on an unrelated ticket.
Measuring adoption and success: adoption is easiest to see as a leading signal, the share of merged pull requests that include a test change alongside the code change, walkthrough attendance and rotation of who presents, a count of small non-ticket cleanup commits. Success is a trailing signal reviewed monthly, the trend in review comments flagging a missing test, self-reported team confidence in the codebase from a short survey, and whether the same module keeps showing up in incident postmortems. Pair the adoption metrics with an occasional spot-check of quality, since presence alone can be gamed with a trivial test just to tick a box.
Worked example
A backend team of six adopts these three habits. In the first two weeks, the tech lead presents first at the weekly walkthrough to model the tone, informal rather than a performance review, then rotation cycles through the rest of the team. By the end of the first month, the share of merged pull requests including a test change rises noticeably from roughly half to nearly all, tracked from the pull request diff data rather than self-report. The leave-it-better habit shows up as a steady trickle of small cleanup commits alongside feature work, loosely tracked by a "cleanup" tag the team adopts as a commit-message convention. At the three-month mark, the team reviews together: review comments flagging missing tests have dropped noticeably, the walkthrough has surfaced two design issues early that would previously have only been caught in a later incident, and a quick anonymous survey shows most of the team feels more comfortable navigating the codebase than before, that combination, not any single number, is what the team uses to call the habits working.
Trade-offs and pitfalls
A daily habit that's too heavy, a full test-suite update on every touch, gets abandoned under deadline pressure, it has to be small enough to survive a genuinely busy week or it won't actually compound. The weekly walkthrough can slide into performance theater or quiet gatekeeping if the same senior person always presents and others feel judged, deliberately rotating presenters and keeping the tone informal matters as much as the format itself. The leave-it-better habit, left unbounded, turns into scope creep that annoys reviewers and slows down unrelated pull requests, it needs an explicit norm that the cleanup stays small and is mentioned in the pull request description rather than silently bundled in. And measuring only activity, walkthrough attendance, test-change percentage, without ever spot-checking quality risks celebrating habits that technically happened but didn't actually raise the bar.
You have a horizontal navigation bar with an unordered list. The design requires items to be centered vertically and spaced evenly across the width; on narrow screens the items should wrap onto multiple lines. Given this HTML:
<nav class='nav'><ul class='nav__list'><li class='nav__item'>Home</li><li class='nav__item'>Products</li><li class='nav__item'>About</li></ul></nav>
Write the CSS (using Flexbox) to achieve the design and explain how to make wrapping work correctly.
Sample Answer
Approach (brief)
Use Flexbox on the UL to lay out items in a row, center vertically via the NAV, allow wrapping with flex-wrap, and control per-item sizing with flex so items space evenly and wrap at a desired breakpoint. Use align-content to control spacing between wrapped rows.
CSS
/* container: center nav vertically */
.nav{
display: flex;
align-items: center; /* vertical centering of the UL inside the nav */
padding: 0 16px;
height: 64px; /* example height from design */
}
/* primary flex row */
.nav__list{
display: flex;
width: 100%;
margin: 0;
padding: 0;
list-style: none;
justify-content: space-between; /* distribute items across full width */
flex-wrap: wrap; /* allow items to wrap to new lines */
align-content: center; /* control vertical distribution of wrapped rows */
gap: 12px; /* gap between items (optional, modern browsers) */
}
/* each nav item */
.nav__item{
box-sizing: border-box;
flex: 1 1 160px; /* grow, shrink, base width = 160px (controls when wrapping occurs) */
text-align: center;
padding: 12px 8px;
white-space: nowrap; /* prevent internal wrapping of long labels */
}
Why this works / tips
- flex-wrap: wrap enables multi-line flow.
- flex: 1 1 160px gives each item equal share but lets them shrink; changing the base width adjusts when items wrap.
- justify-content controls spacing on each line; align-content controls spacing between lines when wrapped.
- If you need perfectly equal spacing including partial last row, consider using flex: 0 0 33.333% (fixed percents) or JavaScript to balance, but the flex approach is responsive and simple.
- Add accessibility/interaction styles (focus, hover) and test across browsers; include min-width or media-query tweaks for very small screens.
You're weighing a real investment in your own growth, whether that's a certification, an advanced degree, or simply protecting learning time against delivery pressure. Walk me through how you'd decide it's worth it, and how you'd negotiate the time or budget to do it.
Sample Answer
Direct answer
Decide by comparing the investment's expected payoff against its real cost, which is time and attention pulled from delivery, not just money, then bring your manager a specific, time-boxed ask paired with a coverage plan rather than an open-ended request.
Structured elaboration
- Name the investment type explicitly, since the shape of the ask differs: a certification (weigh its actual return on investment, or ROI, against the time and fee cost), a formal advanced degree (a far larger, multi-year time and money commitment for a credential), an internal on-the-job rotation (trades delivery time on your current team for exposure elsewhere), or simply protecting a fixed number of weekly hours split across growth domains.
- Compute the real cost honestly. If the ask is a fixed weekly-hours budget, name explicitly what shrinks to make room for it; a request that doesn't name its own trade-off reads as costless and gets challenged later.
- The negotiation lever that works is a bounded pilot: a defined number of weeks, a specific hours-per-week figure, a defined coverage plan for what you'd otherwise be doing, and a checkpoint partway through to reassess, rather than an open-ended protected-time request.
- If the ask involves protecting time against on-call or delivery pressure specifically, address it directly: name how coverage continues (pairing, documentation, swapping on-call windows) rather than letting the ask sound like a straight subtraction from the team's capacity.
Worked example
I wanted to protect a few hours a week for a structured certification relevant to where I wanted to grow, but I didn't just ask for the time. I brought my manager a specific ask: this many hours a week, for this many months, here's exactly what shrinks to make room for it, and here's how on-call coverage stays intact while I'm doing it. I framed it as a pilot with a checkpoint partway through: if my delivery velocity dropped noticeably, we'd pause and reassess rather than quietly abandoning either the study time or the delivery commitments. That framing made it an easy yes, because the cost was explicit and bounded instead of open-ended.
Trade-offs & pitfalls
- Asking for time without naming what shrinks to make room for it is the single biggest reason these requests get pushback.
- Treating a degree, a certification, an on-the-job rotation, and simply protected weekly hours as interchangeable asks misses that they carry very different costs and need different negotiations.
- Framing the investment purely as personal benefit rather than tying it to team or delivery value makes it harder to defend when priorities tighten.
- No checkpoint means no graceful way to pause if delivery genuinely suffers; always build in a reassessment point.
You observe several 'long tasks' (>50ms) on the main thread causing input jank in your SPA. Describe a step-by-step approach using Chrome DevTools to locate the root cause: how to record a performance trace, identify long tasks, inspect call stacks and JS execution time, correlate network/painting activity, and propose at least three strategies to reduce main-thread blocking in production.
Sample Answer
Approach overview
Short, reproducible DevTools trace + focused analysis to find JS heavy call stacks, then correlate with network/painting and apply targeted mitigations.
Record a performance trace
- Open Chrome DevTools → Performance.
- Check "Screenshots", enable "Memory" if needed. Set throttling to emulate target device (e.g., 4x CPU slowdown).
- Click Record, reproduce the interaction causing jank, Stop.
- Save trace for sharing.
Identify long tasks
- In the Performance panel’s Main thread flame chart, look for orange “Long Task” bars (>50 ms) and the Summary → "Main" -> "Self Time".
- Use the Experience Track (or Long Tasks track) to filter to only long tasks.
Inspect call stacks & JS execution
- Click a long task to expand the call stack at the bottom (Call Tree / Bottom-Up).
- Switch between "Call Tree" (logical order) and "Bottom-Up" (hot functions).
- Look for expensive functions: XHR/fetch handlers, framework reconciliation (React commit phase), heavy loops, large JSON.parse, synchronous layout/thrashing.
Correlate network / paint
- Inspect Network panel or Network section in the trace to see requests overlapping tasks.
- Use "Screenshots" and Paint/Composite layers in the trace to spot expensive style/layout/paint work.
- If long task follows a large script download/parse, focus on code-splitting. If paint-heavy, inspect expensive style recalc/layout calls.
Three+ strategies to reduce main-thread blocking
- Code-split & lazy-load: dynamic import routes/components; defer non-critical code so initial interactions avoid heavy parsing/compilation.
- Offload work: move CPU-heavy computation to Web Workers or WASM; use requestIdleCallback for non-urgent work.
- Break up long tasks: chunk loops with setTimeout/setImmediate/messageChannel or cooperative yielding (scheduler/yield points) to keep tasks <50ms.
- Reduce rendering cost: avoid layout trashing, use will-change carefully, virtualize long lists, minimize DOM nodes.
- Optimize third-party scripts: audit and defer/async or use placeholders.
Wrap-up
Iterate: reproduce after each change, re-record trace, verify long tasks removed and input latency improved.
Describe the children prop in React. When should a component accept and render props.children versus exposing a render prop or explicit slot props? Provide a concise example of a Card component that uses children and how a consumer would use it.
Sample Answer
Brief explanation
The children prop is React’s implicit way to pass nested JSX into a component. Use props.children for simple container components where consumers control markup inside (composition). Use render props or explicit slot props when the parent needs to supply specific regions or when the child needs data/callbacks from the component.
When to use which
- props.children: simple wrapper or layout (Card, Panel). Best when content is arbitrary and styling/structure is fixed.
- Render prop: when child needs component state or computed values (e.g., <DataLoader>{data => ...}</DataLoader>).
- Explicit slot props: when you want named regions (header, footer, actions) and clearer API.
Card example
// Card.jsx
export default function Card({ children, className = '' }) {
return (
<div className={`card ${className}`} role="group">
{children}
</div>
);
}
Consumer usage:
<Card>
<h3>Title</h3>
<p>Body content...</p>
<div className="actions"><button>OK</button></div>
</Card>
Notes
- For accessibility, preserve semantic elements inside children.
- If you need a structured API later, migrate to slot props: <Card header={} body={} footer={}>.
How would you evaluate, as a candidate, whether a company's published culture and values are actually practiced day to day rather than just marketing? What would you look for, and what would you ask during the interview process to find out?
Sample Answer
Direct answer
I treat a company's published culture and values as a claim to be tested, not a fact to accept, and I look for evidence in three places: how people describe real, specific incidents (not slogans) when I ask about them, whether the org's actual structures and incentives would make the stated behavior easy or hard to practice, and whether the story is consistent across different people I talk to in the process.
Structured elaboration
- Ask for a specific recent incident, not a description of the value. A question like "tell me about a time the team had to choose between shipping fast and following the documented review process" forces a real story; a question like "how would you describe the engineering culture here" invites a rehearsed, values-page-adjacent answer that tells you little.
- Check whether the org's structure actually supports the stated value, independent of what anyone says. If a company claims to value psychological safety but every interviewer you meet is visibly guarded about naming any team problem, or if a company claims strong autonomy but every technical decision in the loop turns out to require a director's sign-off, the structural evidence contradicts the claim regardless of the wording used to describe it.
- Triangulate across multiple people, ideally at different levels and tenures. A single enthusiastic interviewer proves little; a hiring manager, a peer-level engineer, and someone from a different function independently describing the same specific behavior (not the same slogan) is much stronger evidence.
- Ask what the company would do differently if it stopped believing the value, and watch for a concrete, structural answer versus a vague one. People who work inside a genuinely lived value can usually name a real trade-off it costs them; people describing marketing usually cannot.
- Treat your own discomfort as data. If a described norm (pace, feedback directness, decision-making style) makes you visibly uneasy during the process itself, that is a more reliable signal about fit than anything printed on the careers page, because it is your own live reaction rather than a claim you are being asked to evaluate secondhand.
Worked example
Suppose a company's careers page says it "empowers engineers with high autonomy." During the loop, ask the hiring manager for a specific recent example: "Tell me about the last time an engineer on this team made a production architecture decision without it going through a review committee first." A genuine, lived-autonomy answer sounds like: "Last quarter one of our engineers decided independently to switch a service from synchronous to async processing after noticing latency complaints; she looped in two people for a sanity check, shipped it, and reported the outcome in the next team sync." A marketing-only answer sounds like: "We really believe in empowering our engineers," repeated with no specific incident when pressed twice. If a peer engineer you speak to separately can also describe a comparable specific incident in their own words, that consistency is strong corroborating evidence; if the hiring manager's story turns out to be the ONLY example anyone can produce company-wide, that is itself informative about how common the behavior actually is.
Trade-offs & pitfalls
The main failure mode is accepting an interviewer's fluent, confident description of the culture as sufficient evidence on its own; confidence and specificity are not the same thing, and a well-rehearsed answer to a values-page question is exactly what a company under-delivering on its stated culture is most likely to have prepared. A second pitfall is over-weighting a single glowing anecdote from one enthusiastic interviewer without checking whether it generalizes; one great story is an anecdote, not a pattern. A third is treating any inconsistency you find as automatically disqualifying: it is normal for a large or growing organization to have real variance across teams, so the useful conclusion is usually about the SPECIFIC team and manager you'd actually join, not the company as a monolithic whole.
You're about to ship a significant change to a product used by a large, diverse user base (a UI redesign, a new ranking algorithm, a new model), the kind of change where a bad rollout could hurt real users at scale. Propose your rollout approach: how you'd stage it (for example, a small initial cohort, a canary, or gradual expansion), what you'd monitor to decide whether to keep expanding, your rollback criteria, and how you'd communicate the rollout to stakeholders.
Sample Answer
Direct answer
Propose a staged expansion built around one explicit decision rule: define, before the first user sees the change, exactly what "keep expanding" and "roll back" mean numerically. Expand only when the data clears that bar, starting from a cohort small enough (a canary slice) that a bad outcome is cheap to reverse. Staging beats a full launch here specifically because a large, diverse user base can hide a bad outcome for one segment inside a fine-looking average.
Structured elaboration
- Why staged: the average result can look fine while a specific segment is having a bad time; starting narrow surfaces segment-level effects before they're everyone's problem.
- Stage 1: 1-2% of users, broadly representative rather than just power users, run long enough for a stable read past any novelty effect (users reacting to a change simply because it's new, not because it's actually better, which can make early numbers look inflated).
- Stage 2, only if Stage 1 clears the bar: a meaningfully larger slice, roughly 10-20%, to catch effects that only show up at higher concurrency.
- Full rollout: only after Stage 2 holds; consider a small permanent holdout (a subset of users deliberately kept on the old version, so you always have a live comparison group) afterward to keep measuring true causal impact.
- What to monitor: the primary metric the change should improve, plus at least one guardrail (latency, error rate, a specific segment's experience) that could regress while the primary looks fine.
- Rollback criteria: a numeric trigger per guardrail, set before launch, so rollback is automatic, not a judgment call made under pressure.
- Stakeholder communication: a short update to stakeholders before each expansion on what the current stage showed, and if you roll back, communicate that fast and factually.
Worked example
A new ranking algorithm replaces the current one. Stage 1: 2% of users for 2 weeks, past the novelty bump that typically fades within days. Primary metric: click-through on the top 3 results. Guardrails: page load latency and complaint-ticket rate. Rollback trigger: complaints rising more than 25% above control, or latency up more than 100ms. At 2 weeks: click-through up 6%, latency unchanged, complaints up only 4%, well under the trigger, so you expand to 15% for 2 more weeks. Stage 2 holds the same gain with clean guardrails, so you proceed to full rollout, keeping a 1% holdout for one more month to confirm the gain persists once the algorithm is no longer new.
Trade-offs and pitfalls
A cohort so small or short you never get a stable read, declaring success on a 3-day, 0.1% sample, produces false confidence. Watching only the metric you want to improve and missing a guardrail regression is the other common failure. Treating the rollback bar as negotiable once you're invested in the launch undoes the point of setting it in advance.
Given the head of a singly linked list, determine whether it contains a cycle, and if so, return the node where the cycle begins, using O(1) extra space (no visited-set). Explain why moving one pointer twice as fast as the other guarantees they meet if and only if a cycle exists, and how that same meeting point lets you locate the cycle's start.
Sample Answer
Direct answer
Advance one pointer (slow) one step at a time and another (fast) two steps at a time. If the list has no cycle, fast reaches the end first and you can report there is none. If it does have a cycle, fast eventually laps slow and the two meet somewhere inside it. Once they meet, restarting one pointer at the head and advancing both pointers one step at a time makes them meet again exactly at the cycle's start. All of this uses O(1) extra space, no visited set required.
Structured elaboration
Why meeting implies a cycle, and why no meeting implies no cycle. With no cycle, fast strictly gains ground toward a null terminator every step and reaches it in at most n/2 steps; it can never occupy the same node as slow without a cycle to loop back through. Once both pointers are inside a cycle, fast closes the gap to slow by exactly one node per step, because fast gains two steps of distance while slow gains one, a net closing rate of one per step. Since the gap can never exceed the cycle's length, they are guaranteed to meet within one full lap of the cycle.
Why the meeting point locates the cycle's start. Let a be the distance from the head to the cycle's start, c be the cycle's length, and b be the distance from the cycle's start to the meeting point, with 0≤b<c. By the time they meet, slow has traveled a + b steps and fast has traveled exactly twice that, but fast has also gone around the cycle some whole number of extra laps n≥1:
So a and (c - b) differ by a whole number of cycle lengths, meaning a pointer walking one step at a time from the head, and a pointer walking one step at a time from the meeting point, land on the same node after exactly a steps: the cycle's start.
Related applications of the same fast/slow pattern. Removing the n-th node from the end of a list uses the same shape without any cycle involved: advance one pointer n steps first, then move both pointers together; when the front pointer reaches the end, the trailing pointer sits exactly at the node to remove. Finding a duplicate number hidden in an array reframes the array itself as an implicit linked list, where the value stored at each index tells you which index to visit next; a repeated value forces two different positions to point at the same next index, creating a cycle in that implicit list, which Floyd's tortoise-and-hare detects exactly the way it detects a cycle here.
Worked example
class Node:
def __init__(self, val, next=None):
self.val = val
self.next = next
def detect_cycle_start(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow is fast:
ptr = head
while ptr is not slow:
ptr = ptr.next
slow = slow.next
return ptr
return None
if __name__ == "__main__":
nodes = [Node(i) for i in range(5)] # values 0,1,2,3,4
for i in range(4):
nodes[i].next = nodes[i + 1]
nodes[4].next = nodes[2] # cycle back into node with value 2
start = detect_cycle_start(nodes[0])
print(start.val)
Running this prints 2. In the derivation's terms: a = 2 (two steps from the head, value 0, to the cycle's start, value 2), c = 3 (the cycle 2 to 3 to 4 back to 2 has three edges), and the two pointers first meet at the node with value 3, so b = 1 (one step from the cycle's start to that meeting point). Checking the identity: c - b = 3 - 1 = 2, which equals a, confirming the derivation against this concrete run.
Complexity
Time: O(n). The pointers meet within one full lap of the cycle once both are inside it, and finding the cycle's start afterward takes at most another full lap; both phases are bounded by a constant multiple of the list's length n.
Space: O(1), since only the slow and fast pointers (and later ptr) are held, with no visited set.
Edge cases
- Empty list (
headisNone):fastisNoneimmediately, so the loop never runs and the function correctly returns no cycle. - Single node with no self-link:
fast.nextisNoneon the first check, so the loop exits immediately with no cycle detected. - Single node that cycles to itself:
slowandfastboth land back on that same node on the first iteration, correctly reporting it as the cycle's start.
Trade-offs & pitfalls
A common bug is comparing pointer values instead of pointer identity; when list values can repeat, slow.val == fast.val can be true without slow and fast being the same node, so the check must be slow is fast.
Find and fix the bug in this JavaScript async function, where a missing await causes unpredictable ordering and errors:
async function processItems(items, processor) {
items.forEach(async item => {
await processor(item);
});
console.log('done');
}
Explain the root cause and provide a corrected version that guarantees 'done' prints only after every item has been processed.
Sample Answer
Direct answer
Array.prototype.forEach does not await its callback: it fires each async callback and moves on immediately, so console.log('done') runs before any of the await processor(item) calls have resolved. The fix is to replace forEach with a construct that actually waits, either a for...of loop with await inside it (sequential) or Promise.all over items.map(...) (concurrent).
Structured elaboration
forEach was designed before async/await existed and its callback's return value, including a Promise, is simply discarded. Passing an async function as the callback doesn't change this: each invocation still returns a Promise that forEach never looks at, so forEach itself completes synchronously (having merely started every item, not finished any of them) the instant it has called the callback once per array element. The console.log('done') line after the forEach call then runs immediately, while the async work is still in flight in the background.
Worked example
async function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
// Fixed, distinct per-item delays (not Math.random()) so the interleaving below
// is deterministic and reproduces identically on every run, not just illustrative.
const delays = { 1: 20, 2: 10, 3: 30 };
// BUGGY
async function processItemBuggy(x) { await sleep(delays[x]); console.log(' processed', x, '(buggy)'); }
async function processBuggy(items) {
items.forEach(async item => { await processItemBuggy(item); });
console.log('done (buggy)');
}
// FIXED: sequential
async function processItemFixed(x) { await sleep(delays[x]); console.log(' processed', x, '(fixed)'); }
async function processFixed(items) {
for (const item of items) { await processItemFixed(item); }
console.log('done (fixed)');
}
(async () => {
console.log('--- buggy run ---');
await processBuggy([1, 2, 3]);
await sleep(100); // let the buggy run's background work finish before the next section starts
console.log('--- fixed run (sequential for-of) ---');
await processFixed([1, 2, 3]);
})();
Executed output (buggy items finish asynchronously in the background; with the fixed per-item delays above, item 2 always resolves first, then item 1, then item 3, after done has already printed):
--- buggy run ---
done (buggy)
processed 2 (buggy)
processed 1 (buggy)
processed 3 (buggy)
--- fixed run (sequential for-of) ---
processed 1 (fixed)
processed 2 (fixed)
processed 3 (fixed)
done (fixed)
done (buggy) prints immediately, before any processed line: forEach fired all three async callbacks and moved on without waiting for any of them. The processed (buggy) lines do eventually print, once their fixed delays resolve, in delay order (2, then 1, then 3, not the input order), rather than before done. The for...of version correctly prints all three processed lines, strictly in input order, before done.
Trade-offs and pitfalls
There are two valid fixes with different semantics, and picking the wrong one is itself a common mistake: a for...of loop processes items strictly one at a time (useful when order matters or you must not overwhelm a downstream dependency with concurrent calls), while await Promise.all(items.map(item => processor(item))) processes all items concurrently and finishes as soon as the slowest one does (faster, but only safe if the operations are independent and the downstream system can handle concurrent load). Silently reaching for forEach out of habit, rather than deliberately choosing sequential versus concurrent semantics, is exactly how this bug class gets reintroduced even by developers who already know the rule.
Recommended Additional Resources
- LeetCode (https://leetcode.com/) - Medium level JavaScript problems and UI component challenges
- GreatFrontEnd (https://www.greatfrontend.com/) - Comprehensive frontend interview prep with curated problems
- System Design Primer (https://github.com/donnemartin/system-design-primer) - Adapted for frontend architecture thinking
- Frontend Interview Handbook (https://www.frontendinterviewhandbook.com/) - Comprehensive guide specific to frontend roles
- Cracking the Coding Interview (Book by Gayle Laakmann McDowell) - Classic reference with applicable JavaScript examples
- MDN Web Docs (https://developer.mozilla.org/) - Authoritative resource for JavaScript, CSS, HTML, and APIs
- React Documentation (https://react.dev/) - Official React docs with deep dives into hooks and performance
- Web.dev (https://web.dev/) - Google's resource for modern web development and performance optimization
- JavaScript.info (https://javascript.info/) - Comprehensive JavaScript tutorial and reference
- CSS Tricks (https://css-tricks.com/) - Practical CSS knowledge and best practices
- Performance Auditing with Chrome DevTools (practice using Lighthouse, Performance tab for optimization analysis)
- WCAG 2.1 Guidelines (https://www.w3.org/WAI/WCAG21/quickref/) - Accessibility standards
- Frontend Masters courses - Advanced JavaScript, React performance, system design for frontend
Search Results
34 Front-End Interview Questions (With Sample Answers) - Indeed
What projects have you designed front-end for? · Which of your previous front-end projects would you say you're most proud of? · Have you had any experience in ...
Top 35+ UI Developer Interview Questions and Answers for 2026
Basic UI Developer Interview Questions · 1. What exactly is the role of a UI developer? · 2. What's the difference between a UI developer and a UX developer? · 3.
Introduction | The Official Front End Interview Handbook 2025
Complete frontend developer interview guide: JavaScript coding questions, UI components, system design, quiz prep & expert tips from ex FAANG engineers.
Top Frontend Developer Interview Questions and Answers - Intellipaat
1. Define HTML. How does front-end development employ it? Simply put, Hypertext Markup Language (HTML) is a markup language that is utilized for creating web ...
React JS Interview Questions ( Multi Step Form ) - YouTube
React JS Interview Questions ( Multi Step Form ) - Frontend Machine Coding Interview ... Frontend Interview Questions Mid/Senior Level. theSeniorDev•143K views.
50+ Essential Vue Interview Questions & Answers (Easy to Advanced)
Use this list of Vue interview questions and answers to prepare for your upcoming meeting with a tech recruiter or lead front-end engineer!
Crack Any Frontend Interview: Ultimate Prep Guide - YouTube
... interview questions UI developer infosys react developer infosys frontend developer infosys UI developer. ... Frontend Interview Questions Mid/Senior Level.
This interview preparation guide was generated using AI-powered research from the sources listed above. While we strive for accuracy, we recommend verifying critical information from official company sources.
Want to create your own tailored preparation guide using our deep research?
Get Started for FreeInterview-Ready Courses
Visual-first, interactive, structured learning paths
Browse Frontend Developer jobs
AI-enriched listings across hundreds of company career pages
Explore Jobs