Updated LinkedIn profile - Abhiram Reddy
- Problem Solving: Use a systematic and logical approach to understanding and addressing a problem. Break down the problem into smaller independent issues. Evaluate different approaches and their tradeoffs.
- Software Engineering Foundation: Familiarity with data structures, algorithms, runtime complexity analysis, use of design patterns, and designing solutions with clean abstractions.
- Technical Competence: Ability to translate solutions into working code and demonstrate a strong language understanding.
- Domain Expertise: Understanding the front-end domain and the relevant languages: Browser (DOM and DOM APIs), HTML, CSS, JavaScript, User Experience, Accessibility, i18n, Networks, and Performance.
- Communication: Ask questions to clarify details and clearly explain one’s approach and considerations.
- Verification: Identify various scenarios to test the code against, including edge cases. Be able to diagnose and fix any issues that arise.
Although algorithmic coding questions aren’t specific to the front end, the skills needed to excel in these questions — strong analytical thinking, effective communication, a solid grasp of the common data structures and algorithms, and good code hygiene, are still crucial skills good Front End Engineers should possess. Good Front End Engineers are also good Software Engineers and good Software Engineers should master basic DSA. Hence it’s no surprise that many companies still ask algorithmic coding questions during interviews. Familiarity with data structures and algorithms is also helpful for solving JavaScript coding questions and User Interface coding questions.
Example Questions
Category | Important Topics |
---|---|
Data Structures | Arrays, Maps, Stacks, Trees, Graphs, Matrix (2D Arrays), Sets |
Algorithms | Binary Search, Breadth-first Search, Depth-first Search, Topological Sorting, Recursion |
Category | Important Topics |
---|---|
Data Structures | Arrays, Maps, Stacks, Trees, Sets |
Algorithms | Binary Search, Breadth-first Search, Depth-first Search, Recursion |
JavaScript Language | Data types (checking for types, type coercion), Scope, Closures, Callbacks, How this keyword works, Object-oriented Programming in JavaScript (prototypes, classes, methods), Arrow functions vs normal functions, Invoking functions via Function.prototype.apply() /Function.prototype.call() , Promise, Handling variadic arguments |
DOM | DOM traversal, DOM creation, DOM manipulation, Accessing element/node properties, Event delegation |
Runtime APIs | Timer (setTimeout() , setInterval() ) |
Category | Important Topics |
---|---|
Data Structures | Arrays, Maps, Stacks, Trees, Sets |
Software Engineering | SOLID Principles, Design Patterns, Model-View-Controller |
HTML | Semantic HTML, Form validation, Form submission |
CSS | Box model, Selectors, Specificity, Positioning, Units, Flexbox, Grid, CSS custom properties (variables) |
JavaScript | Closures, Callbacks, Promise, async/await, Handling variadic arguments |
DOM | DOM traversal, DOM creation, DOM manipulation, Accessing element/node properties, Event delegation |
Runtime APIs | Timer (setTimeout(), setInterval()), Network (Ajax, fetch()) |
Accessibility | ARIA roles, states & properties, Keyboard interactions |
Best Practice Questions Here’s the list converted to GitHub Markdown format:
Building the basic accordion component might let you pass the interview, but nailing the accessibility aspects will help you score more points and possibly put you at senior level.
Break down the problem: Break down the problem into stages/milestones that build on top of each other and write your code progressively.
Test frequently: Test the UI in the browser after you complete every feature so that you can catch bugs early. Bugs caught earlier are easier to fix. Make sure the current feature is working before moving on to the next feature.
Use JavaScript frameworks if possible: Your life will be tough if you choose to build a complicated UI using Vanilla JavaScript as the code can get very long and messy quickly. We recommend building apps and games using a framework if possible.
Think ahead and plan accordingly: Think about what features your interviewer might ask you to add next. Design your code in a way that makes it easy for new features to be added.
Component Organization: Separate components into an outer one that provides the data and an inner stateless one that renders the view based on the data.
State is data that changes over time in your UI, commonly due to user interactions or background events (network request response, passing of time, WebSocket events).
Identify essential state vs derived state. A derived state is a state that can be calculated from the essential state.
Learn to use useReducer
Handling accessibility in UI is a huge plus and in some cases a requirement for senior engineers.
Can you use the UI with the keyboard only?
Can you use your UI component with a screen reader?
Can your UI component work without color?
Can your UI component work without sound?
There’s probably not enough time to handle all edge case scenarios in your code during the interview, but it’d be good to mention them to the interviewer for brownie points. Handle long strings Empty states Too many items in a list - pagination, tables.rows, word-break
export default function makeCounter(initialValue = 0) {
return () => initialValue++;
}
export default function mean(array = []) {
const length = array?.length;
if (length === 0) {
return NaN;
}
const sum = array.reduce(
(accumulator, currentValue) => accumulator + currentValue,
0,
);
const mean = sum / length;
return mean;
}
export default function minBy(array, iteratee) {
let minValue, minValueIndex;
array.map((currentIndex) => {
const currentValue = iteratee(currentIndex);
if (currentValue != null && (minValueIndex === undefined || currentValue < minValue)) {
minValue = currentValue;
minValueIndex = currentIndex;
}
});
return minValueIndex;
}
Implementing Stack data structure with javaScript
export default class Stack {
constructor() {
this.arrayStack = [];
}
/**
* Pushes an item onto the top of the stack.
* @param {*} item The item to be pushed onto the stack.
* @return {number} The new length of the stack.
*/
push(item) {
return this.arrayStack.push(item);
}
/**
* Remove an item at the top of the stack.
* @return {*} The item at the top of the stack if it is not empty, `undefined` otherwise.
*/
pop() {
return this.arrayStack.pop();
}
/**
* Determines if the stack is empty.
* @return {boolean} `true` if the stack has no items, `false` otherwise.
*/
isEmpty() {
return this.arrayStack.length === 0;
}
/**
* Returns the item at the top of the stack without removing it from the stack.
* @return {*} The item at the top of the stack if it is not empty, `undefined` otherwise.
*/
peek() {
return this.isEmpty() ? undefined: this.arrayStack[this.length() - 1];
}
/**
* Returns the number of items in the stack.
* @return {number} The number of items in the stack.
*/
length() {
return this.arrayStack.length;
}
}
export function isBoolean(value) {
return typeof value === "boolean";
}
export function isNumber(value) {
return typeof value === "number";
}
// type of null would be object because js is weird
export function isNull(value) {
return value === null;
}
export function isString(value) {
return typeof value === "string";
}
export function isSymbol(value) {
return typeof value === "symbol";
}
export function isUndefined(value) {
return value === undefined;
}
import submitForm from "./submitForm";
export default function App() {
return (
<form
// Ignore the onSubmit prop, it's used by GFE to
// intercept the form submit event to check your solution.
onSubmit={submitForm}
action="https://www.greatfrontend.com/api/questions/contact-form"
method="post"
>
<label for="name">Name</label>
<input type="text" id="name" name="name" />
<br />
<br />
<label for="mail">E-mail</label>
<input type="email" id="mail" name="email" />
<br />
<br />
<label for="message">Message</label>
<textarea type="text" id="message" name="message" />
<br />
<br />
<input type="submit" value="Submit" />
</form>
);
}
export default function cycle(...values) {
let index = 0;
return () => {
const result = values[index];
index = (index + 1) % values.length;
return result;
};
}
Holy Grail Layout
body {
font-family: sans-serif;
font-size: 12px;
font-weight: bold;
margin: 0;
min-height: 100vh;
}
* {
box-sizing: border-box;
}
header,
nav,
main,
aside,
footer {
padding: 12px;
text-align: center;
}
#root {
display: flex;
flex-direction: column;
height: 100vh;
}
header {
background-color: tomato;
height: 60px;
}
nav {
background-color: coral;
flex-shrink: 0;
width: 100px;
}
main {
background-color: moccasin;
flex-grow: 1;
}
aside {
background-color: sandybrown;
flex-shrink: 0;
width: 100px;
}
footer {
background-color: slategray;
height: 100px;
}
.container {
display: flex;
flex-grow: 1;
/* height: 100%;
display: grid;
grid-template-columns: 100px 1fr 100px; */
}
Rob Pike’s 5 Rules of Programming
Note: Flexbox layout is most appropriate to the components of an application, and small-scale layouts, while the Grid layout is intended for larger-scale layouts.
👉 ALIGN-ITEMS - TOP, BOTTOM
👉 JUSTIFY-CONTENT - LEFT, RIGHT
<!-- CSS GRID -->
<style>
.grid-container {
display: grid;
gap: 10px;
padding: 8px;
background-color: blue;
border-radius: 8px;
grid-template-columns: 1fr 1fr;
grid-template-columns: minmax(200px, 1fr) 2fr;
grid-template-columns: repeat(2, 1fr);
}
.item {
border-radius: 4px;
background-color: yellow;
font-family: Arial;
text-align: center;
padding: 40px 0;
font-size: 30px;
}
@media screen and (min-width: 600px) {
.grid-container {
grid-template-columns: repeat(3, minmax(150px, 1fr));
}
}
</style>
<div class="grid-container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
<!-- CSS GRID -->
auto-fill and auto-fit
auto-fill: The auto-fill keyword creates as many tracks as fit into the grid container without causing the grid to overflow it. If there are more columns than items, the extra columns will still occupy space in the grid, even if they are empty.
auto-fit: The auto-fit keyword behaves the same way as auto-fill, except that after grid item placement it will only create as many tracks as needed and any empty repeated track collapses.
👉 The Difference Between Explicit and Implicit Grids
Codepen - - grid-auto-columns, grid-auto-rows
grid-auto-flow: auto-placement algorithm kicks in to automatically place the items
grid-auto-flow: row;
grid-auto-flow: column;