#大数据学习笔记第25天# Linux第1天

## 01.Linux介绍以及VMware安装
软件安装在没有中文和空格的目录下

– VMware
– CentOS-7-x86_64-DVD-1511

## 02.Centos虚拟机安装
安装CentOS7.0基本都是默认下一步:

## 03.Linux基本命令

Select Code
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
44
45
46
47
48
49
50
51
52
53
54
55
[centos@bogon ~]$ 
centos		//用户名
@		//@
bogon		//主机名
~		//当前目录
$		//非root用户命令行
#		//root用户命令行

ls		//列出当前目录下的文件或文件夹
cd		//change directory	切换目录
相对路径	//相对于当前目录的路径		cd Desktop
绝对路径	//相对于根目录的完整路径	cd \Users\chang\Desktop

Linux中路径左斜线“/”
Windows中路径右斜线“\”

ls -al		//-a	显示全部	//全部指的什么?
		//-l	显示详细信息

ll		//ls -l
ls --help	//查看帮助

su root		//switch user 切换用户到root
cat ifcfg-ens33	//查看ifcfg-ens33文件内容
reboot		//重启
ip addr		//查看本机ip
cd ~		//进入到家目录
		//对于centos,家目录是/home/centos
		//对于root,家目录/root
pwd		//查看当前目录的绝对路径
touch 1.txt	//创建1.txt文件
rm 1.txt	//删除1.txt
mkdir aaa	//创建文件夹
ll aaa		//查看文件夹内容
rm -r aaa	//递归删除文件夹
echo		//回音
> 或 >>		//重定向
		//> 为覆盖
		//>> 为追加
echo helloworld > 1.txt		//将helloworld重定向到1.txt
cat 1.txt		//查看整个文档
more 1.txt		//分页查询
head [-n] 1.txt		//默认前十行,输出前n个行
tail [-n] 1.txt		//默认后十行,输出前n个行
clear			//清屏,快捷键为ctrl+L
whoami			//输出当前用户名
sudo			//临时使用root权限进行操作
passwd			//修改密码,修改当前用户
passwd	centos		//指定用户名修改密码,只有root可以做
cp 1.txt 11.txt		//拷贝文件
mv 1.txt 111.txt	//移动文件,可以进行重命名
rename 11.txt 22.txt 11.txt	//重命名
echo -n		//去除换行符
echo -e		//转译,将特殊字符转移
wc 3.txt	//统计单词个数,包括行数、单词数、字节数

远程登录软件:

– putty
– xsheel

## 04.VI讲解 mtputty安装配置 文件和文件夹的增删改查
略:VIM编辑器

## 05.Linux文件查看方式 目录和文件类型

## 06.CentOS文件权限验证 sudoer问题解决

## 07.文件夹权限 yum使用 nano文本编辑器 ifconfig

## 08.CentOS主机名和静态ip配置
### 静态IP配置流程
1、查看宿主机器的IP地址(一定要是192.168.*.*),如果是无线的网络,需要使用路由器联网;

2、设置虚拟机选择VMNet8网卡,设置成和宿主IP一个子网,去掉使用DHCP服务选项

3、设置宿主VMNet8网卡,IP网段要保持一致,才能保证可以通信

4、配置虚拟机网络连接模式,选择NAT模式

5、配置网卡

重启网卡:service network restart

#大数据学习笔记第28天# Hadoop概述

一、hadoop背景介绍


Hadoop官网:http://hadoop.apache.org/

1.1 什么是hadoop

(1)、hadoop是apache旗下的一套开源软件平台,可以通过http://apache.org/—>project–>hadoop打开
(2)、Hadoop是开源软件,可靠的、分布式、可伸缩的。
(3)、Hadoop提供的功能:利用服务器集群,根据用户的自定义业务逻辑,对海量数据进行分布式处理
(4)、广义上来说,Hadoop通常是指一个更广泛的概念—-hadoop生态圈

1.2 数据分析故事

1.3 数据有多大呢

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
1KB (Kilobyte) 	=1024B; 
1MB (Megabyte)	=1024KB = 2^20 B; 
1GB (Gigabyte)	=1024MB = 2^30 B;
1TB (Trillionbyte)	=1024GB
1PB (Petabyte)		=1024TB
1EB (Exabyte)		=1024PB
1ZB (Zettabyte)	=1024EB
1YB (Yottabyte)	=1024ZB
1BB (Brontobyte)	=1024YB
1NB (NonaByte)	=1024BB
1DB (DoggaByte)	=1024NB
1CB (Corydonbyte)	=1024 DB = 2^120 B;
1XB (Xerobyte)	=1024 CB = 2^130 B;

> 注:2014年阿里在杭州召开大数据峰会时提出,大数据从4个V的年代,Volume(大量)、Velocity(高速)、Variety(多样)、Value(价值)延伸至三个维度,可实时性、可解释性、数据准确性稳定性。这三个维度是现在到底数据能不能用上的很重要的三个维度。

去IOE
– IBM //ibm小型机.
– Oracle //oracle数据库服务器 RAC
– EMC //EMC共享存储设备。

较为出名的“去IOE”事件要追溯到2013年5月份——阿里巴巴首先发动了“去IOE”运动。

IBM是服务器提供商,Oracle是数据库软件提供商,EMC则是存储设备提供商,三者构成了一个从软件到硬件的企业数据库系统。由这三驾马车构成的数据库系统几乎占领了全球大部分商用数据库系统市场份额。除阿里巴巴这样需要大量数据运算的电商企业,其他如石油、金融行业也广泛地使用这套系统。

具体来说,阿里巴巴的“去IOE”运动就是用成本更加低廉的软件—MYSQL替代Oracle,使用PC Server替代EMC2、IBM小型机等设备,以消除“IOE”对自己数据库系统的垄断。这一行动也被业内解读为低成本化——基于“IOE”在业内的垄断,整套系统维护费用非常昂贵,仅仅Oracle系统三年的销售价格就达到八位数,而阿里旗下的用户群每年都在增长,在应用云计算的过程中,“IOE”系统并不适合云服务横向扩展,也就是多个数据库系统同时运行,因此云服务一旦扩张,这部分维护成本将非常高。

