【Node】Assertion testing 模块的使用

简言

node:assert 模块提供了一组用于验证不变式的断言函数。
node版本:20.14.0

Assertion testing 测试断言模块

node:assert 模块是一个测试相关的模块。

严格模式和非严格模式

感觉该模块的严格模式和js的严格模式相匹配,非严格模式也是这样的。
严格模式下,那些非严格的API会和严格API作用相同。
使用严格模式:


import { strict as assert } from 'node:assert';
//	或
import assert from 'node:assert/strict';

这里使用的是ESM的模块语法,在package.json的type属性为module时启用。

例如,assert.deepEqual() 的行为与 assert.deepStrictEqual() 类似。

import { strict as assert } from 'node:assert';

assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);

在这里插入图片描述
严格模式下,会报错(比较不进行类型转换),非严格模式则不会。

Class: assert.AssertionError

表示断言失败。node:assert 模块抛出的所有错误都是 AssertionError 类的实例。
它是Error的子类 表示断言失败。
所有实例都包含内置的错误属性(信息和名称)和错误信息:

  • actual —— 设置为 assert.strictEqual() 等方法的实际参数,就是要测试的值。
  • expected —— 设置为 assert.strictEqual() 等方法的预期值。
  • generatedMessage —— 表示信息是否自动生成(true)。
  • code —— 值总是 ERR_ASSERTION,以显示错误是断言错误
  • operator —— 设置为传入的运算符值
import assert from 'node:assert';

// Generate an AssertionError to compare the error message later:
const { message } = new assert.AssertionError({
  actual: 1,
  expected: 2,
  operator: 'strictEqual',
});

// Verify error output:
try {
  assert.strictEqual(1, 2);
} catch (err) {
  assert(err instanceof assert.AssertionError);
  assert.strictEqual(err.message, message);
  assert.strictEqual(err.name, 'AssertionError');
  assert.strictEqual(err.actual, 1);
  assert.strictEqual(err.expected, 2);
  assert.strictEqual(err.code, 'ERR_ASSERTION');
  assert.strictEqual(err.operator, 'strictEqual');
  assert.strictEqual(err.generatedMessage, true);
}

assert(value[, message]) 测试否为真值

assert.ok() 的别名。
测试值是否为真。它等同于 assert.equal(!!value,true,message)。

assert.ok(value[, message])

测试值是否为真。它等同于 assert.equal(!!value,true,message)。
如果值不是真值,则抛出一个 AssertionError,其消息属性设置等于消息参数的值。如果 message 参数未定义,则会分配一个默认错误信息。如果消息参数是 Error 的实例,则将抛出 Error 而不是 AssertionError。如果没有传递参数,则消息将被设置为字符串:“没有向 assert.ok() 传递值参数”。

import assert from 'node:assert/strict';

assert.ok(true);
// OK
assert.ok(1);
// OK

assert.ok();
// AssertionError: No value argument passed to `assert.ok()`

assert.ok(false, 'it\'s false');
// AssertionError: it's false

// In the repl:
assert.ok(typeof 123 === 'string');
// AssertionError: false == true

// In a file (e.g. test.js):
assert.ok(typeof 123 === 'string');
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(typeof 123 === 'string')

assert.ok(false);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(false)

assert.ok(0);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(0)

assert.deepEqual(actual, expected[, message]) 深度比较

严格模式下,相当于assert.deepStrictEqual() 的别名。
测试实际参数与预期参数之间的深度相等。考虑使用 assert.deepStrictEqual() 代替 assert.deepEqual()。assert.deepEqual() 可能会产生令人惊讶的结果。
有三个参数:

  • actual —— 测试值。
  • expected —— 预期值。
  • message —— 错误信息。

