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

MIT 6.824 Lab1记录

MapReduce论文阅读

1. 编程模型

Map 函数(kv -> kv)

Map 函数将输入的键值对处理为一系列中间值(键值对),并将所有的中间结果传递给 Reduce 处理。

map(String key, String value):// key: document name// value: document contentsfor each word w in value:EmitIntermediate(w, "1");

Reduce 函数(kv -> kv)

Reduce 函数将相同键的值合并,每个 Reduce 函数输出 0 或 1 个结果。

reduce(String key, Iterator values):// key: a word// values: a list of countsint result = 0;for each v in values:result += ParseInt(v);Emit(AsString(result));

类型定义

map     (k1, v1)        ->  list(k2, v2)
reduce  (k2, list(v2))  ->  list(v)

例子:统计文本中每个单词的出现次数(词频统计)

输入数据:

假设有以下三段文本数据:

  • 文本1:“apple banana apple”
  • 文本2:“banana orange apple”
  • 文本3:“orange banana banana”
Map 阶段

Map 函数接受输入键值对 (k1, v1),其中 k1 是文本的标识(例如文本编号或文件名),v1 是文本内容。Map 函数将文本内容拆分为单词,并为每个单词输出中间键值对 (k2, v2),其中 k2 是单词,v2 是计数值 1

Map 输入:

  1. ("文本1", "apple banana apple")
  2. ("文本2", "banana orange apple")
  3. ("文本3", "orange banana banana")

Map 输出:

  • 对于输入 ("文本1", "apple banana apple"),Map 函数输出:

    ("apple", 1)
    ("banana", 1)
    ("apple", 1)
    
  • 对于输入 ("文本2", "banana orange apple"),Map 函数输出:

    ("banana", 1)
    ("orange", 1)
    ("apple", 1)
    
  • 对于输入 ("文本3", "orange banana banana"),Map 函数输出:

    ("orange", 1)
    ("banana", 1)
    ("banana", 1)
    
Shuffle and Sort(整理和排序)

将所有 Map 阶段的输出根据键 k2(单词)进行分组,形成 (k2, list(v2)) 的形式:

  • ("apple", [1, 1, 1])
  • ("banana", [1, 1, 1, 1])
  • ("orange", [1, 1])
Reduce 阶段

Reduce 函数接受 (k2, list(v2)),将 list(v2) 中的值累加,得到每个单词的总出现次数。

  • 对于 ("apple", [1, 1, 1]),Reduce 函数计算:

    total = 1 + 1 + 1 = 3
    输出:("apple", 3)
    
  • 对于 ("banana", [1, 1, 1, 1]),Reduce 函数计算:

    total = 1 + 1 + 1 + 1 = 4
    输出:("banana", 4)
    
  • 对于 ("orange", [1, 1]),Reduce 函数计算:

    total = 1 + 1 = 2
    输出:("orange", 2)
    
最终输出
  • ("apple", 3)
  • ("banana", 4)
  • ("orange", 2)
总结流程
  1. Map 阶段:将输入的文本内容拆分为单词,对每个单词生成键值对 (k2, v2),其中 k2 是单词,v2 是计数 1
  2. Shuffle and Sort:将所有的键值对按照键 k2 进行分组,收集所有相同键的值到一个列表 list(v2) 中。
  3. Reduce 阶段:对每个键 k2,将对应的 list(v2) 中的值进行累加,得到该单词的总出现次数。

通过这个例子,可以清楚地看到 MapReduce 的工作过程:

  • Map 阶段:处理输入数据,映射 (k1, v1) 到一系列的 (k2, v2)
  • Reduce 阶段:聚合中间结果,将 (k2, list(v2)) 转化为最终结果 (k2, v)

这个过程非常适合处理大规模的数据集,因为 Map 和 Reduce 阶段都可以并行执行,充分利用分布式计算资源。


示例

