当前位置: 首页 > news >正文

typeScript 之 Array

工具: PlayGround

源码:GitHub TypeScript


数组简介

在TypeScript中, 使用[]表示数组, 它的结构:let valus: 类型名[] = 数据;

// 数字
let numList: number[] = [1, 2, 3];
// 字符串
let strList: string[] = ["hello", 'typeScript'];
// 任意类型
let data: any[] = [1, "hello", 3];console.log(typeof(numList));       // "object"
console.log(typeof(strList));       // "object"
console.log(typeof(data));          // "object"

object类型前文曾说过: 它表示一个非原始类型(数字,字符串,布尔)的值,主要作用于数组,对象和函数等,它是一种泛指的类型,可以包括任意类型值。

object提供的主要接口有:

接口返回值描述
constructorFunction构造函数相关
toString()string返回字符串相关
toLocaleString()string
valueOf()Object返回指定对象的原始值
hasOwnProperty()boolean判断对象是否具有指定名称的属性
isPrototypeOf()boolean判断一个对象是否存在于另一个对象的原型链中
propertyIsEnumerable()boolean判断指定的属性是否可枚举

简单的实例:

let obj = { name: "John", age: 30 };console.log(obj.toString()); 			 // "[object Object]"
console.log(obj.toLocaleString()); // "[object Object]" 
console.log(obj.valueOf()); 			 // { name: "John", age: 30 }console.log(obj.hasOwnProperty("name"));   // true
console.log(obj.hasOwnProperty("gender")); // falseconsole.log(Object.prototype.isPrototypeOf(obj)); // true
console.log(Object.prototype.isPrototypeOf({}));  // trueconsole.log(obj.propertyIsEnumerable("name"));     // true
console.log(obj.propertyIsEnumerable("toString")); // false

Array

数组的构建,同样支持使用Array对象进行构建, 它被称为泛型数组。 源码参考:es5.d.ts

interface ArrayConstructor {// 创建指定长度的数组, 返回any类型new(arrayLength?: number): any[];// 创建指定长度的数组,返回T类型new <T>(arrayLength: number): T[];// 创建包含元素的素组,返回T类型new <T>(...items: T[]): T[];isArray(arg: any): arg is any[];readonly prototype: any[];
}

T在TypeScript中表示泛型,方便我们编写更加通用和灵活性的代码,并使其适用于不同的类型。

简单的创建实例:

const arr_1 = new Array(3);
console.log(arr_1);     // [, , ]const arr_2 = new Array<number>(3);
console.log(arr_2);     // [, , ]const arr_3 = new Array(1, 2, 3);
console.log(arr_3);     // [1, 2, 3] // 均为"object"
console.log(typeof(arr_1), typeof(arr_2), typeof(arr_3));

数组也是支持创建多维数组的, 比如:

// 使用基础类型构建
const numList = [[0, 1, 2], [0, 1, 2]];
console.log(numList);           // [[0, 1, 2], [0, 1, 2]] 
console.log(numList.length);    // 2// 使用Array创建
let dataList = [];
for (let i = 0; i < 2; ++i) {let strs = [];for (let j = 0; j < 3; ++j) {strs.push(j);}dataList.push(strs);
}
console.log(dataList);          // [[0, 1, 2], [0, 1, 2]]
console.log(dataList.length);   // 2

关于Array提供的常用接口如下:

接口返回值描述
lengthnumber返回数组长度
toString()string返回数组的字符串
toLocaleString()string返回数组中各个元素的本地化字符串表示
push()number数组末尾添加新元素,并返回数组的新长度
pop()T | undefined移除数组的最后一个元素,并返回该元素
concat()T[]合并两个或多个数组,并返回一个新的数组
join()string将数组的所有元素连接成一个字符串,并使用指定的分隔符进行分隔
reverse()T[]反转数组中元素的顺序
shift()T移除数组的第一个元素,并返回该元素
unshift()number向数组的开头添加新元素,并返回数组的新长度
slice()T[]返回数组中指定范围的元素
sort()this对数组中的元素进行排序
splice()T[]从数组中移除元素,并可以在指定位置插入新元素
indexOf()number返回指定元素在数组中第一次出现的索引
lastIndexOf()number返回指定元素在数组中最后一次出现的索引
every()boolean检测数组中的所有元素是否满足指定条件
some()boolean检测数组中是否存在满足指定条件的元素
forEach()void遍历数组中的每个元素,并执行指定的回调函数
map()U[]遍历数组中的每个元素,并根据回调函数的返回值创建一个新数组
filter()T[]遍历数组中的每个元素,并返回满足指定条件的元素组成的新数组
reduce()T使用指定的回调函数对数组中的元素进行累积计算,并返回最终的累积结果
reduceRight()T使用指定的回调函数对数组中的元素进行逆向累积计算,并返回最终的累积结果

