Node file lookup rule

If no js file is added, find the file with the same name. If no js file is added, find the file with the same name. If no js file is added, find the file with the same name, find the file with the same name

Browser Event loop and Node Event loop

  • Generally speaking, macro tasks are executed first. In the process of executing micro tasks and script, callback tasks are put into queues first, which can be divided into macro task queue and micro task queue. Each macro task, has its corresponding micro task, after the script has been completed, check if there is a task in the micro task first, so, just empty task queue, and then from acer task queue to retrieve a task execution, execution, found this macro task the task, just put the micro tasks detail task queue, macro task execution is completed, Look at the microtask queue again, empty the microtask, and the browser’s event loop keeps doing this

  • The event loop execution rules for Node are similar to those for browsers, but Node has multiple macro task queues, where process.nextTick is at the bottom of the execution stack. Script -> Timer (setTimeout) -> Poll (I/O call-outs) -> Check (setImmediate)

Eg:

const fs = require('fs') fs.readFile('./a.txt', 'utf-8', () => { setTimeout(() => { console.log('--------------------------time 0---'); }, 0) setTimeout(() => { console.log('--------------------------time 1---'); }, 1000) setImmediate(() => { console.log('---------------------immediate--------'); }) process.nextTick(() => { console.log('---------------------nexttick--------'); }) new Promise((resolve, reject) => { resolve('ok') }).then((data) => { console.log('----------------------promise-------', data); Nexttick PROMISE immediate time 0 time 1Copy the code
setTimeout(() => { console.log('--------------------------time 0---'); }, 0) setTimeout(() => { console.log('--------------------------time 1---'); }, 1000) setImmediate(() => { console.log('---------------------immediate--------'); }) process.nextTick(() => { console.log('---------------------nexttick--------'); }) new Promise((resolve, reject) => { resolve('ok') }).then((data) => { console.log('----------------------promise-------', data); }) // Nexttick promise time 0 immediate time 1Copy the code

Promise to realize promispromisify

const fs = require('fs') function promisify(fn) { return function (... args) { return new Promise((resolve, reject) => { fn(... args, (err, data) => { if (err) return reject(err) resolve(data) }) }) } } const readFile = promisify(fs.readFile) readFile('./1p.js', 'utf-8').then((data) => { console.log('-----------------------------', data); })Copy the code

Way of inheritance

  • prototype.proto
Function A1(){} function A2(){} function A2(){} function A2().__proto__ = A1Copy the code
  • Object.setPrototypeOf(obj, prototype)

The principle of pipe

Rely on on(‘data’)/on(‘drain’) and encapsulate the implementation at the bottom

const fs = require('fs'); const ws = fs.createWriteStream('./c.txt', { highWaterMark: 2, }) let i = 0; function write() { let flag = true; While (I < 10 && flag) {flag = ws.write(I ++ ++ '')}} ws.on('drain', () = > {the console. The log (' -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- memory full -- -- -- -- -- - '); write() }) write()Copy the code

The tree

Binary tree

The node is less than or equal to 2

Binary search tree

In accordance with the characteristics of binary trees, the left node is smaller than the right node

Class Node {constructor(element,parent) {this.element = element; this.parent = parent; this.left = null; this.right = null; } } class Tree { constructor() { this.root = null; Return this.root = new Node(element, null)} add(element) {if (this.root === null) {return this.root = new Node(element, null)} CurrentNode = this.root let parent; let compare; while (currentNode) { parent = currentNode compare = currentNode.element < element if (compare) { currentNode = currentNode.right } else { currentNode = currentNode.left } } let node = new Node(element, parent) if (compare) { parent.right = node } else { parent.left = node } } } let tree = new Tree(); ,8,19,6,15,22,20 [10]. ForEach (item = > {tree. The add (item)}); console.dir(tree, {depth: 200});Copy the code

The first sequence traversal

About the root

 preTraverse() {
    function traverse(node) {
        if (node === null) return 
        console.log('-----------------------------', node.element);
        traverse(node.left)
        traverse(node.right)
    }
    traverse(this.root)
}

Copy the code

In the sequence traversal

Left root right

centerTraverse() {
    function traverse(node) {
        if (node === null) return 
        traverse(node.left)
        console.log('-----------------------------', node.element);
        traverse(node.right)
    }
    traverse(this.root)
}
Copy the code

After the sequence traversal

About the root

nextTraverse() {
    function traverse(node) {
        if (node === null) return 
        traverse(node.left)
        traverse(node.right)
        console.log('-----------------------------', node.element);
    }
    traverse(this.root)
}
Copy the code

Breadth traversal

The core is to put the current node on the stack, find the left and right children of the stack each time, and then use the pointer to point to the next node in sequence [1]. The pointer first finds 1 and finds that 1 has 1,2 children, and then puts 1 and 2 on the stack. The pointer adds 1 to point to 2 [1,2,3]. The pointer points to 3 [1,2,3,4,5] until the tree is traversed

LeverTraverse () {let stack = [this.root] // Let index = 0 let currentNode while (currentNode = stack[index++]) { console.log('---------currentNode--------------------', currentNode.element); if (currentNode.left){ stack.push(currentNode.left) } if (currentNode.right){ stack.push(currentNode.right) } } }Copy the code

Inversion of binary trees

Reverse () {let index = 0 let currentNode while (currentNode = stack[index++]) { console.log('---------currentNode--------------------', currentNode.element); let temp = currentNode.left currentNode.left = currentNode.right currentNode.right = temp if (currentNode.left){ stack.push(currentNode.left) } if (currentNode.right){ stack.push(currentNode.right) } } }Copy the code

Computer network

Osi seven layer model

  • Physical layer: network cables and optical fibers transmit data, representing 0,1
  • Data link layer: data is transferred between devices and data frames are connected (MAC addresses)
  • Network layer: Addressing, finding MAC addresses by IP (IP segment)
  • Transport layer: Because the transmission at the network layer is not reliable, TCP connections must be established at the transport layer to ensure the reliability of data transmission (TCP packets).
  • Session layer: Establishes sessions
  • Presentation layer: data representation, security, etc
  • Application layer: the interface that the user ultimately accesses

In practice, the session layer, presentation layer and application layer are combined into one layer, thus forming a 5-layer model

tcp

  • Transmission control protocol: reliable, inefficient, two-way data transmission
  • The maximum length of a data frame is 1500
  • The maximum header length is 60 bytes and the minimum header length is 20 bytes
  • The first 20 bytes of an IP protocol
  • So a TCP packet can transmit up to 1460 bytes
  • TCP protocol composition
    • Three times handshake
    • 4 disconnections (because the data may be still being sent during disconnection, so it cannot be truly disconnected. Only when the data is sent can it be truly disconnected)
    • Sliding window The receiver’s window is larger than the sender’s. Once the receiver’s window is used up, the sender sends a probe to ask if the receiver’s window is available
    • Congestion Handling If the receiving side has an unlimited window size and can send AN ACK packet after receiving data, the transmission of data depends mainly on the network bandwidth, but the network bandwidth is limited
      • Slow start
      • Congestion avoidance
      • Fast retransmission When packet loss occurs, do not immediately return to the slow start phase. The receiver confirms the lost packet to the sender three times, and the sender resends the lost packet (retransmission).
      • Fast recovery

http

  • Up to 6 simultaneous HTTP requests for a domain name (depending on browser)
  • One HTTP requires one TCP handshake and multiple HTTP requests need to be repeated to establish three handshakes, because simultaneous requests will have the problem of head blocking
  • Http2 establishes only one TCP connection, compresses the header, but does not solve the problem of queue header blocking

The HTTP status code

  • 2
    • 200 success
    • 204 Succeeded but did not return
    • 206 Fragment Transmission
  • 3
    • 301 permanent redirect
    • 302 Temporary redirect
    • 304 the cache
  • 4
    • 400 Parameter Error
    • 401 User rights (not logged in)
    • 403 logged in, no access
    • 404 can’t find
    • 405 The client request method is not supported by the server
    • 416 The requested scope is invalid
  • 5
    • 500 The server has an internal error and could not complete the request
    • 502 Invalid response from request broker
    • 504 Gateway error, timeout, no response
    • 505 The HTTP version is not supported

HTTP request methods

Restful style, realize resource add,delete, change, check, get, POST, PUT,delete

  • Get: There is no request body
  • Post: Theoretically there is no limit to the size of data, which is safer than GET

The HTTP message

Request: Request line, request header, request body Response: response line, response header, response body

The HTTP request demo

const http = require('http'); const server = http.createServer((req, res) => { const url = req.url console.log('---------------------url--------', url); // get has no request body. The post, Buffer let chunk = [] req.on('data', (data) => { chunk.push(data) console.log('----------------data-------------', data.toString()); }) // Req.on ('end', () => { let data = Buffer.concat(chunk) console.log('---------------------end-data--------', data.toString()); Res.setheader (' content-type-custom ', '1234') res.write('server') res.end('end')}) server.listen(3000, () = > {the console. The log (' -- -- -- -- -- -- -- -- -- -- - the connection is successful -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- '); })Copy the code

Options request (cross-domain)

Get. Post is a simple request by default, but if it defines the header information, it will become a complex request

Common cross-domain solutions? Jsonp, IFrame, CORS backend configuration (common), Nginx reverse proxy (common), Websoket,

What happens when you send a URL to a web parser

According to the domain name -> get IP (DNS domain name resolution) -> Establish a connection (TCP) -> IP find MAC address (network layer) -> devices transfer data to each other

Stage summary

flow

The main solution is to read large files, streams can specify the location of the file to read, improve efficiency

  • Pattern classification of flows
    • Readable stream on(‘data’) on(‘end’) push()[Trigger data event]
    • The ws.write() ws.end() argument can only be a string or buffer
    • Socket. Write socket. End socket. On (‘data’)
    • Transform stream transform for example pipe.rs.pipe (ws)

Stack/queue/linked list/tree

  • Stack: First in last out
  • Queue: First in, first out
  • Linked list: There is mainly a head node, which is continuously pointed to the next node through next
  • Tree: mainly a binary tree, the core is a root node, then pointing to the left and right nodes, and finally can get the information of the whole tree

File operations

  • Fs. mkdir Creates a directory
  • Fs.rmdir Deletes a directory
  • The fs.stat() file status determines whether it is a directory or a file
  • Fs. readdir Reads the directory
  • Fs.unlink () deletes a file

The cache

Strong cache

If you request resources through the browser, the first request will not be cached, but the subsequent processing can be cached. After setting strong caching, you will not request resources from the browser, but from the browser’s cache

Cache-control no- Cache sends requests to the server every time, and the Cache is also cached to the browser, but invalidates the strong Cache. Cache-control no-store Sends requests to the server every time, but does not Cache them to the browser, invalidates the Cache

Res.setheader (' cache-control ', 'max-age=10') // New Date(date.now () + 10 * 1000).togmtString ()) // before 1.1Copy the code
const http = require('http'); const path = require('path'); const url = require('url'); const mime = require('mime'); const fs = require('fs'); const fsp = fs.promises const {createReadStream} = fs const server = http.createServer(async (req, Res) => {const {pathName} = url.parse(req.url) const filePath = path.join(__dirname,'public',pathname) // Try {// Set res.setheader (' cache-control ', 'max-age=10') // after 1.1 res.setheader ('Expires', New Date(date.now () + 10 * 1000).togmtString ()) //1.1 前 const fileInfo = await fsp.stat(filePath) if (fileinfo.isfile ())  { res.setHeader('Content-Type', mime.getType(filePath)+'; Charset = utF-8 ') createReadStream(filePath).pipe(res)} else {// Find index. HTML const indexPath = in directory Path. join(filePath,'index.html') // Check whether the file exists try {await fsp.access(indexPath) res.setheader (' content-type ', 'text/ HTML; charset=utf-8') createReadStream(indexPath).pipe(res) } catch(e) { console.log('-----------------------------', e); res.statusCode = 404 res.end('not found') } } } catch (err) { console.log('----------------------------e-', err); res.statusCode = 404 res.end('not found') } }) server.listen(3000, () => { console.log('server start'); })Copy the code

Negotiate the cache

  • ‘Cache-Control’, ‘no-cache’

Make strong cache invalidation, the requested resource for the first time, the server will tell the client resource modification time, after the client request resources, will take the last time, the service side to then the server than the last modified time and request are consistent with the time, don’t agree, return the existing resources, agree, do not return resources, Let the client use the browser’s cached resources

const ctime = fileInfo.ctime.toGMTString() res.setHeader('Last-Modified', ctime) if (req.headers['if-modified-since'] === ctime) { res.statusCode = 304 res.end() } else { res.setHeader('Content-Type', mime.getType(filePath)+'; charset=utf-8') createReadStream(filePath).pipe(res) }Copy the code
const http = require('http'); const path = require('path'); const url = require('url'); const mime = require('mime'); const fs = require('fs'); const fsp = fs.promises const {createReadStream} = fs const server = http.createServer(async (req, Res) => {const {pathName} = url.parse(req.url) const filePath = path.join(__dirname,'public',pathname) // Try {// Set res.setHeader(' cache-control ', 'no-cache') const fileInfo = await fsp.stat(filePath) const ctime = fileInfo.ctime.toGMTString() res.setHeader('Last-Modified', ctime) if (fileInfo.isFile()) { if (req.headers['if-modified-since'] === ctime) { res.statusCode = 304 res.end() } else { res.setHeader('Content-Type', mime.getType(filePath)+'; Charset = utF-8 ') createReadStream(filePath).pipe(res)}} else {// Find index. HTML const indexPath = in directory Path.join (filePath,'index.html') // Check whether the file exists try {await fsp.access(indexPath) if (req.headers['if-modified-since'] === ctime) { res.statusCode = 304 res.end() } else { res.setHeader('Content-Type', 'text/html; charset=utf-8') createReadStream(indexPath).pipe(res) } } catch(e) { res.statusCode = 404 res.end('not found') } } } catch (err) { console.log('----------------------------e-', err); res.statusCode = 404 res.end('not found') } }) server.listen(3000, () => { console.log('server start'); })Copy the code

Last-modified determines whether the requested resource should be updated according to the modification time of the file. The file should be Modified first and then restored. In this way, the content of the file does not change, but the time will change. When the browser requests a resource, the server resends it, invalidating the cache.

  • Etag
const http = require('http'); const path = require('path'); const url = require('url'); const mime = require('mime'); const crypto = require('crypto'); // md5 digest/encrypt const fs = require('fs'); const fsp = fs.promises const {createReadStream} = fs const server = http.createServer(async (req, Res) => {const {pathName} = url.parse(req.url) const filePath = path.join(__dirname,'public',pathname) // Try {// Set res.setHeader(' cache-control ', 'no-cache') const fileInfo = await fsp.stat(filePath) if (fileInfo.isFile()) { const fileContent = await fsp.readFile(filePath) const etag = crypto.createHash('md5').update(fileContent).copy().digest('base64') if (req.headers['if-none-match'] === etag) { res.statusCode = 304 res.end() } else { res.setHeader('Etag', etag) res.setHeader('Content-Type', mime.getType(filePath)+'; Charset = utF-8 ') createReadStream(filePath).pipe(res)}} else {// Find index. HTML const indexPath = in directory Path.join (filePath,'index.html') // Check whether the file exists try {const fileContent = await fsp.readFile(indexPath) const etag = crypto.createHash('md5').update(fileContent).copy().digest('base64') await fsp.access(indexPath) if (req.headers['if-none-match'] === etag) { res.statusCode = 304 res.end() } else { res.setHeader('Etag', etag) res.setHeader('Content-Type', 'text/html; charset=utf-8') createReadStream(indexPath).pipe(res) } } catch(e) { res.statusCode = 404 res.end('not found') } } } catch (err) { console.log('----------------------------e-', err); res.statusCode = 404 res.end('not found') } }) server.listen(3000, () => { console.log('server start'); })Copy the code

It is used to determine whether a file has changed by comparing the contents of the file. However, comparing large files consumes resources, so it is used to compare the size of the file or extract part of the content for comparison.

Cookie Session localStorage sessionStorage difference

  • cookie
    • Server Settings, client presence, each request will be carried automatically, poor confidentiality
    • Cookie size is limited, about 4K, too large pages may be blank, and also waste traffic
    • Domain Takes effect for the specified domain name. .baidu.com. A.baidu.com can access baidu.com cookie
    • Path What path can I access cookies
    • Expires /max-age Specifies the expiration time
    • The httpOnly browser cannot get cookies from code
    • Secure takes effect only in HTTPS mode
  • session
    • Stored on the server
    • Sessions are based on cookies, which are more secure than cookies
  • token
    • JWT does not require server storage and has no cross-domain restrictions