Offer arrives, dig friends to pick up! I am participating in the 2022 Spring Recruitment Series - Experience Review, click to view the details of the event and to be considered a participant
Hello everyone, my name is Shanyue. This article is also available on my blog Roadmap .
One of the frequent questions is: How do I practice programming problems? Shanyue once again summed up a practice route about handwritten code.
To make sure the code runs properly, debug and test it.
All handwritten codes below are pasted in my codepen
All handwritten codes below are posted in my codepen
All handwritten codes below are posted in my codepen
Ready to work
API Design Thinking
As an old front-end who has worked for more than three years, he will understand one thing: the design of the API is more important than the implementation .
Why?
For example compose
function is commonly used in various middleware designs, such as redux
and so on. The implementation of the redux
function is extremely simple, even in one line, but it is even more difficult to be the first to think of compose
.
Therefore, many interview questions in the front-end interview are mainly based on the simulation implementation of ES API and lodash API, so you need to be familiar with lodash
and ES6+
documents before writing code.
code specification
When examining code during the interview process, in addition to examining the candidate's logical ability, secondly, you can examine the candidate's code ability, such as
- Is there a consistent code specification
- Are there clear and readable variable names
- Is there a more brief code
For the ability to develop elegant code, see Clean Code concepts adapted for JavaScript. , with 50+ K stars on Github.
For example, about naming optimization
// BAD
// What the heck is 86400000 for?
setTimeout(blastOff, 86400000);
// GOOD
// Declare them as capitalized named constants.
const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000; //86400000;
setTimeout(blastOff, MILLISECONDS_PER_DAY);
space complexity and time complexity
- Space Complexity describes the size of the storage space temporarily occupied by the algorithm during operation
- Time complexity describes the running time of the algorithm, usually expressed in big O notation
This image is from the article How to find time complexity of an algorithm?
- O(1): Constant Complexity, constant complexity, for example, the final conclusion can be obtained by calculating twice
- O(logn): Logarithmic Complexity, the most common is binary search
- O(n): Linear Complexity, generally a for loop, but half or two for loops are also regarded as O(n)
- O(n^2): Usually nested for loops, such as bubble sort
Handwritten Code Roadmap
The following are the code questions that I have summarized in many major workshops. I will summarize them into different parts according to the difficulty and module attributes.
Remarks: summarizes all the interviews with big factories, please click here
Therefore, I divided the questions into the following categories. You can prepare according to the number of stars and the order in which I listed all the code questions. Find three questions for coding every day, and stick to it. After three months, the coding stage of the interview with the big factory will not change. Problems will arise.
- ES API
- lodash API
- programming logic questions
- Algorithms and Data Structures (leetcode)
All the questions below can be found in Shanyue's warehouse, and most of the code questions can be found on codepen , find my problem solving test and execute it directly.
01 ES API
Many big factory interview questions are obsessed with simulating the implementation of the native API. Although most of the time it is not helpful, sometimes it can further deepen the understanding of the API.
For example, when you write the end Promise.all
, it will be easier to write a Promises for concurrency control.
bind/call/apply ⭐⭐⭐⭐⭐️️️️
High frequency problem, medium frequency realization.
Function.prototype.fakeBind = function(obj, ...args) {
return (...rest) => this.call(obj, ...args, ...rest)
}
sleep/delay ⭐⭐⭐⭐⭐
- Topic: [Q435] How to implement a sleep/delay function
- Code: [Q435] How does JS implement a sleep/delay function
sleep
function is not only a code question often asked in interviews, but also a tool function commonly used in daily work, especially in testing.
const sleep = (seconds) => new Promise(resolve => setTimeout(resolve, seconds))
function delay (func, seconds, ...args) {
return new Promise((resolve, reject) => {
setTimeout(() => {
Promise.resolve(func(...args)).then(resolve)
}, seconds)
})
}
Promise.all ⭐️⭐️⭐️⭐️⭐️
- Code: Promise.all
- Title: Promise.all
Simple at first glance, but difficult to implement.
function pAll (_promises) {
return new Promise((resolve, reject) => {
// Iterable => Array
const promises = Array.from(_promises)
// 结果用一个数组维护
const r = []
const len = promises.length
let count = 0
for (let i = 0; i < len; i++) {
// Promise.resolve 确保把所有数据都转化为 Promise
Promise.resolve(promises[i]).then(o => {
// 因为 promise 是异步的,保持数组一一对应
r[i] = o;
// 如果数组中所有 promise 都完成,则返回结果数组
if (++count === len) {
resolve(r)
}
// 当发生异常时,直接 reject
}).catch(e => reject(e))
}
})
}
Array.isArray ⭐️⭐️⭐️⭐️⭐️
- Title: Array.isArray
Interviews are often asked, but simple enough.
Array.prototype.flat ⭐️⭐️⭐️⭐️⭐️
- Topic: [Q443] Implement a function flatten to flatten an array
- Code: [Q443] Implement an array flattening function flatten
reduce
and concat
are a perfect match
function flatten (list, depth = 1) {
if (depth === 0) return list
return list.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b, depth - 1) : b), [])
}
Note that flatten has a second parameter depth
Promise ⭐️⭐️⭐️⭐️
- Title: Promise
Needless to say, it is not easy to implement a real Promise that conforms to the specification.
Array.prototype.reduce ⭐️⭐️⭐️
- Code: Array.prototype.reduce
- Title: Array.prototype.reduce
const reduce = (list, fn, ...init) => {
let next = init.length ? init[0] : list[0]
for (let i = init.length ? 0 : 1; i < list.length; i++) {
next = fn(next, list[i], i)
}
return next
}
This topic looks simple, but in practice there are many boundary issues that need to be paid attention to, such as
- What is the first Index in the callback function?
- How to deal with arrays as sparse arrays?
String.prototype.trim ⭐️⭐️⭐️
In regular expressions, \s
means to match a whitespace character, including spaces, tabs, form feeds, and newlines. Equivalent to [ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]
.
const trim = str => str.trim || str.replace(/^\s+|\s+$/g, '')
Generally, the API will be examined when examining regularities
02 lodash API
throtle/debounce ⭐⭐⭐⭐⭐️️
The necessary means of reducing rendering in performance optimization, and the code is easy enough, it is often mentioned in interview questions.
function throttle (f, wait) {
let timer
return (...args) => {
if (timer) { return }
timer = setTimeout(() => {
f(...args)
timer = null
}, wait)
}
}
function debounce (f, wait) {
let timer
return (...args) => {
clearTimeout(timer)
timer = setTimeout(() => {
f(...args)
}, wait)
}
}
cloneDeep ⭐⭐️⭐⭐⭐
Deep copy, whether in performance optimization at work or in interviews, is very popular.
Using JSON serialization and deserialization cannot solve the problem of copying some complex objects. The difficulty lies in the processing of different data types.
isEqual ⭐⭐⭐⭐⭐
In-depth comparison is also commonly used in performance optimization, and it is less difficult than cloneDeep
.
get ⭐️⭐️⭐️⭐️⭐️
- Topic: How to implement a function similar to lodash.get
- Code: How to implement similar lodash.get function
In ES6+, use the optional chaining operator ?.
to further reduce implementation difficulty
function get (source, path, defaultValue = undefined) {
// a[3].b -> a.3.b -> [a, 3, b]
const paths = path.replace(/\[(\w+)\]/g, '.$1').replace(/\["(\w+)"\]/g, '.$1').replace(/\['(\w+)'\]/g, '.$1').split('.')
let result = source
for (const p of paths) {
result = result?.[p]
}
return result === undefined ? defaultValue : result
}
compose(flowRight) ⭐️⭐️⭐️⭐️⭐️
const compose = (...fns) =>
// 注意 f、g 的位置,如果实现从左到右计算,则置换顺序
fns.reduce((f, g) => (...args) => f(g(...args)))
shuffle ⭐️⭐️⭐️⭐️⭐️
- Topic: [Q447] How to implement an array shuffle function shuffle
- Related: [Q645] Randomly generate a six-digit mobile phone verification code (repeated/non-repeatable)
- Code: [Q447] How to implement an array shuffle function shuffle
Probably extremely simple to implement a simple shuffle
.
const shuffle = (list) => list.sort((x, y) => Math.random() - 0.5)
Without the help of Array.prototype.sort
, it can be achieved by the following code
function shuffle (list) {
const len = list.length
let result = [...list]
for (let i = len - 1; i > 0; i--) {
const swapIndex = Math.floor(Math.random() * (i + 1));
[result[i], result[swapIndex]] = [result[swapIndex], result[i]]
}
return result
}
In production practice, shuffle
is used in many scenarios, such as to randomly generate a six-digit mobile phone verification code that does not repeat
sample ⭐️⭐️⭐️⭐️⭐️
- Topic: [Q436] How to implement a sample function that randomly selects an element from an array
The Math.random() function returns a floating point, pseudo-random number in the range from 0 to less than 1, which is expressed in mathematics as [0, 1), which can be used to implement the sample function
Array.prototype.sample = function () { return this[Math.floor(Math.random() * this.length)] }
sampleSize ⭐️⭐️⭐️⭐️⭐️
A simple shuffle
can be implemented according to 0623884f2b06bd
const shuffle = (list) => list.sort((x, y) => Math.random() - 0.5)
const sampleSize = (list, n) => shuffle(list).slice(0, n)
maxBy ⭐⭐⭐⭐⭐
- Topic: [Q628] Implement a function maxBy to find the largest array item according to a given condition
keyBy ⭐⭐⭐⭐
groupeBy ⭐⭐⭐⭐
- Subject: [Q679] Implement a function groupBy
chunk ⭐️⭐️⭐️⭐️
function chunk (list, size) {
const l = []
for (let i = 0; i < list.length; i++ ) {
const index = Math.floor(i / size)
l[index] ??= [];
l[index].push(list[i])
}
return l
}
chunk ⭐️⭐️⭐️⭐️
const f = x => x
const onceF = once(f)
//=> 3
onceF(3)
//=> 3
onceF(4)
template ⭐⭐⭐⭐️️️️️
- Topic: [Q660] Implement a render/template function that can be used to render the template
- Code: [Q660] Implement a render/template function that can be used to render the template
A slightly more difficult programming problem.
const template = '{{ user["name"] }},今天你又学习了吗 - 用户ID: {{ user.id }}';
const data = {
user: {
id: 10086,
name: '山月',
}
};
//=> "山月,今天你又学习了吗 - 用户ID: 10086"
render(template, data);
Notice:
- Watch out for deeply nested data
- Note
user['name']
attribute
pickBy/omitBy ⭐⭐⭐⭐
camelCase ⭐️⭐⭐⭐
- Title: Hump named
difference ⭐️⭐️⭐️
03 Programming logic questions
Regarding programming logic questions, it refers to some data processing often encountered in work
FizzBuzz, is it divisible by 3 or 5 ⭐️⭐️⭐️⭐️⭐️
Input an integer, if it is divisible by 3, output Fizz
If divisible by 5, output Buzz
If it is divisible by both 3 and 5, output FizzBuzz
//=> 'fizz'
fizzbuzz(3)
//=> 'buzz'
fizzbuzz(5)
//=> 'fizzbuzz'
fizzbuzz(15)
//=> 7
fizzbuzz(7)
Although this question is very simple, there are still many people who can't get it right in the interview.
Implement Promise.map to control concurrency ⭐️⭐️⭐️⭐️⭐️
- Title: Promise.map
- Code: Promise.map
For Promise concurrency control, it is often asked in interviews and often involved in work. Knowing the implementation of [Promise.all]() will help a lot in implementing concurrency control before getting started.
In addition, the most popular Promise library bluebird implements Promise.map
and is heavily used in the project.
Async sum/add ⭐️⭐️⭐️⭐️⭐️
The master of coding questions , from the headlines, promise serial, parallel, binary, concurrency control, progressive.
How to implement a publish subscribe pattern using JS ⭐️⭐️⭐️⭐️⭐️
- Topic: [Q613] How to use JS to implement a publish-subscribe model
- Code: [Q613] How to use JS to implement a publish-subscribe model
How to implement infinite accumulation sum function ⭐️⭐️⭐️⭐️⭐️
- Topic: [Q421] How to realize a function of infinite accumulation
- Code: [Q421] How to implement a function of infinite accumulation
Implement a sum function as follows:
sum(1, 2, 3).valueOf() //6
sum(2, 3)(2).valueOf() //7
sum(1)(2)(3)(4).valueOf() //10
sum(2)(4, 1)(2).valueOf() //9
sum(1)(2)(3)(4)(5)(6).valueOf() // 21
This is still the most preferred topic of Byte, Kuaishou, and Ali. In fact, there is a little technical problem.
This is still the most preferred topic of Byte, Kuaishou, and Ali. In fact, there is a little technical problem.
This is still the most preferred topic of Byte, Kuaishou, and Ali. In fact, there is a little technical problem.
This is a function about lazy calculation, use sum to collect all accumulated items, use valueOf to calculate
- sum returns a function that collects all accumulated items, implemented using recursion
- The return function has a valueOf attribute for unified calculation
function sum (...args) {
const f = (...rest) => sum(...args, ...rest)
f.valueOf = () => args.reduce((x, y) => x + y, 0)
return f
}
Count the largest number/second largest number in an array ⭐️⭐️⭐️⭐️⭐️
- Title: Count the largest number/second largest number in an array
- Code: The largest number in the statistics array/the second largest number
Find the largest value:
function max (list) {
if (!list.length) { return 0 }
return list.reduce((x, y) => x > y ? x : y)
}
Find the largest two values:
See code Find the largest two values in an array - codepen
function maxTwo (list) {
let max = -Infinity, secondMax = -Infinity
for (const x of list) {
if (x > max) {
secondMax = max
max = x
} else if (x > secondMax) {
secondMax = x
}
}
return [max, secondMax]
}
If you want TopN, you can use large top heap and small top heap to achieve, see another question
Count the most frequently occurring characters in a string ⭐️⭐️⭐️⭐️⭐️
- Topic: [Q644] Count the most frequently occurring characters in a string and the number of times
- Code: [Q644] Count the characters with the most occurrences in the string and the number of times
function getFrequentChar (str) {
const dict = {}
for (const char of str) {
dict[char] = (dict[char] || 0) + 1
}
const maxBy = (list, keyBy) => list.reduce((x, y) => keyBy(x) > keyBy(y) ? x : y)
return maxBy(Object.entries(dict), x => x[1])
}
The following scheme performs counting and statistics once for size comparison, and only needs one algorithm complexity of O(n)
function getFrequentChar2 (str) {
const dict = {}
let maxChar = ['', 0]
for (const char of str) {
dict[char] = (dict[char] || 0) + 1
if (dict[char] > maxChar[1]) {
maxChar = [char, dict[char]]
}
}
return maxChar
}
Encode compression of the following numbers ⭐️⭐️⭐️⭐️⭐️
- Subject: [Q412] Compress and encode the following string
- Code: [Q412] Compress and encode the following string
This is a code question that is often tested by major manufacturers
- Input: 'aaaabbbccd'
- Output: 'a4b3c2d1', which means a appears four times in a row, b appears three times in a row, c appears twice in a row, and d appears once in a row
There are following test cases
//=> a4b3c2
encode('aaaabbbcc')
//=> a4b3a4
encode('aaaabbbaaaa')
//=> a2b2c2
encode('aabbcc')
If the code is written correctly, you can go further:
- If it only appears once, do not encode the number, such as aaab -> a3b
- If it only appears twice, do not encode, such as aabbb -> aab3
- How to solve if the decoding number conflict
Write function encode
to realize this function
For the code, see [Q412] Compress the following characters - codepen
function encode (str) {
const l = []
let i = 0
for (const s of str) {
const len = l.length
const lastChar = len > 0 ? l[len - 1][0] : undefined
if (lastChar === s) {
l[len - 1][1]++
} else {
l.push([s, 1])
}
}
return l.map(x => x.join('')).join('')
}
Test passed
> encode('aaab')
< "a3b1"
But interviewers tend to go deeper
- If it occurs only once, do not encode the number, such as
aaab -> a3b
- If it appears only twice, do not encode, such as
aabbb -> aab3
- If decoding, how to deal with numbers?
Below is further coding besides numbers
function encode (str) {
const l = []
let i = -1;
let lastChar
for (const char of str) {
if (char !== lastChar) {
lastChar = char
i++
l[i] = [char, 1];
} else {
l[i][1]++
}
}
return l.map(([x, y]) => {
if (y === 1) {
return x
}
if (y === 2) {
return x + x
}
return x + y
}).join('')
}
LRU Cache ⭐️⭐️⭐️⭐️⭐️
Implement a function to encode and decode URL querystring ⭐️⭐️⭐️⭐️⭐️
What is the principle of JSONP and how to implement it ⭐️⭐️⭐️⭐️
JSONP
, full name JSON with Padding
, appeared to solve cross-domain problems. Although it can only handle GET cross-domain, although CORS cross-domain is basically used now, it is still necessary to know it, after all interview will ask .
JSONP
based on two principles:
- Dynamically create
script
, usescript.src
to load requests across domains - The content of the script loaded by
script.src
is JSONP: iePADDING(JSON)
format
function jsonp ({ url, onData, params }) {
const script = document.createElement('script')
// 一、为了避免全局污染,使用一个随机函数名
const cbFnName = `JSONP_PADDING_${Math.random().toString().slice(2)}`
// 二、默认 callback 函数为 cbFnName
script.src = `${url}?${stringify({ callback: cbFnName, ...params })}`
// 三、使用 onData 作为 cbFnName 回调函数,接收数据
window[cbFnName] = onData;
document.body.appendChild(script)
}
// 发送 JSONP 请求
jsonp({
url: 'http://localhost:10010',
params: { id: 10000 },
onData (data) {
console.log('Data:', data)
}
})
How to generate a random string using JS ⭐️⭐️⭐️⭐️⭐️
- Topic: [Q619] How to generate a random string using JS
const random = (n) => Math.random().toString(36).slice(2, 2 + n)
Add thousands to numbers ⭐️⭐️⭐️
Thousands character replacement can be matched by the regular /(\d)(?=(\d\d\d)+(?!\d))/
function numberThousands (number, thousandsSeperator = ',') {
return String(number).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousandsSeperator)
}
04 Algorithms and Data Structures (leetcode)
200/100 simple and intermediate difficulty questions, mainly simple questions. Just brush it directly.
In my question bank, I also collected multi-algorithm questions summed up in many big factories. The summary is as follows
Output the Fibonacci sequence up to 100
TopK problem
- Topic: 【Q288】How to find TOP k in an array
Typical binary heap problem
- Take the first k numbers in the array as a small top heap, heap
- The other numbers in the array are compared one by one with the top element of the heap, and if it is greater than the top element of the heap, the number is inserted
Time complexity O(nlg(k))
Find two numbers whose sum is N in an array of positive integers growing in positive order
- Title: [Q681] Find two numbers whose sum is N in an array of positive integers growing in positive order
Find the sum of N numbers in the given array to sum all possible sets
Find the sum of N numbers in the given array to sum all possible sets, please add the following code
function fn(arr, n, sum) {}
How to check if two linked lists intersect
- Topic: 【 】How to judge whether two linked lists intersect1623884f2bad77
classic problem
finally
Code programming questions appear frequently in the interview process, and can largely examine the coding ability and coding style of candidates.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。