2013年5月17日,最后一台小型机在阿里巴巴支付宝下线,标志着阿里已经完成去IOE化。上海财大经济学院副教授、高等研究院市场机制设计和信息经济研究中心主任李玲芳对《第一财经日报》称,阿里巴巴的“去IOE”为市场带来了一个成功的范本,证明“去IOE”是有可能的。

1.4 分布式
由分布在不同主机上的进程协同在一起,才能构成整个应用。
(1)、分布式软件系统(Distributed Software Systems)
该软件系统会划分成多个子系统或模块,各自运行在不同的机器上,子系统或模块之间通过网络通信进行协作,实现最终的整体功能

(2)、分布式应用系统模拟开发
需求:可以实现由主节点将运算任务发往从节点,并将各从节点上的任务启动;

程序清单:
– AppMaster
– AppSlave/APPSlaveThread
– Task

程序运行逻辑流程:

1.5 HADOOP在大数据、云计算中的位置和关系
(1)、虚拟化技术
虚拟化技术是指计算元件在虚拟的基础上而不是真实的基础上运行,它可以扩大硬件的容量,简化软件的重新配置过程,减少软件虚拟机相关开销和支持更广泛的操作系统方面。通过虚拟化技术可实现软件应用与底层硬件相隔离,它包括将单个资源划分成多个虚拟资源的裂分模式,也包括将多个资源整合成一个虚拟资源的聚合模式。虚拟化技术根据对象可分成存储虚拟化、计算虚拟化、网络虚拟化等,计算虚拟化又分为系统级虚拟化、应用级虚拟化和桌面虚拟化目。在云计算实现中。计算系统虚拟化是一切建立在“云”上的服务与应用的基础。虚拟化技术目前主要应用在CPU、操作系统、服务器等多个方面,是提高服务效率的最佳解决方案。

(2)、分布式存储
云计算系统由大量服务器组成,同时为大量用户服务,因此云计算系统采用分布式存储的方式存储数据,用冗余存储的方式(集群计算、数据冗余和分布式存储)保证数据的可靠性。冗余的方式通过任务分解和集群,用低配机器替代超级计算机的性能来保证低成本,这种方式保证分布式数据的高可用、高可靠和经济性,即为同一份数据存储多个副本。云计算系统中广泛使用的数据存储系统是Google的GFS和Hadoop团队开发的GFS的开源实现HDFS。

(3)、海量数据管理技术
云计算需要对分布的、海量的数据进行处理、分析,因此,数据管理技术必需能够高效的管理大量的数据。云计算系统中的数据管理技术主要是Google的BT sT-lO数据管理技术和Hadoop团队开发的开源数据管理模块HBase。由于云数据存储管理形式不同于传统的RDBMS数据管理方式,如何在规模巨大的分布式数据中找到特定的数据,也是云计算数据管理技术所必须解决的问题。同时,由于管理形式的不同造成传统的SQL数据库接口无法直接移植到云管理系统中来,目前一些研究在关注为云数据管理提供RDBMS和SQL的接口,如基于Hadoap 子项目HBase和Hive等。另外,在云数据管理方面,如何保证数据安全性和数据访问高效性也是研究关注的重点问题之一。

(4)、分布式编程模型
云计算提供了分布式的计算模式,客观上要求必须有分布式的编程模式。云计算采用了一种思想简洁的分布式并行编程模型Map-Reduce。Map-Reduce是一种编程模型和任务调度模型。主要用于数据集的并行运算和并行任务的调度处理。在该模式下,用户只需要自行编写Map函数和Reduce函数即可进行并行计算。其中,Map 函数中定义各节点上的分块数据的处理方法,而Reduce函数中定义中间结果的保存方法以及最终结果的归纳方法。

(5)、云平台管理技术
云计算资源规模庞大,服务器数量众多并分布在不同的地点,同时运行着数百种应用,如何有效的管理这些服务器,保证整个系统提供不问断的服务是巨大的挑战。云计算系统的平台管理技术能够使大量的服务器协同工作,方便的进行业务部署和开通,快速发现和恢复系统故障,通过自动化、智能化的手段实现大规模系统的可靠运营。

1.6 HADOOP产生背景

1. HADOOP最早起源于Apache Nutch。Nutch的设计目标是构建一个大型的全网搜索引擎,包括网页抓取、索引、查询等功能,但随着抓取网页数量的增加,遇到了严重的可扩展性问题——如何解决数十亿网页的存储和索引问题。
2. 2003年、2004年谷歌发表的两篇论文为该问题提供了可行的解决方案。
– 分布式文件系统(GFS),可用于处理海量网页的存储
– 分布式计算框架MAPREDUCE,可用于处理海量网页的索引计算问题。
3. Nutch的开发人员完成了相应的开源实现HDFS和MAPREDUCE,并从Nutch中剥离成为独立项目HADOOP,到2008年1月,HADOOP成为Apache顶级项目,迎来了它的快速发展期。

1.7 HADOOP现状
– Yahoo:4.2万节点/10万CPU/大群4500节;广告/用户行为分析/反垃圾邮件
– FaceBook:1400台/1.12万CPU/15PB
– 百度:单群2800节点/上万台/存储100PB
– 阿里:3200/30000core/100Tmem/60PB; 淘宝/天猫/支付宝/秒杀
– 腾讯:5000/单群2000/游戏/QQ/财付通

1.8 国内外HADOOP应用案例介绍
(1)、HADOOP应用于数据服务基础平台建设

(2)、HADOOP用于用户画像

(3)、HADOOP用于网站点击流日志

1.9 国内HADOOP的就业情况分析

(1)、HADOOP就业整体情况
1. 大数据产业已纳入国家十三五规划
1. 各大城市都在进行智慧城市项目建设,而智慧城市的根基就是大数据综合平台
1. 互联网时代数据的种类,增长都呈现爆发式增长,各行业对数据的价值日益重视
1. 相对于传统JAVAEE技术领域来说,大数据领域的人才相对稀缺
1. 随着现代社会的发展,数据处理和数据挖掘的重要性只会增不会减,因此,大数据技术是一个尚在蓬勃发展且具有长远前景的领域

