线性代数sparkscala
22
Algorithm/单源最短路问题.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# 单元最短路问题
|
||||
|
||||
> 通过不同的方式解决单元最短路问题
|
||||
|
||||
> 图,不是树
|
||||
## 0 问题描述
|
||||
|
||||
单元最短路问题、有向无环图
|
||||
|
||||
## 1 暴力求解
|
||||
|
||||
### 深度优先搜索DFS
|
||||
|
||||
### 广度优先搜索BFS
|
||||
|
||||
## 2 回溯法
|
||||
|
||||
深度优先算法,每次回溯的时候进行剪枝操作。
|
||||
如果此分支没有希望比已经保存的最短路更优。
|
||||
|
||||
而且可以从不同的点到达同一个点。保留之前到达这个点的状态,如果最新到达这个点的距离小于之前的距离,则继续向下走,如果大于则放弃并回溯。
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
> 关于笔记记录的说明:我觉得笔记记录的内容过于细节。所有的知识应该以书上为准。整理笔记的目的应该是作为一种快速参考或者索引,而不是详细的记录所有的细节。说实话,我觉得你的笔记废话太多,自己都不一定会看。
|
||||
> 我觉得是时间放弃你愚蠢的笔记策略了。
|
||||
> 从今以后,必须跟上自己的笔记进度和作业进度。不能就学两科还跟不上进度,太傻逼了。
|
||||
> 殷康龙啊,上课时间才是最重要的,记得做笔记啊,啥时候,你成了一个上课不听,下课做作的人???没用的。以后自己去坐到前排学习吧,这种事,确实有利。能强迫自己认真听讲。
|
||||
|
||||
|
||||
## 1 分类标题(用来描述主题的各个方面或者分类)
|
||||
|
||||
127
Scala/1 基本语法.md
Normal file
@@ -0,0 +1,127 @@
|
||||
# 基本语法
|
||||
|
||||
## 1 相关概念
|
||||
|
||||
对象:对象有属性和行为。例如:一只狗的状属性有:颜色,名字,行为有:叫、跑、吃等。对象是一个类的实例。
|
||||
|
||||
类:类是对象的抽象,而对象是类的具体实例。
|
||||
|
||||
方法:方法描述的基本的行为,一个类可以包含多个方法。
|
||||
|
||||
属性:每个对象都有它唯一的实例变量集合。对象的属性通过给字段赋值来创建。
|
||||
|
||||
## 2 基本语法
|
||||
|
||||
### 特点
|
||||
|
||||
区分大小写 - Scala是大小写敏感的,这意味着标识Hello 和 hello在Scala中会有不同的含义。
|
||||
|
||||
类名 - 对于所有的类名的第一个字母要大写。
|
||||
如果需要使用几个单词来构成一个类的名称,每个单词的第一个字母要大写。
|
||||
|
||||
示例:class MyFirstScalaClass
|
||||
|
||||
方法名称 - 所有的方法名称的第一个字母用小写。
|
||||
如果若干单词被用于构成方法的名称,则每个单词的第一个字母应大写。
|
||||
|
||||
示例:def myMethodName()
|
||||
|
||||
程序文件名 - 程序文件的名称应该与对象名称完全匹配(新版本不需要了,但建议保留这种习惯)。
|
||||
保存文件时,应该保存它使用的对象名称(记住Scala是区分大小写),并追加".scala"为文件扩展名。 (如果文件名和对象名称不匹配,程序将无法编译)。
|
||||
|
||||
示例: 假设"HelloWorld"是对象的名称。那么该文件应保存为'HelloWorld.scala"
|
||||
|
||||
def main(args: Array[String]) - Scala程序从main()方法开始处理,这是每一个Scala程序的强制程序入口部分。
|
||||
|
||||
### 标识符
|
||||
Scala 可以使用两种形式的标志符,字符数字和符号。
|
||||
|
||||
字符数字使用字母或是下划线开头,后面可以接字母或是数字,符号"$"在 Scala 中也看作为字母。然而以"$"开头的标识符为保留的 Scala 编译器产生的标志符使用,应用程序应该避免使用"$"开始的标识符,以免造成冲突。
|
||||
|
||||
Scala 的命名规则采用和 Java 类似的 camel 命名规则,首字符小写,比如 toString。类名的首字符还是使用大写。此外也应该避免使用以下划线结尾的标志符以避免冲突。符号标志符包含一个或多个符号,如+,:,? 等,比如:
|
||||
|
||||
+ ++ ::: < ?> :->
|
||||
Scala 内部实现时会使用转义的标志符,比如:-> 使用 $colon$minus$greater 来表示这个符号。因此如果你需要在 Java 代码中访问:->方法,你需要使用 Scala 的内部名称 $colon$minus$greater。
|
||||
|
||||
混合标志符由字符数字标志符后面跟着一个或多个符号组成,比如 unary_+ 为 Scala 对+方法的内部实现时的名称。字面量标志符为使用"定义的字符串,比如 `x` `yield`。
|
||||
|
||||
你可以在"之间使用任何有效的 Scala 标志符,Scala 将它们解释为一个 Scala 标志符,一个典型的使用为 Thread 的 yield 方法, 在 Scala 中你不能使用 Thread.yield()是因为 yield 为 Scala 中的关键字, 你必须使用 Thread.`yield`()来使用这个方法。
|
||||
|
||||
### Scala 关键字
|
||||
下表列出了 scala 保留关键字,我们不能使用以下关键字作为变量:
|
||||
|
||||
abstract case catch class
|
||||
def do else extends
|
||||
false final finally for
|
||||
forSome if implicit import
|
||||
lazy match new null
|
||||
object override package private
|
||||
protected return sealed super
|
||||
this throw trait try
|
||||
true type val var
|
||||
while with yield
|
||||
- : = =>
|
||||
<- <: <% >:
|
||||
# @
|
||||
|
||||
### Scala 注释
|
||||
Scala 类似 Java 支持单行和多行注释。多行注释可以嵌套,但必须正确嵌套,一个注释开始符号对应一个结束符号。注释在 Scala 编译中会被忽略,实例如下:
|
||||
|
||||
object HelloWorld {
|
||||
/* 这是一个 Scala 程序
|
||||
* 这是一行注释
|
||||
* 这里演示了多行注释
|
||||
*/
|
||||
def main(args: Array[String]) {
|
||||
// 输出 Hello World
|
||||
// 这是一个单行注释
|
||||
println("Hello, world!")
|
||||
}
|
||||
}
|
||||
|
||||
### 空行和空格换行符
|
||||
|
||||
一行中只有空格或者带有注释,Scala 会认为其是空行,会忽略它。标记可以被空格或者注释来分割。
|
||||
|
||||
Scala是面向行的语言,语句可以用分号(;)结束或换行符。Scala 程序里,语句末尾的分号通常是可选的。如果你愿意可以输入一个,但若一行里仅 有一个语句也可不写。另一方面,如果一行里写多个语句那么分号是需要的。例如
|
||||
|
||||
val s = "菜鸟教程"; println(s)
|
||||
|
||||
## 3 包
|
||||
|
||||
### Scala 包
|
||||
定义包
|
||||
Scala 使用 package 关键字定义包,在Scala将代码定义到某个包中有两种方式:
|
||||
|
||||
第一种方法和 Java 一样,在文件的头定义包名,这种方法就后续所有代码都放在该包中。 比如:
|
||||
|
||||
package com.runoob
|
||||
class HelloWorld
|
||||
第二种方法有些类似 C#,如:
|
||||
|
||||
package com.runoob {
|
||||
class HelloWorld
|
||||
}
|
||||
第二种方法,可以在一个文件中定义多个包。
|
||||
|
||||
### 引用
|
||||
Scala 使用 import 关键字引用包。
|
||||
|
||||
import java.awt.Color // 引入Color
|
||||
|
||||
import java.awt._ // 引入包内所有成员
|
||||
|
||||
def handler(evt: event.ActionEvent) { // java.awt.event.ActionEvent
|
||||
... // 因为引入了java.awt,所以可以省去前面的部分
|
||||
}
|
||||
import语句可以出现在任何地方,而不是只能在文件顶部。import的效果从开始延伸到语句块的结束。这可以大幅减少名称冲突的可能性。
|
||||
|
||||
如果想要引入包中的几个成员,可以使用selector(选取器):
|
||||
|
||||
import java.awt.{Color, Font}
|
||||
|
||||
// 重命名成员
|
||||
import java.util.{HashMap => JavaHashMap}
|
||||
|
||||
// 隐藏成员
|
||||
import java.util.{HashMap => _, _} // 引入了util包的所有成员,但是HashMap被隐藏了
|
||||
202
Scala/10 数组.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# Scala数组
|
||||
|
||||
|
||||
## 1 基本操作
|
||||
### 声明数组
|
||||
以下是 Scala 数组声明的语法格式:
|
||||
|
||||
var z:Array[String] = new Array[String](3)
|
||||
|
||||
或
|
||||
|
||||
var z = new Array[String](3)
|
||||
|
||||
### 处理数组
|
||||
数组的元素类型和数组的大小都是确定的,所以当处理数组元素时候,我们通常使用基本的 for 循环。
|
||||
|
||||
以下实例演示了数组的创建,初始化等处理过程:
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
var myList = Array(1.9, 2.9, 3.4, 3.5)
|
||||
|
||||
// 输出所有数组元素
|
||||
for ( x <- myList ) {
|
||||
println( x )
|
||||
}
|
||||
|
||||
// 计算数组所有元素的总和
|
||||
var total = 0.0;
|
||||
for ( i <- 0 to (myList.length - 1)) {
|
||||
total += myList(i);
|
||||
}
|
||||
println("总和为 " + total);
|
||||
|
||||
// 查找数组中的最大元素
|
||||
var max = myList(0);
|
||||
for ( i <- 1 to (myList.length - 1) ) {
|
||||
if (myList(i) > max) max = myList(i);
|
||||
}
|
||||
println("最大值为 " + max);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
### 多维数组
|
||||
多维数组一个数组中的值可以是另一个数组,另一个数组的值也可以是一个数组。矩阵与表格是我们常见的二维数组。
|
||||
|
||||
以上是一个定义了二维数组的实例:
|
||||
|
||||
var myMatrix = ofDim[Int](3,3)
|
||||
实例中数组中包含三个数组元素,每个数组元素又含有三个值。
|
||||
|
||||
接下来我们来看一个二维数组处理的完整实例:
|
||||
|
||||
import Array._
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
var myMatrix = ofDim[Int](3,3)
|
||||
|
||||
// 创建矩阵
|
||||
for (i <- 0 to 2) {
|
||||
for ( j <- 0 to 2) {
|
||||
myMatrix(i)(j) = j;
|
||||
}
|
||||
}
|
||||
|
||||
// 打印二维阵列
|
||||
for (i <- 0 to 2) {
|
||||
for ( j <- 0 to 2) {
|
||||
print(" " + myMatrix(i)(j));
|
||||
}
|
||||
println();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
### 合并数组
|
||||
以下实例中,我们使用 concat() 方法来合并两个数组,concat() 方法中接受多个数组参数:
|
||||
|
||||
import Array._
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
var myList1 = Array(1.9, 2.9, 3.4, 3.5)
|
||||
var myList2 = Array(8.9, 7.9, 0.4, 1.5)
|
||||
|
||||
var myList3 = concat( myList1, myList2)
|
||||
|
||||
// 输出所有数组元素
|
||||
for ( x <- myList3 ) {
|
||||
println( x )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
### 创建区间数组
|
||||
以下实例中,我们使用了 range() 方法来生成一个区间范围内的数组。range() 方法最后一个参数为步长,默认为 1:
|
||||
|
||||
import Array._
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
var myList1 = range(10, 20, 2)
|
||||
var myList2 = range(10,20)
|
||||
|
||||
// 输出所有数组元素
|
||||
for ( x <- myList1 ) {
|
||||
print( " " + x )
|
||||
}
|
||||
println()
|
||||
for ( x <- myList2 ) {
|
||||
print( " " + x )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## 数组函数
|
||||
|
||||
Scala 数组方法
|
||||
下表中为 Scala 语言中处理数组的重要方法,使用它前我们需要使用 import Array._ 引入包。
|
||||
|
||||
序号 方法和描述
|
||||
1
|
||||
def apply( x: T, xs: T* ): Array[T]
|
||||
|
||||
创建指定对象 T 的数组, T 的值可以是 Unit, Double, Float, Long, Int, Char, Short, Byte, Boolean。
|
||||
|
||||
2
|
||||
def concat[T]( xss: Array[T]* ): Array[T]
|
||||
|
||||
合并数组
|
||||
|
||||
3
|
||||
def copy( src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int ): Unit
|
||||
|
||||
复制一个数组到另一个数组上。相等于 Java's System.arraycopy(src, srcPos, dest, destPos, length)。
|
||||
|
||||
4
|
||||
def empty[T]: Array[T]
|
||||
|
||||
返回长度为 0 的数组
|
||||
|
||||
5
|
||||
def iterate[T]( start: T, len: Int )( f: (T) => T ): Array[T]
|
||||
|
||||
返回指定长度数组,每个数组元素为指定函数的返回值。
|
||||
|
||||
以上实例数组初始值为 0,长度为 3,计算函数为a=>a+1:
|
||||
|
||||
scala> Array.iterate(0,3)(a=>a+1)
|
||||
res1: Array[Int] = Array(0, 1, 2)
|
||||
6
|
||||
def fill[T]( n: Int )(elem: => T): Array[T]
|
||||
|
||||
返回数组,长度为第一个参数指定,同时每个元素使用第二个参数进行填充。
|
||||
|
||||
7
|
||||
def fill[T]( n1: Int, n2: Int )( elem: => T ): Array[Array[T]]
|
||||
|
||||
返回二数组,长度为第一个参数指定,同时每个元素使用第二个参数进行填充。
|
||||
|
||||
8
|
||||
def ofDim[T]( n1: Int ): Array[T]
|
||||
|
||||
创建指定长度的数组
|
||||
|
||||
9
|
||||
def ofDim[T]( n1: Int, n2: Int ): Array[Array[T]]
|
||||
|
||||
创建二维数组
|
||||
|
||||
10
|
||||
def ofDim[T]( n1: Int, n2: Int, n3: Int ): Array[Array[Array[T]]]
|
||||
|
||||
创建三维数组
|
||||
|
||||
11
|
||||
def range( start: Int, end: Int, step: Int ): Array[Int]
|
||||
|
||||
创建指定区间内的数组,step 为每个元素间的步长
|
||||
|
||||
12
|
||||
def range( start: Int, end: Int ): Array[Int]
|
||||
|
||||
创建指定区间内的数组
|
||||
|
||||
13
|
||||
def tabulate[T]( n: Int )(f: (Int)=> T): Array[T]
|
||||
|
||||
返回指定长度数组,每个数组元素为指定函数的返回值,默认从 0 开始。
|
||||
|
||||
以上实例返回 3 个元素:
|
||||
|
||||
scala> Array.tabulate(3)(a => a + 5)
|
||||
res0: Array[Int] = Array(5, 6, 7)
|
||||
14
|
||||
def tabulate[T]( n1: Int, n2: Int )( f: (Int, Int ) => T): Array[Array[T]]
|
||||
|
||||
返回指定长度的二维数组,每个数组元素为指定函数的返回值,默认从 0 开始。
|
||||
1175
Scala/11 容器.md
Normal file
242
Scala/12 类和对象.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# Scala 类和对象
|
||||
|
||||
## 1 基本概念
|
||||
类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。
|
||||
|
||||
我们可以使用 new 关键字来创建类的对象,实例如下:
|
||||
|
||||
class Point(xc: Int, yc: Int) {
|
||||
var x: Int = xc
|
||||
var y: Int = yc
|
||||
|
||||
def move(dx: Int, dy: Int) {
|
||||
x = x + dx
|
||||
y = y + dy
|
||||
println ("x 的坐标点: " + x);
|
||||
println ("y 的坐标点: " + y);
|
||||
}
|
||||
}
|
||||
Scala中的类不声明为public,一个Scala源文件中可以有多个类。
|
||||
|
||||
以上实例的类定义了两个变量 x 和 y ,一个方法:move,方法没有返回值。
|
||||
|
||||
Scala 的类定义可以有参数,称为类参数,如上面的 xc, yc,类参数在整个类中都可以访问。
|
||||
|
||||
接着我们可以使用 new 来实例化类,并访问类中的方法和变量:
|
||||
|
||||
import java.io._
|
||||
|
||||
class Point(xc: Int, yc: Int) {
|
||||
var x: Int = xc
|
||||
var y: Int = yc
|
||||
|
||||
def move(dx: Int, dy: Int) {
|
||||
x = x + dx
|
||||
y = y + dy
|
||||
println ("x 的坐标点: " + x);
|
||||
println ("y 的坐标点: " + y);
|
||||
}
|
||||
}
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
val pt = new Point(10, 20);
|
||||
|
||||
// 移到一个新的位置
|
||||
pt.move(10, 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
## 2 Scala 继承
|
||||
Scala继承一个基类跟Java很相似, 但我们需要注意以下几点:
|
||||
|
||||
1、重写一个非抽象方法必须使用override修饰符。
|
||||
2、只有主构造函数才可以往基类的构造函数里写参数。
|
||||
3、在子类中重写超类的抽象方法时,你不需要使用override关键字。
|
||||
接下来让我们来看个实例:
|
||||
|
||||
class Point(xc: Int, yc: Int) {
|
||||
var x: Int = xc
|
||||
var y: Int = yc
|
||||
|
||||
def move(dx: Int, dy: Int) {
|
||||
x = x + dx
|
||||
y = y + dy
|
||||
println ("x 的坐标点: " + x);
|
||||
println ("y 的坐标点: " + y);
|
||||
}
|
||||
}
|
||||
|
||||
class Location(override val xc: Int, override val yc: Int,
|
||||
val zc :Int) extends Point(xc, yc){
|
||||
var z: Int = zc
|
||||
|
||||
def move(dx: Int, dy: Int, dz: Int) {
|
||||
x = x + dx
|
||||
y = y + dy
|
||||
z = z + dz
|
||||
println ("x 的坐标点 : " + x);
|
||||
println ("y 的坐标点 : " + y);
|
||||
println ("z 的坐标点 : " + z);
|
||||
}
|
||||
}
|
||||
Scala 使用 extends 关键字来继承一个类。实例中 Location 类继承了 Point 类。Point 称为父类(基类),Location 称为子类。
|
||||
|
||||
override val xc 为重写了父类的字段。
|
||||
|
||||
继承会继承父类的所有属性和方法,Scala 只允许继承一个父类。
|
||||
|
||||
实例如下:
|
||||
|
||||
import java.io._
|
||||
|
||||
class Point(val xc: Int, val yc: Int) {
|
||||
var x: Int = xc
|
||||
var y: Int = yc
|
||||
def move(dx: Int, dy: Int) {
|
||||
x = x + dx
|
||||
y = y + dy
|
||||
println ("x 的坐标点 : " + x);
|
||||
println ("y 的坐标点 : " + y);
|
||||
}
|
||||
}
|
||||
|
||||
class Location(override val xc: Int, override val yc: Int,
|
||||
val zc :Int) extends Point(xc, yc){
|
||||
var z: Int = zc
|
||||
|
||||
def move(dx: Int, dy: Int, dz: Int) {
|
||||
x = x + dx
|
||||
y = y + dy
|
||||
z = z + dz
|
||||
println ("x 的坐标点 : " + x);
|
||||
println ("y 的坐标点 : " + y);
|
||||
println ("z 的坐标点 : " + z);
|
||||
}
|
||||
}
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
val loc = new Location(10, 20, 15);
|
||||
|
||||
// 移到一个新的位置
|
||||
loc.move(10, 10, 5);
|
||||
}
|
||||
}
|
||||
执行以上代码,输出结果为:
|
||||
|
||||
$ scalac Test.scala
|
||||
$ scala Test
|
||||
x 的坐标点 : 20
|
||||
y 的坐标点 : 30
|
||||
z 的坐标点 : 20
|
||||
Scala重写一个非抽象方法,必须用override修饰符。
|
||||
|
||||
class Person {
|
||||
var name = ""
|
||||
override def toString = getClass.getName + "[name=" + name + "]"
|
||||
}
|
||||
|
||||
class Employee extends Person {
|
||||
var salary = 0.0
|
||||
override def toString = super.toString + "[salary=" + salary + "]"
|
||||
}
|
||||
|
||||
object Test extends App {
|
||||
val fred = new Employee
|
||||
fred.name = "Fred"
|
||||
fred.salary = 50000
|
||||
println(fred)
|
||||
}
|
||||
执行以上代码,输出结果为:
|
||||
|
||||
$ scalac Test.scala
|
||||
$ scala Test
|
||||
Employee[name=Fred][salary=50000.0]
|
||||
|
||||
|
||||
## 3 Scala 单例对象
|
||||
在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object。
|
||||
|
||||
Scala 中使用单例模式时,除了定义的类之外,还要定义一个同名的 object 对象,它和类的区别是,object对象不能带参数。
|
||||
|
||||
当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象:companion object。你必须在同一个源文件里定义类和它的伴生对象。类被称为是这个单例对象的伴生类:companion class。类和它的伴生对象可以互相访问其私有成员。
|
||||
|
||||
单例对象实例
|
||||
import java.io._
|
||||
|
||||
class Point(val xc: Int, val yc: Int) {
|
||||
var x: Int = xc
|
||||
var y: Int = yc
|
||||
def move(dx: Int, dy: Int) {
|
||||
x = x + dx
|
||||
y = y + dy
|
||||
}
|
||||
}
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
val point = new Point(10, 20)
|
||||
printPoint
|
||||
|
||||
def printPoint{
|
||||
println ("x 的坐标点 : " + point.x);
|
||||
println ("y 的坐标点 : " + point.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
执行以上代码,输出结果为:
|
||||
|
||||
$ scalac Test.scala
|
||||
$ scala Test
|
||||
x 的坐标点 : 10
|
||||
y 的坐标点 : 20
|
||||
|
||||
## 4 伴生对象实例
|
||||
/* 文件名:Marker.scala
|
||||
* author:菜鸟教程
|
||||
* url:www.runoob.com
|
||||
*/
|
||||
|
||||
// 私有构造方法
|
||||
class Marker private(val color:String) {
|
||||
|
||||
println("创建" + this)
|
||||
|
||||
override def toString(): String = "颜色标记:"+ color
|
||||
|
||||
}
|
||||
|
||||
// 伴生对象,与类名字相同,可以访问类的私有属性和方法
|
||||
object Marker{
|
||||
|
||||
private val markers: Map[String, Marker] = Map(
|
||||
"red" -> new Marker("red"),
|
||||
"blue" -> new Marker("blue"),
|
||||
"green" -> new Marker("green")
|
||||
)
|
||||
|
||||
def apply(color:String) = {
|
||||
if(markers.contains(color)) markers(color) else null
|
||||
}
|
||||
|
||||
|
||||
def getMarker(color:String) = {
|
||||
if(markers.contains(color)) markers(color) else null
|
||||
}
|
||||
def main(args: Array[String]) {
|
||||
println(Marker("red"))
|
||||
// 单例函数调用,省略了.(点)符号
|
||||
println(Marker getMarker "blue")
|
||||
}
|
||||
}
|
||||
执行以上代码,输出结果为:
|
||||
|
||||
$ scalac Marker.scala
|
||||
$ scala Marker
|
||||
创建颜色标记:red
|
||||
创建颜色标记:blue
|
||||
创建颜色标记:green
|
||||
颜色标记:red
|
||||
颜色标记:blue
|
||||
64
Scala/13 Trait.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Scala Trait(特征)
|
||||
Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。
|
||||
|
||||
与接口不同的是,它还可以定义属性和方法的实现。
|
||||
|
||||
一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。
|
||||
|
||||
Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait,如下所示:
|
||||
|
||||
trait Equal {
|
||||
def isEqual(x: Any): Boolean
|
||||
def isNotEqual(x: Any): Boolean = !isEqual(x)
|
||||
}
|
||||
以上Trait(特征)由两个方法组成:isEqual 和 isNotEqual。isEqual 方法没有定义方法的实现,isNotEqual定义了方法的实现。子类继承特征可以实现未被实现的方法。所以其实 Scala Trait(特征)更像 Java 的抽象类。
|
||||
|
||||
以下演示了特征的完整实例:
|
||||
|
||||
/* 文件名:Test.scala
|
||||
* author:菜鸟教程
|
||||
* url:www.runoob.com
|
||||
*/
|
||||
trait Equal {
|
||||
def isEqual(x: Any): Boolean
|
||||
def isNotEqual(x: Any): Boolean = !isEqual(x)
|
||||
}
|
||||
|
||||
class Point(xc: Int, yc: Int) extends Equal {
|
||||
var x: Int = xc
|
||||
var y: Int = yc
|
||||
def isEqual(obj: Any) =
|
||||
obj.isInstanceOf[Point] &&
|
||||
obj.asInstanceOf[Point].x == x
|
||||
}
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
val p1 = new Point(2, 3)
|
||||
val p2 = new Point(2, 4)
|
||||
val p3 = new Point(3, 3)
|
||||
|
||||
println(p1.isNotEqual(p2))
|
||||
println(p1.isNotEqual(p3))
|
||||
println(p1.isNotEqual(2))
|
||||
}
|
||||
}
|
||||
执行以上代码,输出结果为:
|
||||
|
||||
$ scalac Test.scala
|
||||
$ scala Test
|
||||
false
|
||||
true
|
||||
true
|
||||
特征构造顺序
|
||||
特征也可以有构造器,由字段的初始化和其他特征体中的语句构成。这些语句在任何混入该特征的对象在构造时都会被执行。
|
||||
|
||||
构造器的执行顺序:
|
||||
|
||||
调用超类的构造器;
|
||||
特征构造器在超类构造器之后、类构造器之前执行;
|
||||
特征由左到右被构造;
|
||||
每个特征当中,父特征先被构造;
|
||||
如果多个特征共有一个父特征,父特征不会被重复构造
|
||||
所有特征被构造完毕,子类被构造。
|
||||
构造器的顺序是类的线性化的反向。线性化是描述某个类型的所有超类型的一种技术规格。
|
||||
34
Scala/2 数据类型.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# 数据类型
|
||||
|
||||
## 1 数据类型
|
||||
|
||||
### Scala 数据类型
|
||||
Scala 与 Java有着相同的数据类型,下表列出了 Scala 支持的数据类型:
|
||||
|
||||
数据类型 描述
|
||||
Byte 8位有符号补码整数。数值区间为 -128 到 127
|
||||
Short 16位有符号补码整数。数值区间为 -32768 到 32767
|
||||
Int 32位有符号补码整数。数值区间为 -2147483648 到 2147483647
|
||||
Long 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807
|
||||
Float 32 位, IEEE 754 标准的单精度浮点数
|
||||
Double 64 位 IEEE 754 标准的双精度浮点数
|
||||
Char 16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF
|
||||
String 字符序列
|
||||
Boolean true或false
|
||||
Unit 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。
|
||||
Null null 或空引用
|
||||
Nothing Nothing类型在Scala的类层级的最底端;它是任何其他类型的子类型。
|
||||
Any Any是所有其他类的超类
|
||||
AnyRef AnyRef类是Scala里所有引用类(reference class)的基类
|
||||
|
||||
### 转义字符
|
||||
|
||||
转义字符 Unicode 描述
|
||||
\b \u0008 退格(BS) ,将当前位置移到前一列
|
||||
\t \u0009 水平制表(HT) (跳到下一个TAB位置)
|
||||
\n \u000a 换行(LF) ,将当前位置移到下一行开头
|
||||
\f \u000c 换页(FF),将当前位置移到下页开头
|
||||
\r \u000d 回车(CR) ,将当前位置移到本行开头
|
||||
\" \u0022 代表一个双引号(")字符
|
||||
\' \u0027 代表一个单引号(')字符
|
||||
\\ \u005c 代表一个反斜线字符 '\'
|
||||
51
Scala/3 变量常量.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Scala 变量
|
||||
### 变量的作用
|
||||
变量是一种使用方便的占位符,用于引用计算机内存地址,变量创建后会占用一定的内存空间。
|
||||
|
||||
基于变量的数据类型,操作系统会进行内存分配并且决定什么将被储存在保留内存中。因此,通过给变量分配不同的数据类型,你可以在这些变量中存储整数,小数或者字母。
|
||||
|
||||
### 变量声明
|
||||
在学习如何声明变量与常量之前,我们先来了解一些变量与常量。
|
||||
|
||||
一、变量: 在程序运行过程中其值可能发生改变的量叫做变量。如:时间,年龄。
|
||||
二、常量 在程序运行过程中其值不会发生变化的量叫做常量。如:数值 3,字符'A'。
|
||||
在 Scala 中,使用关键词 "var" 声明变量,使用关键词 "val" 声明常量。
|
||||
|
||||
声明变量实例如下:
|
||||
|
||||
var myVar : String = "Foo"
|
||||
var myVar : String = "Too"
|
||||
以上定义了变量 myVar,我们可以修改它。
|
||||
|
||||
声明常量实例如下:
|
||||
|
||||
val myVal : String = "Foo"
|
||||
以上定义了常量 myVal,它是不能修改的。如果程序尝试修改常量 myVal 的值,程序将会在编译时报错。
|
||||
|
||||
### 变量类型声明
|
||||
只声明类型不给值。
|
||||
变量的类型在变量名之后等号之前声明。定义变量的类型的语法格式如下:
|
||||
|
||||
var VariableName : DataType [= Initial Value]
|
||||
|
||||
或
|
||||
|
||||
val VariableName : DataType [= Initial Value]
|
||||
|
||||
### 变量类型引用
|
||||
在 Scala 中声明变量和常量不一定要指明数据类型,在没有指明数据类型的情况下,其数据类型是通过变量或常量的初始值推断出来的。
|
||||
|
||||
所以,如果在没有指明数据类型的情况下声明变量或常量必须要给出其初始值,否则将会报错。
|
||||
|
||||
var myVar = 10;
|
||||
val myVal = "Hello, Scala!";
|
||||
|
||||
### cala 多个变量声明
|
||||
Scala 支持多个变量的声明:
|
||||
|
||||
val xmax, ymax = 100 // xmax, ymax都声明为100
|
||||
如果方法返回值是元组,我们可以使用 val 来声明一个元组:
|
||||
|
||||
scala> val pa = (40,"Foo")
|
||||
pa: (Int, String) = (40,Foo)
|
||||
|
||||
87
Scala/4 访问修饰符.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Scala 访问修饰符
|
||||
Scala 访问修饰符基本和Java的一样,分别有:private,protected,public。
|
||||
|
||||
如果没有指定访问修饰符,默认情况下,Scala 对象的访问级别都是 public。
|
||||
|
||||
Scala 中的 private 限定符,比 Java 更严格,在嵌套类情况下,外层类甚至不能访问被嵌套类的私有成员。
|
||||
|
||||
## 1 私有(Private)成员
|
||||
用 private 关键字修饰,带有此标记的成员仅在包含了成员定义的类或对象内部可见,同样的规则还适用内部类。
|
||||
|
||||
class Outer{
|
||||
class Inner{
|
||||
private def f(){println("f")}
|
||||
class InnerMost{
|
||||
f() // 正确
|
||||
}
|
||||
}
|
||||
(new Inner).f() //错误
|
||||
}
|
||||
(new Inner).f( ) 访问不合法是因为 f 在 Inner 中被声明为 private,而访问不在类 Inner 之内。
|
||||
|
||||
但在 InnerMost 里访问 f 就没有问题的,因为这个访问包含在 Inner 类之内。
|
||||
|
||||
Java中允许这两种访问,因为它允许外部类访问内部类的私有成员。
|
||||
|
||||
## 2 保护(Protected)成员
|
||||
在 scala 中,对保护(Protected)成员的访问比 java 更严格一些。因为它只允许保护成员在定义了该成员的的类的子类中被访问。而在java中,用protected关键字修饰的成员,除了定义了该成员的类的子类可以访问,同一个包里的其他类也可以进行访问。
|
||||
|
||||
package p{
|
||||
class Super{
|
||||
protected def f() {println("f")}
|
||||
}
|
||||
class Sub extends Super{
|
||||
f()
|
||||
}
|
||||
class Other{
|
||||
(new Super).f() //错误
|
||||
}
|
||||
}
|
||||
上例中,Sub 类对 f 的访问没有问题,因为 f 在 Super 中被声明为 protected,而 Sub 是 Super 的子类。相反,Other 对 f 的访问不被允许,因为 other 没有继承自 Super。而后者在 java 里同样被认可,因为 Other 与 Sub 在同一包里。
|
||||
|
||||
## 3 公共(Public)成员
|
||||
Scala中,如果没有指定任何的修饰符,则默认为 public。这样的成员在任何地方都可以被访问。
|
||||
|
||||
class Outer {
|
||||
class Inner {
|
||||
def f() { println("f") }
|
||||
class InnerMost {
|
||||
f() // 正确
|
||||
}
|
||||
}
|
||||
(new Inner).f() // 正确因为 f() 是 public
|
||||
}
|
||||
|
||||
## 4 作用域保护
|
||||
Scala中,访问修饰符可以通过使用限定词强调。格式为:
|
||||
|
||||
private[x]
|
||||
|
||||
或
|
||||
|
||||
protected[x]
|
||||
这里的x指代某个所属的包、类或单例对象。如果写成private[x],读作"这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对像可见外,对其它所有类都是private。
|
||||
|
||||
这种技巧在横跨了若干包的大型项目中非常有用,它允许你定义一些在你项目的若干子包中可见但对于项目外部的客户却始终不可见的东西。
|
||||
|
||||
package bobsrockets{
|
||||
package navigation{
|
||||
private[bobsrockets] class Navigator{
|
||||
protected[navigation] def useStarChart(){}
|
||||
class LegOfJourney{
|
||||
private[Navigator] val distance = 100
|
||||
}
|
||||
private[this] var speed = 200
|
||||
}
|
||||
}
|
||||
package launch{
|
||||
import navigation._
|
||||
object Vehicle{
|
||||
private[launch] val guide = new Navigator
|
||||
}
|
||||
}
|
||||
}
|
||||
上述例子中,类Navigator被标记为private[bobsrockets]就是说这个类对包含在bobsrockets包里的所有的类和对象可见。
|
||||
|
||||
比如说,从Vehicle对象里对Navigator的访问是被允许的,因为对象Vehicle包含在包launch中,而launch包在bobsrockets中,相反,所有在包bobsrockets之外的代码都不能访问类Navigator。
|
||||
|
||||
109
Scala/5 运算符.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Scala 运算符
|
||||
一个运算符是一个符号,用于告诉编译器来执行指定的数学运算和逻辑运算。
|
||||
|
||||
Scala 含有丰富的内置运算符,包括以下几种类型:
|
||||
|
||||
算术运算符
|
||||
|
||||
关系运算符
|
||||
|
||||
逻辑运算符
|
||||
|
||||
位运算符
|
||||
|
||||
赋值运算符
|
||||
|
||||
## 1 算术运算符
|
||||
下表列出了 Scala 支持的算术运算符。
|
||||
|
||||
假定变量 A 为 10,B 为 20:
|
||||
|
||||
运算符 描述 实例
|
||||
+ 加号 A + B 运算结果为 30
|
||||
- 减号 A - B 运算结果为 -10
|
||||
* 乘号 A * B 运算结果为 200
|
||||
/ 除号 B / A 运算结果为 2
|
||||
% 取余 B % A 运算结果为 0
|
||||
|
||||
## 2 关系运算符
|
||||
下表列出了 Scala 支持的关系运算符。
|
||||
|
||||
假定变量 A 为 10,B 为 20:
|
||||
|
||||
运算符 描述 实例
|
||||
== 等于 (A == B) 运算结果为 false
|
||||
!= 不等于 (A != B) 运算结果为 true
|
||||
> 大于 (A > B) 运算结果为 false
|
||||
< 小于 (A < B) 运算结果为 true
|
||||
>= 大于等于 (A >= B) 运算结果为 false
|
||||
<= 小于等于 (A <= B) 运算结果为 true
|
||||
|
||||
## 3 逻辑运算符
|
||||
下表列出了 Scala 支持的逻辑运算符。
|
||||
|
||||
假定变量 A 为 1,B 为 0:
|
||||
|
||||
运算符 描述 实例
|
||||
&& 逻辑与 (A && B) 运算结果为 false
|
||||
|| 逻辑或 (A || B) 运算结果为 true
|
||||
! 逻辑非 !(A && B) 运算结果为 true
|
||||
|
||||
## 4 位运算符
|
||||
位运算符用来对二进制位进行操作,~,&,|,^分别为取反,按位与与,按位与或,按位与异或运算,如下表实例:
|
||||
|
||||
p q p & q p | q p ^ q
|
||||
0 0 0 0 0
|
||||
0 1 0 1 1
|
||||
1 1 1 1 0
|
||||
1 0 0 1 1
|
||||
|
||||
Scala 中的按位运算法则如下:
|
||||
|
||||
运算符 描述 实例
|
||||
& 按位与运算符 (a & b) 输出结果 12 ,二进制解释: 0000 1100
|
||||
| 按位或运算符 (a | b) 输出结果 61 ,二进制解释: 0011 1101
|
||||
^ 按位异或运算符 (a ^ b) 输出结果 49 ,二进制解释: 0011 0001
|
||||
~ 按位取反运算符 (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。
|
||||
<< 左移动运算符 a << 2 输出结果 240 ,二进制解释: 1111 0000
|
||||
>> 右移动运算符 a >> 2 输出结果 15 ,二进制解释: 0000 1111
|
||||
>>> 无符号右移 A >>>2 输出结果 15, 二进制解释: 0000 1111
|
||||
|
||||
## 5 赋值运算符
|
||||
以下列出了 Scala 语言支持的赋值运算符:
|
||||
|
||||
运算符 描述 实例
|
||||
= 简单的赋值运算,指定右边操作数赋值给左边的操作数。 C = A + B 将 A + B 的运算结果赋值给 C
|
||||
+= 相加后再赋值,将左右两边的操作数相加后再赋值给左边的操作数。 C += A 相当于 C = C + A
|
||||
-= 相减后再赋值,将左右两边的操作数相减后再赋值给左边的操作数。 C -= A 相当于 C = C - A
|
||||
*= 相乘后再赋值,将左右两边的操作数相乘后再赋值给左边的操作数。 C *= A 相当于 C = C * A
|
||||
/= 相除后再赋值,将左右两边的操作数相除后再赋值给左边的操作数。 C /= A 相当于 C = C / A
|
||||
%= 求余后再赋值,将左右两边的操作数求余后再赋值给左边的操作数。 C %= A is equivalent to C = C % A
|
||||
<<= 按位左移后再赋值 C <<= 2 相当于 C = C << 2
|
||||
>>= 按位右移后再赋值 C >>= 2 相当于 C = C >> 2
|
||||
&= 按位与运算后赋值 C &= 2 相当于 C = C & 2
|
||||
^= 按位异或运算符后再赋值 C ^= 2 相当于 C = C ^ 2
|
||||
|= 按位或运算后再赋值 C |= 2 相当于 C = C | 2
|
||||
|
||||
## 6 运算符优先级
|
||||
|
||||
取决于所属的运算符组,它会影响算式的的计算。
|
||||
|
||||
实例: x = 7 + 3 * 2; 这里, x 计算结果为 13, 而不是 20,因为乘法(*) 高于加法(+), 所以它先计算 3*2 再加上 7。
|
||||
|
||||
查看以下表格,优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最低的优先级。
|
||||
|
||||
类别 运算符 关联性
|
||||
1 () [] 左到右
|
||||
2 ! ~ 右到左
|
||||
3 * / % 左到右
|
||||
4 + - 左到右
|
||||
5 >> >>> << 左到右
|
||||
6 > >= < <= 左到右
|
||||
7 == != 左到右
|
||||
8 & 左到右
|
||||
9 ^ 左到右
|
||||
10 | 左到右
|
||||
11 && 左到右
|
||||
12 || 左到右
|
||||
13 = += -= *= /= %= >>= <<= &= ^= |= 右到左
|
||||
14 , 左到右
|
||||
56
Scala/6 控制结构.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# 控制结构
|
||||
|
||||
## 1 IF选择
|
||||
Scala IF...ELSE 语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块。
|
||||
|
||||
* if 语句。if 语句有布尔表达式及之后的语句块组成。
|
||||
* if...else 语句。if 语句后可以紧跟 else 语句,else 内的语句块可以在布尔表达式为 false 的时候执行。
|
||||
* if...else if...else 语句。if 语句后可以紧跟 else if...else 语句,在多个条件判断语句的情况下很有用。
|
||||
* if...{if...else...}...else... 嵌套语句。if...else 嵌套语句可以实现在 if 语句内嵌入一个或多个 if 语句。
|
||||
|
||||
|
||||
## 2 循环
|
||||
|
||||
### 循环类型
|
||||
Scala 语言提供了以下几种循环类型。点击链接查看每个类型的细节。
|
||||
|
||||
循环类型 描述
|
||||
while 循环 运行一系列语句,如果条件为true,会重复运行,直到条件变为false。
|
||||
do...while 循环 类似 while 语句区别在于判断循环条件之前,先执行一次循环的代码块。
|
||||
for 循环 用来重复执行一系列语句直到达成特定条件达成,一般通过在每次循环完成后增加计数器的值来实现。
|
||||
|
||||
### while 循环
|
||||
|
||||
Scala 语言中 while 循环的语法:
|
||||
|
||||
while(condition)
|
||||
{
|
||||
statement(s);
|
||||
}
|
||||
在这里,statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。
|
||||
|
||||
condition 可以是任意的表达式,当为任意非零值时都为 true。当条件为 true 时执行循环。 当条件为 false 时,退出循环,程序流将继续执行紧接着循环的下一条语句。
|
||||
|
||||
|
||||
### for循环
|
||||
|
||||
语法
|
||||
Scala 语言中 for 循环的语法:
|
||||
|
||||
for( var x <- Range ){
|
||||
statement(s);
|
||||
}
|
||||
|
||||
### do while循环
|
||||
Scala 语言中 while 循环的语法:
|
||||
|
||||
do {
|
||||
statement(s);
|
||||
} while( condition );
|
||||
### 循环控制语句
|
||||
循环控制语句改变你代码的执行顺序,通过它你可以实现代码的跳转。Scala 以下几种循环控制语句:
|
||||
|
||||
Scala 不支持 break 或 continue 语句,但从 2.8 版本后提供了一种中断循环的方式,点击以下链接查看详情。
|
||||
|
||||
控制语句 描述
|
||||
break 语句 中断循环
|
||||
63
Scala/7 函数.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# 方法函数
|
||||
|
||||
## 1 方法与函数关系
|
||||
|
||||
Scala 有方法与函数,二者在语义上的区别很小。Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法。
|
||||
|
||||
Scala 中的方法跟 Java 的类似,方法是组成类的一部分。
|
||||
|
||||
Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象。
|
||||
|
||||
Scala 中使用 val 语句可以定义函数,def 语句定义方法。
|
||||
|
||||
class Test{
|
||||
def m(x: Int) = x + 3
|
||||
val f = (x: Int) => x + 3
|
||||
}
|
||||
## 2 函数
|
||||
|
||||
### 类型变量混合式
|
||||
|
||||
val f1 = (x:Int,y:Int)=>x*y
|
||||
|
||||
### 类型变量分离式
|
||||
val f2:(Int,Int)=>Int = (x,y)=>x*y
|
||||
|
||||
|
||||
## 3 方法
|
||||
### 方法声明
|
||||
Scala 方法声明格式如下:
|
||||
|
||||
def functionName ([参数列表]) : [return type]
|
||||
如果你不写等于号和方法主体,那么方法会被隐式声明为抽象(abstract),包含它的类型于是也是一个抽象类型。
|
||||
|
||||
### 方法定义
|
||||
方法定义由一个 def 关键字开始,紧接着是可选的参数列表,一个冒号 : 和方法的返回类型,一个等于号 = ,最后是方法的主体。
|
||||
|
||||
Scala 方法定义格式如下:
|
||||
|
||||
def functionName ([参数列表]) : [return type] = {
|
||||
function body
|
||||
return [expr]
|
||||
}
|
||||
|
||||
object add{
|
||||
def addInt( a:Int, b:Int ) : Int = {
|
||||
var sum:Int = 0
|
||||
sum = a + b
|
||||
|
||||
return sum
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
### 方法调用
|
||||
Scala 提供了多种不同的方法调用方式:
|
||||
|
||||
以下是调用方法的标准格式:
|
||||
|
||||
functionName( 参数列表 )
|
||||
如果方法使用了实例的对象来调用,我们可以使用类似java的格式 (使用 . 号):
|
||||
|
||||
[instance.]functionName( 参数列表 )
|
||||
29
Scala/8 闭包.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Scala 闭包
|
||||
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
|
||||
|
||||
闭包通常来讲可以简单的认为是可以访问一个函数里面局部变量的另外一个函数。
|
||||
|
||||
如下面这段匿名的函数:
|
||||
|
||||
val multiplier = (i:Int) => i * 10
|
||||
函数体内有一个变量 i,它作为函数的一个参数。如下面的另一段代码:
|
||||
|
||||
val multiplier = (i:Int) => i * factor
|
||||
在 multiplier 中有两个变量:i 和 factor。其中的一个 i 是函数的形式参数,在 multiplier 函数被调用时,i 被赋予一个新的值。然而,factor不是形式参数,而是自由变量,考虑下面代码:
|
||||
|
||||
var factor = 3
|
||||
val multiplier = (i:Int) => i * factor
|
||||
这里我们引入一个自由变量 factor,这个变量定义在函数外面。
|
||||
|
||||
这样定义的函数变量 multiplier 成为一个"闭包",因为它引用到函数外面定义的变量,定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。
|
||||
|
||||
完整实例
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
println( "muliplier(1) value = " + multiplier(1) )
|
||||
println( "muliplier(2) value = " + multiplier(2) )
|
||||
}
|
||||
var factor = 3
|
||||
val multiplier = (i:Int) => i * factor
|
||||
}
|
||||
289
Scala/9 字符串.md
Normal file
@@ -0,0 +1,289 @@
|
||||
# 字符串
|
||||
|
||||
## 1 简介
|
||||
在 Scala 中,字符串的类型实际上是 Java String,它本身没有 String 类。
|
||||
|
||||
在 Scala 中,String 是一个不可变的对象,所以该对象不可被修改。这就意味着你如果修改字符串就会产生一个新的字符串对象。
|
||||
|
||||
但其他对象,如数组就是可变的对象。接下来我们会为大家介绍常用的 java.lang.String 方法。
|
||||
|
||||
|
||||
## 2 常用方法
|
||||
|
||||
### 创建字符串
|
||||
创建字符串实例如下:
|
||||
|
||||
var greeting = "Hello World!";
|
||||
|
||||
或
|
||||
|
||||
var greeting:String = "Hello World!";
|
||||
|
||||
### 字符串长度
|
||||
我们可以使用 length() 方法来获取字符串长度:
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
var palindrome = "www.runoob.com";
|
||||
var len = palindrome.length();
|
||||
println( "String Length is : " + len );
|
||||
}
|
||||
}
|
||||
|
||||
### 字符串连接
|
||||
String 类中使用 concat() 方法来连接两个字符串:
|
||||
|
||||
string1.concat(string2);
|
||||
|
||||
|
||||
### 创建格式化字符串
|
||||
String 类中你可以使用 printf() 方法来格式化字符串并输出,String format() 方法可以返回 String 对象而不是 PrintStream 对象。以下实例演示了 printf() 方法的使用:
|
||||
|
||||
object Test {
|
||||
def main(args: Array[String]) {
|
||||
var floatVar = 12.456
|
||||
var intVar = 2000
|
||||
var stringVar = "菜鸟教程!"
|
||||
var fs = printf("浮点型变量为 " +
|
||||
"%f, 整型变量为 %d, 字符串为 " +
|
||||
" %s", floatVar, intVar, stringVar)
|
||||
println(fs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
### 常用方法
|
||||
|
||||
String 方法
|
||||
下表列出了 java.lang.String 中常用的方法,你可以在 Scala 中使用:
|
||||
|
||||
序号 方法及描述
|
||||
1
|
||||
char charAt(int index)
|
||||
|
||||
返回指定位置的字符
|
||||
|
||||
2
|
||||
int compareTo(Object o)
|
||||
|
||||
比较字符串与对象
|
||||
|
||||
3
|
||||
int compareTo(String anotherString)
|
||||
|
||||
按字典顺序比较两个字符串
|
||||
|
||||
4
|
||||
int compareToIgnoreCase(String str)
|
||||
|
||||
按字典顺序比较两个字符串,不考虑大小写
|
||||
|
||||
5
|
||||
String concat(String str)
|
||||
|
||||
将指定字符串连接到此字符串的结尾
|
||||
|
||||
6
|
||||
boolean contentEquals(StringBuffer sb)
|
||||
|
||||
将此字符串与指定的 StringBuffer 比较。
|
||||
|
||||
7
|
||||
static String copyValueOf(char[] data)
|
||||
|
||||
返回指定数组中表示该字符序列的 String
|
||||
|
||||
8
|
||||
static String copyValueOf(char[] data, int offset, int count)
|
||||
|
||||
返回指定数组中表示该字符序列的 String
|
||||
|
||||
9
|
||||
boolean endsWith(String suffix)
|
||||
|
||||
测试此字符串是否以指定的后缀结束
|
||||
|
||||
10
|
||||
boolean equals(Object anObject)
|
||||
|
||||
将此字符串与指定的对象比较
|
||||
|
||||
11
|
||||
boolean equalsIgnoreCase(String anotherString)
|
||||
|
||||
将此 String 与另一个 String 比较,不考虑大小写
|
||||
|
||||
12
|
||||
byte getBytes()
|
||||
|
||||
使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中
|
||||
|
||||
13
|
||||
byte[] getBytes(String charsetName
|
||||
|
||||
使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中
|
||||
|
||||
14
|
||||
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
|
||||
|
||||
将字符从此字符串复制到目标字符数组
|
||||
|
||||
15
|
||||
int hashCode()
|
||||
|
||||
返回此字符串的哈希码
|
||||
|
||||
16
|
||||
int indexOf(int ch)
|
||||
|
||||
返回指定字符在此字符串中第一次出现处的索引
|
||||
|
||||
17
|
||||
int indexOf(int ch, int fromIndex)
|
||||
|
||||
返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索
|
||||
|
||||
18
|
||||
int indexOf(String str)
|
||||
|
||||
返回指定子字符串在此字符串中第一次出现处的索引
|
||||
|
||||
19
|
||||
int indexOf(String str, int fromIndex)
|
||||
|
||||
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
|
||||
|
||||
20
|
||||
String intern()
|
||||
|
||||
返回字符串对象的规范化表示形式
|
||||
|
||||
21
|
||||
int lastIndexOf(int ch)
|
||||
|
||||
返回指定字符在此字符串中最后一次出现处的索引
|
||||
|
||||
22
|
||||
int lastIndexOf(int ch, int fromIndex)
|
||||
|
||||
返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索
|
||||
|
||||
23
|
||||
int lastIndexOf(String str)
|
||||
|
||||
返回指定子字符串在此字符串中最右边出现处的索引
|
||||
|
||||
24
|
||||
int lastIndexOf(String str, int fromIndex)
|
||||
|
||||
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
|
||||
|
||||
25
|
||||
int length()
|
||||
|
||||
返回此字符串的长度
|
||||
|
||||
26
|
||||
boolean matches(String regex)
|
||||
|
||||
告知此字符串是否匹配给定的正则表达式
|
||||
|
||||
27
|
||||
boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
|
||||
|
||||
测试两个字符串区域是否相等
|
||||
|
||||
28
|
||||
boolean regionMatches(int toffset, String other, int ooffset, int len)
|
||||
|
||||
测试两个字符串区域是否相等
|
||||
|
||||
29
|
||||
String replace(char oldChar, char newChar)
|
||||
|
||||
返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的
|
||||
|
||||
30
|
||||
String replaceAll(String regex, String replacement
|
||||
|
||||
使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串
|
||||
|
||||
31
|
||||
String replaceFirst(String regex, String replacement)
|
||||
|
||||
使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串
|
||||
|
||||
32
|
||||
String[] split(String regex)
|
||||
|
||||
根据给定正则表达式的匹配拆分此字符串
|
||||
|
||||
33
|
||||
String[] split(String regex, int limit)
|
||||
|
||||
根据匹配给定的正则表达式来拆分此字符串
|
||||
|
||||
34
|
||||
boolean startsWith(String prefix)
|
||||
|
||||
测试此字符串是否以指定的前缀开始
|
||||
|
||||
35
|
||||
boolean startsWith(String prefix, int toffset)
|
||||
|
||||
测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
|
||||
|
||||
36
|
||||
CharSequence subSequence(int beginIndex, int endIndex)
|
||||
|
||||
返回一个新的字符序列,它是此序列的一个子序列
|
||||
|
||||
37
|
||||
String substring(int beginIndex)
|
||||
|
||||
返回一个新的字符串,它是此字符串的一个子字符串
|
||||
|
||||
38
|
||||
String substring(int beginIndex, int endIndex)
|
||||
|
||||
返回一个新字符串,它是此字符串的一个子字符串
|
||||
|
||||
39
|
||||
char[] toCharArray()
|
||||
|
||||
将此字符串转换为一个新的字符数组
|
||||
|
||||
40
|
||||
String toLowerCase()
|
||||
|
||||
使用默认语言环境的规则将此 String 中的所有字符都转换为小写
|
||||
|
||||
41
|
||||
String toLowerCase(Locale locale)
|
||||
|
||||
使用给定 Locale 的规则将此 String 中的所有字符都转换为小写
|
||||
|
||||
42
|
||||
String toString()
|
||||
|
||||
返回此对象本身(它已经是一个字符串!)
|
||||
|
||||
43
|
||||
String toUpperCase()
|
||||
|
||||
使用默认语言环境的规则将此 String 中的所有字符都转换为大写
|
||||
|
||||
44
|
||||
String toUpperCase(Locale locale)
|
||||
|
||||
使用给定 Locale 的规则将此 String 中的所有字符都转换为大写
|
||||
|
||||
45
|
||||
String trim()
|
||||
|
||||
删除指定字符串的首尾空白符
|
||||
|
||||
46
|
||||
static String valueOf(primitive data type x)
|
||||
|
||||
返回指定类型参数的字符串表示形式
|
||||
4
Scala/参考文献.md
Normal file
@@ -0,0 +1,4 @@
|
||||
* [菜鸟教程](https://www.runoob.com/scala/scala-tutorial.html)
|
||||
* [scala详细教程](https://blog.csdn.net/wangshun_410/article/details/90759688#2.3%20IDEAScala%20%E6%8F%92%E4%BB%B6%E7%9A%84%E7%A6%BB%E7%BA%BF%E5%AE%89%E8%A3%85)
|
||||
* [W3c教程](https://www.w3cschool.cn/scaladevelopmentguide/)
|
||||
* [另外一个教程](https://www.cnblogs.com/lq0310/p/9840317.html)
|
||||
97
Spark/Spark原理.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Spark
|
||||
> 参考文献
|
||||
> * [原理介绍](https://www.cnblogs.com/cxxjohnson/p/8909578.html)
|
||||
|
||||
## 1 简介
|
||||
|
||||
Apache Spark是一个围绕速度、易用性和复杂分析构建的大数据处理框架,Spark提供了一个全面、统一的框架用于管理各种有着不同性质(文本数据、图表数据等)的数据集和数据源(批量数据或实时的流数据)的大数据处理的需求
|
||||
|
||||
Spark是一个计算引擎、计算框架,与TensorFlow很像。但是不提供数据存储功能。大数据存储功能由Hadoop等专门的解决方案提供。
|
||||
|
||||
## 2 架构生态
|
||||
|
||||
通常当需要处理的数据量超过了单机尺度(比如我们的计算机有4GB的内存,而我们需要处理100GB以上的数据)这时我们可以选择spark集群进行计算,有时我们可能需要处理的数据量并不大,但是计算很复杂,需要大量的时间,这时我们也可以选择利用spark集群强大的计算资源,并行化地计算,其架构示意图如下:
|
||||
|
||||

|
||||
|
||||
* Spark Core:包含Spark的基本功能;尤其是定义RDD的API、操作以及这两者上的动作。其他Spark的库都是构建在RDD和Spark Core之上的
|
||||
* Spark SQL:提供通过Apache Hive的SQL变体Hive查询语言(HiveQL)与Spark进行交互的API。每个数据库表被当做一个RDD,Spark SQL查询被转换为Spark操作。
|
||||
* Spark Streaming:对实时数据流进行处理和控制。Spark Streaming允许程序能够像普通RDD一样处理实时数据
|
||||
* MLlib:一个常用机器学习算法库,算法被实现为对RDD的Spark操作。这个库包含可扩展的学习算法,比如分类、回归等需要对大量数据集进行迭代的操作。
|
||||
* GraphX:控制图、并行图操作和计算的一组算法和工具的集合。GraphX扩展了RDD API,包含控制图、创建子图、访问路径上所有顶点的操作
|
||||
|
||||
|
||||
## 3 Spark&Hadoop
|
||||
|
||||
* Hadoop有两个核心模块,分布式存储模块HDFS和分布式计算模块Mapreduce
|
||||
* spark本身并没有提供分布式文件系统,因此spark的分析大多依赖于Hadoop的分布式文件系统HDFS
|
||||
* Hadoop的Mapreduce与spark都可以进行数据计算,而相比于Mapreduce,spark的速度更快并且提供的功能更加丰富
|
||||
|
||||
## 4 运行流程及特点
|
||||
|
||||

|
||||
|
||||
1. 构建Spark Application的运行环境,启动SparkContext
|
||||
2. SparkContext向资源管理器(可以是Standalone,Mesos,Yarn)申请运行Executor资源,并启动StandaloneExecutorbackend,
|
||||
3. Executor向SparkContext申请Task
|
||||
4. SparkContext将应用程序分发给Executor
|
||||
5. SparkContext构建成DAG图,将DAG图分解成Stage、将Taskset发送给Task Scheduler,最后由Task Scheduler将Task发送给Executor运行
|
||||
6. Task在Executor上运行,运行完释放所有资源
|
||||
|
||||
|
||||
Spark运行特点:
|
||||
|
||||
* 每个Application获取专属的executor进程,该进程在Application期间一直驻留,并以多线程方式运行Task。这种Application隔离机制是有优势的,无论是从调度角度看(每个Driver调度他自己的任务),还是从运行角度看(来自不同Application的Task运行在不同JVM中),当然这样意味着Spark Application不能跨应用程序共享数据,除非将数据写入外部存储系统
|
||||
* Spark与资源管理器无关,只要能够获取executor进程,并能保持相互通信就可以了
|
||||
* 提交SparkContext的Client应该靠近Worker节点(运行Executor的节点),最好是在同一个Rack里,因为Spark Application运行过程中SparkContext和Executor之间有大量的信息交换
|
||||
* Task采用了数据本地性和推测执行的优化机制
|
||||
|
||||
## 5 常用术语
|
||||
|
||||
* Application: Appliction都是指用户编写的Spark应用程序,其中包括一个Driver功能的代码和分布在集群中多个节点上运行的Executor代码
|
||||
* Driver: Spark中的Driver即运行上述Application的main函数并创建SparkContext,创建SparkContext的目的是为了准备Spark应用程序的运行环境,在Spark中有SparkContext负责与ClusterManager通信,进行资源申请、任务的分配和监控等,当Executor部分运行完毕后,Driver同时负责将SparkContext关闭,通常用SparkContext代表Driver
|
||||
* Executor: 某个Application运行在worker节点上的一个进程, 该进程负责运行某些Task, 并且负责将数据存到内存或磁盘上,每个Application都有各自独立的一批Executor, 在Spark on Yarn模式下,其进程名称为CoarseGrainedExecutor Backend。一个CoarseGrainedExecutor Backend有且仅有一个Executor对象, 负责将Task包装成taskRunner,并从线程池中抽取一个空闲线程运行Task, 这个每一个oarseGrainedExecutor Backend能并行运行Task的数量取决与分配给它的cpu个数
|
||||
* Cluter Manager:指的是在集群上获取资源的外部服务。目前有三种类型
|
||||
* Standalon : spark原生的资源管理,由Master负责资源的分配
|
||||
* Apache Mesos:与hadoop MR兼容性良好的一种资源调度框架
|
||||
* Hadoop Yarn: 主要是指Yarn中的ResourceManager
|
||||
* Worker: 集群中任何可以运行Application代码的节点,在Standalone模式中指的是通过slave文件配置的Worker节点,在Spark on Yarn模式下就是NoteManager节点
|
||||
* Task: 被送到某个Executor上的工作单元,但hadoopMR中的MapTask和ReduceTask概念一样,是运行Application的基本单位,多个Task组成一个Stage,而Task的调度和管理等是由TaskScheduler负责
|
||||
* Job: 包含多个Task组成的并行计算,往往由Spark Action触发生成, 一个Application中往往会产生多个Job
|
||||
* Stage: 每个Job会被拆分成多组Task, 作为一个TaskSet, 其名称为Stage,Stage的划分和调度是有DAGScheduler来负责的,Stage有非最终的Stage(Shuffle Map Stage)和最终的Stage(Result Stage)两种,Stage的边界就是发生shuffle的地方
|
||||
|
||||

|
||||
|
||||
* DAGScheduler: 根据Job构建基于Stage的DAG(Directed Acyclic Graph有向无环图),并提交Stage给TASkScheduler。 其划分Stage的依据是RDD之间的依赖的关系找出开销最小的调度方法,如下图
|
||||
* TASKSedulter: 将TaskSET提交给worker运行,每个Executor运行什么Task就是在此处分配的. TaskScheduler维护所有TaskSet,当Executor向Driver发生心跳时,TaskScheduler会根据资源剩余情况分配相应的Task。另外TaskScheduler还维护着所有Task的运行标签,重试失败的Task。下图展示了TaskScheduler的作用
|
||||
|
||||
在不同运行模式中任务调度器具体为:
|
||||
* Spark on Standalone模式为TaskScheduler
|
||||
* YARN-Client模式为YarnClientClusterScheduler
|
||||
* YARN-Cluster模式为YarnClusterScheduler
|
||||
将这些术语串起来的运行层次图如下:
|
||||
|
||||

|
||||
|
||||
Job=多个stage,Stage=多个同种task, Task分为ShuffleMapTask和ResultTask,Dependency分为ShuffleDependency和NarrowDependency
|
||||
|
||||
|
||||
## 7 RDD 执行流程
|
||||
|
||||
RDD运行流程:
|
||||
|
||||
RDD在Spark中运行大概分为以下三步:
|
||||
1. 创建RDD对象
|
||||
2. DAGScheduler模块介入运算,计算RDD之间的依赖关系,RDD之间的依赖关系就形成了DAG
|
||||
3. 每一个Job被分为多个Stage。划分Stage的一个主要依据是当前计算因子的输入是否是确定的,如果是则将其分在同一个Stage,避免多个Stage之间的消息传递开销
|
||||
|
||||
示例图如下:
|
||||
|
||||

|
||||
|
||||
以下面一个按 A-Z 首字母分类,查找相同首字母下不同姓名总个数的例子来看一下 RDD 是如何运行起来的
|
||||

|
||||
创建 RDD 上面的例子除去最后一个 collect 是个动作,不会创建 RDD 之外,前面四个转换都会创建出新的 RDD 。因此第一步就是创建好所有 RDD( 内部的五项信息 )?
|
||||
创建执行计划 Spark 会尽可能地管道化,并基于是否要重新组织数据来划分 阶段 (stage) ,例如本例中的 groupBy() 转换就会将整个执行计划划分成两阶段执行。最终会产生一个 DAG(directed acyclic graph ,有向无环图 ) 作为逻辑执行计划
|
||||
|
||||
调度任务 将各阶段划分成不同的 任务 (task) ,每个任务都是数据和计算的合体。在进行下一阶段前,当前阶段的所有任务都要执行完成。因为下一阶段的第一个转换一定是重新组织数据的,所以必须等当前阶段所有结果数据都计算出来了才能继续
|
||||
BIN
Spark/image/SparkRDD执行流程.png
Normal file
|
After Width: | Height: | Size: 187 KiB |
BIN
Spark/image/Spark执行层次.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
Spark/image/Spark执行逻辑.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
Spark/image/Spark架构.png.png
Normal file
|
After Width: | Height: | Size: 160 KiB |
BIN
Spark/image/Spark程序实例.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
Spark/image/Spark运行流程.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
@@ -25,7 +25,7 @@ $$
|
||||
* 检验法则:若$(x_1,\dotsm,x_n)\in W$,则拒绝$H_0$,否则由$(x_1,\dotsm,x_n)\in W^c$,就接受$H_0$。称$W$为拒绝域,$W^c$称为接受域。
|
||||
> 拒绝度$\alpha$与拒绝域$W$一一对应。置信度$1-\alpha$与接受域(置信区间)$1-\alpha$一一对应。
|
||||
|
||||
* 检验统计量:能够由统计量确定拒绝域W,则统计量为检验统计量。检验统计量的检验临界值,能够区分两个检验区间。
|
||||
* 检验统计量:能够由统计量确定拒绝域W,则统计量为检验统计量。检验统计量的检验临界值,能够区分两个检验区间。样本空间可以分为拒绝域和接受域,但是无法用数学关系式定量表达。需要使用样本的统计量的不等式,定量表示拒绝域和接受域的范围,而区分这个范围的量称为检验临界值。
|
||||
* 示性函数或者检验函数
|
||||
$$
|
||||
\varphi(x)=\begin{cases}
|
||||
@@ -65,15 +65,21 @@ $\alpha$越大,第一类错误发生的错误越小,第二类错误发生的
|
||||
> 这里的势不依赖于假设,而是一种本质的基于总体真正的属性的计算值。(假设是一种猜测,验证后才可以使准确地)$\varphi(x)$是显示总体本身真实属性的函数,不依赖于假设,与是否犯错无关。
|
||||
|
||||
|
||||
$H_0$不成立时,拒绝$H_0$的概率,称为势和功效。
|
||||
* $H_0$不成立时,成功拒绝$H_0$的概率,称为势和功效。
|
||||
$$
|
||||
\gamma(\theta)=P_\theta\{x\in W\}
|
||||
$$
|
||||
势函数,当$H_0$不成立时拒绝$H_0$的概率,称为势和功效。相当于拒绝度的衡量。
|
||||
|
||||
* 势函数,相当于拒绝度的衡量。
|
||||
|
||||
$$
|
||||
g(\theta)=P_\theta\{x\in W\}=E_\theta(\varphi(x)),\theta\in\Theta\\
|
||||
$$
|
||||
* 势函数的计算
|
||||
> 关键点在于,\theta的范围。
|
||||
$$
|
||||
当\theta\in\Theta_0,g(\theta)=\alpha(\theta)\\
|
||||
当\theta\in\Theta_1,\beta(\theta)=p_\theta\{x\not\in W\}=1-g(\theta)\\
|
||||
当\theta\in\Theta_1,g(\theta)=\gamma(\theta)
|
||||
$$
|
||||
|
||||
@@ -87,6 +93,8 @@ $$
|
||||
* 这里在逻辑上没有说接受概率和拒绝概率。接受概率和拒绝概率是区间估计那里的置信度和拒绝度。而这里用犯错概率来引入概率的影响,因为这里的接受和拒绝依赖于实际的样本,而区间估计并不依赖于实际的样本,是一种理论计算。所以犯错依赖于概率。
|
||||
|
||||
### 定义:检验水平
|
||||
|
||||
> 分析:这里的检验水平就是拒绝水平。如果能在一个水平下拒绝,那么肯定也能在更大范围内拒绝,即包含真实拒绝域的拒绝域,肯定是拒绝域。因为,**如果能在一个范围内接收,肯定能在更小的范围下接受。**,即属于真实接受域的子集一定是接受域。
|
||||
* 条件
|
||||
$$
|
||||
\alpha\in(0,1),\forall \theta\in\Theta\\
|
||||
@@ -99,6 +107,14 @@ $$
|
||||
$$
|
||||
* 条件
|
||||
$$
|
||||
\alpha<\alpha'<1
|
||||
$$
|
||||
* 结论
|
||||
$$
|
||||
\varphi(x)也是一个显著性水平为\alpha'的检验函数
|
||||
$$
|
||||
* 条件
|
||||
$$
|
||||
\alpha=sup\{E_\theta(\varphi(x)),\theta\in\Theta\}
|
||||
$$
|
||||
* 结论
|
||||
@@ -113,3 +129,9 @@ $$
|
||||
> 本质上都是区间积分与值的关系。在概率分布函数图像中即面积和面积临界值的关系。
|
||||
|
||||
|
||||
### 对应关系说明
|
||||
> 将$\theta,W$分开理解,会比较好。但是一个题中如何分开看,如何将二者都计算出来。应该是$\theta$是个条件,$g(\theta)$势函数用来计算拒绝域与接受域的概率。
|
||||
* 假设检验:$H_0,H_1$(命题的划分,不一定包含所有的情况,并集不为全集)
|
||||
* 接受域拒绝域:$W^c,W$(样本空间的划分,反向定义,包含所有的情况,互补)
|
||||
* 检验统计量-检验临界值区分$c$(检验统计量的划分,与样本空间的接受域和拒绝域意义对应)
|
||||
* 置信度拒绝度:$1-\alpha,\alpha$(包含所有的情况,是一个琳结婚之,与检验临界值一一对应,在假设检验部分对应真实水平)
|
||||
@@ -12,9 +12,27 @@ H_0:\mu\geq\mu_0,&H_1:\mu<\mu_0
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
### 假设检验-z检验步骤
|
||||
> 关于假设检验,需要使用样本统计量和临界值对应样本空间的接受域和拒绝域。
|
||||
|
||||
1. 命题假设$H_0:\mu\in\Theta_0,H_1:\mu\in\Theta_1$
|
||||
2. 检验统计量$z=\frac{\overline{x}-\mu_0}{\sigma/\sqrt{n}}$
|
||||
3. 根据检验水平计算拒绝域的临界值$\\双侧检验W=\{(x_1,\dotsm,x_n:|z|\geq z_{1-\frac{\alpha}{2}}\}\\单侧检验W=\{(x_1,\dotsm,x_n:|z|\geq z_{1-\alpha}\}\\$
|
||||
这里也可以根据样本的值,计算此时的$\alpha$的真实水平。
|
||||
4. 计算样本的检验统计量的值,与拒绝域的临界值对比。
|
||||
|
||||
> 单侧检验和双侧检验的区分在于,检验统计量不等式的构建或者说拒绝域不同。
|
||||
|
||||
|
||||
## 2 单个总体-方差未知-均值检验
|
||||
|
||||
> 方差未知的时候,无法通过查表获得z检验的值,此时一半会这接给出样本的均值。
|
||||
### 假设检验-z检验步骤
|
||||
1. 命题假设$H_0:\mu\in\Theta_0,H_1:\mu\in\Theta_1$
|
||||
2. 检验统计量$z=\frac{\overline{x}-\mu_0}{\sigma/\sqrt{n}}$
|
||||
3. 根据检验水平计算拒绝域的临界值$\\双侧检验W=\{(x_1,\dotsm,x_n:|z|\geq z_{1-\frac{\alpha}{2}}\}\\单侧检验W=\{(x_1,\dotsm,x_n:|z|\geq z_{1-\alpha}\}\\$
|
||||
这里也可以根据样本的值,计算此时的$\alpha$的真实水平。
|
||||
4. 计算样本的检验统计量的值,与拒绝域的临界值对比。
|
||||
|
||||
## 3 单个总体-方差检验
|
||||
不同的单侧假设问题
|
||||
@@ -26,6 +44,14 @@ H_0:\sigma^2=\sigma^2_0,&H_1:\sigma^2<\sigma^2_0\\
|
||||
H_0:\sigma^2\geq\sigma^2_0,&H_1:\sigma^2<\sigma^2_0
|
||||
\end{aligned}
|
||||
$$
|
||||
> 一半会直接鬼畜样本的方差,这样不需要通过检验统计量+样本的值计算各个方差。
|
||||
### 假设检验$\chi^2$检验
|
||||
|
||||
1. 命题假设$H_0:\sigma^2\in\Theta_0,H_1:\sigma^2\in\Theta_1$
|
||||
2. 检验统计量$\chi^2=\frac{(n-1)S^2}{\sigma_0^2}$
|
||||
3. 根据检验水平计算拒绝域的临界值$\\双侧检验W=\{(x_1,\dotsm,x_n:\chi^2\leq\chi^2_{\frac{\alpha}{2}}\cup\chi^2\geq \chi^2_{1-\frac{\alpha}{2}}\}\\$
|
||||
4. 计算样本的检验统计量的值,与拒绝域的临界值对比。
|
||||
|
||||
|
||||
## 4 两个总体-均值相等
|
||||
|
||||
|
||||
37
概率论与数理统计/第25节 距离判别.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 距离判别
|
||||
|
||||
> 分类:数据集带标签
|
||||
> 聚类:无标签数据集
|
||||
|
||||
## 1 欧氏距离与马氏距离
|
||||
|
||||
### 定义
|
||||
* 判别分析:根据样品的观察值判定归属。
|
||||
* 距离判别原理:对距离进行规定,就近原则判定样品的归属。
|
||||
### 定义:欧氏距离
|
||||
$$
|
||||
d(x,y)=\sqrt{\sum_{i=1}^n(x_i-y_i)^2}
|
||||
$$
|
||||
> 缺点:指标的量纲不同,意义不同。距离会因各个指标单位的变化而改变
|
||||
|
||||
### 定义:马氏距离
|
||||
* 声明
|
||||
$$
|
||||
p元总体G的均值\mu和协方差矩阵\Sigma(\Sigma>0)
|
||||
$$
|
||||
|
||||
### 性质
|
||||
|
||||
|
||||
### 判别的优劣-回报法
|
||||
使用训练集检验判别的优劣
|
||||
### 判别的优劣-交叉验证法
|
||||
将带标签的数据分为两部分,训练集和测试集。
|
||||
|
||||
分成多份。分别计算f
|
||||
|
||||
### 判别的优劣-刀切法
|
||||
轮流剔除,得到多个模型,用被剔除的数据进行检验。统计误判率。
|
||||
## 2 两个总体的距离
|
||||
|
||||
## 3 多个总体的距离
|
||||
15
概率论与数理统计/第26节 Bayes判别.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bayes判别
|
||||
|
||||
## 1 错判风险ECM最小准则
|
||||
|
||||
|
||||
## 2 两个总体的bayes判别
|
||||
|
||||
### 定理:损失最小判别
|
||||
|
||||
* 声明
|
||||
$$
|
||||
总体G_1,G_2
|
||||
$$
|
||||
* 结论
|
||||
## 3 多个总体的bayes判别
|
||||
106
线性代数/0 线性代数概述.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# 线性代数
|
||||
线性代数究竟讲了个什么事情?线性方程组、向量、线性空间之间有什么关系?他们与矩阵有什么关系?为什么要在线性代数中讲到矩阵?
|
||||
### 1. 映射=函数=变换=算子(在不同领域的不同称呼)
|
||||
|
||||
通常我们说 变换(transformation)时,实际上指的是函数(function)f ,也成为一个算子或者映射,给它一定的输入,它会产生相应的输出。
|
||||
|
||||
在线性代数的场景中,变换(transformation)可以想象为输入某个向量,然后输出另一个向量的过程。
|
||||
### 线性方程、向量空间、线性空间关系
|
||||
|
||||
是同一个东西的不同表述。
|
||||
|
||||
线性方程的系数表示的输入向量,多组$[x_1,\cdots,x_n]$表示多组算子。$[y_1,y_2,\cdots,y_n]$表示变换后的结果。
|
||||
|
||||
向量空间。由多个线性无关的向量组成的向量组,称为向量空间。每一个向量表示一个算子。
|
||||
|
||||
线性空间。有多个线性无关的基底组成的线性空间。每一个基底表示一个算子。
|
||||
|
||||
### 线性变换的表示
|
||||
|
||||
一般来说,方阵能描述任意线性变换。线性变换,在一个线性空间中,将一个向量依次乘一组基底,则完成线性变换,得到另外一个向量。把一个平面想象为彼此间均匀且平行的网格,线性变换会让网格中的线条依然保持平行且均匀。
|
||||
$$
|
||||
[y_1,y_2,\cdots,y_n]^T=[a_1^T,a_2^T,\cdots,a_n^T]^T*[x_1,x_2,\cdots,x_n]^T\\
|
||||
其中a_i=[t_1,t_2,\cdots,t_n]是一个基底。
|
||||
$$
|
||||
|
||||
|
||||
### 线性变换的特点
|
||||
|
||||
线性变换保留了直线和平行线,但原点没有移动。线性变换保留直线的同时,其他的几何性质如长度、角度、面积和体积可能被变换改变了。从非技术意义上说,线性变换可能“拉伸”坐标系,但不会“弯曲”或“卷折”坐标系。
|
||||
1. 向量在变换后仍然是直线,不会被扭曲;
|
||||
2. 原点不会发生移动。
|
||||
|
||||
### 线性变换和线性映射的区别
|
||||
|
||||
线性映射( linear mapping)是从一个向量空间V到另一个向量空间W的映射且保持加法运算和数量乘法运算,而线性变换(linear transformation)是线性空间V到其自身的线性映射。
|
||||
|
||||
### 线性代数
|
||||
|
||||
每一组线性方程的值,每一组线性无关的向量,每一组基底,都可以构成一个矩阵,统一为一个算子。所以线性代数主要讲了两件事。什么是线性变换。如何用矩阵工具解决线性变换问题。
|
||||
|
||||
|
||||
|
||||
## 1 常见矩阵
|
||||
* 单位矩阵
|
||||
* 对角矩阵
|
||||
* (上下)三角矩阵
|
||||
* 伴随矩阵
|
||||
* 逆矩阵
|
||||
* 正交矩阵
|
||||
* 对称矩阵
|
||||
|
||||
## 2 矩阵计算
|
||||
* 加减
|
||||
* 数乘
|
||||
* 矩阵乘积
|
||||
* 行列式
|
||||
* 逆
|
||||
* 秩
|
||||
|
||||
## 3 矩阵变换
|
||||
> 明白矩阵变换的实际意义和矩阵变换前后保留的性质。
|
||||
### 初等变换
|
||||
* 对调
|
||||
* 数乘
|
||||
* 对调数乘
|
||||
|
||||
$$
|
||||
B=A
|
||||
$$
|
||||
|
||||
|
||||
### 相似变换
|
||||
$$
|
||||
P^{-1}AP=B
|
||||
$$
|
||||
|
||||
> 线性无关/自由度/独立性的描述
|
||||
> $$
|
||||
det A \not = 0\\
|
||||
矩阵的秩\\
|
||||
线性无关方程\\
|
||||
线性无关向量(正交是比线性无关更强的条件)\\
|
||||
线性无关空间\\
|
||||
> $$
|
||||
|
||||
|
||||
|
||||
> 矩阵表示
|
||||
> $$
|
||||
A=\left[\begin{array}{cccc}{a_{11}} & {a_{12}} & {\cdots} & {a_{1 n}} \\ {a_{21}} & {a_{22}} & {\cdots} & {a_{2 n}} \\ {\vdots} & {\vdots} & {\ddots} & {\vdots} \\ {a_{m 1}} & {a_{m 2}} & {\cdots} & {a_{m n}}\end{array}\right]
|
||||
> $$
|
||||
> $$
|
||||
A \cdot \vec{x}=
|
||||
\left(\begin{array}{c}
|
||||
{a_{11} x_{1}+a_{12} x_{2}+\cdots+a_{1 n} x_{n}}\\
|
||||
{a_{21} x_{1}+a_{22} x_{2}+\cdots+a_{2 n} x_{n}}\\
|
||||
{\vdots} \\
|
||||
{a_{m 1} x_{1}+a_{m 2} x_{2}+\cdots+a_{m n} x_{n}}
|
||||
\end{array}\right)
|
||||
> $$
|
||||
> $$
|
||||
A x=\lambda x
|
||||
> $$
|
||||
> $$
|
||||
A=P^{-1} B P
|
||||
> $$
|
||||
177
线性代数/1 矩阵行列式.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# 行列式
|
||||
|
||||
## 1 行列式与线性方程组
|
||||
|
||||
### 线性方程程组
|
||||
$$
|
||||
\begin{cases}
|
||||
a_{11}x_1+a_{12}x_2=b_1\\
|
||||
a_{21}x_1+a_{22}x_2=b_2
|
||||
\end{cases}\\
|
||||
$$
|
||||
|
||||
### 行列式含义
|
||||
|
||||
$$
|
||||
\begin{vmatrix}
|
||||
a_{11} & a_{12}\\
|
||||
a_{21} & a_{22}
|
||||
\end{vmatrix}
|
||||
= a_{11}a_{22}-a_{12}a_{21}
|
||||
\\
|
||||
\begin{vmatrix}
|
||||
a_{11} & a_{12} & a_{13}\\
|
||||
a_{21} & a_{22} & a_{23}\\
|
||||
a_{31} & a_{32} & a_{33}
|
||||
\end{vmatrix}\\
|
||||
= a_{11}a_{22}a_{33}+a_{12}a_{23}a_{31}+a_{13}a_{21}a_{32}\\
|
||||
-a_{12}a_{21}a_{33}-a_{11}a_{23}a_{32}-a_{13}a_{21}a_{32}
|
||||
$$
|
||||
|
||||
### 行列式表示线性方程组的解
|
||||
$$
|
||||
D = \begin{vmatrix}
|
||||
a_{11} & a_{12}\\
|
||||
a_{21} & a_{22}
|
||||
\end{vmatrix}
|
||||
|
||||
D_1=\begin{vmatrix}
|
||||
b_1 & a_{12}\\
|
||||
b_2 & a_{21}
|
||||
\end{vmatrix}
|
||||
|
||||
D_2=\begin{vmatrix}
|
||||
a_{11} & b_1\\
|
||||
a_{21} & b_2
|
||||
\end{vmatrix}\\
|
||||
|
||||
x_1=\frac{D_1}{D},x_2=\frac{D_2}{D}
|
||||
$$
|
||||
|
||||
## 2 全排类和逆序数
|
||||
### 全排列
|
||||
把n个不同的元素排成一列,成为全排列
|
||||
|
||||
### 逆序
|
||||
* 当两个元素的先后次序与标准次序不同时,则存在一个逆序。
|
||||
* 一个排列中所有逆序的总数,成为逆序数。
|
||||
* 逆序数为奇数的排列称为奇排列,逆序数为偶数的排列称为偶排列。
|
||||
|
||||
## 3 n阶行列式定义
|
||||
|
||||
### n阶行列式定义
|
||||
$$
|
||||
\begin{vmatrix}
|
||||
{a_{11}} & {a_{12}} & {\cdots} & {a_{1 n}} \\
|
||||
{a_{21}} & {a_{22}} & {\cdots} & {a_{2 n}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
{a_{m 1}} & {a_{m 2}} & {\cdots} & {a_{m n}}
|
||||
\end{vmatrix}
|
||||
=(-1)^ta_{1p_1}\cdots a_{np_n}
|
||||
$$
|
||||
t为逆序数。记作det(A)
|
||||
|
||||
### n阶行列式性质
|
||||
|
||||
* 对角行列式
|
||||
* 上(下)三角行列式与对角行列式的值相同。
|
||||
|
||||
## 4 对换
|
||||
### 定义:对换
|
||||
* 在排列中将任意两个元素对调,其余元素不变,称为对换。
|
||||
* 将相邻的两个元素对换,称为相邻对换。
|
||||
|
||||
### 定理:元素对换
|
||||
|
||||
一个排列中任意两个元素对换,奇偶性改变。奇排列变换为标准排列的对换次数为奇数,偶排列变为标准排列的对换次数是偶数。
|
||||
|
||||
## 5 行列式的性质
|
||||
|
||||
* 性质1:行列式与转置行列式相等。
|
||||
$$
|
||||
D=D^T
|
||||
$$
|
||||
* 性质2:互换行列式的两行(列),行列式变号。如果有两行或者两列完全相同,则行列式等于零。
|
||||
* 性质3:行列式乘一个数,等于行列式的某一行(列)乘这个数。行列式某一行(列)元素的公因子可以提取到行列式外。
|
||||
* 性质4:行列式中如果有两行成比例,则行列式等于零。
|
||||
* 性质5:如果第i行(列)元素都是两数之和,则行列式能够拆成第i行(列)不同的两个行列式之和。
|
||||
* 性质6:行列式的某一列,各个元素乘以同一个数,然后加到另一列上,行列式不变。
|
||||
$$
|
||||
\begin{vmatrix}
|
||||
{a_{11}} & {a_{12}} & {\cdots} & {a_{1 n}} \\
|
||||
{a_{21}} & {a_{22}} & {\cdots} & {a_{2 n}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
{a_{m 1}} & {a_{m 2}} & {\cdots} & {a_{m n}}
|
||||
\end{vmatrix}
|
||||
=
|
||||
\begin{vmatrix}
|
||||
{a_{11}} & {a_{12}} & {\cdots} & {a_{1 n}} \\
|
||||
{a_{21}} & {a_{22}} & {\cdots} & {a_{2 n}} \\
|
||||
{\vdots} & {\vdots} & {\vdots} & {\vdots} \\
|
||||
{a_{k1}}+ka_{i1} & {a_{k2}+ka_{i2}} & {\cdots} & {a_{kn}+ka_{in}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
{a_{m 1}} & {a_{m 2}} & {\cdots} & {a_{m n}}
|
||||
\end{vmatrix}
|
||||
$$
|
||||
## 6 行列式按行列展开
|
||||
### 定义:余子式
|
||||
在n阶行列式中,把(i,j)元素a(i,j)所在的第i行第j列划去 ,留下的n-1阶行列式,叫做(i,j)元素a(i,j)的代数余子式,记作$M_{ij}$。
|
||||
|
||||
代数余子式$A_{ij}=(-1)^{i+j}M_{ij}$
|
||||
|
||||
### 定理:余子式计算
|
||||
|
||||
一个n阶行列式,如果其中第i行所有元素除$a_{ij}$外都为零,那么行列式等于$a_{ij}$与它的代数余子式的成绩。
|
||||
$$
|
||||
D = a_{ij}A_{ij}
|
||||
$$
|
||||
|
||||
### 定理:行列式的余子式表示,行列式按行(列)展开法则
|
||||
|
||||
行列式等于它的任一行的各元素与对应的代数余子式乘积之和。即:
|
||||
$$
|
||||
D = a_{i1}A_{i1}+\cdots+a_{in}A_{in}
|
||||
$$
|
||||
|
||||
### 范德蒙行列式
|
||||
|
||||
$$
|
||||
D_n=
|
||||
\begin{vmatrix}
|
||||
{a_{11}} & {a_{12}} & {\cdots} & {a_{1 n}} \\
|
||||
{a_{21}} & {a_{22}} & {\cdots} & {a_{2 n}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
{a_{m 1}} & {a_{m 2}} & {\cdots} & {a_{m n}}
|
||||
\end{vmatrix}
|
||||
=
|
||||
\prod_{n\geq i>j\geq l}(x_i - x_j)
|
||||
$$
|
||||
|
||||
### 定理:行列式的其他展开
|
||||
|
||||
行列式某一行的元素与玲一行的对应元素的代数余子式乘积之和等于零。
|
||||
|
||||
## 7 克拉默法则
|
||||
### 定理:克拉默法则
|
||||
如果线性方程组的系数行列式不等于零,则方程组有唯一解。
|
||||
|
||||
### 定义:齐次方程组
|
||||
|
||||
线性方程组常数项不全为零时,称为非齐次线性方程组。常数项全为零时,叫做其次线性方程组。
|
||||
|
||||
### 定理:齐次方程组
|
||||
* 如果齐次方程组的系数行列式不等于零,则齐次线性方程组没有非零解。
|
||||
* 如果其次线性方程组有非零解,则它的系数行列式必为零。
|
||||
|
||||
|
||||
## 8 常见题型及解法
|
||||
|
||||
### 求行列式
|
||||
|
||||
* 暴力解
|
||||
* 利用点数余子式解
|
||||
|
||||
|
||||
### 解线性方程组
|
||||
|
||||
* 克拉默法则
|
||||
270
线性代数/2 矩阵基本运算.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# 矩阵及其运算
|
||||
|
||||
## 1 矩阵概念
|
||||
|
||||
### 定义:矩阵
|
||||
|
||||
$$
|
||||
A=\begin{bmatrix}
|
||||
{a_{11}} & {a_{12}} & {\cdots} & {a_{1 n}} \\
|
||||
{a_{21}} & {a_{22}} & {\cdots} & {a_{2 n}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
{a_{m 1}} & {a_{m 2}} & {\cdots} & {a_{m n}}
|
||||
\end{bmatrix}
|
||||
$$
|
||||
|
||||
* m行n列矩阵,$m \times n$矩阵,记作$A_{m\times n}$
|
||||
* 矩阵中的第i行第j列称为A的元素,记作$a_{ij}$
|
||||
|
||||
### 矩阵分类
|
||||
* 实矩阵、复矩阵:元素都是实数的矩阵称为实矩阵,元素是复数的矩阵称为复矩阵。
|
||||
* 方阵:m=n的矩阵称为n阶方阵。
|
||||
* 行列向量:只有一行的矩阵称为行向量,只有一列的矩阵称为列向量。记作
|
||||
$$
|
||||
A=(a_1,\cdots,a_n)\\
|
||||
B= \left(
|
||||
\begin{array}{c}
|
||||
b_1 \\
|
||||
\vdots\\
|
||||
b_n\\
|
||||
\end{array}
|
||||
\right)
|
||||
$$
|
||||
* 同型矩阵:行数、列数都相等。
|
||||
* 矩阵相等:同型矩阵,对应元素相等。
|
||||
* 零矩阵:元素都是零的矩阵称为零矩阵。
|
||||
* 对角矩阵:不在主对角线上的元素都是0。
|
||||
* 单位矩阵:主对角线上的元素都是1,不再主对角线上的元素都为零。
|
||||
> 矩阵与行列式说明:矩阵是一个数据,行列式是方阵的一个运算。
|
||||
|
||||
|
||||
### 线性变换与矩阵运算
|
||||
|
||||
* 线性变换
|
||||
$$
|
||||
y_1={a_{11} x_{1}+a_{12} x_{2}+\cdots+a_{1 n} x_{n}}\\
|
||||
y_2={a_{21} x_{1}+a_{22} x_{2}+\cdots+a_{2 n} x_{n}}\\
|
||||
{\vdots} \\
|
||||
y_n={a_{m 1} x_{1}+a_{m 2} x_{2}+\cdots+a_{m n} x_{n}}
|
||||
$$
|
||||
* 矩阵表示
|
||||
$$
|
||||
A=\begin{bmatrix}
|
||||
{a_{11}} & {a_{12}} & {\cdots} & {a_{1 n}} \\
|
||||
{a_{21}} & {a_{22}} & {\cdots} & {a_{2 n}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
{a_{m 1}} & {a_{m 2}} & {\cdots} & {a_{m n}}
|
||||
\end{bmatrix}
|
||||
$$
|
||||
$$
|
||||
X=(x_1,\cdots,x_n)^T\\
|
||||
Y=(y_1,\cdots,y_n)^T\\
|
||||
$$
|
||||
* 线性变换的矩阵表示
|
||||
$$
|
||||
Y=AX
|
||||
$$
|
||||
## 2 矩阵运算
|
||||
> 矩阵的加法与数乘是线性运算。阶数不会发生变化。
|
||||
> 矩阵是线性变换的一种表示形式。每一种矩阵运算都对应线性变换的一种变化。
|
||||
### 矩阵加法
|
||||
|
||||
同型矩阵A与B相加,对应位置的每个元素相加,记作$A+B$
|
||||
|
||||
$$
|
||||
A+B=\begin{bmatrix}
|
||||
{a_{11}+b_{11}} & {a_{12}+b_{12}} & {\cdots} & {a_{1n}+b_{1n}} \\
|
||||
{a_{21}+b_{21}} & {a_{22}+b_{22}} & {\cdots} & {a_{2 n}+b_{2 n}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
{a_{m 1}+b_{m 1}} & {a_{m 2}+b_{m 2}} & {\cdots} & {a_{m n}+b_{m n}}
|
||||
\end{bmatrix}
|
||||
$$
|
||||
|
||||
* $A+B=B+A$
|
||||
* (A+B)+C=A+(B+C)
|
||||
* 负矩阵$-A=(-a_{ij}$
|
||||
|
||||
### 矩阵数乘
|
||||
|
||||
实数$\lambda$与矩阵A的成绩记作$\lambda A 或 A\lambda$
|
||||
|
||||
$$
|
||||
\lambda A=\begin{bmatrix}
|
||||
\lambda {a_{11}} & \lambda {a_{12}} & {\cdots} & \lambda {a_{1n}} \\
|
||||
\lambda {a_{21}} & \lambda {a_{22}} & {\cdots} & \lambda {a_{2n}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
\lambda {a_{m1}} & \lambda {a_{m2}} & {\cdots} & \lambda {a_{mn}}
|
||||
\end{bmatrix}
|
||||
$$
|
||||
|
||||
* $(\lambda\mu)A=\lambda(\mu A)$
|
||||
* $(\lambda+\mu)A=\lambda A + \mu A$
|
||||
* $\lambda(A+B)=\lambda A+\lambda B$
|
||||
|
||||
### 矩阵乘法
|
||||
|
||||
矩阵$A_{m\times s},B_{s\times n}$。矩阵A,B的乘积是一个$m\times n$的矩阵$C_{m\times n}$
|
||||
$$
|
||||
C = AB
|
||||
$$
|
||||
> 关于维度的理解:一维是列向量,因为一维是向下在行的数量上拓展,列上不拓展。二维是在列的方向上拓展,列数增加。
|
||||
|
||||
* 不满足交换律$AB\neq BA$
|
||||
* $(AB)C=A(BC)$
|
||||
* $\lambda(AB)=(\lambda A)B=A(\lambda B)$
|
||||
* $A(B+C)=AB+AC$
|
||||
* $AI=IA=A$
|
||||
* 矩阵的幂:$A^{k+l}=A^{k}A^l$
|
||||
|
||||
|
||||
### 矩阵转置
|
||||
|
||||
将矩阵的行列互换,得到转置矩阵。
|
||||
$$
|
||||
A^T
|
||||
$$
|
||||
|
||||
* $(A^T)^T=A$
|
||||
* $(A+B)^T=A^T+B^T$
|
||||
* $(\lambda A)^T=\lambda(A)^T$
|
||||
* $(AB)^T=B^TA^T$
|
||||
|
||||
### 矩阵行列式
|
||||
|
||||
n阶方阵A所有的元素构成的行列式。称为方阵A的行列式。记作$|A|或\det A$
|
||||
|
||||
* $|A^T|\|A|$
|
||||
* $|\lambda A|=\lambda^nA$
|
||||
* $|AB|=|A||B|$
|
||||
* $det A = 0$奇异矩阵。$det A \not = 0$非奇异矩阵
|
||||
|
||||
行列式A的各个元素的代数余子式构成矩阵称为伴随矩阵。
|
||||
$$
|
||||
A^* = \begin{bmatrix}
|
||||
{A_{11}} & {A_{12}} & {\cdots} & {A_{1 n}} \\
|
||||
{A_{21}} & {A_{22}} & {\cdots} & {A_{2 n}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
{A_{m 1}} & {A_{m 2}} & {\cdots} & {A_{m n}}
|
||||
\end{bmatrix}
|
||||
$$
|
||||
|
||||
$$
|
||||
A^*A=AA^*=|A|E
|
||||
$$
|
||||
### 矩阵共轭
|
||||
当 $A=(a_{ij})$是复矩阵时,用$\overline{a_{ij}}$表示$a$的共轭复数
|
||||
|
||||
$$
|
||||
\overline{A}=(\overline{a}_{ij})
|
||||
$$
|
||||
* $\overline{A+B}=\overline{A}+\overline{B}$
|
||||
* $\overline{\lambda A}=\overline{\lambda}\cdot\overline{A}$
|
||||
* $\overline{AB}=\overline{A}\cdots\overline{B}$
|
||||
|
||||
### 转角公式
|
||||
|
||||
$$
|
||||
A=\begin{bmatrix}
|
||||
\cos \varphi & -\sin \varphi \\
|
||||
\sin \varphi & \cos \varphi
|
||||
\end{bmatrix}\\
|
||||
\overrightarrow{OP}=(x,y)^T\\
|
||||
|
||||
A\cdot\overrightarrow{OP}表示转过\varphi角度
|
||||
$$
|
||||
|
||||
其中转角公式具有如下性质
|
||||
|
||||
$$
|
||||
A^n = \begin{bmatrix}
|
||||
\cos n\varphi & -\sin n\varphi \\
|
||||
\sin n\varphi & \cos n\varphi
|
||||
\end{bmatrix}\\
|
||||
$$
|
||||
|
||||
## 2 矩阵的逆
|
||||
### 线性变换的逆变换与矩阵关系
|
||||
|
||||
### 定义:矩阵的逆
|
||||
n阶矩阵A,B如果:
|
||||
$$
|
||||
AB=BA=E
|
||||
$$
|
||||
A是可逆的,B是A的逆矩阵。
|
||||
|
||||
### 定理:行列式不为0
|
||||
若矩阵A可逆,则$|A|\not = 0$。若$|A|\not = 0$则矩阵A可逆。
|
||||
|
||||
$$
|
||||
A^{-1}=\frac{1}{|A|}A^*\\
|
||||
A^* 为伴随矩阵。
|
||||
$$
|
||||
|
||||
### 性质:矩阵的逆
|
||||
* $(A^{-1})^{-1}=A$
|
||||
* $(\lambda A)^{-1}=\frac{1}{\lambda}A^{-1}$
|
||||
* $(AB)^{-1}=B^{-1}A^{-1}$
|
||||
* $(A^T)^{-1}=(A^{-1})^T$
|
||||
|
||||
### 矩阵的相似变换
|
||||
|
||||
$$
|
||||
A^n = P B^n P^{-1}
|
||||
$$
|
||||
用来解决一下问题
|
||||
|
||||
$$
|
||||
\varphi(A)=a_0E + a_1 A^1+\dots+a_nA^n\\
|
||||
=P a_0E P^-1 + \dots + P a_n B^n P^{-1}\\
|
||||
=P(\varphi(B))P^{-1}
|
||||
$$
|
||||
|
||||
如果 B是对角阵,则
|
||||
$$
|
||||
B=diag(\lambda_1,\cdots,\lambda_n)\\
|
||||
B^k=diag(\lambda_1^k,\cdots,\lambda_n^k)
|
||||
$$
|
||||
|
||||
## 3 矩阵分块
|
||||
|
||||
$$
|
||||
A = \begin{bmatrix}
|
||||
{A_{11}} & {A_{12}} & {\cdots} & {A_{1 n}} \\
|
||||
{A_{21}} & {A_{22}} & {\cdots} & {A_{2 n}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
{A_{m 1}} & {A_{m 2}} & {\cdots} & {A_{m n}}
|
||||
\end{bmatrix}\\
|
||||
|
||||
B = \begin{bmatrix}
|
||||
{B_{11}} & {B_{12}} & {\cdots} & {B_{1 n}} \\
|
||||
{B_{21}} & {B_{22}} & {\cdots} & {B_{2 n}} \\
|
||||
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
|
||||
{B_{m 1}} & {B_{m 2}} & {\cdots} & {B_{m n}}
|
||||
\end{bmatrix}
|
||||
$$
|
||||
其中$A_{ij},B_{ij}$行列数相同,划分相同
|
||||
|
||||
### 性质:加法
|
||||
|
||||
$$
|
||||
A+B= (A_{ij}+B_{ij})
|
||||
$$
|
||||
### 性质:数乘
|
||||
$$
|
||||
\lambda A = (\lambda A_{ij})
|
||||
$$
|
||||
### 性质:乘积
|
||||
$$
|
||||
AB=(C_{ij})\\
|
||||
C_{ij}=\sum_{k=1}^sA_{ik}B_{kj}
|
||||
$$
|
||||
### 性质:转置
|
||||
$$
|
||||
A^T=((A_{ji})^T)
|
||||
$$
|
||||
|
||||
## 4 常见题型
|
||||
|
||||
### 求矩阵的逆
|
||||
* 定义法,通过伴随矩阵与矩阵的乘积
|
||||
* 初等变换法,通过初等变换,对角单位阵,得到矩阵的逆。
|
||||
48
线性代数/3 矩阵初等变换.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# 矩阵的初等变换
|
||||
|
||||
## 1 矩阵的初等变换
|
||||
|
||||
### 初等变换的定义
|
||||
|
||||
矩阵的初等行变换$A\sim^r B$、初等列变换$A\sim^c B$
|
||||
1. 对调两行
|
||||
2. 数乘某一行
|
||||
3. 某一行元素的k倍加到另外一行
|
||||
|
||||
初等行变换与初等列变换统称初等变换。记作$A\sim B$
|
||||
|
||||
### 初等变换的性质
|
||||
|
||||
1. 反身性$A \sim A$
|
||||
2. 对称性$A\sim B,B\sim A$
|
||||
3. 传递性$A\sim B,B\sim C,A\sim C$
|
||||
|
||||
### 初等变换的形式
|
||||
|
||||
* 行阶梯形式:阶梯型。
|
||||
* 行最简形式:每一行第一个非零元素为1,且该列其他元素为零。
|
||||
* 标准形式:行变换后,进行列变换,到达行最简形式,列最简形式。左上角单位阵
|
||||
$$
|
||||
F=\begin{bmatrix}
|
||||
E_r & 0\\
|
||||
0 & 0
|
||||
\end{bmatrix}_{m\times n}
|
||||
$$
|
||||
|
||||
### 初等变换的乘积表示
|
||||
|
||||
* $A\sim^r B$的充要条件存在m阶可逆矩阵P,使$PA = B$
|
||||
* $A\sim^c B$的充要条件存在n阶可逆矩阵Q,使$AQ = B$
|
||||
* $A\sim B$的充要条件存在m阶可逆矩阵P,存在n阶可逆矩阵Q,使$PAQ =B$
|
||||
|
||||
### 初等矩阵
|
||||
|
||||
由单位阵E经过一次初等变换得到的矩阵称为初等矩阵。
|
||||
|
||||
性质:
|
||||
* 对矩阵进行一次初等行变换,等价于左乘一个初等矩阵。对矩阵进行一次列变换,等价于右乘一个初等矩阵。
|
||||
* 矩阵可逆的充要条件,存在有限个初等矩阵$P_1,\cdots,P_n$使得$A=P_1\cdots P_n$
|
||||
* 方阵A可逆的充要条件是$A\sim^r E$
|
||||
|
||||
## 2 矩阵的秩
|
||||
|
||||
102
线性代数/4 向量空间.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# 向量
|
||||
|
||||
|
||||
## 7 向量运算
|
||||
|
||||
### 定义:向量内积
|
||||
$$
|
||||
x=(x_1,\cdots,x_n)^T\\
|
||||
y=(y_1,\cdots,y_n)^T\\
|
||||
[x,y]=x^Ty=x_1y_1+\cdots+x_ny_n
|
||||
$$
|
||||
[x,y]称为向量的内积。
|
||||
|
||||
### 性质:向量内积
|
||||
|
||||
1. $[x,y]=[y,x]$
|
||||
2. $\lambda[x,y]=[\lambda x,y]$
|
||||
3. $[x+y,z]=[x,z]+[y,z]$
|
||||
4. $x=\overrightarrow{0},=>[x,x]=0\\x \not =\overrightarrow{0},=>[x,x]\not =0$
|
||||
5. 施瓦茨不等式:$[x,y]^2\geq [x,x]+[y,y]$
|
||||
|
||||
### 定义:向量长度(范数)
|
||||
|
||||
$$
|
||||
||x||=\sqrt{[x,x]}=\sqrt{x_1^2+\cdots+x_n^2}
|
||||
$$
|
||||
|
||||
### 性质:向量长度
|
||||
|
||||
1. 非负性:$x=\overrightarrow{0},=>||x||=0\\x \not =\overrightarrow{0},=>||x||\not =0$
|
||||
2. 齐次性:$||\lambda x||=\lambda ||x||$
|
||||
3. 三角不等式:$||x+y||\leq ||x||+||y||$
|
||||
|
||||
### 性质:向量内积的几何意义
|
||||
* 向量内积表示一个向量在另一个向量上投影的积$[x,y]=||x||\cdot||y|| \cos \theta$
|
||||
* n维向量x,y的夹角:$\cos\theta = \frac{[x,y]}{||x||\cdot||y||}$
|
||||
|
||||
### 定义:正交向量
|
||||
|
||||
当n维向量x,y的夹角为90,即[x,y]=0时,称向量x,y正交
|
||||
|
||||
### 定理:线性无关向量与向量正交
|
||||
|
||||
若n为向量$a_1,a_2,\cdots,a_r$是一组两两正交的向量,则这组向量线性无关。
|
||||
|
||||
|
||||
### 定义:规范正交基
|
||||
|
||||
* 条件
|
||||
$$
|
||||
n维向量e_1,\cdots,e_r是向量空间V的一个基(线性无关)\\
|
||||
e_1,\cdots,e_r两两正交\\
|
||||
e_1,\cdots,e_r都是单位向量
|
||||
$$
|
||||
* 结论
|
||||
$$
|
||||
e_1,\cdots,e_r是向量空间V的一个规范正交基\\
|
||||
由一组基得到一组规范正交基的过程称为规范正交化。
|
||||
$$
|
||||
|
||||
### 定理:施密特正交化
|
||||
|
||||
1. 正交化
|
||||
$$
|
||||
每次减去与前一项交叉的部分。\\
|
||||
b_1 = a_1 \\
|
||||
b_2 = a_2 - \frac{[a_2,b_1]}{[b_1,b_1]}b_1\\
|
||||
\cdots\\
|
||||
b_n = a_n - \frac{[a_n,b_{n-1}]}{[b_{n-1},b_{n-1}]}b_{n-1}
|
||||
$$
|
||||
2. 规范化
|
||||
$$
|
||||
e_1 = \frac{b_1}{||b_1||}\\
|
||||
\cdots\\
|
||||
e_n = \frac{b_n}{||b_n||}
|
||||
$$
|
||||
|
||||
### 定义:正交矩阵
|
||||
|
||||
$$
|
||||
A^T\cdot A=E\\
|
||||
A\cdot A^T=E\\
|
||||
A^T=A^{-1}\\
|
||||
$$
|
||||
则称A为正交矩阵。
|
||||
|
||||
|
||||
### 性质:正交矩阵
|
||||
|
||||
1. A的列向量与行向量都是单位向量,且两两正交。
|
||||
2. 若A为正交矩阵,则$A^{-1},A^T$都是正交矩阵,且$det A = |A|=1$
|
||||
3. 若A与B为正交阵,则AB也为正交阵。
|
||||
|
||||
### 定义:正交变换
|
||||
|
||||
若P为正交矩阵,则$y=Px$称为正交变换。
|
||||
|
||||
### 性质:正交变换
|
||||
* ||y||=||x||
|
||||
|
||||
|
||||
|
||||
145
线性代数/5 矩阵相似变换.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# 矩阵相似变换
|
||||
|
||||
## 1 特征值和特征向量
|
||||
> 应用,方阵的对角化,解微分方程
|
||||
|
||||
### 定义:特征值和特征向量
|
||||
|
||||
* 声明
|
||||
|
||||
$$
|
||||
A是n阶矩阵\\
|
||||
\lambda 数\\
|
||||
x是n维向量
|
||||
$$
|
||||
* 条件
|
||||
**特征表达式**
|
||||
$$
|
||||
Ax=\lambda x
|
||||
$$
|
||||
* 结论
|
||||
$$
|
||||
\lambda 是矩阵A的特征值\\
|
||||
x是矩阵A的特征向量。
|
||||
$$
|
||||
### 性质:特征值特征向量
|
||||
* 同一个特征值的所有特征向量的非零线性组合,仍是特征向量。
|
||||
* 特征值的性质:
|
||||
$$
|
||||
\lambda_1+\cdots+\lambda_n=a_1+\cdots+a_n\\
|
||||
\lambda_1\cdots\lambda_n=|A|=det A
|
||||
$$
|
||||
|
||||
### 定理:特征值、特征向量、矩阵的线性变换
|
||||
|
||||
$$
|
||||
\lambda 是矩阵A的特征值,p是属于lambda的特征向量
|
||||
$$
|
||||
|
||||
* $k\lambda 是kA的特征值,p是kA属于k\lambda的特征向量$
|
||||
* $\lambda^k是A^k的特征值,p是A^k属于\lambda^k的特征向量$
|
||||
* $\frac{1}{\lambda}是A^{-1}的特征值$
|
||||
* $\varphi(A)是A的m次多项式,\varphi(\lambda)是\varphi(A)的特征值,p是\varphi(A)属于\varphi(\lambda)的特征向量$
|
||||
|
||||
### 计算:特征值和特征向量
|
||||
特征表达式的另一种表示方法
|
||||
$$
|
||||
(A-\lambda E)\overrightarrow{x}=\overrightarrow{0}
|
||||
$$
|
||||
|
||||
因为是有n个未知数的n个线性方程的齐次线性方程组,有零解的充要条件是系数行列式等于零。**特征方程**成立
|
||||
$$
|
||||
|A-\lambda E|=0
|
||||
$$
|
||||
含有一个未知数的高阶方程,解得有多个重根。每个重根对应一个特征向量。特征向量不唯一,需要转化为模长为1的向量。
|
||||
|
||||
### 定理:特征向量线性无关
|
||||
* 声明
|
||||
$$
|
||||
\lambda_1,\cdots,\lambda_m是m个特征值\\
|
||||
p_1,\cdots,p_m是m个特征向量\\
|
||||
$$
|
||||
* 条件
|
||||
$$
|
||||
\lambda_1,\cdots,\lambda_m各不相等
|
||||
$$
|
||||
* 结论
|
||||
$$
|
||||
p_1,\cdots,p_m线性无关
|
||||
$$
|
||||
|
||||
## 3 相似矩阵
|
||||
|
||||
### 定义:相似变换
|
||||
* 声明
|
||||
$$
|
||||
A,B是n阶矩阵\\
|
||||
P是可逆矩阵
|
||||
$$
|
||||
* 条件
|
||||
$$
|
||||
P^{-1}AP=B
|
||||
$$
|
||||
* 结论
|
||||
$$
|
||||
P^{-1}AP是对A的相似变换。\\
|
||||
B是A的\textbf{相似矩阵}\\
|
||||
P是\textbf{变换矩阵}
|
||||
$$
|
||||
|
||||
### 定理:相似变换特征不变性
|
||||
|
||||
若n阶矩阵A与B相似。则A,B的特征值和特征向量相同。
|
||||
|
||||
### 定理:相似对角化
|
||||
|
||||
若n阶矩阵A与对角阵$\Lambda$相似,则A的n个特征值就是对角阵的元素值。**特征值对角阵$\Lambda$**
|
||||
$$
|
||||
\Lambda=\begin{bmatrix}
|
||||
\lambda_1 &&&\\
|
||||
& \lambda_2&&\\
|
||||
&&\cdots&\\
|
||||
&&&\lambda_n
|
||||
\end{bmatrix}
|
||||
$$
|
||||
并且相似变换P是那个特征向量组成的特征矩阵。
|
||||
$$
|
||||
P=(p_1,p_2,\cdots,p_n)
|
||||
$$
|
||||
### 定理:相似对角化的充要条件
|
||||
|
||||
n阶矩阵A与特征值对角阵相似的充分必要条件,A有n个线性无关的特征向量。
|
||||
|
||||
若n阶矩阵A的n个特征值不相等,则A通过变换矩阵(特征向量矩阵)与特征值对角阵相似。
|
||||
|
||||
## 4 对称矩阵的对角化
|
||||
> 使用对称矩阵强化了相似对角化存在定理。简化相似对角的充分条件。
|
||||
### 定理:对称阵
|
||||
|
||||
对称阵的特征值为实数。
|
||||
|
||||
### 定理:对称阵特征向量正交
|
||||
|
||||
* 条件
|
||||
|
||||
$$
|
||||
\lambda_1,\lambda_2是对称阵A不相等的两个特征值。\\
|
||||
p_1,p_2是其对应的特征向量。
|
||||
$$
|
||||
* 结论
|
||||
|
||||
$$
|
||||
p_1,p_2正交
|
||||
$$
|
||||
|
||||
### 定理:对称阵特征对角矩阵存在
|
||||
|
||||
* 条件
|
||||
$$
|
||||
A 为对称阵,必有正交阵P,\\
|
||||
使得P^{-1}AP=P^TAP=\Lambda\\
|
||||
其中\Lambda是A中以n个特征值为对角元素的特征值对角阵。
|
||||
$$
|
||||
* 结论
|
||||
|
||||
|
||||
0
线性代数/6 线性空间.md
Normal file
125
计算机网络实验/16 综合组网原理.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# 综合组网实验
|
||||
|
||||
|
||||
## 1 网络需求分析
|
||||
|
||||
### 任务
|
||||
* 网络建设目标分析
|
||||
* 网络应用约束分析
|
||||
* 网络技术分析
|
||||
* 网络规格参数分析等
|
||||
|
||||
### 手段
|
||||
* 了解应用背景
|
||||
* 查询技术文档
|
||||
* 与客户交流
|
||||
|
||||
## 2 网络规划设计
|
||||
|
||||
## 指标的分析和评估
|
||||
* 网络的规模
|
||||
* 网络的结构
|
||||
* 网络管理
|
||||
* 网络的扩展
|
||||
* 网络安全
|
||||
* 外部网络的互联
|
||||
|
||||
### 分许报告
|
||||
* 网络的规模
|
||||
* 该方案的优点
|
||||
* 现有网络状况
|
||||
* 网络的运行方式
|
||||
* 安全性要求
|
||||
* 网络可提供的应用
|
||||
* 响应时间
|
||||
* 可靠性
|
||||
* 节点的分布
|
||||
* 扩展性
|
||||
|
||||
|
||||
## 3 网络系统设计
|
||||
|
||||
### 内容
|
||||
|
||||
* 网络系统需求:对网络需求进行分类
|
||||
* 网络体系结构的设计:传输方式、客户接口、服务器、网络划分、互联设备。使用体系结构图表示结果。
|
||||
* 网络拓扑结构设计:综合性、高可靠性、高性能、层次性、支持qos、安全性、扩展性、开放性、标准化、实用性。
|
||||
* 网络安全性设计;网络层安全、系统安全、客户安全、应用程序安全、数据安全。
|
||||
|
||||
|
||||
## 4 网络设备选型
|
||||
|
||||
### 主要设备
|
||||
|
||||
工作站、服务器、路由器、交换机/集线器、共享设备、网络适配器、加密设备、 UPS电源
|
||||
|
||||
### 选取原则
|
||||
* 采用的网络技术
|
||||
* 支持的网络应用
|
||||
* 设备在网络中的功能和所处位置
|
||||
|
||||
## 5 系统集成
|
||||
|
||||
* 系统逻辑结构图的设计
|
||||
* 项目及分包商的管理
|
||||
* 硬件和软件产品的采购
|
||||
* 开发环境的建立
|
||||
* 应用软件的开发
|
||||
* 应用系统的安装、测试、实施和培训
|
||||
|
||||
## 6 综合布线
|
||||
|
||||
### 作用
|
||||
* 网络的性能
|
||||
* 网络的投资
|
||||
* 网络的使用
|
||||
* 网络的维护
|
||||
|
||||
## 7 接入技术
|
||||
|
||||
### 主要技术
|
||||
* 基于双绞线的以太网接入技术
|
||||
* 基于双绞线的ADSL技术
|
||||
* 基于HFC网的CableModem技术
|
||||
* 光纤接入技术
|
||||
|
||||
|
||||
## 8 IP地址规划和子网划分
|
||||
|
||||
### 划分方式
|
||||
* 顺序分配
|
||||
* 按行政分配
|
||||
* 按地域分配
|
||||
* 按拓扑方式分配
|
||||
|
||||
### 分配原则
|
||||
* 管理便捷原则
|
||||
* 地域原则
|
||||
* 业务原则
|
||||
* 地址节省原则
|
||||
|
||||
## 9 路由设计
|
||||
|
||||
### 静态路由
|
||||
|
||||
### 动态路由
|
||||
包括:RIP协议,OSPF协议,BGP协议
|
||||
* 路由能在选取的各种IGP之间进行快速而简捷的切换
|
||||
* 尽量少的流量占用
|
||||
* 优先考虑适应能力和强壮性
|
||||
* 充分利用地址资源
|
||||
* 考虑选取能用于不同AS之间的协议
|
||||
* 使用路由策略控制路由的发布。
|
||||
|
||||
## 10 网络可靠性设计
|
||||
|
||||
### 设备本身可靠性
|
||||
冗余设计,双处理板、双交换网板、多个电源备份。
|
||||
### 链路备份
|
||||
* WAN链路备份
|
||||
* LAN链路备份:STP实现局域网链路备份,链路聚合实现备份
|
||||
* 路由协议备份
|
||||
### 路由备份
|
||||
|
||||
### 设备备份
|
||||
* VRRP,将一组多态路由器组成的虚拟路由器,称为备份组。
|
||||
271
计算机网络实验/17 综合组网实验.md
Normal file
@@ -0,0 +1,271 @@
|
||||
# 综合组网试验
|
||||
|
||||
## 1 总体规划设计
|
||||
|
||||
### 系统需求和设计目标
|
||||
6层楼约30个机房约1600多台计算机,为一般网络应用、监控、服务器、存储、信息发布、电子教室、中控和投影等多个系统提供网络平台
|
||||
|
||||
1. 将整个实验中心机房连成一个相对独立的局域网,保证互联互通、学生自由上机、正常上网、刷卡系统、网络服务器、考试系统的正常运行。
|
||||
2. 满足多媒体教学、流媒体教学的需要,保证音、视频的流畅播放,确保良好的服务质量。
|
||||
3. 网络的连通性完全可控,要求满足某些机房考试时禁止该机房访问互联网,而其他机房正常上课不受影响。
|
||||
4. 网络支持组播应用,能够满足机房管理软件等教学相关应用的需求。
|
||||
5. 网络设备支持抗ARP病毒攻击、广播风暴抑制、DHCP协议、IPv6协议等功能。
|
||||
6. 所有网络设备都要能够被实时监控和管理。
|
||||
|
||||
|
||||
### 总体规划
|
||||
|
||||
1. 信息平台网络采用TCP/IP体系结构,以满足与其他网络系统的互联互通。
|
||||
2. 分层次的方法划分网络
|
||||
3. 不同层次使用不同级别的千兆交换机,出口路由器采用中高端路由器
|
||||
4. 采用地址转换技术(NAT)规划网络。IP地址的划分采用每个机房一个网段。NAT采用基于端口的NAT-PT技术。申请至少128个公网地址的地址池。
|
||||
5. 采用ACL控制机房的访问
|
||||
6. 采用支持IPv6协议、DHCP协议、路由协议、组播协议及安全性高的设备。
|
||||
|
||||

|
||||
### 网络拓扑规划
|
||||
|
||||
|
||||

|
||||
|
||||
## 2 网络详细设计
|
||||
|
||||
### 2.1 网络拓扑设计
|
||||

|
||||
### 2.2 网络可靠性设计
|
||||
|
||||
* WAN链路备份
|
||||
* 用于为路由器的广域网接口提供备份(也可以用于局域网接口备份)
|
||||
* 主接口:路由器上的任意一个物理接口或子接口,以及逻辑通道(Dialer口除外)
|
||||
* 备份接口:当主接口出现故障时,多个备份接口可以根据配置的优先级来决定接替顺序;而且,备份接口具有分担负载功能
|
||||
* LAN链路备份
|
||||
* 使用二层交换机支持的STP协议、端口聚合技术等实现
|
||||

|
||||
* 路由备份
|
||||
* 动态路由协议能够自动发现路由,并生成路由表
|
||||
* 网络中有冗余路径,动态路由收敛需要时间、路由更新报文消耗网络资源等
|
||||

|
||||
|
||||
* 设备备份
|
||||
* VRRP(Virtual Router Redundancy Protocol,虚拟路由器冗余协议),一种LAN接入设备备份协议
|
||||
* 将局域网的一组多台路由器组织成一个虚拟路由器,称为备份组,优先级最高者为主用路由器,其余为备用
|
||||

|
||||
|
||||
### 2.3 设备选型
|
||||
|
||||
* 设备厂商选择
|
||||
* 接入层设备选型
|
||||
* 汇聚层设备选型
|
||||
* 核心层设备选型
|
||||
|
||||
|
||||
### 2.4 VLAN划分、网络地址、设备编号规划
|
||||
* VLAN划分
|
||||
* IP地址规划
|
||||
* 公网地址段: 115.25.141.129∽115.25.141.255/25
|
||||
* 私网地址段: 10.0.0.0/8网段
|
||||
* 对私网地址划分子网,每个实验室一个网段
|
||||
* 地址分配:地址中第二个字节代表楼层,第三个字节代表房间号,第四个字节表示其在房间中的位置编号
|
||||
|
||||
|
||||
* 网络设备采用统一编号:
|
||||
* 核心路由器以SR6602-n方式编号
|
||||
* 核心交换机编号为S7503E-core
|
||||
* 汇聚交换机以Fn-5800方式编号
|
||||
* 接入交换机以“F楼层号-房间号-设备型号-n”方式编号
|
||||
|
||||
### 2.5 路由设计
|
||||
|
||||
* 动态路由
|
||||
* 在拓扑图中的红色虚线标注区域,即各实验室内的接入交换机、各楼层的汇聚交换机F3-S5800、F4-S5800、F5-S5800、F6-S5800、F7-S5800、F8-S5800、核心交换机S7503E-core、核心路由器SR6602-1和SR6602-2的G0/0接口上配置OSPF动态路由协议
|
||||
|
||||
* 静态路由
|
||||
* 在出口路由器(即核心路由器)SR6602-1和SR6602-2上分别配置一条指向外部网络的默认路由
|
||||
|
||||
### 2.6 NAT地址转换与访问控制
|
||||
|
||||
* NAT地址转换
|
||||
* 115.25.141.128/25地址段中115.25.141.193-115.25.141.254/26用于公网地址,另外一段地址为其他服务器等设备使用
|
||||
* 保留私有地址段10.0.0.0/8作为内部IP地址
|
||||
* 在出口路由器SR6602-1和SR6602-2上配置NAT地址转换
|
||||
* 配置命令(包括5大条)
|
||||
```
|
||||
//配置地址池
|
||||
nat address-group 1 115.25.141.193 115.25.141.254
|
||||
//配置访问控制列表
|
||||
acl number 2001
|
||||
rule 0 permit source 10.0.0.0 0.255.255.255
|
||||
rule 1 deny
|
||||
//在路由器出接口上绑定地址池和ACL
|
||||
[interface e0/1]nat outbound 2001 address-group 1
|
||||
```
|
||||
* 访问控制
|
||||
* 通过ACL设置访问控制考试实验室访问Internet,参考命令如下:
|
||||
```
|
||||
acl number 2001//禁止403机房上网
|
||||
rule 0 deny source 10.4.3.0 0.0.0.255
|
||||
rule 1 permit source 10.0.0.0 0.255.255.255
|
||||
rule 2 deny
|
||||
```
|
||||
|
||||
### 2.7 网络管理设计
|
||||
* 在平台内值班室501房间的一台PC机上安装H3C Quidview网管软件,作为网管服务器
|
||||
* 所有接入交换机、汇聚交换机、核心交换机和核心路由器是被管设备,配置SNMP协议,并指定Trap报文发送到上面管理服务器的IP地址
|
||||
```
|
||||
这里以核心交换机S7503E-core为例:
|
||||
[S7503E-core]snmp-agent
|
||||
[S7503E-core]snmp sys version v1
|
||||
[S7503E-core]snmp com write private
|
||||
[S7503E-core]snmp com read public
|
||||
[S7503E-core]snmp trap enable
|
||||
[S7503E-core]snmp target-host trap address udp-domain 10.5.1.100 params securityname public
|
||||
```
|
||||
### 2.8 组播设计
|
||||
|
||||
* 根据需求分析可知,组播应用对网络的要求是:同一实验室内、同一楼层不同实验室机器之间、不同楼层的机器之间都能进行组播传输
|
||||
* 在各接入交换机、汇聚交换机、核心交换机的各接口上都配置了PIM DM组播路由协议
|
||||
* 以汇聚交换机F3-S5800为例的配置请见教程
|
||||
```
|
||||
[F3-S5800]multicast routing-enable
|
||||
[F3-S5800-]int vlan 30
|
||||
[F3-S5800-vlan-interface30]igmp enable
|
||||
[F3-S5800-vlan-interface30]pim dm
|
||||
[F3-S5800-]int vlan 301
|
||||
[F3-S5800-vlan-interface301]igmp enable
|
||||
[F3-S5800-vlan-interface301]pim dm
|
||||
[F3-S5800-]int vlan 302
|
||||
[F3-S5800-vlan-interface302]igmp enable
|
||||
[F3-S5800-vlan-interface302]pim dm
|
||||
[F3-S5800-]int vlan 303
|
||||
[F3-S5800-vlan-interface303]igmp enable
|
||||
[F3-S5800-vlan-interface303]pim dm
|
||||
[F3-S5800-]int vlan 304
|
||||
[F3-S5800-vlan-interface304]igmp enable
|
||||
[F3-S5800-vlan-interface304]pim dm
|
||||
|
||||
```
|
||||
### 2.9 网络布线与电源布线
|
||||
|
||||
* 网络布线
|
||||
* 电源布线及电源改造
|
||||
|
||||
|
||||
## 3 综合组网实验
|
||||

|
||||
### IP配置
|
||||
> 参考图
|
||||
|
||||
### VLAN划分
|
||||
> 参考图
|
||||
|
||||
### 路由实现
|
||||
* 在汇聚交换机、核心交换机、核心路由器上配置OSPF协议
|
||||
```
|
||||
# S2 S1所有端口启动OSPF,R1,R2内网端口启动OSPF
|
||||
router id 1.1.1.1
|
||||
ospf
|
||||
area 0
|
||||
netwrok 10.3.1.1 0.0.0.255
|
||||
network 10.3.2.1 0.0.0.255
|
||||
network 192.168.3.2 0.0.0.255
|
||||
```
|
||||
* 在路由器上配置到达外网的静态路由,并引入到OSPF协议当中
|
||||
```
|
||||
R1,R2配置前往外网的静态路由,并将静态路由引入到ospf协议当中。
|
||||
R1
|
||||
ip route-static 0.0.0.0 0.0.0.0 192.168.5.1
|
||||
[ospf]default-route-advertise cost 100
|
||||
R2
|
||||
ip route-static 0.0.0.0 0.0.0.0 192.168.5.1
|
||||
[ospf]default-route-advertise cost 200
|
||||
R1,R2引入默认路由S1,S2不需要配置默认路由
|
||||
```
|
||||
|
||||
### 可靠性实现
|
||||
|
||||
* 链路聚合+STP协议实现
|
||||
```
|
||||
stp enable
|
||||
|
||||
interface bridge-aggregation 1
|
||||
link-aggregation mode dynamic
|
||||
|
||||
interface Ethernet1/0/1
|
||||
port link-aggregation group 1
|
||||
|
||||
interface Ethernet1/0/2
|
||||
port link-aggregation group 1
|
||||
|
||||
inter bridge-aggregation 1
|
||||
port link-type trunk
|
||||
port trunk permit vlan all
|
||||
```
|
||||
* 设备备份VRRP实现
|
||||
```
|
||||
R1
|
||||
interface ethernet 0/0
|
||||
ip address 192.168.100.3 255.255.255.0
|
||||
vrrp vrid 11 virtual-ip 192.168.100.2
|
||||
|
||||
R2
|
||||
interface ethernet 0/0
|
||||
ip address 192.168.100.4 255.255.255.0
|
||||
vrrp vrid 11 virtual-ip 192.168.100.2
|
||||
vrrp vrid 11 priority 80
|
||||
```
|
||||
* 路由备份实现
|
||||
```
|
||||
[R1-OSPF-1]default-route-advertise cost 100
|
||||
# 将R1上的默认路由ip route-static 0.0.0.0 0.0.0.0 192.168.5.1引入OSPF
|
||||
[R2-OSPF-1]default-route-advertise cost 200
|
||||
|
||||
```
|
||||
### NAT实现
|
||||
```
|
||||
//配置访问控制列表
|
||||
acl number 2001
|
||||
rule 0 permit source 10.0.0.0 0.255.255.255
|
||||
rule 1 deny source any
|
||||
//配置地址池
|
||||
nat address-group 1
|
||||
address 192.168.5.140
|
||||
192.168.5.144
|
||||
//在路由器出接口上绑定地址池和ACL
|
||||
[interface e0/1]nat outbound 2001 address-group 1
|
||||
```
|
||||
### 访问控制列表
|
||||
```
|
||||
//禁止403机房上网
|
||||
acl number 2001
|
||||
rule 0 deny source 10.4.3.0 0.0.0.255
|
||||
rule 1 permit source 10.0.0.0 0.255.255.255
|
||||
rule 2 deny
|
||||
```
|
||||
### 网络管理应用
|
||||
```
|
||||
[S7503E-core]snmp-agent
|
||||
[S7503E-core]snmp sys version v1
|
||||
[S7503E-core]snmp com write private
|
||||
[S7503E-core]snmp com read public
|
||||
[S7503E-core]snmp trap enable
|
||||
[S7503E-core]snmp target-host trap address udp-domain 10.5.1.100 params securityname public
|
||||
```
|
||||
### 组播实现
|
||||
```
|
||||
[F3-S5800]multicast routing-enable
|
||||
[F3-S5800-]int vlan 30
|
||||
[F3-S5800-vlan-interface30]igmp enable
|
||||
[F3-S5800-vlan-interface30]pim dm
|
||||
[F3-S5800-]int vlan 301
|
||||
[F3-S5800-vlan-interface301]igmp enable
|
||||
[F3-S5800-vlan-interface301]pim dm
|
||||
[F3-S5800-]int vlan 302
|
||||
[F3-S5800-vlan-interface302]igmp enable
|
||||
[F3-S5800-vlan-interface302]pim dm
|
||||
[F3-S5800-]int vlan 303
|
||||
[F3-S5800-vlan-interface303]igmp enable
|
||||
[F3-S5800-vlan-interface303]pim dm
|
||||
[F3-S5800-]int vlan 304
|
||||
[F3-S5800-vlan-interface304]igmp enable
|
||||
[F3-S5800-vlan-interface304]pim dm
|
||||
```
|
||||
BIN
计算机网络实验/image/综合组网VRRP设备备份.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
计算机网络实验/image/综合组网分层图.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
计算机网络实验/image/综合组网动态路由备份.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
计算机网络实验/image/综合组网动态路由备份.png
Normal file
|
After Width: | Height: | Size: 230 KiB |
BIN
计算机网络实验/image/综合组网动态路由备份.png.jpg
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
计算机网络实验/image/综合组网拓扑图.png
Normal file
|
After Width: | Height: | Size: 772 KiB |
BIN
计算机网络实验/image/综合组网组网图.png
Normal file
|
After Width: | Height: | Size: 727 KiB |
BIN
计算机网络实验/image/综合组网网络详细拓扑.png
Normal file
|
After Width: | Height: | Size: 178 KiB |
BIN
计算机网络实验/image/综合组网链路备份.png
Normal file
|
After Width: | Height: | Size: 266 KiB |