使用ioredis在Node.js中操作Redis数据结构的详细指南

news2024/12/21 14:51:02

使用ioredis在Node.js中操作Redis数据结构的详细指南

一. 使用ioredis操作Redis数据结构的详细知识点讲解

在Node.js中,ioredis是一个强大且易于使用的Redis客户端库,它提供了对Redis数据库的直接操作。本文将通过一系列代码示例,详细解释如何使用ioredis进行基本的Redis操作,适合初学者理解和学习。

1. 连接管理

首先,我们需要连接到Redis服务器。ioredis默认连接到本地的localhost:6379

const Redis = require('ioredis');
const redis = new Redis(); // 默认连接到 localhost:6379

// 连接到Redis
redis.on('connect', () => {
  console.log('Connected to Redis');
});

// 断开与Redis的连接
redis.disconnect().then(() => {
  console.log('Disconnected from Redis');
});

2. 字符串操作

使用ioredis操作Redis中的字符串类型的详细知识点如下:

1) 基本字符串操作

设置键值对

使用set方法设置键值对:

redis.set('key', 'value');

获取键值对

使用get方法获取键值对的值:

redis.get('key', (err, result) => {
  if (err) throw err;
  console.log(result); // 输出: value
});

设置键值对并设置过期时间

使用setex方法设置键值对,并指定过期时间(秒):

redis.setex('key', 10, 'value');
2) 字符串的过期和删除

删除键

使用del方法删除键:

redis.del('key');
3). 字符串的过期时间

设置键的过期时间

使用expire方法设置键的过期时间(秒):

redis.expire('key', 60);

查看键的剩余过期时间

使用ttl方法查看键的剩余过期时间(秒):

redis.ttl('key');
5). 字符串的位操作

ioredis也支持对字符串执行位操作,例如:

redis.getbit('key', 0); // 获取位
redis.setbit('key', 0, 1); // 设置位
6). 管道和事务

ioredis支持管道和事务,可以批量执行命令,提高性能:

redis.pipeline()
  .set('foo', 'bar')
  .get('foo')
  .exec((err, results) => {
    // results === [ [null, 'OK'], [null, 'bar'] ]
  });

以上是使用ioredis操作Redis中字符串类型的一些基本和高级操作。通过这些操作,你可以有效地管理Redis中的字符串数据。

3. 哈希操作

使用ioredis操作Redis中的哈希(Hash)数据结构时,你可以执行多种操作来管理这些复杂的数据结构。以下是一些详细的知识点和操作方法:

1). 设置哈希字段的值
  • hset(key, field, value):为哈希表中的指定字段赋值。

    redis.hset('myhash', 'field1', 'value1');
    
2). 获取哈希字段的值
  • hget(key, field):获取哈希表中指定字段的值。
    redis.hget('myhash', 'field1').then((value) => {
      console.log('Value:', value); // 输出 'value1'
    });
    
3). 批量设置哈希字段的值
  • hmset(key, field1, value1, field2, value2, …):同时设置哈希表中的多个字段的值。
    redis.hmset('myhash', 'field2', 'value2', 'field3', 'value3');
    
4). 批量获取哈希字段的值
  • hmget(key, field1, field2, …):同时获取哈希表中多个字段的值。
    redis.hmget('myhash', 'field1', 'field2', 'field3').then((values) => {
      console.log(values); // 输出 ['value1', 'value2', 'value3']
    });
    
5). 获取哈希表中的字段数量
  • hlen(key):获取哈希表中字段的数量。
    redis.hlen('myhash').then((result) => {
      console.log(result); // 输出字段数量
    });
    
6). 删除哈希字段
  • hdel(key, field):删除哈希表中的一个或多个字段。
    redis.hdel('myhash', 'field1').then((result) => {
      console.log(result); // 输出被删除的字段数量
    });
    
7). 获取哈希表中的所有字段名
  • hkeys(key):获取哈希表中的所有字段名。
    redis.hkeys('myhash').then((fields) => {
      console.log(fields); // 输出所有字段名
    });
    