深层等价意味着子对象的可枚举 "自有 "属性也要按照以下规则进行递归评估。
比较细节:

  • 除NaN 外,使用 == 运算符比较原始值。如果两边都是 NaN,则视为相同。
  • 对象的类型标记应相同。
  • 只考虑可枚举的 "自有 "属性。
  • 即使错误名称和信息不是可枚举的属性,也始终会进行比较。
  • 对象包装器既可以作为对象进行比较,也可以作为未包装的值进行比较。
  • 对象属性是无序比较的。
  • Map键和Set项无序比较。
  • 当两边不同时或两边都遇到循环参照时,递归停止。
  • 对象原型不参与测试
  • 符号(Symbol)属性不进行比较。
  • WeakMap 和 WeakSet 的比较不依赖于它们的值。
  • RegExp 的 lastIndex、flags 和 source 始终会进行比较,即使这些属性不是可枚举属性。
import assert from 'node:assert';

const obj1 = {
  a: {
    b: 1,
  },
};
const obj2 = {
  a: {
    b: 2,
  },
};
const obj3 = {
  a: {
    b: 1,
  },
};
const obj4 = { __proto__: obj1 };

assert.deepEqual(obj1, obj1);
// OK

// Values of b are different:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }

assert.deepEqual(obj1, obj3);
// OK

// Prototypes are ignored:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}

如果值不相等,则抛出一个 AssertionError,其消息属性设置等于消息参数的值。如果消息参数未定义,则会分配一个默认错误消息。如果消息参数是 Error 的实例,则将抛出 Error 而不是 AssertionError。

assert.deepStrictEqual(actual, expected[, message]) 深度严格比较

参数:

  • actual <any> —— 比较值
  • expected <any> —— 预期值
  • message <string> | <Error> —— 错误信息

测试实际参数和预期参数是否深度相等。"深度 "相等是指子对象的可枚举 "自身 "属性也按照以下规则进行递归评估。

  • 使用 Object.is() 对原始值进行比较。
  • 对象的类型标记应相同。
  • 对象原型使用 === 操作符进行比较。
  • 只考虑可枚举的 "自有 "属性。
  • 即使错误名称和信息不是可枚举的属性,也始终会进行比较。
  • 还对可枚举的自有Symbol属性进行了比较。
  • 对象包装器既可以作为对象进行比较,也可以作为未包装的值进行比较。
  • 对象属性是无序比较的。
  • Map key 和Set 项无序比较。
  • 当两边不同时或两边都遇到循环参照时,递归停止。
  • WeakMap 和 WeakSet 的比较并不依赖于它们的值。
  • RegExp 的 lastIndex、flags 和 source 始终会被比较,即使这些属性不是可枚举属性。
import assert from 'node:assert/strict';

// This fails because 1 !== '1'.
assert.deepStrictEqual({ a: 1 }, { a: '1' });
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
//   {
// +   a: 1
// -   a: '1'
//   }

// The following objects don't have own properties
const date = new Date();
const object = {};
const fakeDate = {};
Object.setPrototypeOf(fakeDate, Date.prototype);

// Different [[Prototype]]:
assert.deepStrictEqual(object, fakeDate);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + {}
// - Date {}

// Different type tags:
assert.deepStrictEqual(date, fakeDate);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + 2018-04-26T00:49:08.604Z
// - Date {}

assert.deepStrictEqual(NaN, NaN);
// OK because Object.is(NaN, NaN) is true.

// Different unwrapped numbers:
assert.deepStrictEqual(new Number(1), new Number(2));
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + [Number: 1]
// - [Number: 2]

assert.deepStrictEqual(new String('foo'), Object('foo'));
// OK because the object and the string are identical when unwrapped.

assert.deepStrictEqual(-0, -0);
// OK

// Different zeros:
assert.deepStrictEqual(0, -0);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + 0
// - -0

assert.doesNotMatch(string, regexp[, message]) 不匹配正则

希望输入的字符串与正则表达式不匹配。
参数:

  • string —— 测试字符串值。
  • regexp —— 匹配正则
  • message —— 错误消息

如果值确实匹配,或者字符串参数是字符串以外的其他类型,则会抛出一个 AssertionError,其消息属性等于消息参数的值。如果消息参数未定义,则会分配默认错误消息。