(2)、HADOOP就业职位要求
大数据是个复合专业,包括应用开发、软件平台、算法、数据挖掘等,因此,大数据技术领域的就业选择是多样的,但就HADOOP而言,通常都需要具备以下技能或知识:
1. HADOOP分布式集群的平台搭建
1. HADOOP分布式文件系统HDFS的原理理解及使用
1. HADOOP分布式运算框架MAPREDUCE的原理理解及编程
1. Hive数据仓库工具的熟练应用
1. Flume、sqoop、oozie等辅助工具的熟练使用
1. Shell/python/scala/等脚本语言的开发能力

2.0 HADOOP生态圈以及各组成部分的简介

重点组件:
– [HDFS:分布式文件系统]
– [MAPREDUCE:分布式运算程序开发框架]
– [HIVE:基于大数据技术(文件系统+运算框架)的SQL数据仓库工具]
– HBASE:基于HADOOP的分布式海量数据库
– [ZOOKEEPER:分布式协调服务基础组件]
– Mahout:基于mapreduce/spark/flink等分布式运算框架的机器学习算法库
– Oozie:工作流调度框架
– Sqoop:数据导入导出工具
– Flume:日志数据采集框架

二、数据分析流程介绍


一个应用广泛的数据分析系统:“web日志数据分析”

2.1 需求分析
2.1.1 案例名称
一般中型的网站(10W的PV以上),每天会产生1G以上Web日志文件。大型或超大型的网站,可能每小时就会产生10G的数据量。
具体来说,比如某电子商务网站,在线团购业务。每日PV数100w,独立IP数5w。用户通常在工作日上午10:00-12:00和下午15:00-18:00访问量最大。日间主要是通过PC端浏览器访问,休息日及夜间通过移动设备访问较多。网站搜索浏量占整个网站的80%,PC用户不足1%的用户会消费,移动用户有5%会消费。

对于日志的这种规模的数据,用HADOOP进行日志分析,是最适合不过的了。

2.1.2 案例需求描述
“Web点击流日志”包含着网站运营很重要的信息,通过日志分析,我们可以知道网站的访问量,哪个网页访问人数最多,哪个网页最有价值,广告转化率、访客的来源信息,访客的终端信息等。

2.1.3 数据来源
本案例的数据主要由用户的点击行为记录
获取方式:在页面预埋一段js程序,为页面上想要监听的标签绑定事件,只要用户点击或移动到标签,即可触发ajax请求到后台servlet程序,用log4j记录下事件信息,从而在web服务器(nginx、tomcat等)上形成不断增长的日志文件。

形如:
58.215.204.118 – – [18/Sep/2013:06:51:35 +0000] “GET /wp-includes/js/jquery/jquery.js?ver=1.10.2 HTTP/1.1” 304 0 “http://blog.fens.me/nodejs-socketio-chat/” “Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0”

2.2 数据处理流程
2.2.1 流程图解析
本案例跟典型的BI系统极其类似,整体流程如下:

但是,由于本案例的前提是处理海量数据,因而,流程中各环节所使用的技术则跟传统BI完全不同,后续课程都会一一讲解:
1. 数据采集:定制开发采集程序,或使用开源框架FLUME
1. 数据预处理:定制开发mapreduce程序运行于hadoop集群
1. 数据仓库技术:基于hadoop之上的Hive
1. 数据导出:基于hadoop的sqoop数据导入导出工具
1. 数据可视化:定制开发web程序或使用kettle等产品
1. 整个过程的流程调度:hadoop生态圈中的oozie工具或其他类似开源产品

2.2.2 项目技术架构图

2.3 项目最终效果
经过完整的数据处理流程后,会周期性输出各类统计指标的报表,在生产实践中,最终需要将这些报表数据以可视化的形式展现出来,本案例采用web程序来实现数据可视化

效果如下所示:

三、hadoop 3种集群方式

独立模式 伪分布式模式 完全分布式模式

3.1独立模式


默认就是独立模式,使用本地文件系统。
3.1.1安装
a)下载jdk-8u65-linux-x64.tar.gz
b)tar开

Select Code
1
2
3
4
$>su centos ; cd ~
$>mkdir downloads
$>cp /mnt/hdfs/downloads/bigdata/jdk-8u65-linux-x64.tar.gz ~/downlooads
$>tar -xzvf jdk-8u65-linux-x64.tar.gz

c)创建/soft文件夹

Select Code
1
2
$>sudo mkdir /soft
$>sudo chown centos:centos /soft

d)移动tar开的文件到/soft下

Select Code
1
$>mv ~/downloads/jdk-1.8.0_65 /soft/

e)创建符号连接

Select Code
1
$>ln -s /soft/jdk-1.8.0_65 /soft/jdk

f)验证jdk安装是否成功

Select Code
1
2
$>cd /soft/jdk/bin
$>./java  -version

3.1.2 配置jdk环境变量
1.编辑/etc/profile

Select Code
1
2
3
4
$>sudo nano /etc/profile
...
export  JAVA_HOME=/soft/jdk
exprot  PATH=$PATH:$JAVA_HOME/bin

2.使环境变量即刻生效

Select Code
1
$>source /etc/profile

3.进入任意目录下,测试是否ok

Select Code
1
2
$>cd ~
$>java  -version

注意点:你创建文件夹一定和你登陆的用户一致

3.1.3 安装HADOOP软件
1.安装hadoop
a)下载hadoop-2.7.3.tar.gz
b)tar开

Select Code
1
2
3
$>su centos ; cd ~
$>cp /mnt/hdfs/downloads/bigdata/hadoop-2.7.3.tar.gz ~/downloads
$>tar -xzvf hadoop-2.7.3.tar.gz

c)无
d)移动tar开的文件到/soft下

Select Code
1
$>mv ~/downloads/hadoop-2.7.3 /soft/

e)创建符号连接

Select Code
1
$>ln -s /soft/hadoop-2.7.3 /soft/hadoop

f)验证hadoop安装是否成功

Select Code
1
2
$>cd /soft/hadoop/bin
$>./hadoop version

2.配置hadoop环境变量

Select Code
1
2
3
4
5
6
7
$>sudo nano /etc/profile
...
export JAVA_HOME=/soft/jdk
exprot PATH=$PATH:$JAVA_HOME/bin

export HADOOP_HOME=/soft/hadoop
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

3.生效

Select Code
1
$>source /etc/profile

4.进入任意目录下,测试是否ok

Select Code
1
2
$>cd ~
$>hadoop version

