Revisit long-forgotten interview questions

Whoa whoa whoa. . . While wiping tears, while transcribing, the interview questions that have long been forgotten need to be remembered in the middle of winter. . .

vue

vue custom directive

  • Through custom instructions, we can extend the behavior of Vue to add additional features and events when rendering DOM elements, so as to better fulfill business needs
  • Vue custom instructions are divided into two types: global instructions and local instructions (in-component instructions)
  • Global directives will be registered on Vue.directive and can be used globally, while local directives can only be used within components

The following is an example of a global custom directive: Register a global custom directive named v-focus
Register a global custom directive named v-focus, and implement the inserted hook function, when the directive is bound When the element is inserted into the DOM, the hook function will be called to realize the focus function of the element

Vue.directive("focus",{
   // 当绑定元素插入到DOM中执行
   inserted:function(el){
       //聚焦元素
       el.focus()
   }
})

Here is an example of a partial custom directive: Define a partial custom directive named v-highlight inside the component

export default {
    derectives:{
        highlight:{
            //当绑定元素插入到DOM中时执行
            inserted:function(el){
                //添加样式类
                el.classList.add("highlight")
            },
            //当绑定元素从DOM中移出时执行
            unbind:function(el){
                //移除样式类
                el.classList.remove("highlight")
            }
        }
    }
}

The difference between hash routing and history routing in Vue

hash模式
    在hash模式下,路由路径会带有一个#符号
    hash模式的路由通过监听 window.location.hash的变化来进行路由切换。
    hash模式的好处是兼容性较好,可以在不支持HTML5 History API的浏览器中正常运行
    缺点是URL中带有#符号,不够美观
History模式:
    在history模式下,路由路径不带有#符号
    history模式利用HTML5 HitoryAPI中的pushState和replaceState方法来实现路由切换
    history模式的好处是URL更加美观,没有#符号
    缺点是兼容性较差,需要在服务器端进行配置,以防止在刷新页面时出现404错误
Application of Custom Instructions in Permission Control
  1. You can control whether certain buttons or rows and columns in the table are visible, editable, and deleteable according to the user's role information. At
    this time, you can implement such permission control through custom commands.
  2. Define a global custom command named v-permission, and implement the bind hook function, in which the
    role information of the current user is used to determine whether the user has the permission of the element, if not, hide the element
    below is a sample code :
//定义一个名为v-permission的全局自定义指令
Vue.directive("permission",{
    //bind 钩子函数只在指令第一次绑定到元素时执行一次
    //如果需要对指令的绑定值进行响应式的操作,应该在update钩子函数中进行
    bind:function(el,binding,vnode){
        //获取当前登录用户的角色信息
        const currentUser = getUserInfoFromLocalStorage().role;
        //获取绑定的值
        const {value} = binding
        //判断当前用户是否有该按钮的权限
        if(value&&value.length&&!value.includes(currentUser)){
            el.style.display = "none";  //隐藏该元素
        }
    }
})


<button v-permission="['admin','superAdmin']">Delete</button>

Dynamic Routing for Vue

Vue中的动态路由是指在路由中使用参数来匹配路径的一种方式,通过动态路由,我们可以轻松实现页面参数传递和多个类似页面的复用
{
    path:'/user/:id',
    name:'user',
    component:User
}
:id表示该路由是一个动态路由,所以其被称为参数,它的值会被传递给User组件进行处理

The role of Vue's key

A key is an attribute used to uniquely identify a node. When Vue renders Dom, it will judge whether it needs to re-render according to the key of the node.
When Vue finds that the key of the node has changed. It will remove the node from the DOM tree, and then recreate a new node and insert it into the appropriate position, which can reduce the number of DOM operations and improve rendering performance.

Router routing guard