源码相关:

interface Array<T> {// 返回Array数组长度length: number;// 返回字符串toString(): string;// 返回数组中各个元素的本地化字符串表示toLocaleString(): string;// 移除数组的最后一个元素,并返回该元素,// 如果数组为空,则返回undefined且不修改数组pop(): T | undefined;// 在数组末尾添加新元素,并返回数组的新长度push(...items: T[]): number;// 合并两个或多个数组,并返回一个新的数组,原有数组不发生改变concat(...items: ConcatArray<T>[]): T[];concat(...items: (T | ConcatArray<T>)[]): T[];/*@func: 将数组的所有元素添加到一个字符串中,用指定的分隔符字符串分隔@param: separator 分割符号,如果省略则使用逗号*/join(separator?: string): string;// 反转数组,它会导致数组改变reverse(): T[];// 从数组中移除第一个元素并返回它// 如果数组为空,则返回undefined且不修改数组shift(): T | undefined;// 在数组的开头插入新元素,并返回新的数组长度unshift(...items: T[]): number;/*@func: 返回数组中指定范围的元素@param: start 开始位置,允许使用负数,比如-1表示倒数第一个元素@param: end 结束位置,元素不包括end索引处元素,如果忽略则为末尾*/slice(start?: number, end?: number): T[];// 数组排序,如果忽略则为ASCII升序排列sort(compareFn?: (a: T, b: T) => number): this;/*@func: 从数组中删除元素,如果需要,在原来的位置插入新元素,并返回被删除的元素@param: start 开始位置,位置索引0开始@param: deleteCount 要删除的元素数量*/splice(start: number, deleteCount?: number): T[];splice(start: number, deleteCount: number, ...items: T[]): T[];/*@func: 返回数组中值第一次出现的索引,如果不存在则返回-1@param: searchElement 要在数组中找到的值@param: fromIndex 开始索引,如果忽略从0开始*/indexOf(searchElement: T, fromIndex?: number): number;/*@func: 返回指定值在数组中最后出现的索引,如果不存在则返回-1@param searchElement 要在数组中找到的值@param fromIndex 开始的索引,如果忽略,则从最后一个索引开始*/lastIndexOf(searchElement: T, fromIndex?: number): number;/*@func: 检测数组中的所有元素是否满足指定条件@param predicate 最多接受三个参数的函数@param thisArg 可以引用的对象, 如果忽略则使用undefined作为this值*/every<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): this is S[];every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;// 检测数组中是否存在满足指定条件的元素some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;/*@func: 遍历数组中的每个元素,并执行指定的回调函数@param callbackfn 回调函数,最多接受三个参数@param thisArg 可以引用的对象, 如果忽略则使用undefined作为this值*/forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;/*@func: 遍历数组中的每个元素,并根据回调函数的返回值创建一个新数组@param callbackfn 回调函数,最多接受三个参数@param thisArg 可以引用的对象, 如果忽略则使用undefined作为this值*/map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];/*@func: 返回满足回调函数中指定条件的数组元素@param predicate 回调函数,最多接受三个参数@param thisArg 可以引用的对象, 如果忽略则使用undefined作为this值*/filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];/*@func: 为数组中的所有元素调用指定的回调函数回调函数的返回值是累积的结果,并在下次调用回调函数时作为参数提供@param: callbackfn 一个最多接受四个参数的回调函数*/reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;// 使用指定的回调函数对数组中的元素进行逆向累积计算,并返回最终的累积结果reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;[n: number]: T;
}

基本使用:

let dataList:number[] = []
// 插入数值
dataList.push(1);
console.log(dataList);          // [1] // 删除数值 
const value = dataList.pop();
console.log(value, dataList);   // 1,  [] 
// 数组已经为空,如果再删除则返回undefined
console.log(dataList.pop());    // undefined 

