面试手写代码总结

★★★手写代码:实现forEach map filter reduce

 // 1. ------_forEach--------// Array.prototype.forEach() 方法对数组的每个元素执行一次给定的函数。//  arr.forEach(callback(currentValue [, index [, array]])[, thisArg])Array.prototype._forEach = function (fn, thisArg) {if (typeof fn !== 'function') throw '参数必须为函数'if (!Array.isArray(this)) throw '只能对数组使用此方法'let arr = thisfor (let i = 0; i < arr.length; i++) {fn.call(thisArg, arr[i], i, arr)  //用call来改变fn里面this的指向}}//test// window.value = 0// let obj = { value: 1 }// let arr = ["_", "for", "each"]// arr._forEach(//   function (ele, index, arr) {//     console.log("ele, index, arr", ele, index, arr);//     console.log("this.vaule", this.value);//   }, obj)// 2. ------_map--------// Array.prototype.map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。//  arr.map(callback(currentValue [, index [, array]])[, thisArg])Array.prototype._map = function (fn, thisArg) {if (typeof fn !== 'function') throw "参数必须是回调函数"if (!Array.isArray(this)) throw "只能为数组使用此方法"const arr = this      //将调用者(实例化的arr)赋值给arrconst newArr = []for (let i = 0, len = arr.length; i < len; i++) {newArr.push(fn.call(thisArg, arr[i], i, arr))//将每次调用的回调函数fn的返回值push到新数组中}return newArr  //返回新数组}//test// window.value = 0// let obj = { value: 1 }// let arr = ["_", "for", "each"]// const newArr = arr._map(//   function (ele, index) {//     return ele + "你好" + index//   }, obj)// console.log(newArr);// 3. ------_filter--------// Array.prototype.map() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 //  arr.filter(callback(currentValue [, index [, array]])[, thisArg])Array.prototype._filter = function (fn, thisArg) {if (typeof fn !== 'function') throw "参数必须是回调函数"if (!Array.isArray(this)) throw "只能为数组使用此方法"const arr = this      //将调用者(实例化的arr)赋值给arrconst newArr = []for (let i = 0, len = arr.length; i < len; i++) {if (fn.call(thisArg, arr[i], i, arr)) { //判断回调的返回值是否为truenewArr.push(arr[i])}}return newArr  //返回新数组}//test// window.value = 0// let obj = { value: 1 }// let arr = ["_", "for", "each"]// const newArr = arr._filter(//   function (ele, index) {//     return ele == "for"//   }, obj)// console.log(newArr);//???????传入的数组这个参数的作用是???????// 4. ------_reduce--------// Array.prototype.map() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。//  arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])Array.prototype._reduce = function (_reducer, initialValue) {if (typeof _reducer !== 'function') throw "参数必须是回调函数"if (!Array.isArray(this)) throw "只能为数组使用此方法"if ((!this.length && !initialValue)) throw "请传入初始值或者给非空对象使用此方法"let arr = this    //将调用者(实例化的arr)赋值给arrlet result = initialValue || arr[0]  //初始值for (let i = 0, len = arr.length; i < len; i++) {if (!initialValue && i == 0) continue // 如果提供了initialValue,则起始索引号为0,否则从索引1起始。result = _reducer(result, arr[i], i, this)}return result  //返回新数组}// //test// let arr = [1, 3, 4]// const Result = arr._reduce(function (accumulator, currentValue, index, array) {//   console.log(index);//   return accumulator + currentValue// }, 2)// console.log(Result);

★★★ 手写实现一个简易的 Vue Reactive


★★★ 手写代码,监测数组变化,并返回数组长度

//手写代码,监测数组变化,并返回数组长度
// 获取Array的原型,并创建一个新的对象指向这个原型// const arrayMethods = Object.create(Array.prototype)// 创建一个新的原型,这就是改造之后的数组原型const ArrayProto = []// 重新构建Array原型里面的虽有方法Object.getOwnPropertyNames(Array.prototype).forEach(method => {if (typeof Array.prototype[method] === "function") {ArrayProto[method] = function () {console.log("我已经监听到数组触发了" + method + "事件")let len = this.lengthlet result = Array.prototype[method].apply(this, arguments)console.log(len, this.length);if (len !== this.length) return this.lengthreturn result}}})let list = [1, 2, 3]// 将数组的原型链指向新构造的原型list.__proto__ = ArrayProto// 执行push事件console.log(list.push(2), list.pop(2), list.slice(2), list.unshift(2));

