This article is collected on GitHub DailyQuestion: DailyQuestion, including big factory promotion opportunity, interview book and several interview questions, study 5 minutes a day, a year to enter the big factory.
- Dachang Face Sutra
- Big push
01 What are anti-shake and throttling, and what are their application scenarios
Communicate and discuss in the Issue: 01 What are anti-shake and throttling, and what are their application scenarios
Image stabilization (debounce)
Anti-shake, as the name implies, to prevent jitter, so as not to mistake an event for many times, typing the keyboard is a daily contact with anti-shake operation.
To understand a concept, you must first understand the scenario in which the concept is applied. In the JS world, what is the scene of anti – shake
- To prevent users from clicking buttons such as login and SMS so fast that multiple requests are sent, you need to avoid shaking
- When adjusting the browser window size, the number of resize times is too frequent, resulting in too much calculation. At this time, it needs to be in place once, so it uses anti-shake
- The text editor saves in real time and saves after one second when there is no change operation
ClearTimeout (timer)
function debounce (f, wait) {
let timer
return (. args) = > {
clearTimeout(timer)
timer = setTimeout((a)= >{ f(... args) }, wait) } }Copy the code
The throttle (throttle)
Throttling, as the name suggests, controls the flow of water. Control the frequency of events, such as 1 second, or even 1 minute. This parameter is similar to the Rate Limit controlled by the server and gateway.
scroll
Event, calculate position information every second, etc- Browser plays events, calculates progress information every second, and so on
- Input box Search and send requests in real time display dropdown list, send requests every second (also can be made to shake)
Timer =timeout
function throttle (f, wait) {
let timer
return (. args) = > {
if (timer) { return }
timer = setTimeout((a)= >{ f(... args) timer =null
}, wait)
}
}
Copy the code
Summary (Brief answer)
- Anti – shake: Prevents jitter. The event trigger can be reset within a unit time, preventing the event from being triggered multiple times by accidental injury. The code implementation focuses on clearing clearTimeout. Anti-shaking can be compared to waiting for an elevator. As soon as one person comes in, you have to wait a little longer. Service scenarios avoid repeated submission when the login button is clicked multiple times.
- Throttling: Controls traffic. Events can be triggered only once per unit of time, similar to the Rate Limit on the server. Timer =timeout; The timer = null. Throttling can be likened to going through a traffic light, waiting for each red light to pass one batch.
02 In front-end development, how to obtain the unique identity of the browser
More description: How do I get a unique browser identity, and how does that work
How do I get the unique identity of the browser in front end development
Because different system graphics cards have different rendering parameters and anti-aliasing algorithms when drawing canvas, the CRC check of the drawn picture data is also different.
function getCanvasFp () {
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
ctx.font = '14px Arial'
ctx.fillStyle = '#ccc'
ctx.fillText('hello, shanyue'.2.2)
return canvas.toDataURL('image/jpeg')}Copy the code
Therefore, browser fingerprint information can be obtained according to Canvas.
- draw
canvas
To obtainbase64
The dataurl - For the string dataURL
md5
Fingerprint information is obtained by calculation
But there are mature solutions for common requirements, and the following libraries can be used in a production environment
- fingerprintjs2
It gets the browser fingerprint information based on the following information, which is called component
canvas
webgl
UserAgent
AudioContext
- Support for new apis, etc
requestIdleCallback(function () {
Fingerprint2.get((components) = > {
const values = components.map((component) = > component.value)
const fp = Fingerprint2.x64hash128(values.join(' '), 31)})})Copy the code
In Fingerprintjs2, there are also categories for Components
- browser independent component: some
component
The same device can get the same value across browsers, and some individual browsers can get different values - stable component: some
component
The value changes after the refresh and is called an unstable component
In actual services, you can select appropriate components based on services
const options = {
excludes: {userAgent: true.language: true}}Copy the code
Short answer
The browser fingerprint information can be obtained according to Canvas
- draw
canvas
To obtainbase64
The dataurl - For the string dataURL
md5
Fingerprint information is obtained by calculation
For use in a production environment, you can use Fingerprintjs2 to select the appropriate component based on business requirements, such as whether a single device is cross-browser
03 How do I Obtain the Client IP Address in a Server Application
How do I get a client IP address in a server application
If you havex-forwarded-for
RemoteAddr; otherwise remoteAddr of the socket to which the connection was established.
This header is forwarded-for. The format of this header is as follows. The first IP address of this header is forwarded-for
X-Forwarded-For: 203.0113.195..70.413.18..150.172238.178.
X-Forwarded-For: <client>, <proxy1>, <proxy2>
Copy the code
Here’s how KOA gets the IP
get ips() {
const proxy = this.app.proxy;
const val = this.get(this.app.proxyIpHeader);
let ips = proxy && val
? val.split(/\s*,\s*/)
: [];
if (this.app.maxIpsCount > 0) {
ips = ips.slice(-this.app.maxIpsCount);
}
return ips;
},
get ip() {
if (!this[IP]) {
this[IP] = this.ips[0] | |this.socket.remoteAddress || ' ';
}
return this[IP];
},
Copy the code
See source code: github.com/koajs/koa/b…
04 How do JS replace all one substring with another
Suppose you have A string ‘hello.hello.hello.’ that needs to be replaced with ‘AAA’, i.e. ‘A’
Exchange and discuss in Issue: how does 04 JS replace all one substring with another
If you want to replace a String in full, you can use string.prototype. replace(re, replacer), where global Flag is enabled for regular expressions
const s = 'foo foo foo'
s.replce(/foo/g.'bar')
Copy the code
Can regular expressions be used instead of substrings
A: No, because when using substrings to build a re, there may be special characters, which may cause problems, as shown below
// Expect result: 'AhelloX hello3 '
> 'hello. helloX hello3 '.replace(new RegExp('hello. '.'g'), 'A')
< "AAA"
Copy the code
Replacing substrings in javascript can only be done in one clever way: str.split(‘foo’).join(‘bar’)
> 'hello. hello. hello. '.split('hello. ').join('A')
< "AAA"
Copy the code
Is really a clever (stupid) wonderful (clumsy) method !!!!! Perhaps TC39 also realized a problem, and a new API was created in ESNext
String.prototype.replaceAll()
'aabbcc'.replaceAll('b'.'. ');
// 'aa.. cc'
Copy the code
Detailed documentation in the String. The prototype. ReplaceAll
Summary (and direct answers)
Two ways
str.split('foo').join('bar')
str.replaceAll('foo', 'bar')
In theESNext
Medium, the current support is not good
05 How do I Obtain and Monitor the memory of a process
More description: when writing scripts, sometimes there will be too much memory, so how do we know the memory of a process? And how is it monitored
How do I get and monitor the memory of a process
Ps lets you know how much memory a process occupies
$ ps -O rss -p 3506
PID RSS S TTY TIME COMMAND
3506 6984 S pts/1 00:00:00 vim
Copy the code
If you want to monitor memory, be sure to use the process-all-purpose pidstat command (PS: the name sounds obvious)
## -r Displays memory information
## -p Specifies the PID
## 1: Print once every second$pidstat -r -p 3506 1 Linux 3.10.0-957.21.3.el7.x86_64 (shanyue) 11/04/19_x86_64_ (2 CPU) 20:47:35 UID PID minflt/s Majflt /s VSZ RSS %MEM Command 20:47:360 0 3506 0.00 0.00 139940 6984 0.18 vim 20:47:370 0 3506 0.00 0.00 139940 6984 0.18 Vim 20:47:350 0.00 0.00 139940 6984 0.18 vim 20:47:350 0.00 0.00 0.00 139940 6984 0.18 vim 20:47:41 0 3506 0.00 0.00 139940 6984 0.18 vimCopy the code
Pidstat is a Linux performance tool under SYSstat, but how do you locate memory changes on the MAC? You can use the all-purpose top/ hTOP
$ htop -p 31796
Copy the code
conclusion
In short, there are three commands
pidstat -r
htop/top -p
ps -O rss -p
For more information about monitoring metrics, see my article: Linux Monitoring Metrics Notes
06 What if CORS needs to specify multiple domain names
06 CORS What if you need to specify multiple domain names
CORS controls which domain names can share resources by controlling access-control-allow-origin. The value can be
Access-Control-Allow-Origin: <origin> | *
Copy the code
* indicates all domain names and origin indicates a specific domain name.
Access-control-allow-origin = access-Control-allow-Origin = access-Control-allow-Origin = access-Control-allow-Origin
Request header: Origin
Not all requests are automatically tagged with Origin, and the logic for putting Origin in a browser is as follows
- If there is cross-domain, bring
Origin
The value is the current domain name - If no cross-domain exists, no
Origin
Access-control-allow-origin = access-Control-allow-origin = access-Control-allow-origin = access-Control-allow-origin
- If the request header does not carry
Origin
, if no cross-domain is proved, no processing is done - If the request header contains
Origin
, prove cross-domain, according toOrigin
Set the correspondingAccess-Control-Allow-Origin: <Origin>
Using pseudocode, the implementation is as follows:
// Get the Origin header
const requestOrigin = ctx.get('Origin');
// If not, skip it
if(! requestOrigin) {return await next();
}
// Set the response header
ctx.set('Access-Control-Allow-Origin', requestOrigin)
Copy the code
Vary: Origin
At this point, multiple domains can control the CORS, but it is assumed that two domains access the cross-domain resources of static.shanyue.tech
foo.shanyue.tech
Is returned in the response headerAccess-Control-Allow-Origin: foo.shanyue.tech
bar.shanyue.tech
Is returned in the response headerAccess-Control-Allow-Origin: bar.shanyue.tech
Everything looks fine, but what if there’s a cache in the middle?
foo.shanyue.tech
Is returned in the response headerAccess-Control-Allow-Origin: foo.shanyue.tech
Is cached by CDNbar.shanyue.tech
, returned in the response header due to the cacheAccess-Control-Allow-Origin: foo.shanyue.tech
A cross-domain problem occurs
At this point, Vary: Origin comes into play, representing caching different resources for different Origin
Summary (Brief answer)
How does CORS specify multiple domain names?
Set the access-Control-allow-Origin response header based on the Origin in the request header
- Always set
Vary: Origin
To avoid CDN cache damage to CORS configuration - If the request header does not carry
Origin
, if no cross-domain is proved, no processing is done - If the request header contains
Origin
, proving browser access across domains, according toOrigin
Set the correspondingAccess-Control-Allow-Origin: <Origin>
Using pseudocode, the implementation is as follows
// Get the Origin header
const requestOrigin = ctx.get('Origin');
ctx.set('Vary'.'Origin')
// If not, skip it
if(! requestOrigin) {return await next();
}
// Set the response header
ctx.set('Access-Control-Allow-Origin', requestOrigin)
Copy the code
Related questions: How to avoid CDN caching mobile pages for PC
07 Since the CORS configuration can do cross-domain control, can it prevent CSRF attacks
07 Since cORS configuration can do cross-domain control, can it prevent CSRF attacks
It doesn’t help CORS at all
- Form submissions do not pass CORS detection. You can test them locally
- Even through
xhr
及fetch
Commit is blocked by CORS,But for simple requests, the request is still sent, has caused an attack
08 How do I Avoid CDN Caching Mobile Pages for the PC
08 How to avoid CDN caching mobile pages for PC
This problem does not occur if PC and mobile are the same code. This problem occurs when PC and mobile are two sets of code, but share the same domain name.
Use nginx configuration as follows, according to UA to determine whether mobile terminal, and follow different logic (determine whether mobile terminal is prone to problems)
Location / {// default PC root /usr/local/website/web; # UA, access to the mobile end if ($http_user_agent ~ * "(Android | webOS | the | the | BlackBerry)") {root/usr/local/website/mobile; } index index.html index.htm; }Copy the code
Solutions typically use the Vary response header to control the CDN’s caching of different request headers.
Here you can useVary: User-Agent
, indicating that if the User-Agent is different, the request is re-initiated instead of reading the page from the cache
Vary: User-Agent
Copy the code
Of course, if there are too many user-agents, there will be too many cache invalidation.
Short answer
Vary: user-Agent is used to cache by UA.
Vary: User-Agent
Copy the code
However, it is best not to do this. If there are two sets of codes for PC and mobile, it is recommended to use two domain names for the following reasons
nginx
Determine whether the mobile terminal is prone to error- Not cache friendly
09 How to implement single and double row fringe style of table
09 How to implement single and double row stripe style in the table
Through cSS3 pseudo-class :nth-child to achieve. Nth-child (an+b) matches subscript {an+b; n = 0, 1, 2, … } and the result is a child of an integer
nth-child(2n)
/nth-child(even)
: Double line stylenth-child(2n+1)
/nth-child(odd)
: Single-line style
Where tr represents rows in the table, it is easy to implement a single or double row style in the table:
tr:nth-child(2n) {
background-color: red;
}
tr:nth-child(2n+1) {
background-color: blue;
}
Copy the code
In the same way:
- How to match the first three child elements:
:nth-child(-n+3)
- How to match the last three child elements:
:nth-last-child(-n+3)
10 Brief CSS Specificity
Communicate and discuss in Issue: 10 CSS Specificity
CSS Specificity refers to the weight of a CSS selector. The following three types of selectors decrease in sequence
id
Selectors, such as#app
class
,attribute
与pseudo-classes
Selectors, such as.header
,[type="radio"]
与:hover
type
Tag selectors and pseudo-element selectors, such ash1
,p
和::before
Where wildcard selector *, combinatorial selector + ~ >, negative pseudo-class selector :not() has no effect on priority
Codepen :not has no effect on the priority of the selector
Module. exports: exports
What is the difference between module. Exports and exports in 11 nodes
In a word:exports
是 module.exports
Ifexports
Without reassignment, there is no difference
Similar to the following
const exports = module.exports
Copy the code
How can the following result be derived?
module.exports = 100
exports = 3
Copy the code
Exports obviously export 100, after all exports are reassigned.
How does that work in the Node source code? The essence of exports can be seen from the source code
See source: github.com/nodejs/node… , you can see that it fits the conjecture
As you know, all module code in Node is wrapped in this function
(function(exports, require, module, __filename, __dirname) {
exports.a = 3
});
Copy the code
Where did exports come from
const dirname = path.dirname(filename);
const require = makeRequireFunction(this, redirects);
let result;
// The essence of exports can be seen here
const exports = this.exports;
const thisValue = exports;
const module = this;
if (requireDepth === 0) statCache = new Map(a);if (inspectorWrapper) {
result = inspectorWrapper(compiledWrapper, thisValue, exports,
require.module, filename, dirname);
} else {
// here is the module wrapper function
result = compiledWrapper.call(thisValue, exports, require.module,
filename, dirname);
}
Copy the code
12 How to Obtain the Number of Online Users (Concurrent Users) in the Current System?
More description: Some SaaS systems will limit the number of team members and the number of concurrent online users based on Pricing considerations. How to achieve this
12 How to obtain the number of online users (concurrent users) in the current system
Some SaaS systems limit the number of team members and the number of concurrent online users based on pricing strategies. How to achieve this?
The number of concurrent users can be realized by redis zset.
When a user requests any interface, a Middleware implementation handles the following logic
// When a user accesses any interface, write zset to that user Id
await redis.zadd(`Organization:${organizationId}:concurrent`.Date.now(), `User:${userId}`)
// Query the number of concurrent requests in the current organization
Check the number of concurrent requests by querying active users within a minute, and throw a specific exception if the number exceeds that
const activeUsers = await redis.zrangebyscore(`Organization:${organizationId}:concurrent`.Date.now() - 1000 * 60.Date.now())
// Check the number of concurrent requests
const count = activeUsers.length
// Delete expired users
await redis.zrembyscore(`Organization:${organizationId}:concurrent`.Date.now() - 1000 * 60.Date.now())
Copy the code
conclusion
- Each time a user accesses the service, the user’s ID is written to the priority queue with the weight being the current time
- Calculate the number of users of the organization within a minute based on the weight (i.e., time)
- Delete users that have expired for more than a minute
13 How to convert JSON data to Demo. json and download the file
13 how to convert JSON data to demo.json and download the file
Json is treated as a string and can be downloaded using the DataURL
Text -> DataURL
In addition to using the DataURL, you can also convert it to an Object URL for downloading
Text -> Blob -> Object URL
You can paste the following code directly into the console download file
function download (url, name) {
const a = document.createElement('a')
a.download = name
a.rel = 'noopener'
a.href = url
// Trigger the mock click
a.dispatchEvent(new MouseEvent('click'))
/ / or a.c lick ()
}
const json = {
a: 3.b: 4.c: 5
}
const str = JSON.stringify(json, null.2)
DataURL -> DataURL
const dataUrl = `data:,${str}`
download(dataUrl, 'demo.json')
// Text -> Blob -> ObjectURL
const url = URL.createObjectURL(new Blob(str.split(' ')))
download(url, 'demo1.json')
Copy the code
conclusion
- Simulation download, you can create a new one
<a href="url" download><a>
Tag and seturl
及download
Properties to download - You can do this by putting
json
intodataurl
To construct the URL - You can do this by putting
json
convertBlob
Again intoObjectURL
To construct the URL
14 How do I listen to clipboard content in the browser
14 How do I listen to clipboard content in the browser
The Clipboard API allows you to access Clipboard contents, but you need to obtain clipboard-read permission. Here is the code for reading Clipboard contents:
// Can read the clipboard permission
// result.state == "granted" || result.state == "prompt"
const result = await navigator.permissions.query({ name: "clipboard-read" })
// Get the clipboard contents
const text = await navigator.clipboard.readText()
Copy the code
Note: This method does not take effect in DevTools
Related questions: [Q019] How to implement the function of selected copy
Pay attention to my
My name is Shanyue and I am dedicated to answering one of the most frequently asked interview questions in five minutes each day.
Welcome to pay attention to the public account [Internet Big factory recruitment], regularly push big factory internal promotion information and brief answers to interview questions, learn five minutes a day, half a year into the big factory