08【保姆级】-GO语言的函数、包、错误处理

08【保姆级】-GO语言的函数、包、错误处理

  • 一、 函数基本介绍
    • 1.1 基本概念
    • 1.2 包的概念
    • 1.3 包使用的注意事项和细节
    • 1.4 函数的调用机制
    • 1.5 函数的递归调用
    • 1.6 函数使用的注意事项和细节讨论
    • 1.7 init函数
    • 1.8 匿名函数
      • 1.8.1 匿名函数使用方式
      • 1.8.2 全局匿名函数
    • 1.9 闭包
      • 1.9.1 闭包的最佳实践
    • 1.10 函数的defer
    • 1.11 函数参数
      • 1.11.1 两种传递方式
      • 1.11.2 值类型和引用类型
    • 1.12 变量的作用域
    • 1.13 字符串常用的系统函数
    • 1.14 时间和日期的常用函数
    • 1.15 内置函数
  • 二、错误处理

之前我学过C、Java、Python语言时总结的经验:

  1. 先建立整体框架,然后再去抠细节。
  2. 先Know how,然后know why。
  3. 先做出来,然后再去一点点研究,才会事半功倍。
  4. 适当的囫囵吞枣。因为死抠某个知识点很浪费时间的。
  5. 对于GO语言,切记遵守语法格式规则。(例如python语言、例如SpringBoot框架等)
    解释:某些知识点,就是很难了解,那么先做出来,然后继续向前学习,可能在某个时间点我们就会恍然大悟。

一、 函数基本介绍

1.1 基本概念

为完成某一功能的程序指令(语句)的集合,称为函数
在Go语言中分为:自定义函数、系统函数。

func 函数名(形参列表) (返回值类型列表){执行语句return 返回值列表
}1. 形参列表: 表示函数的输入
2. 函数中的语句:表示为了实现某一功能代码块
3. 函数可以有返回值,也可以没有

例子: j

func main() {c := add(2, 5)fmt.Println("c=", c)}func add(a int, b int) int {c := a + breturn c
}

1.2 包的概念

  1. 在实际的开发中,我们往往需要在不同的文件中,去调用其它文件的定义的函数,比如 main.go中,去使用 utils.go 文件中的函数,如何实现? -》包
  2. 现在有两个程序员共同开发一个 Go 项目,程序员 xiaoming 希望定义函数 Cal,程序员 xiaoqiang也想定义函数也叫 Cal。两个程序员为此还吵了起来,怎么办?-》包

包的本质实际上就是创建不同的文件夹,来存放程序文件。

包的基本概念: go 的每一个文件都是属于一个包的,也就是说 go 是以包的形式来管理文件和项目目录结构

  • 包的三大作用
  1. 区分相同名字的函数、变量等标识符
  2. 当程序文件很多时,可以很好的管理项目
  3. 控制函数、变量等访问范围,即作用域
  • 包的基本语法
package 包名
  • 引入包的基本语法
import "包的路径"
  • 包使用的快速入门
    包快速入门-Go 相互调用函数,我们将func Cal 定义到文件utils.go,将utils.go放入一个包中,当其他文件需要使用utils.go的方法时,可以import该包,就可以使用了。

在这里插入图片描述

1.3 包使用的注意事项和细节

  1. 在给一个文件打包时,该包对应一个文件夹,比如这里的utils文件夹,对应的包名是utils,文件的包名通常和文件所在的文件夹名一致,一般为小写字母。
  2. 当一个文件要使用其它包函数或变量时,需要先引入对应的包。
引入方式1import “包名”引入方式2import("包名""包名"
)package 指令在 文件第一行,然后是import指令
在import包时,路径从$GOPATH 的src下开始,不用带src,编译器会自动从src下开始引入。
  1. 为了让其他包的文件,可以访问到本包的函数,则该函数名的首字母需要大写,类似其他语言的public,这样才能跨包访问。比如 utils.go

  2. 在访问其他函数,变量时,其语法是 包名.函数名 ,比如这里的 main.go 文件中:

  3. 如果包名较长,Go支持给包取别名,注意细节:取别名后,原来的包名就不能使用了。

说明:如果给包取了别名,则需要使用别名来访问该包的函数和变量

  1. 在同一包下,不能有相同的函数名(也不能有相同的全局变量名),否则报重复定义
  2. 如果你要编译成一个可执行程序文件,就需要将这个包申明为main,既 package main。 这个就是一个语法规范,如果你是写一个库,包名可以自定义。
