前端面试练习24.3.4

目录

普通问题

说一说 严格模式和 非严格模式

关键词:

具体:

SSL/TLS加密

很基础的重点

什么是原型链,说说相关的理解

接下来阐述什么原型:

关系:

说一说你对闭包的理解

闭包的核心概念有三个要素:

闭包的主要特点包括:

拓展:实现链式调用

说一说call apply bind的作用和区别,能手写一个吗

call:

apply

bind

手写:

说一说new会发生什么,能手写一个吗

说一说promise是什么与使用方法

Promise的作用:

Promise使用:

Promise的特点:

加分回答 Promise的其他方法:

说一说axios的拦截器原理及应用

拦截器的应用场景:

拦截器的原理

拓展:

说一说创建ajax过程

创建:

创建 XMLHttpRequest 对象:

 设置请求参数:

 设置回调函数:

 发送请求:

 拓展:

为什么使用虚拟DOM,而不操作真实DOM

vue的diff理解

Virtual DOM:

Diff 算法:

节点比较:

子节点比较:

遍历比较:

Diff 算法的优化:

Key 值:

同层比较:

什么是diff算法

TCP的三四

TCP:

过程:

HTTP和HTTPS

浏览器输入URL之后发生了什么

1.URL解析

2.DNS解析

3.TCP连接

4.发送HTTP请求

5.服务器处理请求

6.服务器发送响应

7.客户端接收并渲染

8.绘制页面

9.TCP断开连接


普通问题

说一说 严格模式和 非严格模式

关键词:

严格模式的使用,this指向,一些报错(delete时),eval函数的影响,变量声明

具体:

严格模式的使用,要在代码文件或函数的开头添加 'use strict';使用后JS引擎会额外的执行一些语法和规则

 

严格模式的 this全局环境中调用指向的是 undefined,非严格就是window

严格模式下,一些写法会报错

// 非严格模式下
var x = 10;
//delete 操作符用于删除对象的属性或数组的元素
delete x; // 在非严格模式下,delete 操作符可能会默默失败,不会报错console.log(x); // 输出:10// 严格模式下
'use strict';var x = 10;
delete x; // 在严格模式下,delete 操作符会抛出异常console.log(x); // TypeError: Cannot delete property 'x' of #<Object>

严格模式下必须使用var let const关键字对变量声明,非严格可以不使用 var 关键字声明变量,隐式创建全局变量。

eval()函数 可以传入包含JS代码的字符串进行解析运行

非严格模式:eval 函数执行的代码在其执行位置的上下文中执行。

// 非严格模式下
var x = 10;function evalExample() {var y = 20;eval('var z = x + y;');console.log(z); // 输出:30,z 变量在 eval 函数内部创建,但是在 eval 函数外部可见
}evalExample();

严格模式:eval 函数执行的代码无法创建新的变量或者函数,并且执行环境被限制在 eval 函数内部。

// 严格模式下
'use strict';var x = 10;function evalExample() {var y = 20;eval('var z = x + y;');console.log(z); // 报错:ReferenceError: z is not defined,z 变量只存在于 eval 函数内部
}evalExample();

SSL/TLS加密

  1. 客户端发送支持的TLS版本和加密算法列表: 客户端向服务器发送一个Hello消息,包含支持的TLS版本和加密算法列表。

  2. 服务器选择TLS版本和加密算法: 服务器收到客户端的Hello消息后,选择与客户端相匹配的TLS版本和加密算法,并生成一个证书,包含服务器的公钥。

  3. 服务器发送证书给客户端: 服务器将包含公钥的证书发送给客户端。

  4. 客户端验证服务器证书: 客户端收到服务器的证书后,验证证书的有效性。这包括检查证书的签发机构是否受信任、证书是否过期、证书中包含的域名是否与实际域名匹配等。

  5. 客户端生成预主密钥并使用服务器公钥加密: 客户端生成一个随机的预主密钥,并使用服务器的公钥进行加密,然后将加密后的预主密钥发送给服务器。

  6. 服务器使用私钥解密预主密钥: 服务器收到客户端发送的预主密钥后,使用自己的私钥进行解密。

  7. 客户端和服务器生成主密钥: 客户端和服务器使用约定好的加密算法,以客户端发送的预主密钥和服务器解密后的预主密钥为输入,生成共享的主密钥。

  8. 客户端和服务器确认握手: 客户端和服务器互相发送消息,确认握手过程已经完成。

  9. 客户端和服务器开始安全通信: 客户端和服务器使用生成的主密钥进行安全通信,包括加密和解密数据。