本节中,我们给出了一些简单的示例,这些示例都是可以通过 MapReduce 计算实现的有趣程序。

  1. 分布式“grep”:如果一行文本匹配给定的模式,那么 Map 函数会输出该行。Reduce 作为一个恒等函数,仅将提供的中间数据复制到输出。

  2. URL 访问频率计数:Map 函数处理网页请求日志,输出 <URL, 1>。Reduce 函数对相同 URL 的值求和,输出 <URL, 总数> 键值对。

  3. 反转 Web 链接拓扑图:Map 函数在名为 source 的页面中,对每个指向的 target URL 输出一个 <target, source> 键值对。Reduce 函数将所有相同 targetsource 合并为一个列表,输出 <target, list(source)> 键值对。

  4. 每个主机的词向量统计:词向量是对一系列文档中最重要的词的汇总,其形式为 <词, 词频> 的键值对列表。Map 函数为每篇输入文档输出一个 <主机名, 词向量> 键值对(主机名 由文档的 URL 解析而来)。Reduce 函数接收给定主机上所有文章的词向量,将这些词向量相加,丢弃低频词,最终输出 <主机名, 词向量> 键值对。

  5. 倒排索引:Map 函数处理每篇文档,输出一系列 <词, 文档 ID> 的键值对。Reduce 函数接受相同词的所有键值对,按 文档 ID 排序,输出 <词, list(文档 ID)> 键值对。所有输出的键值对集合组成了一个简单的倒排索引。如果需要跟踪词的位置,可以通过增量计算实现。

  6. 分布式排序:Map 函数提取每条记录中的键,输出一个 <键, 记录> 的键值对。Reduce 函数不修改中间变量,直接输出所有的键值对。排序计算依赖于 MapReduce 框架中的分区机制和排序特性,以确保数据按照键的顺序输出。


2. 实现

执行概述

输入数据会自动被分割为 M M M个分片(split),这样,map函数调用可以在多个机器上分布式执行,每个输入的分片可以在不同机器上并行处理。中间键值对的键空间会通过被分区函数(例如, h a s h ( k e y ) m o d R hash(key) mod R hash(key)modR)分割为 R R R个分区,这样,reduce函数也可以分布式执行。其中分区的数量( R R R)和分区函数由用户指定。
在这里插入图片描述
图1展示了在我们的实现中,MapReduce操作的完整工作流。当用户程序调用MapReduce函数时会发生如下的操作(下列序号与图1中序号对应):

  1. 程序启动

    • 顶部的 User Program 启动后,通过 fork 操作创建一个 Master 节点和多个 Worker 节点
    • Master 负责任务的协调和分配
  2. 输入阶段

    • 左侧显示输入文件被分成多个 splits(split 0 到 split 4)
    • 这些 splits 代表了需要处理的原始数据的分片
  3. Map 阶段

    • Master 将 map 任务分配给 worker 节点
    • Worker 节点读取相应的输入分片(图中标注为(3) read)
    • 每个 map worker 处理数据并将结果写入本地磁盘(标注为(4) local write)
    • 生成的中间文件存储在 local disks 上
  4. 中间阶段

    • 中间结果以文件形式存储在各个节点的本地磁盘上
    • 这些文件等待被 reduce 阶段的 worker 处理
  5. Reduce 阶段

    • Master 为 reduce worker 分配任务
    • Reduce worker 通过远程读取(标注为(5) remote read)获取它们需要处理的中间文件数据
    • 最后将处理结果写入最终的输出文件(标注为(6) write)
  6. 输出阶段

    • 最终生成多个输出文件(output file 0, output file 1)
    • 这些文件包含了整个MapReduce作业的最终结果

整个流程展示了 MapReduce 的核心特点:

  • 并行处理:多个 worker 同时工作
  • 数据本地性:map 阶段的数据尽量在本地处理
  • 容错性:master 可以重新分配失败的任务
  • 可扩展性:worker 节点可以根据需要增加

这种架构设计使得 MapReduce 能够高效地处理大规模数据,成为分布式计算的重要范式。
在这里插入图片描述

假设我们要统计一个大型文本库中每个单词出现的次数:

  1. 数据分片(Split)阶段

    • 假设我们有 100GB 的文本文件
    • 系统将其分成 M=2000 个分片,每个约 50MB
    • 此时会启动一个 master 和多个 worker 进程
  2. 任务分配阶段

    • Master 会将 2000 个 map 任务分配给空闲的 workers
    • 同时分配好 R(假设=50)个 reduce 任务
  3. Map 处理阶段

    # Map 函数示例
    def map(document):for word in document.split():emit(word, 1)  # 为每个单词发出(word, 1)的键值对
    
  4. 中间结果处理

    • 每个 map worker 将产生的键值对(如:{“hello”: 1, “world”: 1})缓存在内存
    • 按照分区函数(如 hash(word) mod 50)将数据分成 50 个区域
    • 将位置信息报告给 master
  5. Reduce 获取与排序

    • 每个 reduce worker 负责特定的单词集合
    • 例如:reduce-0 可能负责 hash 值为 0 的所有单词
    • 从所有 map worker 收集数据后进行排序
    # 排序后的数据可能如下:
    {"hello": [1,1,1,1], "hi": [1,1]}
    
  6. Reduce 处理

    # Reduce 函数示例
    def reduce(word, counts):sum = 0for count in counts:sum += countemit(word, sum)
    
  7. 完成阶段

    • 最终得到 50 个输出文件,每个文件包含一部分单词的统计结果
    • 这些文件可以直接用于后续处理,如:
      • 作为新的 MapReduce 任务的输入
      • 被其他分布式程序使用

