Hexo


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 日程表

hadoop集群安装

发表于 2019-10-26 | 分类于 hadoop
字数统计: | 阅读时长 ≈

环境准备

  1. CentOS release 6.10
  2. hadoop2.8.0
  3. java-1.8.0-openjdk-devel-1.8.0.232.b09-1.el6_10.x86_64

节点部署图:

配置环境变量

/etc/profile

1
2
3
4
5
6
7
export HADOOP_HOME=/home/hadoop/hadoop-2.8.0
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
export HADOOP_MAPRED_HOME=${HADOOP_HOME}
export HADOOP_HDFS_HOME=${HADOOP_HOME}
export YARN_HOME=${HADOOP_HOME}
export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_HOME}/lib/native
export HADOOP_OPTS="-Djava.library.path=${HADOOP_HOME}/lib:${HADOOP_HOME}/lib/native"

安装jdk

修改主机名,关闭防火墙

配置免密登陆

同spark集群安装

hadoop分布式集群搭建

网络设置

发表于 2019-10-25 | 分类于 network
字数统计: | 阅读时长 ≈

网卡配置

配置网卡ifcfg-eth2

虚拟机配置eth2网卡,每次虚拟机重启不能自动获取ip,所以如下操作

1
2
3
4
5
6
7
8
9
/etc/sysconfig/network-scripts
cat ifcfg-eth22
DEVICE=eth2
HWADDR=08:00:27:d7:58:c8
TYPE=Ethernet
UUID=c89ca729-525a-40e4-93ec-ad073841c318
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=dhcp

linux 网卡配置详解 ifcfg-eth0

1
2
3
4
5
yum -y install NetworkManager
service NetworkManager status
service NetworkManager start
如果一直报NetworkManager 已死,但 pid 文件仍存,就直接reboot,
nmcli con

centos6 查看机器网卡uuid

spark初识

发表于 2019-10-24 | 分类于 spark
字数统计: | 阅读时长 ≈

spark背景

Spark是一个基于内存计算的开源的集群计算系统,目的是让数据分析更加快速,主要源自于MapReduce迭代式计算,交互式数据挖掘

Spark与Hadoop的对比

  • Spark的中间数据放到内存中,对于迭代运算效率更高。
  • Spark更适合于迭代运算比较多的ML和DM运算。因为在Spark里面,有RDD的抽象概念
  • Spark比Hadoop更通用。
  • Spark提供的数据集操作类型有很多种,不像Hadoop只提供了Map和Reduce两种操作。比如map, filter, flatMap, sample, groupByKey, reduceByKey, union,
    join, cogroup, mapValues, sort,partionBy等多种操作类型,Spark把这些操作称为Transformations。同时还提供Count, collect, reduce, lookup, save等多种actions操作。

什么是spark

SparkCore:将分布式数据抽象为弹性分布式数据集(RDD),实现了应用任务调度、RPC、序列化和压缩,并为运行在其上的上层组件提供API。
SparkSQL:Spark Sql 是Spark来操作结构化数据的程序包,可以让我使用SQL语句的方式来查询数据,Spark支持 多种数据源,包含Hive表,parquest以及JSON等内容。
SparkStreaming: 是Spark提供的实时数据进行流式计算的组件。
MLlib:提供常用机器学习算法的实现库。
GraphX:提供一个分布式图计算框架,能高效进行图计算。
BlinkDB:用于在海量数据上进行交互式SQL的近似查询引擎。
Tachyon:以内存为中心高容错的的分布式文件系统。

spark特点

CentOS安装Hadoop

参考文档

spark初识
spark官网
Spark 学习之 Spark 集群部署搭建(二)
Hadoop集群安装

spark安装

发表于 2019-10-24 | 分类于 spark
字数统计: | 阅读时长 ≈

spark安装

  • local
  • on yarn(on yarn模式就是将资源管理交给hadoop的yarn,自己本身只做计算与任务调度)
  • standalone(自己的资源管理与调度器)

standalone模式安装

