School recruitment front-end interview frequently asked questions [5] - front-end framework and common tools

School recruitment front-end interview frequently asked questions [5] - front-end framework and common tools

Written in front:

All the interview questions have been sorted out and shared on GitHub. Welcome to star.
Address: https://github.com/shadowings-zy/front-end-school-recruitment-question

React

Q: Please briefly describe the concept of virtual DOM?

When developing based on React, all DOM construction is carried out through virtual DOM. Whenever the data changes, React will rebuild the entire DOM tree, and then React compares the current entire DOM tree with the previous DOM tree to obtain the DOM structure. difference, and then do an actual browser DOM update of only the parts that need to change.

When React builds the DOM, it uses javascript objects to simulate the DOM. The overhead of comparing js objects is much smaller than that of browser DOM.

Q: Please briefly describe the life cycle of React?

react life cycle

Q: Please briefly describe the concept of React Fiber?

In scenarios where there are many page elements and frequent refreshes are required, React 15 will experience frame drops. So why is there a frame drop problem? The root cause is that a large number of synchronous computing tasks block the browser's UI rendering. By default, JS operations, page layout, and page drawing all run on the main thread of the browser, and they are mutually exclusive. If the JS operation continues to occupy the main thread, the page cannot be updated in time. When we call setState to update the page, React will traverse all the nodes of the application, calculate the difference, and then update the UI. If there are many elements on the page, the entire process may take more than 16 milliseconds, and frame drops are prone to occur. The reason is that React 15 traverses the entire component tree recursively.

react16 changed the data structure of the underlying update unit to a linked list structure. The previous coordination algorithm is a recursive call, which recurses through the stack formed by the react dom tree-level relationship. Fiber is a data storage structure of a flat linked list. Child is used to find the first child node, return is used to find the parent node, and sibling is used to find sibling nodes. Traversal changed from recursion to loop.

This is a major update of React's core algorithm, rewriting React's reconciliation algorithm. The reconciliation algorithm is the algorithm used to update and render the DOM tree. Previous versions of React 15.x used an algorithm called "stack reconciliation", which is now called "fiber reconciler".

The main feature of fiber reconciler is that it can split the update process into small units for update, and it can be interrupted to perform high-priority tasks or browser animation rendering, etc., and continue when the main thread is idle Perform an update.

For the problem of fluency, we can easily think of an api: requestldleCallback. This api can execute callbacks when the browser is idle. If we divide complex tasks into pieces and execute them when the browser is idle, it will not affect the rendering of the browser, etc. Work. This can solve the rendering delay caused by complex tasks occupying the main thread for a long time.

But maybe due to compatibility considerations, the react team abandoned this api and used requestAnimationFrame and MessageChannel pollyfill to create a requestIdleCallback

The current frame first performs tasks such as browser rendering, and if the current frame still has free time, execute the task until the time of the current frame runs out. If there is no free time in the current frame, it will wait until the free time of the next frame to execute.

Q: When is React setState?

When using setState, the data will not be updated directly, but will be directly hung in the update queue.
The timing of the update is: after the current macro task ends and before the micro task starts.

this.state = {
    
    
  a: 1,
}

// 这种情况只会+1,因为它相当于Object.assign(oldState, {count: XXX}, {count: XXX})
this.setState({
    
     count: this.state.count + 1 })
this.setState({
    
     count: this.state.count + 1 })

console.log(this.state.count) // 这时候会取到原来的state,也就是1

// 进行改造,这样就一定会+2了
this.setState((state, props) => {
    
    
  return {
    
     count: state.count + 1 }
})
this.setState((state, props) => {
    
    
  return {
    
     count: state.count + 1 }
})

Vue

Q: What is the mvvm pattern?

M: Model => data, business logic, validation logic, and models often contain business logic.
V: view => interactive interface, which is a visual presentation of model data, and the view may contain display logic.
VM: The middleman between the view and the model.

Two-way binding of data: the change of V is directly reflected on the VM, and the change of M is also directly reflected on the VM.

Q: Please briefly describe the principle of vue responsive data?

The key to responsive data is: how data updates view, and how view updates data.

1. View update data can be monitored through events, such as input tag monitoring 'input' event can be achieved.

2. The point of data update view is how to know that the data has changed. At this time, we Object.defineProperty()set a set function for the property, and this function will be triggered when the data changes, so we only need to put some methods that need to be updated here to realize the data update view.

