MIT6.824(6.5840) Lab1笔记+源码

news2024/9/22 7:40:37

文章目录

  • 其他人的内容,笔记写的更好,思路可以去看他们的
  • MapReduce
    • worker
      • map
      • reduce
    • coordinator
    • rpc
    • 纠错
  • 源码
    • worker.go
    • coordinator.go
    • rpc.go

原本有可借鉴的部分
mrsequential.go,多看几遍源码

其他人的内容,笔记写的更好,思路可以去看他们的

MIT - 6.824 全课程 + Lab 博客总览-CSDN博客

MapReuce 详解与复现, 完成 MIT 6.824(6.5840) Lab1 - 掘金 (juejin.cn)

mit 6.824 lab1 笔记 - 掘金 (juejin.cn)

MapReduce

每个 worker 进程需完成以下工作:
向 master 进程请求 task,从若干文件中读取输入数据,执行 task,并将 task 的输出写入到若干文件中。

master 进程除了为 worker 进程分配 task 外,还需要检查在一定时间内(本实验中为 10 秒)每个 worker 进程是否完成了相应的 task,如果未完成的话则将该 task 转交给其他 worker 进程。

worker

worker函数包含map和redicef两个功能
需要知道自己执行哪个功能

worker 请求获取任务 GetTask

任务设置为结构体,其中一个字段为任务类型

type Task struct{Type:0 1 }0为map,1为reduce const枚举

一个为编号

如何获取任务?

GetTask请求coordinator的assignTask方法,传入为自己的信息(???),获得任务信息

自己当前的状态 空闲 忙碌

call(rpcname,args,reply)bool的rpcname对应coordinator.go中coordinator的相关方法

???没理解这个什么用
GetTask中调用call来从coordinator获取任务信息?

那么rpc.go来干什么

使用ihash(key) % NReduce为Map发出的每个KeyValue选择reduce任务号。随机选择序号
n个文件,生成m个不同文件 n X m个 文件??

保存多少个文件

map得到

对结果ohashkey,写入到文件序号1-10

根据序号分配reduce任务

将结果写入到同一文件

map

mapf func(filename string, content string) []KeyValue

filename是传入的文件名
content为传入的文件的内容——传入前需读取内容

传出intermediate[] 产生文件名 mr-x-y

reduce

reducef func(key string, values []string) string)

这里的key对应ihash生成的任务号??

coordinator

分配任务
需要创建几个map worker—根据几个文件
几个 reduce worker—根据设置,这里为10

coordinator函数用来生成唯一id

Coordinator 结构体定义

用来在不同rpc之间通信,所以其内容是公用的?

type Coordinator struct{
	files   []string
	nReduce int
当前处在什么阶段? state


}

type dic struct{
status 0or1or2
id       
}

map[file string]

如何解决并发问题??

怎么查询worker的状态??

worker主动向coordinator发送信息

rpc

args 请求参数怎么定义

type args struct{

自己的身份信息

自己的状态信息

}

纠错

  1. 6.5840/mr.writeKVs({0xc000e90000, 0x1462a, 0x16800?}, 0xc00007d100, {0xc39d00, 0x0, 0x0?})
    /home/wang2/6.5840/src/mr/worker.go:109 +0x285

  2. *** Starting wc test.
    panic: runtime error: index out of range [1141634764] with length 0

    ihash取余

  3. runtime error: integer divide by zero

reply.NReduce = c.nReduce // 设置 NReduce

  1. cat: ‘mr-out*’: No such file or directory
    — saw 0 workers rather than 2
    — map parallelism test: FAIL
    cat: ‘mr-out*’: No such file or directory
    — map workers did not run in parallel
    — map parallelism test: FAIL

    cat: ‘mr-out*’: No such file or directory
    — too few parallel reduces.
    — reduce parallelism test: FAIL
    文件句柄问题

  2. sort: cannot read: ‘mr-out*’: No such file or directory
    cmp: EOF on mr-wc-all which is empty
    2024/07/19 11:15:10 dialing:dial unix /var/tmp/5840-mr-1000: connect: connection refused
    2024/07/19 11:15:10 dialing:dial unix /var/tmp/5840-mr-1000: connect: connection refused
    2024/07/19 11:15:10 dialing:dial unix /var/tmp/5840-mr-1000: connect: connection refused

  3. coordinator结构体的并发读取问题
    dialing:dial-http unix /var/tmp/5840-mr-1000: read unix @->/var/tmp/5840-mr-1000: read: connection reset by peer

