2019.6.4 14:40 三刷结束留念 ——小楠楠
2019.4.11 17:28 二刷结束留念
慢慢适应了现在的学习节奏,基础学习也步入了正题,每天的视频课程容量都很大,再加上停停顿顿抓住每个细节,一天的视频学习下来也需要好多时间呢,不过因为适应得不错,感受也还好~没有特别累,相反,看完之后有很多新收获成就感大大的有(#^.^#)
从前辈那里学习了他以前的学习计划和经验,原文:2019秋招经验谈
专业技术的学习内容包括:
学习资料:
文字版:
PS:后面又有一些添加,文字版不是很完整,可以参考那张红色的图~
学习路线推荐:
打算按照上面学习路线的顺序来学习专业技术,现在在做第0步,任重而道远~
好咯,开始day03课程的笔记啦。
01-语句(while)
这节讲程序控制中的第三种结构,循环结构。
循环结构中,代表语句有三种:while,do while,for。
while语句格式:
定义初始化表达式;
while(条件表达式):
{
执行语句;
}
02-语句(do while)
do while的语句格式:
do
{
执行语句;
}while(条件表达式);
do while 和 while的不同:
while:先判断条件,只有条件满足才执行循环体。
do while:先执行循环体,再判断条件,条件满足,再继续执行循环体。
do while无论条件是否满足,循环体至少执行一次。
注意:
int y=1;
while(y<3);
不会报错,编译可以通过。但是程序会陷入死循环。
03-语句(for)
for语句格式:
for(初始化表达式;循环条件表达式;循环后的操作表达式)
{
执行语句;
}
例:
for(int x=0;x<3;x++)
{
System.out.println("x="+x);
}
04-语句(for和while的区别)
上面那个例子用while来写:
int y=0;
while(y<3)
{
System.out.println("y="+y);
}
效果是一样的,没有什么区别。
但是若for循环的初始表达式是在for循环中定义的,如for(int x=0;x<3;x++),那么如果这个循环结束了,变量x也会消失。但while循环中的初始表达式是在while循环外定义的,循环结束变量y依然存在。
所以,对于变量来讲,如果这个变量仅仅用来控制循环次数,作为循环增量来讲的话,用for循环比较合适。(哈哈~要严谨要一丝不苟,这一点点内存也要好好规划呢(*^▽^*))
05-语句(循环语句的其他特点)
一个例子:
进行一些修改:
这次编译成功啦。
这个例子告诉我们for循环的两件事:1.条件一定要为真或者为假。2.初始表达式不一定是int x=0;这种形式,只要是合法的表达式就OK。
再进行一些修改:
也可以编译成功。循环后的操作表达式,不一定是惟一的,也可以有多个表达式,用逗号隔开即可。
下面两种写法效果相同,即可以把初始表达式写在外面,把循环后的操作写在里面,但其实也没什么意义,所以一般不这么干。
无限循环的最简单表现形式:
for(;;){}
while(true){}
06-语句(for语句练习-累加&计数器)
练习1:获取1~10的和,并打印。
用while来写:
//1,定义变量用于存储不断变化的和
int sum=0;
//2,定义变量记录住不断变化的被加的数
int x=1;
//3,定义循环,重复加法的过程
while(x<=10)
{
sum=sum+x;
x++;
}
System.out.println("while sum="+sum);
循环注意:
一定要明确哪些语句需要参与循环,哪些不需要。
用for来写:
int sum=0;
for(int x=0;x<=10;x++)
{
sum+=x;
}
System.out.println("for sum="+sum);
其实这就是累加思想。
原理:通过变量记录住每次变化的结果。
通过循环的形式,进行累加动作。
字符串的延长也是累加。
记住了累加的思想,可以解决很多问题,如果只记住了上面这串代码,那只能解决1~100的累加。记住代码,可以解决一个问题,记住思想,可以解决一类问题。
练习2:1~100之间7的倍数的个数,并打印。
思路:
1,先对1~100进行循环(遍历)通过循环的形式。
2,在遍历的过程中,定义条件,只对7的倍数进行操作。
步骤:
1,定义循环语句,选择for语句。
2,在循环中定义判断,只要是7的倍数即可。使用if语句。条件:7的背书 x%7=0;
for(int x=1;x<=100;x++)
{
if(x%7==0)
System.out.println("x="+x);
}
如果想要知道100内有多少个7的倍数呢?
在思路中加入第三条:
3,因为7的倍数不确定,只要符合条件,就通过一个变量来记录住这个变化的次数。
在步骤中加入第三条:
3,定义变量,该变量随着7的倍数的出现而自增。
int count=0;
for(int x=1;x<=100;x++)
{
if(x%7==0)
count++;
}
System.out.println("count="+count);
计数器思想:
通过一个变量记录住数据的状态变化。
也需要通过循环完成。
07-语句(for嵌套)
语句嵌套形式,其实就是语句中还有语句。
一个循环嵌套的例子。
打印长方形:
for(int x=0;x<3;x++)
{
for(int y=0;y<4;y++)
{
System.out.print("*");
}
System.out.println();//只有一个功能就是换行
//System.out.print();//如果这样写一点功能都没有 Java看到这种废话都会给提示的
}
对于打印长方形:外循环控制行数,内循环控制每一行的列数,也就是一行中元素的个数。
再一个例子,打印下面的图形:
*****
****
***
**
*
发现图形有很多行,每一行有很多列。
要使用嵌套循环。原理:形象说法:大圈套小圈。
for(int x=0;x<5;x++)//x<5:因为外循环控制行数。一共五行。
{
for(int y=x;y<5;y++)
{
System.out.print("*");
}
System.out.println();
}
08-语句(for嵌套练习)
练习1 打印下面的图形:
*
**
***
****
*****
for(int x=0;x<5;x++)
{
for(int y=0;y<=x;y++)
{
System.out.print("*");
}
System.out.println();
}
不是规律的规律:
尖朝上,可以改变条件,让条件随着外循环变化。
尖朝下,可以改变初始化值,让初始化随着外循环变化。
练习2 打印下面的图形:
1
12
123
1234
12345
经过观察,每一行第一列都是1,所以控制列的内循环变量y的初始值为1;每一列都在自增1,所以循环后的操作是y++;列数和行数的关系是,列数等于行数,所以循环条件表达式为y<=x。
for(int x=1;x<=5;x++)
{
for(int y=1;y<=x;y++)
{
System.out.print(y);
}
System.out.println();
}
09-语句(for嵌套-九九乘法表)
九九乘法表:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
观察一下,每一行第一个被乘数都是1,所以控制列的内循环的变量y的初始值为1;第二个被乘数都是第一个自增1,后面同理,且列数和行数是一致的,所以循环条件表达式为y<=x;再看乘数,每一行的乘数都跟着行数递增而递增,是和行数一致的,因此控制行的外循环的变量x的初始化值为1,循环条件表达式为x<=3。
for(x=1;x<=3;x++)
{
for(y=1;y<=x;y++)
{
System.out.print(y+"*"+x+"="+y*x+"\t");//最后直接用空格" "的话会对不齐,所以用制表符\t
}
System.out.println();
}
将它应用到打印出九九乘法表,将x<=3中的3改成9即可。
10-语句(break-continue)
其他流程控制语句:break(跳出),continue(继续)。
break语句:应用范围:选择结构和循环结构。跳出循环。
一种特殊情况,给内循环和外循环标号以做区分:
例1,break只是跳出内循环,外循环依然执行。
for(int x=0;x<3;x++)
{
for(int y=0;y<4;y++)
{
System.out.println("x="+x);
break;
}
}
例2,通过标号可以区分两个循环,指明跳出哪个循环,内循环可以不定义,因为默认跳出的就是内循环~
w:for(int x=0;x<3;x++)
{
for(int y=0;y<4;y++)
{
System.out.println("x="+x);
break w;
}
}
continue语句:只能作用于循环结构。继续循环。特点:结束本次循环,继续下一次循环。
for(int x=1;x<10;x++)
{
if(x%2==1)
continue;
System.out.println("x="+x);
}
一种特殊情况:
w:for(int x=0;x<3;x++)
{
for(int y=0;y<4;y++)
{
System.out.println("x="+x);
continue w;//如果这里不写w,这个语句就没有什么意义,写了之后,是继续外循环
}
}
注意:
1,break和continue语句作用的范围。
2,break和continue语句单独存在时,下面可以有任何语句,因为都执行不到。
11-语句(练习)
画这个图形:
“-”表示空格。
其实是将下面这个三角形,不打印单个的*,而是打印*+空格,最后画出来的。
行数是确定的,所以外循环是固定的。内循环部分,我们首先要打印空格。
for(int x=0;x<5;x++)
{
for(int y=x+1;y<5;y++)
{
System.out.print(" ");
}
for(int z=0;z<=x;z++)
{
System.out.print("* ");
}
System.out.println();
}
12-函数(概述)
函数的定义
函数就是定义在类中的具有特定功能的一段独立小程序。
函数也称为方法。
int x=4;
System.out.println(x*3+5);
x=6;
System.out.println(x*3+5);
发现以上的运算,因为获取不同数据的运算结果,代码出现了重复。
为了提高代码的复用性,对代码进行抽取。
将这个部分定义成一个独立的功能,方便于日后使用。
java中对功能的定义是通过函数的形式来体现的。
需要定义功能,完成一个整数的*3+5的运算,并打印结果。
1,先明确函数定义的格式。
修饰符:对函数进行外加功能的定义,比如衣服之于人,穿着军装就是军人,穿着便服就是老百姓,衣服就是一种修饰。
返回值类型:函数运行后的结果的数据类型。
参数类型:是形式参数的数据类型。
形式参数: 是一个变量,用于存储调用函数时传递给函数的实际参数。
实际参数:传递给形式参数的具体数值。
return:用于结束函数。
返回值:该值会返回给调用者。
public static int getResult(int num)
{
return num*3+5;
}
这个函数,定义在主函数后面也可以,定义在主函数前面也可以,定义在主函数前面放在第一个位置,程序一开始也不会第一个执行它,主函数在哪里,程序就从哪里入口执行。定义的函数,不一定会被执行,只有调用它,它才会执行。
怎么调用它呢?
在主函数中:
public static void main(String[] args)
{
getResult(4);
}
捋一下过程:主函数先被调用,这里面有一行代码getResult(4);被执行,这行代码跳转到定义的函数中来执行, 同时把4这个具体的值传给了num,传完之后给num*3+5,然后把结果返回给主函数。
这样最后执行是没有结果哒,我们可以写成这样:
int x=getResult(4);
System.out.println("x="+x);
运行就有结果打印出来啦。
由上,函数的功能:提高复用性。
函数的特点:
定义函数可以将功能代码进行封装。
便于对该功能进行复用。
函数只有被调用才会被执行。
函数的出现提高了代码的复用性。
对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。
13-函数(应用)
我们在编写程序,其实就是在不断的实现功能,而Java中最小的功能单元就是函数。所以日后在写代码的时候,定义一个功能就把它定义到一个独立的函数中去,而不要乱七八糟都塞到主函数里。
主函数的功能其实就一个:调用函数。
如何定义一个函数呢?
1,既然函数是一个独立的功能,那么该功能的运算结果是什么先明确。(因为有了现实中的需求,所以才需要用Java中的代码来体现一下功能需求,所以在写代码之前要先想好功能才能用代码体现~)
因为这是在明确函数的返回值类型。
2,在明确定义该功能的过程中是否需要未知的内容参与运算。(即这个功能是能够完全独立实现,还是需要调用者给一些值?)
因为这是在明确函数的参数列表(参数的类型和参数的个数)。
例1:
//需求:定义一个功能,完成3+4的运算,并将结果返回给调用者。
/*
1,明确功能的结果:是一个整数的和。
2,在实现该功能的过程中是否有未知内容参与运算,没有。
其实这两个功能就是在明确函数的定义。
1,是在明确函数的返回值类型。
2,明确函数的参数列表。
*/
public static int getSum()
{
return 3+4;
}
例2:
/*
以上这个函数的功能,结果是固定的,毫无扩展性而言。
为了方便用户需求,由用户来指定加数和被加数。这样,功能才有意义。
思路:
1,功能结果是一个和。返回值类型是int。
2,有未知内容参与运算。有两个。这两个未知内容的类型都是int。
*/
public static int getSum(int x,int y)
{
return x+y;
}
例3:
/*
需求:判断两个数是否相同。
思路:
1,明确功能的结果:结果是:boolean。
2,功能是否有未知内容参与运算。有,两个整数。
*/
public static boolean compare(int a,int b)
{
//优化前
//if(a==b)
// return true;
//else
// return false;
//优化中
//return (a==b)?true:false;
//优化后
return a==b;
}
例4:
/*
需求:定义功能,对两个数进行比较,获取较大的数。
*/
public static int getMax(int a,int b)
{
/*
if(a>b)
return a;
else
return b;
*/
return (a>b)?a:b;
}
一个不对的例子:
14-函数(练习)
1,定义一个功能,用于打印矩形。
2,定义一个打印99乘法表功能的函数。
/*
定义一个功能,用于打印矩形。
思路:
1,确定结果:没有,因为直接打印,所以返回值类型是void。
2,有未知内容吗?有,两个,因为矩形的行和列不确定。
*/
public static void draw(int row,int col)
{
for(int x=0;x<row;x++)
{
for(int y=0;y<col;y++)
{
System.out.print("*");
}
System.out.println();
}
}
//主函数调用
draw(5,6);
/*
定义一个打印99乘法表功能的函数。
*/
public static void print99()
{
for(int x=1;x<=9;x++)
{
for(int y=1;y<=x;y++)
{
System.out.print(y+"*"+x+"="+y*x+"\t");
}
System.out.println();
}
}
//主函数调用
print99();
15-函数(重载)
重载的概念:
在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。
重载的特点:
与返回值类型无关,只看参数列表。
例:
//定义一个加法运算,获取两个整数的和。
public static int add(int x,int y)
{
return x+y;
}
//定义一个加法,获取三个整数的和。
public static int add(int x,int y,int z)
{
return x+y+z;
}
什么时候用重载?
当定义的功能相同,但参与运算的未知内容不同时。
那么,这时就定义一个函数名称以表示其功能,方便阅读,而通过参数列表的不同来区分多个同名函数。
九九乘法表的优化:
public static void print99(int num)
{
for(int x=1;x<=num;x++)
{
for(int y=1;y<=x;y++)
{
System.out.print(y+"*"+x+"="+y*x+"\t");
}
System.out.println();
}
}
public static void print99()
{
print99(9);
}
同理,刚刚的加法也可以优化:
public static int add(int x,int y)
{
return x+y;
}
public static int add(int x,int y,int z)
{
return add(x,y)+z;
}
几个例子~
17-数组(概述-内存结构)
数组的概念:
同一种类型数据的集合。其实数组就是一个容器。
数组的好处:
可以自动给数组中的元素从0开始编号,方便操作这些元素。
定义方法:
元素类型[] 数组名=new 元素类型[元素个数或数组长度];
例:
//需求:想定义一个可以存储3个整数的容器。
int[] x=new int[3];
上面的x是什么类型呢?
注意它不是int型哦,它是数组类型,数组是一种单独的数据类型。
第一讲的时候有讲到数据类型有两种:基本数据类型和引用数据类型,数组类型就是引用数据类型的三种之一。
那么 int[] x=new int[3];在内存中是什么样的呢?
内存结构
Java程序在运行时,需要在内存中分配空间。为了提高运算效率,又对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
划分为五片空间:栈内存,堆内存,方法区,本地方法区,寄存器。
我们这里主要讲前两种,后面三种以后再说~
例:
int x=3;
int[] x=new int[3];
这也是数组类型是引用数据类型的原因。因为数据并没有存到x中,而是存在x所指向的地址的空间中,x只是引用了这个地址而已~
堆内存中的实体都是用来封装数据的,它都有默认的初始化值。默认的初始化值是什么呢?这就要根据定义的数组类型来定啦。如果定义的是int型数组,默认的初始化值就是0,float就是0.0,boolean类型就是false。
如果我们不想让x再指向数组该怎么做呢?
x=null;
x不再指向数组,而是值为空,这时x就和数组没有关系啦。此时实体在堆内存中就没有人使用了,当一个实体在对内存中没有人引用和使用时,我们就视它为垃圾。垃圾不会立刻被内存清理掉,而是在不定时的时间内启动一个垃圾回收机制,将这个数组实体在堆内存中清除。
说一下Java语言的垃圾回收机制。
Java语言呢本身成长自C++,它优化了C++语言的一些特性,而变得更加易学易用,尤其在内存这一块,它做得比C++更好。
C++语言的特点在于,我们写了很多的程序,运行的时候会在内存中开辟空间,当内存中的实体越来越多的时候,哪些实体不用就得想办法清理掉。在C++中,是由程序员手动来将不用的实体在内存中清理掉。如果程序员忘记清理了,那么运行的时间越长,程序就越慢,甚至到最后会死机。
而Java不需要程序员手动去清除,一旦这个对象变成垃圾,虚拟机会自动启动垃圾回收机制将堆内存中不再被使用的实体清除掉。
一定会马上清除掉吗?不是的,是会不定时的启动这个~然后清除掉。
由上,栈和堆是不一样的,栈是自动释放,堆是垃圾回收。
一个例子:
这是两个引用在同时操作同一个数组的例子。
即使x指向为空,堆内存中也没有垃圾,因为还有y指向它呢。
就像两个人用一台电脑,第一个人装了一个软件,第二个人也可以用。
再一个例子:
a的值依然是5,没有变。
再一个例子:
此时x为空后堆内存中就有垃圾啦。
就像两个人用两台电脑,各自用各自的,一个在自己的电脑上修改了,也不会影响另一个人~
day03是战线拖得最长的一次,写了两周多才写好,中间发生了很多事情,包括八周年庆的策划、导师给安排的任务等等~都忙完后赶紧把这个赶着写完啦,接下来更要抓紧时间,想在年底之前把基础打完~加油!小楠楠(ง •_•)ง