An important feature in Router that allows developers to perform some control and validation logic when navigating to a route or leaving the current route. Vue Router provides three different types of routing guards at global level, routing level and component level, including:

  1. The global front guard beforeEach is used to verify whether the user is logged in or not and other global controls
  2. The global resolution guard beforeResolve is used to be called after the global pre-guard and before the component is rendered
  3. The global after hook afterEach is used to clean up after the route is completed
  4. The route-exclusive guard beforeEnter is used to verify before entering a specific route
  5. The guards beforeRouteEnter, beforeRouteUpdate and beforeRouteLeave inside the component are used to handle the internal control logic of the page

    javascript

    Event Loop

    Event loop (Event Loop) is a mechanism for processing asynchronous tasks. It is part of the js runtime and is used to manage and schedule the execution order of tasks.
    In js, tasks can be divided into two types:
    1. Synchronous tasks: execute in sequence according to the order of the code until the execution is completed
    2. Asynchronous tasks: will not be executed immediately, but will be executed at a certain time in the future. Asynchronous tasks usually involve network requests, timers, event listeners, etc.
    The event loop works as follows:

1 执行同步任务,直到遇到第一个异步任务。
2 将异步任务放入相应的任务队列(如宏任务队列,微任务队列)中。
3 继续执行后续的同步任务,直到执行栈为空。
4 检查微任务队列,如果有任务则按顺序执行所有的微任务。
5 执行宏任务队列中的一个人物
6.回到第三步,重复以上步骤

In each event loop, all microtasks are executed first, and then a macrotask is executed. Such a mechanism guarantees the execution order of asynchronous tasks and can respond to user interactions in a timely manner.
Common macro tasks include setTimeout, setInterval, network requests, etc., while micro tasks include Promise, MutationObserver, etc.
Understanding the actual loop is very important to write efficient asynchronous code, it can help us process tasks reasonably and avoid blocking the main thread.

Scope chain:

  • Each function in js has its own scope,
  • When a variable is referenced inside a function, js will search upwards from the current scope in the order in which it appears in the code
  • Until the first scope containing this variable is found, this process is called scope chain lookup
  • If the entire scope chain is not found, it will report an error and throw a ReferenceError exception
function outer(){
    const a = 10
    function inner(){
        console.log(a);
        console.log(b);//Uncaught: ReferenceError:b is not defined
    }
    inner()
}
outer()

Several ways to add 0 when the minute and second are less than 10 in js when changing the time

const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = seconds % 60;

1 使用ES6模版字符串
padStart指定字符串的长度,如果不满,则在前面补上自己定义的字符串
`${h.toString().padStart(2,'0')}:${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}`

2 使用三元运算符
(h<10?"0"+h:h)+ ":" + (m<10?"0"+m:m)+":"+(s<10?"0"+s:s)

3 使用Array.map和Array.join方法

const timeArr = [h,m,s].map(value=>{
    return value <10?"0"+value:value
})
timeArr.join(":")

What happens when we enter a URL in the browser address bar

1. DNS resolution: The browser will check whether it has a cache, if there is an IP address corresponding to the domain name, it will be used directly, otherwise it will initiate a request to DNS
2. Initiate an Http request, and the browser will initiate a response to the server according to the protocol header of the URL At the same time, the browser will also send some request headers and request parameters.
3. Establish a TCP connection: Before the HTTP request is established, the browser needs to establish a TCP connection with the server. TCP is a connection-oriented, reliable, word-based The throttling transmission protocol ensures that the data can be
sent to the server accurately and reliably through a three-way handshake without data loss or disorder.
4. Send HTTP requests. After the TCP connection is established, the browser can send The server sends an HTTP request message. The HTTP request message includes the request header, the request line, and the request body
. 5. Accept the response message from the server: When the server receives the request message, it will parse the request, and then return the corresponding response message to the client. The HTTP response message includes three parts: status line, response header and response body, where the status line contains the result status code of the request.
6. Parsing and rendering the page: When the browser receives the response message returned by the server, it will parse out the corresponding DOM tree, CSS rule tree and javascript according to the content in the corresponding message (such as HTML, CSS, javascript and other resources). code
and build a render tree from them. Finally, these contents are handed over to the browser's rendering engine for rendering to generate the page we finally see.
7. Disconnect the TCP connection. When the browser receives the response message returned by the server, it will close the connection and release resources. If the browser needs to request more resources, it needs to re-establish a new TCP connection