路径下写:
- src - 项目名称- 各个包名

1.4 函数的调用机制

关于栈区:
函数在调用的时候,基本数据类型,一般说分配到栈区,编译器存在一个逃逸分析
栈区:
add 栈区
main 栈区

  1. 在调用一个函数时,会给该函数分配一个新的空间,编译器会通过自身的处理,让这个新的空间和其他的栈的空间区分开来
  2. 在每个函数对应的栈中, 数据空间是独立的。不会混淆
  3. 当一个函数调用完毕(执行完毕)后,程序会销毁这个函数对应的栈空间。
func main() {n := 10add(n)fmt.Println("main() 的n =", n)   // main() 的n = 10}
func add(n int) {n = n + 1fmt.Println("add() 的n =", n)  // add() 的n = 11
}1. 其中两个函数都是在栈中,当main函数只是将 n 的值 传给了add函数(值传递).
2. 这样说来,add更改n的值,并不会更改main的n的值.
3. 其中根据栈的原则,先进后出,main先进去的,所以,先打印add函数的println语句。

关于堆区:
堆区:引用数据类型一般说分配到堆区,编译器存在一个逃逸分析

代码区:
所有的代码存储到此位置。


案例要求:写一个函数,传入两个int值,返回两者的相加和相减

func main() {n1 := 10n2 := 5add, sub := addOrSub(n1, n2)fmt.Println("add=", add, "sub=", sub) // add= 15 sub= 5}
func addOrSub(n1 int, n2 int) (int, int) {return n1 + n2, n1 - n2
}

1.5 函数的递归调用

一个函数在函数体内调用了本身,我们称为递归调用。

  1. 执行一个函数时,就创建一个新的受保护的独立空间(新函数栈)
  2. 函数的局部变量是独立的,不会相互影响
  3. 递归必须向退出递归的条件逼近,否则就是无限递归,死鬼了
  4. 当一个函数执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当函数执行完毕或者返回时,该函数本身也会被系统销毁。

递归的演示案例:

-- 第一种: 
//  第一种自己的思路(方便理解):
// 当第1次调用test时,调用了递归,我们可以先把fmt.println打印的结果写出来,也就是3
// 当第2次调用test时,调用了递归,我们可以先把fmt.println打印的结果写出来,也就是2
// 当第3次调用test时,没有调用递归,我们可以先把fmt.println打印的结果写出来,也就是2
// 那么最后的结果,反推上去也就是:2/2/3func main() {n1 := 4test(n1)
}
func test(n1 int) {if n1 > 2 {n1--test(n1)}fmt.Println("n1=", n1)
}
n1= 2
n1= 2
n1= 3-- 第二种:
// 自己的思路:
// 不管多少次递归,那么最后结果是,最后一次不符合if条件后,才会执行的else结果。
func main() {n1 := 4test(n1)}
func test(n1 int) {if n1 > 2 {n1--test(n1)} else {fmt.Println("n1=", n1)}
}
n1= 2

1.6 函数使用的注意事项和细节讨论

  1. 函数的形参列表可以是多个,返回值列表也可以是多个。
  2. 形参列表和返回值列表的数据类型可以是值类型和引用类型。
  3. 函数的命名遵循标识符命名规范,首字母不能是数字,首字母大写该函数可以被本包文件和其它文件使用,类似public首字母小写只能被本包文件使用,其它包文件不能使用,类似private
  4. 函数中的变量是局部的,函数外不生效
  5. 基本数据类型和数组 默认都是值传递的,既进行值拷贝。在函数内修改,不会影响到原来的值
  6. 如果希望函数内的变量能修改函数外的变量(指的是 默认以值传递的方式的数据类型),而已传入的地址&,函数内以指针的方式操作变量。
func main() {n1 := 4test(&n1)fmt.Println("main() n1=", n1)  //main() n1= 14
}
func test(n1 *int) {*n1 = *n1 + 10fmt.Println("test() n1=", *n1)  // test() n1= 14
}
  1. Go函数不支持函数重载。
  2. 在Go中,函数也是一种数据类型 ,可以赋值给一个变量,则该变量就是一个函数类型的变量了。通过该变量可以对函数 调用。
func main() {//在Go中,函数也是一种数据类型a := getSumfmt.Println(a(1, 2))
}func getSum(n1 int, n2 int) int {return n1 + n2
}
  1. 函数既然是一个种函数类型,因此在Go中,函数可以作为函数,并且调用。
1. myFun函数,将三个参数分别赋值给myFun() 其中func(int ,int)int 是一个类型。funvar = getSumnum1 = 50num2 = 60
2. 然后将 num1 和 num2 赋值给 funvar(num1,num2)
3. 根据第一点得知,funvar 等于 getSum函数。
4. 根据getSum()函数得知,n1 + n2 =50+60. 得到结果是110getSum()函数返回110给的是res2
5. 切记:getSum返回的110,是返回给res2的

在这里插入图片描述

  1. 为了简化数据类型定义,Go支持自定义数据类型
基本语法:type 自定义数据类型名   数据类型 
// 理解:相当于一个别名
案例:type myInt int  
// 这时  myInt 就等价 int来使用了
// myInt 是一个类型,虽然根据定义是一个类型,是一个int类型,但是Go认为并不是同种类型。
//如代码:

在这里插入图片描述

案例:type mySum func(int,int)int 
// 这时 mySum就等价 一个函数类型func(int,int) int
//  创建一个mySum 类型,该类型是一个函数,名为:func(int,int)int函数

在这里插入图片描述

  1. 支持对函数返回值命名
func main() {var num1 intvar num2 intnum1 = 10num2 = 10add, sub := addOrSub(num1, num2)fmt.Println("add=", add, "sub=", sub)// add= 20 sub= 0
}func addOrSub(num1 int, num2 int) (add int, sub int) {add = num1 + num2sub = num1 - num2return// 此时可以忽略掉 返回类型和顺序
}
  1. 只用 _ 标识符,忽略返回值
  2. Go支持可变参数
// 支持0到多个参数
func sunc(args... int ) sum int {
}
// 支持1到多个参数
func sum(n1 int ,args... int) sum int{
}
14. args是slice切片(可以理解java的数组),通过args[index] key访问到各个值
15. 如果一个函数的形参列表中有可变参数,则可变参数需要放在形参列表最后。

编写函数swap(n1 *int,n2 *int) 进行交换n1 和 n2的值

func main() {var n1 int = 10var n2 int = 20fmt.Println("前n1=", n1, "前n2=", n2)swap(&n1, &n2)fmt.Println("后n1=", n1, "后n2=", n2)//前n1= 10 前n2= 20//后n1= 20 后n2= 10
}func swap(a *int, b *int) {var test inttest = *a*a = *b*b = test
}

1.7 init函数

每一个源文件都可以包含一个init函数,该函数会在main函数执行前,被Go运行框架调用,也就是说init会在main函数前被调用。

在这里插入图片描述在这里插入图片描述

  1. 如果一个文件同时包含全局变量定义init函数,和main函数 ,则 执行流程:全局变量定义 -> init 函数 -> main函数

    1. 当如果有被引入的包,那么会先执行被引入的包。例如 fmt 、 utils
      在这里插入图片描述
  2. init函数最主要的作用,就是完成一些初始化的工作

在这里插入图片描述

1.8 匿名函数

Go支持匿名函数,匿名函数就是没有名字的函数,如果我们某个函数只是希望使用一次,可以考虑使用匿名函数,匿名函数也可以实现多次调用。

1.8.1 匿名函数使用方式

在定义匿名函数时就直接调用,这种方式匿名函数只能调用一次。

// 在定义匿名函数时就直接调用,这种方式匿名函数只能调用一次。
func main() {resAdd := func(a int, b int) int {return a + b}(1, 2)fmt.Println("resAdd=", resAdd) //  resAdd= 3
}

匿名函数赋给一个变量(函数变量),再通过该变量来调用匿名函数

resSub := func(c int, d int) int {return c - d}sub := resSub(1, 2)fmt.Println("sub=", sub) // sub= -1

1.8.2 全局匿名函数

如果将匿名函数赋给一个全局变量,那么这个匿名变量,就成为一个全局匿名函数,可以在程序有效。

var (myAllFunc = func(num1 int, num2 int) int {return num1 + num2}
)// 在定义匿名函数时就直接调用,这种方式匿名函数只能调用一次。
func main() {fmt.Println("调用全局的匿名函数的结果为:", myAllFunc(1, 2))// 调用全局的匿名函数的结果为: 3
}

在这里插入图片描述

1.9 闭包

闭包就是一个函数和与其相关的引用环境组合的一个整体(实体)

  1. AddUpper 是一个函数,返回的数据类型是fun (int) int
  2. 闭包的说明
    返回的是一个匿名函数,但是这个匿名函数引用到函数外的 n,因此这个匿名函数就和n形成个整体,构成闭包。
  3. 大家可以这样理解: 闭包是类,函数是操作,n 是字段。函数和它使用到 n 构成闭包。
  4. 当我们反复的调用 f函数时,因为 n 是初始化一次,因此每调用一次就进行累计。
  5. 我们要搞清楚闭包的关键,就是要分析出返回的函数它使用(引用)到哪些变量,因为函数和它引用到的变量共同构成闭包。

1.9.1 闭包的最佳实践

  1. 编写一个函数 makeSuffix(sufix string) 可以接收一个文件后缀名(比如jpg),并返回一个闭包2. 调用闭包,可以传入一个文件名,如果该文件名没有指定的后缀(比如.jpg),则返回 文件名jpg,如果已经有.ipg 后缀,则返回原文件名。
  2. 要求使用闭包的方式完成
  3. strings.HasSuffix,该函数可以判断某个字符串是否有指定的后缀。
package mainimport ("fmt""strings"
)func main() {res := makeSuffix(".txt")fmt.Println("测试的名字是:", res("zhangsan1.txt"))
}func makeSuffix(houzhui string) func(name string) string {return func(name string) string {// 判断如果输入的name后缀有huizhui,那么为true。 (! 取反)if !strings.HasSuffix(name, houzhui) {return name + houzhui + "a"}return name}
}

1.10 函数的defer

在函数中,程序员经常需要创建资源(比如: 数据库连接、文件句柄、锁等) ,为了在函数执行完毕后,及时的释放资源,Go 的设计者提供 defer(延时机制)。

  1. 当 go 执行到一个 defer 时,不会立即执行 defer 后的语句,而是将 defer 后的语句压入到一个栈中[我为了讲课方便,暂时称该栈为 defer 栈1然后继续执行函数下一个语句。
  2. 当函数执行完毕后,在从 defer 中,依次从栈顶取出语句执行(注:遵守栈 先入后出的机制).
    在这里插入图片描述
  3. 在 defer 将语句放入到栈时,也会将相关的值拷贝同时入栈

在这里插入图片描述

  1. defer 最主要的价值是在,当函数执行完毕后,可以及时的释放函数创建的资源
  2. 在 golang 编程中的通常做法是,创建资源后,比如(打开了文件,获取了数据库的链接,或者是锁资源,可以执行 defer file.Close() defer connect.Close()
  3. 在 defer 后,可以继续使用创建资源.
  4. 当函数完毕后,系统会依次从 defer 栈中,取出语句,关闭资源
  5. 这种机制,非常简洁,程序员不用再为在什么时机关闭资源而烦心。

1.11 函数参数

1.11.1 两种传递方式

  1. 值传递
  2. 引用传递
    其实,不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递的是地址的拷贝,一般来说,地址拷贝效率高,因为数据量小,而值拷贝决定拷贝的数据大小,数据越大,效率越低。

1.11.2 值类型和引用类型

  1. 值类型:基本数据类型 int 系列,flat 系列,bool,string 、数组和结构体 struct

  2. 引用类型: 指针、slice 切片、map、管道 chan、interface 等都是引用类型

  3. 值类型默认是值传递:变量直接存储值,内存通常在栈中分配

  4. 引用类型默认是引用传递,变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收。

  5. 如果希望函数内的变量能修改函数外的变量,可以传入变量的地址&,函数内以指针的方式操作变量。从效果上看类似引用 。

1.12 变量的作用域

  1. 函数内部声明/定义的变量叫局部变量,作用域仅限于函数内部
  2. 函数外部声明/定义的变量叫全局变量,作用域在整个包都有效,如果其首字母为大写,则作用域在整个程序有效
  3. 如果变量是在一个代码块,比如 for /if 中,那么这个变量的的作用域就在该代码块

1.13 字符串常用的系统函数

  1. 统计字符串的长度,按字节 len(str)
  2. 字符串遍历,同时处理有中文的问题r:=[]rune(str)
  3. 字符串转整数: n,err := strconv.Atoi(”12"”)
  4. 整数转字符串 str = strconv.ltoa(12345)
  5. 字符串转[Ibyte: var bytes = []byte(“hello go”)
  6. []byte转字符串:str=string([]byte(97,98, 99}
  7. 10进制转 2,8,16进制: str=strconv,Formatlnt(123,2) // 2-> 8,16
  8. 查找子串是否在指定的字符串中: strings.Contains("seafood”,“foo”) //true
  9. 统计一个字符串有几个指定的子串 : strings.Count(“ceheese”,“e”)//4
  10. 不区分大小写的字符串比较(==是区分字母大小写的):fmt,Println(strings.EqualFold("abc”,“Abc”) true
  11. 返回子串在字符串第一次出现的index值,如果没有返回-1 :strings.Index(“NLT abc”,“abc”)//4

1.14 时间和日期的常用函数

1.15 内置函数

二、错误处理

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java 进阶篇】JQuery 遍历 —— For 循环的奇妙之旅

在前端开发的世界里,遍历是一个常见而重要的操作。它让我们能够浏览并操纵文档中的元素,为用户提供更加丰富和交互性的体验。而在 JQuery 中,遍历的方式多种多样,其中 for 循环是一种简单而灵活的选择。在本篇博客中,我…

Mac电脑VSCode配置PHP开发环境

1.安装 PHP 首先,打开终端,安装 Homebrew,输入如下命令: $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 安装了 Homebrew 之后,你可以使用下面的…

这款开源神器,让聚类算法从此变得简单易用

Scikit-Learn 以其提供的多个经过验证的聚类算法而著称。尽管如此,其中大多数都是参数化的,并需要设置集群的数量,这是聚类中最大的挑战之一。 通常,使用迭代方法来决定数据的最佳聚类数量,这意味着你需要多次进行聚类…

【华为OD题库-015】报文重排序-Java

题目 对报文进行重传和重排序是常用的可靠性机制&#xff0c;重传缓冲区内有一定数量的子报文&#xff0c;每个子报文在原始报文中的顺序已知&#xff0c;现在需要恢复出原始报文。 输入描述 输入第一行为N,表示子报文的个数&#xff0c;0<N < 1000。 输入第二行为N个子报…

Unity 2021 LTS / Unity 2022 LTS New Shader Graph Node 参考样本

Shader Graph团队很高兴地宣布发布新的节点参考样本&#xff0c;现在可用于2021 LTS, 2022 LTS和未来的版本。 节点参考样本是超过140个Shader图形资源的集合。您可以将这些图用作参考&#xff0c;以了解每个节点的作用及其工作原理&#xff0c;而不是在项目中使用这些图。每个…

【软件安装】Centos系统中安装docker容器(华为云HECS云耀服务器)

这篇文章&#xff0c;主要介绍Centos系统中安装docker容器&#xff08;华为云HECS云耀服务器&#xff09;。 目录 一、安装docker 1.1、卸载旧版本docker 1.2、更新repo镜像 1.3、安装依赖包 1.4、添加docker-ce镜像 1.5、安装docker-ce 1.6、查看docker安装版本 1.7、…

Opengauss到Oracle增量同步, 使用debezium

一、概述 PG到Oracle的同步方案使用debezium kafka kafka-connect-jdbc。debezium是一款开源的变更捕获软件&#xff0c;它以kafka的connector形式运行&#xff0c;可以捕获PostgreSQL、MySQL、Oracle中的变更数据&#xff0c;保存到kafka。kafka-connect-jdbc是confluent公…

[Linux] ssh远程访问及控制

一、ssh介绍 1.1 SSH简介 SSH&#xff08;Secure Shell&#xff09;是一种安全通道协议&#xff0c;主要用于实现远程登录、远程复制等功能的字符接口。SSH 协议包括用户在登录时输入的用户密码、双方之间的通信。 加密数据传输&#xff0c;SSH 是一种建立在应用层和传输层上…

Please No More Sigma(构造矩阵)

Please No More Sigma 给f(n)定义如下&#xff1a; f(n)1 n1,2; f(n)f(n-1)f(n-2) n>2; 给定n&#xff0c;求下式模1e97后的值 Input 第一行一个数字T&#xff0c;表示样例数 以下有T行&#xff0c;每行一个数&#xff0c;表示n。 保证T<100&#xff0c;n<100000…

【Proteus仿真】【Arduino单片机】DHT11温湿度

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用PCF8574、LCD1602液晶、DHT11温湿度传感器等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示传感器采集温度和湿度。 二、软件设…

SQL存储过程和函数

SQL存储过程和函数 变量系统变量用户定义变量局部变量 存储过程存储函数 变量 在MySQL中变量分为三种类型: 系统变量、用户定义变量、局部变量。 系统变量 系统变量 是MySQL服务器提供&#xff0c;不是用户定义的&#xff0c;属于服务器层面。分为全局变量&#xff08;GLOBA…

全栈工程师必须要掌握的前端Html技能

作为一名全栈工程师&#xff0c;在日常的工作中&#xff0c;可能更侧重于后端开发&#xff0c;如&#xff1a;C#&#xff0c;Java&#xff0c;SQL &#xff0c;Python等&#xff0c;对前端的知识则不太精通。在一些比较完善的公司或者项目中&#xff0c;一般会搭配前端工程师&a…

Mistral 7B 比Llama 2更好的开源大模型 (二)

Mistral 7B 论文学习 Mistral 7B 论文链接 https://arxiv.org/abs/2310.06825 代码: https://github.com/mistralai/mistral-src 网站: https://mistral.ai/news/announcing-mistral-7b/ 论文摘要 Mistral 7B是一个70亿参数的语言模型,旨在获得卓越的性能和效率。Mistral 7…

C# 使用Microsoft.Office.Interop.Excel库操作Excel

1.在NuGet管理包中搜索&#xff1a;Microsoft.Office.Interop.Excel&#xff0c;如下图红色标记处所示&#xff0c;进行安装 2. 安装完成后&#xff0c;在程序中引入命名空间如下所示&#xff1a; using Microsoft.Office.Interop.Excel; //第一步 添加excel第三方库 usi…

算法笔记-贪心1

算法笔记-贪心 什么是贪心算法分配饼干例题理解二分割字符串最优装箱整数配对最大组合整数分配区间问题买股票的最佳时机区间选点 问题什么是贪心算法 分配饼干例题 //贪心算法 //保证局部最优,从而使最后得到的结果是全局最优的 #include<iostream> #include<a…

VIVADO+FPGA调试记录

vivadoFPGA调试记录 vitis编译vivado导出的硬件平台&#xff0c;提示xxxx.h file cant findVITIS内定义的头文件找不到 vitis编译vivado导出的硬件平台&#xff0c;提示’xxxx.h file cant find’ 此硬件平台中&#xff0c;包含有AXI接口类型的ip。在vitis编译硬件平台时&…

【漏洞复现】maccms苹果cms 命令执行漏洞

漏洞描述 感谢提供更多信息。“苹果CMS” 似乎是指 “Maccms”&#xff0c;这是一款开源的内容管理系统&#xff0c;主要用于搭建视频网站。Maccms 提供了一套完整的解决方案&#xff0c;包括用户管理、视频上传、分类管理、数据统计等功能&#xff0c;使用户能够方便地创建和…

如何构建风险矩阵?3大注意事项

风险矩阵法&#xff08;RMA&#xff09;是确定威胁优先级别的最有效工具之一&#xff0c;可以帮助项目团队识别和评估项目中的风险&#xff0c;帮助项目团队对风险进行排序&#xff0c;清晰地展示风险的可能性和严重性&#xff0c;为项目团队制定风险管理策略提供依据。 如果没…

【ArcGIS处理】行政区划与流域区划间转化

【ArcGIS处理】行政区划与流域区划间转化 引言数据准备1、行政区划数据2、流域区划数据 ArcGIS详细处理步骤Step1&#xff1a;统计行政区划下子流域面积1、创建批量处理模型2、添加批量裁剪处理3、添加计算面积 Step2&#xff1a;根据子流域面积占比均化得到各行政区固定值 参考…

hadoop 大数据环境配置 配置jdk, hadoop环境变量 配置centos环境变量 hadoop(五)

1. 遗漏一步配置系统环境变量&#xff0c;下面是步骤&#xff0c;别忘输入更新系统环境命令 2. 将下载好得压缩包上传至服务器&#xff1a; /opt/module 解压缩文件存放地址 /opt/software 压缩包地址 3. 配置环境变量&#xff1a; 在/etc/profile.d 文件夹下创建shell文件 …