源码

由于笔记等提示跟没有没区别,这里将源码放上,等大家实在没办法再看吧,
github仓库地址
注意lab1中的提示很重要

博主初期也迷茫过,检查bug也痛苦过,祝福大家。
在这里插入图片描述

有的时候也会出错,但是不想搞了–

在这里插入图片描述

worker.go

package mr

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"sort"
	"strings"
	"time"
)
import "log"
import "net/rpc"
import "hash/fnv"

// for sorting by key.
type ByKey []KeyValue

// for sorting by key.
func (a ByKey) Len() int           { return len(a) }
func (a ByKey) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByKey) Less(i, j int) bool { return a[i].Key < a[j].Key }

const (
	Map = iota
	Reduce
	Over
)
const (
	Idle = iota
	Busy
	Finish
)

// Map functions return a slice of KeyValue.

type KeyValue struct {
	Key   string
	Value string
}

// use ihash(key) % NReduce to choose the reduce
// task number for each KeyValue emitted by Map.

func ihash(key string) int {
	h := fnv.New32a()
	h.Write([]byte(key))
	return int(h.Sum32() & 0x7fffffff)
}

// main/mrworker.go calls this function.

func Worker(mapf func(string, string) []KeyValue, reducef func(string, []string) string) {
	// Your worker implementation here.

	Ch := make(chan bool)
	for {
		var Res = &Args{State: Idle} //初始化为idle状态
		var TaskInformation = &TaskInfo{}
		GetTask(Res, TaskInformation)

		//主任务结束后不再请求
		if TaskInformation.TaskType == Over {
			break
		}
		//fmt.Println("do it!")
		go DoTask(TaskInformation, mapf, reducef, Ch)

		sign := <-Ch
		//fmt.Println("sign:", sign)

		if sign == true {
			//fmt.Println("Finish one,ID:", TaskInformation.TaskId)
			Done(Res, TaskInformation)

		} else {
			//TaskInformation.Status = Idle
			//fmt.Println("err one,ID:", TaskInformation.TaskId)
			call("Coordinator.Err", Res, TaskInformation)
			Res = &Args{State: Idle}
		}
		time.Sleep(time.Second)
	}

	// uncomment to send the Example RPC to the coordinator.
	//CallExample()

}

func GetTask(Args *Args, TaskInformation *TaskInfo) {
	// 调用coordinator获取任务
	for {
		call("Coordinator.AssignTask", Args, TaskInformation)
		//fmt.Println(TaskInformation)

		if TaskInformation.Status != Idle {
			Args.State = Busy
			Args.Tasktype = TaskInformation.TaskType
			Args.TaskId = TaskInformation.TaskId
			//fmt.Println("TaskInfo:", TaskInformation)
			//fmt.Println("Args:", Args)
			call("Coordinator.Verify", Args, TaskInformation)
			break
		}

		time.Sleep(time.Second)
	}
	//fmt.Printf("Type:%v,Id:%v\n", TaskInformation.TaskType, TaskInformation.TaskId)
}

func writeKVs(KVs []KeyValue, info *TaskInfo, fConts []*os.File) {
	//fConts := make([]io.Writer, info.NReduce)
	KVset := make([][]KeyValue, info.NReduce)

	//fmt.Println("start write")

	//for j := 1; j <= info.NReduce; j++ {
	//
	//	fileName := fmt.Sprintf("mr-%v-%v", info.TaskId, j)
	//	os.Create(fileName)
	//
	//	f, _ := os.Open(fileName)
	//	fConts[j-1] = f
	//
	//	defer f.Close()
	//}
	var Order int
	for _, v := range KVs {
		Order = ihash(v.Key) % info.NReduce
		KVset[Order] = append(KVset[Order], v)
	}
	//fmt.Println("kvset:", KVset)

	for i, v := range KVset {

		for _, value := range v {
			data, _ := json.Marshal(value)
			_, err := fConts[i].Write(data)

			//fmt.Println("data: ", data)
			//fmt.Println("numbers:", write)
			if err != nil {
				return
			}

		}
	}
	//fmt.Println("finish write")
}