很基础的重点

什么是原型链,说说相关的理解

首先要明白一点:原型存在于对象中的。

接下来阐述什么原型:

在js中,每个构造函数内部都有一个prototype属性,该属性的值是个对象,该对象包含了该构造函数所有实例共享的属性和方法。当我们通过构造函数创建对象的时候,在这个对象中有一个指针,这个指针指向构造函数的prototype的值,我们将这个指向prototype的指针称为原型。或者用另一种简单却难理解的说法是:js中的对象都有一个特殊的[[Prototype]]内置属性,其实这就是原型。

关系:

所有的引用类型(包括数组,对象,函数)都有隐性原型属性(proto), 值也是一个普通的对象。

所有的函数,都有一个 prototype 属性,值也是一个普通的对象。

所有的引用类型的proto属性值都指向构造函数的 prototype 属性值

所以得出以下 关系:

构造函数.prototype===原型

原型.constructor===构造函数

实例对象.__proto__===原型

说一说你对闭包的理解

闭包的核心概念有三个要素:
  1. 函数(Function):闭包是一个函数,它可以执行特定的代码逻辑。
  2. 函数定义时的环境(Environment):闭包还包含了在函数定义时所处的作用域中的变量。
  3. 函数返回值(Return Value):闭包可以返回一个函数或者值,这取决于函数的具体实现。
闭包的主要特点包括:
  1. 记忆状态:闭包可以记住定义时的上下文信息,即使在定义之后,这些上下文已经不再存在。
  2. 封装性:闭包将变量和函数绑定在一起,形成一个封闭的单元,避免了全局变量的污染。
  3. 延迟执行:闭包中的函数可以延迟执行,等待外部条件满足后再执行。