构建一个由Master+Slave构成的Spark集群,Spark运行在集群中。
所有安装都必须要保证安装的环境一致,否则成功只能看运气
环境 系统:Centos6.10;3台虚拟机 软件:JDK1.8 + Spark2.4.4

1
2
3
4
|     Host       |   HostName    | Master | Slave |
| 100.80.128.34 | server01 | √ | √ |
| 100.80.128.253 | server02 | | √ |
| 100.80.128.168 | server03 | | √ |

虚拟机:
启动无窗口VirtualBox虚拟机 以便用远程桌面连接
虚拟机配置eth2网卡,开机不能自动获取ip

集群机器环境初始化

集群部署需要节点间互信才能启动所有节点的 Worker,互信的意思就是无需输入密码,只根据 hostname 就可以登录到其他节点上,遍历3个节点都进行配置

创建hadoop用户

使用hadoop单独用户操作数据,安全

1
2
3
4
5
6
7
8
# 创建hadoop用户
sudo adduser hadoop
passwd hadoop
# 创建组
sudo usermod -a -G hadoop hadoop
# 给hadoop用户增加sudo权限
vim /etc/sudoers
hadoop ALL=(ALL) ALL
修改主机名

spark配置文件中配置的是机器名

修改主机名(临时):
sudo hostname server01
修改主机名(永久)

1
2
3
4
5
6
[root@server01 ~]# cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=server01
[root@server01 ~]# cat /etc/hosts
127.0.0.1 localhost server01 localhost4 localhost4.localdomain4
::1 localhost server01 localhost6 localhost6.localdomain6
修改/ect/hosts文件

spark是根据域名来查找slave节点的,域名解析,所以需要单独配置hosts文件

1
2
3
100.80.128.253 server02
100.80.128.168 server03
100.80.128.34 server01
安装ssh, 配置开机启动,root远程访问
1
2
3
4
5
6
7
8
yum install openssh-server -y

vim /etc/ssh/sshd_config
RSAAuthentication yes
PubkeyAuthentication yes

service sshd restart
chkconfig sshd on #开机自启
配置ssh互信
1
2
3
4
5
6
// 生成公钥
ssh-keygen -t rsa
// 循环拷贝公钥,自己向自己也要拷贝
ssh-copy-id -i /home/hadoop/.ssh/id_rsa.pub hadoop@server01
ssh-copy-id -i /home/hadoop/.ssh/id_rsa.pub hadoop@server02
ssh-copy-id -i /home/hadoop/.ssh/id_rsa.pub hadoop@server03
关闭防火墙

spark的启动会开放一些端口(8080,4040),并且机器远程访问需要ssh(22),所以需要关闭防火墙

1
2
3
4
5
6
7
8
# 默认清空表中所有链的内容
sudo iptables -F
# 查看防火墙状态
sudo service iptables status
# 关闭防火墙(centos6操作)
sudo service iptables stop
# 设置开机不启动(centos6操作)
sudo chkconfig iptables off

安装jdk8

CentOS使用yum安装jdk

安装spark

下载地址

解压拷贝
1
2
3
4
5
tar -zxvf spark-2.4.4-bin-hadoop2.7.tgz

cd spark-2.4.4-bin-hadoop2.7/conf
cp slaves.template slaves
cp spark-env.sh.template spark-env.sh
修改slaves配置文件

server01将会是master,所以只配置这两个

1
2
server02
server03
修改spark-env.sh配置文件
1
2
3
4
5
6
7
8
9
10
# java环境变量
export JAVA_HOME=/java/jdk1.8.0_161
# spark集群master进程主机host,要用真实的IP地址,不能用/etc/hosts文件中配置的server01,否则在UI界面上看不到worker节点的信息
export SPARK_MASTER_HOST=100.80.128.177
# spark集群master的端口号
export SPARK_MASTER_PORT=7077
# worker数量
export SPARK_WORKER_CORES=3
# worker机器的内存设置
export SPARK_WORKER_MEMORY=1g

启动Spark在UI界面上看不到worker节点的信息