func read(filename string) []byte {
	//fmt.Println("read", filename)
	file, err := os.Open(filename)
	defer file.Close()
	if err != nil {
		log.Fatalf("cannot open %v", filename)
		fmt.Println(err)
	}
	content, err := io.ReadAll(file)
	if err != nil {
		log.Fatalf("cannot read %v", filename)
	}

	return content
}

// DoTask 执行mapf或者reducef任务

func DoTask(info *TaskInfo, mapf func(string, string) []KeyValue, reducef func(string, []string) string, Ch chan bool) {
	//fConts := make([]io.Writer, info.NReduce)

	//fmt.Println("start", info.TaskId)
	//go AssignAnother(Ch)
	switch info.TaskType {
	case Map:
		info.FileContent = string(read(info.FileName))
		//fmt.Println(info.FileContent)
		KVs := mapf(info.FileName, info.FileContent.(string))
		//fmt.Println("map:", KVs)
		//将其排序
		sort.Sort(ByKey(KVs))

		var fConts []*os.File // 修改为 *os.File 类型

		//0-9
		for j := 0; j < info.NReduce; j++ {

			//暂时名,完成后重命名
			fileName := fmt.Sprintf("mr-%v-%v-test", info.TaskId, j)
			//_, err := os.Create(fileName)
			//if err != nil {
			//	fmt.Println(err)
			//	return
			//}
			//
			//f, _ := os.Open(fileName)
			//fConts[j-1] = f
			//
			//defer f.Close()
			f, err := os.Create(fileName) // 直接使用 Create 函数
			if err != nil {
				fmt.Println(err)
				return
			}

			//fmt.Println("creatfile:  ", fileName)

			//fConts[j] = f
			fConts = append(fConts, f)
			defer os.Rename(fileName, strings.TrimSuffix(fileName, "-test"))
			defer f.Close()
		}

		writeKVs(KVs, info, fConts)

	case Reduce:
		fileName := fmt.Sprintf("testmr-out-%v", info.TaskId)
		fileOS, err := os.Create(fileName)
		//fmt.Println("create success")
		if err != nil {
			fmt.Println("Error creating file:", err)
			return
		}
		defer os.Rename(fileName, strings.TrimPrefix(fileName, "test"))
		defer fileOS.Close()
		var KVs []KeyValue
		//读取文件
		for i := 0; i < info.Nmap; i++ {
			fileName := fmt.Sprintf("mr-%v-%v", i, info.TaskId)
			//fmt.Println(fileName)

			file, err := os.Open(fileName)
			defer file.Close()
			if err != nil {
				fmt.Println(err)
			}

			dec := json.NewDecoder(file)

			for {
				var kv KeyValue
				if err := dec.Decode(&kv); err != nil {
					break
				}
				//fmt.Println(kv)
				KVs = append(KVs, kv)
			}
		}
		//var KVsRes []KeyValue
		sort.Sort(ByKey(KVs))
		//整理并传输内容给reduce
		i := 0
		for i < len(KVs) {
			j := i + 1
			for j < len(KVs) && KVs[j].Key == KVs[i].Key {
				j++
			}
			values := []string{}
			for k := i; k < j; k++ {
				values = append(values, KVs[k].Value)
			}
			// this is the correct format for each line of Reduce output.
			output := reducef(KVs[i].Key, values)
			//每个key对应的计数
			//KVsRes = append(KVsRes, KeyValue{KVs[i].Key, output})

			fmt.Fprintf(fileOS, "%v %v\n", KVs[i].Key, output)

			i = j
		}

	}
	Ch <- true

}