How to reduce reflows and repaints

Reflow and redraw are two key steps in the browser rendering process.
Reflow refers to the process in which the browser calculates the position and size attributes of elements and re-layouts the page.
Redrawing refers to redrawing the appearance of elements according to the style attributes of elements.
Reflowing and redrawing are performance-consuming operations, so reducing reflowing and redrawing can improve page performance and responsiveness

1. 批量修改样式:避免对元素的样式属性进行频繁的单独修改,而是尽量将多个样式的修改合并为一个操作。可以使用Css类名的方式一次性地修改多个样式属性。
2. 使用文档片段:如果需要通过js动态地插入一系列元素,可以先将它们添加到文档片段(Document Fragment)中,然后再一次性的讲文档片段添加到文档中,这样可以减少重排的次数。
3. 避免频繁读取布局信息,当获取元素的位置、大小等布局信息时,尽量避免在每次操作中都去读取这些信息,而是将其缓存起来,以减少重排的次数
4. 使用CSS3动画和过渡:CSS3动画和过渡是基于浏览器的硬件加速,可以减少重绘和重排的开销。尽量使用CSS3动画和过渡来实现动画效果,而不是使用js来操作样式属性。
5. 使用requestAnimationFrame: 使用requestAnimationFrame来执行动画可以更好的与浏览器的重绘机制结合,减少不必要的重绘和重排操作
6. 避免频繁的DOM操作:DOM操作会导致重排和重绘,尽量避免频繁的对DOM进行增删改操作,可以先将需要操作的DOM元素从文档中移除,进行批量操作后再重新插入。
7. 使用css布局工具:使用Css的flexBox和Grid等布局工具可以更好地控制页面布局,减少重排的次数。

import and require are two different modularization specifications of js

  1. The new modular syntax in ES6 when the usage is different
    import is used to introduce the exported objects of other ES6 modules in the code. It is a top-level statement
    that can only appear in the outermost layer of js code or other similar top-level positions, and cannot be used in other code blocks. import {debounce} from "lodash"
    require is a modular syntax in the CommonJS specification, used in code Introduce the exported object of the CommonJS module, which can be used anywhere, including inside the function or inside the code const debounce = require("lodash/debounce")
  2. The loading timing is different.
    The import will be processed when the code is edited, so the corresponding module has been loaded before the code is executed. This allows import to be statically analyzed before the code runs, thereby optimizing at build time
    require is loaded at runtime, which means that when require is used in the code, it will load the module when the code is executed , and returns its exported object as the result
  3. The syntax
    of import is relatively concise, and the namespace separation and deconstruction of modules can be performed. At the same time, it also supports asynchronous loading of modules

    //引入lodash模块中的debounce方法并重命名为myDebounce
    //解构  只导出需要的内容,减少导出对象的大小
    import {debounce as myDebounce} from "lodash"
    import * as myModule from "./model.js" //命名空间分离   通过一个对象承载模块的所有导出内容。从而实现命名空间分离
    //使用异步函数动态引入模块
    const someAsyncModule = await import ('./path/to/module')

The syntax of require is relatively complicated, especially when multi-layer path nesting is required. It cannot perform namespace separation, nor does it support the destructuring syntax in ES6. At the same time, modules cannot be loaded asynchronously, requiring additional libraries or manually writing asynchronous loading logic

In short, if you need to use new features in Es6 or load modules asynchronously, use import, and if you need to be compatible with node or CommonJS environments, you can use require

Use of WebSockets

WebSocket is a protocol for full-duplex communication between a web browser and a server. It provides more powerful real-time data transmission capabilities. Compared with the traditional HTTP request-response mode, WebSocket allows the server to actively push data to the client, realizing true two-way communication.