8). 获取哈希表中的所有值
  • hvals(key):获取哈希表中的所有值。
    redis.hvals('myhash').then((values) => {
      console.log(values); // 输出所有值
    });
    
9). 获取哈希表中的所有字段和值
  • hgetall(key):获取哈希表中的所有字段和值。
    redis.hgetall('myhash').then((hash) => {
      console.log(hash); // 输出所有字段和值
    });
    
10). 检查哈希字段是否存在
  • hexists(key, field):检查哈希表中指定的字段是否存在。
    redis.hexists('myhash', 'field1').then((exists) => {
      console.log(exists); // 如果字段存在,输出 1,否则输出 0
    });
    
11). 为哈希表字段的整数值增加增量
  • hincrby(key, field, increment):为哈希表中指定字段的整数值增加指定的增量。
    redis.hincrby('myhash', 'field1', 1); // 将 'field1' 的值增加 1
    
12). 为哈希表字段的浮点数值增加增量
  • hincrbyfloat(key, field, increment):为哈希表中指定字段的浮点数值增加指定的增量。
    redis.hincrbyfloat('myhash', 'field1', 1.5); // 将 'field1' 的值增加 1.5
    
13). 获取哈希表中字符串字段的长度
  • hstrlen(key, field):获取哈希表中字符串字段的长度。
    redis.hstrlen('myhash', 'field1').then((length) => {
      console.log(length); // 输出字段值的长度
    });
    

这些操作提供了对Redis哈希数据结构的全面管理能力,使得在Node.js应用中处理复杂数据变得更加简单和高效。

4. 列表操作

使用ioredis操作Redis中的列表(List)数据结构时,你可以执行多种操作来管理这些数据结构。以下是一些详细的知识点和操作方法:

1). 插入元素
  • lpush(key, …values):在列表的左侧(头部)插入一个或多个元素。

    await redis.lpush('my_list', 'element1', 'element2');
    

    参考:[腾讯云开发者社区-使用aioredis操作列表对象:插入单个元素]

  • rpush(key, …values):在列表的右侧(尾部)插入一个或多个元素。

    await redis.rpush('my_list', 'element1', 'element2');
    
2). 弹出元素
  • lpop(key):从列表的左侧(头部)弹出一个元素。

    const element = await redis.lpop('my_list');
    
  • rpop(key):从列表的右侧(尾部)弹出一个元素。

    const element = await redis.rpop('my_list');
    
3). 获取列表长度
  • llen(key):获取列表的长度。
    const length = await redis.llen('my_list');
    
4). 获取列表元素
  • lrange(key, start, stop):获取列表中指定范围内的元素。
    const elements = await redis.lrange('my_list', 0, -1); // 获取所有元素
    
5). 删除元素
  • lrem(key, count, value):删除列表中与给定值相等的元素。
    // 从列表中删除第一个匹配的元素
    await redis.lrem('my_list', 1, 'element1');
    
6). 根据索引设置元素值
  • lset(key, index, value):设置列表指定索引处的元素值。
    await redis.lset('my_list', 0, 'newElement');
    
7). 截取列表
  • ltrim(key, start, stop):对一个列表进行修剪,只保留指定范围内的元素。
    await redis.ltrim('my_list', 0, -1); // 保留所有元素
    
8). 管道和事务

ioredis支持管道和事务,可以批量执行命令,提高性能:

const pipeline = redis.pipeline();
pipeline.lpush('my_list', 'newElement');
pipeline.lrange('my_list', 0, -1);
pipeline.exec((err, results) => {
  // 处理结果
});

以上是使用ioredis操作Redis中列表数据结构的一些基本和高级操作。通过这些操作,你可以有效地管理Redis中的列表数据。

5. 集合操作

使用ioredis操作Redis中的集合(Set)数据结构时,你可以执行多种操作来管理这些数据结构。以下是一些详细的知识点和操作方法:

1). 向集合添加元素
  • sadd(key, member1, member2, …):向集合中添加一个或多个元素。如果元素已存在,则不会重复添加。
    await redis.sadd('myset', 'one', 'two', 'three');
    
2). 从集合中移除元素
  • srem(key, member1, member2, …):从集合中移除一个或多个元素。
    await redis.srem('myset', 'two');
    
3). 检查元素是否在集合中
  • sismember(key, member):检查元素是否是集合的成员。
    const isMember = await redis.sismember('myset', 'one');
    console.log('Is member:', isMember); // true 或 false
    
4). 获取集合中的所有元素
  • smembers(key):获取集合中的所有元素。
    const members = await redis.smembers('myset');
    console.log('Members:', members);
    
5). 获取集合的大小
  • scard(key):获取集合的大小,即元素的数量。
    const size = await redis.scard('myset');
    console.log('Set size:', size);
    
6). 集合运算
  • sinter(key1, key2, …):返回两个或多个集合的交集。

    const intersection = await redis.sinter('myset', 'anotherSet');
    console.log('Intersection:', intersection);
    
  • sunion(key1, key2, …):返回两个或多个集合的并集。

    const union = await redis.sunion('myset', 'anotherSet');
    console.log('Union:', union);
    
  • sdiff(key1, key2, …):返回两个集合的差集,即存在于第一个集合中但不在第二个集合中的元素。

    const difference = await redis.sdiff('myset', 'anotherSet');
    console.log('Difference:', difference);
    
  • smove(source, destination, member):将元素从一个集合移动到另一个集合。

    await redis.smove('myset', 'anotherSet', 'one');
    

以上是使用ioredis操作Redis中集合数据结构的一些基本操作。通过这些操作,你可以有效地管理Redis中的集合数据。

6. 有序集合操作

使用ioredis操作Redis中的有序集合(Sorted Set)涉及到一系列的命令,这些命令可以帮助你管理有序集合中的数据。以下是一些详细的知识点和操作方法:

1). 向有序集合添加元素
  • zadd(key, score, member):向有序集合中添加一个元素,或者更新已存在元素的分数。
    await redis.zadd('myzset', { 'one': 1, 'two': 2, 'three': 3 });
    
2). 获取有序集合中的元素
  • zrange(key, start, stop, [withscores]):获取有序集合中指定范围内的元素,可以包含分数。
    const elements = await redis.zrange('myzset', 0, -1, 'WITHSCORES');
    console.log(elements); // 输出 ['one', '1', 'two', '2', 'three', '3']
    
3). 获取有序集合中元素的逆序排列
  • zrevrange(key, start, stop, [withscores]):获取有序集合中指定范围内的元素,按照分数从大到小排序。
    const elements = await redis.zrevrange('myzset', 0, -1, 'WITHSCORES');
    console.log(elements); // 输出 ['three', '3', 'two', '2', 'one', '1']
    
4). 获取有序集合中元素的排名
  • zrank(key, member):获取有序集合中指定元素的排名,按分数从小到大排列。

    const rank = await redis.zrank('myzset', 'two');
    console.log(rank); // 输出 '1'
    
  • zrevrank(key, member):获取有序集合中指定元素的排名,按分数从大到小排列。

    const rank = await redis.zrevrank('myzset', 'two');
    console.log(rank); // 输出 '2'
    
5). 删除有序集合中的元素
  • zrem(key, member1, [member2, …]):从有序集合中移除一个或多个元素。
    await redis.zrem('myzset', 'one');
    
6). 获取有序集合的大小
  • zcard(key):获取有序集合中的成员数。
    const size = await redis.zcard('myzset');
    console.log(size); // 输出集合的大小
    
7). 计算有序集合中指定分数区间的成员数
  • zcount(key, min, max):计算在有序集合中指定区间分数的成员数。
    const count = await redis.zcount('myzset', '1', '2');
    console.log(count); // 输出分数在1到2之间的成员数
    