func Done(Arg *Args, Info *TaskInfo) {

	//Info.Status = Idle
	call("Coordinator.WorkerDone", Arg, Info)

	//arg重新清空
	Arg = &Args{State: Idle}
}

func AssignAnother(Ch chan bool) {
	time.Sleep(2 * time.Second)

	Ch <- false
}

// example function to show how to make an RPC call to the coordinator.
//
// the RPC argument and reply types are defined in rpc.go.
func CallExample() {

	// declare an argument structure.
	args := ExampleArgs{}

	// fill in the argument(s).
	args.X = 99

	// declare a reply structure.
	reply := ExampleReply{}

	// send the RPC request, wait for the reply.
	// the "Coordinator.Example" tells the
	// receiving server that we'd like to call
	// the Example() method of struct Coordinator.
	ok := call("Coordinator.Example", &args, &reply)
	if ok {
		// reply.Y should be 100.
		fmt.Printf("reply.Y %v\n", reply.Y)
	} else {
		fmt.Printf("call failed!\n")
	}
}

// send an RPC request to the coordinator, wait for the response.
// usually returns true.
// returns false if something goes wrong.

func call(rpcname string, args interface{}, reply interface{}) bool {
	// c, err := rpc.DialHTTP("tcp", "127.0.0.1"+":1234")
	sockname := coordinatorSock()
	//fmt.Println("Worker is dialing", sockname)
	c, err := rpc.DialHTTP("unix", sockname)
	if err != nil {
		//log.Fatal("dialing:", err)
		return false
	}
	defer c.Close()

	err = c.Call(rpcname, args, reply)
	if err != nil {
		//fmt.Println(err)
		return false
	}

	return true
}

coordinator.go

package mr

import (
	"log"
	"sync"
	"time"
)
import "net"
import "os"
import "net/rpc"
import "net/http"

type Coordinator struct {
	// Your definitions here.
	files      []string
	nReduce    int
	MapTask    map[int]*Task
	ReduceTask []int
	OK         bool
	Lock       sync.Mutex
}

type Task struct {
	fileName string
	state    int
}

var TaskMapR map[int]*Task

func (c *Coordinator) Verify(Arg *Args, Reply *TaskInfo) error {

	switch Arg.Tasktype {
	case Map:
		time.Sleep(3 * time.Second)
		if c.MapTask[Arg.TaskId].state != Finish {
			c.MapTask[Arg.TaskId].state = Idle
			Reply = &TaskInfo{}
		}
	case Reduce:
		time.Sleep(3 * time.Second)
		if c.ReduceTask[Arg.TaskId] != Finish {
			c.ReduceTask[Arg.TaskId] = Idle
			Reply = &TaskInfo{}
		}
	}
	return nil
}

// Your code here -- RPC handlers for the worker to call.
func (c *Coordinator) AssignTask(Arg *Args, Reply *TaskInfo) error {
	c.Lock.Lock()
	defer c.Lock.Unlock()
	//如果请求为空闲
	if Arg.State == Idle {

		//Args.State = Busy
		//首先分配Map
		for i, task := range c.MapTask {
			//fmt.Println(*task, "Id:", i)
			if task.state == Idle {
				//Arg.Tasktype = Map
				//Arg.TaskId = i + 1
				Reply.TaskType = Map
				Reply.FileName = task.fileName

				//fmt.Println(task.fileName)

				Reply.TaskId = i          //range从0开始
				Reply.NReduce = c.nReduce // 设置 NReduce
				Reply.Status = Busy
				task.state = Busy
				//fmt.Println("map,Id:", i)
				return nil
			}
		}

		//Map完成后再Reduce
		for _, task := range c.MapTask {
			if task.state != Finish {
				//fmt.Println("等待Map完成")
				return nil
			}
		}

		//fmt.Println("MapDone")

		//分配Reduce
		for i, v := range c.ReduceTask {
			//fmt.Println(c.ReduceTask)
			if v == Idle {
				Arg.Tasktype = Reduce
				Arg.TaskId = i
				Reply.TaskType = Reduce
				Reply.TaskId = i
				Reply.NReduce = c.nReduce // 设置 NReduce
				Reply.Status = Busy
				Reply.Nmap = len(c.files)
				c.ReduceTask[i] = Busy
				//fmt.Println(c.ReduceTask[i])
				//fmt.Println("reduce", i)
				return nil
			}
		}

		//Reduce都结束则成功
		for _, v := range c.ReduceTask {
			if v == Finish {
			} else {
				return nil
			}
		}
		Reply.TaskType = Over
		c.OK = true
	}

	return nil
}