关键特点:

  1. 容错性:如果某个 worker 失败,master 会将任务重新分配给其他 worker

  2. 本地性优化:master 会尽量将 map 任务分配给拥有对应输入数据的机器,减少网络传输

  3. 扩展性

    • M 和 R 的值可以远大于机器数量
    • 动态负载均衡
    • 适应不同规模的计算集群
      在我们的MapReduce实现的实际情况中,对 M M M R R R的上限进行了限制。如前文所述,master必须做出 O ( M + R ) O(M+R) O(M+R)个调度决策,并在内存中保存 O ( M × R ) O(M \times R) O(M×R)个状态。(内存占用的常数因子比较小: O ( M × R ) O(M \times R) O(M×R)条状态由大约每个map/reduce任务仅一字节的数据组成。)
      此外, R R R还经常受用户限制,因为每个reduce任务会生成一个单独的输出文件。在实际情况下,我们更倾向于自定义参数 M M M,这样可以使每个单独的任务的输入数据大概在16MB到64MB(这样可以使前面提到的局部性优化最有效),同时,我们使 R R R是期望使用的worker机器的较小的倍数。我们经常在 2 , 000 2,000 2,000台机器上选择 M = 200 , 000 M=200,000 M=200,000 R = 5 , 000 R=5,000 R=5,000的参数执行MapReduce计算。

容错

1. Worker 故障处理

  • Master 通过定期 ping 来监控 worker 状态
  • Worker 无响应时会被标记为故障
  • 故障 worker 的任务处理:
    • 已完成的 map 任务:重置为"等待中"状态,需要重新执行(因为输出在本地磁盘)
    • 已完成的 reduce 任务:不需重新执行(因为输出在全局文件系统)
    • 正在执行的任务:重置为"等待中"状态
  • Map 任务重新执行时会通知所有 reduce worker
  • 系统可以处理大规模故障(如文中提到的 80 台机器同时故障)

2. Master 故障处理

  • 采用检查点机制,定期保存状态
  • Master 故障时从最近检查点恢复
  • 当前实现:Master 故障则终止计算,由客户端决定是否重试

3. 故障时的语义保证

  • 确定性函数情况:

    • 分布式执行结果与顺序执行相同
    • 通过原子提交机制实现:
      • Map/Reduce 任务输出先写入临时文件
      • Map 完成时向 master 报告临时文件名
      • Reduce 完成时原子性重命名为永久文件
  • 非确定性函数情况:

    • 提供较弱的语义保证
    • 同一 reduce 任务的输出等同于顺序执行
    • 不同 reduce 任务可能基于不同执行结果

改进

1. 分区函数(Partitioning Function)

  • 允许用户自定义分区方式
  • 默认使用 hash(key) mod R
  • 可根据需求自定义,如按 URL 主机名分区

2. 有序性保证

  • 同一分区内的中间键值对按键升序处理
  • 便于生成有序输出
  • 支持按键的高效随机访问

3. 合并函数(Combiner Function)

  • 在 map 端预先合并相同 key 的数据
  • 减少网络传输量
  • 适用于满足交换律和结合律的操作(如词频统计)

4. 输入输出类型

  • 支持多种输入格式(如文本行、键值对序列)
  • 可扩展的 reader/writer 接口
  • 支持自定义数据源(如数据库、内存数据结构)

5. 附属输出

  • 支持生成额外的输出文件
  • 通过临时文件和原子重命名确保一致性
  • 不支持跨文件的两阶段提交

6. 容错机制

  • 可跳过导致确定性崩溃的记录
  • 使用信号处理器捕获错误
  • master 跟踪并管理问题记录

7. 本地执行支持

  • 提供本地顺序执行模式
  • 便于调试和测试
  • 支持常规调试工具(如 gdb)

8. 状态信息

  • master 提供 HTTP 状态页面
  • 显示进度、资源使用等信息
  • 支持任务执行状态监控

9. 计数器功能

  • 支持自定义计数器统计事件
  • 自动维护系统级计数器
  • 用于监控和验证处理进度
  • 处理重复计数问题
    (1). 基本用法示例 - 文档处理统计
