1. What problems can Node solve?

The primary goal of Node is to provide a simple development tool for creating high-performance servers. The bottleneck of Web servers is the number of concurrent users (the browser often receives requests from clients and forwards them to our server), compared to Java and Php implementations

Draw a picture :(traditional Java or tomcat server)



A thread is a unit of a process (a process consists of many threads). The process is larger than the thread

For example, if we have one or more clients accessing our server at the same time (common servers are Tomcat and IIS), the characteristics of such servers are: multithreading; The execution space of the server is usually called: process;) When our client sends a request to our server, our server will open a so-called thread to cooperate, this thread is equivalent to a space, this space will send requests to our background (database, common mysql database, including other databases), in this case, The server is going to forward this request to mysql for our data, and then the thread is dead, you know, if it doesn’t get the result from the database, it’s stuck. It such as to a client to access our server, the request again, come again a thread put forward this request to our database, this operation generally called IO operation (operating more than database data), that this time, found a problem, the client sends the request, the more the more threads, thread processing generally very quickly, for instance, Database after the request is successful, the results back, that this thread is closed, used to be like that, but now this thread will not shut down, now the tomcat transformation strategy, he will make this thread for reuse, for example, the default open 20 thread, a client sends a request, the server and then open a thread, but the threads will not be destroyed, The next time the request is made, the thread comes out again, and it always reuses one thread.

But if it’s multithreaded:

  1. May waste resources (open one thread for one client request, waste one resource)
  2. Multithreading relies on switching time slices, which can also waste resources
  3. Multithreaded locks

These multithreading problems can occur on a traditional Java or Tomcat server, so here are the benefits of Node:

Draw a graph :(node)



Graphic: Node features: Single-threaded (single thread didn’t lock the concept, does not operate the same data at the same time), what he called a single-threaded application is not to say that we in a thread, he said, referring to the main thread (the main thread is a single thread), which means an application (processes) may be a main thread, which means it article may also have a lot of inside thread, such as other threads, Like setTimeout, setTimeout is also a thread, but setTimeout is not in our main thread, and the benefits of setTimeout are: For example, we have a client to visit our server, the server at this time to open a thread to match, and to access the database, but the node has a characteristic: asynchronous non-blocking, that is to say, it will not wait for the database when it finished, he only tell the client what data you want, and then it just idle down. He will not wait for the database to return the result to our client, for example: Go up to a client access server, a client is no matter, and then move the thread one directly to the below, this time, if there are a lot of clients to access servers, only need to access the database server, no need to wait for the database returns as a result, know the database is beginning to return results, the thread 1 data go back again to return to a client. So Node can handle tens of millions of concurrent connections, whereas Java can only handle 40 or 50 million, which is a huge difference in performance.

Node has significant performance advantages in high concurrency,I/O intensive scenarios

  • High concurrency refers to concurrent access to the server at the same time
  • I/O intensive refers to the file operation, network operation, database, the relative CPU intensive,CPU intensive refers to the logical processing operation, compression, decompression, encryption, decryption

2. What is Node?

Node.js is based on Chrome V8 Node is not a language that allows JavaScript to run at the back end of the runtime, and does not include the full set of JavaScript because it does not include DOM and BOM in the server. Node also provides some new modules such as HTTP and FS modules. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, and Node.js’s package manager, NPM, is the largest open source library ecosystem in the world.

3. Processes and threads

A process is the basic unit used by an operating system to allocate resources and schedule tasks (an application may be a process). A thread is a unit used to run a program once built on a process. The best analogy is our browser, a browser is multi-process.

3.1 Draw a picture: Talk about browsers



  • User interface – includes address bar, forward/back buttons, bookmark menu, etc
  • Browser engine – passes instructions between the user interface and the rendering engine (the main process of the browser)
  • Rendering engine, also known as browser kernel (browser rendering process)
  • One plug-in for one process (third-party plug-in process)
  • GPU Improves web browsing experience (GPU process)

So the browser is multi-process, and from our point of view we care more about the browser rendering engine