func (c *Coordinator) WorkerDone(args *Args, reply *TaskInfo) error {
	//c.Lock.Lock()
	//defer c.Lock.Unlock()

	//reply清空
	reply = &TaskInfo{}
	//args.State = Finish

	id := args.TaskId
	//fmt.Println("id", id)
	switch args.Tasktype {
	case Map:
		c.MapTask[id].state = Finish
		//fmt.Println(*c.MapTask[id])
	case Reduce:
		c.ReduceTask[id] = Finish
		//fmt.Println(c.ReduceTask)
	}
	return nil
}

func (c *Coordinator) Err(args *Args, reply *TaskInfo) error {
	//c.Lock.Lock()
	//defer c.Lock.Unlock()

	reply = &TaskInfo{}
	id := args.TaskId
	switch args.Tasktype {
	case Map:
		if c.MapTask[id].state != Finish {
			c.MapTask[id].state = Idle
		}

	case Reduce:
		if c.ReduceTask[id] != Finish {
			c.ReduceTask[id] = Idle
		}
	}
	return nil
}

// an example RPC handler.
//
// the RPC argument and reply types are defined in rpc.go.

func (c *Coordinator) Example(args *ExampleArgs, reply *ExampleReply) error {
	reply.Y = args.X + 1
	return nil
}

// start a thread that listens for RPCs from worker.go

func (c *Coordinator) server() {
	rpc.Register(c)
	rpc.HandleHTTP()
	sockname := coordinatorSock()
	os.Remove(sockname)
	l, e := net.Listen("unix", sockname)
	if e != nil {
		log.Fatal("listen error:", e)
	}
	//fmt.Println("Coordinator is listening on", sockname)
	go http.Serve(l, nil)
}

// main/mrcoordinator.go calls Done() periodically to find out
// if the entire job has finished.

func (c *Coordinator) Done() bool {
	//c.Lock.Lock()
	//defer c.Lock.Unlock()

	ret := false
	if c.OK == true {
		ret = true
	}
	// Your code here.

	return ret
}

// create a Coordinator.
// main/mrcoordinator.go calls this function.
// nReduce is the number of reduce tasks to use.
func MakeCoordinator(files []string, nReduce int) *Coordinator {
	//fmt.Println(files)
	TaskMapR = make(map[int]*Task, len(files))

	for i, file := range files {
		TaskMapR[i] = &Task{
			fileName: file,
			state:    Idle,
		}
	}

	ReduceMap := make([]int, nReduce)

	c := Coordinator{
		files:      files,
		nReduce:    nReduce,
		MapTask:    TaskMapR,
		ReduceTask: ReduceMap,
		OK:         false,
	}

	// Your code here.

	c.server()

	return &c
}

rpc.go

package mr

//
// RPC definitions.
//
// remember to capitalize all names.
//

import "os"
import "strconv"

//
// example to show how to declare the arguments
// and reply for an RPC.
//

type ExampleArgs struct {
	X int
}

type ExampleReply struct {
	Y int
}

// Add your RPC definitions here.

type Args struct {
	State    int
	Tasktype int
	TaskId   int
}

type TaskInfo struct {
	Status int

	TaskType int //任务基本信息
	TaskId   int

	NReduce int
	Nmap    int

	FileName    string
	FileContent any

	//Key    string //reduce所需信息
	//Values []string
}

