JavaScript数据结构【进阶】

news2024/10/6 8:36:59

注:最后有面试挑战,看看自己掌握了吗


🌸I could be bounded in a nutshell and count myself a king of infinite space.
在这里插入图片描述


使用 splice() 添加元素

还记得在上个挑战中我们提到 splice() 方法最多可以接收 3 个参数吗? 第三个参数可以是一个或多个元素,这些元素会被添加到数组中。 这样,我们能够便捷地将数组中的一个或多个连续元素换成其他的元素。

const numbers = [10, 11, 12, 12, 15];
const startIndex = 3;
const amountToDelete = 1;

numbers.splice(startIndex, amountToDelete, 13, 14);
console.log(numbers);

第二个 12 已被删除,我们在同一索引处添加 13 和 14。 numbers 数组现在将会是 [ 10, 11, 12, 13, 14, 15 ]。

在上面的代码中,数组一开始包含了若干数字。 接着,我们调用 splice() 方法,索引为 (3) 的地方开始删除元素,删除的元素数量是 (1)。然后,(13, 14) 是在删除位置插入的元素。 可以在 amountToDelete 后面传入任意数量的元素(以逗号分隔),每个都会被插入到数组中。

我们已经定义了一个 htmlColorNames 函数,它以一个 HTML 颜色的数组作为输入参数。 请修改这个函数,使用 splice() 来移除数组中的前两个元素,并在对应的位置上添加 ‘DarkSalmon’ 和 ‘BlanchedAlmond’。

function htmlColorNames(arr) {
  // 只修改这一行下面的代码
  arr.splice(0,2,'DarkSalmon' ,'BlanchedAlmond')
  // 只修改这一行上面的代码
  return arr;
}

console.log(htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurquoise', 'FireBrick']));

使用 slice() 复制数组元素

接下来我们要介绍 slice() 方法。 slice() 不会修改数组,而是会复制,或者说*提取(extract)*给定数量的元素到一个新数组。 slice() 只接收 2 个输入参数:第一个是开始提取元素的位置(索引),第二个是提取元素的结束位置(索引)。 提取的元素中不包括第二个参数所对应的元素。 如下示例:

let weatherConditions = ['rain', 'snow', 'sleet', 'hail', 'clear'];

let todaysWeather = weatherConditions.slice(1, 3);

todaysWeather 值为 ['snow', 'sleet'],weatherConditions 值仍然为 [‘rain’, ‘snow’, ‘sleet’, ‘hail’, ‘clear’]。

在上面的代码中,我们从一个数组中提取了一些元素,并用这些元素创建了一个新数组。

我们已经定义了一个 forecast 函数,它接受一个数组作为参数。 请修改这个函数,利用 slice() 从输入的数组中提取信息,最终返回一个包含元素 warm 和 sunny 的新数组。

使用展开运算符复制数组

slice() 可以让我们从一个数组中选择一些元素来复制到新数组中,而 ES6 中又引入了一个简洁且可读性强的语法:展开运算符(spread operator),它能让我们方便地复制数组中的所有元素。 展开语法写出来是这样:...

我们可以用展开运算符来复制数组:

let thisArray = [true, true, undefined, false, null];
let thatArray = [...thisArray];

thatArray 等于 [true, true, undefined, false, null]。 thisArray 保持不变, thatArray 包含与 thisArray 相同的元素。

我们已经定义了一个 copyMachine 函数,它接受 arr(一个数组)和 num(一个数字)作为输入参数。 该函数需要返回一个由 num 个 arr 组成的新的二维数组。 同时,我们写好了大致的流程,只是细节实现还没有写完。 请修改这个函数,使用展开语法,使该函数能正常工作(提示:我们已经学到过的一个方法很适合用在这里)!

function copyMachine(arr, num) {
  let newArr = [];
  while (num >= 1) {
    // 只修改这一行下面的代码
    newArr.push([...arr])
    // 只修改这一行上面的代码
    num--;
  }
  return newArr;
}

console.log(copyMachine([true, false, true], 2));

使用展开运算符合并数组

展开语法(spread)的另一个重要用途是合并数组,或者将某个数组的所有元素插入到另一个数组的任意位置。 我们也可以使用 ES5 的语法连接两个数组,但只能让它们首尾相接。 而展开语法可以让这样的操作变得极其简单:

let thisArray = ['sage', 'rosemary', 'parsley', 'thyme'];

let thatArray = ['basil', 'cilantro', ...thisArray, 'coriander'];

thatArray 会有值 [‘basil’, ‘cilantro’, ‘sage’, ‘rosemary’, ‘parsley’, ‘thyme’, ‘coriander’]

使用展开语法,我们就可以很方便的实现一个用传统方法会写得很复杂且冗长的操作。

我们已经定义了一个返回 sentence 变量的 spreadOut 函数。 请修改这个函数,利用 spread 使该函数返回数组 [‘learning’, ‘to’, ‘code’, ‘is’, ‘fun’]。

使用 indexOf() 检查元素是否存在

由于数组随时都可以修改或发生 mutated,我们很难保证某个数据始终处于数组中的特定位置,甚至不能保证该元素是否还存在于该数组中。 好消息是,JavaScript 为我们提供了内置方法 indexOf()。 这个方法让我们可以方便地检查某个元素是否存在于数组中。 indexOf() 方法接受一个元素作为输入参数,并返回该元素在数组中的位置(索引);若该元素不存在于数组中则返回 -1。

例如:

let fruits = ['apples', 'pears', 'oranges', 'peaches', 'pears'];

fruits.indexOf('dates');
fruits.indexOf('oranges');
fruits.indexOf('pears');

indexOf(‘dates’) 返回 -1,indexOf(‘oranges’) 返回 2,indexOf(‘pears’) 返回 1 (每个元素存在的第一个索引)。

indexOf() 在快速检查一个数组中是否存在某个元素时非常有用。 我们已经定义了一个 quickCheck 函数,它接受一个数组和一个元素作为输入参数。 请通过 indexOf() 方法修改这个函数,使得当传入的参数在数组中存在时返回 true,否则返回 false。

function quickCheck(arr, elem) {
  // 只修改这一行下面的代码
 return arr.indexOf(elem)>=0?true
 :false
  // 只修改这一行上面的代码
}

console.log(quickCheck(['squash', 'onions', 'shallots'], 'mushrooms'));

使用 for 循环遍历数组中的全部元素

使用数组时,我们经常需要遍历数组的所有元素来找出我们需要的一个或多个元素,抑或是对数组执行一些特定的操作。 JavaScript 为我们提供了几个内置的方法,它们以不同的方式遍历数组,以便我们可以用于不同的场景(如 every()、forEach()、map() 等等)。 然而,最简单的 for 循环不仅能实现上述这些方法的功能,而且相比之下也会更加灵活。

请看以下的例子:

function greaterThanTen(arr) {
  let newArr = [];
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] > 10) {
      newArr.push(arr[i]);
    }
  }
  return newArr;
}