User interface, browser engine, and browser rendering engine are all processes. What we care most about when we write code is the browser’s rendering engine, which is divided into: Networking (requests), Javascript Interperter (JS threads), AND UI Backend (CSS rendering). Networking, Javascript Interperter, and UI Backend are all threads. We care about two threads: JS thread and UI thread. The relationship between these two threads is as follows:

thread

  • JS thread UI thread: These two threads run on the browser at the same time, but there is a difference: the two threads are mutually exclusive. The purpose is to ensure that there is no conflict, because the UI thread renders the DOM and the JS thread manipulates the DOM. So the JS thread executes, the UI thread doesn’t execute; The UI thread executes, the JS thread does not.
  • While the JS thread is executing, the UI thread may render again, so where does the render result go? At this point, the UI thread will queue the changes, and when the JS thread is idle, the UI thread will continue rendering.

Webworker multithreading *

  • The main thread can control the Webworker. The Webworker can’t manipulate dom and can’t get document or window

Write a short example of webworker:



       





3.2 Rendering Engine

The rendering engine is multi-threaded internally, containing the two most important threads, the UI thread and the JS thread. It is important to note that the UI thread and the JS thread are mutually exclusive, because the results of the JS run affect the results of the UI thread. UI updates are stored in the queue and executed as soon as the JS thread is idle.

3.3 JS single thread

Javascript was originally designed to be single-threaded, so why not multi-threaded? Wouldn’t it be confusing if multiple threads were manipulating the DOM at the same time? By single-threaded I mean that the main thread is single-threaded, so in Node the main thread is still single-threaded.

3.4 Other Threads

  • The browser event trigger thread (used to control the event loop and hold setTimeout, browser events, ajax callback functions)
  • Timer trigger thread (setTimeout timer thread)
  • Asynchronous HTTP request thread (Ajax request thread)


4. Event Loop in your browser



  • 1. All synchronization tasks are executed on the main thread, forming an execution stack
  • 2. In addition to the main thread, a task queue exists. Whenever an asynchronous task has a result, an event is placed in the task queue.
  • 3. Once all synchronization tasks in the execution stack are completed, the system reads the task queue and puts the events in the queue into the execution stack for execution
  • 4. The main thread reads events from the task queue in a continuous loop

This whole mechanism is called an Event Loop


Diagram: The event loop is divided into several parts. Js is divided into two parts, one is called heap, one is called stack; Objects are placed in the heap, common base types and functions are placed in the stack, and functions are executed on the stack as they are executed. There may be some Dom manipulation, Ajax manipulation and setTimeout timer in the stack. The applications in the stack go first and then go back. The WebAPIs are executed and the results of the execution are placed in the callback queue. That is, when the applications in the stack are finished, the events are read from the task queue and executed in the stack. The process is continuous.

Small Example 1:



Log (1), console.log(2), and console.log(5) are executed on the stack. SetTimeout may be called in the stack, but it must be executed in one time. The setTimeout methods are not executed, and are first moved to the callback queue, and then, when the stack is complete, start to read events from the task queue and execute them in the stack.

Lesson 2:



Log (1), console.log(2), and console.log(5) are executed on the stack. SetTimeout may be called in the stack, but it must be executed in one time. The setTimeout methods are not executed, and will be moved to the callback queue. After 1, 2, and 5 are executed, the setTimeout methods will be read from the task queue and executed in the stack. At this point, 3,4 will be executed, and 6,7 will be queued. It reads the event from the task queue and executes it on the stack. So the order is 1,2,5,3,4,6,7

If setTimeout is set, it is executed according to the success times of setTimeout, as shown in figure 1,2,5,4,7,3,6. Whenever two sets of time are different, the set with a short time (including the callback function in the set) is completed, and the set with a slow time is completed. If the time of two sets is the same, the callback in the set is executed in sequence.



Tip 3: When a callback function is triggered, it is placed in a queue. It is always done in the stack and then read the event from the task queue and execute it in the stack.




The difference between stack and queue:

Stack method LIFO (Last In First Out) : advanced Last Out (advanced Last Out), typically function calls.

Such as:



Code chart:



The first place in the stack is the global scope (code execution has a global text environment), then one. After one, I put two in, after two, I put three in, layer upon layer. So how did it get out? How did it get destroyed? => The first one to go must be three, because if two is destroyed first, then the code B of three will not be available, so it is first in and last out (advanced and last out), so three is first out, then two, and then one.

Queue method FIFO (First In First Out)

(head of team) [1,2,3,4] (back of team) enter from the back of the team 1,2,3,4 and exit from the head of the team 1,2,3,4




The code execution is done as a result of the stack, but when we call the multi-threaded methods (WebAPIs), these multi-threaded methods are queued, which means that the methods that were queued first are executed first. When will methods in WebAPIs be implemented again? = > such as: When the stack is finished, it will execute the queue methods, and when another event is written to the stack, that event may also call the asynchronous methods in WebAPIs, and those asynchronous methods will be placed in the queue when called again, and then the main thread (the stack) will read the event from the task queue. The process is continuous.

5. The Node system

Node doesn’t work like an event loop in a browser. Node has its own mechanism. Let’s start with a picture of how Node works



  • 1. The JS code we write will be handed over to the V8 engine for processing
  • 2. NodeApi may be called in the code, and Node is handed over to the Libuv library
  • 3. Libuv implements asynchronous I/O through blocking I/O and multithreading
  • 4. In an event-driven way, put the result into the event queue and finally deliver it to our application.

Node features: Asynchronous non-blocking I/O nodes use the LIBUV library to implement their own asynchronism. By default, there are no asynchronous methods.

Illustration: The v8 engine provides methods such as setTimeout for the v8 engine’s methods. The V8 engine also calls the nodeAPI. The common nodeAPI has readFile, which is asynchronous. When the nodeAPI is called, it hands the method to the LIBUV library, which uses BLOCKING and WORKER THREADS, so node is multithreaded at the bottom. It implements asynchronous I/O based on BLOCKING OPERATION and WORKER THREADS, and finally returns the result to our application through the EVENT LOOP. It will put the successful result in the EVENT QUEUE, and it will also call the result in the EVENT QUEUE and return it to our application.

6. Synchronous and asynchronous

Synchronous and asynchronous focus on message notification mechanisms

  • Synchronization is when you make a call, it doesn’t return until you get the result, and once it returns, you get the value back. In short, the caller actively waits for the result of the call
  • Asynchronous, on the other hand, returns no result after the caller makes the call. In other words, when an asynchronous procedure call is made, the caller does not get the result immediately. Instead, after the call is made, the caller processes the call through status, notification, or callback functions.

7. Blocking and non-blocking

Blocking and non-blocking are concerned with the state of the program while it waits for the result of the call (message, return value).

  • A blocking call means that the current thread is suspended until the result of the call is returned. The calling thread does not return until it gets the result.
  • A non-blocking call does not block the current thread until the result is not immediately available.

Combination of 8.

Synchronous asynchrony depends on the caller, blocking non-blocking depends on the caller

  • A synchronized block
  • Asynchronous blocking
  • Synchronous nonblocking
  • Asynchronous non-blocking (Node is asynchronous non-blocking)

9. Macro and micro tasks (often asked in interviews)



Synchronous code executes first and executes on the stack, and then microtasks execute first and then macro tasks

Tasks can be divided into macro tasks and micro tasks

  • Macro-task: setTimeout, setInterval, setImmediate, I/O
  • NextTick, native Promise(some implemented promises put then methods in macro tasks),Object.observe(deprecated), MutationObserver incompatible

Promise.then (source code see Promise use setTimeout), then methods should not be placed in macro tasks (source code setTimeout is mandatory), in our real browser implementation this then is microtasks. As shown in figure:



Console.log (1), where the new Promise() is executed immediately, is synchronous, and the then is executed after console.log(2), so it is not synchronous. What does this have to do with macro tasks and micro tasks? => We can add a setTimeout (macro task) for comparison, as shown in the figure:



Conclusion: Synchronous code executes first and executes on the stack, then microtasks execute first and then macro tasks

MutationObserver





10. When should you consider using the Node framework

When an application needs to handle a large number of concurrent inputs and outputs, the application does not need to do very complex processing before responding to the client.

  • Chat server
  • E-commerce sites