针对于删除可做下拓展,比如删除重复数值:

// 方法1: 使用push相关增加新数组
let arr: number[] = [1, 2, 2, 3, 4, 4, 5, 5];
let uniqueArr: number[] = [];
for (let i = 0; i < arr.length; i++) {if (uniqueArr.indexOf(arr[i]) === -1) {uniqueArr.push(arr[i]);}
}
console.log(uniqueArr); // 输出 [1, 2, 3, 4, 5]// 方法2:使用filter方法进行遍历获取新的数组
let arr: number[] = [1, 2, 2, 3, 4, 4, 5, 5];
let uniqueArr: number[] = arr.filter((value, index, self) => {return self.indexOf(value) === index;
});
console.log(uniqueArr); // 输出 [1, 2, 3, 4, 5]// 方法3: 使用reduce方法
let arr: number[] = [1, 2, 2, 3, 4, 4, 5, 5];
let uniqueArr: number[] = arr.reduce((prev, curr) => {if (!prev.includes(curr)) {prev.push(curr);}return prev;
}, []);
console.log(uniqueArr); // 输出 [1, 2, 3, 4, 5]

如果要移除或插入特定的元素相关也可以考虑unshiftshift相关:

// 使用Array对象
let arrObj = new Array();
console.log(arrObj);            // []// 使用 unshift 在数组开头插入元素, 并返回长度
arrObj.unshift(1);
arrObj.unshift(2);
let len = arrObj.unshift(0);
console.log(len, arrObj);       // 3,  [0, 2, 1] // 使用shift移除首位置元素,并返回删除元素
let newLen = arrObj.shift();
console.log(newLen, arrObj);    // 0,  [2, 1] 

数组的遍历,如果需要有回调方法的支持,可以使用forEach