8). 增加有序集合中元素的分数
  • zincrby(key, increment, member):有序集合中对指定成员的分数加上增量。
    await redis.zincrby('myzset', 1, 'two'); // 将 'two' 的分数增加 1
    
9). 获取有序集合中元素的分数
  • zscore(key, member):获取有序集合中指定成员的分数。
    const score = await redis.zscore('myzset', 'two');
    console.log(score); // 输出 'two' 的分数
    
10). 根据分数区间获取有序集合中的元素
  • zrangebyscore(key, min, max, [withscores], [limit]):返回有序集合中指定分数区间的成员。
    const elements = await redis.zrangebyscore('myzset', '1', '3', 'WITHSCORES');
    console.log(elements); // 输出分数在1到3之间的成员及其分数
    
11). 根据字典区间获取有序集合中的元素
  • zrangebylex(key, min, max):通过字典区间返回有序集合的成员。
    const elements = await redis.zrangebylex('myzset', '-', '+');
    console.log(elements); // 输出字典序在 '-' 到 '+' 之间的成员
    
12). 移除有序集合中指定分数区间的成员
  • zremrangebyscore(key, min, max):移除有序集合中给定的分数区间的所有成员。
    await redis.zremrangebyscore('myzset', '1', '2');
    

以上是使用ioredis操作Redis中有序集合的一些基本和高级操作。通过这些操作,你可以有效地管理Redis中的有序集合数据。

7. 发布/订阅

发布/订阅模式允许我们发布消息到频道,并订阅频道以接收消息。

// 向频道发布消息
redis.publish('myChannel', 'Hello!').then((numSubscribers) => {
  console.log('Number of subscribers:', numSubscribers);
});

// 订阅频道
const subscriber = new Redis();
subscriber.on('message', (channel, message) => {
  console.log(`Received data: ${message} from ${channel}`);
});
subscriber.subscribe('myChannel');

8. 键管理

键管理操作允许我们检查键是否存在、设置过期时间、获取剩余过期时间以及删除键。

// 检查键是否存在
redis.exists('myKey').then((exists) => {
  console.log('Key exists:', exists);
});

// 设置键的过期时间
redis.expire('myKey', 10).then((didSetExpire) => {
  console.log('Key has an expiration time set:', didSetExpire);
});

// 获取键的剩余过期时间
redis.ttl('myKey').then((ttl) => {
  console.log('Time to live for key:', ttl);
});

// 删除键
redis.del('myKey').then((delCount) => {
  console.log('Deleted keys count:', delCount);
});

9. 事务处理

事务处理允许我们执行一系列操作,这些操作要么全部成功,要么全部失败。

// 开始一个事务
redis.multi()
  .set('foo', 'bar')
  .get('foo')
  .exec().then((results) => {
    console.log('Transaction results:', results);
  });

10. 管道处理

管道处理允许我们批量执行多个命令,减少网络延迟。

// 创建一个管道
redis.pipeline()
  .set('foo', 'bar')
  .get('foo')
  .exec().then((results) => {
    console.log('Pipeline results:', results);
  });

11. 脚本执行

脚本执行允许我们执行Lua脚本,这可以提高性能,尤其是在需要执行多个操作时。

// 执行Lua脚本
redis.eval('return redis.call("set", KEYS[1], ARGV[1])', 1, 'myLuaKey', 'luaValue').then(() => {
  console.log('Lua script executed');
});

// 执行已加载的Lua脚本
const script = `
  local value = redis.call('get', KEYS[1])
  if value then
    return value
  else
    return 'nil'
  end
`;
redis.evalsha(script, 1, 'myLuaKey').then((result) => {
  console.log('Lua script result:', result);
});

以上是ioredis库中一些基本操作的入门指南。每个示例都包含了一个简单的操作和相应的代码,以帮助理解每个方法的作用。在实际开发中,你可能需要根据具体的业务逻辑来组合和扩展这些操作。希望这篇文章能帮助你更好地理解和使用ioredis