5.nothing !
不需要启用单独的hadoop进程。

6.hdfs dfs -ls /home 和 linux中的ls效果一样(使用本地的文件系统

3.2 伪分布模式(Pseudodistributed mode)


a)进入${HADOOP_HOME}/etc/hadoop目录

三种模式共存

1.创建三个配置目录,内容等同于hadoop目录

Select Code
1
2
3
${hadoop_home}/etc/local
${hadoop_home}/etc/pesudo
${hadoop_home}/etc/full

2.创建符号连接

Select Code
1
$>ln -s pesudo hadoop

b)编辑core-site.xml

Select Code
1
2
3
4
5
6
7
<?xml version="1.0"?>
<configuration>
<property>
	<name>fs.defaultFS</name>
	<value>hdfs://localhost/</value>
</property>
</configuration>

c)编辑hdfs-site.xml

Select Code
1
2
3
4
5
6
7
<?xml version="1.0"?>
<configuration>
<property>
	<name>dfs.replication</name>
	<value>1</value>
</property>
</configuration>

d)编辑mapred-site.xml
注意:cp mapred-site.xml.template mapred-site.xml

Select Code
1
2
3
4
5
6
7
<?xml version="1.0"?>
<configuration>
<property>
	<name>mapreduce.framework.name</name>
	<value>yarn</value>
</property>
</configuration>

e)编辑yarn-site.xml

Select Code
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0"?>
<configuration>
<property>
	<name>yarn.resourcemanager.hostname</name>
	<value>localhost</value>
</property>
<property>
	<name>yarn.nodemanager.aux-services</name>
	<value>mapreduce_shuffle</value>
</property>
</configuration>

f)配置SSH

四、SSH介绍

4.1 什么是ssh

简单说,SSH是一种网络协议,用于计算机之间的加密登录。
如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码也不会泄露。
最早的时候,互联网通信都是明文通信,一旦被截获,内容就暴露无疑。1995年,芬兰学者Tatu Ylonen设计了SSH协议,将登录信息全部加密,成为互联网安全的一个基本解决方案,迅速在全世界获得推广,目前已经成为Linux系统的标准配置。
需要指出的是,SSH只是一种协议,存在多种实现,既有商业实现,也有开源实现。本文针对的实现是OpenSSH,它是自由软件,应用非常广泛。

4.2 ssh原理

4.2.1查看是否centos自动安装这些软件
命令:yum list installed | grep ssh

4.3 配置SSH

1)检查是否安装了ssh相关软件包(openssh-server + openssh-clients + openssh)
$yum list installed | grep ssh

2)检查是否启动了sshd进程
$>ps -Af | grep sshd

3)在client侧生成公私秘钥对。
$>ssh-keygen -t rsa -P ” -f ~/.ssh/id_rsa

4)生成~/.ssh文件夹,里面有id_rsa(私钥) + id_rsa.pub(公钥)

5)追加公钥到~/.ssh/authorized_keys文件中(文件名、位置固定)
$>cd ~/.ssh
$>cat id_rsa.pub >> authorized_keys

6)修改authorized_keys的权限为644.
$>chmod 644 authorized_keys
其他不能有w这个不能权限

7)测试
$>ssh localhost
Rwx

五、开启伪分布式

1.对hdfs进行格式化

Select Code
1
$>hadoop namenode -format =hdfs namenode -format

2.修改hadoop配置文件,手动指定JAVA_HOME环境变量

Select Code
1
2
3
4
[${hadoop_home}/etc/hadoop/hadoop-env.sh]
...
export JAVA_HOME=/soft/jdk
...

3.启动hadoop的所有进程

Select Code
1
$>start-all.sh

4.启动完成后,出现以下进程

Select Code
1
2
3
4
5
6
7
$>jps
33702 NameNode
33792 DataNode
33954 SecondaryNameNode

29041 ResourceManager
34191 NodeManager

5查看hdfs文件系统

Select Code
1
$>hdfs dfs -ls /

6.创建目录

Select Code
1
$>hdfs dfs -mkdir -p /user/centos/hadoop

7.通过webui查看hadoop的文件系统

Select Code
1
http://IP地址:50070/

8.停止hadoop所有进程

Select Code
1
$>stop-all.sh

六、通过hadoop自带的demo运行单词统计

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
1)mkdir input
2)cd  intput
3)echo “hello word” > file1.txt
4)echo “hello hadoop” > file2.txt
5)echo “hello mapreduce” >> file2.txt
6) more file2.txt
7) hadoop fs -mkdir  /wc_input
8) hadoop fs -ls /
9) hadoop fs -put ~/input/fi* /wc_input
10)hadoop fs -ls  /wc_input
11)hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar wordcount /wc_input /output
12)hadoop fs -ls /output
13)hadoop fs -cat /output/part-r-00000

执行结果截图:

参考资料:
https://blog.csdn.net/hliq5399/article/details/78193113

#大数据学习笔记第6天# 数组

回顾

方法的重载:为了方法名的重用。遵守两同、一不同原则(同类同方法名,不同的参数个数或参数类型)。

大纲

### 第一节课
– 知识点回顾
– 数组概述
– 数组模拟打分实例

### 第二节课
– 方法调用的值传递原理

### 第三节课
– 二维数组
– 二维数组的遍历
– 二维数组计数求和

### 第四节课
– 二维数组练习
– 二维数组打印杨辉三角

数组基础

概念:同一种类型数据的集合,可以是基本的数据类型,也可以是引用数据类型。

### 特点
1. 数组存储的都是相同数据类型的元素。
2. 数组的长度也就是数组中元素的个数。
3. 元素从0开始编号,编号也称为索引\index\下标。
4. 数组中元素的访问方式是通过数组名+索引的方式。

### 数组的定义格式
基本数据类型变量的定义:int x;
数组类型变量的定义:int[] arr;

### 数组的初始化
初始化方式1:

动态初始化:数组的创建和元素的赋值分开进行;
格式:元素类型[] 数组名=new 元素类型[数组长度];

int[] arr = new int[3];

初始化方式2:

静态初始化:数组创建时就给数组元素赋值;
格式:元素类型[] 数组名=new 元素类型[]{元素1,元素2,…};

int[] arr = new int[]{1,2,3}
静态初始化的简写方式:int[] arr = {1,2,3}