启动

启动集群

1
2
3
server01机器启动节点
start-all.sh
ps -ef | grep spark

使用

指定master,这样会使用spark集群
./bin/spark-shell --master spark://100.80.128.177:7077
不指定,则使用本机器spark
./bin/spark-shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[hadoop@server02 spark-2.4.4-bin-hadoop2.7]$ ./bin/spark-shell
19/10/25 18:02:04 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
Spark context Web UI available at http://server02:4040
Spark context available as 'sc' (master = local[*], app id = local-1571997739840).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.4.4
/_/

Using Scala version 2.11.12 (OpenJDK 64-Bit Server VM, Java 1.8.0_232)
Type in expressions to have them evaluated.
Type :help for more information.

scala> sc.textFile("LICENSE").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).collect
res0: Array[(String, Int)] = Array((Unless,3), (agree,1), (reproduce,,1), ((or,3), (org.scalanlp:breeze-macros_2.11,1), (org.iq80.snappy:snappy,1), (MERCHANTABILITY,,1), (However,,1), (been,2), (2-Clause,1), (appropriateness,1), (com.squareup.okio:okio,1), (direct,,1), (com.fasterxml.jackson.module:jackson-module-paranamer,1), (https://github.com/jax-rs,1), (9.,1), (com.esotericsoftware:minlog,1), (CSS,1), (-------------,1), (file,6), (org.scala-lang:scala-library,1), (file.,1), (harmless,1), (------------------------------------------------------------------------------------,2), (are,7), (2.,1), (part,4), (reproduction,,3), (alone,1), (different,1), (grant,1), (org.jodd:jodd-core,1), (io.fabric8:kubernetes-model,1), ("[]",1), (FITNESS,1), (be,5), (distribution,,1), (org.apache.xbean:x...
scala>

spark local模式搭建mac版本

Spark源码阅读

发表于 2019-10-24 | 分类于 spark
字数统计: | 阅读时长 ≈

Mac上配置IntelliJ IDEA的Spark源码阅读环境

Spark Standalone模式搭建

ansible使用坑

发表于 2019-10-24 | 分类于 ansible
字数统计: | 阅读时长 ≈

ansible shell 之运行后台程序

ansible shell 之运行后台程序

Scala知识点

发表于 2019-10-23 | 分类于 Scala
字数统计: | 阅读时长 ≈

Scala中的None,Nothing,Null,Nil,null,Unit

  • Nil是一个空的List,定义为List[Nothing],根据List的定义List[+A],所有Nil是所有List[T]的子类
  • None是一个object,是Option的子类型
  • null 是Null的实例,类似java中的null
  • Nothing是所有类型的子类,也是Null的子类。Nothing没有对象,但是可以用来定义类型
  • 空(Null)是一个trait
  • Unit,类似java中的void,不返回任何值的方法的类型

Nothing:

1
2
3
4
5
6
7
8
9
10
11
12
13
// List [Nothing]分配给对List [String]的引用。Nothing是String的子类,所以正确
scala> val emptyStringList:List[String] = List[Nothing]()
emptyStringList: List[String] = List()


scala> val emptyStringList:List[Int] = List[Nothing]()
emptyStringList: List[Int] = List()
//虽然Nothing是所有东西的子类,但它不是任何东西的`超类`,也没有 Nothing的实例,包括字符串“abc”。所以Nothing的任何集合都必须是空的
scala> val emptyStringList: List[String] = List[Nothing]("abc")
^
error: type mismatch;
found : String("abc")
required: Nothing

Scala中的None,Nothing,Null,Nil

scala不使用new关键字创建对象实例

Scala 解惑篇

SBT

发表于 2019-10-21 | 分类于 Scala
字数统计: | 阅读时长 ≈

sbt简介

sbt是类似ANT、MAVEN的构建工具,全称为Simple build tool,是Scala事实上的标准构建工具。

Mac 平台安装 SBT

Scala菜鸟教程

发表于 2019-10-21 | 分类于 Scala
字数统计: | 阅读时长 ≈

Scala 变量

变量vs常量

在 Scala 中,使用关键词 “var” 声明变量(可以修改),使用关键词 “val” 声明常量(不能修改)。

1
2
3
4
5
# 变量(可以修改)
var myVar: String = "hello"
myVar = "world"//可以修改
# 常量(不能修改)
val myVar: String = "hello"// 不能修改

变量类型声明

var VariableName : DataType [= Initial Value]

变量类型引用

Scala 中声明变量和常量不一定要指明数据类型,在没有指明数据类型的情况下,其数据类型是通过变量或常量的初始值推断出来的

1
2
var myVar = 10;
val myVal = "Hello, Scala!";

多个变量声明

1
2
val xmax, ymax = 100  // xmax, ymax都声明为100
val pa = (40,"Foo")

Scala 访问修饰符

分别有:private,protected,public,没有指定默认是public,

私有(Private)成员

Scala 中的 private 限定符,比 Java 更严格,在嵌套类情况下,外层类甚至不能访问被嵌套类的私有成员

1
2
3
4
5
6
7
8
9
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 类之内

保护(Protected)成员

在 scala 中,对保护(Protected)成员的访问比 java 更严格一些。因为它只允许保护成员在定义了该成员的的类的子类中被访问。而在java中,用protected关键字修饰的成员,除了定义了该成员的类的子类可以访问,同一个包里的其他类也可以进行访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package p {

class Super {
protected def sayHello() {
print("hello")
}
}

class Sun extends Super {
sayHello()
}

class Other {
(new Super).sayHello()
}

}

Other 对 f 的访问不被允许,因为 other 没有继承自 Super

公共(Public)成员

Scala中,如果没有指定任何的修饰符,则默认为 public。这样的成员在任何地方都可以被访问。

作用域保护

1
private[x] 或 protected[x]

这里的x指代某个所属的包、类或单例对象。如果写成private[x],读作”这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对像可见外,对其它所有类都是private。这种技巧在横跨了若干包的大型项目中非常有用,它允许你定义一些在你项目的若干子包中可见但对于项目外部的客户却始终不可见的东西。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Hello {

class World {
private var world: String = "xxxxx"

class A1 {
print(world)
}

}

class C1 extends World {
print(world)//异常
}
}

由于私有变量不能被继承,执行会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Hello {

class World {
private[Hello] var world: String = "xxxxx"

class A1 {
print(world)//正常
}

}

class C1 extends World {
print(world)
}

}

重新定义了world的作用域,就可以访问了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package scopeA {
class C1 {
private[scopeA] val scopeA_privateField = 1
protected[scopeA] val scopeA_protectedField = 2
private[C1] val c1_privateField = 3
protected[C1] val c1_protectedField = 4
private[this] val this_privateField = 5
protected[this] val this_protectedField = 6
}
class C2 extends C1 {
val field1 = scopeA_privateField
val field2 = scopeA_protectedField
// val field3 = c1_privateField // 错误
val field4 = c1_protectedField
// val field5 = this_privateField // 错误
val field6 = this_protectedField
}
}
package scopeB {
class C3 extends scopeA.C1 {
// val field1 = scopeA_privateField // 错误
val field2 = scopeA_protectedField
// val field3 = c1_privateField // 错误
val field4 = c1_protectedField
// val field5 = this_privateField // 错误
val field6 = this_protectedField
}
}

Scala 为用户提供了一些额外方法,以帮助用户以更小的粒度对可见性的作用域进行调整。从这一点看,Scala 超过了大多数的语言。Scala 提供了作用域内私有(scoped private)可见性声明和作用域内受保护(scoped protected)可见性声明。请注意,在具有继承关系的情况下,`对类成应用这两类可见性后表现不同。但除此之外,这两类可见性的表现完全一致,因此在同一个作用域内,私有可见性可以和受保护可见性交换使用。

Scala 可见性

Scala 运算符

符号 描述
/ 除号
% 取余
&& 逻辑与
`
! 逻辑非
>>> 无符号右移
>> 右移

右移与无符号右移区别:

  • 右移>> :该数对应的二进制码整体右移,左边的用原有标志位补充,右边超出的部分舍弃。
  • 无符号右移>>> :不管正负标志位为0还是1,将该数的二进制码整体右移,左边部分总是以0填充,右边部分舍弃

运算符优先级
Scala 运算符

操作符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
scala> "A"::"B"::Nil
res0: List[String] = List(A, B)

scala> "A"+:"B"+:Nil
res1: List[String] = List(A, B)

scala> Nil:+"A":+"B"
res2: List[String] = List(A, B)

scala> res0 ++ res1
res3: List[String] = List(A, B, A, B)

scala> res0 ::: res1
res4: List[String] = List(A, B, A, B)

scala> res0 :: res1
res5: List[java.io.Serializable] = List(List(A, B), A, B)

scala中:: , +:, :+, :::, +++的区别

Scala 方法与函数

Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象。
Scala 中使用 val 语句可以定义函数,def 语句定义方法。

1
2
3
4
class Test{
def m(x: Int) = x + 3
val f = (x: Int) => x + 3
}

如果方法没有返回值,可以返回为 Unit,这个类似于 Java 的 void, 实例如下:

1
2
3
4
5
object Hello{
def printMe( ) : Unit = {
println("Hello, Scala!")
}
}

函数

Scala 函数传名调用(call-by-name)

Scala的解释器在解析函数参数(function arguments)时有两种方式:

  • 传值调用(call-by-value):先计算参数表达式的值,再应用到函数内部;
  • 传名调用(call-by-name):将未计算的参数表达式直接应用到函数内部

在进入函数内部前,传值调用方式就已经将参数表达式的值计算完毕,而传名调用是在函数内部进行参数表达式的值计算的。这就造成了一种现象,每次使用传名调用时,解释器都会计算一次表达式的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
object Test {
def main(args: Array[String]) {
delayed(time());
}

def time() = {
println("获取时间,单位为纳秒")
System.nanoTime
}

def delayed(t: => Long) = {
println("在 delayed 方法内")
println("参数: " + t)
print(t)
}
}
# 结果
在 delayed 方法内
获取时间,单位为纳秒
参数: 27696238732400
获取时间,单位为纳秒
27696238800842

Scala 指定函数参数名

我们也可以通过指定函数参数名,并且不需要按照顺序向函数传递参

1
2
3
4
5
6
7
8
9
object Test {
def main(args: Array[String]) {
printInt(b=5, a=7);
}
def printInt( a:Int, b:Int ) = {
println("Value of a : " + a );
println("Value of b : " + b );
}
}

Scala 函数 - 可变参数

Scala 通过在参数的类型之后放一个星号来设置可变参数(可重复的参数)

1
2
3
4
5
6
7
8
9
10
11
12
object Test {
def main(args: Array[String]) {
printStrings("Runoob", "Scala", "Python");
}
def printStrings( args:String* ) = {
var i : Int = 0;
for( arg <- args ){
println("Arg value[" + i + "] = " + arg );
i = i + 1;
}
}
}

Scala 递归函数

Scala 函数 - 默认参数值

Scala 可以为函数参数指定默认参数值,使用了默认参数,你在调用函数的过程中可以不需要传递参数,这时函数就会调用它的默认参数值,如果传递了参数,则传递值会取代默认值

1
2
3
4
5
6
7
8
9
10
11
object Test {
def main(args: Array[String]) {
println( "返回值 : " + addInt() );
}
def addInt( a:Int=5, b:Int=7 ) : Int = {
var sum:Int = 0
sum = a + b

return sum
}
}

Scala 高阶函数

Scala 中允许使用高阶函数, 高阶函数可以使用其他函数作为参数

1
2
3
4
5
6
7
8
9
10
11
12
object Test {
def main(args: Array[String]) {

println( apply( layout, 10) )

}
// 函数 f 和 值 v 作为参数,而函数 f 又调用了参数 v
def apply(f: Int => String, v: Int) = f(v)

def layout[A](x: A) = "[" + x.toString() + "]"

}

Scala 函数嵌套

我们可以在 Scala 函数内定义函数,定义在函数内的函数称之为局部函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
object Test {
def main(args: Array[String]) {
println( factorial(0) )
println( factorial(1) )
println( factorial(2) )
println( factorial(3) )
}

def factorial(i: Int): Int = {
def fact(i: Int, accumulator: Int): Int = {
if (i <= 1)
accumulator
else
fact(i - 1, i * accumulator)
}
fact(i, 1)
}
}

Scala 匿名函数

1
var inc = (x:Int) => x+1

Scala 偏应用函数

Scala 偏应用函数是一种表达式,你不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.Date

object Test {
def main(args: Array[String]) {
val date = new Date
val logWithDateBound = log(date, _ : String)

logWithDateBound("message1" )
Thread.sleep(1000)
logWithDateBound("message2" )
Thread.sleep(1000)
logWithDateBound("message3" )
}

def log(date: Date, message: String) = {
println(date + "----" + message)
}
}
Scala 函数柯里化(Currying)

闭包

闭包出现是因为lexical scope,闭包是由函数和环境组成,Scala应该支持函数作为参数或返回值,这时如果没有闭包,那么函数的free 变量就会出错

闭包源于λ表达式,它的概念核心分为两块,1.上下文环境 2.控制流程。进一步地说,闭包是绑定了自由变量的函数实例。通常来讲,闭包地实现机制是定义一个特殊的数据结构,保存了函数地址指针与闭包创建时的函数的词法环境以及绑定自由变量。对于闭包最好的解释,莫过于《流程的Python》里给出的“它是延伸了作用域的函数,其中包括函数定义体引用,但是不在定义体定义的非全局变量。核心在于闭包能够访问定义体之外定义的非全局变量。

闭包 = 代码 + 用到的非局部变量

1
2
3
4
5
6
scala> var more =1
more: Int = 1
scala> val addMore = (x:Int) => x + more
addMore: Int => Int = <function1>
scala> addMore (100)
res1: Int = 101

它“捕获”自身的自由变量(more)从而“闭合”该匿名函数

在Scala里“捕获”的是变量本身,而不是变量本身引用的值。

1
2
3
4
5
scala> more = 100
more: Int = 100

scala> add(2)
res2: Int = 102

当然,反过来也是成立的,闭包也可以修改其自由变量

1
2
3
4
5
6
7
scala> val minusOne = (x:Int) => {more = more - x}
minusOne: Int => Unit = <function1>

scala> minusOne(1)

scala> more
res4: Int = 99

那么问题来了,如果more这个变量随着程序的运行被修改了很多次,那么闭包会选择哪一个呢?Scala的答案是,闭包被创建时这个变量最新的那个。(根据定义函数的词法作用域计算自由变量)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
scala> def Increase(more:Int) = (x:Int) => x + more
Increase: (more: Int)Int => Int

scala> val Inc1 = Increase(1)
Inc1: Int => Int = <function1>

scala> val Inc9 = Increase(9)
Inc9: Int => Int = <function1>

scala> Inc1(10)
res5: Int = 11

scala> Inc9(10)
res6: Int = 19

闭包
Python和Scala里的闭包

Scala 字符串

  1. 在 Scala 中,字符串的类型实际上是 Java String,它本身没有 String 类
  2. String 对象是不可变的,如果你需要创建一个可以修改的字符串,可以使用 String Builder 类
    1
    2
    3
    4
    5
    6
    7
    8
    object Test {
    def main(args: Array[String]) {
    val buf = new StringBuilder;
    buf += 'a'
    buf ++= "bcdef"
    println( "buf is : " + buf.toString );
    }
    }

Scala 数组

声明数组

1
2
var z:Array[String] = new Array[String](3)
var z = new Array[String](3)

赋值

1
2
z(0) = "Runoob"; z(1) = "Baidu"; z(2) = "Google"
var z = Array("Runoob", "Baidu", "Google")

数组遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
object Closures {
def main(args: Array[String]): Unit = {
val myList = Array(1, 2, 3, 4, 5)
for (x <- myList) {
println(x)
}
var total: Int = 0
for ( i <- myList.indices) {
total += myList(i)
}
println("总和为 " + total)
}
}

多维数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import scala.Array._

object Closures {
def main(args: Array[String]): Unit = {
val 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) {
println(myMatrix(i)(j))
}
}
}
}

Scala Collection

Scala 集合分为可变的和不可变的集合

  • 可变集合可以在适当的地方被更新或扩展。这意味着你可以修改,添加,移除一个集合的元素。
  • 不可变集合类,相比之下,永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变
1
2
3
4
5
val x = List(1, 3, 4, 5)
val y = Set(1, 3, 4, 5)
val z = Map("one" -> 1, "two" -> 2, "three" -> 3)
val w = (10, "rexxx")
var t: Option[Int] = Some(5)

Scala Iterator(迭代器)

Scala Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法。迭代器 it 的两个基本操作是 next 和 hasNext。

模式匹配

语法:

1
2
3
4
5
6
7
8
9
import scala.util.Random

val x: Int = Random.nextInt(10)
x match {
case 0 => "zero"
case 1 => "one"
case 2 => "two"
case _ => "other"
}

模式匹配

javap命令
Scala 教程

伴生对象

发表于 2019-10-20 | 分类于 Scala
字数统计: | 阅读时长 ≈

start

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 编写Hello.scala
/** 1. object表示一个伴生对象,可以理解就是一个对象
* 2. Hello就是对象名字,它底层真正对应的类名是Hello$,对象Hello$类型的一个静态对象MODULE$
* 3. 当我们编写一个object底层会生成
* */
object Hello {
def main(args: Array[String]): Unit = {
print("hello world")
}
}

# 编译Hello.scala
scalac Hello.scala
# 生成如下
Hello$.class Hello.class Hello.scala
# 安装jd-gui
brew cask install jd-gui
# 反编译Hello$.class
public final class Hello$ { public static final Hello$ MODULE$ = new Hello$();
public void main(String[] args) { // Byte code:
// 0: getstatic scala/Predef$.MODULE$ : Lscala/Predef$;
// 3: ldc 'hello world'
// 5: invokevirtual print : (Ljava/lang/Object;)V
// 8: return
// Line number table:
// Java source line number -> byte code offset
// #3 -> 0
// Local variable table:
// start length slot name descriptor
// 0 9 0 this LHello$;
// 0 9 1 args [Ljava/lang/String;
}
}

# 反编译Hello.class
import scala.reflect.ScalaSignature;

@ScalaSignature(bytes = "\006\005%:Q\001B\003\t\002!1QAC\003\t\002-AQAE\001\005\002MAQ\001F\001\005\002U\tQ\001S3mY>T\021AB\001\by\025l\007\017^=?\007\001\001\"!C\001\016\003\025\021Q\001S3mY>\034\"!\001\007\021\0055\001R\"\001\b\013\003=\tQa]2bY\006L!!\005\b\003\r\005s\027PU3g\003\031a\024N\\5u}Q\t\001\"\001\003nC&tGC\001\f\032!\tiq#\003\002\031\035\t!QK\\5u\021\025Q2\0011\001\034\003\021\t'oZ:\021\0075ab$\003\002\036\035\t)\021I\035:bsB\021qD\n\b\003A\021\002\"!\t\b\016\003\tR!aI\004\002\rq\022xn\034;?\023\t)c\"\001\004Qe\026$WMZ\005\003O!\022aa\025;sS:<'BA\023\017\001")
public final class Hello {
public static void main(String[] paramArrayOfString) {
Hello$.MODULE$.main(paramArrayOfString);
}
}
1…5678
John Doe

John Doe

78 日志
26 分类
27 标签
© 2019 John Doe | Site words total count:
本站访客数:
|
博客全站共字
|
主题 — NexT.Mist v5.1.4