二. Promise风格与回调函数风格在Redis String类型CRUD操作中的对比

帮助理解:

ioredis库中,当你使用回调函数风格的API时,这些方法实际上返回的是 Promise对象。这意味着即使你在方法调用的末尾提供了一个 回调函数ioredis内部仍然会返回一个 Promise对象,以便支持现代的异步处理方式。

当然,下面我将对比展示使用Promise风格的异步处理方式和使用回调函数风格的异步处理方式,以Redis的String类型为例

1. Promise风格(现代异步处理方式)

Promise风格是ES6引入的一种异步处理方式,它允许我们使用.then().catch()方法来处理异步操作的结果和错误。

  • 创建(Create)

    redis.set('key', 'value')
      .then(result => {
        console.log('Set result:', result); // 处理结果
      })
      .catch(err => {
        console.error('Error setting key:', err); // 处理错误
      });
    
  • 读取(Read)

    redis.get('key')
      .then(result => {
        console.log('Get result:', result); // 处理结果
      })
      .catch(err => {
        console.error('Error getting key:', err); // 处理错误
      });
    
  • 更新(Update)

    redis.set('key', 'new_value')
      .then(result => {
        console.log('Update result:', result); // 处理结果
      })
      .catch(err => {
        console.error('Error updating key:', err); // 处理错误
      });
    
  • 删除(Delete)

    redis.del('key')
      .then(result => {
        console.log('Delete result:', result); // 处理结果
      })
      .catch(err => {
        console.error('Error deleting key:', err); // 处理错误
      });
    

2. 回调函数风格(Node.js传统异步处理方式)

回调函数风格是在Promise之前Node.js中处理异步操作的主要方式。每个异步函数都接受一个回调函数作为最后一个参数,该回调函数在操作完成时被调用。

  • 创建(Create)

    redis.set('key', 'value', function(err, result) {
      if (err) {
        console.error('Error setting key:', err); // 处理错误
      } else {
        console.log('Set result:', result); // 处理结果
      }
    });
    
  • 读取(Read)

    redis.get('key', function(err, result) {
      if (err) {
        console.error('Error getting key:', err); // 处理错误
      } else {
        console.log('Get result:', result); // 处理结果
      }
    });
    
  • 更新(Update)

    redis.set('key', 'new_value', function(err, result) {
      if (err) {
        console.error('Error updating key:', err); // 处理错误
      } else {
        console.log('Update result:', result); // 处理结果
      }
    });
    
  • 删除(Delete)

    redis.del('key', function(err, result) {
      if (err) {
        console.error('Error deleting key:', err); // 处理错误
      } else {
        console.log('Delete result:', result); // 处理结果
      }
    });
    

3. 对比理解

  • 链式调用 vs 嵌套回调

    • Promise风格允许链式调用.then().catch(),使得代码更加线性和易于阅读,特别是在处理多个异步操作时,避免了所谓的“回调地狱”。
    • 回调函数风格需要嵌套回调,当有多个异步操作时,代码可能会变得难以阅读和维护。
  • 错误处理

    • Promise风格通过.catch()集中处理错误,使得错误处理更加集中和一致。
    • 回调函数风格在每个回调中单独处理错误,可能会导致错误处理代码的重复。
  • 异步控制

    • Promise风格提供了更多的控制力,如async/await语法,使得异步代码可以像同步代码一样编写,提高了代码的可读性和可维护性。
    • 回调函数风格在异步控制上较为有限,通常需要手动管理回调的执行顺序。

总的来说,Promise风格提供了一种更加现代和强大的异步处理方式,而回调函数风格则是Node.js中传统的处理方式。选择哪种方式取决于个人偏好和项目需求。

三. 使用Express和ioredis管理Redis中的代办任务:深入指南

这段代码是一个使用Express框架和ioredis库的Node.js应用程序,它提供了一个简单的API来管理代办任务。这些任务存储在Redis数据库中,使用哈希数据结构。下面我将结合这段代码,深入讲解Redis中的相关知识。