直接打印数组类型的变量,会发现结果是一段看不懂的字符串,这就是引用数据类型变量的特点;它实际上代表的是一段内存空间的十六进制表示形式,真正的数据在JVM的堆内存空间中。

### 代码实例

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
public class ArrayDemo{
public static void main(String[] args){
	// 动态初始化
	int[] arr1 = new int[3];
	System.out.println(arr1);	//打印的是包含了十六进制的字符串,实际上代表的是数组的地址
	
	// 静态初始化
	int[] arr2 = new int[]{1,2,3};
	int[] arr3 = {4,5,6};
	System.out.println(arr2);
	System.out.println(arr3);
}
}

内存结构

Java程序在运行时,为了提高运行效率,对内存进行了不同区域的划分,每一种区域都有特定的处理数据的方式和内存管理方式。

如图:

– 栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放;
– 堆内存:存放数组和对象,通过new建立的实例都存放在堆内存中;
– 每一个实例都有内存地址值;
– 实例中的变量都有默认初始值;
– 当实例不再被使用,会在不确定的时间被垃圾回收器回收;
– 方法区:存放类文件和方法(面向对象部分再阐述)

本地方法栈:供本地方法使用,与操作系统有关。
程序计数器:对字节码文件计数;

常见异常

1. 数组索引越界异常
2. 空指针异常

### 代码实例

Select Code
1
2
3
4
5
6
7
8
9
public class ArrayDemo2{
public static void main(String[] args){
	int[] arr = new int[2];
	// arr[2] = 1;	//java.lang.ArrayIndexOutOfBoundsException
	
	arr=null;
	System.out.print(arr[0]); //java.lang.NullPointerException
}
}

案例:数组模拟打分

从键盘录入5个分数作为评分,然后去除一个最高分,去除一个最低分,用剩余的数据的平均分作为最终的评分;

代码:

Select Code
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
44
45
46
47
48
49
50
51
52
import java.util.Scanner;

public class Demo01{
public static void main(String[] args){
	Scanner s = new Scanner(System.in);
	int[] score = new int[5];
	System.out.println("请输入第1个评分");
	score[0] = s.nextInt();
	System.out.println("请输入第2个评分");
	score[1] = s.nextInt();
	System.out.println("请输入第3个评分");
	score[2] = s.nextInt();
	System.out.println("请输入第4个评分");
	score[3] = s.nextInt();
	System.out.println("请输入第5个评分");
	score[4] = s.nextInt();
	
	double res = getScore(score);
	System.out.println("最终的评分是:" + res);
}

public static int getMax(int[] arr){
	int max = arr[0];
	for(int i=0; i < arr.length; i++){
		if(arr[i] > max){
			max = arr[i];
		}
	}
	return max;
}

public static int getMin(int[] arr){
	int min = arr[0];
	for(int i=0; i < arr.length; i++){
		if(arr[i] < min){
			min = arr[i];
		}
	}
	return min;
}

public static double getScore(int[] arr){
	int max = getMax(arr);
	int min = getMin(arr);
	int sum = 0;
	for(int i=0; i<arr.length; i++){
		sum += arr[i];
	}
	double score = (sum - max - min) / (arr.length - 2.0);
	return score;
}
}

方法调用的值传递原理

Java中参数传递(实参->形参)的问题:

– 参数是基本数据类型,传递的是数值的副本;
– 参数是引用数据类型,传递的是引用的副本;

### 代码实例

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 参数是基本数据类型,传递的是数值的副本;
public class Demo02{
	public static void main(String[] args){
		int x=10;
		int y=20;
		change(x, y);
		System.out.println("x=" + x + ", y=" + y);
	}
	
	public static void change(int x, int y){
		System.out.println("方法内部x=" + x + ", y=" + y);
		x = 0;
		y = 0;
		System.out.println("方法内部x=" + x + ", y=" + y);
	}
}

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//参数是引用数据类型,传递的是引用的副本;
public class Demo03{
	public static void main(String[] args){
		int[] arr = {1,2,3};
		change(arr);
		for(int i=0; i<arr.length; i++){
			System.out.print(arr[i]+" ");
		}
	}
	
	public static void change(int[] arr){
		for(int i=0; i<arr.length; i++){
			arr[i]=0;
		}
		System.out.print("方法内部数组元素是:");
		for(int i=0; i<arr.length; i++){
			System.out.print(arr[i] + " ");
		}
		System.out.println();
	}
}

杨辉三角


– 端点的数为1.
– 每个数等于它上方两数之和。
– 每行数字左右对称,由1开始逐渐变大。
– 第n行的数字有n项。
– 第n行数字和为2^(n-1)。
– 每个数字等于上一行的左右两个数字之和。可用此性质写出整个杨辉三角。即第n+1行的第i个数等于第n行的第i-1个数和第i个数之和,这也是组合数的性质之一。

代码实现:

Select Code
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
/*
	定义一个杨辉三角,10行
*/

public class YangHuiTrianger{
	public static void main(String[] args){
		int[][] arr = new int[10][];
		
		for(int i=0; i < arr.length; i++){
			int[] line = new int[i+1];
			arr[i] = line;
			
			//遍历一维数组
			for(int j=0; j<arr[i].length; j++){
				if(i==0){
					arr[i][j] = 1;
				}
				if(j==0 || j==(arr[i].length-1)){
					arr[i][j] = 1;
				}else{
					arr[i][j]=arr[i-1][j-1] + arr[i-1][j];
				}
			}
		}
		
		printArray(arr);
	}
	
	// 打印二维数组
	public static void printArray(int[][] arr){
		for(int i=0;i<arr.length;i++){
			for(int j=0;j<arr[i].length;j++){
				System.out.print(arr[i][j] + " ");
			}
			System.out.println();
		}
	}
}

展示效果:

#读书笔记# 《增长黑客》

增长黑客讲的是互联网行业产品的运营方法论,本文列出了本书的大纲,这也是本书的精华纲要,当然有些知识未必是完全实用的,有些方法还是值得深入去研究的。比如说:增长团队的建设、结合数据的挖掘,通过收集想法,进行大量的测试,寻找产品的“核心体验”并加以合理的利用达到更好的病毒传播是很科学的推广方法论。