//创建WebSocket连接   得到一个Websocket对象,url是websocket服务器的地址
const socket = new WebSocket("ws://example.com/socket")

监听事件: WebSocket对象支持多个事件,如`open`,'message',"error"和'close'。通过给WebSocket对象添加对应的事件监听器函数,
可以处理连接打开、接收到消息、出现错误和连接关闭等情况
// 监听连接打开事件
socket.addEventListener("open",event=>{
    console.log("WebSocket 连接已打开");
})
// 监听接受到消息事件
socket.addEventListener("message",event=>{
    console.log("收到消息",event.data);
})
// 监听连接错误事件
socket.addEventListener("error",error=>{
    console.log("WebSocket 错误:",error);
})

//监听连接关闭事件
socket.addEventListener("close",event=>{
    console.log("Websocket 连接已关闭");
})

//发送消息 send(data)方法可以向服务器发送消息。服务器接收到消息后,可以通过‘message’ 事件监听器处理。
//客户端可以使用event.data获取服务器发送的消息内容
socket.send("Hello,Websocket")

//关闭连接:当不再需要连接时,可以使用WebSocket对象的close方法来关闭连接
socket.close()

The WebSocket connection requires server support, and the server needs to implement the corresponding WebSocket protocol to handle the connection and message transmission.
In actual use, you can use the ws module such as Node.js or the Websocket framework to implement server-side functions

Microtasks and macrotasks and usage scenarios

Microtasks and macrotasks are mechanisms used to manage the execution order of js asynchronous tasks. They determine the order in which tasks are executed in the event loop.
Microtasks are task queues provided by the js engine. Its execution priority is higher than that of macro tasks. Common microtasks include Promise callback functions, MutationObserver and progress.nextTick macro tasks are task queues provided by browsers. Its
execution The priority is low, common macro tasks include timer setTimeout, setinterval, DOM event callback and Ajax request, etc.

scenes to be used:

Scenarios for using microtasks:
1. For tasks that need to be executed at the end of the current event loop, you can use microtasks, such as the callback function of Promise.
2 For tasks that need to be executed immediately, you can use microtasks, such as MutationObserver to monitor DOM changes and respond immediately

Scenarios for using macro tasks:
1. For tasks that need to be delayed, you can use macro tasks, such as timer callback functions.
2 Tasks that need to be executed in the next cycle of the event cycle can use macro tasks, such as DOM time callbacks and Ajax requests

In an event loop, when all macro tasks are executed, all micro tasks will be executed first, and then the next macro task will be executed, which can ensure that the priority of micro tasks is higher than that of macro tasks, ensuring timely response and Update
To sum up, microtasks and macrotasks are mechanisms used to manage the execution order of asynchronous tasks. The execution priority of microtasks is higher than that of macrotasks, and is suitable for processing tasks that need to be executed immediately or at the end of the current loop. Macro tasks are suitable for processing tasks that need to be delayed or executed in the next cycle

Some common features and syntax in ES6

  1. let and const keywords
  2. arrow function
  3. destructuring assignment
  4. spread operator
  5. Classes and Inheritance
  6. template string
  7. promises and async/await
  8. Modular
    Symbol, Map, Set, Proxy, Reflect

React

The difference between Vue and React