Redis哈希数据结构

Redis的哈希是一个字符串字段到字符串值的映射表,适合用于存储对象。在上面的代码中,每个代办任务都被表示为一个对象,并存储在Redis哈希中。

1. 代办任务的添加

router.post('/add', (req, res) => {
    let { task } = req.body;
    let taskId = Date.now();
    const key = `task_obj:${taskId}`;
    redis.hset(key, { state: 0, code: 0, task: task }, (error, result) => {
        if (error) {
            console.log(error);
            return res.status(500).send('Error adding task');
        }
        res.send("Task added OK!");
    });
});
  • hset命令用于设置哈希表中的字段值。如果字段已存在,则会更新其值。
  • taskId是使用当前时间戳生成的唯一标识符,确保每个任务都有一个唯一的键。
  • key是任务的唯一键,格式为task_obj:<taskId>
  • 回调函数中的error参数用于处理可能发生的错误,result参数表示操作的结果。

2. 查看所有代办任务

router.get('/tasks', async (req, res) => {
    const keys = await redis.keys("task_obj:*");
    let task_item;
    const task_arr = [];
    keys.forEach(async v => {
        task_item = await redis.hgetall(v);
        task_arr.push({ ...task_item, tid: v.substr(9) });
        if (keys.length == task_arr.length) {
            res.json({ code: 0, data: task_arr });
        }
    });
});
  • keys命令用于查找所有匹配给定模式的键。这里使用task_obj:*模式来查找所有任务对象。
  • hgetall命令用于获取哈希表中所有的字段和值。
  • 使用async/await语法来处理异步操作,使代码更易于阅读和维护。
  • task_arr数组用于存储所有任务对象,每个对象都包含一个额外的tid属性,它是任务的唯一标识符。

3. 获取单个代办任务

router.get('/task', (req, res) => {
    let { id } = req.query;
    let key = `task_obj:${id}`;
    redis.hgetall(key, (error, task) => {
        if (error) {
            return res.status(500).send('Error retrieving task');
        }
        if (!task) {
            return res.status(404).send('Task not found');
        }
        res.json({ code: 0, task });
    });
});
  • 通过查询参数id来获取任务的键,并使用hgetall命令获取任务的详细信息。
  • 如果任务不存在,返回404状态码。

4. 更新代办任务

router.post('/update', (req, res) => {
    let { id, task } = req.body;
    let key = `task_obj:${id}`;
    redis.hset(key, { code: 0, state: 0, task: task }, (error, result) => {
        if (error) {
            console.log(error);
            return res.status(500).send('Error updating task');
        }
        res.send('Task updated');
    });
});
  • 与添加任务类似,hset命令用于更新任务的状态和内容。
  • 如果更新失败,返回500状态码。

5. 删除代办任务

router.get('/del', (req, res) => {
    let { id } = req.query;
    let key = `task_obj:${id}`;
    redis.del(key, (error, result) => {
        if (error) {
            console.log(error);
            return res.status(500).send('Error deleting task');
        }
        if (result === 0) {
            return res.status(404).send('Task not found');
        }
        res.send('Task deleted');
    });
});
  • del命令用于删除一个或多个键。
  • result参数表示被删除的键的数量。如果为0,则表示没有键被删除,可能是因为键不存在。

总结

这段代码展示了如何在Node.js应用程序中使用Redis来存储和管理代办任务。通过ioredis库,我们可以轻松地执行Redis命令,如hsethgetallkeysdel等,来操作哈希数据结构。此外,代码中使用了异步/等待(async/await)语法来简化异步操作的处理,使代码更加清晰和易于维护。

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

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

相关文章

C#代码实现把中文录音文件(.mp3 .wav)转为文本文字内容