class DocumentCounters:def __init__(self):self.total_docs = GetCounter("total_documents")self.english_docs = GetCounter("english_documents")self.chinese_docs = GetCounter("chinese_documents")self.invalid_docs = GetCounter("invalid_documents")self.large_docs = GetCounter("large_docs_over_1mb")def map(doc_id, content):# 增加总文档计数counters.total_docs.Increment()# 检查文档大小if len(content) > 1024 * 1024:  # 1MBcounters.large_docs.Increment()try:lang = detect_language(content)if lang == 'en':counters.english_docs.Increment()elif lang == 'zh':counters.chinese_docs.Increment()process_document(content)except InvalidDocumentError:counters.invalid_docs.Increment()return# 任务完成后可以获取统计信息:
# total_documents: 1000000
# english_documents: 600000
# chinese_documents: 350000
# invalid_documents: 50000
# large_docs_over_1mb: 5000

(2). 质量控制示例 - 数据处理验证

class QualityCounters:def __init__(self):self.input_records = GetCounter("input_records")self.output_records = GetCounter("output_records")self.malformed_records = GetCounter("malformed_records")self.null_fields = GetCounter("null_required_fields")self.out_of_range = GetCounter("value_out_of_range")def map(key, record):counters.input_records.Increment()# 验证记录格式if not is_valid_format(record):counters.malformed_records.Increment()return# 检查必填字段if has_null_required_fields(record):counters.null_fields.Increment()return# 检查数值范围if not is_value_in_range(record.value):counters.out_of_range.Increment()return# 处理有效记录process_record(record)counters.output_records.Increment()# 可以通过比较计数器验证数据质量:
# input_records == output_records + malformed_records + null_fields + out_of_range

(3). 性能监控示例 - 处理时间统计

class PerformanceCounters:def __init__(self):self.processed_bytes = GetCounter("processed_bytes")self.cache_hits = GetCounter("cache_hits")self.cache_misses = GetCounter("cache_misses")self.slow_operations = GetCounter("slow_operations_over_100ms")def map(key, data):start_time = time.time()# 统计处理的数据量counters.processed_bytes.Increment(len(data))# 缓存使用统计if cache.has(key):counters.cache_hits.Increment()else:counters.cache_misses.Increment()# 处理数据result = process_data(data)# 统计慢操作if (time.time() - start_time) * 1000 > 100:  # 100mscounters.slow_operations.Increment()# 可以分析性能指标:
# cache_hit_rate = cache_hits / (cache_hits + cache_misses)
# avg_processing_speed = processed_bytes / total_time
# slow_operation_percentage = slow_operations / total_operations

(4). 业务指标统计示例 - 电商数据分析

class BusinessCounters:def __init__(self):self.total_orders = GetCounter("total_orders")self.total_revenue = GetCounter("total_revenue")self.cancelled_orders = GetCounter("cancelled_orders")self.high_value_orders = GetCounter("orders_over_1000")self.new_customers = GetCounter("new_customers")def map(order_id, order):counters.total_orders.Increment()counters.total_revenue.Increment(order.amount)if order.amount > 1000:counters.high_value_orders.Increment()if order.status == 'CANCELLED':counters.cancelled_orders.Increment()if order.is_new_customer:counters.new_customers.Increment()# 可以计算关键业务指标:
# average_order_value = total_revenue / total_orders
# cancellation_rate = cancelled_orders / total_orders
# high_value_percentage = high_value_orders / total_orders

3. 总结

目前,我们使用MapReduce做的最重要的工作之一是完全重写了一个索引系统,该系统被用作生成用于Google web搜索服务的数据结构。该索引系统将大量被我们爬虫系统检索到的文档(作为GFS文件存储)作为输入。这些文档的原始内容的数据大小超过20TB。索引进程会运行一系列5~10个MapReduce操作。使用MapReduce(而不是旧版索引系统中ad-hoc分布式传递方案)提供了很多好处:

索引代码更简单、短、便于理解,因为处理容错、分布式和并行的代码被隐藏在了MapReduce库中。例如,计算中的有一个阶段的代码量从3800行C++代码所见到了700行使用MapReduce的代码。

MapReduce库的性能足够好,这让我们可以将概念上不相关的计算分离开,而不是将它们混合在一起,这样可以避免传递过多额外的数据。这使改变索引程序变得非常简单。例如,在我们旧的索引系统中,一处修改会花费几个月的时间,而新的系统仅需要几天就能实现。

索引系统变得更容易操作。大部分因机器故障、缓慢的机器、网络不稳定等引起的问题都被MapReduce库自动处理了,不需要引入额外的操作。此外,向索引集群添加新机器以获得更好的性能变得更加简单。


实验环境

  • 操作系统:macos
  • IDE:GOLAND
  • 语言:GO 1.23
  • lab1链接:

Lab1 说明

实验内容

MapReduce 作业的抽象视图 – 词频统计示例

Input1 -> Map -> a,1 b,1
Input2 -> Map ->     b,1
Input3 -> Map -> a,1     c,1|   |   ||   |   -> Reduce -> c,1|   -----> Reduce -> b,2---------> Reduce -> a,2

