Uber 60-min FE Interview - mid-July Problem: on Hackerrank online IDE, given the function definitions, implement certain logic to obtain the expected output while ensuring the function calls running in parallel .
Note that (based on clarification made by the interviewer):
Only JS/TS allowed for this problem;
The function of getNameById is meant to simulate certain time consuming task; no change should be made other than under TODO inside asyncMap;
callback param passed into getNameById is not the same as that in asyncMap.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function getNameById (id, callback ) { const randomRequestTime = Math .floor (Math .random () * 100 ) * 200 ; setTimeout (() => { callback ("User" + id); }, randomRequestTime); } const userIds = [1 , 2 , 3 , 4 , 5 ];async function asyncMap (input, iterateeFn, callback ) { } asyncMap (userIds, getNameById, (names ) => { console .log (names); });
Revise via vibe coding:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 async function asyncMap (input, iterateeFn, callback ) { const names = new Set (); const output = []; const promiseBasedIteratee = (id, taskCallback ) => { return new Promise ((resolve ) => { iterateeFn (id, async (taskName) => { resolve (); await taskCallback (taskName); }); }); }; Promise .all ( input.map (async (id) => { await promiseBasedIteratee (id, async (taskName) => { for (let prev = 1 ; prev < id; prev++) { while (!names.has (prev)) { await new Promise ((resolve ) => setTimeout (resolve, 100 )); } } names.add (id); output.push (taskName); }); }) ).then (async () => { while (output.length < userIds.length ) { await new Promise ((resolve ) => setTimeout (resolve, 100 )); } callback (output); }); }
Notes:
Beware of the location of resolve param inside Promise Object, which may affect parallelism.
The original function param iterateeFn is callback-based and may lead to race conditions if not converted into Promise-based, in which case Promise.all() resolves immediately VS when the actual callback execution completes.
Promise.all() resolves as soon as all calls complete regardless of ordering, not ensuring the resolving/completion.
Reference: https://shnoman97.medium.com/parallel-processing-in-javascript-with-concurrency-c214e9facefd
Non-native parallel implementation based on Promise.all.
Example:
1 2 3 4 5 6 7 8 9 async function parallel (arr, fn, threads = 2 ) { const result = []; while (arr.length ) { const res = await Promise .all (arr.splice (0 , threads).map ((x ) => fn (x))); result.push (res); } return result.flat (); } const res = await parallel (arr, apiLikeFunction, 5 );
Nuro 45-min FE Interview - late-June Problem description:
1 2 3 4 Self dismissing modal 1. When button is clicked, modal should cover the page2. After 5 seconds, the modal closes on it's own
Revised implementation w/o error risk when using JSX element VS functional call:
App.tsx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 import "./App.css" ;import "h8k-components" ;import React , { useState, useEffect } from "react" ;const title = "React App" ;const App = ( ) => { const [count, setCount] = useState (0 ); const [modalVisible, setModalVisible] = useState (false ); useEffect (() => { if (modalVisible) { const interval = setInterval (() => { if (modalVisible && count > 0 ) { setCount ((count ) => count - 1 ); } }, 1000 ); return () => { clearInterval (interval); }; } }, [modalVisible]); const Modal = ( ) => ( <div style ={{ display: modalVisible ? "flex " : "none ", flexDirection: "column ", padding: "18px ", }} > <h2 > This is a modal</h2 > <p > Countdown: {count} second(s) left ...</p > </div > ); return ( <div className ="App" > <Modal /> {/* {Modal()} */} <h8k-navbar header ={title} > </h8k-navbar > <div className ="fill-height layout-column justify-content-center align-items-center" > {/* step 2: replace the button to open the model */} <button onClick ={() => { setModalVisible(true); setCount(5); setTimeout(() => setModalVisible(false), 5000); }} disabled={modalVisible} > Open Modal </button > </div > </div > ); }; export default App ;
Original defective implementation during the interview:
./src/App.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 import "./App.css" ;import "h8k-components" ;import React , { useState, useEffect } from "react" ;const title = "React App" ;const App = ( ) => { const [count, setCount] = useState (0 ); const [modalVisible, setModalVisible] = useState (false ); const [countDown, setCountDown] = useState (false ); useEffect (() => { console .log ("modal visible:" , modalVisible); if (modalVisible && !countDown) { setInterval (() => { if (modalVisible && count > 0 ) { console .log ("time left:" , count); } }, 1000 ); } return () => { clearTimeout (); }; }, [modalVisible]); const Modal = ( ) => { return ( <div style ={{ display: modalVisible ? "flex " : "none ", flexDirection: "column ", padding: "18px ", }} > <h2 > This is a modal</h2 > <p > Countdown: {count} second(s) left ...</p > </div > ); }; return ( <div className ="App" > <Modal /> {/* {Modal()} */} <h8k-navbar header ={title} > </h8k-navbar > <div className ="fill-height layout-column justify-content-center align-items-center" > {/* <p data-testid ="output" > You clicked {count} times ...</p > */} {/* <button data-testid ="add-button" onClick ={() => setCount(count + 1)}>Click Me</button > */} {/* step 2: replace the button to open the model */} <button onClick ={() => { setModalVisible(true); setCount(5); setTimeout(() => setModalVisible(false), 5000); setCountDown(true); }} disabled={modalVisible} > Open Modal </button > </div > </div > ); }; export default App ;
./src/App.css 1 @import "../node_modules/h8k-design/dist/index.css" ;
./src/index.js 1 2 3 4 5 6 7 8 9 import React from "react" ;import ReactDOM from "react-dom" ;import App from "./App" ;import { applyPolyfills, defineCustomElements } from "h8k-components/loader" ;ReactDOM .render (<App /> , document .getElementById ("root" ));applyPolyfills ().then (() => { defineCustomElements (window ); });
package.json 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 { "name" : "react-app" , "version" : "0.1.0" , "private" : true , "dependencies" : { "h8k-components" : "^1.0.0" , "h8k-design" : "^1.0.16" , "react" : "^16.13.1" , "react-dom" : "^16.13.1" , "react-scripts" : "3.4.1" , "@testing-library/jest-dom" : "5.16.1" , "@testing-library/react" : "12.1.2" } , "scripts" : { "prestart" : "npm install" , "start" : "cross-env HOST=0.0.0.0 PORT=8000 ./node_modules/.bin/react-scripts start" } , "devDependencies" : { "cross-env" : "^7.0.2" } , "browserslist" : { "production" : [ ">0.2%" , "not dead" , "not op_mini all" ] , "development" : [ "last 1 chrome version" , "last 1 firefox version" , "last 1 safari version" ] } }
Yahoo Final Rounds - FE Section - mid-March External references after revision:
Revised implementation of App component:
App.tsx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 function App ( ) { const [comments, setComments] = useState ([]); const [inputValue, setInputValue] = useState ({ id : "" , name : "" , email : "" , body : "" , }); const getComments = async ( ) => { try { const response = await fetch ( "https://jsonplaceholder.typicode.com/posts/1/comments" ); if (!response.ok ) { throw new Error (`Response status: ${response.status} ` ); } const json = await response.json (); console .log ("resp:" , json); setComments (json); } catch (error) { console .error (error.message ); } }; const submitComment = (event ) => { event.preventDefault (); const newComment = { ...inputValue, }; console .log ("inputs:" , newComment); setComments ((prevComments ) => [newComment, ...prevComments]); setInputValue ({ id : "" , name : "" , email : "" , body : "" }); }; useEffect (() => { getComments (); }, []); return ( <div className ="app" > <h1 > Comments</h1 > <form > <div > <span > ID:</span > <input id ="id-input" type ="text" value ={inputValue.id} onChange ={(e) => setInputValue((prevInput) => { return { ...prevInput, id: e.target.value }; }) } /> </div > <div > <span > Name:</span > <input id ="name-input" type ="text" value ={inputValue.name} onChange ={(e) => setInputValue((prevInput) => { return { ...prevInput, name: e.target.value }; }) } /> </div > <div > <span > Email:</span > <input id ="email-input" type ="text" value ={inputValue.email} onChange ={(e) => setInputValue((prevInput) => { return { ...prevInput, email: e.target.value }; }) } /> </div > <div > <span > Content:</span > <input id ="comment-input" type ="text" value ={inputValue.body} onChange ={(e) => { // console.log('Input onchange:', e.target.value, e.currentTarget.value); // setInputValue(e.target.value); setInputValue((prevInput) => { return { ...prevInput, body: e.target.value }; }); }} /> </div > <button type ="submit" onClick ={submitComment} > Submit Comment </button > </form > <ul > {comments.map((comment) => { const { id, name, email, body } = comment; return ( <li key ={ `comment-key- ${id }`}> <div > <h4 > {name} {email} </h4 > <p > {body}</p > </div > </li > ); })} </ul > </div > ); } export default App ;
Wisdom AI 60-min Screening in FE - early-Feb Problem: Implement a FE page of basic card game using stackblitz.com online IDE (JS only, no TS support).
Constants 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const numbers = [ "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" , "J" , "Q" , "K" , "A" , ]; const suits = ["♠" , "♣" , "♥" , "♦" ];
Revised coding (online IDE / Live Demo ):
style.css 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 h1 ,p { font-family : -apple-system, BlinkMacSystemFont, "Segoe UI" , Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans" , "Helvetica Neue" , sans-serif; } .card-list { display : flex; column-gap : 4px ; } .card { border : 2px solid green; border-radius : 4px ; display : flex; align-items : center; justify-content : center; min-width : 50px ; min-height : 30px ; }
App.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 import React , { useState } from "react" ;import "./style.css" ;const numbers = [ "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" , "J" , "Q" , "K" , "A" , ]; const suits = ["♠" , "♣" , "♥" , "♦" ];const generate_card = ( ) => { const random_num = Math .floor (Math .random () * numbers.length ); const random_suit = Math .floor (Math .random () * suits.length ); return numbers[random_num] + suits[random_suit]; }; const draw_cards = (card_num ) => { const cards = new Set (); while (cards.size < card_num) { const new_card = generate_card (); if (cards.has (new_card)) { continue ; } cards.add (new_card); } return Array .from (cards); }; export default function App ( ) { const [cardNum, setCardNum] = useState (5 ); const [cardList, setCardList] = useState ([]); const deal_a_hand = ( ) => { setCardList (() => { const cards = draw_cards (cardNum); return cards.map ((card ) => <span className ="card" > {card}</span > ); }); setCardNum (4 ); }; return ( <div > {/* <h1 > Hello StackBlitz!</h1 > <p > Start editing to see some magic happen :)</p > */} <button onClick ={deal_a_hand} > Deal a Hand</button > <h2 > Cards</h2 > <div className ="card-column" > <p className ="card-list" > {cardList}</p > </div > </div > ); }