我们有一个中文录音文件.mp3格式或者是.wav格式&#xff0c;如果我们想要提取录音文件中的文字内容&#xff0c;我们可以采用以下方法&#xff0c;不需要使用Azure Speech API 密钥注册通过离线的方式实现。 1.首先我们先在NuGet中下载两个包 NAudio 2.2.1、Whisper.net 1.7.3…

数据可视化-2. 条形图

目录 1. 条形图适用场景分析 1.1 比较不同类别的数据 1.2 展示数据分布 1.3 强调特定数据点 1.4 展示时间序列数据的对比 1.5 数据可视化教育 1.6 特定领域的应用 2. 条形图局限性 3. 条形图图代码实现 3.1 Python 源代码 3.2 条形图效果&#xff08;网页显示&#…

基于Redis的网关鉴权方案与性能优化

文章目录 前言一、微服务鉴权1.1 前端权限检查1.2 后端权限检查1.3 优缺点 二、网关鉴权2.1 接口权限存储至Redis2.2 网关鉴权做匹配 总结 前言 在微服务架构中&#xff0c;如何通过网关鉴权结合Redis缓存提升权限控制的效率与性能。首先&#xff0c;文章对比了两种常见的权限…

Ansible 批量管理华为 CE 交换机

注&#xff1a;本文为 “Ansible 管理华为 CE 交换机” 相关文章合辑。 使用 CloudEngine - Ansible 批量管理华为 CE 交换机 wsf535 IP 属地&#xff1a;贵州 2018.02.05 15:26:05 总体介绍 Ansible 是一个开源的自动化运维工具&#xff0c;AnsibleWorks 成立于 2012 年&a…

使用自定义分光比对分束器进行建模

分束器将一束光分成两个或多个单独的光束。它常用于各种光学系统&#xff0c;例如显微镜、干涉仪和成像设备。分束器可以由不同的材料制成&#xff0c;通常涂有金属或介电材料的薄层&#xff0c;以达到所需的分束效果。分束器的两种流行形式是立方体和板式。立方体分束器由两个…

C++对象数组对象指针对象指针数组

一、对象数组 对象数组中的每一个元素都是同类的对象&#xff1b; 例1 对象数组成员的初始化 #include<iostream> using namespace std;class Student { public:Student( ){ };Student(int n,string nam,char s):num(n),name(nam),sex(s){};void display(){cout<&l…

SQL进阶技巧:如何计算商品需求与到货队列表进出计划?

目录 0 需求描述 1 数据准备 2 问题分析 3 小结 累计到货数量计算 出货数量计算 剩余数量计算 0 需求描述 假设现有多种商品的订单需求表 DEMO_REQUIREMENT&#xff0c;以及商品的到货队列表 DEMO_ARR_QUEUE&#xff0c;要求按照业务需要&#xff0c;设计一个报表&#…

清远榉之乡托养机构为你深度分析:特殊碳水化合物饮食对自闭症的作用

在探索自闭症干预方法的道路上&#xff0c;各种尝试不断涌现。其中&#xff0c;特殊碳水化合物饮食引起了不少家长的关注。那么&#xff0c;特殊碳水化合物饮食对自闭症究竟有怎样的作用呢&#xff1f;今天&#xff0c;清远榉之乡托养机构为你深度分析。 榉之乡大龄自闭症托养机…

ElasticSearch 数据聚合与运算

1、数据聚合 聚合&#xff08;aggregations&#xff09;可以让我们极其方便的实现数据的统计、分析和运算。实现这些统计功能的比数据库的 SQL 要方便的多&#xff0c;而且查询速度非常快&#xff0c;可以实现近实时搜索效果。 注意&#xff1a; 参加聚合的字段必须是 keywor…

ONES 功能上新|ONES Copilot、ONES Wiki 新功能一览

ONES Copilot 可基于工作项的标题、描述、属性信息&#xff0c;对工作项产生的动态和评论生成总结。 针对不同类型的工作项&#xff0c;总结输出的内容有对应的侧重点。 应用场景&#xff1a; 在一些流程步骤复杂、上下游参与成员角色丰富的场景中&#xff0c;工作项动态往往会…