function outerFunction(x) {// 内部函数可以访问外部函数的参数和局部变量function innerFunction(y) {return x + y; // innerFunction 可以访问 outerFunction 的参数 x}return innerFunction; // 返回内部函数
}// 创建一个闭包
var closure = outerFunction(5);// 调用闭包,传入参数 3
var result = closure(3);console.log(result); // 输出:8
拓展:实现链式调用
function fun1(x) {let total = x;function sum(value) {total += value;return sum; // 返回自身以便链式调用}sum.toString = function () {return total;}return sum;
}console.log(fun1(1)(2)(3).toString()); // 输出 6

说一说call apply bind的作用和区别,能手写一个吗

call:

用来改变调用函数的this指向,后面可以紧跟参数,立即执行

function.call(newThis,arg1,arg2...)

apply

用来改变调用函数的this指向,区别在于传递的参数是数组形式,立即执行

function.apply(newThis,[arg1,arg2...])

bind

也可以用来改变函数this指向,但是,它是返回一个新的函数,需要我们后续手动再次调用。

// 示例函数
function greet(name) {console.log(`Hello, ${name}! My name is ${this.name}.`);
}// 创建一个对象作为上下文
const context = {name: 'John'
};// 使用 call() 方法调用函数,并指定上下文和参数列表
greet.call(context, 'Alice'); // 输出: "Hello, Alice! My name is John."// 使用 apply() 方法调用函数,并指定上下文和参数数组
const args = ['Bob'];
greet.apply(context, args); // 输出: "Hello, Bob! My name is John."// 使用 bind() 方法创建一个新的绑定函数
const boundGreet = greet.bind(context, 'Charlie');// 稍后调用绑定函数
// 此时David是第二个参数,不是name,如果要显示,需要在greet函数添加后续参数
boundGreet('David'); // 输出: "Hello, Charlie! My name is John."
手写:
// 手写实现 call 方法
Function.prototype.myCall = function(thisArg, ...args) {// 判断是否传入了有效的上下文,如果传入的上下文为 null 或者 undefined,则默认为全局对象(浏览器中为 window)thisArg = thisArg || window;// 将当前函数设置为传入的上下文的属性thisArg.__fn__ = this;// 调用函数const result = thisArg.__fn__(...args);// 删除临时属性delete thisArg.__fn__;return result;
};// 手写实现 apply 方法
Function.prototype.myApply = function(thisArg, argsArray) {thisArg = thisArg || window;thisArg.__fn__ = this;// 使用扩展运算符将数组展开为参数列表const result = thisArg.__fn__(...argsArray);delete thisArg.__fn__;return result;
};// 手写实现 bind 方法
Function.prototype.myBind = function(thisArg, ...args) {const fn = this;return function(...innerArgs) {return fn.apply(thisArg, args.concat(innerArgs));};
};

说一说new会发生什么,能手写一个吗

  1. 创建一个新的空对象。
  2. 将该空对象的原型链指向构造函数的原型对象(即 prototype 属性)。
  3. 将构造函数的执行上下文(this)绑定到这个新创建的对象。
  4. 执行构造函数内部的代码,以初始化新创建的对象。如果构造函数中有返回值,并且返回值是一个对象,那么这个对象将取代第一步中创建的新对象;如果返回值不是对象,则忽略这个返回值,返回第一步中创建的新对象。
  5. 如果构造函数没有返回值,那么会默认返回第一步中创建的新对象。

function myNew(constructor, ...args) {// 创建一个新的空对象,继承构造函数的原型对象const obj = Object.create(constructor.prototype);// 将构造函数的执行上下文绑定到新对象上,并执行构造函数const result = constructor.apply(obj, args);// 如果构造函数有返回值且返回值是对象,则返回这个对象;否则返回新创建的对象return typeof result === 'object' ? result : obj;
}// 示例构造函数
function Person(name, age) {this.name = name;this.age = age;
}// 使用 myNew 关键字创建实例
const person1 = myNew(Person, 'Alice', 30);
console.log(person1); // 输出: Person { name: 'Alice', age: 30 }

说一说promise是什么与使用方法

Promise的作用:

Promise是异步微任务,解决了异步多层嵌套回调的问题,让代码的可读性更高,更容易维护。

Promise使用:

Promise是ES6提供的一个构造函数,可以使用Promise构造函数new一个实例,Promise构造函数接收一个函数作为参数,这个函数有两个参数,分别是两个函数 resolverejectresolve将Promise的状态由等待变为成功,将异步操作的结果作为参数传递过去;reject则将状态由等待转变为失败,在异步操作失败时调用,将异步操作报出的错误作为参数传递过去。实例创建完成后,可以使用then方法分别指定成功或失败的回调函数,也可以使用catch捕获失败,thencatch最终返回的也是一个Promise,所以可以链式调用。

Promise的特点:
  1. 对象的状态不受外界影响(Promise对象代表一个异步操作,有三种状态)。

    • pending(执行中)
    • Resolved(成功,又称Fulfilled)
    • rejected(拒绝) 其中pending为初始状态,fulfilled和rejected为结束状态(结束状态表示promise的生命周期已结束)。
  2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。 Promise对象的状态改变,只有两种可能(状态凝固了,就不会再变了,会一直保持这个结果):

    • 从Pending变为Resolved
    • 从Pending变为Rejected
  3. resolve 方法的参数是then中回调函数的参数,reject 方法中的参数是catch中的参数

  4. then 方法和 catch方法 只要不报错,返回的都是一个fullfilled状态的promise

加分回答 Promise的其他方法:
  • Promise.resolve() : 返回的Promise对象状态为fulfilled,并且将该value传递给对应的then方法。

  • Promise.reject():返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法。

  • Promise.all():返回一个新的promise对象,该promise对象在参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。

  • Promise.any():接收一个Promise对象的集合,当其中的一个 promise 成功,就返回那个成功的promise的值。

  • Promise.race():当参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。

说一说axios的拦截器原理及应用

axios的拦截器可以在请求发送之前和响应返回之后进行处理,这样可以方便地对请求和响应进行统一处理,比如添加请求头、统一处理错误等。

拦截器的应用场景:
  1. 请求拦截器的应用场景

    • 在请求发送之前对请求进行处理,比如为每个请求添加相应的参数(如 token、时间戳等)。
    • 对请求进行统一的错误处理,比如请求超时、网络错误等。
    • 在发送请求前显示 loading 动画,请求完成后隐藏 loading 动画。
  2. 响应拦截器的应用场景

    • 在接收到响应后对响应进行处理,比如对返回的状态码进行判断,判断 token 是否过期。
    • 统一处理错误信息,比如处理后端返回的特定错误码。
    • 在接收到响应后隐藏 loading 动画,展示响应数据。
拦截器的原理

是通过创建一个数组(通常称为 interceptor chain,简称 chn),数组中保存了拦截器相应的方法以及 dispatchRequest 方法。

请求拦截器的方法会被放到 chn 数组的前面,

响应拦截器的方法会被放到 chn 数组的后面。

为了保证拦截器的执行顺序,需要使用 Promise 以出队列的方式对 chn 数组中的方法挨个执行。

一般来说,拦截器的执行顺序是这样的:

  1. 请求拦截器方法依次执行,按照定义顺序从前往后执行。
  2. dispatchRequest 方法执行。
  3. 响应拦截器方法依次执行,按照定义顺序从前往后执行。

拓展:

Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 Node.js 中。它具有以下特点:

  • 从浏览器中创建 XMLHttpRequests,从 Node.js 创建 HTTP 请求。
  • 支持 Promise API,使得使用异步请求更加方便和简洁。
  • 可拦截请求和响应,可以在发送请求之前或接收到响应之后对其进行处理。
  • 可转换请求数据和响应数据,例如,可以使用 JSON.stringify 将请求数据转换为 JSON 格式,使用 JSON.parse 将响应数据解析为 JavaScript 对象。
  • 可取消请求,当请求已经发送但未完成时,可以通过 cancelToken 取消请求。
  • 可自动转换 JSON 数据,无需手动解析 JSON 数据,Axios 会自动将 JSON 数据转换为 JavaScript 对象。
  • 客户端支持防御 XSRF(跨站请求伪造)攻击,可以通过配置 xsrfCookieNamexsrfHeaderName 来设置 XSRF 防御相关的选项。

说一说创建ajax过程

创建:
创建 XMLHttpRequest 对象

首先,需要创建一个 XMLHttpRequest 对象,用于发起 AJAX 请求。在现代浏览器中,可以直接使用 new XMLHttpRequest() 来创建 XMLHttpRequest 对象。

const xhr = new XMLHttpRequest();
 设置请求参数

在发送 AJAX 请求之前,通常需要设置一些请求参数,比如请求的 URL、请求的方法(GET、POST 等)、请求头、是否异步等。

xhr.open('GET', 'https://api.example.com/data', true);
xhr.setRequestHeader('Content-Type', 'application/json');
 设置回调函数

AJAX 请求是异步的,因此需要设置回调函数来处理请求的各个阶段,包括请求被发送、接收到响应、以及请求过程中发生的错误等。

xhr.onreadystatechange = function() {if (xhr.readyState === XMLHttpRequest.DONE) {if (xhr.status === 200) {console.log('请求成功,返回数据为:', xhr.responseText);} else {console.error('请求失败,状态码为:', xhr.status);}}
};
 发送请求

当所有参数都设置好之后,使用 send() 方法发送 AJAX 请求。

xhr.send();
 拓展:

POST请求需要设置请求头 readyState值说明

0:初始化,XHR对象已经创建,还未执行open

1:载入,已经调用open方法,但是还没发送请求

2:载入完成,请求已经发送完成

3:交互,可以接收到部分数据

4:数据全部返回

status值说明 200:成功 404:没有发现文件、查询或URl 500:服务器产生内部错误

为什么使用虚拟DOM,而不操作真实DOM

  1. 性能优化: 虚拟DOM可以批量更新和高效比较,减少了频繁操作真实DOM带来的性能损耗。通过比较虚拟DOM树和上一次渲染的虚拟DOM树的差异,可以最小化对真实DOM的操作,提高页面渲染的效率。

  2. 跨平台兼容性: 虚拟DOM可以使得框架或库在不同平台上运行时保持一致的行为,无需关心底层平台的DOM API差异。这样可以使得开发者更加专注于业务逻辑的实现,而不用考虑跨平台兼容性带来的问题。

  3. 简化复杂度: 直接操作真实DOM可能会涉及到复杂的DOM操作和手动维护DOM状态的问题。而虚拟DOM将复杂的DOM操作抽象为对虚拟DOM树的操作,简化了代码逻辑,提高了开发效率。

  4. 方便实现组件化: 虚拟DOM与组件化开发相结合,可以更方便地管理组件状态和组件间的通信。通过将组件状态存储在虚拟DOM树中,并通过比较虚拟DOM树的差异来更新组件状态,可以实现更灵活、可维护的组件化架构。

vue的diff理解

Vue 的 Virtual DOM 和 diff 算法是 Vue 实现响应式更新的核心机制之一。

Virtual DOM

在 Vue 中,每当状态发生变化时,Vue 会先生成一颗虚拟 DOM 树,即一个 JavaScript 对象表示的树形结构。这个虚拟 DOM 树会和上一次渲染时生成的虚拟 DOM 树进行对比,然后计算出最小的变更,并只对真实 DOM 进行最小化的修改,这样可以提高性能。

Diff 算法

Diff 算法是用来比较两棵树的算法,主要用于寻找变更并最小化变更操作的数量。Vue 中使用的是一种基于深度优先搜索的双端比较算法。它将新旧节点树进行逐层对比,并找出最少的变更来更新视图。

节点比较

对比两个节点的类型和 key(如果有),如果不同,则直接将旧节点替换为新节点。

子节点比较

对比子节点,会有以下几种情况:

子节点数量不同:直接替换子节点。

子节点相同位置的节点不同:递归对比子节点。

子节点顺序不同:尝试通过移动节点来匹配对应的位置。

遍历比较

递归地对比整棵树,找出需要更新的节点。

Diff 算法的优化

在实际应用中,为了进一步提高性能,Vue 在 Diff 算法中进行了一些优化:

Key 值

给每个节点设置一个唯一的 key 值,可以提高 diff 算法的性能,避免出现不必要的更新。

同层比较

在对比子节点时,Vue 会尽量保持节点的同层级比较,减少节点的跨层级移动,从而提高效率。

总的来说,Vue 的 diff 算法通过对比虚拟 DOM 树的变化来最小化 DOM 操作,从而提高渲染性能和用户体验。

什么是diff算法

Diff(差异化算法)是一种用于比较两个树形结构的算法,常用于前端框架中用于更新视图。在 Vue、React 等现代前端框架中,Diff 算法被用于比较虚拟 DOM 树的差异,从而高效地更新真实 DOM。

Diff 算法的基本原理是:通过比较两棵树的结构差异,找出最小的更新操作,然后将这些更新操作应用到真实 DOM 上,以实现视图的更新。

Diff 算法的目的是尽量减少更新操作的数量,从而提高渲染性能。在实际应用中,Diff 算法通常会结合一些优化策略,比如给每个节点添加唯一的 key 值、尽量保持同层级的比较等,以进一步提高性能。

TCP的三四

TCP:

TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议,它负责在通信的两个应用程序之间提供可靠的数据传输服务。

TCP连接分为三次握手与四次挥手。

过程:

三次握手:

第一次:客户端发送SYN(同步)报文段给服务器

第二次:服务器端接收到SYN后,返回SYN+ACK(同步+确认)报文段给客户端,表示收到了客户端的请求,并且请求连接,指定了自己的初始序列号。

第三次:客户端收到回复后,发送ACK(确认)报文段给服务器,表示收到请求,并且建立连接。

此时双端建立了双向的数据传输通道进行数据传输。

四次挥手:

第一次:客户端发送 FIN 报文段 给服务器端,表明自己完成了数据的发送

第二次:服务器端发送ACK(确认)报文段,表示自己接收到了客户端的结束请求。

第三次:服务器端发送 FIN 报文段,表明自己也已经发送完数据。

第四次:客户端发送ACK(确认)报文段,表明收到了服务器端的结束请求。

通过这样的四次挥手过程,客户端和服务器完成了连接的关闭,释放了资源,并且可以安全地终止连接。

HTTP和HTTPS

HTTP(超文本传输协议)和HTTPS(安全超文本传输协议)是用于在客户端和服务器之间传输数据的协议。它们有以下主要区别:

  1. HTTP:

    • HTTP是一种不安全的协议,数据在传输过程中是明文的,容易被窃听和篡改。
    • HTTP使用端口号80进行通信。
    • HTTP在网络中传输的数据不经过加密,因此不适合传输敏感信息,例如用户登录凭据、银行卡信息等。
  2. HTTPS:

    • HTTPS是在HTTP的基础上添加了SSL/TLS加密层的安全协议,通过加密通道来保护数据的传输安全。
    • HTTPS使用端口号443进行通信。
    • HTTPS采用公钥加密和私钥解密的方式,确保数据在传输过程中是加密的,不易被窃听和篡改。
    • 通过数字证书,HTTPS还能够验证服务器的身份,防止中间人攻击。

浏览器输入URL之后发生了什么

1.URL解析

浏览器首先解析输入的URL,提取出其中的协议(例如HTTP、HTTPS)、主机名、端口号(如果有)、路径以及查询字符串等信息。

(端口用来;标识网络应用,实现进程间通信,提供网络服务,提高网络安全)

2.DNS解析

浏览器会检查缓存中是否有与主机名对应的IP地址,如果没有,则会进行DNS解析,将主机名解析成IP地址。这个过程涉及向DNS服务器发送请求,并等待响应。

3.TCP连接

浏览器通过HTTP或HTTPS协议与Web服务器建立TCP连接。如果URL中使用的是HTTPS协议,则还需要进行SSL/TLS握手,确保通信安全。

4.发送HTTP请求

浏览器向Web服务器发送HTTP请求,请求中包括请求方法(如GET、POST)、请求头(如User-Agent、Accept)、请求体(如表单数据或JSON数据)等信息。

5.服务器处理请求

Web服务器接收到浏览器发送的HTTP请求后,会根据请求的URL和方法执行相应的处理。处理的具体过程可能包括读取文件、查询数据库、执行脚本等操作。

6.服务器发送响应

Web服务器根据处理结果生成HTTP响应,响应中包括状态码、响应头(如Content-Type、Content-Length)、响应体(如HTML、CSS、JavaScript代码)等信息。

7.客户端接收并渲染

浏览器接收到服务器的HTTP响应后,会根据响应的内容进行渲染。如果响应的内容是HTML文档,则浏览器会解析HTML、加载CSS、执行JavaScript,并将结果显示在页面上。

8.绘制页面

浏览器根据解析后的内容绘制页面,并将页面呈现给用户。这个过程涉及布局计算、渲染树构建、绘制等操作。

9.TCP断开连接

当页面加载完成后,浏览器会关闭与Web服务器建立的TCP连接,释放资源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/721593.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用conda安装rasa macbook亲测有效

要使用conda安装Rasa&#xff0c;你可以按照以下步骤进行操作&#xff1a; 首先&#xff0c;确保你已经安装了Anaconda或Miniconda&#xff0c;并且conda命令可以在终端或命令提示符中正常运行。 创建一个新的conda虚拟环境&#xff0c;专门为Rasa安装。这样做可以隔离Rasa及其…

租房招聘平台新篇章:Java+SpringBoot技术革新

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

ansible批量筛选出指定操作系统的主机列表

查看主机操作系统的shell脚本getOS.sh #!/bin/bash# 获取操作系统信息 os_info$(hostnamectl | grep Operating System | awk -F : {print $NF})# 检查是否包含"centos" if echo "$os_info" | grep -E *centos* > /dev/null; then# 打印主机IPecho &qu…

嵌入式面试常见问题(四)

1.在基于Linux的网络套接字编程中&#xff0c;如果需要创建一个IPv4的网络套接字&#xff0c;应该在socket函数中指定domain参数为AF_INET 解析&#xff1a; socket()函数创建套接字 函数原型:int socket(int domain, int type, int protocol); domain&#xff1a;协议簇&…

js教程(2)

一、运算符 1.赋值运算符 对变量进行赋值的运算符叫做赋值运算符&#xff0c;除了“”以外&#xff0c;还有一些复合赋值运算符&#xff1a;“”、“-”、“*”、“/”、“%“&#xff0c;使用这些运算符可以在对变量赋值时进行快速操作&#xff0c;例如&#xff1a; let num…

k8s-prometheus应用监控 23

使用prometheus监控&#xff0c;结合prometheus传递的指标&#xff0c;从而实现业务监控的自动化弹缩。 注&#xff1a;部署集群需要消耗较大的内存&#xff0c;需要提前扩容各节点的内存量至少达到4g 部署一个用于被监控的应用 上传所需镜像 修改yaml文件 部署完成 没有就绪是…

Linux检查软件信息及Linux清理日志等功能

提示:工具下载链接在文章最后 目录 一.ywtool check命令1.1 ywtool check -I1.2 ywtool check all1.3 ywtool check io1.4 ywtool check elk1.5 ywtool check php1.6 ywtool check mysql1.7 ywtool check nginx1.8 ywtool check system1.9 ywtool check docker_nbip [容器名称]…

mysql主从问题整理

以下3种情况是在HA切换时&#xff0c;由于是异步复制&#xff0c;且sync_binlog0&#xff0c;会造成一小部分binlog没接收完导致同步报错。 第一种&#xff1a;在master上删除一条记录&#xff0c;而slave上找不到。 第二种&#xff1a;主键重复。在slave已经有该记录&#x…

MyCAT集群——MyCAT2如何配置读写分离

先搭载MySQL一主两从 192.168.20.110MyCAT192.168.20.111Master192.168.20.112slave1192.168.20.113slave2 配置就不写了&#xff0c;比较基础&#xff0c;写一下步骤 1.进入mysql配置文件或者其子配置文件&#xff0c;添加server_id,开启gtidgtid_modeON,enforce-gtid-cons…

SAP 修改记录写入的思考

上一篇 调用SAP 采购配额维护 SAP ABAP 采购配额维护-CSDN博客 ME_UPDATE_QUOTA没有写入修改记录里面&#xff0c;使得从修改记录的表数据读取的报表/接口 取不到数据了 参考 https://wenku.baidu.com/view/95052a8ccd22bcd126fff705cc17552707225ea3.html?_wkts_17096217505…

STM32:CAN功能板设计和调试

0前言 本文主要目的是&#xff0c;总结去年设计stm32-CAN板子过程中遇到的问题&#xff0c;分为keil嵌入式软件和嘉立创EDA设计两个部分。 1 STM32F1 CAN功能 keil expected a “}“ 问题在于&#xff0c;PCB使用芯片为stm32f103c8t6&#xff0c;下载程序时选择device默认此…

项目部署发布

目录 上传数据库 修改代码中的数据源配置 修改配置文件中的日志级别和日志目录 打包程序 ​编辑​编辑 上传程序 查看进程是否在运行 以及端口 云服务器开放端口(项目所需要的端口) 上传数据库 通过xshell控制服务器 创建目录 mkdir bit_forum 然后进入该目录 查看路…

012 Linux_线程控制

前言 本文将会向你介绍线程控制&#xff08;创建&#xff08;请见上文&#xff09;&#xff0c;终止&#xff0c;等待&#xff0c;分离&#xff09; 线程控制 线程终止 pthread_t pthread_self(void); 获取线程自身的ID 如果需要只终止某个线程而不终止整个进程,可以有三种…

第十一章 配置 IIS 以与 Web 网关配合使用 (Windows) - 配置 IIS 返回 SOAP 故障详细信息

文章目录 第十一章 配置 IIS 以与 Web 网关配合使用 (Windows) - 配置 IIS 返回 SOAP 故障详细信息配置 IIS 返回 SOAP 故障详细信息 第十一章 配置 IIS 以与 Web 网关配合使用 (Windows) - 配置 IIS 返回 SOAP 故障详细信息 配置 IIS 返回 SOAP 故障详细信息 遇到错误的 IRI…

【C语言】Leetcode 206.反转链表

博主主页&#xff1a;17_Kevin-CSDN博客 收录专栏&#xff1a;《Leetcode》 题目 解决思路 思路一&#xff1a;翻转链表 struct ListNode* reverseList(struct ListNode* head) {if(head NULL){return NULL;}struct ListNode* n1 NULL,*n2 head,*n3 n2 -> next;while(…

线上问题——学习记录幂等判断失效问题分析

一、业务流程 上图是对save和saveScore两个接口的流程抽象&#xff0c;save是上传答题数据&#xff0c;saveScore则是上传答题分数&#xff0c;为保证幂等和防止并发调用&#xff0c;这两个接口都加了分布式锁&#xff08;还是两层哦&#xff09;。第一层使用的是不同的锁&…

Python 运算符介绍

Python 解释 Python是一种高级编程语言&#xff0c;以其简洁、易读和易用而闻名。它是一种通用的、解释型的编程语言&#xff0c;适用于广泛的应用领域&#xff0c;包括软件开发、数据分析、人工智能等。python是一种解释型&#xff0c;面向对象、动态数据类型的高级程序设计…

【笔记】Android 漫游定制SPN定制有关字段

一、SPN模块简介 【笔记】SPN和PLMN 运营商网络名称显示 Android U 配置 WiFiCalling 场景下PLMN/SPN 显示的代码逻辑介绍 【笔记】Android Telephony 漫游SPN显示定制&#xff08;Roaming Alpha Tag&#xff09; 二、相关配置字段 non_roaming_operator_string_array 是否…

闰年计算中的计算机Bug

不知道你有没有看过凯瑟琳泽塔琼斯主演的《偷天陷阱》&#xff0c;里面主题思想是用银行结算系统的千年虫bug&#xff0c;精心设计&#xff0c;盗取银行几十亿的精彩动作片。所谓2000 年千禧年的千年虫&#xff0c;其实就是计算机计算闰年的bug。 这个闰年计算的历史源远流长&…

共筑前端学习之路:欢迎加入我们的前端组件学习交流群

共筑前端学习之路&#xff1a;欢迎加入我们的前端组件学习交流群 随着信息技术的飞速发展&#xff0c;前端开发作为构建数字化世界的重要一环&#xff0c;越来越受到广大开发者的关注和重视。为了更好地服务于前端开发者&#xff0c;尤其是那些对前端组件充满热情的粉丝&#x…