// Cook up a unique-ish UNIX-domain socket name
// in /var/tmp, for the coordinator.
// Can't use the current directory since
// Athena AFS doesn't support UNIX-domain sockets.

func coordinatorSock() string {
	s := "/var/tmp/5840-mr-"
	s += strconv.Itoa(os.Getuid())
	return s
}

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

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

相关文章

如何实现ORACLE19c 安装包DIY

最近一直忙&#xff0c;本想每周有更新的&#xff0c;但老板一句话&#xff0c;就得去干活&#xff0c;想实现这个愿望&#xff0c;看来真的很难&#xff0c;做一天好人容易&#xff0c;要一辈子做好人&#xff0c;难。所以&#xff0c;看到德哥&#xff0c;尹总监&#xff0c;…

言语理解与表达

** 言语理解与表达 1.逻辑填空 2.语句表达 3.阅读理解

MTK 安卓14 launcher3修改桌面模式,替换某些应用图标,以及定制化Hotseat

原生的launcher的Hotseat如下图(1)所示,我想把效果改成图(2) 图(1) 图(2) 一:定制化HotSeat 修改的类&#xff1a;packages/apps/Launcher3/com/android/launcher3/Hotseat.java &#xff08;1&#xff09;.修改hotseat的宽 Hotseat------->setInsetsOverridepublic void…

Java 22 中的4个永久特性

功能处于孵化或预览阶段是什么意思&#xff1f; 实际上&#xff0c;这是向 Java 编程语言添加新功能的新过程&#xff0c;Java 社区使用这种过程来在 API 和工具处于早期实验阶段时从社区获得反馈&#xff08;孵化功能&#xff09;或已经完全指定但尚未永久的阶段&#xff08;…

ConstraintLayout属性说明

ayout_constraintTop_toTopOf&#xff1a;将某一控件的顶部与另一控件的顶部对齐。 layout_constraintTop_toBottomOf&#xff1a;将某一控件的顶部与另一控件的底部对齐。 layout_constraintBottom_toTopOf&#xff1a;将某一控件的底部与另一控件的顶部对齐。 layout_cons…

3GPP R18 Multi-USIM是怎么回事?(四)

前几篇主要是MUSIM feature NAS 部分内容的总结,这篇开始看RRC部分相关的内容,由于RRC部分内容过长,也分成了2篇。这篇就着重看下musim gap以及RRC触发UE离开RRC Connected mode相关的内容,直入正题, 上面的内容在overview中有提到,对应的是如下38.300中的描述。 处于网络…

【Node.js基础02】fs、path模块

目录 一&#xff1a;fs模块-读写文件 1 加载fs模块对象 2 读制定文件内容文件 3 向文件中写入内容 二&#xff1a;path模块-路径处理 1 问题引入 2 __dirname内置变量 使用方法 一&#xff1a;fs模块-读写文件 fs模块封装了与本机文件系统交互方法和属性 1 加载fs模块…

Win11 改造

记录一些安装 win11 系统之后&#xff0c;对使用不习惯的地方&#xff0c;进行的个人改造 右键菜单 Hiyoung006/Win11Useable: 将Win11右键菜单及资源管理器恢复为Win10样式的脚本 切换到旧版右键菜单&#xff1a; reg add "HKCU\Software\Classes\CLSID\{86ca1aa0-34…

Chapter18 基于物理的渲染——Shader入门精要学习

Chapter18 基于物理的渲染 一、PBS理论和数学基础1.光是什么微表面模型 2.渲染方程3.精确光源4.双向反射分布函数 BRDF5.漫反射项&#xff08;Lambert 模型&#xff09;Lambertian BRDF为&#xff1a;Disney BRDF中漫反射项 6.高光反射项微面元理论BRDF的高光反射项①菲涅尔反射…

LabVIEW和IQ测试仪进行WiFi测试

介绍一个使用LabVIEW和LitePoint IQxel-MW IQ测试仪进行WiFi测试的系统。包括具体的硬件型号、如何实现通讯、开发中需要注意的事项以及实现的功能。 使用的硬件​ IQ测试仪型号: LitePoint IQxel-MW 电脑: 配置高效的台式机或笔记本电脑 路由器: 支持802.11ax (Wi-Fi 6) 的…