Specific usage of Object.defineProperty:

Object.defineProperty(obj, prop, descriptor)
obj:要在其上定义属性的对象。
prop:要定义或修改的属性的名称。
descriptor:将被定义或修改的属性描述符。

descriptor 具有以下两种可选值:
get:给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入 this 对象。
set:给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。

A simple example of responsive data:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>defineProperty</title>
  </head>
  <body>
    <div id="app">
      <input type="text" id="txt" />
      <p id="show"></p>
    </div>

    <script>
      let obj = {
      
      }

      Object.defineProperty(obj, 'txt', {
      
      
        get: function () {
      
      
          return obj
        },
        set: function (newValue) {
      
      
          document.getElementById('txt').value = newValue
          document.getElementById('show').innerHTML = newValue
        },
      })
      document.addEventListener('keyup', function (e) {
      
      
        obj.txt = e.target.value
      })
    </script>
  </body>
</html>

Q: Please briefly describe the life cycle of Vue?

Vue life cycle

Q: Please briefly describe the principle of Vue router?

Vue router has two modes: hash mode and history mode, corresponding to two principles:

hash mode:

hash("#")符号的本来作用是加在 URL 指示网页中的位置,例如:
http://www.example.com/index.html#print

#本身以及它后面的字符称之为 hash 可通过 window.location.hash 属性读取。
hash 虽然出现在 url 中,但不会被包括在 http 请求中,对服务器端完全无用,因此,改变 hash 不会重新加载页面。

我们可以为 hash 的改变添加监听事件:
window.addEventListener("hashchange",funcRef,false)

每一次改变 hash,我们都会重新注入对应的组件,就可以来实现前端路由"更新视图但不重新请求页面"的功能了。

history mode:

从HTML5开始,History interface提供了2个新的方法:pushState(),replaceState()使得我们可以对浏览器历史记录栈进行修改。

window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)

stateObject: 当浏览器跳转到新状态时,触发popState事件,该事件将携带stateObject参数的副本
title: 所添加记录的标题
URL: 所添加记录的URL

我们可以为window.history的改变添加监听事件:
window.addEventListener("popstate",funcRef,false)

在监听事件中,重新注入对应的组件,就可以来实现前端路由"更新视图但不重新请求页面"的功能了。

用 HTML5 实现,单页路由的 url 就不会多出一个#,变得更加美观。但因为没有 # 号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求,可能会造成404。

packaging tool

Q: Tell me about webpack?

webpack is a module packaging tool. In webpack, all files are modules, and what webpack can do is to package them together.

Webpack mainly has the following common attributes during configuration:

1. entry and output:
The entry point indicates which module webpack should use as the start of building its internal dependency graph. After entering the entry point, webpack will find out which modules and libraries the entry point depends on (directly and indirectly).

The output attribute tells webpack where to output the bundles it creates, and how to name these files. The default value is ./dist. Basically, the entire application structure, will be compiled into a folder in the output path you specify. You can configure these processes by specifying an output field in the configuration.

const path = require('path')
module.exports = {
    
    
  entry: './path/to/my/entry/file.js',
  output: {
    
    
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js',
  },
}

2. loader:
loader allows webpack to process those non-JavaScript files. The loader can convert all types of files into valid modules that webpack can handle, and then you can use webpack's packaging capabilities to process them.
Essentially, the webpack loader turns all types of files into modules that the application's dependency graph (and ultimately the bundle) can directly reference.

const path = require('path')
const config = {
    
    
  module: {
    
    
    rules: [{
    
     test: /\.txt$/, use: 'raw-loader' }],
  },
}

3. Plugins:
Compared with loaders, plugins can be used to perform a wider range of tasks, such as compression and packaging, optimization, etc. To use a plugin, you just require() it and add it to the plugins array.

const HtmlWebpackPlugin = require('html-webpack-plugin') // 通过 npm 安装
const webpack = require('webpack') // 用于访问内置插件
const config = {
    
    
  module: {
    
    
    rules: [{
    
     test: /\.txt$/, use: 'raw-loader' }],
  },
  plugins: [new HtmlWebpackPlugin({
    
     template: './src/index.html' })],
}

Guess you like

Origin blog.csdn.net/u011748319/article/details/119894867