import assert from 'node:assert/strict';

assert.doesNotMatch('I will fail', /fail/);
// AssertionError [ERR_ASSERTION]: The input was expected to not match the ...

assert.doesNotMatch(123, /pass/);
// AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.

assert.doesNotMatch('I will pass', /different/);
// OK

assert.doesNotReject(asyncFn[, error][, message]) 不会拒绝

等待 asyncFn 承诺,如果 asyncFn 是一个函数,则立即调用该函数并等待返回的承诺完成。然后,它会检查承诺是否被拒绝。
如果 asyncFn 是一个函数,并且同步抛出错误,assert.doesNotReject() 将返回一个带有该错误的被拒绝 Promise。如果函数不返回 Promise,assert.doesNotReject() 将返回带有 ERR_INVALID_RETURN_VALUE 错误的被拒绝 Promise。在这两种情况下,错误处理程序都会被跳过。
使用 assert.doesNotReject() 实际上并没有什么用处,因为捕捉到拒绝后再次拒绝并没有什么好处。相反,可以考虑在不应该拒绝的特定代码路径旁边添加注释,并尽可能保持错误信息的表现力。
除了 await 的异步性质外,完成的行为与 assert.doesNotThrow() 相同。

import assert from 'node:assert/strict';

await assert.doesNotReject(
  async () => {
    throw new TypeError('Wrong value');
  },
  SyntaxError,
);

assert.doesNotThrow(fn[, error][, message]) 函数不报错

断言函数 fn 不会出错。
当 assert.doesNotThrow() 被调用时,它会立即调用 fn 函数。
如果抛出的错误与错误参数指定的类型相同,则会抛出一个 AssertionError。如果错误的类型不同,或者错误参数未定义,则错误会传播回调用者。
例如,由于断言中没有匹配的错误类型,以下代码将抛出 TypeError:

import assert from 'node:assert/strict';

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value');
  },
  SyntaxError,
);

使用 assert.doesNotThrow() 实际上并无用处,因为捕获错误后再重新抛出没有任何好处。相反,可以考虑在不应该抛出错误的特定代码路径旁边添加注释,并尽可能保持错误信息的表现力。

assert.equal(actual, expected[, message]) 比较

严格模式下,assert.strictEqual() 的别名。
使用 == 运算符测试实际参数和预期参数之间的浅层强制相等性。如果两边都是 NaN,则 NaN 会被特殊处理并视为相同。

import assert from 'node:assert';

assert.equal(1, 1);
// OK, 1 == 1
assert.equal(1, '1');
// OK, 1 == '1'
assert.equal(NaN, NaN);
// OK

assert.equal(1, 2);
// AssertionError: 1 == 2
assert.equal({ a: { b: 1 } }, { a: { b: 1 } });
// AssertionError: { a: { b: 1 } } == { a: { b: 1 } }

如果值不相等,则抛出一个 AssertionError,其消息属性设置等于消息参数的值。如果消息参数未定义,则会分配一个默认错误消息。如果消息参数是 Error 的实例,则将抛出 Error 而不是 AssertionError。

assert.strictEqual(actual, expected[, message]) 严格比较

测试由 Object.is() 确定的实际参数和预期参数之间的严格相等性。

import assert from 'node:assert/strict';

assert.strictEqual(1, 2);
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
//
// 1 !== 2

assert.strictEqual(1, 1);
// OK

assert.strictEqual('Hello foobar', 'Hello World!');
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
// + actual - expected
//
// + 'Hello foobar'
// - 'Hello World!'
//          ^