greaterThanTen([2, 12, 8, 14, 80, 0, 1]);

在这个函数中,我们用一个 for 循环来遍历数组,逐一对其中的元素进行判断。 通过上面的代码,我们可以找出数组中大于 10 的所有元素,并返回一个包含这些元素的新数组 [12, 14, 80]。

我们已经定义了 filteredArray 函数,它接受一个嵌套的数组 arr 和一个 elem 作为参数,并要返回一个新数组。 arr 数组中嵌套的数组里可能包含 elem 元素,也可能不包含。 请修改该函数,用一个 for 循环来做筛选,使函数返回一个由 arr 中不包含 elem 的数组所组成的新数组。

function filteredArray(arr, elem) {
  let newArr = [];
  // 只修改这一行下面的代码
for(let i=0;i<arr.length;i++){
  if(arr[i].indexOf(elem)==-1){
    newArr.push(arr[i])
  }
}
  // 只修改这一行上面的代码
  return newArr;
}

console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));
function filteredArray(arr, elem) {
  let newArr = [];
  // 只修改这一行下面的代码
for(let i=0;i<arr.length;i++){
  let j=0
  for(;j<arr[i].length;j++){

  if(elem==arr[i][j]){
    break;
  }
  
}
if(j==arr[i].length){
    newArr.push(arr[i]);
}
}
  // 只修改这一行上面的代码
  return newArr;
}

console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));

创建复杂的多维数组

很好! 你现在已经学到很多关于数组的知识了, 但这些只是个开始。我们将在接下来的中挑战中学到更多与数组相关的知识。 但在继续查看 对象 之前,让我们再看一下,看看数组如何变得比我们在之前的挑战中看到的更复杂一些。

数组的一个强大的特性是,它可以包含其他数组,甚至完全由其他数组组成。 在上一个挑战中,我们已经接触到了包含数组的数组,但它还算是比较简单的。 数组中的数组还可以再包含其他数组,即可以嵌套任意多层数组。 通过这种方式,数组可以很快成为非常复杂的数据结构,称为多维(multi-dimensional)数组,或嵌套(nested)数组。 请看如下的示例:

let nestedArray = [
  ['deep'],
  [
    ['deeper'], ['deeper'] 
  ],
  [
    [
      ['deepest'], ['deepest']
    ],
    [
      [
        ['deepest-est?']
      ]
    ]
  ]
];

deep 数组已嵌套 2 层。 deeper 数组嵌套了 3 层。 deepest 数组嵌套了 3 层, deepest-est? 嵌套了 5 层。

虽然这个例子看起来错综复杂,不过,尤其是在处理大量数据的时候,这种数据结构还是会用到的。 尽管结构复杂,不过我们仍可以通过方括号表示法来访问嵌套得最深的数组:

console.log(nestedArray[2][1][0][0][0]);

控制台打印的是字符串 deepest-est?。 既然我们知道数据的位置,当然,我们也可以修改它:

nestedArray[2][1][0][0][0] = 'deeper still';

console.log(nestedArray[2][1][0][0][0]);

现在控制台打印的是 deeper still。

我们已经定义了一个叫做 myNestedArray 的数组变量。 请修改 myNestedArray,使用字符串(string)、数字(number)或布尔值(boolean)的任意组合作为数组的元素,并让 myNestedArray 刚好有 5 层(注意,最外层的数组是第 1 层)。 同时,请在第 3 层的数组中包含字符串 deep;在第 4 层的数组中包含字符串 deeper,在第 5 层的数组中包含字符串 deepest。

将键值对添加到对象中

对象(object)本质上是键值对(key-value pair)的集合。 或者说,一系列被映射到唯一标识符的数据就是对象;习惯上,唯一标识符叫做属性(property)或者键(key);数据叫做值(value)。 让我们来看一个简单的例子:

const tekkenCharacter = {
  player: 'Hwoarang',
  fightingStyle: 'Tae Kwon Doe',
  human: true
};

上面的代码定义了一个叫做 tekkenCharacter 的“铁拳”游戏人物对象。 它有三个属性,每个属性都对应一个特定的值。 如果我们想为它再添加一个叫做 origin 的属性,可以这样写:

tekkenCharacter.origin = 'South Korea';

上面的代码中,我们使用了点号表示法。 如果我们现在输出 tekkenCharacter 对象,便可以看到它具有 origin 属性。 接下来,因为这个人物在游戏中有着与众不同的橘色头发, 我们可以通过方括号表示法来为它添加这个属性,像这样:

tekkenCharacter['hair color'] = 'dyed orange';

如果要设置的属性中存在空格,或者要设置的属性是一个变量,那我们必须使用方括号表示法(bracket notation)来为对象添加属性。 在上面的代码中,我们把属性(hair color)放到引号里,以此来表示整个字符串都是需要设置的属性。 如果我们不加上引号,那么中括号里的内容会被当作一个变量来解析,这个变量对应的值就会作为要设置的属性, 请看这段代码:

const eyes = 'eye color';


tekkenCharacter[eyes] = 'brown';

执行以上所有示例代码后,对象会变成这样:

{
  player: 'Hwoarang',
  fightingStyle: 'Tae Kwon Doe',
  human: true,
  origin: 'South Korea',
  'hair color': 'dyed orange',
  'eye color': 'brown'
};

我们已经为你创建了包含三个项目的 foods 对象。 请使用上述任意语法,来为 foods 对象添加如下三个键值对:bananas 属性,值为 13;grapes 属性,值为 35;strawberries 属性,值为 27。

修改嵌套在对象中的对象

现在我们来看一个稍复杂的对象。 在对象中,我们也可以嵌套任意层数的对象,对象的属性值可以是 JavaScript 支持的任意类型,包括数组和其他对象。 请看以下例子:

let nestedObject = {
  id: 28802695164,
  date: 'December 31, 2016',
  data: {
    totalUsers: 99,
    online: 80,
    onlineStatus: {
      active: 67,
      away: 13,
      busy: 8
    }
  }
};

nestedObject 有 3 个属性:id(属性值为数字)、date(属性值为字符串)、data(属性值为嵌套的对象)。 虽然对象中的数据可能很复杂,我们仍能使用上一个挑战中讲到的写法来访问我们需要的信息。 如果我们想把嵌套在 onlineStatus 中 busy 的属性值改为 10,可以用点号表示法来这样实现:

nestedObject.data.onlineStatus.busy = 10;