In five aspects:

  1. Template syntax:
    Vue uses HTML template syntax to write component templates, which is relatively easy to understand and learn, allowing developers to quickly write pages. The advantage of this is that the HTML and JavaScript codes are separated,
    which is conducive to the maintainability and readability of the code. Vue's template syntax also provides some powerful functions, such as conditional rendering, loop rendering, event handling, etc.
    React respects: everything is javascript, it uses jsx syntax, that is, a mixed syntax of Javascript and Xml, using jsx can easily Create complex UI more efficiently, and improve the performance of the application,
    but colleagues who use jsx, you need to learn more syntax and programming paradigms
  2. Data binding
    Vue provides the function of two-way data binding, which can realize the automatic synchronization of views and data, which greatly facilitates data management and operation. Two-way binding consists of two parts: the data model and the view model. In Vue, the data model is the data in the component instance; the view model is responsible for binding the data in the data model to the view.
    The data flow of React is one-way. It adopts the transfer and management data of props and State between components, passes attribute values ​​to components through props, and listens to the change event of this attribute to update the UI to realize the one-way flow of data
    ; The state is the place to save the internal state of the component. It is mutable data. It is recommended to use immutable data as much as possible under appropriate circumstances.
  3. Component classification
    Vue divides components into two types: stateful components and stateless functional components. Stateful components contain the logic and data in the application and can achieve more complex operations and interactions; stateless components only provide a corresponding UI Interface, without data and logic processing, is usually used for widgets or pure display components. Vue's components have lifecycle functions that can perform different processing logic at different stages of the component.
    React does not have a strict component classification, but usually divides components into two types: functional components and class components. A functional component is a pure javascript function that accepts a props object as a parameter and returns a React element, which does not support state and life cycle functions; a class component uses object-oriented programming to build components and supports state and life cycle functions. So React components also have a life cycle, which can perform related operations in different stages of the component.

  4. Both Vue and React have their own lifecycle functions, and call these functions in different component phases . Vue's life cycle functions include created, mounted, updated, and destroyed, and each function has a specific purpose and function.
    React's life cycle functions include componentWillMount, componentDidMount, shouldComponentUpdate, componentWillUnmount, etc., which also have their own characteristics and uses.
    Lifecycle functions can be used to solve a series of problems and logic in the process of component mounting, updating, destroying, etc.
  5. rendering efficiency

Vue uses technologies such as virtual DOM and asynchronous rendering to improve the performance of the program. Virtual DOM abstracts the real DOM into js objects, which can be compared and calculated quickly, thereby reducing the performance loss caused by DOM operations; asynchronous rendering
is Allows the browser to render components during idle time, thus improving rendering efficiency.
React uses an algorithm called reconciliation to update the UI without re-rendering the entire number of components, which also makes React have high rendering efficiency.
When the component is updated, React will update the UI by comparing the changes of the virtual DOM, thus avoiding a large number of DOM operations

Both Vue and React are excellent front-end frameworks, which adopt different implementation methods and are suitable for different development scenarios. Vue pays more attention to development experience and ease of use, suitable for rapid development of small and medium-sized applications; React pays more attention to application maintainability and performance, suitable for large-scale applications or applications that require better scalability. Which framework to choose depends on the needs of the project and the preferences of the team

Webpack

webpack-tree-shaking

摇树(tree Shaking)是指在打包过程中,通过静态分析的方式,去掉没有使用的代码,从而减小最终打包后的文件体积

在Webpack中摇树是通过ES6模块化语法和静态分析工具(如UglifyJS)来实现的。
当Webpack打包时,它会分析模块之间的依赖关系,并且检查哪些代码被实际使用了,哪些去除掉没有被使用的代码

摇树的原理是基于ES6模块化的静态特性,它可以在编译时进行静态分析,因为ES6模块化的导入和导出是静态的,而CommonJS模块化的导入和导出是动态的

要实现摇树,需要满足以下条件:
1 使用ES6模块化语法进行导入和导出
2 代码中的导入必须是静态的,不能使用动态导入
3 代码中的导出必须是静态的,不能使用动态导出

当满足这些条件时,Webpack在打包的过程中会自动进行摇树优化,去掉没有使用的代码,从而减小打包后的文件体积
需要注意的是,摇树只能去掉没有使用的代码,而不能去除没有被导入但被使用的代码。

What does webpack do when npm run dev