再比如:对于营销渠道的分类、营销方法的制定、营销渠道的选择,如何用最小的代价获取目标用户群体的方法进行阐述。你还可以通过数据分析,对产品进行诊断:获客、激活注册用户、留存率、用户变现。

感兴趣的朋友可以阅读原文吧!

『方法篇』
## 搭建增长团队

  • 人员构成
    • 增长负责人
    • 产品经理
    • 软件工程师
    • 营销专员
    • 数据分析师
    • 产品设计师
  • 工作流程
    • (1) 数据分析与洞察收集
    • (2) 想法产生
    • (3) 排定试验优先级
    • (4) 试验验收

## 好产品是增长的根本
增长团队应该找到产品真正的核心价值,它可能完全不同于我们最初在产品愿景中所设定的,它可能是产品推出之后才加进去的某个功能或者用户体验。

– 不宜过早开展增长攻势,维持长期的用户增长,你首先必须有一个好产品,而不是仓促的追求获客增长;
– 找到产品让人眼前一亮的时刻,成为不可或缺的产品
– 产品的不可或缺性调查
– 查看用户留存率
– A/B测试
– 深挖数据
– 对产品的试验
– 跟踪活跃用户的数据
– 重新定位产品

## 确定增长杠杆
– 真正重要的指标,明确增长战略
– 整合数据资源
– 简洁明了的报告,数据不是唯一

## 快节奏试验
– 缓慢起步、逐渐提速
– 增长黑客循环
– 准备工作
– 分析
– 提出想法
– 排定优先级
– 测试
– 增长会议

『实战』
## 一、获客
– 设计打动人心的广告语
– 通过实验寻找最优渠道
– 设计病毒循环
– 挖掘产品的网络效应:邀请机制

## 二、激活
– 用户调查
– 创建转化和流失漏斗报告
– 优化用户体验,减少阻力

## 三、留存
– 不断试验和设计改善留存
– 靠什么留住用户
– 让用户养成习惯
– 持续引导,保持长期的活跃
– 提供个性化关系、体验式回报

## 四、变现
– 绘制变现漏斗
– 关注每个群组的贡献
– 优化定价
– 重温消费者心理学

## 小结:良性循环
– 避免停滞增长
– 挖掘数据金矿
– 发觉新渠道,引入全新视角

#大数据学习笔记第5天# 函数

## 回顾

## 大纲
– 方法的定义
– 方法的特点
– 方法的应用
– 方法的重载

## 方法的定义
什么是方法?

– 方法就是定义在类中的,具有特定功能的一段小程序;
– 方法也称为函数;
– 方法可以接收输入,根据需要输出内容;

方法定义的格式:

Select Code
1
2
3
4
修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, ...){
	方法体语句;
	return [返回值];
}
  • 修饰符:暂时固定写成public static
  • 返回值类型:方法执行后返回结果的数据类型
  • 形式参数列表:
    • 参数类型:是形式参数的数据类型;
    • 形式参数:是一个变量,用于接收方法被调用时传给方法的实际参数的值
    • 实际参数:放大调用时传递给形式参数的具体数值
  • return:关键字,用于表示方法结束
  • 返回值:该方法运算后需要返回给调用者的结果,其类型要和返回值类型匹配,或者可以自动转型

## 方法的特点:
– 定义方法可以将功能代码进行封装;
– 提高了代码的复用性;
– 方法只有被调用才会被执行;
– 注意:方法之间是调用关系,不可以在方法内部再定义方法;

## 方法练习:
1. 定义方法,用于计算两个double整型的和;
2. 定义方法,用于打印九九乘法表;
3. 定义方法,用于打印任何行数和列数的“+”号;
4. 定义方法,用于判断一个int数是否是偶数;
5. 定义方法,接收一个int值,返回该值对应的应该是星期几,要求switch结构实现;
6. 定义方法,获取两个数中的最大值;
7. 定义方法,获取三个数中的最大值;

### 答案
题1:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
/*
	定义方法,用于计算两个double整型的和;
*/
public class Demo01{
	public static void main(String[] args){
		System.out.println(add(1.0,2.0));	//3.0
	}
	
	public static double add(double d1, double d2){
		return d1+d2;
	}
}

题2:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
	定义方法,用于打印九九乘法表;
*/
public class Demo02{
	public static void main(String[] args){
		chenfabiao();
	}
	
	public static void chenfabiao(){
		for(int i=1; i<=9; i++){
			for(int j=1; j<=i; j++){
				System.out.print(i+"*"+j+"="+(i * j)+"\t");
			}
			System.out.println();
		}
	}
}

打印效果如图:

题3:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Scanner;
/*
	定义方法,用于打印任何行数和列数的“+”号;
*/
public class Demo03{
	public static void main(String[] args){
		Scanner s = new Scanner(System.in);
		System.out.println("请输入行数:");
		int line = s.nextInt();
		System.out.println("请输入列数:");
		int col = s.nextInt();
		print_plus(line,col);
	}
	
	public static void print_plus(int line, int col){
		for(int i=1; i<=line; i++){
			for(int j=1; j<=col; j++){
				System.out.print("+");
			}
			System.out.println();
		}
	}
}

打印效果如图:

题4:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Scanner;
/*
	定义方法,用于判断一个int数是否是偶数;
*/
public class Demo04{
	public static void main(String[] args){
		Scanner s = new Scanner(System.in);
		System.out.println("请输入一个int整数:");
		int num = s.nextInt();
		if(is_even(num)){
			System.out.println("这是一个偶数");
		}else{
			System.out.println("这是一个奇数");
		}
	}
	
	public static boolean is_even(int num){
		if(num % 2 == 0){
			return true;
		} else {
			return false;
		}
	}
}

打印效果如图:

题5:

Select Code
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
import java.util.Scanner;
/*
	定义方法,接收一个int值,返回该值对应的应该是星期几,要求switch结构实现;
*/
public class Demo05{
	public static void main(String[] args){
		Scanner s = new Scanner(System.in);
		System.out.println("请输入一个1-7范围内的整数:");
		int num = s.nextInt();
		System.out.print("这表示:" + week_day(num));
	}
	