我们已经定义了一个 userActivity 对象,它包含了另一个对象。 请将 online 的属性值改为 45。

使用方括号访问属性名称

在关于对象的第一个挑战中,我们提到可以在一对方括号中用一个变量作为属性名来访问属性的值。 假设一个超市收银台程序中有一个 foods 对象, 并且有一个函数会设置 selectedFood;如果我们需要查询 foods 对象中,某种食物是否存在, 可以这样实现:

let selectedFood = getCurrentFood(scannedItem);
let inventory = foods[selectedFood];

上述代码会先读取 selectedFood 变量的值,并返回 foods 对象中以该值命名的属性所对应的属性值。 若没有以该值命名的属性,则会返回 undefined。 有时候对象的属性名在运行之前是不确定的,或者我们需要动态地访问对象的属性值。在这些场景下,方括号表示法就变得十分有用

我们已经定义了 checkInventory 函数,它接受一个被扫描到的商品名作为输入参数。 请让这个函数返回 foods 对象中,以 scannedItem 的值所命名的属性对应的属性值。 在本挑战中,只有合理有效的属性名会作为参数传入 checkInventory,因此你不需要处理参数无效的情况。

使用 delete 关键字删除对象属性

现在我们已经学习了什么是对象以及对象的基本特性和用途。 总之,对象是以键值对的形式,灵活、直观地存储结构化数据的一种方式,而且,通过对象的属性查找属性值是速度很快的操作。 在本章余下的挑战中,我们来了解一下对象的几种常用操作,这样你能更好地在代码中使用这个十分有用的数据结构:对象。

在之前的挑战中,我们已经试过添加和修改对象中的键值对。 现在我们来看看如何从一个对象中移除一个键值对。

我们再来回顾一下上一个挑战中的 foods 对象。 如果我们想移除 apples 属性,可以像这样使用 delete 关键字:

delete foods.apples;

请使用 delete 关键字来移除 foods 中的 oranges、plums 和 strawberries 属性。

检查对象是否具有某个属性

我们已经学习了如何添加、修改和移除对象中的属性。 但如果我们想知道一个对象中是否包含某个属性呢? JavaScript 为我们提供了两种不同的方式来实现这个功能: 一个是通过 hasOwnProperty() 方法,另一个是使用 in 关键字。 假如我们有一个 users 对象,为检查它是否含有 Alan 属性,可以这样写:

users.hasOwnProperty('Alan');
'Alan' in users;

这两者结果都应该为 true。

请完善这个函数,如果传递给它的对象包含四个名字 Alan、Jeff、Sarah 和 Ryan,函数返回 true,否则返回 false。

使用 for…in 语句遍历对象

有时候你需要遍历一个对象中的所有键。 你可以使用 for...in 循环来做这件事。 for…in 循环是这样的:

const refrigerator = {
  'milk': 1,
  'eggs': 12,
};

for (const food in refrigerator) {
  console.log(food, refrigerator[food]);
}

以上代码记录 milk 1 和 eggs 12,每个键值对单独为一行。

我们在循环头中定义了变量 food ,这个变量被设置为每次迭代上对象的每个键值,将每个食物的名称打印到控制台。

注意:对象中的键是无序的,这与数组不同。 因此,一个对象中某个属性的位置,或者说它出现的相对顺序,在引用或访问该属性时是不确定的。

我们定义了一个函数 countOnline,它接收一个参数 allUsers。 在这个函数中使用 for…in 语句来遍历 allUsers 对象,并返回 online 属性为 true 的用户数量。 一个可以传递给 countOnline 的对象的例子显示如下。 每个用户都有 online 属性,其属性值为 true 或 false。

{
  Alan: {
    online: false
  },
  Jeff: {
    online: true
  },
  Sarah: {
    online: false
  }
}

使用 Object.keys() 生成由对象的所有属性组成的数组

我们可以给 Object.keys() 方法传入一个对象作为参数,来生成包含对象所有键的数组。 这个方法将对象作为参数并返回代表对象中每个属性的字符串数组。 需要注意的是,数组中元素的顺序是不确定的。

请完成 getArrayOfUsers 函数的实现,使其返回一个由输入对象中的所有属性所组成的数组。

let users = {
  Alan: {
    age: 27,
    online: false
  },
  Jeff: {
    age: 32,
    online: true
  },
  Sarah: {
    age: 48,
    online: false
  },
  Ryan: {
    age: 19,
    online: true
  }
};