当你运行npm run dev命令时,webpack会执行一系列的操作来构建和打包你的项目。
1. 根据配置文件(通常是webpack.config.js),webpack会读取配置中的入口文件(entry)和出口文件(output)的路径信息。
2. 根据入口文件的路径,webpack会分析项目的依赖关系,找到所有需要打包的模块。
3. webpack会根据配置中的加载器(loader)对模块进行处理。加载器可以将非js文件(如css,图片等)转换为js模块,或者对js模块进行预处理(如使用Babel进行ES6转换)
4. webpack会根据配置中的插件(plugin)对模块进一步的处理。插件可以用于优化打包结果、拓展webpack的功能等。
5. webpack会根据配置中的出口文件路径和文件名,将打包后的模块输出到指定的目录中
6. 在开发模式下,webpack会启动一个开发服务器( dev server),并监听文件的变化,当文件发生变化时,webpack会自动重新构建并刷新浏览器
7 webpack 还会生成一个包含构建信息的统计文件,可以用于分析打包结果、性能优化等

In general: when webpack runs npm run dev, it will build and package the project according to the configuration file, and provide the development server and automatic compilation function, which is convenient for developers to debug and develop in real time

webpack cache

Webpack provides a caching mechanism that can improve construction performance through caching. The caching mechanism of webpack has two aspects:

  1. Loader cache:
    During the webpack build process, Loader can use cache to improve performance.
    Loader cache can avoid repeated processing of the same file, thereby speeding up the build.
    Enable Loader caching by setting cache:true, for example:

     module:{
         rules:[{
             test:/\.js$/,
             use:'babel-loader',
             options:{
                 cacheDirectory:true
             }
         }]
     }
  2. Module cache:
    During the webpack construction process, Webpack will generate a unique identifier (hash) based on the content of the module.
    If the content in the module has not changed, Webpack will reuse the previous build results to avoid rebuilding the module, thereby Improve build speed.
    The Module cache is based on the file, and will only be rebuilt when the file content changes. The
    Module cache is enabled by default, and you can set cache:true to show that the cache is enabled.
    By using Loader cache and Module cache, Webpack can avoid repeated processing and build unchanging modules, thereby improving the performance and speed of the build.
    It should be noted that the caching mechanism will only take effect when the content of the file found during the construction process has not changed. If the content of the file changes, Webpack will rebuild the entire module and dependency tree.

TypeScript

How to add a new type in ts

There are several ways to create new types in ts:

1. 类型别名(Type Alias):
    使用type 关键字创建一个类型别名,可以给现有类型起一个新的名字
    例如: type myType = string|Number;
2.接口(interface):
    使用interface 关键字创建一个接口,用于定义一个对象的结构。
    例如interface MyInterface{name:string;age:number;}
3.类(Class):
    使用class 关键字创建一个类,用于定义一个对象的结构和行为。
    例如: class MyClass{name:string;age:number}
4.枚举(Enum):
    使用enum关键字创建一个枚举类型,用于定义一组具名的常量值。
    例如:enum MyEnum{A,B,C}

The difference between any and unknown

In Typescript, both any and unknown are used to represent uncertain types, and both represent arbitrary types, but there are some differences between them:

1 可赋值性:
    any 类型可以赋值给任何类型,也可以从任何类型中获取值
    unknown类型只能被赋值给unkown和any类型,不能直接从中获取值。
2 类型检查和类型判断:
  any类型的变量不会进行类型检查,编译器不会对其进行类型推断或类型检查。
  unknow类型的变量在编译器中会进行类型检查,使用之前必须进行类型检查或类型断言
3 方法和属性的调用:
  any类型的变量可以调用任何方法和属性,而不会报错。
  unknown类型的变量不能调用任何方法或属性,除非先进行类型断言或类型检查
4 类型安全性:
  使用any类型会丧失类型安全性,因为它可以接受任何类型的值。
  使用unkonw类型可以提供更好的类型安全性,因为在使用之前必须进行类型检查。
  因此,unkown类型相比于any类型提供了更好的类型检查和类型推断,以及更好的类型安全性,因此,尽量使用unkown

Guess you like

Origin blog.csdn.net/wangonik_l/article/details/131373221