运行流程

  1. 输入已被分割成 M 个片段。
  2. MapReduce 为每个输入分片调用 Map() 函数,生成键值对列表,这些数据称为“中间数据”。每个 Map() 调用是一个“任务”。
  3. 当 Map 任务完成后,MapReduce 收集每个键的所有中间值,并将每个键及其对应的值传递给 Reduce 调用。
  4. 最终输出是一组来自 Reduce() 的键值对。

词频统计代码

Map(d)将 d 切分成单词对于每个单词 wemit(w, "1")Reduce(k, v[])emit(len(v[]))

MapReduce 特点

  • 扩展性:多台计算机(N台)可以获得 N 倍的吞吐量,Map() 和 Reduce() 函数可并行运行。
  • 自动化容错处理:自动处理 Map 和 Reduce 函数代码的分发、任务跟踪、中间数据的传输、负载均衡、崩溃恢复等。
  • 设计限制:不允许有交互或状态,数据流只支持 Map/Reduce 模式,不支持实时或流式处理。

实验要求

核心任务

实现一个分布式的 MapReduce 系统,包含两个主要程序:

  1. coordinator(协调者)
  2. worker(工作者)

系统架构

  • 只有一个 coordinator 进程。
  • 允许多个 worker 进程并行执行,worker 通过 RPC 与 coordinator 通信。
  • 所有进程运行在同一台机器上。

Worker 工作流程

  1. 向 coordinator 请求任务。
  2. 从一个或多个文件读取任务输入。
  3. 执行任务并将输出写入一个或多个文件。
  4. 重复请求新任务直到任务完成。

具体要求

  1. Map 阶段输出要求

    • 将中间键分成 nReduce 个桶,每个 mapper 创建 nReduce 个中间文件供 reduce 任务使用。
  2. 输出文件要求

    • 第 X 个 reduce 任务的输出放在 mr-out-X 文件中,每个 Reduce 函数的输出一行,使用 Go 的 “%v %v” 格式化输出 key 和 value。
  3. 容错处理

    • coordinator 需要检测 worker 是否在 10 秒内完成任务,如果超时,则将任务重新分配给其他 worker。
  4. 任务完成判断

    • coordinator 需实现 Done() 方法,当 MapReduce 工作完全结束时返回 true,通知 worker 进程退出。

可修改的文件

  • mr/worker.go
  • mr/coordinator.go
  • mr/rpc.go

实验提示(Hints)

  1. 入门建议

    • 修改 mr/worker.go 的 Worker() 函数,使其发送 RPC 请求给 coordinator 请求任务。
    • 修改 coordinator 使其返回尚未开始的 map 任务文件名,worker 可使用该文件名调用应用程序的 Map 函数。
  2. 插件

    • Map 和 Reduce 函数通过 Go plugin 包从 .so 文件加载。修改 mr/ 目录下内容时,需重新构建 MapReduce 插件:
      go build -buildmode=plugin ../mrapps/wc.go
      
  3. 文件系统

    • 本实验要求 workers 共享文件系统,同一机器上运行时较简单,不同机器上则需 GFS 等全局文件系统支持。
  4. 命名约定

    • 中间文件命名格式:mr-X-Y,其中 X 是 Map 任务编号,Y 是 reduce 任务编号。
  5. JSON 存储建议

    // 写入 key/value 对
    enc := json.NewEncoder(file)
    for _, kv := ... {err := enc.Encode(&kv)
    }// 读取 key/value 对
    dec := json.NewDecoder(file)
    for {var kv KeyValueif err := dec.Decode(&kv); err != nil {break}kva = append(kva, kv)
    }
    
  6. 任务分配

    • worker 可以使用 ihash(key) 函数(在 worker.go 中)来选择 reduce 任务。
    • 可参考 mrsequential.go 实现中的代码:读取 Map 输入文件、中间 key/value 对排序、将 Reduce 输出存储到文件。
  7. 并发与锁定

    • coordinator 是 RPC 服务器,需要锁定共享数据。可使用 Go 的竞态检测器测试并发:
      go run -race
      
  8. 等待机制

    • workers 有时需要等待(如等待最后一个 map 完成后才能开始 reduce),可让 workers 定期询问 coordinator,并使用 time.Sleep()
  9. 错误处理

    • coordinator 需要处理 worker 崩溃或卡住的情况,建议等待 10 秒后假设 worker 已死亡,重新分配任务。
  10. 测试建议

    • 使用 mrapps/crash.go 测试崩溃恢复。
    • 使用临时文件并原子重命名处理崩溃的文件写入:
      tempFile, _ := ioutil.TempFile("", "temp-")
      os.Rename(tempFile.Name(), "final-output-file")
      
  11. RPC 相关

    • Go RPC 只发送首字母大写的结构体字段,reply 结构体需包含默认值。
    • 调用 RPC call() 函数时,reply 结构体应包含所有默认值:
      reply := SomeType{}
      call(..., &reply)
      