便携气象站:科技助力气象观测

在科技飞速发展的今天&#xff0c;便携气象站以其轻便、高效、全面的特点&#xff0c;正逐渐改变着气象观测的传统模式。这款小巧而强大的设备&#xff0c;不仅为气象学研究和气象灾害预警提供了有力支持&#xff0c;更为户外活动、农业生产等领域带来了诸多便利。 便携气象站是…

遗传算法模型Python代码——用Python实现遗传算法案例

一、遗传算法概述 1.1适用范围 遗传算法&#xff08;Genetic Algorithm, GA&#xff09;是一种启发式搜索算法&#xff0c;广泛应用于以下领域&#xff1a; 优化问题&#xff1a;如函数优化、路径规划、资源分配等。机器学习&#xff1a;用于特征选择、超参数优化等。经济与…

服务器系统盘存储不够,添加数据盘并挂载(阿里云)

目录 1.获取数据盘设备名称 2.为数据盘创建分区 3.为分区创建文件系统 4.配置开机自动挂载分区 阿里云数据盘挂载说明链接&#xff1a;在Linux系统中初始化小于等于2 TiB的数据盘_云服务器 ECS(ECS)-阿里云帮助中心 1.获取数据盘设备名称 sudo fdisk -lu 运行结果如下所示…

解决 elementUI 组件在 WebStorm 中显示为未知标签的问题

解决 elementUI 组件在 WebStorm 中显示为未知标签的问题 一、问题 自从转到 ts 之后&#xff0c;编辑器就一直提示用到的 elementUI 标签未知&#xff0c;一直显示一溜黄色警示&#xff0c;很烦&#xff1a; 二、解决 把它改成大写就可以了。 如下&#xff1a; 把整个项目…

【C++】学习笔记——哈希_2

文章目录 十八、哈希3. 实现哈希表哈希表的存储节点哈希函数哈希表的定义哈希表的插入哈希表的查找哈希表的删除测试函数完整代码结果 未完待续 十八、哈希 3. 实现哈希表 哈希表的实现方法有蛮多种&#xff0c;这里我们选一个比较经典的开散列法来实现哈希表。由于STL库里的…

使用PicGo操作gitee图床(及web端html不能访问图片的解决办法)

1.新建仓库 2.输入仓库名称,也就是图床名称,必须设置开源可见 也可以在创建仓库后,点击管理->基本信息->是否开源进行设置 鼠标悬浮到右上角头像->设置 点击私人令牌 点击生成新令牌,填写描述,直接点提交即可 点击提交后输入登录密码会生成一个token秘钥,如下,这个…

新版本异次元荔枝V4自动发卡系统源码

新版本异次元荔枝V4自动发卡系统源码&#xff0c;增加主站货源系统&#xff0c;支持分站自定义支付接口&#xff0c;目前插件大部分免费&#xff0c;UI页面全面更新&#xff0c;分站可支持对接其他分站产品&#xff0c;分站客服可自定义&#xff0c;支持限定优惠。 源码下载&a…

matlab--legend利用for循环添加图例

第一种方法 %% 第一种方法 R 1:4; THETA1 atand(R./1.8); legend_name {}; for i 1:4THETA atand(R(i)./1.8);intTheta floor(THETA);R_THERA 1.8 - (R(i)./tand(intTheta-10:intTheta10));R_THERA1 1.8 - (R(i)/tand(intTheta));plot(R_THERA);grid on;hold onlegend…

Git之repo sync -c与repo sync -dc用法区别(四十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

了解Linux中的shell脚本

目录 1、什么是shell 2、编写第一个shell文件 3、shell的权限 4、变量 5、 shell传递参数 6、shell数组 7、shell基本运算符 7.1 算术运算符 7.2 关系运算符 7.3 布尔运算符 7.4 逻辑运算符 7.5 字符串运算符 8、控制语句 8.1 if 8.2 for 8.3 while语句 9、其他 1、…