This guide covers common frontend interview questions, frequently asked topics, and technical concepts that appear in technical interviews. The content is organized by technology area and includes practical examples where applicable.
HTML Fundamentals
1. What is the purpose of semantic HTML?
Semantic HTML means using the correct HTML elements for their intended purpose. It improves code readability, structures content logically, enhances accessibility, and benefits SEO by providing clear context to browsers and search engines.
2. Key Features of HTML5
- Cenvas and SVG for graphics
- Drag and Drop API
- Semantic elements (header, nav, footer, article, section)
- Audio and Video elements
- Geolocation API
- Local storage mechanisms (localStorage, sessionStorage)
- Enhanced form inputs (date, time, email, url, search)
- Web Workers for multi-threading
- WebSocket for full-duplex communication
- History API for navigation management
- PostMessage for cross-window communication
- FormData API
3. Differences Between Cookies, sessionStorage, and localStorage
| Feature | Cookie | sessionStorage | localStorage |
|---|---|---|---|
| Storage Capacity | ~4KB | 5-10MB | 5-10MB |
| Lifetime | Configurable (session by default) | Until tab/browser closes | Persistent until manually cleared |
| HTTP Requests | Automatically included with requests | Not sent automatically | Not sent automatically |
| Access Scope | All windows under same origin | Current tab only | All windows under same origin |
| API Ease of Use | String-based (manual parsing needed) | Key-value pairs | Key-value pairs |
| Security | Supports Secure/HttpOnly flags | No special security mechanisms | No special security mechanisms |
Cookies are primarily used for user authentication, localStorage for cross-page data sharing, and sessionStorage for temporary data within a session.
CSS Fundamentals
1. CSS Selectors and Specificity
Basic Selectors
- Element Selector: Targets all HTML elements of a specific type. ```
p { color: blue; }
- Class Selector: Targets elements with a specific class. ```
.highlight { color: red; }
- ID Selector: Targets a single element with a specific ID. ```
#main-title { color: green; }
Combinator Selectors
- Descendant Selector: Targets elements that are descendants of another element. ```
div p { color: yellow; }
- Child Selector: Targets direct children of an element. ```
ul > li { color: green; }
- Adjacent Sibling Selector: Targets an element immediately following another. ```
h1 + p { color: red; }
- General Sibling Selector: Targets elements that are siblings of another element. ```
h1 ~ p { color: yellow; }
Attribute Selectors
- Presence of Attribute: Targets elements with a specific attribute. ```
[type="text"] { border: 1px solid black; }
- Attribute Value Matching: Targets elements with attribute values matching a pattern. ```
[href^="https"] { color: orange; }
Pseudo-classes
- State Pseudo-classes: Target elements in specific states (hover, active, focus, visited, etc.) ```
a:hover { color: red; }
- Structural Pseudo-classes: Target elements based on their position in the document tree (first-child, last-child, nth-child, etc.) ```
ul li:first-child { color: red; }
Pseudo-elements
- ::before and ::after: Insert content before or after an element's content. ```
p::before { content: "Note: "; color: red; }
CSS Specificity Rules
The order of CSS specificity from highest to lowest:
- !important declarations
- Inline styles (style attribute)
- ID selectors
- Class selectors, attribute selectors, and pseudo-classes
- Type selectors and pseudo-elements
- Universal selector (*)
When multiple rules have the same specificity, the one defined later in the stylesheet takes precedence.
2. CSS Box Model
The CSS box model consists of four components:
- Content: The actual content of the box
- Padding: Space around the content
- Border: The border around the padding
- Margin: Space outside the border
There are two box model typees:
- Content-box (default): Width and height include only the content area. ```
/* Total width = width + padding + border + margin */
.box {
width: 200px;
padding: 20px;
border: 2px solid red;
margin: 10px;
}
- Border-box: Width and height include content, padding, and border. ```
/* Total width = width + margin */
.box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 2px solid red;
margin: 10px;
}
3. CSS Units
- Absolute units: px (pixels)
- Relative to parent element: % (percentage)
- Relative to parent font size: em
- Relative to root font size: rem
- Viewport-relative units: vw (viewport width), vh (viewport height)
- Grid layout units: fr (fractional units)
4. Display: none vs. Visibility: hidden
| display: none | visibility: hidden |
|---|---|
| Completely removes element from layout | Preserves element's space in layout |
| Element is removed from document flow | Element remains in document flow |
| All child elements are hidden | Child elements can be made visible |
| No transition support | Supports transitions |
| Triggers reflow | Triggers repaint |
5. CSS Layout Techniques
Creating a Square with Half Viewport Dimensions
/* Using percentage padding */
.square {
width: 50%;
padding-top: 50%;
background-color: blue;
}
/* Using viewport units */
.square {
width: 50vw;
height: 50vh;
background-color: blue;
}
Creating a 0.5px Line
.thin-line {
position: relative;
}
.thin-line::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 1px;
background: #ddd;
transform: scaleY(0.5);
transform-origin: 0 0;
}
/* Android optimization */
@media (-webkit-device-pixel-ratio: 1.5) {
.thin-line::after {
transform: scaleY(0.7);
}
}
Creating CSS Triangles
/* Upward triangle */
.triangle-up {
width: 0;
height: 0;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-bottom: 30px solid red;
}
6. Clearing Floats
-
Clearfix Method (recommended): ``` .clearfix::after { content: ""; display: block; clear: both; }
.parent { overflow: hidden; }
-
Empty Div Method: ``` .parent { overflow: hidden; }
JavaScript Fundamentals
1. ES6+ Features
- Block-scoped variables with let and const
- Destructuring assignment
- Template literals with ${}
- Default parameters
- Arrow functions (=>)
- Spread operator (...)
- Modules (import/export)
- Classes and inheritance
- Promises
- Proxy objects
- Set and Map data structures
- Optional chaining (?.) and nullish coalescing (??)
2. ES7 and ES8 Features
ES7
- Array.prototype.includes()
- Exponentiation operator (**)
ES8
- Async/await syntax
- New Object methods (entries, values, etc.)
3. Closures
A closure is a function that has access to variables in its outer (enclosing) function's scope even after the outer function has returned. Closures are used to create private variables and methods.
Characteristics:
- Function nested within another function
- Can access variables from the outer function
- Variables are not garbage collected as long as the closure exists
Use cases:
- Debouncing and throttling
- Encapsulation and private variables
- Higher-order functions
- Caching mechanisms
4. JavaScript Data Types
Primitive Types
- Number: Numeric values (integer and floating-point)
- String: Textual data
- Boolean: Logical values (true/false)
- Undefined: Variable declared but not assigned
- Null: Intentional absence of value
- Symbol: Unique identifiers (ES6)
- BigInt: Arbitrary-precision integers (ES11)
Reference Types
- Object: Includes Array, Function, Date, Error, etc.
5. Prototypes and Prototype Chain
Prototypes allow JavaScript objects to inherit properties and methods from other objects. Each JavaScript object has a prototype property, which is an object that contains shared properties and methods.
The prototype chain is the mechanism by which JavaScript objects inherit features from one another. When you try to access a property on an object, JavaScript will look for that property on the object itself, and if not found, it will look at the object's prototype, then the prototype's prototype, and so on.
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
console.log(`Hello, my name is ${this.name}`);
};
const person = new Person('Alice');
console.log(person.__proto__ === Person.prototype); // true
console.log(Person.prototype.constructor === Person); // true
6. Call, Apply, and Bind
These methods are used to control the this context in functions:
-
call(): Invokes a function with a given this value and arguments provided individually. ``` function greet(greeting, punctuation) { console.log(
${greeting}, ${this.name}${punctuation}); }const person = { name: 'Alice' }; greet.call(person, 'Hello', '!'); // "Hello, Alice!"
-
apply(): Invokes a function with a given this value and arguments provided as an array. ``` greet.apply(person, ['Hi', '.']); // "Hi, Alice."
-
bind(): Creates a new function that, when called, has its this keyword set to the provided value. ``` const greetPerson = greet.bind(person); greetPerson('Hey', '?'); // "Hey, Alice?"
7. Promises
Promises represent the eventual completion (or failure) of an asynchronous operation and its resulting value. A Promise is in one of these states:
- pending: initial state, not fulfilled or rejected
- fulfilled: operation completed successfully
- rejected: operation failed
const fetchData = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve({ data: 'Sample data' });
} else {
reject(new Error('Failed to fetch data'));
}
}, 1000);
});
fetchData
.then(response => console.log(response.data))
.catch(error => console.error(error.message));
8. Async/Await
Async/await is syntactic sugar built on top of promises, making asynchronous code look more like synchronous code.
async function getUserData() {
try {
const response = await fetch('https://api.example.com/user');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
getUserData();
9. Event Loop
The event loop is a mechanism that allows JavaScript to perform non-blocking operations despite being single-threaded. It continuously checks if there are any pending tasks in the call stack and executes them.
Task Types
- Macrotasks: setTimeout, setInterval, I/O operations, UI rendering
- Microtasks: Promises, async/await, queueMicrotask
The event loop executes microtasks before macrotasks. This means that all microtasks in the queue will be executed before any macrotask.
10. Array Methods
Methods that Modify Original Array
- push(): Add elements to the end
- pop(): Remove last element
- shift(): Remove first element
- unshift(): Add elements to the beginning
- splice(): Add/remove elements at any position
- sort(): Sort elements
- reverse(): Reverse elements
Methods that Return New Array
- concat(): Merge arrays
- slice(): Extract portion of array
- map(): Transform elements
- filter(): Select elements
- reduce(): Reduce to single value
11. Deep vs. Shallow Copy
Shallow Copy
Creates a new object, but the properties are references to the same values as the original object.
const original = { name: 'John', address: { city: 'New York' } };
const shallowCopy = { ...original };
shallowCopy.name = 'Jane'; // Doesn't affect original
shallowCopy.address.city = 'Boston'; // Affects original!
Deep Copy
Creates a completely independent clone of an object, including all nested objects.
const original = { name: 'John', address: { city: 'New York' } };
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.name = 'Jane'; // Doesn't affect original
deepCopy.address.city = 'Boston'; // Doesn't affect original
12. Debounce and Throttle
Debounce
Ensures a function is only called after a certain amount of time has passed since it was last called. Useful for search input and window resize events.
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
const debouncedSearch = debounce(query => {
console.log('Searching for:', query);
}, 300);
// Called multiple times but only executes once after 300ms of inactivity
Throttle
Ensures a function is called at most once every specified time interval. Useful for scroll events and mousemove events.
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
const throttledScroll = throttle(() => {
console.log('Scroll event handled');
}, 200); // Max once every 200ms
Frontend Frameworks
React
1. React Component Lifecycle
Class Components
- Mounting:
- constructor()
- render()
- componentDidMount()
- Updating:
- shouldComponentUpdate()
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()
- Unmounting:
- componentWillUnmount()
Function Components
Function components use hooks to manage lifecycle effects:
- useEffect() for mounting, updating, and unmounting
- useMemo() and useCallback() for performance optimization
2. Controlled vs. Uncontrolled Components
Controlled Components
Form elements whose values are controlled by React state:
function ControlledForm() {
const [value, setValue] = useState('');
return (
<input onchange="{(e)" type="text" value="{value}"></input> setValue(e.target.value)}
/>
);
}
Uncontrolled Components
Form elements that maintain their own state using refs:
function UncontrolledForm() {
const inputRef = useRef();
const handleSubmit = () => {
console.log(inputRef.current.value);
};
return (
<div>
<input ref="{inputRef}" type="text"></input>
<button onclick="{handleSubmit}">Submit</button>
</div>
);
}
3. React Hooks
- useState(): Manages component state ```
const [count, setCount] = useState(0);
- useEffect(): Handles side effects ```
useEffect(() => {
document.title =
Count: ${count}; }, [count]); - useContext(): Accesses context values ```
const theme = useContext(ThemeContext);
- useReducer(): Manages complex state logic ```
const [state, dispatch] = useReducer(reducer, initialState);
- useRef(): Creates mutable references ```
const inputRef = useRef();
- useMemo(): Memoizes expensive calculations ```
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- useCallback(): Memoizes functions ```
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);
Vue
Vue 3 Composition API
The Composition API allows for better code organization and reuse:
import { ref, computed, onMounted } from 'vue';
export default {
setup() {
const count = ref(0);
const doubled = computed(() => count.value * 2);
function increment() {
count.value++;
}
onMounted(() => {
console.log('Component mounted');
});
return {
count,
doubled,
increment
};
}
}
Angular
Services and Dependency Injection
Services in Angular are typically singletons that can be injected into components:
@Injectable({
providedIn: 'root'
})
export class DataService {
private data = new BehaviorSubject<string>([]);
get data$() {
return this.data.asObservable();
}
addData(item: string) {
this.data.next([...this.data.value, item]);
}
}</string>
Web Performance
1. Browser Rendering Process
The browser rendering process involves several steps:
- HTML parsing and DOM tree construction
- CSS parsing and CSSOM tree construction
- Render tree construction (combining DOM and CSSOM)
- Layout (calculating element positions and dimensions)
- Painting (rendering pixels to the screen)
- Composite (combining multiple layers)
2. Performance Optimization Techniques
- Minimize HTTP requests
- Enable compression (gzip, Brotli)
- Optimize images (use appropriate formats, dimensions)
- Implement lazy loading for images and components
- Use browser caching strategies
- Minimize DOM manipulation
- Use efficient CSS selectors
- Debounce and throttle event handlers
- Implement code splitting
- Use Content Delivery Networks (CDNs)
3. Web Vitals
Key metrics for measuring user experience:
- LCP (Largest Contentful Paint): Time to render the largest content element
- FID (First Input Delay): Time from user interaction to browser response
- CLS (Cumulative Layout Shift): Unexpected layout movements
- FCP (First Contentful Paint): Time to first content paint
- TTFB (Time to First Byte): Time to first byte from server
Web Security
1. Cross-Site Scripting (XSS)
Prevention techniques:
- Input validation and sanitization
- Output encoding
- Content Security Policy (CSP)
- HttpOnly cookies
2. Cross-Site Request Forgery (CSRF)
Prevention techniques:
- Anti-CSRF tokens
- SameSite cookies
- Origin validation
3. Content Security Policy (CSP)
Example CSP header:
Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-inline' https://trusted.cdn.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
frame-ancestors 'none';
Build Tools
1. Webpack
Webpack is a module bundler for JavaScript applications:
- Entry point configuration
- Loaders for transforming files
- Plugins for extending functionality
- Code splitting and optimization
2. Vite
Vite is a modern build tool that leverages native ES modules:
- Instant server start using native ES modules
- Hot Module Replacement (HMR) at lightning speed
- Built-in support for TypeScript, JSX, CSS
- Optimized production builds using Rollup
3. Babel
Babel is a JavaScript transcompiler that converts modern JavaScript code into backward-compatible versions:
- Polyfills for missing features
- Syntax transformation
- Source map generation
TypeScript
1. TypeScript Benefits
- Static type checking
- Better IDE support
- Improved code maintainability
- Early error detection
- Enhanced code documentation
2. TypeScript Types
Basic Types
- number, string, boolean
- any, unknown, never, void
- array, tuple, enum
Advanced Types
- Union types (|)
- Intersection types (&)
- Type aliases (type)
- Interfaces (interface)
3. Type vs. Interface
Both can define object shapes, but with key differences:
- Type can represent primitives, unions, tuples, and other types that interfaces can't
- Interfaces can be extanded or implemented
- Multiple interfaces with the same name are merged; types with the same name cause an error
HTTP and Networking
1. HTTP vs. HTTPS
| Feature | HTTP | HTTPS |
|---|---|---|
| Protocol | Hypertext Transfer Protocol | HTTP over SSL/TLS |
| Port | 80 | 443 |
| Security | No encryption | Encrypted with SSL/TLS |
| Certificate | Not required | Required (issued by CA) |
| Performance | Faster (no encryption overhead) | Slightly slower due to encryption |
2. HTTP Status Codes
Informational (1xx)
- 100: Continue
Success (2xx)
- 200: OK
- 201: Created
- 204: No Content
Redirection (3xx)
- 301: Moved Permanently
- 304: Not Modified
Client Error (4xx)
- 400: Bad Request
- 401: Unauthorized
- 403: Forbidden
- 404: Not Found
Server Error (5xx)
- 500: Internal Server Error
- 502: Bad Gateway
- 503: Service Unavailable
3. Caching Mechanisms
Cache-Control Directives
- max-age: Maximum time in seconds resource is considered fresh
- no-cache: Must validate with server before using cached response
- no-store: Never cache response
- public: Cacheable by any cache
- private: Cacheable only by private cache
ETag and Last-Modified
- ETag: Unique identifier for resource version
- Last-Modified: Timestamp of last modification
4. Cross-Origin Resource Sharing (CORS)
CORS is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served.
Key headers:
- Access-Control-Allow-Origin: Specifies which domains are allowed
- Access-Control-Allow-Methods: Specifies allowed HTTP methods
- Access-Control-Allow-Headers: Specifies allowed headers
- Access-Control-Allow-Credentials: Indicates whether credentials can be included
5. Fetch API
The Fetch API provides a modern interface for making HTTP requests:
// GET request
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// POST request
fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ key: 'value' }),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Testing
1. Testing Frameworks
- Jest: JavaScript testing framework with focus on simplicity
- Mocha: Feature-rich JavaScript test framework
- Cypress: End-to-end testing framework
- Testing Library: Simple and complete testing utilities
2. Testing Types
- Unit Testing: Testing individual components in isolation
- Integration Testing: Testing interactions between components
- End-to-End Testing: Testing user workflows from start to finish
3. Example: Jest Test
function sum(a, b) {
return a + b;
}
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
test('object assignment', () => {
const data = { one: 1 };
data['two'] = 2;
expect(data).toEqual({ one: 1, two: 2 });
});
Conclusion
This guide covers essential frontend development concepts that are commonly tested in technical interviews. Understanding these topics thoroughly will help you succeed in frontend interviews and build robust, efficient web applications.
Remember that practical experience is just as important as theoretical knowledge. Implement these concepts in your projects to solidify your understanding.