规则说明

  1. Map 阶段规则

    • Map 阶段将中间键分成 nReduce 个桶用于 reduce 任务,每个 mapper 为 reduce 任务创建 nReduce 个中间文件。
  2. 输出文件规则

    • worker 将第 X 个 reduce 任务的输出放在 mr-out-X 文件中。
  3. 输出格式规则

    • mr-out-X 文件中的每行输出使用 Go 的 “%v %v” 格式,传入 key 和 value。
  4. 文件修改规则

    • 可修改 mr/worker.gomr/coordinator.gomr/rpc.go。测试时需确保代码在原始版本下正常运行。
  5. 中间输出规则

    • worker 将 Map 的中间输出放在当前目录的文件中供后续 Reduce 任务读取。
  6. 任务完成状态规则

    • main/mrcoordinator.go 中 Done() 方法在任务完成时返回 true,协调器结束任务。
  7. 进程退出规则

    • worker 如果无法联系到 coordinator,可假设任务已完成并退出。coordinator 也可发送“请退出”的伪任务。

测试要求

必须通过以下测试:

  1. Word Count 测试
  2. Indexer 测试
  3. Map 并行性测试
  4. Reduce 并行性测试
  5. Job Count 测试
  6. Early Exit 测试
  7. Crash 测试

所有测试包含在 test-mr.sh 脚本中,最终输出需与顺序执行结果一致。

具体实现

问题

  1. 使用goland中的模板进行build的时候出错
    如果直接从main函数进行build不会报错,如果手动从模板进行会报错
  2. lab题目理解出问题

总结

参考

  1. MapReduce论文翻译

相关文章:

MIT 6.824 Lab1记录

MapReduce论文阅读 1. 编程模型 Map 函数&#xff08;kv -> kv&#xff09; Map 函数将输入的键值对处理为一系列中间值&#xff08;键值对&#xff09;&#xff0c;并将所有的中间结果传递给 Reduce 处理。 map(String key, String value):// key: document name// val…...

C语言数据结构学习:[汇总]

介绍 这些是我在学习C语言数据结构时练习的一些题目以及个人笔记 大家也可以参考着来学习 正在更新 大家可以在我的gitee仓库 中下载笔记源文件 笔记源文件可以在Notion中导入 内容导航 C语言数据结构学习&#xff1a;单链表-CSDN博客...

unity游戏开发之塔防游戏

如何制作塔防游戏 让我们以迷你游戏的形式创建一个休闲塔防。 从基本处理到适用技术&#xff0c;应有尽有&#xff0c;因此您只需制作一次即可获得 Unity 中的游戏制作专业知识。 与背景素材结合使用时&#xff0c;您将获得以下游戏视图&#xff1a; 由于在创建过程中使用了 …...

前端项目接入sqlite轻量级数据库sql.js指南

前端项目接入sqlite轻量级数据库sql.js指南 引言 sql.js 是一个强大的JavaScript库&#xff0c;它使得SQLite数据库能够在网页浏览器中运行。这个开源项目提供了一种方式&#xff0c;让开发者可以在前端环境中实现轻量级的数据库操作&#xff0c;无需依赖服务器端数据存储&…...

模拟退火算法(Simulated Annealing)详细解读

模拟退火算法&#xff08;Simulated Annealing&#xff09; 是一种随机优化算法&#xff0c;受到物理学中金属退火过程的启发。它用于寻找全局最优解&#xff0c;特别适合解决组合优化问题。模拟退火算法通过模拟物质在加热和冷却过程中粒子位置的变化&#xff0c;逐渐寻找系统…...

(二十一)、Docker 部署 Minikube 使用可视化管理工具 Kuboard

文章目录 1、介绍docker 运行 minikube 集群节点&#xff08;kube-apiserver &#xff09;无法被直接访问的问题Kuboard 需要访问到 k8s 集群的kube-apiserver 2、安装 Kuboard2.1、k8s 集群节点可以被外部直接访问的情况2.1.1、下载镜像2.1.2、运行 deployment.yml2.1.3、访问…...

代码编辑组件

代码编辑组件 文章说明核心代码运行演示源码下载 文章说明 拖了很久&#xff0c;总算是自己写了一个简单的代码编辑组件&#xff0c;虽然还有不少的bug&#xff0c;真的很难写&#xff0c;在写的过程中感觉自己的前端技术根本不够用&#xff0c;好像总是方案不够好&#xff1b;…...