function getArrayOfUsers(obj) {
  // 只修改这一行下面的代码
return Object.keys(obj)
  // 只修改这一行上面的代码
}

console.log(getArrayOfUsers(users));

修改存储在对象中的数组

我们已经学习了 JavaScript 对象的这些基本操作: 添加、修改、移除键值对、检查某个属性是否存在、遍历对象的所有属性。 在继续学习 JavaScript 的过程中,我们会了解对象的更多用法。 另外,在之后的数据结构课程中,我们还会学习 ES6 的 Map 和 Set。 这两种数据结构与我们现在学到的对象十分类似,但它们在对象的基础上提供了一些额外的功能。 目前,我们已经学习了数组和对象的基础知识,让我们试着来用所学的知识解决一些更复杂的问题。

请看一下代码编辑器中我们为你写好的对象。 user 对象包含 3 个属性; data 对象包含 5 个属性,其中包含一个叫做 friends 的数组。 这就是对象作为数据结构所展现出的灵活性。 我们已经写好了 addFriend 函数的一部分, 请你完成这个函数,使其接受一个 user 对象,将 friend 参数中的名字添加到 user.data.friends 数组中并返回该数组。

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

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

相关文章

阶段总结(linux基础)

目录 一、初始linux系统 二、基本操作命令 三、目录结构 四、文件及目录管理命令 查看文件内容 创建文件 五、用户与组管理 六、文件权限与压缩管理 七、磁盘管理 八、系统程序与进程管理 管理机制 文件系统损坏 grub引导故障 磁盘资源耗尽 程序与进程的区别 查…

Grafana V10 告警推送

最近项目建设完成&#xff0c;一个城域网项目&#xff0c;相关zabbix和grafana展示已经完&#xff0c;想了想&#xff0c;不想天天看平台去盯网络监控平台&#xff0c;索性对告警进行分类调整&#xff0c;增加告警的推送&#xff0c;和相关部门的提醒&#xff0c;其他部门看不懂…

绿盾用户使用看图软件每次都需要把图片解密之后才能打开查看,怎么才能不用这么麻烦打开就能看

环境: Win10专业版 绿盾控制台7.0 看图软件FastStone Image Viewer 问题描述: 绿盾用户使用看图软件FastStone Image Viewer每次都需要把图片解密之后才能打开查看,怎么才能不用这么麻烦打开就能看,用户说每次都需要把图片解密之后才能使用,实在是影响效率 解决方案…

4、长度最小的子数组

找到一个数组中&#xff0c;有多少个连续元素的和小于某个值&#xff0c;求出连续元素的长度的最小值。 滑动窗口法&#xff1a; 其本质也是快慢指针&#xff0c;一个指针指向窗口的起始位置&#xff0c;另一个指针指向窗口的终止位置。 1.定义快慢指针&#xff1a; 2.更新慢指…

css-3:什么是响应式设计?响应式的原理是什么?如何做?

1、响应式设计是什么&#xff1f; 响应式网站设计&#xff08;Responsive WEB desgin&#xff09;是一个网络页面设计布局&#xff0c;页面的设计与开发应当根据用户行为以及设备环境&#xff08;系统平台、屏幕尺寸、屏幕定向等&#xff09;进行相应的相应和调整。 描述响应式…

Unity 实现字幕打字效果

Text文本打字效果&#xff0c;TextMeshPro可以对应参考&#xff0c;差距不大&#xff0c;改改参数名就能用。改脚本原本被我集成到其他的程序集中&#xff0c;现在已经分离。 效果 实现功能 1.能够设置每行能够容纳的字数和允许的冗余 2.打字效果 3.每行打完上移 4.开头进入&…

项目实战 — 消息队列(5){统一硬盘操作}

前面已经使用数据库管理了交换机、绑定、队列&#xff0c;然后又使用了数据文件管理了消息。 那么&#xff0c;这里就创建一个类&#xff0c;讲之前的两个部分整合起来&#xff0c;对上层提供统一的一套接口&#xff0c;表示硬盘上存储的所有的类的信息。 /* * 用这个类来管理…

C++笔记之enum class和emun的区别

C笔记之enum class和emun的区别 code review! 代码,使用 enum class 的示例&#xff1a; #include <iostream>enum class Month { January, February, March, April, May, June, July, August, September, October, November, December };int main() {Month currentM…

龙迅LT8711H是Type-C/DP1.2转HDMI1.4芯片 -现货来了