	public static String week_day(int num){
		String s="";
		switch(num){
			case 1:
				s = "星期一";
				break;
			case 2:
				s = "星期二";
				break;
			case 3:
				s = "星期三";
				break;
			case 4:
				s = "星期四";
				break;
			case 5:
				s = "星期五";
				break;
			case 6:
				s = "星期六";
				break;
			case 7:
				s = "星期日";
				break;
			default:
				s = "非法值";
		}
		return s;
	}
}

打印效果如图:

题6:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;
/*
	定义方法,获取两个数中的最大值;
*/
public class Demo06{
	public static void main(String[] args){
		Scanner s = new Scanner(System.in);
		System.out.println("请输入第一个整数:");
		int num1 = s.nextInt();
		System.out.println("请输入第二个整数:");
		int num2 = s.nextInt();
		System.out.println("比较大的整数是:" + max(num1, num2));
	}
	
	public static int max(int num1, int num2){
		if(num1 >= num2){
			return num1;
		}else{
			return num2;
		}
	}
}

打印效果如图:

题7:

Select Code
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
import java.util.Scanner;
/*
	定义方法,获取三个数中的最大值;
*/
public class Demo07{
	public static void main(String[] args){
		Scanner s = new Scanner(System.in);
		System.out.println("请输入第一个小数:");
		Double num1 = s.nextDouble();
		System.out.println("请输入第二个小数:");
		Double num2 = s.nextDouble();
		System.out.println("请输入第三个小数:");
		Double num3 = s.nextDouble();
		System.out.println("三个数中最大的整数是:" + max(num1, num2, num3));
	}
	
	public static double max(double d1, double d2, double d3){
		if(d1 > d2){
			if(d1 > d3){
				return d1;
			}else{
				return d3;
			}
		}else{
			if(d2 > d3){
				return d2;
			}else{
				return d3;
			}
		}
	}
}

打印效果如图:

## 方法的重载
在同一个类中,允许出现同名,但是形参列表不同的多个方法,称为方法的重载

为什么有方法的重载?
为了重复使用方法名,简化编程,方便阅读。

程序如何辨别到底调用的是哪个方法?
重载方法虽然方法名相同,但是参数列表不同,虚拟机就是根据调用方法时,传递不同的参数来决定到底调用的是哪一个方法。

## 重载示例与练习

#大数据学习笔记第4天# 流程控制

## 回顾

## 作用

## 大纲
– Switch结构
– 循环结构
– for循环
– while循环
– do…while循环
– 循环嵌套
– 2个案例:猜数字、循环输入成绩进行判断

## 第一节课 ##
– 回顾、作业
– Switch结构
– Switch练习

## 第二节课 ##
– for循环
– for循环练习

## 第三节课 ##
– while循环
– do…while循环
– 循环嵌套

## 第四节课 ##
– 案例:循环嵌套之九九乘法表
– 案例:猜数字
– 案例:循环输入成绩进行判断

## 分支结构:switch

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
switch(表达式或变量){
	case 取值1:
		语句体1;
		break;
	case 取值2:
		语句体2;
		break;
	...
	default:
		语句体n+1;
		break;
}

### switch注意事项:

  • switch语句表达式的类型有:byte,short,int,char,String(1.7之后才支持)和枚举类型;
  • case之间与default没有顺序,case相当于入口点,没有匹配的case将执行default,default也不是必须的;
  • 结束switch语句的情况:遇到break或执行到switch语句结束;
  • 如果匹配的case或者default没有对应的break,那么程序会继续向下执行,运行可以执行的语句,直到遇到break或者switch结尾;

## 循环结构:概述
循环语句可以在满足循环条件的情况下,反复执行某一段代码;被反复执行的代码称为循环体;需要在适当的时候,把循环条件改为假,从而结束循环,否则循环将一直执行下去,形成死循环;

完整的循环应该包含以下四个部分:

  • 初始化语句:初始化工作,在循环体开始之前执行;
  • 循环条件:一个boolean表达式,决定是否执行循环体;
  • 循环体:反复执行的部分;
  • 迭代语句:在循环体执行完之后执行,然后再去判断循环条件,一般用来控制循环条件中的变量,使循环在合适的时候结束;

## 循环结构:for
格式:

Select Code
1
2
3
for(初始化表达式;条件表达式;循环变量控制语句){
循环体语句;
}

格式说明:for运行的顺序

1. 执行初始化表达式,只执行一次,通常是定义循环变量语句;
2. 判断循环条件,为真就往下执行,为假就结束循环;
3. 执行循环体语句;
4. 执行循环变量控制语句,一般是循环变量的自增或自减;
5. 回到第2步,重复这个过程,直到为假时结束;

## 10个练习题
1. 在控制台上依次打印1-10;
2. 在控制台上依次打印10-1;
3. 求1-10所有数之和;
4. 求出1-100之间的所有偶数之和;
5. 求出1-100之间的所有奇数之和;
6. 求出5的阶乘;
7. 求水仙花数;
8. 列出5位数中的回文数;
9. 统计1000以内,同时是3,5,7的倍数的数有多少个?
10. 在1-100之间,若是3的倍数,则在它之后输出中文“三”,若是5的倍数,则在它之后输出中文“五”,若是7的倍数,则在它之后输出中文“七”

答案:

01题:

Select Code
1
2
3
4
5
6
7
public class Demo01{
	public static void main(String[] args){
		for(int i=1;i<=10;i++){
			System.out.println(i);
		}
	}
}

02题:

Select Code
1
2
3
4
5
6
7
public class Demo02{
	public static void main(String[] args){
		for(int i=10;i>0;i--){
			System.out.println(i);
		}
	}
}

03题:

Select Code
1
2
3
4
5
6
7
8
9
public class Demo03{
	public static void main(String[] args){
		int sum = 0;
		for(int i=1;i<=10;i++){
			sum += i;
		}
		System.out.println("求1-10所有数之和:" + sum);
	}
}

04题:

Select Code
1
2
3
4
5
6
7
8
9
10
11
public class Demo04{
public static void main(String[] args){
	int sum = 0;
	for(int i=1; i<=100; i++){
		if(i%2==0){
			sum += i;
		}
	}
	System.out.println("求出1-100之间的所有偶数之和:" + sum);
}
}

05题:

Select Code
1
2
3
4
5
6
7
8
9
10
11
public class Demo05{
public static void main(String[] args){
	int sum = 0;
	for(int i=1; i<=100; i++){
		if(i%2==1){
			sum += i;
		}
	}
	System.out.println("求出1-100之间的所有奇数之和:"+sum);	//2500
}
}