leecode494.目标和

这道题目第一眼感觉就不像是动态规划&#xff0c;可以看出来是回溯问题&#xff0c;但是暴力回溯超时&#xff0c;想要用动态规划得进行一点数学转换 class Solution { public:int findTargetSumWays(vector<int>& nums, int target) {int nnums.size(),bagWeight0,s…

python使用Flask框架创建一个简单的动态日历

0. 运行效果 运行代码&#xff0c;然后在浏览器中访问 http://127.0.0.1:5000/&#xff0c;将看到一个动态日历&#xff0c;能够通过点击按钮切换月份。 1. 安装 Flask 首先&#xff0c;确保你已经安装了Flask。如果没有&#xff0c;可以使用以下命令安装&#xff1a; pip i…

一键优化Linux服务器性能(One Click Optimization of Linux Server Performance)

服务器上线之一键优化Linux服务器性能 以下是一个简单的Shell脚本&#xff0c;用于执行服务器上线优化的一些基本步骤。请注意&#xff0c;这个脚本是基于一个通用的Linux服务器配置&#xff0c;您可能需要根据您的具体需求和环境进行调整。 功能如下&#xff1a; 1.关闭SEL…

【电脑技巧】将键盘的方向键映射为alt+i、k、j、l

最近感觉方向键太远了&#xff0c;想找个方法修改键盘映射&#xff0c;有几种方式可以实现 使用powertoys的键盘映射&#xff08;软件太大了&#xff0c;只为键盘映射不值得下这个&#xff09;使用autohotkey&#xff08;通过脚本的方式&#xff0c;可以打包成exe文件&#xf…

apache-tomcat-6.0.44.exe Win10

apache-tomcat-6.0.44.exe Win10

文件防泄漏 | 文件防泄漏软件解决方案分享,网络数据泄露防护系统

文件防泄漏 | 文件防泄漏软件解决方案分享&#xff0c;网络数据泄露防护系统 企业面临的一大挑战是数据安全和隐私保护。 网络数据泄露不仅会导致经济损失&#xff0c;还会损害企业的声誉和客户关系。 为了应对这一挑战&#xff0c;域智盾软件应运而生&#xff0c;成为众多企…

11篇--图像边缘检测

图像梯度 要学习图像边缘检测&#xff0c;要先了解图像梯度的概念&#xff0c;我们正是通过梯度值来区分边缘像素点的 处于边缘附近的像素点与周围像素点的差距很大&#xff08;不然不会有边缘呈现&#xff09;&#xff0c;所以给边缘附近的的梯度之变化很快&#xff0c;通过…

细说STM32F407单片机轮询方式读写SPI FLASH W25Q16BV

目录 一、工程配置 1、时钟、DEBUG 2、GPIO 3、SPI2 4、USART6 5、NVIC 二、软件设计 1、FALSH &#xff08;1&#xff09;w25flash.h &#xff08;2&#xff09; w25flash.c 1&#xff09;W25Q16基本操作指令 2&#xff09;计算地址的辅助功能函数 3&#xff09;器…

.net core在linux导出excel,System.Drawing.Common is not supported on this platform

使用框架 .NET7 导出组件 Aspose.Cells for .NET 5.3.1 asp.net core mvc 如果使用Aspose.Cells导出excel时&#xff0c;报错 &#xff1a; System.Drawing.Common is not supported on this platform 平台特定实现&#xff1a; 对于Windows平台&#xff0c;System.Drawing.C…

岁末回望,追梦远方

又到了岁末年初&#xff0c;按惯例&#xff0c;风云我都会写一篇长长的感悟&#xff0c;给自己辞旧的总结复盘&#xff0c;迎新的追梦定调&#xff0c;今年赋诗一首&#xff0c;畅想一下诗和远方&#xff0c;简洁而又虚无&#xff0c;缥缈中坚定初心。 岁末回首步履深&#xf…