const numList = [1, 2, 3]
numList.forEach((value, index, array) => {if (value % 2 === 0) {console.log(`索引是:${index} 为偶数`);	// "索引是:1 为偶数" }console.log("数据是" + array.join("#"));		// "数据是1#2#3" 
});

数组是支持排序的,可以使用sort

const numList: number[] = [1,3,2,5,4];
// 默认为升序
numList.sort(); 
console.log(numList);       // [1, 2, 3, 4, 5]    // 使用比较函数排序
numList.sort((a, b) => b - a);
console.log(numList);       // [5, 4, 3, 2, 1] // 元素反转
numList.reverse()
console.log(numList);       // [1, 2, 3, 4, 5] 

获取数组中某个元素

获取数组中的元素可以通过索引来简单获取

const arr_1 = [1, 2, 3, 4];
const arr_2 = [[1, 2, 3], [4, 5,6]];
console.log(arr_1[0], arr_2[1][0]);     // 1, 4
// 如果索引错误,则返回undefined
console.log(arr_1[5], arr_2[1][10]);    // undefined,  undefined 

也可以使用indexOflastIndexOf相关查找元素的索引位置相关

const arrObj = new Array<number>(1, 2, 2, 3);// indexOf 查找元素首次出现的位置
const firstIndex = arrObj.indexOf(2);
console.log(firstIndex);            // 1// lastIndexOf 查找元素最后出现的位置
const lastIndex = arrObj.lastIndexOf(2);
console.log(lastIndex);             // 2// 如果查找不到,返回-1
console.log(arrObj.indexOf(0), arrObj.indexOf(0));

合并数组

可以使用contact方法

const arr_1 = [1,2,3,4,5];
const arr_2 = [1,2,3,6,7];
// 使用concat合并数组, 原有数组不会发生改变
let newArr_1 = arr_1.concat(arr_2);
console.log(arr_1, arr_2);  // [1, 2, 3, 4, 5],  [1, 2, 3, 6, 7] 
console.log(newArr_1);      // [1, 2, 3, 4, 5, 1, 2, 3, 6, 7] 

拓展下,如果想剔除重复元素,可以考虑filter

let arr1: number[] = [1, 2, 3];
let arr2: number[] = [2, 3, 4];let mergedArr: number[] = [...arr1, ...arr2].filter((value, index, self) => {return self.indexOf(value) === index;
});console.log(mergedArr);     // [1, 2, 3, 4] 

再进行拓展下,使用最笨的循环方法实现:

let arr1: number[] = [1, 2, 3];
let arr2: number[] = [2, 3, 4];// 获取排序的合并数组
function getMergeArr(originArr: any, destArr: any) {if (originArr.length <= 0) {return console.error("originArr is nil");}if (destArr.length <= 0) {return console.error("originArr is nil");}let mergeArr: any = [];// 遍历originArrfor (let i = 0; i < originArr.length; ++i) {if (!mergeArr.includes(originArr[i])) {mergeArr.push(originArr[i]);}}// 遍历destArrfor (let i = 0; i < destArr.length; ++i) {if (!mergeArr.includes(destArr[i])) {mergeArr.push(destArr[i]);}}return mergeArr;
}
console.log(getMergeArr(arr1, arr2));       // [1, 2, 3, 4] 

includes方法来源于Array对象 ES2016中, 它主要用于判定数组中是否包含指定元素。

// es2016.array.include.d.ts
interface Array<T> {includes(searchElement: T, fromIndex?: number): boolean;
}

其他

  • map 遍历数组中的每个元素,并根据回调函数的返回值创建一个新数组
let arr: number[] = [1, 2, 3, 4, 5];let doubledArr: number[] = arr.map((value, index, array) => {return value * 2;
});console.log(doubledArr); // [2, 4, 6, 8, 10]

相关文章:

typeScript 之 Array

工具: PlayGround 源码&#xff1a;GitHub TypeScript 数组简介 在TypeScript中&#xff0c; 使用[]表示数组&#xff0c; 它的结构&#xff1a;let valus: 类型名[] 数据; // 数字 let numList: number[] [1, 2, 3]; // 字符串 let strList: string[] ["hello"…...

【题解】二叉树的前中后遍历

文章目录 二叉树的前序遍历二叉树的中序遍历二叉树的后序遍历 二叉树的前序遍历 题目链接&#xff1a;二叉树的前序遍历 解题思路1&#xff1a;递归 代码如下&#xff1a; void preorder(vector<int>& res, TreeNode* root){if(root nullptr) return;//遇到空节点…...

文件操作/IO

文件 文件是一种在硬盘上存储数据的方式&#xff0c;操作系统帮我们把硬盘的一些细节都封装起来了&#xff0c;程序员只需要了解文件相关的接口即可&#xff0c;相当于操作文件就是间接的操作硬盘了 硬盘用来存储数据&#xff0c;和内存相比硬盘的存储空间更大&#xff0c;访问…...

基于Java+SpringBoot+vue前后端分离共享汽车管理系统设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…...

Mac RN环境搭建

RN ios android原生环境搭建有时候是真恶心&#xff0c;电脑环境不一样配置也有差异。 我已经安装官网的文档配置了ios环境 执行 npx react-nativelatest init AwesomeProject 报错 然后自己百度查呀执行 gem update --system 说是没有权限&#xff0c;执行失败。因为Mac…...

log4j教程_编程入门自学教程_菜鸟教程-免费教程分享

教程简介 Log4j是Apache的一个开源项目&#xff0c;通过使用Log4j&#xff0c;我们可以控制日志信息输送的目的地是控制台、文件、GUI组件&#xff0c;甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等&#xff1b;我们也可以控制每一条日志的输出格式&#xff1b;…...

DP——背包问题

DP——背包问题 01背包问题分数背包问题多重背包问题完全背包问题 当我们谈论背包问题时&#xff0c;可以想象成一个小朋友要去旅行&#xff0c;但是他只能带一个容量有限的背包。他有一些物品可以选择放入背包&#xff0c;每个物品都有自己的重量和价值。小朋友的目标是在不超…...

【从零学习python 】29. 「函数参数详解」——了解Python函数参数的不同用法

文章目录 函数参数详解一、缺省参数二、不定长参数三、缺省参数在*args后面可变、不可变类型总结 进阶案例 函数参数详解 一、缺省参数 调用函数时&#xff0c;缺省参数的值如果没有传入&#xff0c;则取默认值。 下例会打印默认的age&#xff0c;如果age没有被传入&#xf…...

10个经典战略分析模型,助力洞察市场明确优势

在企业的经营管理过程中&#xff0c;要时刻清晰内外部环境和自身的优劣势&#xff0c;做好企业略规划&#xff0c;进行企业内外部资源的分析&#xff0c;对经营环境&#xff0c;企业核心竞争力有足够的判断&#xff0c;才能明确企业的发展方向。本文为大家分享10个常用的战略分…...

C++(Qt)软件调试---将调试工具安装到AeDebug(11)

C(Qt)软件调试—将调试工具安装到AeDebug&#xff08;11&#xff09; 文章目录 C(Qt)软件调试---将调试工具安装到AeDebug&#xff08;11&#xff09;1、前言1.1 使用的调试工具 2、调试器安装1.1 WinDbg1.2 procdump1.3 DrMinGW1.4 vsjitdebugger 更多精彩内容&#x1f449;个…...

浅谈限流式保护器在住宅电气防火的应用

安科瑞 华楠 【摘要】随着人民生活水平的提高&#xff0c;家用大功率电器普遍被使用&#xff0c;导致用电量剧增&#xff0c;电气火灾频发。文章分析了电气火灾发生的原因&#xff0c;并时电气火灾的防范措施进行了探讨。 【关键词】电气火灾&#xff1b;原因&#xff1b;防范…...

ChatGPT助力ModStartBlog,博客写作更智能

ModStartBlog v7.1.0&#xff0c;ChatGPT 支持、界面全新优化 在数字化时代&#xff0c;博客已经成为人们分享知识、表达观点和建立个人品牌的重要工具。ModStartBlog是一款流行的博客平台&#xff0c;其最新的版本v7.1.0不仅增加了ChatGPT支持&#xff0c;还对界面进行了全新…...

Jpa与Druid线程池及Spring Boot整合(二): spring-boot-starter-data-jpa 踏坑异常处理方案

Jpa与Druid线程池及Spring Boot整合(一) Jpa与Druid线程池及Spring Boot整合(二)&#xff1a;几个坑 附录官网文档&#xff1a;core.domain-events域事件 从聚合根发布事件 存储库管理的实体是聚合根。在领域驱动设计应用程序中&#xff0c;这些聚合根通常会发布领域事件。Sp…...

Vue3组件库

Vue组件库 ViteVue3TypescriptTSX 1、项目搭建 1.1、创建项目&#xff08;yarn&#xff09; D:\WebstromProject>yarn create vite yarn create v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh pa…...

AUTOSAR从入门到精通-【应用篇】基于 CAN/LIN 总线的智能配电监控系统的研究设计

目录 前言 国内外研究现状 CAN 总线和 LIN 总线技术 2.1CAN 总线技术 2.1.1 通信模型...

数据安全服务能力评定资格证书-申请流程

数据安全服务能力评定&#xff08;以下简称能力评定&#xff09;是指对数据安全服务提供商从事数据安全服务综合能力的评定&#xff0c;包括技术能力、服务能力、质量保证能力、人员构成与素质、经营业绩、资产状况等要素。 用于对中华人民共和国境内的数据安全服务提供商提供…...

用js快速生成一个简单的css原子库 例如: .mr-18 .pl-18

第三方css原子库的缺点 比如 tailwindcss&#xff0c;有学习成本最开始写的时候效率可能还没有我们自己手写效率高&#xff0c;需要配置&#xff0c;会有原始样式被覆盖的问题&#xff1b;总之就是一个字重 自己搓的优点 学习成本低灵活不会有副作用 <!DOCTYPE html>…...

Java鹰眼轨迹服务 轻骑小程序 运动健康与社交案例

Java地图专题课 基本API BMapGLLib 地图找房案例 MongoDB 百度地图鹰眼轨迹服务 鹰眼轨迹服务概述 鹰眼是一套轨迹管理服务&#xff0c;提供各端SDK和API供开发者便捷接入&#xff0c;追踪所管理的车辆/人员等运动物体。 基于鹰眼提供的接口和云端服务&#xff0c;开发者可以迅…...

【产品经理】微信小程序隐私保护指引

为了分辨用户&#xff0c;开发者将在获取你的明示同意后&#xff0c;收集你的微信昵称、头像。 为了显示距离&#xff0c;开发者将在获取你的明示同意后&#xff0c;收集你的位置信息。 开发者收集你的地址&#xff0c;用于获取位置信息。 开发者收集你的发票信息&#xff0…...

springboot创建websocket服务端

springboot创建websocket服务端 1.配置类 package com.neusoft.airport.websocket;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndp…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...