06题:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
求出5的阶乘;
公式:n!=n*(n-1)! 阶乘的计算方法 阶乘指从1乘以2乘以3乘以4一直乘到所要求的数。 
*/
public class Demo06{
	public static void main(String[] args){
		int res = 1;
		for(int i=1; i<=5; i++){
			res = res * i;
		}
		System.out.println("5的阶乘:" + res);
	}
}

07题:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
求水仙花数;
所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数 本身。
*/
public class Demo07{
	public static void main(String[] args){
		for(int i=100; i<1000; i++){
			int ge = i%10;		// 个位数
			int shi = i/10%10;	// 十位数
			int bai = i/100;	// 百位数
		
			if(ge*ge*ge+shi*shi*shi+bai*bai*bai==i){
				System.out.println(i);
			}
		}
	}
}

08题:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
	列出5位数中的回文数
	回文数的概念:即是给定一个数,这个数顺读和逆读都是一样的。例如:121,1221...
*/
public class Demo08{
	public static void main(String[] args){
		int count = 0;
		for(int i=10000; i<100000; i++){
			// 个十百千万
			int ge = i%10; // 12345
			int shi = i%100/10;
			int qian = i%10000/1000;
			int wan = i/10000;
			
			if(ge==wan && shi==qian){
				count++;
				System.out.println(i);
			}
		}
		System.out.println("5位数中一共有"+count+"个回文数");	// 900
	}
}

09题:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
	统计1000以内,同时是3,5,7的倍数的数有多少个?
*/
public class Demo09{
	public static void main(String[] args){
		int count = 0;
		for (int i=0; i<1000; i++){
			if(i%3==0 && i%5==0 && i%7==0){
				System.out.println(i);
				count++;
			}
		}
		System.out.println("统计1000以内,同时是3,5,7的倍数的数有多少个?" + count);
	}
}

10题:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
在1-100之间,若是3的倍数,则在它之后输出中文“三”,若是5的倍数,则在它之后输出中文“五”,若是7的倍数,则在它之后输出中文“七”
*/
public class Demo10{
	public static void main(String[] args){
		for(int i=1; i<=100; i++){
			System.out.print(i);

			if(i%3==0){
				System.out.print("三");
			}else if(i%5==0){
				System.out.print("五");
			}else if(i%7==0){
				System.out.print("七");
			}

			System.out.println();
		}
	}
}

## 循环结构:while
while语句格式:

Select Code
1
2
3
4
5
[初始化部分]
while(条件表达式){
	循环体语句;
	[循环变量控制语句]
}

执行流程:

1. 执行初始化语句(如果有的话);
2. 判断条件表达式真假;如果真,往下执行;如果假,结束循环;
3. 执行循环体语句;
4. 执行循环变量控制语句(如果有的话);
5. 返回第2步,重复执行,直到条件为假,结束循环;

### 循环变量的使用问题:
for循环的循环变量,一般情况下在循环外是不能访问到的,因为它的作用域是在for循环的{}之内,但是可以通过把循环变量定义在循环之外来实现这个功能;或者定义计数器;

Select Code
1
2
3
4
5
6
7
8
9
10
for(int i=0;i<10;i++){
		...
	}
	System.out.println(i);	//error

	int i=0;
	for(;i<10;i++){
		...
	}
	System.out.println(i);	//ok

while循环本身就是把循环变量定义在循环之外,所以没有这个问题;

Select Code
1
2
3
4
5
6
int i=0;
	while(i<10){
		...
		i++;
	}
	System.out.println(i);

### for 和 while 的使用场景
1. 当明确知道循环的范围的时候,通常使用for;
2. 当不明确循环次数的时候,for和while都可以,通常使用while;

### 案例:
已知珠穆朗玛峰的高度是8848米,假设有一张足够大的纸,厚度是0.01米,请问:这张纸折叠多少次可以保证厚度不低于珠穆朗玛峰的高度?

答案:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
public class ZhuMuLangMa2{
		public static void main(String[] args){
			double h=0.01;
			double all_height = h;
			int count=0;
			while(all_height<=8848){
				all_height *= 2;
				count++;
			}
			System.out.println("需要折叠的次数是:"+count);
		}
	}

另外一种方法:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ZhuMuLangMa{
		public static void main(String[] args){
			double h=0.01;
			double all_height = h;
			int count=0;
			while(true){
				all_height *= 2;
				count++;
				if(all_height>8848){
					break;
				}
			}
			System.out.println("需要折叠的次数是:"+count);
		}
	}

## 循环结构:do-while
do while语句格式:

Select Code
1
2
3
4
5
[初始化部分]
	do{
		循环体语句;
		[循环变量控制语句]
	}while(条件表达式);

执行流程:

1. 执行初始化部分(如果有)
2. 执行循环体语句
3. 执行循环变量控制语句(如果有)
4. 判断条件表达式,如果为真,返回第2步;如果为假,结束循环

特点:循环体至少被执行1次;

### 三种循环的比较和死循环
– while和for可以互换;
– do-while循环的循环体语句至少执行一次;
– 优先选择使用for循环;
– 死循环:条件表达式永远为true;

## 循环的嵌套
外层循环表达式为真时,进入内层循环条件的判断,内层循环结束时,跳到外层循环继续判断外层循环的条件;

代码实例:

Select Code
1
2
3
4
5
6
7
8
9
10
public class QianTao{
		public static void main(String[] args){
			for(int i=0; i<5; i++){ //外层循环
				for(int j=0; j<5; j++){	//内层循环
					System.out.println(i+"*"+j);
				}
				System.out.println("-------");
			}
		}
	}

### 案例
循环嵌套打印正三角形、倒三角形;

代码:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
	打印三角形:第n行打印n次星号
	*/
	import java.util.Scanner;

	public class SanJiaoXing{
		public static void main(String[] args){
			Scanner s = new Scanner(System.in);
			System.out.println("请输入一个数字,表示三角形的行数:");
			int num = s.nextInt();
			
			for(int i=1; i<=num; i++){
				for(int j=i; j>0; j--){
					System.out.print("*");
				}
				System.out.println();
			}
		}
	}


备注:可以试试输出一个倒三角形。