const apples = 1;
const oranges = 2;
assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`);
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2

assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
// TypeError: Inputs are not identical

assert.fail([message]) 抛出错误信息

抛出带有提供的错误信息或默认错误信息的 AssertionError。如果消息参数是一个 Error 实例,则将抛出 Error 而不是 AssertionError。

import assert from 'node:assert/strict';

assert.fail();
// AssertionError [ERR_ASSERTION]: Failed

assert.fail('boom');
// AssertionError [ERR_ASSERTION]: boom

assert.fail(new TypeError('need array'));
// TypeError: need array

assert.ifError(value) 是否是未定义或空值

如果值不是未定义或空,则抛出值。这在测试回调中的错误参数时非常有用。堆栈跟踪包含传递给 ifError() 的错误的所有帧,包括 ifError() 本身的潜在新帧。

import assert from 'node:assert/strict';

assert.ifError(null);
// OK
assert.ifError(0);
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 0
assert.ifError('error');
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 'error'
assert.ifError(new Error());
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error

// Create some random error frames.
let err;
(function errorFrame() {
  err = new Error('test error');
})();

(function ifErrorFrame() {
  assert.ifError(err);
})();
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error
//     at ifErrorFrame
//     at errorFrame

assert.match(string, regexp[, message]) 正则匹配

希望输入的字符串与正则表达式匹配。

import assert from 'node:assert/strict';

assert.match('I will fail', /pass/);
// AssertionError [ERR_ASSERTION]: The input did not match the regular ...

assert.match(123, /pass/);
// AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.

assert.match('I will pass', /pass/);
// OK

assert.notDeepEqual(actual, expected[, message]) 深度不相等比较

严格模式下,assert.notDeepStrictEqual() 的别名。
测试任何深度不等式。与 assert.deepEqual() 相反。

assert.notDeepStrictEqual(actual, expected[, message]) 严格深度不相等比较

测试深度严格不等式。与 assert.deepStrictEqual() 相反。

import assert from 'node:assert/strict';

assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// OK

assert.notEqual(actual, expected[, message]) 不相等比较

严格模式下,assert.notStrictEqual() 的别名。
使用 != 运算符测试浅层强制不等式。如果两边都是 NaN,NaN 会被特殊处理并视为相同。

import assert from 'node:assert';

assert.notEqual(1, 2);
// OK

assert.notEqual(1, 1);
// AssertionError: 1 != 1

assert.notEqual(1, '1');
// AssertionError: 1 != '1'

assert.notStrictEqual(actual, expected[, message]) 严格不相等比较

测试由 Object.is() 确定的实际参数和预期参数之间的严格不等式。

import assert from 'node:assert/strict';

assert.notStrictEqual(1, 2);
// OK

assert.notStrictEqual(1, 1);
// AssertionError [ERR_ASSERTION]: Expected "actual" to be strictly unequal to:
//
// 1

assert.notStrictEqual(1, '1');
// OK

assert.rejects(asyncFn[, error][, message]) 是否拒绝

等待 asyncFn 承诺,如果 asyncFn 是一个函数,则立即调用该函数并等待返回的承诺完成。然后,它会检查该承诺是否被拒绝。
如果 asyncFn 是一个函数,并且同步抛出错误,assert.rejections() 将返回一个带有该错误的被拒绝 Promise。如果函数不返回 Promise,assert.rejections() 将返回带有 ERR_INVALID_RETURN_VALUE 错误的被拒绝 Promise。在这两种情况下,错误处理程序都会被跳过。
除了 await 的异步性质外,完成的行为与 assert.throws() 相同。
如果指定,error 可以是一个类、RegExp、一个验证函数、一个将测试每个属性的对象,或者是一个将测试每个属性(包括不可累加的消息和名称属性)的 error 实例。
如果指定,当 asyncFn 拒绝失败时,message 将是 AssertionError 提供的信息。

import assert from 'node:assert/strict';

await assert.rejects(
  async () => {
    throw new TypeError('Wrong value');
  },
  {
    name: 'TypeError',
    message: 'Wrong value',
  },
);

assert.throws(fn[, error][, message]) 是否抛错

希望函数 fn 引发错误。
如果指定,error 可以是一个类、RegExp、一个验证函数、一个验证对象(其中每个属性都将进行严格的深度相等测试),或者是 error 的一个实例(其中每个属性都将进行严格的深度相等测试,包括不可数的消息和名称属性)。使用对象验证字符串属性时,也可以使用正则表达式。请参阅下面的示例。
如果指定,在 fn 调用失败或错误验证失败时,信息将附加到 AssertionError 提供的信息中。
自定义验证对象/错误实例:

import assert from 'node:assert/strict';

const err = new TypeError('Wrong value');
err.code = 404;
err.foo = 'bar';
err.info = {
  nested: true,
  baz: 'text',
};
err.reg = /abc/i;

assert.throws(
  () => {
    throw err;
  },
  {
    name: 'TypeError',
    message: 'Wrong value',
    info: {
      nested: true,
      baz: 'text',
    },
    // Only properties on the validation object will be tested for.
    // Using nested objects requires all properties to be present. Otherwise
    // the validation is going to fail.
  },
);

// Using regular expressions to validate error properties:
assert.throws(
  () => {
    throw err;
  },
  {
    // The `name` and `message` properties are strings and using regular
    // expressions on those will match against the string. If they fail, an
    // error is thrown.
    name: /^TypeError$/,
    message: /Wrong/,
    foo: 'bar',
    info: {
      nested: true,
      // It is not possible to use regular expressions for nested properties!
      baz: 'text',
    },
    // The `reg` property contains a regular expression and only if the
    // validation object contains an identical regular expression, it is going
    // to pass.
    reg: /abc/i,
  },
);

// Fails due to the different `message` and `name` properties:
assert.throws(
  () => {
    const otherErr = new Error('Not found');
    // Copy all enumerable properties from `err` to `otherErr`.
    for (const [key, value] of Object.entries(err)) {
      otherErr[key] = value;
    }
    throw otherErr;
  },
  // The error's `message` and `name` properties will also be checked when using
  // an error as validation object.
  err,
);

使用构造函数验证 instanceof:

import assert from 'node:assert/strict';

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  Error,
);

使用 RegExp 验证错误信息:

import assert from 'node:assert/strict';

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  /^Error: Wrong value$/,
);

使用正则表达式会在错误对象上运行 .toString,因此也会包含错误名称。

自定义错误验证:
函数必须返回 true,以表示所有内部验证均已通过。否则将导致 AssertionError 失败。

import assert from 'node:assert/strict';

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  (err) => {
    assert(err instanceof Error);
    assert(/value/.test(err));
    // Avoid returning anything from validation functions besides `true`.
    // Otherwise, it's not clear what part of the validation failed. Instead,
    // throw an error about the specific validation that failed (as done in this
    // example) and add as much helpful debugging information to that error as
    // possible.
    return true;
  },
  'unexpected error',
);

error 不能是字符串。如果提供字符串作为第二个参数,则错误会被假定为省略,而使用字符串作为信息。这会导致容易出错的错误。使用与抛出的错误信息相同的信息将导致 ERR_AMBIGUOUS_ARGUMENT 错误。如果考虑使用字符串作为第二个参数,请仔细阅读下面的示例:

import assert from 'node:assert/strict';

function throwingFirst() {
  throw new Error('First');
}

function throwingSecond() {
  throw new Error('Second');
}

function notThrowing() {}

// The second argument is a string and the input function threw an Error.
// The first case will not throw as it does not match for the error message
// thrown by the input function!
assert.throws(throwingFirst, 'Second');
// In the next example the message has no benefit over the message from the
// error and since it is not clear if the user intended to actually match
// against the error message, Node.js throws an `ERR_AMBIGUOUS_ARGUMENT` error.
assert.throws(throwingSecond, 'Second');
// TypeError [ERR_AMBIGUOUS_ARGUMENT]

// The string is only used (as message) in case the function does not throw:
assert.throws(notThrowing, 'Second');
// AssertionError [ERR_ASSERTION]: Missing expected exception: Second

// If it was intended to match for the error message do this instead:
// It does not throw because the error messages match.
assert.throws(throwingSecond, /Second$/);

// If the error message does not match, an AssertionError is thrown.
assert.throws(throwingFirst, /Second$/);
// AssertionError [ERR_ASSERTION]

由于这种符号容易引起混淆,因此应避免使用字符串作为第二个参数。

结语

结束了。
assert模块用的不多,只作了解,平常都会使用成熟的测试框架来测试代码。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

掘金AI 商战 宝典 进阶班:如何用AI绘画设计(实战实操 现学现用 玩赚超值)

课程内容 10-第十讲用AI做网站设计 11-第十一讲用AI做艺术字 12-第十二讲用AI做室内设计(上) 13-第十三讲用AI做室内设计(下) 14-第十四讲用AI抠图与修图 15-第十五讲用AI修复模糊照片 16-第十六讲用AI自动做PPT(上) 17-第十七讲用AI自动做PPT(下) 18-第十八讲用AI做文…

atcoder350,351,352,353,354,355期部分题解

声明&#xff1a;有些题感觉已经说到很明白了&#xff0c;就先不写代码了&#xff0c;有空会补上 目录 350D: new friend 350E: toward 0 351D:Grid and Magnet 352D:permutation subsequence 353C: sigma problem 353D: another sigma problem 354C: atcoder magics …

一文读懂存内计算与近存计算的分类与应用

存内计算与近存计算-基础理论及分类 技术基础知识和分类 "近存计算"与"存内计算"易混淆&#xff0c;本章明晰其分类&#xff0c;并比较各内存驱动方法的独特优势。可计算存储器设备可作分立加速器或替代现有存储模块。我们深入剖析每种方法的利弊&#xf…

像艺术家一样工作

接下来开始翻译这本小册子 豆瓣评分还是挺高的&#xff0c;目前在国内没有看到有在售的翻译版本 书名直译的话是&#xff1a;像艺术家一样去偷 作者可能是为了制造营销话题&#xff0c;所以起了这么一个名字 但是偷这个词总归不太体面&#xff0c;所以我把书名翻译为&#…

Qos令牌桶算法:笔记0601

令牌桶 令牌&#xff1a;目前看到2种表述&#xff0c;csdn表示一个令牌代表一个字节&#xff0c;51cto是一个令牌代表一个bit。51cto上关于cisco qos算法描述多表达为一个令牌一个bit (不知道rfc上咋表达的懒得去查了&#xff0c;主打一个好读书不求甚解&#xff0c;感觉应该是…

c++学习----初识类和对象(上)

1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间的交互完 成。…

rtl8723DU移植 android4.4 4418

一、 linux 的移植。 首先编译一遍确保没有问题。 将驱动拷贝到 driver/net/wireless 目录下。 使用的是&#xff1a; 改写 makefile Kconfig 去改写 8723 的makefile 设置menuconfig 使能固有的 库。 使能USB部分 ieee 部分 编译一遍 有报错。 解决&#xff1a; …

基于深度学习YOLOv8\YOLOv5的花卉识别鲜花识别检测分类系统设计

本文将介绍基于深度学习YOLOv8\YOLOv5PySide6SQLite的花卉检测与识别系统&#xff0c;该系统基于YOLOv8算法&#xff0c;并与YOLOv5版本进行比较&#xff0c;该系统不仅实现了对花卉的精准识别和分类&#xff0c;还提供了包括用户认证管理、模型快速切换及界面个性化定制在内的…

ssm汉服文化平台网站

博主介绍&#xff1a;✌程序员徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【TB作品】msp430f5529单片机墨水屏,口袋板,tmp421温度,温控风扇

文章目录 一、扬声器模块介绍二、驱动介绍三、程序介绍四、全部代码下载 msp430f5529d单片机墨水屏&#xff0c;口袋板&#xff0c;tmp421温度&#xff0c;温控风扇 基本要求&#xff1a;高于20度开转&#xff0c;温度越高转速越快&#xff0c;高于40度风扇停转&#xff0c;温…

Day45 动态规划part05

LC1049最后一块石头重量II(未掌握) 未掌握分析&#xff1a;其实本题跟LC416分割等和子集类似&#xff0c;本质上题目的要求是尽量让石头分成重量相同的两堆&#xff0c;相撞之后剩下的石头最小&#xff0c;也就是01背包问题weight和value都是stones数组&#xff0c;题目可以看…

Java的JDK环境变量配置(Windows)

只写了需要配置的环境变量 注&#xff1a;从JDK1.5开始&#xff0c;配置Java环境变量时&#xff0c;不再需要配置CLASSPATH&#xff0c;只需要配置JAVA_HOME和Path 1、配置JAVA_HOME 找到自己的JDK位置&#xff0c;我这里是 C:\dev\java\jdk-17.0.119在环境变量-系统变量中&…

【已解决】Error in the HTTP2 framing layer

1.问题描述 在使用git将代码上传github的时候在最后一部push的时候遇到这个fatal 2.解决方案 由于我原先设置的origin是http协议下的&#xff0c;如下 git remote add origin https://github.com/Charlesbibi/Simple_Cloud.githttp协议下行不通不妨试一试ssh协议下&#xff…

代码随想录算法训练营 day23| ● 669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树

文章目录 前言669. 修剪二叉搜索树思路方法一 递归法方法二 迭代法 108.将有序数组转换为二叉搜索树思路方法一 递归法方法二 迭代法 538.把二叉搜索树转换为累加树思路方法一方法二 总结 前言 迭代法都没看主要是669和538【538很简单】 669. 修剪二叉搜索树 思路 不用看教程…

stack学习

std::stack 类是一种容器适配器&#xff0c;它给予程序员栈的功能——特别是 FILO&#xff08;先进后出&#xff09;数据结构。该类模板用处为底层容器的包装器——只提供特定函数集合。栈从被称作栈顶的容器尾部推弹元素。 operator 赋值给容器适配器 (公开成员函数) 元素访问…

C#开发的应用升级更新服务器端工具 - 开源研究系列文章 - 个人小作品

笔者开发过一些小应用&#xff0c;然后这些应用就需要有升级更新的功能&#xff0c;但是如果每个都集成进去也行&#xff0c;但是就是得写死更新的代码了。于是就想写一个应用升级更新的管理器&#xff0c;以前看到过Github上有一个AutoUpdate.Net&#xff0c;不过它那个要集成…

openssl 常用命令demo

RSA Private Key的结构&#xff08;ASN.1&#xff09; RSAPrivateKey :: SEQUENCE { version Version, modulus INTEGER, -- n publicExponent INTEGER, -- e privateExponent INTEGER, -- d prime1 INTEGER, -- …

Redis缓存(笔记一:缓存介绍和数据库启动)

目录 1、NoSQL数据库简介 2、Redis介绍 3、Redis(win系统、linux系统中操作) 3.1 win版本Redis启动 3.2 linux版本Redis启动 1、NoSQL数据库简介 技术的分类&#xff1a;&#xff08;发展史&#xff09; 1、解决功能性的问题&#xff1a;Java、Jsp、RDBMS、Tomcat、HTML、…

FreeRTOS任务调度机制(源码讲解)

任务的调度机制(核心是链表)&#xff01;&#xff01;&#xff01; 使用链表来管理任务 在我前面写的FreeRTOS任务(深入到源码进行分析)&#xff0c;我创建了三个任务&#xff0c;他们的优先级都是一样的&#xff0c;所以他们在FreeRTOS中是轮流执行的&#xff0c;实际上&…

【Python从入门到进阶】56、Mysql防止SQL注入及ORM库简化操作

接上篇《55、使用Python轻松操作Mysql数据库》 上一篇我们讲解了Mysql的基本链接和增删改查&#xff0c;本篇我们来介绍链接Mysql时参数化查询与防止SQL注入以及使用ORM&#xff08;对象关系映射&#xff09;库简化操作的内容。 一、参数化查询与防止SQL注入 在数据库操作中&…