裴蜀定理与欧几里得算法——蓝桥杯真题中的应用

目录 裴蜀定理&#xff08;Bzouts Theorem&#xff09;1、定义2、推论3、欧几里得算法4、多个整数的裴蜀定理扩展 真题挑战解题思路代码实现与详细注释代码解析 裴蜀定理&#xff08;Bzout’s Theorem&#xff09; 1、定义 对于任意两个整数 a 和 b &#xff0c;如果它们的最…...

冯诺依曼架构及CPU相关概念

一. 操作系统的概念 1. 概念 操作系统(Operating System). 首先, 所有的计算机都是由软件和硬件构成的. 而操作系统就是许许多多软件中的一种软件, 操作系统可以看作是由两部分组成: 操作系统内核系统级应用程序. 2. 作用 (1) 管理硬件设备, 调度和协调各个硬件之间的工作.…...

智能管线巡检系统:强化巡检质量,确保安全高效运维

线路巡检质量的监控是确保线路安全、稳定运行的重要环节。为了有效监控巡检质量&#xff0c;采用管线巡检系统是一种高效、科学的手段。以下是对如何通过管线巡检系统实现线路巡检质量监控的详细分析&#xff1a; 一、巡检速度监控 管线巡检系统能够实时监控巡检人员的巡检速度…...

React写关键字高亮的三个方案

1.js正则replaceAlldangerouslySetInnerHTML{{ __html: xxx }}危险属性 步骤最简单,但是是危险属性,不推荐使用,项目中实在没有头绪,可以使用它应急 通过useMemo计算得到新的状态值,赋值给dangerouslySetInnerHTML属性的__html 关键代码: const [state1, setState1] useSt…...

重塑在线软件开发新纪元:集成高效安全特性,深度解析与评估会员与促销管理系统的系统架构设计

案例 阅读以下关于软件架构设计与评估的叙述&#xff0c;回答问题1和问题2。 【题目】 某电子商务公司拟升级其会员与促销管理系统&#xff0c;向用户提供个性化服务&#xff0c;提高用户的粘性。在项目立项之初&#xff0c;公司领导层一致认为本次升级的主要目标是提升会员管…...

多层感知机的从零实现与softmax的从零实现(真·0000零基础)

今天再读zh.d2l书&#xff08;4.2. 多层感知机的从零开始实现 — 动手学深度学习 2.0.0 documentation&#xff09;&#xff0c; 看了关于多层感知机的从零实现与softmax的从零实现 目录 mlp从零实现&#xff0c; 点击“paddle”的代码 点击“torch”的代码 训练 参数解…...

【Rust练习】18.特征 Trait

练习题来自&#xff1a;https://practice-zh.course.rs/generics-traits/traits.html 1 // 完成两个 impl 语句块 // 不要修改 main 中的代码 trait Hello {fn say_hi(&self) -> String {String::from("hi")}fn say_something(&self) -> String; }str…...

【自动化测试之oracle数据库】MacOs如何安装oracle- client

操作系统为Mac OS&#xff0c;本地在pycharm上跑自动化脚本时&#xff0c;因为有操作oracle数据库的部分&#xff0c;所以需要安装oracle数据库的客户端&#xff0c;并install cx_oracle,本文主要介绍如何在macOS上完成安装&#xff0c;并在python自动化测试代码中配置&#xf…...

Spring MVC的MultipartFile

定义 MultipartFile接口是Spring MVC中用来处理上传文件的接口&#xff0c;它提供了访问上传文件内容、文件名称、文件大小等信息的方法。 源码&#xff1a; package org.springframework.web.multipart;import java.io.File; import java.io.IOException; import java.io.I…...

●Leetcode| 242.有效的字母异位词 ● 349. 两个数组的交集 ● 202. 快乐数● 1. 两数之和

242,该题目中数组范围比较短&#xff0c;可以数组使用并不会占太多的空间&#xff0c;利用数组的映射&#xff0c;查找到自己所需要的字符 class Solution { public:bool isAnagram(string s, string t) {int record[26] {0};for(int i0;i<s.size();i){record[s[i] - a];/…...

关于算法的时间复杂度和空间复杂度的分析

由于最近开始准备蓝桥杯(python组)&#xff0c;开始对编程基础进行一些复习&#xff0c;当我发现蓝桥对大多数题目程序运行时间及大小有要求时&#xff0c;我知道我不得不考虑性能问题&#xff0c;而不是能跑就行&#x1f913; 写下这篇文章希望对其他同志有帮助吧 什么是算法…...

深入浅出 C++ STL:解锁高效编程的秘密武器

