Spark入门实战系列--2.Spark编译与部署(下)--Spark编译安装
2015-08-12 23:13
911 查看
【注】该系列文章以及使用到安装包/测试数据 可以在《倾情大奉送–Spark入门实战系列》获取
1 编译Spark
Spark可以通过SBT和Maven两种方式进行编译,再通过make-distribution.sh脚本生成部署包。SBT编译需要安装git工具,而Maven安装则需要maven工具,两种方式均需要在联网下进行,通过比较发现SBT编译速度较慢(原因有可能是1、时间不一样,SBT是白天编译,Maven是深夜进行的,获取依赖包速度不同 2、maven下载大文件是多线程进行,而SBT是单进程),Maven编译成功前后花了3、4个小时。
1.1 编译Spark(SBT)
1.1.1 安装git并编译安装
1.从如下地址下载git安装包
http://www.onlinedown.net/softdown/169333_2.htm
https://www.kernel.org/pub/software/scm/git/
如果linux是CentOS操作系统可以通过:yum install git直接进行安装
由于从https获取内容,需要安装curl-devel,可以从如下地址获取
http://rpmfind.net/linux/rpm2html/search.php?query=curl-devel
如果linux是CentOS操作系统可以通过:yum install curl-devel直接进行安装
2.上传git并解压缩
把git-1.7.6.tar.gz安装包上传到/home/hadoop/upload目录中,解压缩然后放到/app目录下
3.编译安装git
以root用户进行在git所在路径编译安装git
4.把git加入到PATH路径中
打开/etc/profile把git所在路径加入到PATH参数中
重新登录或者使用source /etc/profile使参数生效,然后使用git命令查看配置是否正确
1.1.2 下载Spark源代码并上传
1.可以从如下地址下载到spark源代码:
http://spark.apache.org/downloads.html
http://d3kbcqa49mib13.cloudfront.net/spark-1.1.0.tgz
git clone https://github.com/apache/spark.git
把下载好的spark-1.1.0.tgz源代码包使用1.1.3.1介绍的工具上传到/home/hadoop/upload 目录下
2.在主节点上解压缩
3.把spark-1.1.0改名并移动到/app/complied目录下
1.1.3 编译代码
编译spark源代码的时候,需要从网上下载依赖包,所以整个编译过程机器必须保证在联网状态。编译执行如下脚本:
整个编译过程编译了约十几个任务,重新编译N次,需要几个甚至十几个小时才能编译完成(主要看下载依赖包的速度)。
1.2 编译Spark(Maven)
1.2.1 安装Maven并配置参数
在编译前最好安装3.0以上版本的Maven,在/etc/profile配置文件中加入如下设置:
1.2.2 下载Spark源代码并上传
1.可以从如下地址下载到spark源代码:
http://spark.apache.org/downloads.html
http://d3kbcqa49mib13.cloudfront.net/spark-1.1.0.tgz
git clone https://github.com/apache/spark.git
把下载好的spark-1.1.0.tgz源代码包使用1.1.3.1介绍的工具上传到/home/hadoop/upload 目录下
2.在主节点上解压缩
3.把spark-1.1.0改名并移动到/app/complied目录下
1.2.3 编译代码
编译spark源代码的时候,需要从网上下载依赖包,所以整个编译过程机器必须保证在联网状态。编译执行如下脚本:
整个编译过程编译了约24个任务,整个过程耗时1小时45分钟。
1.3 生成Spark部署包
在Spark源码根目录下有一个生成部署包的脚本make-distribution.sh,可以通过执行如下命令进行打包 ./make-distribution.sh [–name] [–tgz] [–with-tachyon]
例子:
1.生成支持yarn 、hadoop2.2.0 、hive 的部署包:
2.生成支持yarn 、hadoop2.2.0 、hive 、ganglia 的部署包:
1.3.1 生成部署包
使用如下命令生成Spark部署包,由于该脚本默认在JDK1.6进行,在开始时会进行询问是否继续,只要选择Y即可
生成Spark部署包编译了约24个任务,用时大概1小时38分钟。
1.3.2 查看生成结果
生成在部署包位于根目录下,文件名类似于spark-1.1.0-bin-2.2.0.tgz。
2 安装Spark
2.1 上传并解压Spark安装包
1.我们使用上一步骤编译好的spark-1.1.0-bin-2.2.0.tgz文件作为安装包(也可以从网上下载native文件夹或者打包好的64位hadoop安装包),使用” Spark编译与部署(上)”中1. 3.1介绍的工具上传到/home/hadoop/upload 目录下
2.在主节点上解压缩
3.把spark改名并移动到/app/hadoop目录下
2.2 配置/etc/profile
1.打开配置文件/etc/profile
2.定义SPARK_HOME并把spark路径加入到PATH参数中
2.3 配置conf/slaves
1.打开配置文件conf/slaves
2.加入slave配置节点
2.4 配置conf/spark-env.sh
1.打开配置文件conf/spark-env.sh
2.加入Spark环境配置内容,设置hadoop1为Master节点
2.5 向各节点分发Spark程序
1.进入hadoop1机器/app/hadoop目录,使用如下命令把spark文件夹复制到hadoop2和hadoop3机器
2.在从节点查看是否复制成功
2.6 启动Spark
2.7 验证启动
此时在hadoop1上面运行的进程有:Worker和Master
此时在hadoop2和hadoop3上面运行的进程有只有Worker
通过 netstat -nlt 命令查看hadoop1节点网络情况
在浏览器中输入 http://hadoop1:8080(需要注意的是要在网络设置中把hadoop*除外,否则会到外网DNS解析,出现无法访问的情况) 既可以进入Spark集群状态页面
2.8 验证客户端连接
进入hadoop1节点,进入spark的bin目录,使用spark-shell连接集群
在命令中只指定了内存大小并没有指定核数,所以该客户端将占用该集群所有核并在每个节点分配500M内存
3 Spark测试
3.1 使用Spark-shell测试
这里我们测试一下在Hadoop中大家都知道的WordCout程序,在MapReduce实现WordCout需要Map、Reduce和Job三个部分,而在Spark中甚至一行就能够搞定。下面就看一下是如何实现的:
3.1.1 启动HDFS
通过jps观察启动情况,在hadoop1上面运行的进程有:NameNode、SecondaryNameNode和DataNode
hadoop2和hadoop3上面运行的进程有:NameNode和DataNode
3.1.2 上传数据到HDFS中
把hadoop配置文件core-site.xml文件作为测试文件上传到HDFS中
3.1.3 启动Spark
3.1.4 启动Spark-shell
在spark客户端(这里在hadoop1节点),使用spark-shell连接集群
3.1.5 运行WordCount脚本
下面就是WordCount的执行脚本,该脚本是scala编写,以下为一行实现:
为了更好看到实现过程,下面将逐行进行实现:
词频统计结果如下:
Array[(String, Int)] = Array((“”,100), (the,7), (,6), (,6), (under,3), (in,3), (License,3), (this,2), (–>,2), (file.,2))
3.1.6 观察运行情况
通过http://hadoop1:8080查看Spark运行情况,可以看到Spark为3个节点,每个节点各为1个内核/512M内存,客户端分配3个核,每个核有512M内存。
通过点击客户端运行任务ID,可以看到该任务在hadoop2和hadoop3节点上运行,在hadoop1上并没有运行,主要是由于hadoop1为NameNode和Spark客户端造成内存占用过大造成
3.2 使用Spark-submit测试
从Spark1.0.0开始,Spark提供了一个易用的应用程序部署工具bin/spark-submit,可以完成Spark应用程序在local、Standalone、YARN、Mesos上的快捷部署。该工具语法及参数说明如下:
3.2.1 运行脚本1
该脚本为Spark自带例子,在该例子中个计算了圆周率π的值,以下为执行脚本:
参数说明(详细可以参考上面的参数说明):
3.2.2 观察运行情况
通过观察Spark集群有3个Worker节点和正在运行的1个应用程序,每个Worker节点为1内核/512M内存。由于没有指定应用程序所占内核数目,则该应用程序占用该集群所有3个内核,并且每个节点分配512M内存。
根据每个节点负载情况,每个节点运行executor并不相同,其中hadoop1的executor数目为0。而hadoop3执行executor数为10个,其中5个EXITED状态,5个KILLED状态。
3.2.3 运行脚本2
该脚本为Spark自带例子,在该例子中个计算了圆周率π的值,区别脚本1这里指定了每个executor内核数据,以下为执行脚本:
参数说明(详细可以参考上面的参数说明):
3.2.4 观察运行情况
通过观察Spark集群有3个Worker节点和正在运行的1个应用程序,每个Worker节点为1内核/512M内存。由于指定应用程序所占内核数目为2,则该应用程序使用该集群所有2个内核。
1 编译Spark
Spark可以通过SBT和Maven两种方式进行编译,再通过make-distribution.sh脚本生成部署包。SBT编译需要安装git工具,而Maven安装则需要maven工具,两种方式均需要在联网下进行,通过比较发现SBT编译速度较慢(原因有可能是1、时间不一样,SBT是白天编译,Maven是深夜进行的,获取依赖包速度不同 2、maven下载大文件是多线程进行,而SBT是单进程),Maven编译成功前后花了3、4个小时。
1.1 编译Spark(SBT)
1.1.1 安装git并编译安装
1.从如下地址下载git安装包
http://www.onlinedown.net/softdown/169333_2.htm
https://www.kernel.org/pub/software/scm/git/
如果linux是CentOS操作系统可以通过:yum install git直接进行安装
由于从https获取内容,需要安装curl-devel,可以从如下地址获取
http://rpmfind.net/linux/rpm2html/search.php?query=curl-devel
如果linux是CentOS操作系统可以通过:yum install curl-devel直接进行安装
2.上传git并解压缩
把git-1.7.6.tar.gz安装包上传到/home/hadoop/upload目录中,解压缩然后放到/app目录下
$cd /home/hadoop/upload/ $tar -xzf git-1.7.6.tar.gz $mv git-1.7.6 /app $ll /app
3.编译安装git
以root用户进行在git所在路径编译安装git
#yum install curl-devel #cd /app/git-1.7.6 #./configure #make #make install
4.把git加入到PATH路径中
打开/etc/profile把git所在路径加入到PATH参数中
export GIT_HOME=/app/git-1.7.6 export PATH=$PATH:$J***A_HOME/bin:$M***EN_HOME/bin:$GIT_HOME/bin
重新登录或者使用source /etc/profile使参数生效,然后使用git命令查看配置是否正确
1.1.2 下载Spark源代码并上传
1.可以从如下地址下载到spark源代码:
http://spark.apache.org/downloads.html
http://d3kbcqa49mib13.cloudfront.net/spark-1.1.0.tgz
git clone https://github.com/apache/spark.git
把下载好的spark-1.1.0.tgz源代码包使用1.1.3.1介绍的工具上传到/home/hadoop/upload 目录下
2.在主节点上解压缩
$cd /home/hadoop/upload/ $tar -xzf spark-1.1.0.tgz
3.把spark-1.1.0改名并移动到/app/complied目录下
$mv spark-1.1.0 /app/complied/spark-1.1.0-sbt $ls /app/complied
1.1.3 编译代码
编译spark源代码的时候,需要从网上下载依赖包,所以整个编译过程机器必须保证在联网状态。编译执行如下脚本:
$cd /app/complied/spark-1.1.0-sbt $sbt/sbt assembly -Pyarn -Phadoop-2.2 -Pspark-ganglia-lgpl -Pkinesis-asl -Phive
整个编译过程编译了约十几个任务,重新编译N次,需要几个甚至十几个小时才能编译完成(主要看下载依赖包的速度)。
1.2 编译Spark(Maven)
1.2.1 安装Maven并配置参数
在编译前最好安装3.0以上版本的Maven,在/etc/profile配置文件中加入如下设置:
export M***EN_HOME=/app/apache-maven-3.0.5 export PATH=$PATH:$J***A_HOME/bin:$M***EN_HOME/bin:$GIT_HOME/bin
1.2.2 下载Spark源代码并上传
1.可以从如下地址下载到spark源代码:
http://spark.apache.org/downloads.html
http://d3kbcqa49mib13.cloudfront.net/spark-1.1.0.tgz
git clone https://github.com/apache/spark.git
把下载好的spark-1.1.0.tgz源代码包使用1.1.3.1介绍的工具上传到/home/hadoop/upload 目录下
2.在主节点上解压缩
$cd /home/hadoop/upload/ $tar -xzf spark-1.1.0.tgz
3.把spark-1.1.0改名并移动到/app/complied目录下
$mv spark-1.1.0 /app/complied/spark-1.1.0-mvn $ls /app/complied
1.2.3 编译代码
编译spark源代码的时候,需要从网上下载依赖包,所以整个编译过程机器必须保证在联网状态。编译执行如下脚本:
$cd /app/complied/spark-1.1.0-mvn $export M***EN_OPTS="-Xmx2g -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=512m" $mvn -Pyarn -Phadoop-2.2 -Pspark-ganglia-lgpl -Pkinesis-asl -Phive -DskipTests clean package
整个编译过程编译了约24个任务,整个过程耗时1小时45分钟。
1.3 生成Spark部署包
在Spark源码根目录下有一个生成部署包的脚本make-distribution.sh,可以通过执行如下命令进行打包 ./make-distribution.sh [–name] [–tgz] [–with-tachyon]
--name NAME 和--tgz 结合可以生成spark-$VERSION-bin-$NAME.tgz 的部署包,不加此参数时NAME 为hadoop 的版本号 --tgz 在根目录下生成 spark-$VERSION-bin.tgz ,不加此参数时不生成tgz 文件,只生成/dist 目录 --with-tachyon 是否支持内存文件系统Tachyon ,不加此参数时不支持tachyon
例子:
1.生成支持yarn 、hadoop2.2.0 、hive 的部署包:
./make-distribution.sh --tgz --name 2.2.0 -Pyarn -Phadoop-2.2 -Phive
2.生成支持yarn 、hadoop2.2.0 、hive 、ganglia 的部署包:
./make-distribution.sh --tgz --name 2.2.0 -Pyarn -Phadoop-2.2 -Pspark-ganglia-lgpl -P hive
1.3.1 生成部署包
使用如下命令生成Spark部署包,由于该脚本默认在JDK1.6进行,在开始时会进行询问是否继续,只要选择Y即可
$cd /app/complied/spark-1.1.0-mvn/ $./make-distribution.sh --tgz --name 2.2.0 -Pyarn -Phadoop-2.2 -Pspark-ganglia-lgpl -P hive
生成Spark部署包编译了约24个任务,用时大概1小时38分钟。
1.3.2 查看生成结果
生成在部署包位于根目录下,文件名类似于spark-1.1.0-bin-2.2.0.tgz。
2 安装Spark
2.1 上传并解压Spark安装包
1.我们使用上一步骤编译好的spark-1.1.0-bin-2.2.0.tgz文件作为安装包(也可以从网上下载native文件夹或者打包好的64位hadoop安装包),使用” Spark编译与部署(上)”中1. 3.1介绍的工具上传到/home/hadoop/upload 目录下
2.在主节点上解压缩
$cd /home/hadoop/upload/ $tar -xzf spark-1.1.0-bin-2.2.0.tgz
3.把spark改名并移动到/app/hadoop目录下
$mv spark-1.1.0-bin-2.2.0 /app/hadoop/spark-1.1.0 $ll /app/hadoop
2.2 配置/etc/profile
1.打开配置文件/etc/profile
$sudo vi /etc/profile
2.定义SPARK_HOME并把spark路径加入到PATH参数中
SPARK_HOME=/app/hadoop/spark-1.1.0 PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin
2.3 配置conf/slaves
1.打开配置文件conf/slaves
$cd /app/hadoop/spark-1.1.0/conf $sudo vi slaves
2.加入slave配置节点
hadoop1 hadoop2 hadoop3
2.4 配置conf/spark-env.sh
1.打开配置文件conf/spark-env.sh
$cd /app/hadoop/spark-1.1.0/conf $cp spark-env.sh.template spark-env.sh $sudo vi spark-env.sh
2.加入Spark环境配置内容,设置hadoop1为Master节点
export SPARK_MASTER_IP=hadoop1 export SPARK_MASTER_PORT=7077 export SPARK_WORKER_CORES=1 export SPARK_WORKER_INSTANCES=1 export SPARK_WORKER_MEMORY=512M
2.5 向各节点分发Spark程序
1.进入hadoop1机器/app/hadoop目录,使用如下命令把spark文件夹复制到hadoop2和hadoop3机器
$cd /app/hadoop $scp -r spark-1.1.0 hadoop@hadoop2:/app/hadoop/ $scp -r spark-1.1.0 hadoop@hadoop3:/app/hadoop/
2.在从节点查看是否复制成功
2.6 启动Spark
$cd /app/hadoop/spark-1.1.0/sbin $./start-all.sh
2.7 验证启动
此时在hadoop1上面运行的进程有:Worker和Master
此时在hadoop2和hadoop3上面运行的进程有只有Worker
通过 netstat -nlt 命令查看hadoop1节点网络情况
在浏览器中输入 http://hadoop1:8080(需要注意的是要在网络设置中把hadoop*除外,否则会到外网DNS解析,出现无法访问的情况) 既可以进入Spark集群状态页面
2.8 验证客户端连接
进入hadoop1节点,进入spark的bin目录,使用spark-shell连接集群
$cd /app/hadoop/spark-1.1.0/bin $spark-shell --master spark://hadoop1:7077 --executor-memory 500m
在命令中只指定了内存大小并没有指定核数,所以该客户端将占用该集群所有核并在每个节点分配500M内存
3 Spark测试
3.1 使用Spark-shell测试
这里我们测试一下在Hadoop中大家都知道的WordCout程序,在MapReduce实现WordCout需要Map、Reduce和Job三个部分,而在Spark中甚至一行就能够搞定。下面就看一下是如何实现的:
3.1.1 启动HDFS
$cd /app/hadoop/hadoop-2.2.0/sbin $./start-dfs.sh
通过jps观察启动情况,在hadoop1上面运行的进程有:NameNode、SecondaryNameNode和DataNode
hadoop2和hadoop3上面运行的进程有:NameNode和DataNode
3.1.2 上传数据到HDFS中
把hadoop配置文件core-site.xml文件作为测试文件上传到HDFS中
$hadoop fs -mkdir -p /user/hadoop/testdata $hadoop fs -put /app/hadoop/hadoop-2.2.0/etc/hadoop/core-site.xml /user/hadoop/testdata
3.1.3 启动Spark
$cd /app/hadoop/spark-1.1.0/sbin $./start-all.sh
3.1.4 启动Spark-shell
在spark客户端(这里在hadoop1节点),使用spark-shell连接集群
$cd /app/hadoop/spark-1.1.0/bin $./spark-shell --master spark://hadoop1:7077 --executor-memory 512m --driver-memory 500m
3.1.5 运行WordCount脚本
下面就是WordCount的执行脚本,该脚本是scala编写,以下为一行实现:
scala>sc.textFile("hdfs://hadoop1:9000/user/hadoop/testdata/core-site.xml").flatMap(_.split(" ")).map(x=>(x,1)).reduceByKey(_+_).map(x=>(x._2,x._1)).sortByKey(false).map(x=>(x._2,x._1)).take(10)
为了更好看到实现过程,下面将逐行进行实现:
scala>val rdd=sc.textFile("hdfs://hadoop1:9000/user/hadoop/testdata/core-site.xml") scala>rdd.cache() scala>val wordcount=rdd.flatMap(_.split(" ")).map(x=>(x,1)).reduceByKey(_+_) scala>wordcount.take(10) scala>val wordsort=wordcount.map(x=>(x._2,x._1)).sortByKey(false).map(x=>(x._2,x._1)) scala>wordsort.take(10)
词频统计结果如下:
Array[(String, Int)] = Array((“”,100), (the,7), (,6), (,6), (under,3), (in,3), (License,3), (this,2), (–>,2), (file.,2))
3.1.6 观察运行情况
通过http://hadoop1:8080查看Spark运行情况,可以看到Spark为3个节点,每个节点各为1个内核/512M内存,客户端分配3个核,每个核有512M内存。
通过点击客户端运行任务ID,可以看到该任务在hadoop2和hadoop3节点上运行,在hadoop1上并没有运行,主要是由于hadoop1为NameNode和Spark客户端造成内存占用过大造成
3.2 使用Spark-submit测试
从Spark1.0.0开始,Spark提供了一个易用的应用程序部署工具bin/spark-submit,可以完成Spark应用程序在local、Standalone、YARN、Mesos上的快捷部署。该工具语法及参数说明如下:
Usage: spark-submit [options] <app jar | python file> [app options] Options: --master MASTER_URL spark://host:port, mesos://host:port, yarn, or local. --deploy-mode DEPLOY_MODE driver运行之处,client运行在本机,cluster运行在集群 --class CLASS_NAME 应用程序包的要运行的class --name NAME 应用程序名称 --jars JARS 用逗号隔开的driver本地jar包列表以及executor类路径 --py-files PY_FILES 用逗号隔开的放置在Python应用程序 PYTHONPATH上的.zip, .egg, .py文件列表 --files FILES 用逗号隔开的要放置在每个executor工作目录的文件列表 --properties-file FILE 设置应用程序属性的文件放置位置,默认是conf/spark-defaults.conf --driver-memory MEM driver内存大小,默认512M --driver-java-options driver的java选项 --driver-library-path driver的库路径Extra library path entries to pass to the driver --driver-class-path driver的类路径,用--jars 添加的jar包会自动包含在类路径里 --executor-memory MEM executor内存大小,默认1G Spark standalone with cluster deploy mode only: --driver-cores NUM driver使用内核数,默认为1 --supervise 如果设置了该参数,driver失败是会重启 Spark standalone and Mesos only: --total-executor-cores NUM executor使用的总核数 YARN-only: --executor-cores NUM 每个executor使用的内核数,默认为1 --queue QUEUE_NAME 提交应用程序给哪个YARN的队列,默认是default队列 --num-executors NUM 启动的executor数量,默认是2个 --archives ARCHIVES 被每个executor提取到工作目录的档案列表,用逗号隔开
3.2.1 运行脚本1
该脚本为Spark自带例子,在该例子中个计算了圆周率π的值,以下为执行脚本:
$cd /app/hadoop/spark-1.1.0/bin $./spark-submit --master spark://hadoop1:7077 --class org.apache.spark.examples.SparkPi --executor-memory 512m ../lib/spark-examples-1.1.0-hadoop2.2.0.jar 200
参数说明(详细可以参考上面的参数说明):
--master Master所在地址,可以有Mesos、Spark、YARN和Local四种,在这里为Spark Standalone集群,地址为spark://hadoop1:7077 --class 应用程序调用的类名,这里为org.apache.spark.examples.SparkPi --executor-memory 每个executor所分配的内存大小,这里为512M 执行jar包 这里是../lib/spark-examples-1.1.0-hadoop2.2.0.jar 分片数目 这里数目为200
3.2.2 观察运行情况
通过观察Spark集群有3个Worker节点和正在运行的1个应用程序,每个Worker节点为1内核/512M内存。由于没有指定应用程序所占内核数目,则该应用程序占用该集群所有3个内核,并且每个节点分配512M内存。
根据每个节点负载情况,每个节点运行executor并不相同,其中hadoop1的executor数目为0。而hadoop3执行executor数为10个,其中5个EXITED状态,5个KILLED状态。
3.2.3 运行脚本2
该脚本为Spark自带例子,在该例子中个计算了圆周率π的值,区别脚本1这里指定了每个executor内核数据,以下为执行脚本:
$cd /app/hadoop/spark-1.1.0/bin $./spark-submit --master spark://hadoop1:7077 --class org.apache.spark.examples.SparkPi --executor-memory 512m --total-executor-cores 2 ../lib/spark-examples-1.1.0-hadoop2.2.0.jar 200
参数说明(详细可以参考上面的参数说明):
--master Master所在地址,可以有Mesos、Spark、YARN和Local四种,在这里为Spark Standalone集群,地址为spark://hadoop1:7077 --class 应用程序调用的类名,这里为org.apache.spark.examples.SparkPi --executor-memory 每个executor所分配的内存大小,这里为512M --total-executor-cores 2 每个executor分配的内核数 执行jar包 这里是../lib/spark-examples-1.1.0-hadoop2.2.0.jar 分片数目 这里数目为200
3.2.4 观察运行情况
通过观察Spark集群有3个Worker节点和正在运行的1个应用程序,每个Worker节点为1内核/512M内存。由于指定应用程序所占内核数目为2,则该应用程序使用该集群所有2个内核。
相关文章推荐
- 奶牛食品
- 常用的操作系统镜像下载windows、linux 和MacOS
- Maven简单教程(一)
- Spark入门实战系列--2.Spark编译与部署(中)--Hadoop编译安装
- CXF简单示例(二)之异步调用
- HDU 5372 Segment Game
- 面向程序员的数据库访问性能优化法则
- 360:最后一个字符
- Centos7&Centos6 Root密码破解详解
- 图论训练总结
- profile
- 图的广度优先遍历和深度优先遍历(基于链式前向星)
- 如何解决adb devices 端口被占用的问题zz
- 黑马程序员——类与对象2
- Leetcode64 Minimum Path Sum
- Mac下添加java环境变量
- 黑马程序员 oc随记 foundation框架 nsstring.NSmutable.nsarray与nsdictionay
- 【bzoj1087】[SCOI2005]互不侵犯King
- opencv获取图像的像素值
- Request Parameters and Header Values