1.概述 LT8711H是一款高性能Type-C / DP1.2至HDMI1.4转换器&#xff0c;旨在将USB Type-C源或DP1.2源连接至HDMI1.4接收器。 LT8711H集成了符合DP1.2的接收器和符合HDMI1.4的发送器。此外&#xff0c;还包括两个CC控制器&#xff0c;用于CC通信以实现DP Alt Mode和功率传输功…

Frida 编译(去特征)

Frida 编译&#xff08;去特征&#xff09; 编译最新版server编译往期版server更改特征使用定制库 hluwa本文引用&#xff1a; 本文环境&#xff1a; kali-linux-xfce 编译最新版server 第一步&#xff1a; 下载frida git clone --recurse-submodules https://github.com/fri…

Redis键值设计

1.1、优雅的key结构 Redis的Key虽然可以自定义&#xff0c;但最好遵循下面的几个最佳实践约定&#xff1a; 遵循基本格式&#xff1a;[业务名称]:[数据名]:[id]长度不超过44字节不包含特殊字符 例如&#xff1a;我们的登录业务&#xff0c;保存用户信息&#xff0c;其key可以…

模型训练技术指南

目录 引言 1. 模型训练的重要性 2. 数据预处理 3. 特征工程 4. 模型选择与评估 5. 参数调优 6. 模型集成 7. 过拟合与欠拟合 8. 模型保存与加载 9. 分布式训练与加速 10. 最佳实践与常见问题 引言 模型训练是机器学习领域中至关重要的一步&#xff0c;它决定了模型的…

处理该文件没有与之关联的应用来执行该操作,若已经安装应用,请在“默认应用设置”页面中创建关联

一、晚上在睡觉前接到一个删除了注册表导致的错误消息 二、解决方法一&#xff1a; 桌面新建 txt&#xff0c;把下面的代码复制粘贴到 txt 文件&#xff0c;然后重命名为1.bat&#xff0c;右键以管理员身份运行。 taskkill /f /im explorer.exe reg add "HKEY_LOCAL_MA…

【数据结构与算法】二叉排序树(BST)

二叉排序树&#xff08;BST&#xff09; 需求&#xff1a; 给你一个数列{7,3,10,12,5,1,9}&#xff0c;要求能够高效的完成对数据的查询和添加。 解决方案分析 使用数组 数组未排序&#xff0c;优点&#xff1a;直接在数组尾添加&#xff0c;速度快。缺点&#xff1a;查找速…

了解华为(H3C)网络设备和OSI模型基本概念

目录 一&#xff0c;认识华为 1.华为发展史 2.华为网络设备介绍 3.VRP概述 二&#xff0c;OSI七层模型 1.七层模型详细表格 2.各层的作用 3.数据在各层之间的传递过程 4.OSI四层网络模型 一&#xff0c;认识华为 官网&#xff1a;https://www.huawei.com/cn/ 1.华为发…

记录一个CMD命令异常 文件名、目录名或卷标语法不正确。

由git clone下来导致缺少符号 使用文档格式转换-转为windows-CR LF即可。 当前测试的命令内容 >cs 文件名、目录名或卷标语法不正确。 ho 不是内部或外部命令&#xff0c;也不是可运行的程序 或批处理文件。 系统默认的nodepad好像不能转换&#xff0c;直接新建一个文件&am…

【GTest学习】

1. GTest简介&#xff1a; GTest 就是 Google Test, 它是一个免费开源的测试框架, 用于编写测试用 C语言编写的程序(C 程序也能用, 但是需要用 C编译器编译)。gtest的官方网站是&#xff1a;http://code.google.com/p/googletest/ 2.GTest下载与环境搭建&#xff1a; GTest 下…

【雕爷学编程】Arduino动手做(195)---HT16k33 矩阵 8*8点阵屏模块4

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

MFC计算分贝

分贝的一种定义是&#xff0c;表示功率量之比的一种单位&#xff0c;等于功率强度之比的常用对数的10倍&#xff1b; 主要用于度量声音强度&#xff0c;常用dB表示&#xff1b; 其计算&#xff0c;摘录网上一段资料&#xff1b; 声音的分贝值可以通过以下公式计算&#xff1…

python爬虫(七)_urllib2:urlerror和httperror

python爬虫(七)_urllib2&#xff1a;urlerror和httperror urllib2的异常错误处理 在我们用urlopen或opener.open方法发出一个请求时&#xff0c;如果urlopen或opener.open不能处理这个response&#xff0c;就产生错误。 这里主要说的是URLError和HTTPError,以及对它们的错误…