Frontend Questions
Frontend Questions
10. What are data attributes in HTML, and when would you use them?
Data attributes allow you to store custom data directly in HTML elements using the data-* format.
Example: <div data-user-id="12345">Username</div>
When to use them:
• Custom Data Storage: When you need to store small amounts of data that JavaScript can
access and manipulate (e.g., storing a user’s ID or additional information).
• JavaScript Interaction: When you want to easily access this data in your JavaScript code
without making an API call or creating a new variable.
3. How do CSS selectors work? Can you give examples of different types of selectors?
CSS selectors target HTML elements to apply styles to them. There are different types:
• Element selector: Targets all elements of a specific type, e.g., p { color: blue; } (applies to all
<p> elements).
• Class selector: Targets elements with a specific class, e.g., .button { background: red; }.
• ID selector: Targets an element with a specific ID, e.g., #header { font-size: 20px; }.
• Attribute selector: Targets elements with a specific attribute, e.g., a[href] { color: green; }.
• Pseudo-class selector: Targets elements in a specific state, e.g., a:hover { color: red; }.
5. Explain how flexbox works in CSS. What are some use cases?
Flexbox is a layout model that allows items within a container to be aligned and distributed flexibly.
Key features:
• Flexible layout: Items can grow, shrink, and wrap automatically based on available space.
• Alignment: You can easily align items horizontally (justify-content) and vertically (align-items).
• Direction: Use flex-direction to set the direction of items (row or column).
Use cases: Centering items, creating responsive layouts, aligning navigation bars, and distributing
space evenly between elements.
12. Explain the concept of media queries in CSS and how they are used for responsiveness.
Media queries allow you to apply CSS rules only when certain conditions are met, such as screen size,
orientation, or resolution.
Example:
@media (max-width: 768px) {
body {
font-size: 14px;
}
}
In this example, the font size will only change if the screen width is 768px or less. This is how websites
adjust their layout to different devices (desktop, tablet, mobile).
3. What are arrow functions in JavaScript, and how are they different from regular functions?
Arrow functions are a shorter syntax for writing functions:
const add = (a, b) => a + b;
Differences from regular functions:
• Arrow functions don’t have their own this value; they inherit it from their surrounding context.
• They cannot be used as constructors and don’t have a prototype property.
4. Explain how closures work in JavaScript. Can you provide an example?
A closure is a function that remembers and can access variables from its outer scope, even after the
outer function has finished executing.
Example:
function outer() {
let count = 0;
return function inner() {
count++;
console.log(count);
}
}
const counter = outer();
counter(); // 1
counter(); // 2
Here, inner is a closure that remembers the count variable from outer.
7. How does JavaScript handle asynchronous operations? What is the difference between callback,
promise, and async/await?
JavaScript uses asynchronous operations for tasks like API calls or timers without blocking the main
thread.
• Callback: A function passed as an argument to another function, which is executed after an
asynchronous task.
o Example: setTimeout(() => console.log('Hello'), 1000);
• Promise: An object representing a future value, either resolved (success) or rejected (failure).
o Example:
let promise = new Promise((resolve, reject) => {
resolve('Success!');
});
promise.then(result => console.log(result));
• Async/Await: Syntactic sugar over promises, making asynchronous code look like synchronous
code.
o Example:
async function fetchData() {
let data = await fetch('url');
console.log(data);
}
10. What is a prototype in JavaScript? How does inheritance work using prototypes?
Every JavaScript object has a prototype, which is another object from which it inherits properties and
methods.
Inheritance using prototypes works by linking an object to another object (the prototype). When you
access a property or method on an object, JavaScript first checks the object itself. If it doesn't find the
property, it checks the object's prototype.
13. How do you handle errors in JavaScript? What are try, catch, and finally blocks?
Errors in JavaScript can be handled using the try...catch...finally blocks:
• try: Code that may throw an error is placed inside this block.
• catch: This block handles any error that occurs in the try block.
• finally: This block executes regardless of whether an error occurred or not.
Example:
try {
// Code that might throw an error
} catch (error) {
console.log(error.message); // Handle the error
} finally {
console.log('This always runs');
}
14. What is the difference between synchronous and asynchronous programming in JavaScript?
• Synchronous: Code runs sequentially, one task after another. Each task waits for the previous
one to finish before executing.
o Example: Console logs executed one after another.
• Asynchronous: Code allows multiple tasks to be processed at the same time, without waiting
for others to complete. Commonly used for tasks like network requests or file reading.
o Example: Using setTimeout, promises, or async/await for non-blocking operations.
15. How do you create and manipulate arrays and objects in JavaScript?
• Creating arrays:
let arr = [1, 2, 3];
• Manipulating arrays:
o Add: arr.push(4); (adds to the end)
o Remove: arr.pop(); (removes the last element)
o Iterate: arr.forEach(item => console.log(item));
• Creating objects:
let obj = { name: "John", age: 30 };
• Manipulating objects:
o Access: obj.name or obj['name']
o Add/update: obj.gender = "male";
o Delete: delete obj.age;
3. What are React components? How are functional components different from class components?
• React components are building blocks of a React application that represent parts of the user
interface.
• Functional components are simple JavaScript functions that return JSX. They don’t have state
or lifecycle methods unless you use React hooks.
• Class components are ES6 classes that extend React.Component and can have state and
lifecycle methods. Class components are now less common with the introduction of hooks.
5. What are props in React? How are they different from state?
• Props are inputs passed to a component from its parent, making components reusable. They
are read-only and cannot be changed by the component itself.
• State is an internal object managed by the component itself. It is mutable and can be changed
using setState or useState.
8. What are React hooks? Can you explain useState and useEffect hooks with examples?
Hooks are functions that let you use state and other React features in functional components.
• useState: Manages state in functional components.
const [count, setCount] = useState(0);
• useEffect: Runs side effects in functional components (e.g., fetching data or updating the
DOM).
useEffect(() => {
console.log('Component mounted or updated');
}, [count]); // Runs when 'count' changes
10. What is React Router, and how do you implement routing in a React application?
React Router is a library for handling navigation in React applications. It allows you to switch between
different views (pages) without refreshing the browser.
Example:
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
<Router>
<Switch>
<Route path="/home" component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
11. How do you handle forms in React? What are some best practices?
Forms in React can be handled using controlled components. You update state on every input change
and submit the form by handling the onSubmit event.
Best practices:
• Keep form state local to the component.
• Validate input data before submission.
• Use libraries like Formik for larger forms.
14. What is prop drilling, and how can you avoid it?
Prop drilling occurs when you pass props through multiple layers like Redux.
15. Explain how React's useMemo and useCallback hooks help in performance optimization.
• useMemo: Memoizes the result of a function, only recalculating when dependencies change.
It optimizes expensive calculations.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
• useCallback: Memoizes a function, preventing it from being recreated on every render. It’s
useful for passing stable functions to child components.
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);
19. What is lazy loading in React, and how do you implement it?
Lazy loading is a technique that delays loading components or resources until they are needed. In
React, you can use React.lazy and Suspense to load components lazily.
Example:
const LazyComponent = React.lazy(() => import('./LazyComponent'));
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
20. How do you handle side effects in React? Explain how to use useEffect for handling side effects.
Side effects include actions like data fetching, subscriptions, or manually updating the DOM. In React,
you handle side effects using the useEffect hook.
Example:
useEffect(() => {
fetchData();
}, []); // Empty array means it runs only once (on mount)
useEffect runs after every render unless you specify dependencies.
2. Explain how REST APIs work and how you would interact with them using React and JavaScript.
• REST API (Representational State Transfer API) is a way for two systems (client and server) to
communicate over HTTP using standard methods like:
o GET: Retrieve data
o POST: Send new data
o PUT/PATCH: Update existing data
o DELETE: Remove data
A REST API usually responds with JSON data, which can be consumed by frontend applications.
• In React, you can interact with REST APIs using fetch() or libraries like Axios.
Example with fetch():
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data))
.catch(error => console.error('Error fetching data:', error));
}, []);
Example with Axios:
import axios from 'axios';
useEffect(() => {
axios.get('https://api.example.com/data')
.then(response => setData(response.data))
.catch(error => console.error('Error fetching data:', error));
}, []);
Both methods make a request to the API, receive a response (usually in JSON format), and update the
state with the fetched data.
4. How do you manage asynchronous data fetching in React? How would you use fetch() or libraries
like Axios?
To manage asynchronous data fetching in React, you typically use useEffect to perform side effects
like API calls. You can either use the built-in fetch() function or a third-party library like Axios.
Using fetch():
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
setData(data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
fetchData();
}, []);
• The fetch() function returns a Promise, and await is used to wait for the response.
• You convert the response into JSON using response.json().
Using Axios:
import axios from 'axios';
useEffect(() => {
const fetchData = async () => {
try {
const result = await axios.get('https://api.example.com/data');
setData(result.data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
fetchData();
}, []);
• Axios is simpler to use because it automatically handles JSON parsing and has better error
handling than fetch().
For both approaches, you should handle errors properly (using try-catch) and manage loading states
to give users a good experience while data is being fetched.
Example:
const worker = new Worker('worker.js'); // Initialize web worker
worker.postMessage('Start Task'); // Send task to worker
4. What are CORS, and how do you handle CORS issues in frontend development?
CORS (Cross-Origin Resource Sharing) is a security feature implemented by browsers to control how
web pages from one domain interact with resources from another domain. It prevents malicious
scripts from making requests to different domains than the one that served the web page.
When a request is made from a frontend to a backend on a different domain, the server must include
proper CORS headers (like Access-Control-Allow-Origin) to allow the request.
Handling CORS issues:
• Server-side solution: Configure the backend server to include the correct Access-Control-
Allow-Origin header, allowing cross-origin requests from trusted sources.
• Proxy: You can use a proxy (either in development or production) to bypass CORS issues by
making requests to the proxy instead of directly to the server.
5. How do you secure a web application from common vulnerabilities like XSS and CSRF?
Securing a web application from vulnerabilities like XSS (Cross-Site Scripting) and CSRF (Cross-Site
Request Forgery) involves several practices:
• XSS protection:
o Sanitize inputs: Always sanitize and escape user inputs before rendering them on the
page to avoid injecting malicious scripts.
o Content Security Policy (CSP): Use CSP headers to control which sources of scripts are
allowed to execute.
o Use HTTPS: Secure communication with the server to prevent man-in-the-middle
attacks.
• CSRF protection:
o Use anti-CSRF tokens: Include tokens in forms and verify them on the server side to
ensure the request is legitimate.
o SameSite cookies: Set cookies with the SameSite attribute to prevent them from being
sent along with cross-site requests.
6. What is Progressive Web App (PWA), and how do you create one?
A Progressive Web App (PWA) is a web application that combines the best features of web and mobile
apps. PWAs can be installed on a user's device and work offline, offering a native-like experience.
Key features of PWAs:
• Service Workers: These are background scripts that enable offline functionality and caching.
• Web App Manifest: A JSON file that provides metadata about the app, such as the app's name,
icons, and theme color.
• Responsive design: PWAs work on any device, regardless of screen size.
lazyImages.forEach((image) => {
image.src = image.dataset.src;
image.classList.remove("lazy");
});
});
Lazy loading in React (React Suspense):
const LazyComponent = React.lazy(() => import('./MyComponent'));
function App() {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</React.Suspense>
);
}
This ensures that certain resources are only loaded when needed, reducing the time it takes for the
main content to appear and improving user experience.
Problem-Solving/Logical Questions
1. How would you improve the page load speed of a web application?
Improving page load speed is critical for a good user experience. Here are some ways to optimize it:
• Minimize HTTP requests: Reduce the number of elements loaded by the page (e.g., combining
files, using CSS sprites).
• Use lazy loading: Load images, videos, and components only when they are needed (e.g.,
when they appear in the viewport).
• Optimize images: Use efficient image formats like WebP, compress images, and serve
responsive images.
• Minify and compress files: Minify CSS, JavaScript, and HTML files, and use gzip or Brotli
compression to reduce their size.
• Implement caching: Use browser caching and server-side caching (CDN) to store static
resources.
• Code splitting: In React, split the code into smaller chunks and load them dynamically to avoid
loading unnecessary code all at once.
• Use a CDN: Content Delivery Networks distribute resources across different servers
worldwide, reducing latency.
• Preload critical resources: Preload key CSS and JavaScript files to prioritize their loading.
2. Explain a challenging bug you encountered in a project and how you resolved it.
Example bug: In one of my React projects, I encountered a bug where the UI wasn’t updating correctly
after fetching new data from an API. Despite successfully receiving data from the API, the component
state was not reflecting the changes.
Resolution:
1. Diagnosis: After thorough debugging, I realized that the state update was asynchronous, and
the component was trying to render before the state was fully updated.
2. Solution: I used the useEffect hook with the API call and ensured that the state update
occurred correctly within it. I also used the setState callback function to make sure that the UI
rendered only after the state was updated.
useEffect(() => {
async function fetchData() {
const response = await fetch("api-endpoint");
const data = await response.json();
setData(data);
}
fetchData();
}, []); // Empty array ensures the effect runs only once.
This fixed the issue and allowed the UI to correctly reflect the fetched data.
2. What is unit testing, and how would you apply it in a React project?
Unit testing is a type of software testing where individual units or components of a software
application are tested in isolation. In React, unit tests verify the correctness of components, functions,
or methods.
To apply unit testing in a React project:
• Testing framework: Use frameworks like Jest or Mocha to write test cases.
• Testing library: Use React Testing Library to simulate user interactions and assert component
behavior.
• Example of a test:
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';
3. What is the difference between shallow and deep rendering in testing React components?
• Shallow rendering:
o In shallow rendering, only the component being tested is rendered, and its child
components are not rendered.
o It is useful when you want to test a component’s logic and output without testing the
behavior of its children.
o Example: With Enzyme (a testing utility), shallow rendering can be done using
shallow().
import { shallow } from 'enzyme';
const wrapper = shallow(<MyComponent />);
expect(wrapper.find('h1').text()).toBe('Hello World');
• Deep rendering (Full rendering):
o Deep rendering, also called full rendering, renders the component and all of its
children recursively.
o This is used when you need to test the integration of components and how they work
together.
o Example: Using mount() in Enzyme allows for deep rendering.
import { mount } from 'enzyme';
const wrapper = mount(<MyComponent />);
expect(wrapper.find('ChildComponent').length).toBe(1);
• When to use:
o Use shallow rendering for unit tests when you only want to test a component in
isolation.
o Use deep rendering for integration tests when you need to test the interaction
between a component and its children.