★★★ 手写原生继承,并说出局限性?


★★★★ 手写一个柯里化函数

//柯里化:固定部分参数,返回一个接受剩余参数的函数,也称为部分计算函数,目的是为了缩小适用范围,创建一个针对性更强的函数。核心思想是把多参数传入的函数拆成单参数(或部分)函数,内部再返回调用下一个单参数(或部分)函数,依次处理剩余的参数。
//好处: 入口单一,易于测试和复用  
//缺点:  函数嵌套多、占内存function Curry(fn,...args){return (..._args)=>{return fn(...args,..._args))}
}function V(l,w,h){return l*w*h
}const hcy =Curry(V,10)
hcy(5,8)   //400
hcy(6,7)   //420

★★★ 手写一个反柯里化函数

//反柯里化,从字面讲,意义和用法跟函数柯里化相比正好相反,扩大适用范围,创建一个应用范围更广的函数。使本来只有特定对象才适用的方法,扩展到更多的对象。
Function.prototype.unCurrying = function() {const self = thisreturn function(...rest) {return Function.prototype.call.apply(self, rest)}
}

★★★★ 手写一个Promise

class Promise{constructor(executor){this.state = 'pending';this.value = undefined;this.reason = undefined;this.onResolvedCallbacks = [];this.onRejectedCallbacks = [];try{  // 如果executor执行报错,直接执行rejectexecutor(this.resolve, this.reject);} catch (err) {reject(err);}}//成功resolv(value){// state改变,resolve调用就会失败if (this.state === 'pending') {// resolve调用后,state转化为成功态this.state = 'fulfilled';// 储存成功的值this.value = value;}};//失败reject(reason) {// state改变,reject调用就会失败if (this.state === 'pending') {// reject调用后,state转化为失败态this.state = 'rejected';// 储存失败的原因this.reason = reason;}};//then方法then(onFulfilled,onRejected) {// 声明返回的promise2let promise2 = new Promise((resolve, reject)=>{if (this.state === 'fulfilled') {let x = onFulfilled(this.value);// resolvePromise函数,处理自己return的promise和默认的promise2的关系resolvePromise(promise2, x, resolve, reject);};if (this.state === 'rejected') {let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject);};if (this.state === 'pending') {this.onResolvedCallbacks.push(()=>{let x = onFulfilled(this.value);resolvePromise(promise2, x, resolve, reject);})this.onRejectedCallbacks.push(()=>{let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject);})}});// 返回promise,完成链式return promise2;}
}

★★★ 手写一个instanceOf

function instanceOf(left,right){let proto = left.__proto__let prototype = right.prototypewhile(true){if(proto === null) return falseif(proto === prototype) return true proto = proto.__proto__;}
}

★★★ 手写ajax

//1.创建对象
let  xhq = new XMLHttpRequest()
//2.初始话http请求参数
xhq.open(methode, url, true)
//3.发送请求
xhq.send({username:'wzx'
})
//4.监听请求状态,执行对应的回调函数
xhq.onreadystatechange = function () {if ( xhq.readystate == 4 && xhq.status == 200 ) {// success 回调success(xhq.responseText)}  else if (xhq.readyState == 4 && xhq.status !== 200) {// error 回调error()}
}//-----------完整实现-----------
function sendAjax(obj) {function splicStr(data) {// get方式传入时,将内容进行data内容进行拼接var str = ''for (var i in data) {str = i + '=' + data[i]}return str}// 原生ajax实现 步骤分析
// 一、声明XMLHttpRequest, 为了兼容IE5、6需要使用ActiveXObject()let xhq = new XMLHttpRequest() // 创建对象
// 二、初始化HTTP请求参数, 只初始化并不会发送if (obj.method.toUpperCase() === 'GET') { // get方法xhq.open(obj.method, obj.url + '?' + splicStr(obj.data),  typeof obj.async === 'boolean'? obj.async : true) // 路径拼接xhq.send()// 三、发送此次请求}else if (obj.method.toUpperCase() === 'POST') { // post方法xhq.open(obj.method, obj.url, typeof obj.async === 'boolean'? obj.async : true)xhq.setRequestHeader("content-type","application/x-www-form-urlencoded") // 以表单提交xhq.send(obj.data)// 三、发送此次请求}
//四、监听发送xhq.onreadystatechange = function () {if ( xhq.readyState == 4 && xhq.status == 200 ) {// success 回调success(xhq.responseText)} else if (xhq.readyState == 4 && xhq.status !== 200) {// error 回调error()}}
}sendAjax({url: 'your url',method: 'post',async: true,data: {username: 'xiong',pwd: '123'},success: function (data) {console.log(data)},error: function () {console.log('发生了错误')}
})

★★★ 手写JSONP的原理和实现

function jsonp(url,data,callback){var funcName = 'jsonp_'+Date.now()+Math.random().toString().substr(2, 5)//如果有其他参数需要拼接if(typeof data==='object'){var tmpArr = []for (let key in data){let value =data[key]tmpArr.push(key+'='+value)}data = tmpArr.join('&')}let script = document.createElement('script')script.src = url + '?' + data + '&callback= ' + funcNamedocument.body.appendChild(script)window[funcName]= function (data){callback(data)//清除标签delete Window[funcName]document.body.removeChild(script)}
}

★★★★ 手写深拷贝

//乞丐版
function deepCopy(obj){return obj.JSON.Parse(JSON.Stringify(obj))
}//面试够用版
function deepCopy(obj){if(typeof obj)if(typeof obj =='object'){//判断是否为复杂数据源类型var result = obj.constructor == Array?[]:{}  //数组还是对象for(let i in obj){result[i]= typeof obj[i] =='object'? deepCopy(obj[i]):obj[i]}}else{//简单数据类型 var result = obj;}return result
}

★★★ 手写浅拷贝

function clone(target) {if(target === null ) {return target}// 克隆 数组 和 对象let cloneTarget = Array.isArray(target) ? [] : {}for (const key in target) {if (target.hasOwnProperty(key)) {//判断是否是本身的属性cloneTarget[key] = target[key]}}return cloneTarget
}

★★★★ 手写 bind

Function.prototype.myBind = function(context) {if (typeof this !== 'function') {throw new TypeError('Error')}//返回一个绑定this的函数,这里我们需要保存thisconst _this = thisconst args = [...arguments].slice(1)//返回一个函数return function F() {//因为返回一个函数,我们可以new F()需要判断能当做构造函数吗if (this instanceof F) { //实例是F这个构造函数造出来的return new _this(...args, ...arguments)  }return _this.apply(context, args.concat(...arguments))}
}

★★★★ 手写 call

Function.prototype.myCall = function(context) {context=context||window //传入参数的话,就指定context为this指向,否则指定windowcontext.fn = thisconst args = [...arguments].slice(1) //入参删除contextconst result = context.fn(...args)delete context.fnreturn result
}

★★★★ 手写 apply

Function.prototype.myApply = function(context) {context = context || windowcontext.fn = this   //给传入的上下文对象添加一个fn方法,这个fn方法即为myApply调用者let result if(arguments[1]){result = context.fn(...arguments[1])}else{result = context.fn()}delete context.fnreturn result
}

★★★ 手写模拟 object.create

function _create (obj){function F(){}  //创建一个构造函数F.prototype = obj  //将构造函数的原型对象赋值return new F()
}

★★★ 手写模拟 Object.is

function _is(x, y) {if (x === y) {//运行到1/x === 1/y的时候x和y都为0,但是1/+0 = +Infinity, 1/-0 = -Infinity, 是不一样的return x !== 0 || y !== 0 || 1 / x === 1 / y} else {//NaN===NaN是false,这是不对的,我们在这里做一个拦截,x !== x,那么一定是 NaN, y 同理//两个都是NaN的时候返回truereturn x !== x && y !== y}
}console.log(is(+0, -0))
console.log(is(NaN, NaN))

★★★ 手写 new

//new的实现过程(实际上就是调用这个构造函数,同时将构造函数的prototype上的属性方法挂上去。)
//1. 新建一个对象
//2. 对象 继承 构造函数的 原型链
//3. 将构造函数的this指向这个对象
//4. 根据构造函数的返回值的返回结构
function myNew(fn){ let obj = {} //定义空对象objobj = Object.create(fn.prototype) //将传入的构造函数的prototype属性方法复制到obj里面let args = Array.prototype.slice.call(arguments,1)// 获取除去fn之外的参数//或者  [...arguments].slice(1)let result = fn.call(obj,...args)  // 调用传入的构造函数,矫正this为obj,并传入argsreturn typeof result === 'object'||result instanceof Function? result : obj;//如果构造函数返回引用类型,直接返回,否则返回obj
}class Foo{constructor(){this.name = 'ciel'this.arg = arguments[0]}callname(){console.log(this.name)}
}// 测试
let test = myNew(Foo, 'hhh', '123', 'saf')
test.callName()
console.log(test.arg)

★★★ 手写对象扁平化

export function jsonFlatten(data) {var result = {}function recurse(cur, prop) {if (Object(cur) !== cur) {result[prop] = cur} else if (Array.isArray(cur)) {for (var i = 0, l = cur.length; i < l; i++) { recurse(cur[i], prop + '[' + i + ']') }if (l === 0) { result[prop] = [] }} else {var isEmpty = truefor (var p in cur) {isEmpty = falserecurse(cur[p], prop ? prop + '.' + p : p)}if (isEmpty && prop) { result[prop] = {} }}}recurse(data, '')return result
}

★★★ 手写数组扁平化

//第一种 正则表达式
function flatten(arr){let str = JSON.stringify(arr);return str.replace(/(\[\]))/g,'').split(',')
}
//第二种 递归
function flatten(arr, result = []) {if (!Array.isArray(arr)) {result.push(arr)return result}for (let value of arr) {flatten(value, result)}return result
}
//第三种 数组字符串方法
function flatten(arr) {return arr.toString().split(',').map(ele => parseInt(ele))
}//第四种
function flatten(arr){while(arr.some(item => Array.isArray(item))){arr = [].concat(...arr);}return arr;
}

★★★ 手写数组去重

//1.ES6的Setfunction unique(arr){ruturn Array.from(new Set(arr))   }
//2. 双层for循环function unique(arr) {let result = []for (let i = 0, len = arr.length; i < len; i++) { //第一层遍历let flag = false  //进行标记for (let k = i + 1, len = arr.length; k < len; k++) {if (arr[i] === arr[k]) {  //如果后面有重复的就跳过flag = truek = arr.length}}if (!flag) result.push(arr[i]) //没有重复的,添加到数组中}return result}
//3. 利用数组的indexOf方法 function unique(arr) {let result = []for (let i = 0, len = arr.length; i < len; i++) {if (result.indexOf(arr[i]) === -1) result.push(arr[i])}return result}
//4. 利用类似桶排序的方法function unique(arr) {let result = []   let bucket = [];  //创建一个桶for (let i = 0, len = arr.length; i < len; i++) {bucket[arr[i]] = 1   //将有些桶标记}for (key in bucket) { //取出有标记的桶的下标console.log(key);result.push(Number(key))}return result}
//5. 利用filter方法function unique(arr) {return arr.filter((ele, index) => (arr.indexOf(ele) === index)) //过滤}//6. 利用map方法function unique(arr) {return arr.map((ele, index) => {if (arr.indexOf(ele) === index) return ele})}
//7.排序后进行数组function unique(arr) {arr.sort()let result = []arr.forEach((ele, index) => {if (ele !== arr[index + 1]) result.push(ele)})return result}

★★★ 手写模拟实现 async/await


★★★★ 手写实现发布/订阅模式

class Subject { //定义被观察者constructor() {this.observers = []}addObserver(observer) { //订阅this.observers.push(observer)}removerObserver(observer) {//取消订阅let index = this.observers.indexOf(observer)if (index !== -1) {this.observers.splice(index, 1)}}notify() {  //通知this.observers.forEach(observer => {observer.update()})}
}class Observer { // 定义观察者update() {console.log('subject更新了');}subscribeTo(subject) {subject.addObserver(this)}
}let subject = new Subject() //被观察者
let observer1 = new Observer()  //观察者
observer1.subscribeTo(subject) //观察者进行订阅
let observer2 = new Observer()  //观察者
observer2.subscribeTo(subject) //观察者进行订阅
subject.notify()

★★★★ 手写防抖

funtion debounce(fn,delay){let timer = nullreturn ()=>{clearTimeout(timer)timer =  setTimeout(()=>(fn()),delay)}
}let a = debounce(()=>(console.log('防抖处理')),500)function 点击事件(){a()
}

★★★★ 手写节流

function throttle(fn, delay = 500) {let lastTime, timereturn function(){let context = this;let args = [].slice.call(arguments);time = Date.now()if (!lastTime || time - lastTime > delay) {fn.apply(context)lastTime = time}}
}function fn(){console.log('节流')
}let a =  throttle(fn, 1000)function 点击事件(){a()
}

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

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

相关文章

TIDB7.5LTS集群安装配置手册

简介 因近期有一个项目需要上线,在评估使用什么架构时,和开发同仁沟通需求,了解到该应用为OLTP但是数据量很集中,会有几张超大的表,如果要保证事务效率,使用mysql集群难免会要做分库分表,对后期的运维带来很大的挑战;而TIDB属于分布式集群,TIKV的行存模式非常适用于大…

微信小程序管理奖品(抽奖)

话不多说直接上代码 功能&#xff1a; 使用微信小程序vant-weapp 组件库中的upload组件以及两个input框 最后拿到的值是一个数组对象的形式 主要代码如下&#xff1a; wxml <view wx:for"{{prizes}}" wx:key"index" class"inputs"><i…

【算法刷题】Day21

1. 【模板】前缀和 原题链接 题干&#xff1a; 给定一个长度为 n 的数组 有 q 次查询&#xff0c;每次有两个参数 l 和 r 算法原理&#xff1a; 1. 暴力解法 &#xff08;模拟&#xff09; 这个时间复杂度是 O(n) 2. 前缀和&#xff08;快速求出数组中某一个连续区间的和&…

Docker+PXC+Haproxy搭建高可用MySQL集群

搭建 本次搭建集群环境以5节点MySQL为例 1、安装pxc镜像 拉取pxc镜像 docker pull percona/percona-xtradb-cluster 镜像名称太长&#xff0c;修改一下&#xff1a; docker tag percona/percona-xtradb-cluster pxc 删除之前的&#xff1a; docker rmi percona/percona-xtr…

DOM是什么?

1、概述 &#xff08;1&#xff09;DOM代表文档对象模型&#xff0c;是 HTML 和 XML 文档的接口&#xff08;API&#xff09; &#xff08;2&#xff09;当浏览器第一次读取&#xff08;解析&#xff09;HTML文档时&#xff0c;会创建一个基于 HTML 文档的大对象&#xff0c;…

SpringBoot操作Redis缓存

SpringBoot操作Redis缓存 Redis有很多使用场景&#xff0c;一个使用场景就是缓存数据库的数据。Redis作为一个内存数据库&#xff0c;存取数据的速度比传 统的数据库快得多。使用Redis缓存数据库数据&#xff0c;可以减轻系统对数据库的访问压力&#xff0c;及加快查询效率等…

听GPT 讲Rust源代码--src/tools(15)

File: rust/src/tools/rust-analyzer/crates/mbe/src/token_map.rs 在Rust源代码中&#xff0c;rust/src/tools/rust-analyzer/crates/mbe/src/token_map.rs文件的作用是实现了一个能够将输入的文本映射为标记的结构。具体来说&#xff0c;它定义和实现了几个结构体&#xff08…

【已解决】Mysql在更新的时候,需要更新的字段是其他表查询的值,这个时候update语句怎么写

Mysql在更新的时候,需要更新的字段是其他表查询的值&#xff0c;这个时候update语句怎么写&#xff1f; 例如&#xff1a;我想要更新A表中的floor字段。但是这个字段的是是根据条件在B表中查询后&#xff0c;得到的值。 这样需求的sql语句怎么写 &#xff1f; 要点&#xff…

Mysql5.7版本中,查询分组GROUP BY通过子查询中ORDER BY进行排序无效的问题解决办法

文章目录 一、场景&#xff1a;二、解决办法1、使用 having 来阻止合并2、足够大的limit3、子查询 一、场景&#xff1a; 问题描述&#xff1a;Mysql5.7版本中&#xff0c;查询分组GROUP BY通过子查询中ORDER BY进行排序无效的问题解决办法。 应用场景&#xff1a;一对多的关系…

数据库(三)超详细SQL语句入门 | SQL增删改查,重命名,字符操作,联合操作,聚合函数,嵌套子查询

文章目录 1 SQL表内类型2 SQL增删改语句2.1 创建表2.2 删除表2.3 表中添加属性2.4 添加新的元组信息2.5 删除表所有元组2.6 元组 3 查询语句4 重命名4.1 为什么用 5 字符操作5.1 寻找 6 生序降序7 联合操作7.1 并集Union7.2 交集 INTERSECT7.3 差集 EXCEPT7.4 对于空值补充 8 聚…

掀起全新的互联网直播风潮

随着科技的不断进步和智能手机的普及&#xff0c;无人直播作为一种全新的互联网直播方式&#xff0c;在近些年迅速崛起&#xff0c;并引起了广泛关注。本文将围绕手机无人直播展开探讨&#xff0c;探究其背后的原因以及对社会生活带来的影响。 首先&#xff0c;我们需要明确什…

[Angular] 笔记 5:ngClass

Angular 中的 ngClass 是什么&#xff1f; chatgpt 回答&#xff1a; 在Angular中&#xff0c;ngClass 是一个内置的指令&#xff0c;用于动态地添加或移除 HTML 元素的 CSS 类。它允许你根据条件设置一个或多个 CSS 类&#xff0c;可以是对象、数组或字符串。 使用方式&#…

一篇文章带你进阶CTF命令执行

以下的命令是为了方便以后做题时方便各位读者直接来这里复制使用&#xff0c;刚开始还请先看完这篇文章后才会懂得下面的命令 ?ceval($_GET[shy]);&shypassthru(cat flag.php); #逃逸过滤 ?cinclude%09$_GET[shy]?>&shyphp://filter/readconvert.base64-…

mysql:查看服务端没有睡眠的线程数量

使用命令show global status like Threads_running;可以查看服务端没有睡眠的线程数量。 例如&#xff1a;

使用React和ResizeObserver实现自适应ECharts图表

关键词 React ECharts ResizeObserver 摘要 在现代 Web 开发中&#xff0c;响应式布局和数据可视化是非常常见的需求。本文将介绍如何使用React、ResizeObserver和ECharts库来创建一个自适应的图表组件。 什么是ResizeObserver ResizeObserver是JavaScript的一个API&#x…

定时任务,停用用户。

1&#xff0c; <!-- 定时3.用户三个月无操作&#xff0c;停用用户 begin --> <bean id"autoStopSleepUserService" class"com.rjhc.application.sysmanage.service.impl.SysTaskScheduleServiceImpl" /> <bean id"jobDetail_…

玩转Spring状态机

说起Spring状态机&#xff0c;大家很容易联想到这个状态机和设计模式中状态模式的区别是啥呢&#xff1f;没错&#xff0c;Spring状态机就是状态模式的一种实现&#xff0c;在介绍Spring状态机之前&#xff0c;让我们来看看设计模式中的状态模式。 1. 状态模式 状态模式的定义如…

代码随想录 322. 零钱兑换

题目 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种硬币的数量是无限的。…

[Encryptedd@mailfence.com].faust 勒索病毒肆虐:如何恢复被加密的数据文件?

导言&#xff1a; 在网络安全的战场上&#xff0c;[backupsairmail.cc].faust [Deciphermailfence.com].faust[Encrypteddmailfence.com].faust[support2022cock.li].faust [tsai.shenmailfence.com].faust勒索病毒是一种极具破坏性的恶意软件。本文91数据恢复将深入介绍该病毒…

Docker仓库

官方docker仓库使用 网址&#xff1a;https://hub.docker.com 每个注册用户都可以上传和管理自己的镜像 用户登录 上传镜像前需要登陆&#xff0c;登陆后生成~/.docker/config.json文件保存验证信息 docker login 给本地镜像打标签 上传本地镜像前必须先给上传的镜像用do…