引言 C 标准模板库&#xff08;STL&#xff09;是现代 C 的核心部分之一&#xff0c;为开发者提供了丰富的预定义数据结构和算法&#xff0c;极大地提升了编程效率和代码的可读性。理解和掌握 STL 对于 C 开发者来说至关重要。以下是对 STL 的详细介绍&#xff0c;涵盖其基础知…...

2024年1024程序人生总结

2024-1024 0.大环境0.1.经济0.2.战争 1.我的程序人生1.1.游戏 2.节日祝福 0.大环境 今年的1024最大的感触就是没有节日氛围&#xff0c;往年公司还会准备节日礼物&#xff0c;今年没有&#xff0c;由此可见大环境有多么糟糕。 除此之外&#xff0c;就是到公司应聘的程序员越来…...

【p2p、分布式,区块链笔记 分布式容错算法】: 拜占庭将军问题+实用拜占庭容错算法PBFT

papercodehttps://pmg.csail.mit.edu/papers/osdi99.pdfhttps://github.com/luckydonald/pbft 其他相关实现&#xff1a;This is an implementation of the Pracltical Byzantine Fault Tolerance protocol using PythonAn implementation of the PBFT consensus algorithm us…...

鸿蒙NEXT开发-应用数据持久化之用户首选项(基于最新api12稳定版)

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…...

人工智能_神经网络103_感知机_感知机工作原理_感知机具备学习能力_在学习过程中自我调整权重_优化效果_多元线性回归_逻辑回归---人工智能工作笔记0228

由于之前一直对神经网络不是特别清楚,尤其是对神经网络中的一些具体的概念,包括循环,神经网络卷积神经网络以及他们具体的作用,都是应用于什么方向不是特别清楚,所以现在我们来做教程来具体明确一下。 当然在机器学习之后还有深度学习,然后在深度学习中对各种神经网络的…...

WISE:重新思考大语言模型的终身模型编辑与知识记忆机制

论文地址&#xff1a;https://arxiv.org/abs/2405.14768https://arxiv.org/abs/2405.14768 1. 概述 随着世界知识的不断变化&#xff0c;大语言模型&#xff08;LLMs&#xff09;需要及时更新&#xff0c;纠正其生成的虚假信息或错误响应。这种持续的知识更新被称为终身模型编…...

网络安全证书介绍

网络安全领域有很多专业的证书&#xff0c;可以帮助你提升知识和技能&#xff0c;增强在这个行业中的竞争力。以下是一些常见的网络安全证书&#xff1a; 1. CompTIA Security 适合人群&#xff1a;初级安全专业人员证书内容&#xff1a;基础的网络安全概念和实践&#xff0c…...

【已解决】【hadoop】【hive】启动不成功 报错 无法与MySQL服务器建立连接 Hive连接到MetaStore失败 无法进入交互式执行环境

启动hive显示什么才是成功 当你成功启动Hive时&#xff0c;通常会看到一系列的日志信息输出到控制台&#xff0c;这些信息包括了Hive服务初始化的过程以及它与Metastore服务连接的情况等。一旦Hive完成启动并准备就绪&#xff0c;你将看到提示符&#xff08;如 hive> &#…...

基于架设一台NFS服务器实操作业

架设一台NFS服务器&#xff0c;并按照以下要求配置 首先需要关闭防火墙和SELinux 1、开放/nfs/shared目录&#xff0c;供所有用户查询资料 赋予所有用户只读的权限&#xff0c;sync将数据同步写到磁盘上 在客户端需要创建挂载点&#xff0c;把服务端共享的文件系统挂载到所创建…...

eachers中的树形图在点击其中某个子节点时关闭其他同级子节点

答案在代码末尾&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; tubiaoinit(params: any) {// 手动触发变化检测this.changeDetectorRef.detectChanges();if (this.myChart ! undefined) {this.myChart.dispose();}this.myChart echarts.init(this.pieChart?…...

Maven 介绍与核心概念解析

目录 1. pom文件解析 2. Maven坐标 3. Maven依赖范围 4. Maven 依赖传递与冲突解决 Maven&#xff0c;作为一个广泛应用于 Java 平台的自动化构建和依赖管理工具&#xff0c;其强大功能和易用性使得它在开发社区中备受青睐。本文将详细解析 Maven 的几个核心概念&a…...

计算机网络-MSTP概述

一、RSTP/STP的缺陷与不足 前面我们学习了RSTP对于STP的一些优化与快速收敛机制。但在划分VLAN的网络中运行RSTP/STP&#xff0c;局域网内所有的VLAN共享一棵生成树&#xff0c;被阻塞后的链路将不承载任何流量&#xff0c;无法在VLAN间实现数据流量的负载均衡&#xff0c;导致…...